diff options
306 files changed, 17137 insertions, 2606 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 1808f1157f30..a49709e86d59 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1970,6 +1970,8 @@ and is between 256 and 4096 characters. It is defined in the file norom [X86] Do not assign address space to expansion ROMs that do not already have BIOS assigned address ranges. + nobar [X86] Do not assign address space to the + BARs that weren't assigned by the BIOS. irqmask=0xMMMM [X86] Set a bit mask of IRQs allowed to be assigned automatically to PCI devices. You can make the kernel exclude IRQs of your ISA cards diff --git a/MAINTAINERS b/MAINTAINERS index 13608bd2e791..25b4159fa132 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -948,8 +948,9 @@ ARM/SHMOBILE ARM ARCHITECTURE M: Paul Mundt <lethal@linux-sh.org> M: Magnus Damm <magnus.damm@gmail.com> L: linux-sh@vger.kernel.org -T: git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/genesis-2.6.git W: http://oss.renesas.com +Q: http://patchwork.kernel.org/project/linux-sh/list/ +T: git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/genesis-2.6.git S: Supported F: arch/arm/mach-shmobile/ F: drivers/sh/ diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index a52a27c1d9be..6f80665f477e 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -951,8 +951,6 @@ static int sa1111_resume(struct platform_device *dev) if (!save) return 0; - spin_lock_irqsave(&sachip->lock, flags); - /* * Ensure that the SA1111 is still here. * FIXME: shouldn't do this here. @@ -969,6 +967,13 @@ static int sa1111_resume(struct platform_device *dev) * First of all, wake up the chip. */ sa1111_wake(sachip); + + /* + * Only lock for write ops. Also, sa1111_wake must be called with + * released spinlock! + */ + spin_lock_irqsave(&sachip->lock, flags); + sa1111_writel(0, sachip->base + SA1111_INTC + SA1111_INTEN0); sa1111_writel(0, sachip->base + SA1111_INTC + SA1111_INTEN1); diff --git a/arch/arm/configs/ap4evb_defconfig b/arch/arm/configs/ap4evb_defconfig index e14229be7676..57cb4b0ea83e 100644 --- a/arch/arm/configs/ap4evb_defconfig +++ b/arch/arm/configs/ap4evb_defconfig @@ -1,12 +1,15 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc7 -# Mon Feb 8 12:25:36 2010 +# Linux kernel version: 2.6.35-rc1 +# Mon May 31 14:29:17 2010 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y CONFIG_GENERIC_TIME=y +# CONFIG_ARCH_USES_GETTIMEOFFSET is not set CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_HAVE_PROC_CPU=y CONFIG_GENERIC_HARDIRQS=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_HAVE_LATENCYTOP_SUPPORT=y @@ -17,6 +20,7 @@ CONFIG_GENERIC_IRQ_PROBE=y CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y CONFIG_VECTORS_BASE=0xffff0000 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" @@ -31,6 +35,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZMA=y CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set @@ -54,11 +59,6 @@ CONFIG_RCU_FANOUT=32 CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=16 -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set # CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set @@ -94,10 +94,14 @@ CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # +# CONFIG_PERF_EVENTS is not set +# CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y CONFIG_SLAB=y @@ -172,8 +176,11 @@ CONFIG_MMU=y # CONFIG_ARCH_INTEGRATOR is not set # CONFIG_ARCH_REALVIEW is not set # CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_VEXPRESS is not set # CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_BCMRING is not set # CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CNS3XXX is not set # CONFIG_ARCH_GEMINI is not set # CONFIG_ARCH_EBSA110 is not set # CONFIG_ARCH_EP93XX is not set @@ -182,7 +189,6 @@ CONFIG_MMU=y # CONFIG_ARCH_STMP3XXX is not set # CONFIG_ARCH_NETX is not set # CONFIG_ARCH_H720X is not set -# CONFIG_ARCH_NOMADIK is not set # CONFIG_ARCH_IOP13XX is not set # CONFIG_ARCH_IOP32X is not set # CONFIG_ARCH_IOP33X is not set @@ -199,6 +205,7 @@ CONFIG_MMU=y # CONFIG_ARCH_KS8695 is not set # CONFIG_ARCH_NS9XXX is not set # CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_NUC93X is not set # CONFIG_ARCH_PNX4008 is not set # CONFIG_ARCH_PXA is not set # CONFIG_ARCH_MSM is not set @@ -207,14 +214,18 @@ CONFIG_ARCH_SHMOBILE=y # CONFIG_ARCH_SA1100 is not set # CONFIG_ARCH_S3C2410 is not set # CONFIG_ARCH_S3C64XX is not set -# CONFIG_ARCH_S5PC1XX is not set +# CONFIG_ARCH_S5P6440 is not set +# CONFIG_ARCH_S5P6442 is not set +# CONFIG_ARCH_S5PC100 is not set +# CONFIG_ARCH_S5PV210 is not set # CONFIG_ARCH_SHARK is not set # CONFIG_ARCH_LH7A40X is not set # CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_U8500 is not set +# CONFIG_ARCH_NOMADIK is not set # CONFIG_ARCH_DAVINCI is not set # CONFIG_ARCH_OMAP is not set -# CONFIG_ARCH_BCMRING is not set -# CONFIG_ARCH_U8500 is not set +# CONFIG_PLAT_SPEAR is not set # # SH-Mobile System Type @@ -242,6 +253,8 @@ CONFIG_MEMORY_SIZE=0x10000000 # Timer and clock configuration # CONFIG_SH_TIMER_CMT=y +CONFIG_SH_TIMER_TMU=y +CONFIG_SH_CLK_CPG=y # # Processor Type @@ -269,6 +282,8 @@ CONFIG_ARM_THUMB=y # CONFIG_CPU_BPREDICT_DISABLE is not set CONFIG_HAS_TLS_REG=y CONFIG_ARM_L1_CACHE_SHIFT=5 +CONFIG_ARM_DMA_MEM_BUFFERABLE=y +CONFIG_CPU_HAS_PMU=y # CONFIG_ARM_ERRATA_430973 is not set # CONFIG_ARM_ERRATA_458693 is not set # CONFIG_ARM_ERRATA_460075 is not set @@ -322,7 +337,8 @@ CONFIG_ALIGNMENT_TRAP=y # CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="console=ttySC0,115200 earlyprintk=sh-sci.0,115200" +CONFIG_CMDLINE="console=ttySC0,115200" +# CONFIG_CMDLINE_FORCE is not set # CONFIG_XIP_KERNEL is not set CONFIG_KEXEC=y CONFIG_ATAGS_PROC=y @@ -398,6 +414,7 @@ CONFIG_MTD_BLOCK=y # CONFIG_INFTL is not set # CONFIG_RFD_FTL is not set # CONFIG_SSFDC is not set +# CONFIG_SM_FTL is not set # CONFIG_MTD_OOPS is not set # @@ -449,13 +466,19 @@ CONFIG_MTD_PHYSMAP=y # CONFIG_MTD_DOC2001 is not set # CONFIG_MTD_DOC2001PLUS is not set CONFIG_MTD_NAND=y -# CONFIG_MTD_NAND_VERIFY_WRITE is not set +CONFIG_MTD_NAND_ECC=y # CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_SM_COMMON is not set # CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_DENALI_SCRATCH_REG_ADDR=0xFF108018 +# CONFIG_MTD_NAND_GPIO is not set CONFIG_MTD_NAND_IDS=y # CONFIG_MTD_NAND_DISKONCHIP is not set # CONFIG_MTD_NAND_NANDSIM is not set # CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ALAUDA is not set +# CONFIG_MTD_NAND_SH_FLCTL is not set # CONFIG_MTD_ONENAND is not set # @@ -476,6 +499,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # CONFIG_SCSI_DMA is not set @@ -506,17 +530,56 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # # Input Device Drivers # -# CONFIG_INPUT_KEYBOARD is not set +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ADP5588 is not set +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_QT2160 is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_GPIO is not set +# CONFIG_KEYBOARD_TCA6416 is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_MAX7359 is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +CONFIG_KEYBOARD_SH_KEYSC=y +# CONFIG_KEYBOARD_XTKBD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_INPUT_JOYSTICK is not set # CONFIG_INPUT_TABLET is not set -# CONFIG_INPUT_TOUCHSCREEN is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_AD7879_I2C is not set +# CONFIG_TOUCHSCREEN_AD7879 is not set +# CONFIG_TOUCHSCREEN_DYNAPRO is not set +# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set +# CONFIG_TOUCHSCREEN_EETI is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_MCS5000 is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +CONFIG_TOUCHSCREEN_TSC2007=y +# CONFIG_TOUCHSCREEN_W90X900 is not set +# CONFIG_TOUCHSCREEN_TPS6507X is not set # CONFIG_INPUT_MISC is not set # # Hardware I/O ports # -# CONFIG_SERIO is not set +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set # CONFIG_GAMEPORT is not set # @@ -541,8 +604,12 @@ CONFIG_DEVKMEM=y CONFIG_SERIAL_SH_SCI=y CONFIG_SERIAL_SH_SCI_NR_UARTS=8 CONFIG_SERIAL_SH_SCI_CONSOLE=y +CONFIG_SERIAL_SH_SCI_DMA=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set @@ -551,13 +618,81 @@ CONFIG_UNIX98_PTYS=y # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set # CONFIG_TCG_TPM is not set -# CONFIG_I2C is not set +# CONFIG_RAMOOPS is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +# CONFIG_I2C_CHARDEV is not set +CONFIG_I2C_HELPER_AUTO=y + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_DESIGNWARE is not set +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_OCORES is not set +CONFIG_I2C_SH_MOBILE=y +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set # CONFIG_SPI is not set # # PPS support # # CONFIG_PPS is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +# CONFIG_GPIO_SYSFS is not set + +# +# Memory mapped GPIO expanders: +# +# CONFIG_GPIO_IT8761E is not set + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_ADP5588 is not set + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# + +# +# AC97 GPIO expanders: +# + +# +# MODULbus GPIO expanders: +# # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set @@ -569,25 +704,170 @@ CONFIG_SSB_POSSIBLE=y # Sonics Silicon Backplane # # CONFIG_SSB is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_CORE is not set +CONFIG_MFD_SUPPORT=y +CONFIG_MFD_CORE=y +# CONFIG_MFD_88PM860X is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +CONFIG_MFD_SH_MOBILE_SDHI=y +# CONFIG_HTC_EGPIO is not set # CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_TPS65010 is not set +# CONFIG_TPS6507X is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_MFD_TC35892 is not set # CONFIG_MFD_TMIO is not set +CONFIG_TMIO_MMC_DMA=y # CONFIG_MFD_T7L66XB is not set # CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_ABX500_CORE is not set # CONFIG_REGULATOR is not set -# CONFIG_MEDIA_SUPPORT is not set +CONFIG_MEDIA_SUPPORT=y + +# +# Multimedia core support +# +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L2_COMMON=y +# CONFIG_VIDEO_ALLOW_V4L1 is not set +# CONFIG_VIDEO_V4L1_COMPAT is not set +CONFIG_VIDEO_MEDIA=y + +# +# Multimedia drivers +# +CONFIG_IR_CORE=y +CONFIG_VIDEO_IR=y +CONFIG_RC_MAP=y +CONFIG_IR_NEC_DECODER=y +CONFIG_IR_RC5_DECODER=y +CONFIG_IR_RC6_DECODER=y +CONFIG_IR_JVC_DECODER=y +CONFIG_IR_SONY_DECODER=y +# CONFIG_IR_IMON is not set +CONFIG_MEDIA_TUNER=y +# CONFIG_MEDIA_TUNER_CUSTOMISE is not set +CONFIG_MEDIA_TUNER_SIMPLE=y +CONFIG_MEDIA_TUNER_TDA8290=y +CONFIG_MEDIA_TUNER_TDA9887=y +CONFIG_MEDIA_TUNER_TEA5761=y +CONFIG_MEDIA_TUNER_TEA5767=y +CONFIG_MEDIA_TUNER_MT20XX=y +CONFIG_MEDIA_TUNER_XC2028=y +CONFIG_MEDIA_TUNER_XC5000=y +CONFIG_MEDIA_TUNER_MC44S803=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +CONFIG_VIDEO_IR_I2C=y +# CONFIG_VIDEO_SH_VOU is not set +# CONFIG_VIDEO_SAA5246A is not set +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_SOC_CAMERA is not set +CONFIG_V4L_USB_DRIVERS=y +# CONFIG_USB_VIDEO_CLASS is not set +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +CONFIG_USB_GSPCA=y +# CONFIG_USB_M5602 is not set +# CONFIG_USB_STV06XX is not set +# CONFIG_USB_GL860 is not set +# CONFIG_USB_GSPCA_BENQ is not set +# CONFIG_USB_GSPCA_CONEX is not set +# CONFIG_USB_GSPCA_CPIA1 is not set +# CONFIG_USB_GSPCA_ETOMS is not set +# CONFIG_USB_GSPCA_FINEPIX is not set +# CONFIG_USB_GSPCA_JEILINJ is not set +# CONFIG_USB_GSPCA_MARS is not set +# CONFIG_USB_GSPCA_MR97310A is not set +# CONFIG_USB_GSPCA_OV519 is not set +# CONFIG_USB_GSPCA_OV534 is not set +# CONFIG_USB_GSPCA_OV534_9 is not set +# CONFIG_USB_GSPCA_PAC207 is not set +# CONFIG_USB_GSPCA_PAC7302 is not set +# CONFIG_USB_GSPCA_PAC7311 is not set +# CONFIG_USB_GSPCA_SN9C2028 is not set +# CONFIG_USB_GSPCA_SN9C20X is not set +# CONFIG_USB_GSPCA_SONIXB is not set +# CONFIG_USB_GSPCA_SONIXJ is not set +# CONFIG_USB_GSPCA_SPCA500 is not set +# CONFIG_USB_GSPCA_SPCA501 is not set +# CONFIG_USB_GSPCA_SPCA505 is not set +# CONFIG_USB_GSPCA_SPCA506 is not set +# CONFIG_USB_GSPCA_SPCA508 is not set +# CONFIG_USB_GSPCA_SPCA561 is not set +# CONFIG_USB_GSPCA_SQ905 is not set +# CONFIG_USB_GSPCA_SQ905C is not set +# CONFIG_USB_GSPCA_STK014 is not set +# CONFIG_USB_GSPCA_STV0680 is not set +# CONFIG_USB_GSPCA_SUNPLUS is not set +# CONFIG_USB_GSPCA_T613 is not set +# CONFIG_USB_GSPCA_TV8532 is not set +# CONFIG_USB_GSPCA_VC032X is not set +# CONFIG_USB_GSPCA_ZC3XX is not set +# CONFIG_VIDEO_PVRUSB2 is not set +# CONFIG_VIDEO_HDPVR is not set +# CONFIG_VIDEO_EM28XX is not set +# CONFIG_VIDEO_CX231XX is not set +# CONFIG_VIDEO_USBVISION is not set +# CONFIG_USB_ET61X251 is not set +# CONFIG_USB_SN9C102 is not set +# CONFIG_USB_ZC0301 is not set +# CONFIG_USB_ZR364XX is not set +# CONFIG_USB_STKWEBCAM is not set +# CONFIG_USB_S2255 is not set +# CONFIG_V4L_MEM2MEM_DRIVERS is not set +# CONFIG_RADIO_ADAPTERS is not set +# 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_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +# CONFIG_FB_CFB_FILLRECT is not set +# CONFIG_FB_CFB_COPYAREA is not set +# CONFIG_FB_CFB_IMAGEBLIT is not set +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +CONFIG_FB_SYS_FILLRECT=y +CONFIG_FB_SYS_COPYAREA=y +CONFIG_FB_SYS_IMAGEBLIT=y +# CONFIG_FB_FOREIGN_ENDIAN is not set +CONFIG_FB_SYS_FOPS=y +CONFIG_FB_DEFERRED_IO=y +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_S1D13XXX is not set +CONFIG_SH_MIPI_DSI=y +CONFIG_SH_LCD_MIPI_DSI=y +CONFIG_FB_SH_MOBILE_LCDC=y +# CONFIG_FB_TMIO is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # @@ -600,22 +880,237 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_VGA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y -# CONFIG_SOUND is not set +# CONFIG_FRAMEBUFFER_CONSOLE is not set +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y +CONFIG_SOUND=y +# CONFIG_SOUND_OSS_CORE is not set +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_JACK=y +# CONFIG_SND_SEQUENCER is not set +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +CONFIG_SND_DRIVERS=y +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set +CONFIG_SND_ARM=y +CONFIG_SND_USB=y +# CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_UA101 is not set +# CONFIG_SND_USB_CAIAQ is not set +CONFIG_SND_SOC=y + +# +# SoC Audio support for SuperH +# +CONFIG_SND_SOC_SH4_FSI=y +CONFIG_SND_FSI_AK4642=y +CONFIG_SND_FSI_DA7210=y +CONFIG_SND_SOC_I2C_AND_SPI=y +# CONFIG_SND_SOC_ALL_CODECS is not set +CONFIG_SND_SOC_AK4642=y +CONFIG_SND_SOC_DA7210=y +# CONFIG_SOUND_PRIME is not set # CONFIG_HID_SUPPORT is not set -# CONFIG_USB_SUPPORT is not set -# CONFIG_MMC is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_MON is not set +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +# CONFIG_USB_SL811_HCD is not set +CONFIG_USB_R8A66597_HCD=y +# CONFIG_USB_HWA_HCD is not set +# CONFIG_USB_MUSB_HDRC is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set + +# +# USB port drivers +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_GADGET is not set + +# +# OTG and related infrastructure +# +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_USB_ULPI is not set +# CONFIG_NOP_USB_XCEIV is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_SDHCI is not set +CONFIG_MMC_TMIO=y +CONFIG_MMC_SH_MMCIF=y # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_ACCESSIBILITY is not set CONFIG_RTC_LIB=y -# CONFIG_RTC_CLASS is not set -# CONFIG_DMADEVICES is not set -# CONFIG_AUXDISPLAY is not set -# CONFIG_UIO is not set +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set # -# TI VLYNQ +# RTC interfaces # +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +CONFIG_RTC_DRV_RS5C372=y +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set + +# +# SPI RTC drivers +# + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +CONFIG_DMADEVICES=y +# CONFIG_DMADEVICES_DEBUG is not set + +# +# DMA Devices +# +CONFIG_SH_DMAE=y +# CONFIG_TIMB_DMA is not set +CONFIG_DMA_ENGINE=y + +# +# DMA Clients +# +# CONFIG_ASYNC_TX_DMA is not set +# CONFIG_DMATEST is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set # CONFIG_STAGING is not set # @@ -677,7 +1172,46 @@ CONFIG_TMPFS=y # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y -# CONFIG_NLS is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set # # Kernel hacking @@ -733,6 +1267,7 @@ CONFIG_DEBUG_MEMORY_INIT=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_TRACING_SUPPORT=y # CONFIG_FTRACE is not set +# CONFIG_ATOMIC64_SELFTEST is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set @@ -760,12 +1295,13 @@ CONFIG_DEFAULT_SECURITY="" # # Library routines # +CONFIG_BITREVERSE=y CONFIG_GENERIC_FIND_LAST_BIT=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set # CONFIG_CRC_T10DIF is not set # CONFIG_CRC_ITU_T is not set -# CONFIG_CRC32 is not set +CONFIG_CRC32=y # CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y diff --git a/arch/arm/configs/g3evm_defconfig b/arch/arm/configs/g3evm_defconfig index 3c19031961db..549e46064a29 100644 --- a/arch/arm/configs/g3evm_defconfig +++ b/arch/arm/configs/g3evm_defconfig @@ -1,12 +1,15 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc7 -# Mon Feb 8 12:20:01 2010 +# Linux kernel version: 2.6.34 +# Thu May 20 12:21:19 2010 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y CONFIG_GENERIC_TIME=y +# CONFIG_ARCH_USES_GETTIMEOFFSET is not set CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_HAVE_PROC_CPU=y CONFIG_GENERIC_HARDIRQS=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_HAVE_LATENCYTOP_SUPPORT=y @@ -17,6 +20,7 @@ CONFIG_GENERIC_IRQ_PROBE=y CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y CONFIG_VECTORS_BASE=0xffff0000 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" @@ -31,6 +35,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZMA=y CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set @@ -54,11 +59,6 @@ CONFIG_RCU_FANOUT=32 CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=16 -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set # CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set @@ -94,10 +94,14 @@ CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # +# CONFIG_PERF_EVENTS is not set +# CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y CONFIG_SLAB=y @@ -172,8 +176,11 @@ CONFIG_MMU=y # CONFIG_ARCH_INTEGRATOR is not set # CONFIG_ARCH_REALVIEW is not set # CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_VEXPRESS is not set # CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_BCMRING is not set # CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CNS3XXX is not set # CONFIG_ARCH_GEMINI is not set # CONFIG_ARCH_EBSA110 is not set # CONFIG_ARCH_EP93XX is not set @@ -182,7 +189,6 @@ CONFIG_MMU=y # CONFIG_ARCH_STMP3XXX is not set # CONFIG_ARCH_NETX is not set # CONFIG_ARCH_H720X is not set -# CONFIG_ARCH_NOMADIK is not set # CONFIG_ARCH_IOP13XX is not set # CONFIG_ARCH_IOP32X is not set # CONFIG_ARCH_IOP33X is not set @@ -199,6 +205,7 @@ CONFIG_MMU=y # CONFIG_ARCH_KS8695 is not set # CONFIG_ARCH_NS9XXX is not set # CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_NUC93X is not set # CONFIG_ARCH_PNX4008 is not set # CONFIG_ARCH_PXA is not set # CONFIG_ARCH_MSM is not set @@ -207,14 +214,18 @@ CONFIG_ARCH_SHMOBILE=y # CONFIG_ARCH_SA1100 is not set # CONFIG_ARCH_S3C2410 is not set # CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_S5P6440 is not set +# CONFIG_ARCH_S5P6442 is not set # CONFIG_ARCH_S5PC1XX is not set +# CONFIG_ARCH_S5PV210 is not set # CONFIG_ARCH_SHARK is not set # CONFIG_ARCH_LH7A40X is not set # CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_U8500 is not set +# CONFIG_ARCH_NOMADIK is not set # CONFIG_ARCH_DAVINCI is not set # CONFIG_ARCH_OMAP is not set -# CONFIG_ARCH_BCMRING is not set -# CONFIG_ARCH_U8500 is not set +# CONFIG_PLAT_SPEAR is not set # # SH-Mobile System Type @@ -242,6 +253,7 @@ CONFIG_MEMORY_SIZE=0x08000000 # Timer and clock configuration # CONFIG_SH_TIMER_CMT=y +CONFIG_SH_TIMER_TMU=y # # Processor Type @@ -267,6 +279,8 @@ CONFIG_ARM_THUMB=y # CONFIG_CPU_DCACHE_DISABLE is not set # CONFIG_CPU_BPREDICT_DISABLE is not set CONFIG_ARM_L1_CACHE_SHIFT=5 +CONFIG_ARM_DMA_MEM_BUFFERABLE=y +CONFIG_CPU_HAS_PMU=y # CONFIG_ARM_ERRATA_411920 is not set CONFIG_COMMON_CLKDEV=y @@ -317,7 +331,7 @@ CONFIG_ALIGNMENT_TRAP=y # CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="console=ttySC1,115200 earlyprintk=sh-sci.1,115200" +CONFIG_CMDLINE="console=ttySC1,115200" # CONFIG_XIP_KERNEL is not set CONFIG_KEXEC=y CONFIG_ATAGS_PROC=y @@ -447,10 +461,12 @@ CONFIG_MTD_NAND=y # CONFIG_MTD_NAND_VERIFY_WRITE is not set # CONFIG_MTD_NAND_ECC_SMC is not set # CONFIG_MTD_NAND_MUSEUM_IDS is not set +# CONFIG_MTD_NAND_GPIO is not set CONFIG_MTD_NAND_IDS=y # CONFIG_MTD_NAND_DISKONCHIP is not set # CONFIG_MTD_NAND_NANDSIM is not set # CONFIG_MTD_NAND_PLATFORM is not set +CONFIG_MTD_NAND_SH_FLCTL=y # CONFIG_MTD_ONENAND is not set # @@ -471,6 +487,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # CONFIG_SCSI_DMA is not set @@ -538,6 +555,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=8 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set @@ -553,6 +571,31 @@ CONFIG_UNIX98_PTYS=y # PPS support # # CONFIG_PPS is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +# CONFIG_GPIO_SYSFS is not set + +# +# Memory mapped GPIO expanders: +# +# CONFIG_GPIO_IT8761E is not set + +# +# I2C GPIO expanders: +# + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# + +# +# AC97 GPIO expanders: +# # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set @@ -568,12 +611,16 @@ CONFIG_SSB_POSSIBLE=y # # Multifunction device drivers # -# CONFIG_MFD_CORE is not set +CONFIG_MFD_CORE=y # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +CONFIG_MFD_SH_MOBILE_SDHI=y +# CONFIG_HTC_EGPIO is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_MFD_T7L66XB is not set # CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -728,6 +775,7 @@ CONFIG_DEBUG_MEMORY_INIT=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_TRACING_SUPPORT=y # CONFIG_FTRACE is not set +# CONFIG_ATOMIC64_SELFTEST is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set @@ -772,3 +820,4 @@ CONFIG_DECOMPRESS_LZO=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y +CONFIG_GENERIC_ATOMIC64=y diff --git a/arch/arm/configs/g4evm_defconfig b/arch/arm/configs/g4evm_defconfig index 8ee79a537134..3841bc609d41 100644 --- a/arch/arm/configs/g4evm_defconfig +++ b/arch/arm/configs/g4evm_defconfig @@ -1,12 +1,15 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc7 -# Mon Feb 8 12:21:35 2010 +# Linux kernel version: 2.6.34 +# Thu May 20 12:37:38 2010 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y CONFIG_GENERIC_TIME=y +# CONFIG_ARCH_USES_GETTIMEOFFSET is not set CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_HAVE_PROC_CPU=y CONFIG_GENERIC_HARDIRQS=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_HAVE_LATENCYTOP_SUPPORT=y @@ -17,6 +20,7 @@ CONFIG_GENERIC_IRQ_PROBE=y CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y CONFIG_VECTORS_BASE=0xffff0000 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" @@ -31,6 +35,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZMA=y CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set @@ -54,11 +59,6 @@ CONFIG_RCU_FANOUT=32 CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=16 -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set # CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set @@ -94,10 +94,14 @@ CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # +# CONFIG_PERF_EVENTS is not set +# CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y CONFIG_SLAB=y @@ -172,8 +176,11 @@ CONFIG_MMU=y # CONFIG_ARCH_INTEGRATOR is not set # CONFIG_ARCH_REALVIEW is not set # CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_VEXPRESS is not set # CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_BCMRING is not set # CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CNS3XXX is not set # CONFIG_ARCH_GEMINI is not set # CONFIG_ARCH_EBSA110 is not set # CONFIG_ARCH_EP93XX is not set @@ -182,7 +189,6 @@ CONFIG_MMU=y # CONFIG_ARCH_STMP3XXX is not set # CONFIG_ARCH_NETX is not set # CONFIG_ARCH_H720X is not set -# CONFIG_ARCH_NOMADIK is not set # CONFIG_ARCH_IOP13XX is not set # CONFIG_ARCH_IOP32X is not set # CONFIG_ARCH_IOP33X is not set @@ -199,6 +205,7 @@ CONFIG_MMU=y # CONFIG_ARCH_KS8695 is not set # CONFIG_ARCH_NS9XXX is not set # CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_NUC93X is not set # CONFIG_ARCH_PNX4008 is not set # CONFIG_ARCH_PXA is not set # CONFIG_ARCH_MSM is not set @@ -207,14 +214,18 @@ CONFIG_ARCH_SHMOBILE=y # CONFIG_ARCH_SA1100 is not set # CONFIG_ARCH_S3C2410 is not set # CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_S5P6440 is not set +# CONFIG_ARCH_S5P6442 is not set # CONFIG_ARCH_S5PC1XX is not set +# CONFIG_ARCH_S5PV210 is not set # CONFIG_ARCH_SHARK is not set # CONFIG_ARCH_LH7A40X is not set # CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_U8500 is not set +# CONFIG_ARCH_NOMADIK is not set # CONFIG_ARCH_DAVINCI is not set # CONFIG_ARCH_OMAP is not set -# CONFIG_ARCH_BCMRING is not set -# CONFIG_ARCH_U8500 is not set +# CONFIG_PLAT_SPEAR is not set # # SH-Mobile System Type @@ -242,6 +253,7 @@ CONFIG_MEMORY_SIZE=0x08000000 # Timer and clock configuration # CONFIG_SH_TIMER_CMT=y +CONFIG_SH_TIMER_TMU=y # # Processor Type @@ -269,6 +281,8 @@ CONFIG_ARM_THUMB=y # CONFIG_CPU_BPREDICT_DISABLE is not set CONFIG_HAS_TLS_REG=y CONFIG_ARM_L1_CACHE_SHIFT=5 +CONFIG_ARM_DMA_MEM_BUFFERABLE=y +CONFIG_CPU_HAS_PMU=y # CONFIG_ARM_ERRATA_430973 is not set # CONFIG_ARM_ERRATA_458693 is not set # CONFIG_ARM_ERRATA_460075 is not set @@ -322,7 +336,7 @@ CONFIG_ALIGNMENT_TRAP=y # CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="console=ttySC4,115200 earlyprintk=sh-sci.4,115200" +CONFIG_CMDLINE="console=ttySC4,115200" # CONFIG_XIP_KERNEL is not set CONFIG_KEXEC=y CONFIG_ATAGS_PROC=y @@ -452,10 +466,12 @@ CONFIG_MTD_NAND=y # CONFIG_MTD_NAND_VERIFY_WRITE is not set # CONFIG_MTD_NAND_ECC_SMC is not set # CONFIG_MTD_NAND_MUSEUM_IDS is not set +# CONFIG_MTD_NAND_GPIO is not set CONFIG_MTD_NAND_IDS=y # CONFIG_MTD_NAND_DISKONCHIP is not set # CONFIG_MTD_NAND_NANDSIM is not set # CONFIG_MTD_NAND_PLATFORM is not set +CONFIG_MTD_NAND_SH_FLCTL=y # CONFIG_MTD_ONENAND is not set # @@ -476,6 +492,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # CONFIG_SCSI_DMA is not set @@ -543,6 +560,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=8 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set @@ -558,6 +576,31 @@ CONFIG_UNIX98_PTYS=y # PPS support # # CONFIG_PPS is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +# CONFIG_GPIO_SYSFS is not set + +# +# Memory mapped GPIO expanders: +# +# CONFIG_GPIO_IT8761E is not set + +# +# I2C GPIO expanders: +# + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# + +# +# AC97 GPIO expanders: +# # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set @@ -573,12 +616,16 @@ CONFIG_SSB_POSSIBLE=y # # Multifunction device drivers # -# CONFIG_MFD_CORE is not set +CONFIG_MFD_CORE=y # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +CONFIG_MFD_SH_MOBILE_SDHI=y +# CONFIG_HTC_EGPIO is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set # CONFIG_MFD_T7L66XB is not set # CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -733,6 +780,7 @@ CONFIG_DEBUG_MEMORY_INIT=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_TRACING_SUPPORT=y # CONFIG_FTRACE is not set +# CONFIG_ATOMIC64_SELFTEST is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set diff --git a/arch/arm/configs/mx25_defconfig b/arch/arm/configs/mx25_defconfig new file mode 100644 index 000000000000..17d40ee5519b --- /dev/null +++ b/arch/arm/configs/mx25_defconfig @@ -0,0 +1,1756 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.34 +# Mon May 31 10:57:45 2010 +# +CONFIG_ARM=y +CONFIG_HAVE_PWM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +# CONFIG_ARCH_USES_GETTIMEOFFSET is not set +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_FIQ=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y + +# +# Kernel Performance Events And Counters +# +# CONFIG_PERF_EVENTS is not set +# CONFIG_PERF_COUNTERS is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_COMPAT_BRK=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_CLK=y + +# +# GCOV-based kernel profiling +# +# CONFIG_SLOW_WORK is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +CONFIG_LBDAF=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set +CONFIG_FREEZER=y + +# +# System Type +# +CONFIG_MMU=y +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_VEXPRESS is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_BCMRING is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CNS3XXX is not set +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +CONFIG_ARCH_MXC=y +# CONFIG_ARCH_STMP3XXX is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_DOVE is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_LOKI is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_NUC93X is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_SHMOBILE is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_S5P6440 is not set +# CONFIG_ARCH_S5P6442 is not set +# CONFIG_ARCH_S5PC100 is not set +# CONFIG_ARCH_S5PV210 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_U8500 is not set +# CONFIG_ARCH_NOMADIK is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_PLAT_SPEAR is not set + +# +# Freescale MXC Implementations +# +# CONFIG_ARCH_MX1 is not set +# CONFIG_ARCH_MX2 is not set +CONFIG_ARCH_MX25=y +# CONFIG_ARCH_MX3 is not set +# CONFIG_ARCH_MXC91231 is not set +# CONFIG_ARCH_MX5 is not set + +# +# MX25 platforms: +# +CONFIG_MACH_MX25_3DS=y +CONFIG_MXC_IRQ_PRIOR=y +CONFIG_MXC_PWM=y +CONFIG_ARCH_MXC_IOMUX_V3=y + +# +# Processor Type +# +CONFIG_CPU_ARM926T=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_PABRT_LEGACY=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_CACHE_ROUND_ROBIN is not set +CONFIG_ARM_L1_CACHE_SHIFT=5 +CONFIG_COMMON_CLKDEV=y + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_HZ=100 +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +# CONFIG_HIGHMEM is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=999999 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_UACCESS_WITH_MEMCPY is not set + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="noinitrd console=ttymxc0,115200 root=/dev/mtdblock2 rw ip=off" +# CONFIG_CMDLINE_FORCE is not set +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# CPU Power Management +# +# CONFIG_CPU_IDLE is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_FPE_NWFPE is not set +# CONFIG_FPE_FASTFPE is not set +CONFIG_VFP=y + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_HAVE_AOUT=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +CONFIG_PM=y +CONFIG_PM_DEBUG=y +# CONFIG_PM_ADVANCED_DEBUG is not set +# CONFIG_PM_VERBOSE is not set +CONFIG_CAN_PM_TRACE=y +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND=y +# CONFIG_PM_TEST_SUSPEND is not set +CONFIG_SUSPEND_FREEZER=y +# CONFIG_APM_EMULATION is not set +# CONFIG_PM_RUNTIME is not set +CONFIG_PM_OPS=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_L2TP is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +CONFIG_WIRELESS=y +# CONFIG_CFG80211 is not set +# CONFIG_LIB80211 is not set + +# +# CFG80211 needs to be enabled for MAC80211 +# + +# +# Some wireless drivers require a rate control algorithm +# +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set +# CONFIG_CAIF is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=m +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_SM_FTL is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_CFI_INTELEXT is not set +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +# CONFIG_MTD_PHYSMAP_COMPAT is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SST25L is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_ECC=y +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_SM_COMMON is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_DENALI_SCRATCH_REG_ADDR=0xFF108018 +# CONFIG_MTD_NAND_GPIO is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ALAUDA is not set +CONFIG_MTD_NAND_MXC=y +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# +# UBI - Unsorted block images +# +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_GLUEBI is not set + +# +# UBI debugging options +# +# CONFIG_MTD_UBI_DEBUG is not set +# CONFIG_PARPORT is not set +# CONFIG_BLK_DEV is not set +CONFIG_MISC_DEVICES=y +# CONFIG_AD525X_DPOT is not set +# CONFIG_ICS932S401 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_ISL29003 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_DS1682 is not set +# CONFIG_TI_DAC7512 is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +CONFIG_EEPROM_AT24=y +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_IWMC3200TOP is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +CONFIG_SMSC_PHY=y +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MICREL_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set +# CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMC911X is not set +CONFIG_SMSC911X=y +CONFIG_DNET=y +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set +CONFIG_FEC=y +# CONFIG_FEC2 is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +CONFIG_WLAN=y +# CONFIG_USB_ZD1201 is not set +# CONFIG_HOSTAP is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_IPHETH is not set +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ADP5588 is not set +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_QT2160 is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_GPIO is not set +# CONFIG_KEYBOARD_TCA6416 is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_LM8323 is not set +# CONFIG_KEYBOARD_MAX7359 is not set +CONFIG_KEYBOARD_IMX=y +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_AD7877 is not set +# CONFIG_TOUCHSCREEN_AD7879_I2C is not set +# CONFIG_TOUCHSCREEN_AD7879_SPI is not set +# CONFIG_TOUCHSCREEN_AD7879 is not set +# CONFIG_TOUCHSCREEN_DYNAPRO is not set +# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set +# CONFIG_TOUCHSCREEN_EETI is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_MCS5000 is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_WM97XX is not set +# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set +# CONFIG_TOUCHSCREEN_W90X900 is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_N_GSM is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=m +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +# CONFIG_SERIAL_8250_MANY_PORTS is not set +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_RSA is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_MAX3100 is not set +CONFIG_SERIAL_IMX=y +CONFIG_SERIAL_IMX_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_HELPER_AUTO=y + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_DESIGNWARE is not set +# CONFIG_I2C_GPIO is not set +CONFIG_I2C_IMX=y +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +CONFIG_SPI=y +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_BITBANG=y +CONFIG_SPI_GPIO=y +CONFIG_SPI_IMX=y +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_DESIGNWARE is not set + +# +# SPI Protocol Masters +# +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set + +# +# PPS support +# +# CONFIG_PPS is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_GPIO_SYSFS is not set + +# +# Memory mapped GPIO expanders: +# +# CONFIG_GPIO_IT8761E is not set + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_ADP5588 is not set + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set + +# +# AC97 GPIO expanders: +# +CONFIG_W1=y + +# +# 1-wire Bus Masters +# +# CONFIG_W1_MASTER_DS2490 is not set +# CONFIG_W1_MASTER_DS2482 is not set +CONFIG_W1_MASTER_MXC=y +# CONFIG_W1_MASTER_DS1WM is not set +# CONFIG_W1_MASTER_GPIO is not set + +# +# 1-wire Slaves +# +CONFIG_W1_SLAVE_THERM=y +# CONFIG_W1_SLAVE_SMEM is not set +# CONFIG_W1_SLAVE_DS2431 is not set +# CONFIG_W1_SLAVE_DS2433 is not set +# CONFIG_W1_SLAVE_DS2760 is not set +# CONFIG_W1_SLAVE_BQ27000 is not set +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +# CONFIG_PDA_POWER is not set +# CONFIG_TEST_POWER is not set +# CONFIG_BATTERY_DS2760 is not set +# CONFIG_BATTERY_DS2782 is not set +# CONFIG_BATTERY_BQ27x00 is not set +# CONFIG_BATTERY_MAX17040 is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_UCB1400_CORE is not set +# CONFIG_TPS65010 is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13783 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_AB4500_CORE is not set +CONFIG_REGULATOR=y +# CONFIG_REGULATOR_DEBUG is not set +# CONFIG_REGULATOR_DUMMY is not set +# CONFIG_REGULATOR_FIXED_VOLTAGE is not set +# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set +# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set +# CONFIG_REGULATOR_BQ24022 is not set +# CONFIG_REGULATOR_MAX1586 is not set +# CONFIG_REGULATOR_MAX8649 is not set +# CONFIG_REGULATOR_MAX8660 is not set +# CONFIG_REGULATOR_LP3971 is not set +# CONFIG_REGULATOR_TPS65023 is not set +# CONFIG_REGULATOR_TPS6507X is not set +CONFIG_MEDIA_SUPPORT=y + +# +# Multimedia core support +# +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L2_COMMON=y +# CONFIG_VIDEO_ALLOW_V4L1 is not set +CONFIG_VIDEO_V4L1_COMPAT=y +# CONFIG_DVB_CORE is not set +CONFIG_VIDEO_MEDIA=y + +# +# Multimedia drivers +# +CONFIG_IR_CORE=y +CONFIG_VIDEO_IR=y +CONFIG_RC_MAP=y +CONFIG_IR_NEC_DECODER=y +CONFIG_IR_RC5_DECODER=y +CONFIG_IR_RC6_DECODER=y +CONFIG_IR_JVC_DECODER=y +CONFIG_IR_SONY_DECODER=y +# CONFIG_IR_IMON is not set +# CONFIG_MEDIA_ATTACH is not set +CONFIG_MEDIA_TUNER=y +# CONFIG_MEDIA_TUNER_CUSTOMISE is not set +CONFIG_MEDIA_TUNER_SIMPLE=y +CONFIG_MEDIA_TUNER_TDA8290=y +CONFIG_MEDIA_TUNER_TDA9887=y +CONFIG_MEDIA_TUNER_TEA5761=y +CONFIG_MEDIA_TUNER_TEA5767=y +CONFIG_MEDIA_TUNER_MT20XX=y +CONFIG_MEDIA_TUNER_XC2028=y +CONFIG_MEDIA_TUNER_XC5000=y +CONFIG_MEDIA_TUNER_MC44S803=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEOBUF_GEN=y +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +CONFIG_VIDEO_IR_I2C=y +# CONFIG_VIDEO_SAA5246A is not set +# CONFIG_VIDEO_SAA5249 is not set +CONFIG_SOC_CAMERA=y +CONFIG_SOC_CAMERA_MT9M001=y +CONFIG_SOC_CAMERA_MT9M111=y +CONFIG_SOC_CAMERA_MT9T031=y +# CONFIG_SOC_CAMERA_MT9T112 is not set +CONFIG_SOC_CAMERA_MT9V022=y +# CONFIG_SOC_CAMERA_RJ54N1 is not set +CONFIG_SOC_CAMERA_TW9910=y +# CONFIG_SOC_CAMERA_PLATFORM is not set +CONFIG_SOC_CAMERA_OV772X=y +# CONFIG_SOC_CAMERA_OV9640 is not set +# CONFIG_VIDEO_SH_MOBILE_CEU is not set +CONFIG_V4L_USB_DRIVERS=y +# CONFIG_USB_VIDEO_CLASS is not set +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +CONFIG_USB_GSPCA=m +# CONFIG_USB_M5602 is not set +# CONFIG_USB_STV06XX is not set +# CONFIG_USB_GL860 is not set +# CONFIG_USB_GSPCA_BENQ is not set +# CONFIG_USB_GSPCA_CONEX is not set +# CONFIG_USB_GSPCA_CPIA1 is not set +# CONFIG_USB_GSPCA_ETOMS is not set +# CONFIG_USB_GSPCA_FINEPIX is not set +# CONFIG_USB_GSPCA_JEILINJ is not set +# CONFIG_USB_GSPCA_MARS is not set +# CONFIG_USB_GSPCA_MR97310A is not set +# CONFIG_USB_GSPCA_OV519 is not set +# CONFIG_USB_GSPCA_OV534 is not set +# CONFIG_USB_GSPCA_OV534_9 is not set +# CONFIG_USB_GSPCA_PAC207 is not set +# CONFIG_USB_GSPCA_PAC7302 is not set +# CONFIG_USB_GSPCA_PAC7311 is not set +# CONFIG_USB_GSPCA_SN9C2028 is not set +# CONFIG_USB_GSPCA_SN9C20X is not set +# CONFIG_USB_GSPCA_SONIXB is not set +# CONFIG_USB_GSPCA_SONIXJ is not set +# CONFIG_USB_GSPCA_SPCA500 is not set +# CONFIG_USB_GSPCA_SPCA501 is not set +# CONFIG_USB_GSPCA_SPCA505 is not set +# CONFIG_USB_GSPCA_SPCA506 is not set +# CONFIG_USB_GSPCA_SPCA508 is not set +# CONFIG_USB_GSPCA_SPCA561 is not set +# CONFIG_USB_GSPCA_SQ905 is not set +# CONFIG_USB_GSPCA_SQ905C is not set +# CONFIG_USB_GSPCA_STK014 is not set +# CONFIG_USB_GSPCA_STV0680 is not set +# CONFIG_USB_GSPCA_SUNPLUS is not set +# CONFIG_USB_GSPCA_T613 is not set +# CONFIG_USB_GSPCA_TV8532 is not set +# CONFIG_USB_GSPCA_VC032X is not set +# CONFIG_USB_GSPCA_ZC3XX is not set +# CONFIG_VIDEO_PVRUSB2 is not set +# CONFIG_VIDEO_HDPVR is not set +# CONFIG_VIDEO_EM28XX is not set +# CONFIG_VIDEO_CX231XX is not set +# CONFIG_VIDEO_USBVISION is not set +# CONFIG_USB_ET61X251 is not set +# CONFIG_USB_SN9C102 is not set +# CONFIG_USB_ZC0301 is not set +# CONFIG_USB_ZR364XX is not set +# CONFIG_USB_STKWEBCAM is not set +# CONFIG_USB_S2255 is not set +# CONFIG_V4L_MEM2MEM_DRIVERS is not set +# CONFIG_RADIO_ADAPTERS is not set +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +CONFIG_HAVE_FB_IMX=y +CONFIG_FB_IMX=y +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_LOGO is not set +CONFIG_SOUND=y +# CONFIG_SOUND_OSS_CORE is not set +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_JACK=y +# CONFIG_SND_SEQUENCER is not set +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +# CONFIG_SND_HRTIMER is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +CONFIG_SND_DRIVERS=y +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set +# CONFIG_SND_ARM is not set +# CONFIG_SND_SPI is not set +# CONFIG_SND_USB is not set +CONFIG_SND_SOC=y +CONFIG_SND_SOC_AC97_BUS=y +CONFIG_SND_IMX_SOC=y +# CONFIG_SND_MXC_SOC_WM1133_EV1 is not set +CONFIG_SND_SOC_I2C_AND_SPI=y +# CONFIG_SND_SOC_ALL_CODECS is not set +# CONFIG_SOUND_PRIME is not set +CONFIG_AC97_BUS=y +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HIDRAW is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_HID_PID is not set +# CONFIG_USB_HIDDEV is not set + +# +# Special HID drivers +# +# CONFIG_HID_3M_PCT is not set +# CONFIG_HID_A4TECH is not set +# CONFIG_HID_APPLE is not set +# CONFIG_HID_BELKIN is not set +# CONFIG_HID_CANDO is not set +# CONFIG_HID_CHERRY is not set +# CONFIG_HID_CHICONY is not set +# CONFIG_HID_PRODIKEYS is not set +# CONFIG_HID_CYPRESS is not set +# CONFIG_HID_DRAGONRISE is not set +# CONFIG_HID_EGALAX is not set +# CONFIG_HID_EZKEY is not set +# CONFIG_HID_KYE is not set +# CONFIG_HID_GYRATION is not set +# CONFIG_HID_TWINHAN is not set +# CONFIG_HID_KENSINGTON is not set +# CONFIG_HID_LOGITECH is not set +# CONFIG_HID_MICROSOFT is not set +# CONFIG_HID_MOSART is not set +# CONFIG_HID_MONTEREY is not set +# CONFIG_HID_NTRIG is not set +# CONFIG_HID_ORTEK is not set +# CONFIG_HID_PANTHERLORD is not set +# CONFIG_HID_PETALYNX is not set +# CONFIG_HID_PICOLCD is not set +# CONFIG_HID_QUANTA is not set +# CONFIG_HID_ROCCAT_KONE is not set +# CONFIG_HID_SAMSUNG is not set +# CONFIG_HID_SONY is not set +# CONFIG_HID_STANTUM is not set +# CONFIG_HID_SUNPLUS is not set +# CONFIG_HID_GREENASIA is not set +# CONFIG_HID_SMARTJOYPLUS is not set +# CONFIG_HID_TOPSEED is not set +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_ZEROPLUS is not set +# CONFIG_HID_ZYDACRON is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_MON is not set +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +# CONFIG_USB_EHCI_TT_NEWSCHED is not set +CONFIG_USB_EHCI_MXC=y +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HWA_HCD is not set +# CONFIG_USB_MUSB_HDRC is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set + +# +# USB port drivers +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_GADGET is not set + +# +# OTG and related infrastructure +# +CONFIG_USB_OTG_UTILS=y +# CONFIG_USB_GPIO_VBUS is not set +CONFIG_USB_ULPI=y +# CONFIG_NOP_USB_XCEIV is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_SDHCI is not set +# CONFIG_MMC_MXC is not set +# CONFIG_MMC_SPI is not set +# CONFIG_MEMSTICK is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +# CONFIG_LEDS_PCA9532 is not set +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_GPIO_PLATFORM=y +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_PWM is not set +CONFIG_LEDS_REGULATOR=y +# CONFIG_LEDS_BD2802 is not set +# CONFIG_LEDS_LT3593 is not set +CONFIG_LEDS_TRIGGERS=y + +# +# LED Triggers +# +# CONFIG_LEDS_TRIGGER_TIMER is not set +# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_GPIO is not set +# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set + +# +# iptables trigger is under Netfilter config (LED target) +# +# CONFIG_ACCESSIBILITY is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_MXC is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +CONFIG_DMADEVICES=y +# CONFIG_DMADEVICES_DEBUG is not set + +# +# DMA Devices +# +# CONFIG_TIMB_DMA is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set +# CONFIG_STAGING is not set + +# +# File systems +# +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +# CONFIG_DNOTIFY is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +CONFIG_UBIFS_FS=y +# CONFIG_UBIFS_FS_XATTR is not set +# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set +CONFIG_UBIFS_FS_LZO=y +CONFIG_UBIFS_FS_ZLIB=y +# CONFIG_UBIFS_FS_DEBUG is not set +# CONFIG_LOGFS is not set +# CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +# CONFIG_NFS_V4_1 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set +# CONFIG_DLM is not set + +# +# Kernel hacking +# +CONFIG_PRINTK_TIME=y +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_FRAME_WARN=1024 +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_LATENCYTOP is not set +CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_ATOMIC64_SELFTEST is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_ARM_UNWIND=y +# CONFIG_DEBUG_USER is not set +# CONFIG_OC_ETM is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +# CONFIG_CRYPTO_ECB is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=y +# CONFIG_CRYPTO_ZLIB is not set +CONFIG_CRYPTO_LZO=y + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_RATIONAL=y +CONFIG_GENERIC_FIND_LAST_BIT=y +# CONFIG_CRC_CCITT is not set +CONFIG_CRC16=y +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_NLATTR=y +CONFIG_GENERIC_ATOMIC64=y diff --git a/arch/arm/configs/mx3_defconfig b/arch/arm/configs/mx3_defconfig index 8a06bc64fe59..c45f9eccda34 100644 --- a/arch/arm/configs/mx3_defconfig +++ b/arch/arm/configs/mx3_defconfig @@ -1,14 +1,16 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.32-rc5 -# Sun Nov 1 22:56:24 2009 +# Linux kernel version: 2.6.34 +# Tue May 25 14:54:32 2010 # CONFIG_ARM=y CONFIG_HAVE_PWM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y CONFIG_GENERIC_GPIO=y CONFIG_GENERIC_TIME=y +# CONFIG_ARCH_USES_GETTIMEOFFSET is not set CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_HAVE_PROC_CPU=y CONFIG_GENERIC_HARDIRQS=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_HAVE_LATENCYTOP_SUPPORT=y @@ -19,7 +21,8 @@ CONFIG_GENERIC_IRQ_PROBE=y CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_ARCH_MTD_XIP=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_FIQ=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y CONFIG_VECTORS_BASE=0xffff0000 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" @@ -34,6 +37,13 @@ CONFIG_LOCK_KERNEL=y CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -47,6 +57,7 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -54,11 +65,6 @@ CONFIG_RCU_FANOUT=32 CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -85,10 +91,14 @@ CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # +# CONFIG_PERF_EVENTS is not set +# CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y CONFIG_SLAB=y @@ -124,14 +134,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -# CONFIG_DEFAULT_AS is not set # CONFIG_DEFAULT_DEADLINE is not set CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set CONFIG_FREEZER=y # @@ -142,8 +179,11 @@ CONFIG_MMU=y # CONFIG_ARCH_INTEGRATOR is not set # CONFIG_ARCH_REALVIEW is not set # CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_VEXPRESS is not set # CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_BCMRING is not set # CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CNS3XXX is not set # CONFIG_ARCH_GEMINI is not set # CONFIG_ARCH_EBSA110 is not set # CONFIG_ARCH_EP93XX is not set @@ -152,7 +192,6 @@ CONFIG_ARCH_MXC=y # CONFIG_ARCH_STMP3XXX is not set # CONFIG_ARCH_NETX is not set # CONFIG_ARCH_H720X is not set -# CONFIG_ARCH_NOMADIK is not set # CONFIG_ARCH_IOP13XX is not set # CONFIG_ARCH_IOP32X is not set # CONFIG_ARCH_IOP33X is not set @@ -160,6 +199,7 @@ CONFIG_ARCH_MXC=y # CONFIG_ARCH_IXP2000 is not set # CONFIG_ARCH_IXP4XX is not set # CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_DOVE is not set # CONFIG_ARCH_KIRKWOOD is not set # CONFIG_ARCH_LOKI is not set # CONFIG_ARCH_MV78XX0 is not set @@ -168,20 +208,27 @@ CONFIG_ARCH_MXC=y # CONFIG_ARCH_KS8695 is not set # CONFIG_ARCH_NS9XXX is not set # CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_NUC93X is not set # CONFIG_ARCH_PNX4008 is not set # CONFIG_ARCH_PXA is not set # CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_SHMOBILE is not set # CONFIG_ARCH_RPC is not set # CONFIG_ARCH_SA1100 is not set # CONFIG_ARCH_S3C2410 is not set # CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_S5P6440 is not set +# CONFIG_ARCH_S5P6442 is not set # CONFIG_ARCH_S5PC1XX is not set +# CONFIG_ARCH_S5PV210 is not set # CONFIG_ARCH_SHARK is not set # CONFIG_ARCH_LH7A40X is not set # CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_U8500 is not set +# CONFIG_ARCH_NOMADIK is not set # CONFIG_ARCH_DAVINCI is not set # CONFIG_ARCH_OMAP is not set -# CONFIG_ARCH_BCMRING is not set +# CONFIG_PLAT_SPEAR is not set # # Freescale MXC Implementations @@ -191,6 +238,7 @@ CONFIG_ARCH_MXC=y # CONFIG_ARCH_MX25 is not set CONFIG_ARCH_MX3=y # CONFIG_ARCH_MXC91231 is not set +# CONFIG_ARCH_MX5 is not set CONFIG_ARCH_MX31=y CONFIG_ARCH_MX35=y @@ -203,6 +251,7 @@ CONFIG_MACH_PCM037=y CONFIG_MACH_PCM037_EET=y CONFIG_MACH_MX31LITE=y CONFIG_MACH_MX31_3DS=y +# CONFIG_MACH_MX31_3DS_MXC_NAND_USE_BBT is not set CONFIG_MACH_MX31MOBOARD=y CONFIG_MACH_MX31LILLY=y CONFIG_MACH_QONG=y @@ -212,8 +261,10 @@ CONFIG_MACH_MX35_3DS=y CONFIG_MACH_KZM_ARM11_01=y CONFIG_MXC_IRQ_PRIOR=y CONFIG_MXC_PWM=y +CONFIG_MXC_ULPI=y CONFIG_ARCH_HAS_RNGA=y CONFIG_ARCH_MXC_IOMUX_V3=y +CONFIG_ARCH_MXC_AUDMUX_V2=y # # Processor Type @@ -239,8 +290,11 @@ CONFIG_ARM_THUMB=y # CONFIG_CPU_DCACHE_DISABLE is not set # CONFIG_CPU_BPREDICT_DISABLE is not set CONFIG_OUTER_CACHE=y +CONFIG_OUTER_CACHE_SYNC=y CONFIG_CACHE_L2X0=y CONFIG_ARM_L1_CACHE_SHIFT=5 +CONFIG_ARM_DMA_MEM_BUFFERABLE=y +CONFIG_CPU_HAS_PMU=y # CONFIG_ARM_ERRATA_411920 is not set CONFIG_COMMON_CLKDEV=y @@ -282,8 +336,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_VIRT_TO_BUS=y -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 CONFIG_ALIGNMENT_TRAP=y @@ -328,13 +380,16 @@ CONFIG_HAVE_AOUT=y # CONFIG_PM=y CONFIG_PM_DEBUG=y +# CONFIG_PM_ADVANCED_DEBUG is not set # CONFIG_PM_VERBOSE is not set CONFIG_CAN_PM_TRACE=y CONFIG_PM_SLEEP=y CONFIG_SUSPEND=y +# CONFIG_PM_TEST_SUSPEND is not set CONFIG_SUSPEND_FREEZER=y # CONFIG_APM_EMULATION is not set # CONFIG_PM_RUNTIME is not set +CONFIG_PM_OPS=y CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_NET=y @@ -342,7 +397,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -379,6 +433,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_RDS is not set # CONFIG_TIPC is not set # CONFIG_ATM is not set +# CONFIG_L2TP is not set # CONFIG_BRIDGE is not set # CONFIG_NET_DSA is not set # CONFIG_VLAN_8021Q is not set @@ -404,12 +459,27 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set -# CONFIG_WIRELESS is not set +CONFIG_WIRELESS=y +# CONFIG_CFG80211 is not set +# CONFIG_LIB80211 is not set + +# +# CFG80211 needs to be enabled for MAC80211 +# + +# +# Some wireless drivers require a rate control algorithm +# # CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set # +# CAIF Support +# +# CONFIG_CAIF is not set + +# # Device Drivers # @@ -446,6 +516,7 @@ CONFIG_MTD_BLOCK=y # CONFIG_INFTL is not set # CONFIG_RFD_FTL is not set # CONFIG_SSFDC is not set +# CONFIG_SM_FTL is not set # CONFIG_MTD_OOPS is not set # @@ -485,6 +556,9 @@ CONFIG_MTD_PHYSMAP=y # # Self-contained MTD device drivers # +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SST25L is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set @@ -497,14 +571,18 @@ CONFIG_MTD_PHYSMAP=y # CONFIG_MTD_DOC2001 is not set # CONFIG_MTD_DOC2001PLUS is not set CONFIG_MTD_NAND=y -# CONFIG_MTD_NAND_VERIFY_WRITE is not set +CONFIG_MTD_NAND_ECC=y # CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_SM_COMMON is not set # CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_DENALI_SCRATCH_REG_ADDR=0xFF108018 # CONFIG_MTD_NAND_GPIO is not set CONFIG_MTD_NAND_IDS=y # CONFIG_MTD_NAND_DISKONCHIP is not set # CONFIG_MTD_NAND_NANDSIM is not set # CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ALAUDA is not set CONFIG_MTD_NAND_MXC=y # CONFIG_MTD_ONENAND is not set @@ -528,24 +606,31 @@ CONFIG_MTD_UBI_BEB_RESERVE=1 # CONFIG_PARPORT is not set # CONFIG_BLK_DEV is not set CONFIG_MISC_DEVICES=y +# CONFIG_AD525X_DPOT is not set # CONFIG_ICS932S401 is not set # CONFIG_ENCLOSURE_SERVICES is not set # CONFIG_ISL29003 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_DS1682 is not set +# CONFIG_TI_DAC7512 is not set # CONFIG_C2PORT is not set # # EEPROM support # CONFIG_EEPROM_AT24=y +# CONFIG_EEPROM_AT25 is not set # CONFIG_EEPROM_LEGACY is not set # CONFIG_EEPROM_MAX6875 is not set # CONFIG_EEPROM_93CX6 is not set +# CONFIG_IWMC3200TOP is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # CONFIG_SCSI_DMA is not set @@ -577,6 +662,7 @@ CONFIG_SMSC_PHY=y # CONFIG_NATIONAL_PHY is not set # CONFIG_STE10XP is not set # CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MICREL_PHY is not set # CONFIG_FIXED_PHY is not set # CONFIG_MDIO_BITBANG is not set CONFIG_NET_ETHERNET=y @@ -584,6 +670,7 @@ CONFIG_MII=y # CONFIG_AX88796 is not set # CONFIG_SMC91X is not set # CONFIG_DM9000 is not set +# CONFIG_ENC28J60 is not set # CONFIG_ETHOC is not set # CONFIG_SMC911X is not set CONFIG_SMSC911X=y @@ -598,18 +685,29 @@ CONFIG_DNET=y # CONFIG_B44 is not set # CONFIG_CS89x0 is not set # CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set # CONFIG_KS8851_MLL is not set CONFIG_FEC=y # CONFIG_FEC2 is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set CONFIG_WLAN=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_HOSTAP is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers # + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_IPHETH is not set # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -622,12 +720,80 @@ CONFIG_WLAN=y # # Input device support # -# CONFIG_INPUT is not set +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ADP5588 is not set +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_QT2160 is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_GPIO is not set +# CONFIG_KEYBOARD_TCA6416 is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_LM8323 is not set +# CONFIG_KEYBOARD_MAX7359 is not set +# CONFIG_KEYBOARD_IMX is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_AD7877 is not set +# CONFIG_TOUCHSCREEN_AD7879_I2C is not set +# CONFIG_TOUCHSCREEN_AD7879_SPI is not set +# CONFIG_TOUCHSCREEN_AD7879 is not set +# CONFIG_TOUCHSCREEN_DYNAPRO is not set +# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set +# CONFIG_TOUCHSCREEN_EETI is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_MCS5000 is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_WM97XX is not set +# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set +CONFIG_TOUCHSCREEN_MC13783=y +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set +# CONFIG_TOUCHSCREEN_W90X900 is not set +# CONFIG_INPUT_MISC is not set # # Hardware I/O ports # -# CONFIG_SERIO is not set +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set # CONFIG_GAMEPORT is not set # @@ -636,6 +802,7 @@ CONFIG_WLAN=y # CONFIG_VT is not set CONFIG_DEVKMEM=y # CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_N_GSM is not set # # Serial drivers @@ -652,10 +819,14 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y # # Non-8250 serial port support # +# CONFIG_SERIAL_MAX3100 is not set CONFIG_SERIAL_IMX=y CONFIG_SERIAL_IMX_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set @@ -682,29 +853,40 @@ CONFIG_I2C_HELPER_AUTO=y CONFIG_I2C_IMX=y # CONFIG_I2C_OCORES is not set # CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set # # External I2C/SMBus adapter drivers # # CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set # # Other I2C/SMBus bus drivers # # CONFIG_I2C_PCA_PLATFORM is not set # CONFIG_I2C_STUB is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_DS1682 is not set -# CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set -# CONFIG_SPI is not set +CONFIG_SPI=y +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_BITBANG=y +CONFIG_SPI_GPIO=y +CONFIG_SPI_IMX=y +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_DESIGNWARE is not set + +# +# SPI Protocol Masters +# +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set # # PPS support @@ -717,13 +899,17 @@ CONFIG_GPIOLIB=y # # Memory mapped GPIO expanders: # +# CONFIG_GPIO_IT8761E is not set # # I2C GPIO expanders: # +# CONFIG_GPIO_MAX7300 is not set # CONFIG_GPIO_MAX732X is not set # CONFIG_GPIO_PCA953X is not set # CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_WM8350 is not set +# CONFIG_GPIO_ADP5588 is not set # # PCI GPIO expanders: @@ -732,6 +918,9 @@ CONFIG_GPIOLIB=y # # SPI GPIO expanders: # +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set # # AC97 GPIO expanders: @@ -741,6 +930,7 @@ CONFIG_W1=y # # 1-wire Bus Masters # +# CONFIG_W1_MASTER_DS2490 is not set # CONFIG_W1_MASTER_DS2482 is not set CONFIG_W1_MASTER_MXC=y # CONFIG_W1_MASTER_DS1WM is not set @@ -755,7 +945,15 @@ CONFIG_W1_SLAVE_THERM=y # CONFIG_W1_SLAVE_DS2433 is not set # CONFIG_W1_SLAVE_DS2760 is not set # CONFIG_W1_SLAVE_BQ27000 is not set -# CONFIG_POWER_SUPPLY is not set +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +# CONFIG_PDA_POWER is not set +# CONFIG_WM8350_POWER is not set +# CONFIG_TEST_POWER is not set +# CONFIG_BATTERY_DS2760 is not set +# CONFIG_BATTERY_DS2782 is not set +# CONFIG_BATTERY_BQ27x00 is not set +# CONFIG_BATTERY_MAX17040 is not set # CONFIG_HWMON is not set # CONFIG_THERMAL is not set # CONFIG_WATCHDOG is not set @@ -769,11 +967,14 @@ CONFIG_SSB_POSSIBLE=y # # Multifunction device drivers # -# CONFIG_MFD_CORE is not set +CONFIG_MFD_CORE=y +# CONFIG_MFD_88PM860X is not set # CONFIG_MFD_SM501 is not set # CONFIG_MFD_ASIC3 is not set # CONFIG_HTC_EGPIO is not set # CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_UCB1400_CORE is not set # CONFIG_TPS65010 is not set # CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set @@ -781,23 +982,33 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_TC6387XB is not set # CONFIG_MFD_TC6393XB is not set # CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set CONFIG_MFD_WM8350=y CONFIG_MFD_WM8350_CONFIG_MODE_0=y CONFIG_MFD_WM8352_CONFIG_MODE_0=y CONFIG_MFD_WM8350_I2C=y +# CONFIG_MFD_WM8994 is not set # CONFIG_MFD_PCF50633 is not set +CONFIG_MFD_MC13783=y # CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_AB4500_CORE is not set CONFIG_REGULATOR=y # CONFIG_REGULATOR_DEBUG is not set +# CONFIG_REGULATOR_DUMMY is not set # CONFIG_REGULATOR_FIXED_VOLTAGE is not set # CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set # CONFIG_REGULATOR_USERSPACE_CONSUMER is not set # CONFIG_REGULATOR_BQ24022 is not set # CONFIG_REGULATOR_MAX1586 is not set +# CONFIG_REGULATOR_MAX8649 is not set +# CONFIG_REGULATOR_MAX8660 is not set CONFIG_REGULATOR_WM8350=y # CONFIG_REGULATOR_LP3971 is not set +# CONFIG_REGULATOR_MC13783 is not set # CONFIG_REGULATOR_TPS65023 is not set # CONFIG_REGULATOR_TPS6507X is not set CONFIG_MEDIA_SUPPORT=y @@ -815,6 +1026,15 @@ CONFIG_VIDEO_MEDIA=y # # Multimedia drivers # +CONFIG_IR_CORE=y +CONFIG_VIDEO_IR=y +CONFIG_RC_MAP=y +CONFIG_IR_NEC_DECODER=y +CONFIG_IR_RC5_DECODER=y +CONFIG_IR_RC6_DECODER=y +CONFIG_IR_JVC_DECODER=y +CONFIG_IR_SONY_DECODER=y +# CONFIG_IR_IMON is not set # CONFIG_MEDIA_ATTACH is not set CONFIG_MEDIA_TUNER=y # CONFIG_MEDIA_TUNER_CUSTOMISE is not set @@ -834,20 +1054,75 @@ CONFIG_VIDEO_CAPTURE_DRIVERS=y # CONFIG_VIDEO_ADV_DEBUG is not set # CONFIG_VIDEO_FIXED_MINOR_RANGES is not set CONFIG_VIDEO_HELPER_CHIPS_AUTO=y -# CONFIG_VIDEO_VIVI is not set +CONFIG_VIDEO_IR_I2C=y # CONFIG_VIDEO_SAA5246A is not set # CONFIG_VIDEO_SAA5249 is not set CONFIG_SOC_CAMERA=y CONFIG_SOC_CAMERA_MT9M001=y CONFIG_SOC_CAMERA_MT9M111=y CONFIG_SOC_CAMERA_MT9T031=y +# CONFIG_SOC_CAMERA_MT9T112 is not set CONFIG_SOC_CAMERA_MT9V022=y +# CONFIG_SOC_CAMERA_RJ54N1 is not set CONFIG_SOC_CAMERA_TW9910=y # CONFIG_SOC_CAMERA_PLATFORM is not set CONFIG_SOC_CAMERA_OV772X=y +# CONFIG_SOC_CAMERA_OV9640 is not set CONFIG_MX3_VIDEO=y CONFIG_VIDEO_MX3=y # CONFIG_VIDEO_SH_MOBILE_CEU is not set +CONFIG_V4L_USB_DRIVERS=y +# CONFIG_USB_VIDEO_CLASS is not set +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +CONFIG_USB_GSPCA=m +# CONFIG_USB_M5602 is not set +# CONFIG_USB_STV06XX is not set +# CONFIG_USB_GL860 is not set +# CONFIG_USB_GSPCA_BENQ is not set +# CONFIG_USB_GSPCA_CONEX is not set +# CONFIG_USB_GSPCA_CPIA1 is not set +# CONFIG_USB_GSPCA_ETOMS is not set +# CONFIG_USB_GSPCA_FINEPIX is not set +# CONFIG_USB_GSPCA_JEILINJ is not set +# CONFIG_USB_GSPCA_MARS is not set +# CONFIG_USB_GSPCA_MR97310A is not set +# CONFIG_USB_GSPCA_OV519 is not set +# CONFIG_USB_GSPCA_OV534 is not set +# CONFIG_USB_GSPCA_OV534_9 is not set +# CONFIG_USB_GSPCA_PAC207 is not set +# CONFIG_USB_GSPCA_PAC7302 is not set +# CONFIG_USB_GSPCA_PAC7311 is not set +# CONFIG_USB_GSPCA_SN9C2028 is not set +# CONFIG_USB_GSPCA_SN9C20X is not set +# CONFIG_USB_GSPCA_SONIXB is not set +# CONFIG_USB_GSPCA_SONIXJ is not set +# CONFIG_USB_GSPCA_SPCA500 is not set +# CONFIG_USB_GSPCA_SPCA501 is not set +# CONFIG_USB_GSPCA_SPCA505 is not set +# CONFIG_USB_GSPCA_SPCA506 is not set +# CONFIG_USB_GSPCA_SPCA508 is not set +# CONFIG_USB_GSPCA_SPCA561 is not set +# CONFIG_USB_GSPCA_SQ905 is not set +# CONFIG_USB_GSPCA_SQ905C is not set +# CONFIG_USB_GSPCA_STK014 is not set +# CONFIG_USB_GSPCA_STV0680 is not set +# CONFIG_USB_GSPCA_SUNPLUS is not set +# CONFIG_USB_GSPCA_T613 is not set +# CONFIG_USB_GSPCA_TV8532 is not set +# CONFIG_USB_GSPCA_VC032X is not set +# CONFIG_USB_GSPCA_ZC3XX is not set +# CONFIG_VIDEO_PVRUSB2 is not set +# CONFIG_VIDEO_HDPVR is not set +# CONFIG_VIDEO_EM28XX is not set +# CONFIG_VIDEO_CX231XX is not set +# CONFIG_VIDEO_USBVISION is not set +# CONFIG_USB_ET61X251 is not set +# CONFIG_USB_SN9C102 is not set +# CONFIG_USB_ZC0301 is not set +# CONFIG_USB_ZR364XX is not set +# CONFIG_USB_STKWEBCAM is not set +# CONFIG_USB_S2255 is not set +# CONFIG_V4L_MEM2MEM_DRIVERS is not set # CONFIG_RADIO_ADAPTERS is not set # CONFIG_DAB is not set @@ -879,6 +1154,7 @@ CONFIG_FB_CFB_IMAGEBLIT=y # Frame buffer hardware drivers # # CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_TMIO is not set # CONFIG_FB_VIRTUAL is not set # CONFIG_FB_METRONOME is not set # CONFIG_FB_MB862XX is not set @@ -891,8 +1167,193 @@ CONFIG_FB_MX3=y # # CONFIG_DISPLAY_SUPPORT is not set # CONFIG_LOGO is not set -# CONFIG_SOUND is not set -# CONFIG_USB_SUPPORT is not set +CONFIG_SOUND=y +# CONFIG_SOUND_OSS_CORE is not set +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_JACK=y +# CONFIG_SND_SEQUENCER is not set +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +# CONFIG_SND_HRTIMER is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +CONFIG_SND_DRIVERS=y +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set +CONFIG_SND_ARM=y +CONFIG_SND_SPI=y +CONFIG_SND_USB=y +# CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_UA101 is not set +# CONFIG_SND_USB_CAIAQ is not set +CONFIG_SND_SOC=y +CONFIG_SND_SOC_AC97_BUS=y +CONFIG_SND_IMX_SOC=y +CONFIG_SND_MXC_SOC_SSI=y +CONFIG_SND_MXC_SOC_WM1133_EV1=y +CONFIG_SND_SOC_I2C_AND_SPI=y +# CONFIG_SND_SOC_ALL_CODECS is not set +CONFIG_SND_SOC_WM8350=y +# CONFIG_SOUND_PRIME is not set +CONFIG_AC97_BUS=y +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HIDRAW is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_HID_PID is not set +# CONFIG_USB_HIDDEV is not set + +# +# Special HID drivers +# +# CONFIG_HID_3M_PCT is not set +# CONFIG_HID_A4TECH is not set +# CONFIG_HID_APPLE is not set +# CONFIG_HID_BELKIN is not set +# CONFIG_HID_CANDO is not set +# CONFIG_HID_CHERRY is not set +# CONFIG_HID_CHICONY is not set +# CONFIG_HID_PRODIKEYS is not set +# CONFIG_HID_CYPRESS is not set +# CONFIG_HID_DRAGONRISE is not set +# CONFIG_HID_EGALAX is not set +# CONFIG_HID_EZKEY is not set +# CONFIG_HID_KYE is not set +# CONFIG_HID_GYRATION is not set +# CONFIG_HID_TWINHAN is not set +# CONFIG_HID_KENSINGTON is not set +# CONFIG_HID_LOGITECH is not set +# CONFIG_HID_MICROSOFT is not set +# CONFIG_HID_MOSART is not set +# CONFIG_HID_MONTEREY is not set +# CONFIG_HID_NTRIG is not set +# CONFIG_HID_ORTEK is not set +# CONFIG_HID_PANTHERLORD is not set +# CONFIG_HID_PETALYNX is not set +# CONFIG_HID_PICOLCD is not set +# CONFIG_HID_QUANTA is not set +# CONFIG_HID_ROCCAT_KONE is not set +# CONFIG_HID_SAMSUNG is not set +# CONFIG_HID_SONY is not set +# CONFIG_HID_STANTUM is not set +# CONFIG_HID_SUNPLUS is not set +# CONFIG_HID_GREENASIA is not set +# CONFIG_HID_SMARTJOYPLUS is not set +# CONFIG_HID_TOPSEED is not set +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_ZEROPLUS is not set +# CONFIG_HID_ZYDACRON is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_MON is not set +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +# CONFIG_USB_EHCI_TT_NEWSCHED is not set +CONFIG_USB_EHCI_MXC=y +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HWA_HCD is not set +# CONFIG_USB_MUSB_HDRC is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set + +# +# USB port drivers +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_GADGET is not set + +# +# OTG and related infrastructure +# +CONFIG_USB_OTG_UTILS=y +# CONFIG_USB_GPIO_VBUS is not set +CONFIG_USB_ULPI=y +# CONFIG_NOP_USB_XCEIV is not set CONFIG_MMC=y # CONFIG_MMC_DEBUG is not set # CONFIG_MMC_UNSAFE_RESUME is not set @@ -909,21 +1370,119 @@ CONFIG_MMC_BLOCK_BOUNCE=y # MMC/SD/SDIO Host Controller Drivers # # CONFIG_MMC_SDHCI is not set -# CONFIG_MMC_AT91 is not set -# CONFIG_MMC_ATMELMCI is not set CONFIG_MMC_MXC=y +# CONFIG_MMC_SPI is not set # CONFIG_MEMSTICK is not set -# CONFIG_NEW_LEDS is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +# CONFIG_LEDS_PCA9532 is not set +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_GPIO_PLATFORM=y +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_WM8350 is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_PWM is not set +CONFIG_LEDS_REGULATOR=y +# CONFIG_LEDS_BD2802 is not set +# CONFIG_LEDS_LT3593 is not set +CONFIG_LEDS_TRIGGERS=y + +# +# LED Triggers +# +# CONFIG_LEDS_TRIGGER_TIMER is not set +# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_GPIO is not set +# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set + +# +# iptables trigger is under Netfilter config (LED target) +# # CONFIG_ACCESSIBILITY is not set CONFIG_RTC_LIB=y -# CONFIG_RTC_CLASS is not set +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_MXC is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_V3020 is not set +# CONFIG_RTC_DRV_WM8350 is not set + +# +# on-CPU RTC drivers +# +CONFIG_RTC_DRV_MC13783=y CONFIG_DMADEVICES=y +# CONFIG_DMADEVICES_DEBUG is not set # # DMA Devices # CONFIG_MX3_IPU=y CONFIG_MX3_IPU_IRQS=4 +# CONFIG_TIMB_DMA is not set CONFIG_DMA_ENGINE=y # @@ -934,10 +1493,6 @@ CONFIG_DMA_ENGINE=y # CONFIG_DMATEST is not set # CONFIG_AUXDISPLAY is not set # CONFIG_UIO is not set - -# -# TI VLYNQ -# # CONFIG_STAGING is not set # @@ -1018,6 +1573,7 @@ CONFIG_UBIFS_FS=y CONFIG_UBIFS_FS_LZO=y CONFIG_UBIFS_FS_ZLIB=y # CONFIG_UBIFS_FS_DEBUG is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -1044,6 +1600,7 @@ CONFIG_SUNRPC_GSS=y CONFIG_RPCSEC_GSS_KRB5=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1054,13 +1611,52 @@ CONFIG_RPCSEC_GSS_KRB5=y # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y -# CONFIG_NLS is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set # CONFIG_DLM is not set # # Kernel hacking # -# CONFIG_PRINTK_TIME is not set +CONFIG_PRINTK_TIME=y # CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_FRAME_WARN=1024 @@ -1070,7 +1666,7 @@ CONFIG_FRAME_WARN=1024 # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_LATENCYTOP is not set @@ -1078,10 +1674,12 @@ CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_TRACING_SUPPORT=y # CONFIG_FTRACE is not set +# CONFIG_ATOMIC64_SELFTEST is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y CONFIG_ARM_UNWIND=y # CONFIG_DEBUG_USER is not set +# CONFIG_OC_ETM is not set # # Security options @@ -1089,7 +1687,11 @@ CONFIG_ARM_UNWIND=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # @@ -1210,3 +1812,4 @@ CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y CONFIG_NLATTR=y +CONFIG_GENERIC_ATOMIC64=y diff --git a/arch/arm/mach-msm/acpuclock-arm11.c b/arch/arm/mach-msm/acpuclock-arm11.c index af5e85b91d02..6ca42fd5ce2a 100644 --- a/arch/arm/mach-msm/acpuclock-arm11.c +++ b/arch/arm/mach-msm/acpuclock-arm11.c @@ -17,7 +17,6 @@ * */ -#include <linux/version.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/list.h> diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c index 9cb1276ab749..c57210f4f06a 100644 --- a/arch/arm/mach-msm/clock.c +++ b/arch/arm/mach-msm/clock.c @@ -14,7 +14,6 @@ * */ -#include <linux/version.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/module.h> diff --git a/arch/arm/mach-msm/dma.c b/arch/arm/mach-msm/dma.c index d029d1f5f9e2..02cae5e2951c 100644 --- a/arch/arm/mach-msm/dma.c +++ b/arch/arm/mach-msm/dma.c @@ -17,6 +17,7 @@ #include <linux/err.h> #include <linux/io.h> #include <linux/interrupt.h> +#include <linux/completion.h> #include <mach/dma.h> #define MSM_DMOV_CHANNEL_COUNT 16 diff --git a/arch/arm/mach-mx2/Kconfig b/arch/arm/mach-mx2/Kconfig index 742fd4e6dcb9..3f756f4ad050 100644 --- a/arch/arm/mach-mx2/Kconfig +++ b/arch/arm/mach-mx2/Kconfig @@ -59,6 +59,7 @@ endchoice config MACH_CPUIMX27 bool "Eukrea CPUIMX27 module" depends on MACH_MX27 + select MXC_ULPI if USB_ULPI help Include support for Eukrea CPUIMX27 platform. This includes specific configurations for the module and its peripherals. @@ -67,9 +68,16 @@ config MACH_EUKREA_CPUIMX27_USESDHC2 bool "CPUIMX27 integrates SDHC2 module" depends on MACH_CPUIMX27 help - This adds support for the internal SDHC2 used on CPUIMX27 used + This adds support for the internal SDHC2 used on CPUIMX27 for wifi or eMMC. +config MACH_EUKREA_CPUIMX27_USEUART4 + bool "CPUIMX27 integrates UART4 module" + depends on MACH_CPUIMX27 + help + This adds support for the internal UART4 used on CPUIMX27 + for bluetooth. + choice prompt "Baseboard" depends on MACH_CPUIMX27 diff --git a/arch/arm/mach-mx2/devices.c b/arch/arm/mach-mx2/devices.c index a0aeb8a4adc1..4df2e340652c 100644 --- a/arch/arm/mach-mx2/devices.c +++ b/arch/arm/mach-mx2/devices.c @@ -501,3 +501,21 @@ struct platform_device mx21_usbhc_device = { }; #endif +static struct resource imx_kpp_resources[] = { + { + .start = MX2x_KPP_BASE_ADDR, + .end = MX2x_KPP_BASE_ADDR + 0xf, + .flags = IORESOURCE_MEM + }, { + .start = MX2x_INT_KPP, + .end = MX2x_INT_KPP, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device imx_kpp_device = { + .name = "imx-keypad", + .id = -1, + .num_resources = ARRAY_SIZE(imx_kpp_resources), + .resource = imx_kpp_resources, +}; diff --git a/arch/arm/mach-mx2/devices.h b/arch/arm/mach-mx2/devices.h index 84ed51380174..cd4977990bd4 100644 --- a/arch/arm/mach-mx2/devices.h +++ b/arch/arm/mach-mx2/devices.h @@ -40,3 +40,4 @@ extern struct platform_device mxc_spi_device2; extern struct platform_device mx21_usbhc_device; extern struct platform_device imx_ssi_device0; extern struct platform_device imx_ssi_device1; +extern struct platform_device imx_kpp_device; diff --git a/arch/arm/mach-mx2/eukrea_mbimx27-baseboard.c b/arch/arm/mach-mx2/eukrea_mbimx27-baseboard.c index f3b169d5245f..80f626803401 100644 --- a/arch/arm/mach-mx2/eukrea_mbimx27-baseboard.c +++ b/arch/arm/mach-mx2/eukrea_mbimx27-baseboard.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Eric Benard - eric@eukrea.com + * Copyright (C) 2009-2010 Eric Benard - eric@eukrea.com * * Based on pcm970-baseboard.c which is : * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de) @@ -24,6 +24,9 @@ #include <linux/platform_device.h> #include <linux/spi/spi.h> #include <linux/spi/ads7846.h> +#include <linux/backlight.h> +#include <video/platform_lcd.h> +#include <linux/input/matrix_keypad.h> #include <asm/mach/arch.h> @@ -33,6 +36,9 @@ #include <mach/hardware.h> #include <mach/mmc.h> #include <mach/imx-uart.h> +#include <mach/spi.h> +#include <mach/ssi.h> +#include <mach/audmux.h> #include "devices.h" @@ -48,10 +54,12 @@ static int eukrea_mbimx27_pins[] = { PE10_PF_UART3_CTS, PE11_PF_UART3_RTS, /* UART4 */ +#if !defined(MACH_EUKREA_CPUIMX27_USEUART4) PB26_AF_UART4_RTS, PB28_AF_UART4_TXD, PB29_AF_UART4_CTS, PB31_AF_UART4_RXD, +#endif /* SDHC1*/ PE18_PF_SD1_D0, PE19_PF_SD1_D1, @@ -84,10 +92,28 @@ static int eukrea_mbimx27_pins[] = { PA30_PF_CONTRAST, PA31_PF_OE_ACD, /* SPI1 */ - PD28_PF_CSPI1_SS0, PD29_PF_CSPI1_SCLK, PD30_PF_CSPI1_MISO, PD31_PF_CSPI1_MOSI, + /* SSI4 */ +#if defined(CONFIG_SND_SOC_EUKREA_TLV320) + PC16_PF_SSI4_FS, + PC17_PF_SSI4_RXD | GPIO_PUEN, + PC18_PF_SSI4_TXD | GPIO_PUEN, + PC19_PF_SSI4_CLK, +#endif +}; + +static const uint32_t eukrea_mbimx27_keymap[] = { + KEY(0, 0, KEY_UP), + KEY(0, 1, KEY_DOWN), + KEY(1, 0, KEY_RIGHT), + KEY(1, 1, KEY_LEFT), +}; + +static struct matrix_keymap_data eukrea_mbimx27_keymap_data = { + .keymap = eukrea_mbimx27_keymap, + .keymap_size = ARRAY_SIZE(eukrea_mbimx27_keymap), }; static struct gpio_led gpio_leds[] = { @@ -103,12 +129,6 @@ static struct gpio_led gpio_leds[] = { .active_low = 1, .gpio = GPIO_PORTF | 19, }, - { - .name = "backlight", - .default_trigger = "backlight", - .active_low = 0, - .gpio = GPIO_PORTE | 5, - }, }; static struct gpio_led_platform_data gpio_led_info = { @@ -127,7 +147,7 @@ static struct platform_device leds_gpio = { static struct imx_fb_videomode eukrea_mbimx27_modes[] = { { .mode = { - .name = "CMO-QGVA", + .name = "CMO-QVGA", .refresh = 60, .xres = 320, .yres = 240, @@ -141,6 +161,38 @@ static struct imx_fb_videomode eukrea_mbimx27_modes[] = { }, .pcr = 0xFAD08B80, .bpp = 16, + }, { + .mode = { + .name = "DVI-VGA", + .refresh = 60, + .xres = 640, + .yres = 480, + .pixclock = 32000, + .hsync_len = 1, + .left_margin = 35, + .right_margin = 0, + .vsync_len = 1, + .upper_margin = 7, + .lower_margin = 0, + }, + .pcr = 0xFA208B80, + .bpp = 16, + }, { + .mode = { + .name = "DVI-SVGA", + .refresh = 60, + .xres = 800, + .yres = 600, + .pixclock = 25000, + .hsync_len = 1, + .left_margin = 35, + .right_margin = 0, + .vsync_len = 1, + .upper_margin = 7, + .lower_margin = 0, + }, + .pcr = 0xFA208B80, + .bpp = 16, }, }; @@ -153,6 +205,47 @@ static struct imx_fb_platform_data eukrea_mbimx27_fb_data = { .dmacr = 0x00040060, }; +static void eukrea_mbimx27_bl_set_intensity(int intensity) +{ + if (intensity) + gpio_direction_output(GPIO_PORTE | 5, 1); + else + gpio_direction_output(GPIO_PORTE | 5, 0); +} + +static struct generic_bl_info eukrea_mbimx27_bl_info = { + .name = "eukrea_mbimx27-bl", + .max_intensity = 0xff, + .default_intensity = 0xff, + .set_bl_intensity = eukrea_mbimx27_bl_set_intensity, +}; + +static struct platform_device eukrea_mbimx27_bl_dev = { + .name = "generic-bl", + .id = 1, + .dev = { + .platform_data = &eukrea_mbimx27_bl_info, + }, +}; + +static void eukrea_mbimx27_lcd_power_set(struct plat_lcd_data *pd, + unsigned int power) +{ + if (power) + gpio_direction_output(GPIO_PORTA | 25, 1); + else + gpio_direction_output(GPIO_PORTA | 25, 0); +} + +static struct plat_lcd_data eukrea_mbimx27_lcd_power_data = { + .set_power = eukrea_mbimx27_lcd_power_set, +}; + +static struct platform_device eukrea_mbimx27_lcd_powerdev = { + .name = "platform-lcd", + .dev.platform_data = &eukrea_mbimx27_lcd_power_data, +}; + static struct imxuart_platform_data uart_pdata[] = { { .flags = IMXUART_HAVE_RTSCTS, @@ -160,9 +253,12 @@ static struct imxuart_platform_data uart_pdata[] = { { .flags = IMXUART_HAVE_RTSCTS, }, + { + .flags = IMXUART_HAVE_RTSCTS, + }, }; -#if defined(CONFIG_TOUCHSCREEN_ADS7846) +#if defined(CONFIG_TOUCHSCREEN_ADS7846) \ || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) #define ADS7846_PENDOWN (GPIO_PORTD | 25) @@ -173,7 +269,6 @@ static void ads7846_dev_init(void) printk(KERN_ERR "can't get ads746 pen down GPIO\n"); return; } - gpio_direction_input(ADS7846_PENDOWN); } @@ -186,7 +281,9 @@ static struct ads7846_platform_data ads7846_config __initdata = { .get_pendown_state = ads7846_get_pendown_state, .keep_vref_on = 1, }; +#endif +#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE) static struct spi_board_info eukrea_mbimx27_spi_board_info[] __initdata = { [0] = { .modalias = "ads7846", @@ -199,6 +296,12 @@ static struct spi_board_info eukrea_mbimx27_spi_board_info[] __initdata = { }, }; +static struct i2c_board_info eukrea_mbimx27_i2c_devices[] = { + { + I2C_BOARD_INFO("tlv320aic23", 0x1a), + }, +}; + static int eukrea_mbimx27_spi_cs[] = {GPIO_PORTD | 28}; static struct spi_imx_master eukrea_mbimx27_spi_0_data = { @@ -211,6 +314,14 @@ static struct platform_device *platform_devices[] __initdata = { &leds_gpio, }; +static struct imxmmc_platform_data sdhc_pdata = { + .dat3_card_detect = 1, +}; + +struct imx_ssi_platform_data eukrea_mbimx27_ssi_pdata = { + .flags = IMX_SSI_DMA | IMX_SSI_USE_I2S_SLAVE, +}; + /* * system init for baseboard usage. Will be called by cpuimx27 init. * @@ -222,21 +333,51 @@ void __init eukrea_mbimx27_baseboard_init(void) mxc_gpio_setup_multiple_pins(eukrea_mbimx27_pins, ARRAY_SIZE(eukrea_mbimx27_pins), "MBIMX27"); +#if defined(CONFIG_SND_SOC_EUKREA_TLV320) + /* SSI unit master I2S codec connected to SSI_PINS_4*/ + mxc_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0, + MXC_AUDMUX_V1_PCR_SYN | + MXC_AUDMUX_V1_PCR_TFSDIR | + MXC_AUDMUX_V1_PCR_TCLKDIR | + MXC_AUDMUX_V1_PCR_RFSDIR | + MXC_AUDMUX_V1_PCR_RCLKDIR | + MXC_AUDMUX_V1_PCR_TFCSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4) | + MXC_AUDMUX_V1_PCR_RFCSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4) | + MXC_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4) + ); + mxc_audmux_v1_configure_port(MX27_AUDMUX_HPCR3_SSI_PINS_4, + MXC_AUDMUX_V1_PCR_SYN | + MXC_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0) + ); +#endif + mxc_register_device(&mxc_uart_device1, &uart_pdata[0]); mxc_register_device(&mxc_uart_device2, &uart_pdata[1]); +#if !defined(MACH_EUKREA_CPUIMX27_USEUART4) + mxc_register_device(&mxc_uart_device3, &uart_pdata[2]); +#endif mxc_register_device(&mxc_fb_device, &eukrea_mbimx27_fb_data); - mxc_register_device(&mxc_sdhc_device0, NULL); + mxc_register_device(&mxc_sdhc_device0, &sdhc_pdata); + + i2c_register_board_info(0, eukrea_mbimx27_i2c_devices, + ARRAY_SIZE(eukrea_mbimx27_i2c_devices)); + + mxc_register_device(&imx_ssi_device0, &eukrea_mbimx27_ssi_pdata); -#if defined(CONFIG_TOUCHSCREEN_ADS7846) +#if defined(CONFIG_TOUCHSCREEN_ADS7846) \ || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) - /* SPI and ADS7846 Touchscreen controler init */ - mxc_gpio_mode(GPIO_PORTD | 28 | GPIO_GPIO | GPIO_OUT); + /* ADS7846 Touchscreen controller init */ mxc_gpio_mode(GPIO_PORTD | 25 | GPIO_GPIO | GPIO_IN); + ads7846_dev_init(); +#endif + +#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE) + /* SPI_CS0 init */ + mxc_gpio_mode(GPIO_PORTD | 28 | GPIO_GPIO | GPIO_OUT); mxc_register_device(&mxc_spi_device0, &eukrea_mbimx27_spi_0_data); spi_register_board_info(eukrea_mbimx27_spi_board_info, ARRAY_SIZE(eukrea_mbimx27_spi_board_info)); - ads7846_dev_init(); #endif /* Leds configuration */ @@ -244,6 +385,14 @@ void __init eukrea_mbimx27_baseboard_init(void) mxc_gpio_mode(GPIO_PORTF | 19 | GPIO_GPIO | GPIO_OUT); /* Backlight */ mxc_gpio_mode(GPIO_PORTE | 5 | GPIO_GPIO | GPIO_OUT); + gpio_request(GPIO_PORTE | 5, "backlight"); + platform_device_register(&eukrea_mbimx27_bl_dev); + /* LCD Reset */ + mxc_gpio_mode(GPIO_PORTA | 25 | GPIO_GPIO | GPIO_OUT); + gpio_request(GPIO_PORTA | 25, "lcd_enable"); + platform_device_register(&eukrea_mbimx27_lcd_powerdev); + + mxc_register_device(&imx_kpp_device, &eukrea_mbimx27_keymap_data); platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); } diff --git a/arch/arm/mach-mx2/mach-cpuimx27.c b/arch/arm/mach-mx2/mach-cpuimx27.c index 1f616dcaabc9..dc2dca3ff9b7 100644 --- a/arch/arm/mach-mx2/mach-cpuimx27.c +++ b/arch/arm/mach-mx2/mach-cpuimx27.c @@ -26,6 +26,9 @@ #include <linux/mtd/physmap.h> #include <linux/platform_device.h> #include <linux/serial_8250.h> +#include <linux/usb/otg.h> +#include <linux/usb/ulpi.h> +#include <linux/fsl_devices.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> @@ -39,6 +42,8 @@ #include <mach/iomux-mx27.h> #include <mach/imx-uart.h> #include <mach/mxc_nand.h> +#include <mach/mxc_ehci.h> +#include <mach/ulpi.h> #include "devices.h" @@ -49,10 +54,12 @@ static int eukrea_cpuimx27_pins[] = { PE14_PF_UART1_CTS, PE15_PF_UART1_RTS, /* UART4 */ +#if defined(MACH_EUKREA_CPUIMX27_USEUART4) PB26_AF_UART4_RTS, PB28_AF_UART4_TXD, PB29_AF_UART4_CTS, PB31_AF_UART4_RXD, +#endif /* FEC */ PD0_AIN_FEC_TXD0, PD1_AIN_FEC_TXD1, @@ -76,19 +83,47 @@ static int eukrea_cpuimx27_pins[] = { PD17_PF_I2C_DATA, PD18_PF_I2C_CLK, /* SDHC2 */ +#if defined(CONFIG_MACH_EUKREA_CPUIMX27_USESDHC2) PB4_PF_SD2_D0, PB5_PF_SD2_D1, PB6_PF_SD2_D2, PB7_PF_SD2_D3, PB8_PF_SD2_CMD, PB9_PF_SD2_CLK, +#endif #if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE) /* Quad UART's IRQ */ - GPIO_PORTD | 22 | GPIO_GPIO | GPIO_IN, - GPIO_PORTD | 23 | GPIO_GPIO | GPIO_IN, - GPIO_PORTD | 27 | GPIO_GPIO | GPIO_IN, - GPIO_PORTD | 30 | GPIO_GPIO | GPIO_IN, + GPIO_PORTB | 22 | GPIO_GPIO | GPIO_IN, + GPIO_PORTB | 23 | GPIO_GPIO | GPIO_IN, + GPIO_PORTB | 27 | GPIO_GPIO | GPIO_IN, + GPIO_PORTB | 30 | GPIO_GPIO | GPIO_IN, #endif + /* OTG */ + PC7_PF_USBOTG_DATA5, + PC8_PF_USBOTG_DATA6, + PC9_PF_USBOTG_DATA0, + PC10_PF_USBOTG_DATA2, + PC11_PF_USBOTG_DATA1, + PC12_PF_USBOTG_DATA4, + PC13_PF_USBOTG_DATA3, + PE0_PF_USBOTG_NXT, + PE1_PF_USBOTG_STP, + PE2_PF_USBOTG_DIR, + PE24_PF_USBOTG_CLK, + PE25_PF_USBOTG_DATA7, + /* USBH2 */ + PA0_PF_USBH2_CLK, + PA1_PF_USBH2_DIR, + PA2_PF_USBH2_DATA7, + PA3_PF_USBH2_NXT, + PA4_PF_USBH2_STP, + PD19_AF_USBH2_DATA4, + PD20_AF_USBH2_DATA3, + PD21_AF_USBH2_DATA6, + PD22_AF_USBH2_DATA0, + PD23_AF_USBH2_DATA2, + PD24_AF_USBH2_DATA1, + PD26_AF_USBH2_DATA5, }; static struct physmap_flash_data eukrea_cpuimx27_flash_data = { @@ -127,6 +162,8 @@ static struct mxc_nand_platform_data eukrea_cpuimx27_nand_board_info = { static struct platform_device *platform_devices[] __initdata = { &eukrea_cpuimx27_nor_mtd_device, &mxc_fec_device, + &mxc_wdt, + &mxc_w1_master_device, }; static struct imxi2c_platform_data eukrea_cpuimx27_i2c_1_data = { @@ -182,6 +219,36 @@ static struct platform_device serial_device = { }; #endif +static struct mxc_usbh_platform_data otg_pdata = { + .portsc = MXC_EHCI_MODE_ULPI, + .flags = MXC_EHCI_INTERFACE_DIFF_UNI, +}; + +static struct mxc_usbh_platform_data usbh2_pdata = { + .portsc = MXC_EHCI_MODE_ULPI, + .flags = MXC_EHCI_INTERFACE_DIFF_UNI, +}; + +static struct fsl_usb2_platform_data otg_device_pdata = { + .operating_mode = FSL_USB2_DR_DEVICE, + .phy_mode = FSL_USB2_PHY_ULPI, +}; + +static int otg_mode_host; + +static int __init eukrea_cpuimx27_otg_mode(char *options) +{ + if (!strcmp(options, "host")) + otg_mode_host = 1; + else if (!strcmp(options, "device")) + otg_mode_host = 0; + else + pr_info("otg_mode neither \"host\" nor \"device\". " + "Defaulting to device\n"); + return 0; +} +__setup("otg_mode=", eukrea_cpuimx27_otg_mode); + static void __init eukrea_cpuimx27_init(void) { mxc_gpio_setup_multiple_pins(eukrea_cpuimx27_pins, @@ -202,6 +269,8 @@ static void __init eukrea_cpuimx27_init(void) #if defined(CONFIG_MACH_EUKREA_CPUIMX27_USESDHC2) /* SDHC2 can be used for Wifi */ mxc_register_device(&mxc_sdhc_device1, NULL); +#endif +#if defined(MACH_EUKREA_CPUIMX27_USEUART4) /* in which case UART4 is also used for Bluetooth */ mxc_register_device(&mxc_uart_device3, &uart_pdata[1]); #endif @@ -210,6 +279,22 @@ static void __init eukrea_cpuimx27_init(void) platform_device_register(&serial_device); #endif +#if defined(CONFIG_USB_ULPI) + if (otg_mode_host) { + otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, + USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); + + mxc_register_device(&mxc_otg_host, &otg_pdata); + } + + usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, + USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); + + mxc_register_device(&mxc_usbh2, &usbh2_pdata); +#endif + if (!otg_mode_host) + mxc_register_device(&mxc_otg_udc_device, &otg_device_pdata); + #ifdef CONFIG_MACH_EUKREA_MBIMX27_BASEBOARD eukrea_mbimx27_baseboard_init(); #endif diff --git a/arch/arm/mach-mx2/mach-pca100.c b/arch/arm/mach-mx2/mach-pca100.c index a87422ed4ff5..7651d0ef4666 100644 --- a/arch/arm/mach-mx2/mach-pca100.c +++ b/arch/arm/mach-mx2/mach-pca100.c @@ -253,6 +253,7 @@ static struct imxmmc_platform_data sdhc_pdata = { .exit = pca100_sdhc2_exit, }; +#if defined(CONFIG_USB_ULPI) static int otg_phy_init(struct platform_device *pdev) { gpio_set_value(OTG_PHY_CS_GPIO, 0); @@ -276,6 +277,7 @@ static struct mxc_usbh_platform_data usbh2_pdata = { .portsc = MXC_EHCI_MODE_ULPI, .flags = MXC_EHCI_INTERFACE_DIFF_UNI, }; +#endif static struct fsl_usb2_platform_data otg_device_pdata = { .operating_mode = FSL_USB2_DR_DEVICE, diff --git a/arch/arm/mach-mx25/clock.c b/arch/arm/mach-mx25/clock.c index 155014993b13..f44d65765b9a 100644 --- a/arch/arm/mach-mx25/clock.c +++ b/arch/arm/mach-mx25/clock.c @@ -217,7 +217,7 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK("mxc_pwm.1", NULL, pwm2_clk) _REGISTER_CLOCK("mxc_pwm.2", NULL, pwm3_clk) _REGISTER_CLOCK("mxc_pwm.3", NULL, pwm4_clk) - _REGISTER_CLOCK("mxc-keypad", NULL, kpp_clk) + _REGISTER_CLOCK("imx-keypad", NULL, kpp_clk) _REGISTER_CLOCK("mx25-adc", NULL, tsc_clk) _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk) _REGISTER_CLOCK("imx-i2c.1", NULL, i2c_clk) diff --git a/arch/arm/mach-mx25/devices.c b/arch/arm/mach-mx25/devices.c index 3a405fa400eb..fd331d04ea0d 100644 --- a/arch/arm/mach-mx25/devices.c +++ b/arch/arm/mach-mx25/devices.c @@ -515,3 +515,23 @@ struct platform_device mxc_wdt = { .num_resources = ARRAY_SIZE(mxc_wdt_resources), .resource = mxc_wdt_resources, }; + +static struct resource mx25_kpp_resources[] = { + { + .start = MX25_KPP_BASE_ADDR, + .end = MX25_KPP_BASE_ADDR + 0xf, + .flags = IORESOURCE_MEM, + }, + { + .start = MX25_INT_KPP, + .end = MX25_INT_KPP, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device mx25_kpp_device = { + .name = "imx-keypad", + .id = -1, + .num_resources = ARRAY_SIZE(mx25_kpp_resources), + .resource = mx25_kpp_resources, +}; diff --git a/arch/arm/mach-mx25/devices.h b/arch/arm/mach-mx25/devices.h index cee12c0a0be6..8247fd451118 100644 --- a/arch/arm/mach-mx25/devices.h +++ b/arch/arm/mach-mx25/devices.h @@ -22,3 +22,4 @@ extern struct platform_device mxc_nand_device; extern struct platform_device mx25_rtc_device; extern struct platform_device mx25_fb_device; extern struct platform_device mxc_wdt; +extern struct platform_device mx25_kpp_device; diff --git a/arch/arm/mach-mx25/mach-mx25pdk.c b/arch/arm/mach-mx25/mach-mx25pdk.c index 83d74109e7d8..4a57f68860cb 100644 --- a/arch/arm/mach-mx25/mach-mx25pdk.c +++ b/arch/arm/mach-mx25/mach-mx25pdk.c @@ -24,6 +24,7 @@ #include <linux/gpio.h> #include <linux/fec.h> #include <linux/platform_device.h> +#include <linux/input/matrix_keypad.h> #include <mach/hardware.h> #include <asm/mach-types.h> @@ -80,6 +81,16 @@ static struct pad_desc mx25pdk_pads[] = { MX25_PAD_LSCLK__LSCLK, MX25_PAD_OE_ACD__OE_ACD, MX25_PAD_CONTRAST__CONTRAST, + + /* Keypad */ + MX25_PAD_KPP_ROW0__KPP_ROW0, + MX25_PAD_KPP_ROW1__KPP_ROW1, + MX25_PAD_KPP_ROW2__KPP_ROW2, + MX25_PAD_KPP_ROW3__KPP_ROW3, + MX25_PAD_KPP_COL0__KPP_COL0, + MX25_PAD_KPP_COL1__KPP_COL1, + MX25_PAD_KPP_COL2__KPP_COL2, + MX25_PAD_KPP_COL3__KPP_COL3, }; static struct fec_platform_data mx25_fec_pdata = { @@ -137,6 +148,30 @@ static struct imx_fb_platform_data mx25pdk_fb_pdata = { .dmacr = 0x00020010, }; +static const uint32_t mx25pdk_keymap[] = { + KEY(0, 0, KEY_UP), + KEY(0, 1, KEY_DOWN), + KEY(0, 2, KEY_VOLUMEDOWN), + KEY(0, 3, KEY_HOME), + KEY(1, 0, KEY_RIGHT), + KEY(1, 1, KEY_LEFT), + KEY(1, 2, KEY_ENTER), + KEY(1, 3, KEY_VOLUMEUP), + KEY(2, 0, KEY_F6), + KEY(2, 1, KEY_F8), + KEY(2, 2, KEY_F9), + KEY(2, 3, KEY_F10), + KEY(3, 0, KEY_F1), + KEY(3, 1, KEY_F2), + KEY(3, 2, KEY_F3), + KEY(3, 3, KEY_POWER), +}; + +static struct matrix_keymap_data mx25pdk_keymap_data = { + .keymap = mx25pdk_keymap, + .keymap_size = ARRAY_SIZE(mx25pdk_keymap), +}; + static void __init mx25pdk_init(void) { mxc_iomux_v3_setup_multiple_pads(mx25pdk_pads, @@ -150,6 +185,7 @@ static void __init mx25pdk_init(void) mx25pdk_fec_reset(); mxc_register_device(&mx25_fec_device, &mx25_fec_pdata); + mxc_register_device(&mx25_kpp_device, &mx25pdk_keymap_data); } static void __init mx25pdk_timer_init(void) diff --git a/arch/arm/mach-mx3/mach-mx31lilly.c b/arch/arm/mach-mx3/mach-mx31lilly.c index d3d5877c750e..4b330844ccc5 100644 --- a/arch/arm/mach-mx3/mach-mx31lilly.c +++ b/arch/arm/mach-mx3/mach-mx31lilly.c @@ -115,6 +115,8 @@ static struct platform_device physmap_flash_device = { /* USB */ +#if defined(CONFIG_USB_ULPI) + #define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \ PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU) @@ -244,10 +246,20 @@ static struct mxc_usbh_platform_data usbh2_pdata = { .flags = MXC_EHCI_POWER_PINS_ENABLED, }; -static struct platform_device *devices[] __initdata = { - &smsc91x_device, - &physmap_flash_device, -}; +static void lilly1131_usb_init(void) +{ + usbotg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, + USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); + usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, + USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); + + mxc_register_device(&mxc_usbh1, &usbh1_pdata); + mxc_register_device(&mxc_usbh2, &usbh2_pdata); +} + +#else +static inline void lilly1131_usb_init(void) {} +#endif /* CONFIG_USB_ULPI */ /* SPI */ @@ -277,6 +289,12 @@ static struct spi_board_info mc13783_dev __initdata = { .bus_num = 1, .chip_select = 0, .platform_data = &mc13783_pdata, + .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3), +}; + +static struct platform_device *devices[] __initdata = { + &smsc91x_device, + &physmap_flash_device, }; static int mx31lilly_baseboard; @@ -321,13 +339,7 @@ static void __init mx31lilly_board_init(void) platform_add_devices(devices, ARRAY_SIZE(devices)); /* USB */ - usbotg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, - USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); - usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, - USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); - - mxc_register_device(&mxc_usbh1, &usbh1_pdata); - mxc_register_device(&mxc_usbh2, &usbh2_pdata); + lilly1131_usb_init(); } static void __init mx31lilly_timer_init(void) diff --git a/arch/arm/mach-mx3/mach-pcm037.c b/arch/arm/mach-mx3/mach-pcm037.c index cce410662383..bb6c056854e9 100644 --- a/arch/arm/mach-mx3/mach-pcm037.c +++ b/arch/arm/mach-mx3/mach-pcm037.c @@ -545,6 +545,7 @@ static struct platform_device pcm970_sja1000 = { .num_resources = ARRAY_SIZE(pcm970_sja1000_resources), }; +#if defined(CONFIG_USB_ULPI) static struct mxc_usbh_platform_data otg_pdata = { .portsc = MXC_EHCI_MODE_ULPI, .flags = MXC_EHCI_INTERFACE_DIFF_UNI, @@ -554,6 +555,7 @@ static struct mxc_usbh_platform_data usbh2_pdata = { .portsc = MXC_EHCI_MODE_ULPI, .flags = MXC_EHCI_INTERFACE_DIFF_UNI, }; +#endif static struct fsl_usb2_platform_data otg_device_pdata = { .operating_mode = FSL_USB2_DR_DEVICE, @@ -581,7 +583,6 @@ __setup("otg_mode=", pcm037_otg_mode); static void __init mxc_board_init(void) { int ret; - u32 tmp; mxc_iomux_set_gpr(MUX_PGP_UH2, 1); diff --git a/arch/arm/mach-mx3/mach-pcm043.c b/arch/arm/mach-mx3/mach-pcm043.c index 78d9185a9d4b..8071b7281c4b 100644 --- a/arch/arm/mach-mx3/mach-pcm043.c +++ b/arch/arm/mach-mx3/mach-pcm043.c @@ -309,6 +309,7 @@ static struct mxc_nand_platform_data pcm037_nand_board_info = { .hw_ecc = 1, }; +#if defined(CONFIG_USB_ULPI) static struct mxc_usbh_platform_data otg_pdata = { .portsc = MXC_EHCI_MODE_UTMI, .flags = MXC_EHCI_INTERFACE_DIFF_UNI, @@ -319,6 +320,7 @@ static struct mxc_usbh_platform_data usbh1_pdata = { .flags = MXC_EHCI_INTERFACE_SINGLE_UNI | MXC_EHCI_INTERNAL_PHY | MXC_EHCI_IPPUE_DOWN, }; +#endif static struct fsl_usb2_platform_data otg_device_pdata = { .operating_mode = FSL_USB2_DR_DEVICE, diff --git a/arch/arm/mach-mx5/board-mx51_babbage.c b/arch/arm/mach-mx5/board-mx51_babbage.c index ed885f9d7b73..19cde6896302 100644 --- a/arch/arm/mach-mx5/board-mx51_babbage.c +++ b/arch/arm/mach-mx5/board-mx51_babbage.c @@ -12,6 +12,7 @@ #include <linux/init.h> #include <linux/platform_device.h> +#include <linux/i2c.h> #include <linux/gpio.h> #include <linux/delay.h> #include <linux/io.h> @@ -21,6 +22,7 @@ #include <mach/hardware.h> #include <mach/imx-uart.h> #include <mach/iomux-mx51.h> +#include <mach/i2c.h> #include <mach/mxc_ehci.h> #include <asm/irq.h> @@ -64,6 +66,18 @@ static struct pad_desc mx51babbage_pads[] = { MX51_PAD_EIM_D27__UART3_RTS, MX51_PAD_EIM_D24__UART3_CTS, + /* I2C1 */ + MX51_PAD_EIM_D16__I2C1_SDA, + MX51_PAD_EIM_D19__I2C1_SCL, + + /* I2C2 */ + MX51_PAD_KEY_COL4__I2C2_SCL, + MX51_PAD_KEY_COL5__I2C2_SDA, + + /* HSI2C */ + MX51_PAD_I2C1_CLK__HSI2C_CLK, + MX51_PAD_I2C1_DAT__HSI2C_DAT, + /* USB HOST1 */ MX51_PAD_USBH1_CLK__USBH1_CLK, MX51_PAD_USBH1_DIR__USBH1_DIR, @@ -99,6 +113,14 @@ static inline void mxc_init_imx_uart(void) } #endif /* SERIAL_IMX */ +static struct imxi2c_platform_data babbage_i2c_data = { + .bitrate = 100000, +}; + +static struct imxi2c_platform_data babbage_hsi2c_data = { + .bitrate = 400000, +}; + static int gpio_usbh1_active(void) { struct pad_desc usbh1stp_gpio = MX51_PAD_USBH1_STP__GPIO_1_27; @@ -230,6 +252,10 @@ static void __init mxc_board_init(void) mxc_init_imx_uart(); platform_add_devices(devices, ARRAY_SIZE(devices)); + mxc_register_device(&mxc_i2c_device0, &babbage_i2c_data); + mxc_register_device(&mxc_i2c_device1, &babbage_i2c_data); + mxc_register_device(&mxc_hsi2c_device, &babbage_hsi2c_data); + if (otg_mode_host) mxc_register_device(&mxc_usbdr_host_device, &dr_utmi_config); else { diff --git a/arch/arm/mach-mx5/clock-mx51.c b/arch/arm/mach-mx5/clock-mx51.c index d9f612d3370e..fd24092154b5 100644 --- a/arch/arm/mach-mx5/clock-mx51.c +++ b/arch/arm/mach-mx5/clock-mx51.c @@ -798,6 +798,14 @@ DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET, DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_OFFSET, NULL, NULL, &ipg_clk, NULL); +/* I2C */ +DEFINE_CLOCK(i2c1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG9_OFFSET, + NULL, NULL, &ipg_clk, NULL); +DEFINE_CLOCK(i2c2_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG10_OFFSET, + NULL, NULL, &ipg_clk, NULL); +DEFINE_CLOCK(hsi2c_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG11_OFFSET, + NULL, NULL, &ipg_clk, NULL); + /* FEC */ DEFINE_CLOCK(fec_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG12_OFFSET, NULL, NULL, &ipg_clk, NULL); @@ -815,6 +823,9 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk) _REGISTER_CLOCK(NULL, "gpt", gpt_clk) _REGISTER_CLOCK("fec.0", NULL, fec_clk) + _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk) + _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk) + _REGISTER_CLOCK("imx-i2c.2", NULL, hsi2c_clk) _REGISTER_CLOCK("mxc-ehci.0", "usb", usboh3_clk) _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", ahb_clk) _REGISTER_CLOCK("mxc-ehci.1", "usb", usboh3_clk) diff --git a/arch/arm/mach-mx5/devices.c b/arch/arm/mach-mx5/devices.c index 7130449aacdc..ede4fcbc7e80 100644 --- a/arch/arm/mach-mx5/devices.c +++ b/arch/arm/mach-mx5/devices.c @@ -93,6 +93,64 @@ struct platform_device mxc_fec_device = { .resource = mxc_fec_resources, }; +static struct resource mxc_i2c0_resources[] = { + { + .start = MX51_I2C1_BASE_ADDR, + .end = MX51_I2C1_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, { + .start = MX51_MXC_INT_I2C1, + .end = MX51_MXC_INT_I2C1, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device mxc_i2c_device0 = { + .name = "imx-i2c", + .id = 0, + .num_resources = ARRAY_SIZE(mxc_i2c0_resources), + .resource = mxc_i2c0_resources, +}; + +static struct resource mxc_i2c1_resources[] = { + { + .start = MX51_I2C2_BASE_ADDR, + .end = MX51_I2C2_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, { + .start = MX51_MXC_INT_I2C2, + .end = MX51_MXC_INT_I2C2, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device mxc_i2c_device1 = { + .name = "imx-i2c", + .id = 1, + .num_resources = ARRAY_SIZE(mxc_i2c1_resources), + .resource = mxc_i2c1_resources, +}; + +static struct resource mxc_hsi2c_resources[] = { + { + .start = MX51_HSI2C_DMA_BASE_ADDR, + .end = MX51_HSI2C_DMA_BASE_ADDR + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = MX51_MXC_INT_HS_I2C, + .end = MX51_MXC_INT_HS_I2C, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device mxc_hsi2c_device = { + .name = "imx-i2c", + .id = 2, + .num_resources = ARRAY_SIZE(mxc_hsi2c_resources), + .resource = mxc_hsi2c_resources +}; + static u64 usb_dma_mask = DMA_BIT_MASK(32); static struct resource usbotg_resources[] = { diff --git a/arch/arm/mach-mx5/devices.h b/arch/arm/mach-mx5/devices.h index c879ae71cd5b..a853933682e7 100644 --- a/arch/arm/mach-mx5/devices.h +++ b/arch/arm/mach-mx5/devices.h @@ -6,3 +6,6 @@ extern struct platform_device mxc_usbdr_host_device; extern struct platform_device mxc_usbh1_device; extern struct platform_device mxc_usbdr_udc_device; extern struct platform_device mxc_wdt; +extern struct platform_device mxc_i2c_device0; +extern struct platform_device mxc_i2c_device1; +extern struct platform_device mxc_hsi2c_device; diff --git a/arch/arm/mach-nomadik/clock.c b/arch/arm/mach-nomadik/clock.c index 2c471fc451d7..f035f4185274 100644 --- a/arch/arm/mach-nomadik/clock.c +++ b/arch/arm/mach-nomadik/clock.c @@ -32,7 +32,10 @@ void clk_disable(struct clk *clk) } EXPORT_SYMBOL(clk_disable); -/* We have a fixed clock alone, for now */ +static struct clk clk_24 = { + .rate = 2400000, +}; + static struct clk clk_48 = { .rate = 48 * 1000 * 1000, }; @@ -50,6 +53,8 @@ static struct clk clk_default; } static struct clk_lookup lookups[] = { + CLK(&clk_24, "mtu0"), + CLK(&clk_24, "mtu1"), CLK(&clk_48, "uart0"), CLK(&clk_48, "uart1"), CLK(&clk_default, "gpio.0"), @@ -59,10 +64,8 @@ static struct clk_lookup lookups[] = { CLK(&clk_default, "rng"), }; -static int __init clk_init(void) +int __init clk_init(void) { clkdev_add_table(lookups, ARRAY_SIZE(lookups)); return 0; } - -arch_initcall(clk_init); diff --git a/arch/arm/mach-nomadik/clock.h b/arch/arm/mach-nomadik/clock.h index 5563985a2cc7..78da2e7c3985 100644 --- a/arch/arm/mach-nomadik/clock.h +++ b/arch/arm/mach-nomadik/clock.h @@ -11,3 +11,5 @@ struct clk { unsigned long rate; }; + +int __init clk_init(void); diff --git a/arch/arm/mach-nomadik/cpu-8815.c b/arch/arm/mach-nomadik/cpu-8815.c index 91c3c901b469..ac58e3b03b1a 100644 --- a/arch/arm/mach-nomadik/cpu-8815.c +++ b/arch/arm/mach-nomadik/cpu-8815.c @@ -31,6 +31,8 @@ #include <asm/cacheflush.h> #include <asm/hardware/cache-l2x0.h> +#include "clock.h" + #define __MEM_4K_RESOURCE(x) \ .res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM} @@ -143,6 +145,12 @@ void __init cpu8815_init_irq(void) /* This modified VIC cell has two register blocks, at 0 and 0x20 */ vic_init(io_p2v(NOMADIK_IC_BASE + 0x00), IRQ_VIC_START + 0, ~0, 0); vic_init(io_p2v(NOMADIK_IC_BASE + 0x20), IRQ_VIC_START + 32, ~0, 0); + + /* + * Init clocks here so that they are available for system timer + * initialization. + */ + clk_init(); } /* diff --git a/arch/arm/mach-omap2/usb-ehci.c b/arch/arm/mach-omap2/usb-ehci.c index c68f799e83c5..d72d1ac30333 100644 --- a/arch/arm/mach-omap2/usb-ehci.c +++ b/arch/arm/mach-omap2/usb-ehci.c @@ -20,6 +20,8 @@ #include <linux/delay.h> #include <linux/platform_device.h> #include <linux/clk.h> +#include <linux/dma-mapping.h> + #include <asm/io.h> #include <plat/mux.h> diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index f2b88c5fe142..1de8d171c6e9 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig @@ -7,6 +7,7 @@ config ARCH_SH7367 select CPU_V6 select HAVE_CLK select COMMON_CLKDEV + select SH_CLK_CPG select GENERIC_CLOCKEVENTS config ARCH_SH7377 @@ -14,6 +15,7 @@ config ARCH_SH7377 select CPU_V7 select HAVE_CLK select COMMON_CLKDEV + select SH_CLK_CPG select GENERIC_CLOCKEVENTS config ARCH_SH7372 @@ -21,6 +23,7 @@ config ARCH_SH7372 select CPU_V7 select HAVE_CLK select COMMON_CLKDEV + select SH_CLK_CPG select GENERIC_CLOCKEVENTS comment "SH-Mobile Board Type" @@ -39,6 +42,7 @@ config MACH_AP4EVB bool "AP4EVB board" depends on ARCH_SH7372 select ARCH_REQUIRE_GPIOLIB + select SH_LCD_MIPI_DSI comment "SH-Mobile System Configuration" @@ -76,6 +80,15 @@ config SH_TIMER_CMT help This enables build of the CMT timer driver. +config SH_TIMER_TMU + bool "TMU timer driver" + default y + help + This enables build of the TMU timer driver. + endmenu +config SH_CLK_CPG + bool + endif diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile index 6d385d371c33..5e16b4c69222 100644 --- a/arch/arm/mach-shmobile/Makefile +++ b/arch/arm/mach-shmobile/Makefile @@ -3,12 +3,12 @@ # # Common objects -obj-y := timer.o console.o +obj-y := timer.o console.o clock.o # CPU objects obj-$(CONFIG_ARCH_SH7367) += setup-sh7367.o clock-sh7367.o intc-sh7367.o -obj-$(CONFIG_ARCH_SH7377) += setup-sh7377.o clock-sh7367.o intc-sh7377.o -obj-$(CONFIG_ARCH_SH7372) += setup-sh7372.o clock-sh7367.o intc-sh7372.o +obj-$(CONFIG_ARCH_SH7377) += setup-sh7377.o clock-sh7377.o intc-sh7377.o +obj-$(CONFIG_ARCH_SH7372) += setup-sh7372.o clock-sh7372.o intc-sh7372.o # Pinmux setup pfc-$(CONFIG_ARCH_SH7367) := pfc-sh7367.o diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index 1c2ec96ce261..bdc4c6bd3108 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c @@ -17,25 +17,44 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include <linux/clk.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/irq.h> #include <linux/platform_device.h> #include <linux/delay.h> +#include <linux/mfd/sh_mobile_sdhi.h> +#include <linux/mmc/host.h> #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> #include <linux/mtd/physmap.h> +#include <linux/mmc/host.h> +#include <linux/mmc/sh_mmcif.h> +#include <linux/i2c.h> +#include <linux/i2c/tsc2007.h> #include <linux/io.h> #include <linux/smsc911x.h> +#include <linux/sh_intc.h> +#include <linux/sh_clk.h> #include <linux/gpio.h> #include <linux/input.h> #include <linux/input/sh_keysc.h> +#include <linux/usb/r8a66597.h> + +#include <sound/sh_fsi.h> + +#include <video/sh_mobile_lcdc.h> +#include <video/sh_mipi_dsi.h> + #include <mach/common.h> +#include <mach/irqs.h> #include <mach/sh7372.h> + #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> +#include <asm/mach/time.h> /* * Address Interface BusWidth note @@ -80,12 +99,44 @@ */ /* - * KEYSC + * LCD / IRQ / KEYSC / IrDA + * + * IRQ = IRQ26 (TS), IRQ27 (VIO), IRQ28 (TouchScreen) + * LCD = 2nd LCDC * - * SW43 KEYSC - * ------------------------- - * ON enable - * OFF disable + * | SW43 | + * SW3 | ON | OFF | + * -------------+-----------------------+---------------+ + * ON | KEY / IrDA | LCD | + * OFF | KEY / IrDA / IRQ | IRQ | + */ + +/* + * USB + * + * J7 : 1-2 MAX3355E VBUS + * 2-3 DC 5.0V + * + * S39: bit2: off + */ + +/* + * FSI/FSMI + * + * SW41 : ON : SH-Mobile AP4 Audio Mode + * : OFF : Bluetooth Audio Mode + */ + +/* + * MMC (CN7) + * + * J22 : 1-2: 1.8v for MMC + * 2-3: 3.3v for MMC + * SW1 : OFF + * SW33: bit1: OFF + * bit2: ON + * bit3: ON + * bit4: X */ /* MTD */ @@ -148,7 +199,7 @@ static struct resource smc911x_resources[] = { .end = 0x16000000 - 1, .flags = IORESOURCE_MEM, }, { - .start = 6, + .start = evt2irq(0x02c0) /* IRQ6A */, .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, }, }; @@ -191,7 +242,7 @@ static struct resource keysc_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = 79, + .start = evt2irq(0x0be0), /* KEYSC_KEY */ .flags = IORESOURCE_IRQ, }, }; @@ -206,7 +257,52 @@ static struct platform_device keysc_device = { }, }; +/* SH_MMCIF */ +static struct resource sh_mmcif_resources[] = { + [0] = { + .name = "SH_MMCIF", + .start = 0xE6BD0000, + .end = 0xE6BD00FF, + .flags = IORESOURCE_MEM, + }, + [1] = { + /* MMC ERR */ + .start = 198, + .flags = IORESOURCE_IRQ, + }, + [2] = { + /* MMC NOR */ + .start = 199, + .flags = IORESOURCE_IRQ, + }, +}; + +struct sh_mmcif_plat_data sh_mmcif_plat = { + .sup_pclk = 0, + .ocr = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34, + .caps = MMC_CAP_4_BIT_DATA | + MMC_CAP_8_BIT_DATA | + MMC_CAP_NEEDS_POLL, +}; + +static struct platform_device sh_mmcif_device = { + .name = "sh_mmcif", + .id = 0, + .dev = { + .dma_mask = NULL, + .coherent_dma_mask = 0xffffffff, + .platform_data = &sh_mmcif_plat, + }, + .num_resources = ARRAY_SIZE(sh_mmcif_resources), + .resource = sh_mmcif_resources, +}; + /* SDHI0 */ +static struct sh_mobile_sdhi_info sdhi0_info = { + .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, + .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, +}; + static struct resource sdhi0_resources[] = { [0] = { .name = "SDHI0", @@ -215,7 +311,7 @@ static struct resource sdhi0_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = 96, + .start = evt2irq(0x0e00) /* SDHI0 */, .flags = IORESOURCE_IRQ, }, }; @@ -225,6 +321,206 @@ static struct platform_device sdhi0_device = { .num_resources = ARRAY_SIZE(sdhi0_resources), .resource = sdhi0_resources, .id = 0, + .dev = { + .platform_data = &sdhi0_info, + }, +}; + +/* SDHI1 */ +static struct sh_mobile_sdhi_info sdhi1_info = { + .dma_slave_tx = SHDMA_SLAVE_SDHI1_TX, + .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX, + .tmio_ocr_mask = MMC_VDD_165_195, +}; + +static struct resource sdhi1_resources[] = { + [0] = { + .name = "SDHI1", + .start = 0xe6860000, + .end = 0xe68601ff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = evt2irq(0x0e80), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device sdhi1_device = { + .name = "sh_mobile_sdhi", + .num_resources = ARRAY_SIZE(sdhi1_resources), + .resource = sdhi1_resources, + .id = 1, + .dev = { + .platform_data = &sdhi1_info, + }, +}; + +/* USB1 */ +void usb1_host_port_power(int port, int power) +{ + if (!power) /* only power-on supported for now */ + return; + + /* set VBOUT/PWEN and EXTLP1 in DVSTCTR */ + __raw_writew(__raw_readw(0xE68B0008) | 0x600, 0xE68B0008); +} + +static struct r8a66597_platdata usb1_host_data = { + .on_chip = 1, + .port_power = usb1_host_port_power, +}; + +static struct resource usb1_host_resources[] = { + [0] = { + .name = "USBHS", + .start = 0xE68B0000, + .end = 0xE68B00E6 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = evt2irq(0x1ce0) /* USB1_USB1I0 */, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device usb1_host_device = { + .name = "r8a66597_hcd", + .id = 1, + .dev = { + .dma_mask = NULL, /* not use dma */ + .coherent_dma_mask = 0xffffffff, + .platform_data = &usb1_host_data, + }, + .num_resources = ARRAY_SIZE(usb1_host_resources), + .resource = usb1_host_resources, +}; + +static struct sh_mobile_lcdc_info sh_mobile_lcdc_info = { + .clock_source = LCDC_CLK_PERIPHERAL, /* One of interface clocks */ + .ch[0] = { + .chan = LCDC_CHAN_MAINLCD, + .bpp = 16, + .interface_type = RGB24, + .clock_divider = 1, + .flags = LCDC_FLAGS_DWPOL, + .lcd_cfg = { + .name = "R63302(QHD)", + .xres = 544, + .yres = 961, + .left_margin = 72, + .right_margin = 600, + .hsync_len = 16, + .upper_margin = 8, + .lower_margin = 8, + .vsync_len = 2, + .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT, + }, + .lcd_size_cfg = { + .width = 44, + .height = 79, + }, + } +}; + +static struct resource lcdc_resources[] = { + [0] = { + .name = "LCDC", + .start = 0xfe940000, /* P4-only space */ + .end = 0xfe943fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = intcs_evt2irq(0x580), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device lcdc_device = { + .name = "sh_mobile_lcdc_fb", + .num_resources = ARRAY_SIZE(lcdc_resources), + .resource = lcdc_resources, + .dev = { + .platform_data = &sh_mobile_lcdc_info, + .coherent_dma_mask = ~0, + }, +}; + +static struct resource mipidsi0_resources[] = { + [0] = { + .start = 0xffc60000, + .end = 0xffc68fff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct sh_mipi_dsi_info mipidsi0_info = { + .data_format = MIPI_RGB888, + .lcd_chan = &sh_mobile_lcdc_info.ch[0], +}; + +static struct platform_device mipidsi0_device = { + .name = "sh-mipi-dsi", + .num_resources = ARRAY_SIZE(mipidsi0_resources), + .resource = mipidsi0_resources, + .id = 0, + .dev = { + .platform_data = &mipidsi0_info, + }, +}; + +/* FSI */ +#define IRQ_FSI evt2irq(0x1840) +#define FSIACKCR 0xE6150018 +static void fsiackcr_init(struct clk *clk) +{ + u32 status = __raw_readl(clk->enable_reg); + + /* use external clock */ + status &= ~0x000000ff; + status |= 0x00000080; + __raw_writel(status, clk->enable_reg); +} + +static struct clk_ops fsiackcr_clk_ops = { + .init = fsiackcr_init, +}; + +static struct clk fsiackcr_clk = { + .ops = &fsiackcr_clk_ops, + .enable_reg = (void __iomem *)FSIACKCR, + .rate = 0, /* unknown */ +}; + +struct sh_fsi_platform_info fsi_info = { + .porta_flags = SH_FSI_BRS_INV | + SH_FSI_OUT_SLAVE_MODE | + SH_FSI_IN_SLAVE_MODE | + SH_FSI_OFMT(PCM) | + SH_FSI_IFMT(PCM), +}; + +static struct resource fsi_resources[] = { + [0] = { + .name = "FSI", + .start = 0xFE3C0000, + .end = 0xFE3C0400 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_FSI, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device fsi_device = { + .name = "sh_fsi2", + .id = 0, + .num_resources = ARRAY_SIZE(fsi_resources), + .resource = fsi_resources, + .dev = { + .platform_data = &fsi_info, + }, }; static struct platform_device *ap4evb_devices[] __initdata = { @@ -232,6 +528,38 @@ static struct platform_device *ap4evb_devices[] __initdata = { &smc911x_device, &keysc_device, &sdhi0_device, + &sdhi1_device, + &usb1_host_device, + &lcdc_device, + &mipidsi0_device, + &fsi_device, + &sh_mmcif_device +}; + +/* TouchScreen (Needs SW3 set to OFF) */ +#define IRQ28 evt2irq(0x3380) /* IRQ28A */ +struct tsc2007_platform_data tsc2007_info = { + .model = 2007, + .x_plate_ohms = 180, +}; + +/* I2C */ +static struct i2c_board_info i2c0_devices[] = { + { + I2C_BOARD_INFO("ak4643", 0x13), + }, +}; + +static struct i2c_board_info i2c1_devices[] = { + { + I2C_BOARD_INFO("r2025sd", 0x32), + }, + { + I2C_BOARD_INFO("tsc2007", 0x48), + .type = "tsc2007", + .platform_data = &tsc2007_info, + .irq = IRQ28, + }, }; static struct map_desc ap4evb_io_desc[] __initdata = { @@ -250,14 +578,71 @@ static void __init ap4evb_map_io(void) { iotable_init(ap4evb_io_desc, ARRAY_SIZE(ap4evb_io_desc)); - /* setup early devices, clocks and console here as well */ + /* setup early devices and console here as well */ sh7372_add_early_devices(); - sh7367_clock_init(); /* use g3 clocks for now */ shmobile_setup_console(); } +/* This function will disappear when we switch to (runtime) PM */ +static int __init ap4evb_init_display_clk(void) +{ + struct clk *lcdc_clk; + struct clk *dsitx_clk; + int ret; + + lcdc_clk = clk_get(&lcdc_device.dev, "sh_mobile_lcdc_fb.0"); + if (IS_ERR(lcdc_clk)) + return PTR_ERR(lcdc_clk); + + dsitx_clk = clk_get(&mipidsi0_device.dev, "sh-mipi-dsi.0"); + if (IS_ERR(dsitx_clk)) { + ret = PTR_ERR(dsitx_clk); + goto eclkdsitxget; + } + + ret = clk_enable(lcdc_clk); + if (ret < 0) + goto eclklcdcon; + + ret = clk_enable(dsitx_clk); + if (ret < 0) + goto eclkdsitxon; + + return 0; + +eclkdsitxon: + clk_disable(lcdc_clk); +eclklcdcon: + clk_put(dsitx_clk); +eclkdsitxget: + clk_put(lcdc_clk); + + return ret; +} + +device_initcall(ap4evb_init_display_clk); + +/* + * FIXME !! + * + * gpio_no_direction is quick_hack. + * + * current gpio frame work doesn't have + * the method to control only pull up/down/free. + * this function should be replaced by correct gpio function + */ +static void __init gpio_no_direction(u32 addr) +{ + __raw_writeb(0x00, addr); +} + +#define GPIO_PORT9CR 0xE6051009 +#define GPIO_PORT10CR 0xE605100A + static void __init ap4evb_init(void) { + struct clk *clk; + sh7372_pinmux_init(); /* enable SCIFA0 */ @@ -318,16 +703,102 @@ static void __init ap4evb_init(void) gpio_request(GPIO_FN_SDHID0_1, NULL); gpio_request(GPIO_FN_SDHID0_0, NULL); + /* enable TouchScreen */ + gpio_request(GPIO_FN_IRQ28_123, NULL); + set_irq_type(IRQ28, IRQ_TYPE_LEVEL_LOW); + + /* MMCIF */ + gpio_request(GPIO_FN_MMCD0_0, NULL); + gpio_request(GPIO_FN_MMCD0_1, NULL); + gpio_request(GPIO_FN_MMCD0_2, NULL); + gpio_request(GPIO_FN_MMCD0_3, NULL); + gpio_request(GPIO_FN_MMCD0_4, NULL); + gpio_request(GPIO_FN_MMCD0_5, NULL); + gpio_request(GPIO_FN_MMCD0_6, NULL); + gpio_request(GPIO_FN_MMCD0_7, NULL); + gpio_request(GPIO_FN_MMCCMD0, NULL); + gpio_request(GPIO_FN_MMCCLK0, NULL); + + /* USB enable */ + gpio_request(GPIO_FN_VBUS0_1, NULL); + gpio_request(GPIO_FN_IDIN_1_18, NULL); + gpio_request(GPIO_FN_PWEN_1_115, NULL); + gpio_request(GPIO_FN_OVCN_1_114, NULL); + gpio_request(GPIO_FN_EXTLP_1, NULL); + gpio_request(GPIO_FN_OVCN2_1, NULL); + + /* setup USB phy */ + __raw_writew(0x8a0a, 0xE6058130); /* USBCR2 */ + + /* enable FSI2 */ + gpio_request(GPIO_FN_FSIAIBT, NULL); + gpio_request(GPIO_FN_FSIAILR, NULL); + gpio_request(GPIO_FN_FSIAISLD, NULL); + gpio_request(GPIO_FN_FSIAOSLD, NULL); + gpio_request(GPIO_PORT161, NULL); + gpio_direction_output(GPIO_PORT161, 0); /* slave */ + + gpio_request(GPIO_PORT9, NULL); + gpio_request(GPIO_PORT10, NULL); + gpio_no_direction(GPIO_PORT9CR); /* FSIAOBT needs no direction */ + gpio_no_direction(GPIO_PORT10CR); /* FSIAOLR needs no direction */ + + /* set SPU2 clock to 119.6 MHz */ + clk = clk_get(NULL, "spu_clk"); + if (!IS_ERR(clk)) { + clk_set_rate(clk, clk_round_rate(clk, 119600000)); + clk_put(clk); + } + + /* change parent of FSI A */ + clk = clk_get(NULL, "fsia_clk"); + if (!IS_ERR(clk)) { + clk_register(&fsiackcr_clk); + clk_set_parent(clk, &fsiackcr_clk); + clk_put(clk); + } + + /* + * set irq priority, to avoid sound chopping + * when NFS rootfs is used + * FSI(3) > SMSC911X(2) + */ + intc_set_priority(IRQ_FSI, 3); + + i2c_register_board_info(0, i2c0_devices, + ARRAY_SIZE(i2c0_devices)); + + i2c_register_board_info(1, i2c1_devices, + ARRAY_SIZE(i2c1_devices)); + + /* SDHI1 */ + gpio_request(GPIO_FN_SDHICMD1, NULL); + gpio_request(GPIO_FN_SDHICLK1, NULL); + gpio_request(GPIO_FN_SDHID1_3, NULL); + gpio_request(GPIO_FN_SDHID1_2, NULL); + gpio_request(GPIO_FN_SDHID1_1, NULL); + gpio_request(GPIO_FN_SDHID1_0, NULL); + sh7372_add_standard_devices(); platform_add_devices(ap4evb_devices, ARRAY_SIZE(ap4evb_devices)); } +static void __init ap4evb_timer_init(void) +{ + sh7372_clock_init(); + shmobile_timer.init(); +} + +static struct sys_timer ap4evb_timer = { + .init = ap4evb_timer_init, +}; + MACHINE_START(AP4EVB, "ap4evb") .phys_io = 0xe6000000, .io_pg_offst = ((0xe6000000) >> 18) & 0xfffc, .map_io = ap4evb_map_io, .init_irq = sh7372_init_irq, .init_machine = ap4evb_init, - .timer = &shmobile_timer, + .timer = &ap4evb_timer, MACHINE_END diff --git a/arch/arm/mach-shmobile/board-g3evm.c b/arch/arm/mach-shmobile/board-g3evm.c index 9247503296c4..a8f20cb0b7d2 100644 --- a/arch/arm/mach-shmobile/board-g3evm.c +++ b/arch/arm/mach-shmobile/board-g3evm.c @@ -37,6 +37,15 @@ #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> +#include <asm/mach/time.h> + +/* + * IrDA + * + * S67: 5bit : ON power + * : 6bit : ON remote control + * OFF IrDA + */ static struct mtd_partition nor_flash_partitions[] = { { @@ -113,7 +122,7 @@ static struct resource usb_host_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = 65, + .start = evt2irq(0xa20), /* USBHS_USHI0 */ .flags = IORESOURCE_IRQ, }, }; @@ -153,7 +162,7 @@ static struct resource keysc_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = 79, + .start = evt2irq(0xbe0), /* KEYSC_KEY */ .flags = IORESOURCE_IRQ, }, }; @@ -209,11 +218,30 @@ static struct platform_device nand_flash_device = { }, }; +static struct resource irda_resources[] = { + [0] = { + .start = 0xE6D00000, + .end = 0xE6D01FD4 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = evt2irq(0x480), /* IRDA */ + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device irda_device = { + .name = "sh_irda", + .resource = irda_resources, + .num_resources = ARRAY_SIZE(irda_resources), +}; + static struct platform_device *g3evm_devices[] __initdata = { &nor_flash_device, &usb_host_device, &keysc_device, &nand_flash_device, + &irda_device, }; static struct map_desc g3evm_io_desc[] __initdata = { @@ -232,9 +260,8 @@ static void __init g3evm_map_io(void) { iotable_init(g3evm_io_desc, ARRAY_SIZE(g3evm_io_desc)); - /* setup early devices, clocks and console here as well */ + /* setup early devices and console here as well */ sh7367_add_early_devices(); - sh7367_clock_init(); shmobile_setup_console(); } @@ -271,9 +298,6 @@ static void __init g3evm_init(void) gpio_request(GPIO_FN_EXTLP, NULL); gpio_request(GPIO_FN_IDIN, NULL); - /* enable clock in SYMSTPCR2 */ - __raw_writel(__raw_readl(0xe6158048) & ~(1 << 22), 0xe6158048); - /* setup USB phy */ __raw_writew(0x0300, 0xe605810a); /* USBCR1 */ __raw_writew(0x00e0, 0xe60581c0); /* CPFCH */ @@ -318,16 +342,32 @@ static void __init g3evm_init(void) /* FOE, FCDE, FSC on dedicated pins */ __raw_writel(__raw_readl(0xe6158048) & ~(1 << 15), 0xe6158048); + /* IrDA */ + gpio_request(GPIO_FN_IRDA_OUT, NULL); + gpio_request(GPIO_FN_IRDA_IN, NULL); + gpio_request(GPIO_FN_IRDA_FIRSEL, NULL); + set_irq_type(evt2irq(0x480), IRQ_TYPE_LEVEL_LOW); + sh7367_add_standard_devices(); platform_add_devices(g3evm_devices, ARRAY_SIZE(g3evm_devices)); } +static void __init g3evm_timer_init(void) +{ + sh7367_clock_init(); + shmobile_timer.init(); +} + +static struct sys_timer g3evm_timer = { + .init = g3evm_timer_init, +}; + MACHINE_START(G3EVM, "g3evm") .phys_io = 0xe6000000, .io_pg_offst = ((0xe6000000) >> 18) & 0xfffc, .map_io = g3evm_map_io, .init_irq = sh7367_init_irq, .init_machine = g3evm_init, - .timer = &shmobile_timer, + .timer = &g3evm_timer, MACHINE_END diff --git a/arch/arm/mach-shmobile/board-g4evm.c b/arch/arm/mach-shmobile/board-g4evm.c index 10673a90be52..e256b7cc4275 100644 --- a/arch/arm/mach-shmobile/board-g4evm.c +++ b/arch/arm/mach-shmobile/board-g4evm.c @@ -30,12 +30,39 @@ #include <linux/io.h> #include <linux/input.h> #include <linux/input/sh_keysc.h> +#include <linux/mfd/sh_mobile_sdhi.h> #include <linux/gpio.h> #include <mach/sh7377.h> #include <mach/common.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> +#include <asm/mach/time.h> + +/* + * SDHI + * + * SDHI0 : card detection is possible + * SDHI1 : card detection is impossible + * + * [G4-MAIN-BOARD] + * JP74 : short # DBG_2V8A for SDHI0 + * JP75 : NC # DBG_3V3A for SDHI0 + * JP76 : NC # DBG_3V3A_SD for SDHI0 + * JP77 : NC # 3V3A_SDIO for SDHI1 + * JP78 : short # DBG_2V8A for SDHI1 + * JP79 : NC # DBG_3V3A for SDHI1 + * JP80 : NC # DBG_3V3A_SD for SDHI1 + * + * [G4-CORE-BOARD] + * S32 : all off # to dissever from G3-CORE_DBG board + * S33 : all off # to dissever from G3-CORE_DBG board + * + * [G3-CORE_DBG-BOARD] + * S1 : all off # to dissever from G3-CORE_DBG board + * S3 : all off # to dissever from G3-CORE_DBG board + * S4 : all off # to dissever from G3-CORE_DBG board + */ static struct mtd_partition nor_flash_partitions[] = { { @@ -112,8 +139,7 @@ static struct resource usb_host_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = 65, - .end = 65, + .start = evt2irq(0x0a20), /* USBHS_USHI0 */ .flags = IORESOURCE_IRQ, }, }; @@ -154,7 +180,7 @@ static struct resource keysc_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = 79, + .start = evt2irq(0x0be0), /* KEYSC_KEY */ .flags = IORESOURCE_IRQ, }, }; @@ -169,10 +195,53 @@ static struct platform_device keysc_device = { }, }; +/* SDHI */ +static struct resource sdhi0_resources[] = { + [0] = { + .name = "SDHI0", + .start = 0xe6d50000, + .end = 0xe6d501ff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = evt2irq(0x0e00), /* SDHI0 */ + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device sdhi0_device = { + .name = "sh_mobile_sdhi", + .num_resources = ARRAY_SIZE(sdhi0_resources), + .resource = sdhi0_resources, + .id = 0, +}; + +static struct resource sdhi1_resources[] = { + [0] = { + .name = "SDHI1", + .start = 0xe6d60000, + .end = 0xe6d601ff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = evt2irq(0x0e80), /* SDHI1 */ + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device sdhi1_device = { + .name = "sh_mobile_sdhi", + .num_resources = ARRAY_SIZE(sdhi1_resources), + .resource = sdhi1_resources, + .id = 1, +}; + static struct platform_device *g4evm_devices[] __initdata = { &nor_flash_device, &usb_host_device, &keysc_device, + &sdhi0_device, + &sdhi1_device, }; static struct map_desc g4evm_io_desc[] __initdata = { @@ -191,12 +260,41 @@ static void __init g4evm_map_io(void) { iotable_init(g4evm_io_desc, ARRAY_SIZE(g4evm_io_desc)); - /* setup early devices, clocks and console here as well */ + /* setup early devices and console here as well */ sh7377_add_early_devices(); - sh7367_clock_init(); /* use g3 clocks for now */ shmobile_setup_console(); } +#define GPIO_SDHID0_D0 0xe60520fc +#define GPIO_SDHID0_D1 0xe60520fd +#define GPIO_SDHID0_D2 0xe60520fe +#define GPIO_SDHID0_D3 0xe60520ff +#define GPIO_SDHICMD0 0xe6052100 + +#define GPIO_SDHID1_D0 0xe6052103 +#define GPIO_SDHID1_D1 0xe6052104 +#define GPIO_SDHID1_D2 0xe6052105 +#define GPIO_SDHID1_D3 0xe6052106 +#define GPIO_SDHICMD1 0xe6052107 + +/* + * FIXME !! + * + * gpio_pull_up is quick_hack. + * + * current gpio frame work doesn't have + * the method to control only pull up/down/free. + * this function should be replaced by correct gpio function + */ +static void __init gpio_pull_up(u32 addr) +{ + u8 data = __raw_readb(addr); + + data &= 0x0F; + data |= 0xC0; + __raw_writeb(data, addr); +} + static void __init g4evm_init(void) { sh7377_pinmux_init(); @@ -229,9 +327,6 @@ static void __init g4evm_init(void) gpio_request(GPIO_FN_EXTLP, NULL); gpio_request(GPIO_FN_IDIN, NULL); - /* enable clock in SMSTPCR3 */ - __raw_writel(__raw_readl(0xe615013c) & ~(1 << 22), 0xe615013c); - /* setup USB phy */ __raw_writew(0x0200, 0xe605810a); /* USBCR1 */ __raw_writew(0x00e0, 0xe60581c0); /* CPFCH */ @@ -253,16 +348,54 @@ static void __init g4evm_init(void) gpio_request(GPIO_FN_PORT71_KEYIN5_PU, NULL); gpio_request(GPIO_FN_PORT72_KEYIN6_PU, NULL); + /* SDHI0 */ + gpio_request(GPIO_FN_SDHICLK0, NULL); + gpio_request(GPIO_FN_SDHICD0, NULL); + gpio_request(GPIO_FN_SDHID0_0, NULL); + gpio_request(GPIO_FN_SDHID0_1, NULL); + gpio_request(GPIO_FN_SDHID0_2, NULL); + gpio_request(GPIO_FN_SDHID0_3, NULL); + gpio_request(GPIO_FN_SDHICMD0, NULL); + gpio_request(GPIO_FN_SDHIWP0, NULL); + gpio_pull_up(GPIO_SDHID0_D0); + gpio_pull_up(GPIO_SDHID0_D1); + gpio_pull_up(GPIO_SDHID0_D2); + gpio_pull_up(GPIO_SDHID0_D3); + gpio_pull_up(GPIO_SDHICMD0); + + /* SDHI1 */ + gpio_request(GPIO_FN_SDHICLK1, NULL); + gpio_request(GPIO_FN_SDHID1_0, NULL); + gpio_request(GPIO_FN_SDHID1_1, NULL); + gpio_request(GPIO_FN_SDHID1_2, NULL); + gpio_request(GPIO_FN_SDHID1_3, NULL); + gpio_request(GPIO_FN_SDHICMD1, NULL); + gpio_pull_up(GPIO_SDHID1_D0); + gpio_pull_up(GPIO_SDHID1_D1); + gpio_pull_up(GPIO_SDHID1_D2); + gpio_pull_up(GPIO_SDHID1_D3); + gpio_pull_up(GPIO_SDHICMD1); + sh7377_add_standard_devices(); platform_add_devices(g4evm_devices, ARRAY_SIZE(g4evm_devices)); } +static void __init g4evm_timer_init(void) +{ + sh7377_clock_init(); + shmobile_timer.init(); +} + +static struct sys_timer g4evm_timer = { + .init = g4evm_timer_init, +}; + MACHINE_START(G4EVM, "g4evm") .phys_io = 0xe6000000, .io_pg_offst = ((0xe6000000) >> 18) & 0xfffc, .map_io = g4evm_map_io, .init_irq = sh7377_init_irq, .init_machine = g4evm_init, - .timer = &shmobile_timer, + .timer = &g4evm_timer, MACHINE_END diff --git a/arch/arm/mach-shmobile/clock-sh7367.c b/arch/arm/mach-shmobile/clock-sh7367.c index bb940c6e4e6c..b6454c9f2abb 100644 --- a/arch/arm/mach-shmobile/clock-sh7367.c +++ b/arch/arm/mach-shmobile/clock-sh7367.c @@ -1,5 +1,5 @@ /* - * Preliminary clock framework support for sh7367 + * SH7367 clock framework support * * Copyright (C) 2010 Magnus Damm * @@ -17,87 +17,342 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include <linux/init.h> -#include <linux/module.h> #include <linux/kernel.h> -#include <linux/list.h> -#include <linux/clk.h> +#include <linux/io.h> +#include <linux/sh_clk.h> +#include <mach/common.h> +#include <asm/clkdev.h> + +/* SH7367 registers */ +#define RTFRQCR 0xe6150000 +#define SYFRQCR 0xe6150004 +#define CMFRQCR 0xe61500E0 +#define VCLKCR1 0xe6150008 +#define VCLKCR2 0xe615000C +#define VCLKCR3 0xe615001C +#define SCLKACR 0xe6150010 +#define SCLKBCR 0xe6150014 +#define SUBUSBCKCR 0xe6158080 +#define SPUCKCR 0xe6150084 +#define MSUCKCR 0xe6150088 +#define MVI3CKCR 0xe6150090 +#define VOUCKCR 0xe6150094 +#define MFCK1CR 0xe6150098 +#define MFCK2CR 0xe615009C +#define PLLC1CR 0xe6150028 +#define PLLC2CR 0xe615002C +#define RTMSTPCR0 0xe6158030 +#define RTMSTPCR2 0xe6158038 +#define SYMSTPCR0 0xe6158040 +#define SYMSTPCR2 0xe6158048 +#define CMMSTPCR0 0xe615804c -struct clk { - const char *name; - unsigned long rate; +/* Fixed 32 KHz root clock from EXTALR pin */ +static struct clk r_clk = { + .rate = 32768, }; -#include <asm/clkdev.h> +/* + * 26MHz default rate for the EXTALB1 root input clock. + * If needed, reset this with clk_set_rate() from the platform code. + */ +struct clk sh7367_extalb1_clk = { + .rate = 26666666, +}; -int __clk_get(struct clk *clk) -{ - return 1; -} -EXPORT_SYMBOL(__clk_get); +/* + * 48MHz default rate for the EXTAL2 root input clock. + * If needed, reset this with clk_set_rate() from the platform code. + */ +struct clk sh7367_extal2_clk = { + .rate = 48000000, +}; -void __clk_put(struct clk *clk) +/* A fixed divide-by-2 block */ +static unsigned long div2_recalc(struct clk *clk) { + return clk->parent->rate / 2; } -EXPORT_SYMBOL(__clk_put); +static struct clk_ops div2_clk_ops = { + .recalc = div2_recalc, +}; + +/* Divide extalb1 by two */ +static struct clk extalb1_div2_clk = { + .ops = &div2_clk_ops, + .parent = &sh7367_extalb1_clk, +}; + +/* Divide extal2 by two */ +static struct clk extal2_div2_clk = { + .ops = &div2_clk_ops, + .parent = &sh7367_extal2_clk, +}; -int clk_enable(struct clk *clk) +/* PLLC1 */ +static unsigned long pllc1_recalc(struct clk *clk) { - return 0; + unsigned long mult = 1; + + if (__raw_readl(PLLC1CR) & (1 << 14)) + mult = (((__raw_readl(RTFRQCR) >> 24) & 0x3f) + 1) * 2; + + return clk->parent->rate * mult; } -EXPORT_SYMBOL(clk_enable); -void clk_disable(struct clk *clk) +static struct clk_ops pllc1_clk_ops = { + .recalc = pllc1_recalc, +}; + +static struct clk pllc1_clk = { + .ops = &pllc1_clk_ops, + .flags = CLK_ENABLE_ON_INIT, + .parent = &extalb1_div2_clk, +}; + +/* Divide PLLC1 by two */ +static struct clk pllc1_div2_clk = { + .ops = &div2_clk_ops, + .parent = &pllc1_clk, +}; + +/* PLLC2 */ +static unsigned long pllc2_recalc(struct clk *clk) { + unsigned long mult = 1; + + if (__raw_readl(PLLC2CR) & (1 << 31)) + mult = (((__raw_readl(PLLC2CR) >> 24) & 0x3f) + 1) * 2; + + return clk->parent->rate * mult; } -EXPORT_SYMBOL(clk_disable); -unsigned long clk_get_rate(struct clk *clk) +static struct clk_ops pllc2_clk_ops = { + .recalc = pllc2_recalc, +}; + +static struct clk pllc2_clk = { + .ops = &pllc2_clk_ops, + .flags = CLK_ENABLE_ON_INIT, + .parent = &extalb1_div2_clk, +}; + +static struct clk *main_clks[] = { + &r_clk, + &sh7367_extalb1_clk, + &sh7367_extal2_clk, + &extalb1_div2_clk, + &extal2_div2_clk, + &pllc1_clk, + &pllc1_div2_clk, + &pllc2_clk, +}; + +static void div4_kick(struct clk *clk) { - return clk ? clk->rate : 0; + unsigned long value; + + /* set KICK bit in SYFRQCR to update hardware setting */ + value = __raw_readl(SYFRQCR); + value |= (1 << 31); + __raw_writel(value, SYFRQCR); } -EXPORT_SYMBOL(clk_get_rate); -/* a static peripheral clock for now - enough to get sh-sci working */ -static struct clk peripheral_clk = { - .name = "peripheral_clk", - .rate = 48000000, +static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18, + 24, 32, 36, 48, 0, 72, 0, 0 }; + +static struct clk_div_mult_table div4_div_mult_table = { + .divisors = divisors, + .nr_divisors = ARRAY_SIZE(divisors), }; -/* a static rclk for now - enough to get sh_cmt working */ -static struct clk r_clk = { - .name = "r_clk", - .rate = 32768, +static struct clk_div4_table div4_table = { + .div_mult_table = &div4_div_mult_table, + .kick = div4_kick, +}; + +enum { DIV4_I, DIV4_G, DIV4_S, DIV4_B, + DIV4_ZX, DIV4_ZT, DIV4_Z, DIV4_ZD, DIV4_HP, + DIV4_ZS, DIV4_ZB, DIV4_ZB3, DIV4_CP, DIV4_NR }; + +#define DIV4(_reg, _bit, _mask, _flags) \ + SH_CLK_DIV4(&pllc1_clk, _reg, _bit, _mask, _flags) + +static struct clk div4_clks[DIV4_NR] = { + [DIV4_I] = DIV4(RTFRQCR, 20, 0x6fff, CLK_ENABLE_ON_INIT), + [DIV4_G] = DIV4(RTFRQCR, 16, 0x6fff, CLK_ENABLE_ON_INIT), + [DIV4_S] = DIV4(RTFRQCR, 12, 0x6fff, CLK_ENABLE_ON_INIT), + [DIV4_B] = DIV4(RTFRQCR, 8, 0x6fff, CLK_ENABLE_ON_INIT), + [DIV4_ZX] = DIV4(SYFRQCR, 20, 0x6fff, 0), + [DIV4_ZT] = DIV4(SYFRQCR, 16, 0x6fff, 0), + [DIV4_Z] = DIV4(SYFRQCR, 12, 0x6fff, 0), + [DIV4_ZD] = DIV4(SYFRQCR, 8, 0x6fff, 0), + [DIV4_HP] = DIV4(SYFRQCR, 4, 0x6fff, 0), + [DIV4_ZS] = DIV4(CMFRQCR, 12, 0x6fff, 0), + [DIV4_ZB] = DIV4(CMFRQCR, 8, 0x6fff, 0), + [DIV4_ZB3] = DIV4(CMFRQCR, 4, 0x6fff, 0), + [DIV4_CP] = DIV4(CMFRQCR, 0, 0x6fff, 0), }; -/* a static usb0 for now - enough to get r8a66597 working */ -static struct clk usb0_clk = { - .name = "usb0", +enum { DIV6_SUB, DIV6_SIUA, DIV6_SIUB, DIV6_MSU, DIV6_SPU, + DIV6_MVI3, DIV6_MF1, DIV6_MF2, + DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_VOU, + DIV6_NR }; + +static struct clk div6_clks[DIV6_NR] = { + [DIV6_SUB] = SH_CLK_DIV6(&sh7367_extal2_clk, SUBUSBCKCR, 0), + [DIV6_SIUA] = SH_CLK_DIV6(&pllc1_div2_clk, SCLKACR, 0), + [DIV6_SIUB] = SH_CLK_DIV6(&pllc1_div2_clk, SCLKBCR, 0), + [DIV6_MSU] = SH_CLK_DIV6(&pllc1_div2_clk, MSUCKCR, 0), + [DIV6_SPU] = SH_CLK_DIV6(&pllc1_div2_clk, SPUCKCR, 0), + [DIV6_MVI3] = SH_CLK_DIV6(&pllc1_div2_clk, MVI3CKCR, 0), + [DIV6_MF1] = SH_CLK_DIV6(&pllc1_div2_clk, MFCK1CR, 0), + [DIV6_MF2] = SH_CLK_DIV6(&pllc1_div2_clk, MFCK2CR, 0), + [DIV6_VCK1] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR1, 0), + [DIV6_VCK2] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR2, 0), + [DIV6_VCK3] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR3, 0), + [DIV6_VOU] = SH_CLK_DIV6(&pllc1_div2_clk, VOUCKCR, 0), }; -/* a static keysc0 clk for now - enough to get sh_keysc working */ -static struct clk keysc0_clk = { - .name = "keysc0", +enum { RTMSTP001, + RTMSTP231, RTMSTP230, RTMSTP229, RTMSTP228, RTMSTP226, + RTMSTP216, RTMSTP206, RTMSTP205, RTMSTP201, + SYMSTP023, SYMSTP007, SYMSTP006, SYMSTP004, + SYMSTP003, SYMSTP002, SYMSTP001, SYMSTP000, + SYMSTP231, SYMSTP229, SYMSTP225, SYMSTP223, SYMSTP222, + SYMSTP215, SYMSTP214, SYMSTP213, SYMSTP211, + CMMSTP003, + MSTP_NR }; + +#define MSTP(_parent, _reg, _bit, _flags) \ + SH_CLK_MSTP32(_parent, _reg, _bit, _flags) + +static struct clk mstp_clks[MSTP_NR] = { + [RTMSTP001] = MSTP(&div6_clks[DIV6_SUB], RTMSTPCR0, 1, 0), /* IIC2 */ + [RTMSTP231] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 31, 0), /* VEU3 */ + [RTMSTP230] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 30, 0), /* VEU2 */ + [RTMSTP229] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 29, 0), /* VEU1 */ + [RTMSTP228] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 28, 0), /* VEU0 */ + [RTMSTP226] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 26, 0), /* VEU2H */ + [RTMSTP216] = MSTP(&div6_clks[DIV6_SUB], RTMSTPCR2, 16, 0), /* IIC0 */ + [RTMSTP206] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 6, 0), /* JPU */ + [RTMSTP205] = MSTP(&div6_clks[DIV6_VOU], RTMSTPCR2, 5, 0), /* VOU */ + [RTMSTP201] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 1, 0), /* VPU */ + [SYMSTP023] = MSTP(&div6_clks[DIV6_SPU], SYMSTPCR0, 23, 0), /* SPU1 */ + [SYMSTP007] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 7, 0), /* SCIFA5 */ + [SYMSTP006] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 6, 0), /* SCIFB */ + [SYMSTP004] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 4, 0), /* SCIFA0 */ + [SYMSTP003] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 3, 0), /* SCIFA1 */ + [SYMSTP002] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 2, 0), /* SCIFA2 */ + [SYMSTP001] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 1, 0), /* SCIFA3 */ + [SYMSTP000] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 0, 0), /* SCIFA4 */ + [SYMSTP231] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR2, 31, 0), /* SIU */ + [SYMSTP229] = MSTP(&r_clk, SYMSTPCR2, 29, 0), /* CMT10 */ + [SYMSTP225] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR2, 25, 0), /* IRDA */ + [SYMSTP223] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR2, 23, 0), /* IIC1 */ + [SYMSTP222] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR2, 22, 0), /* USBHS */ + [SYMSTP215] = MSTP(&div4_clks[DIV4_HP], SYMSTPCR2, 15, 0), /* FLCTL */ + [SYMSTP214] = MSTP(&div4_clks[DIV4_HP], SYMSTPCR2, 14, 0), /* SDHI0 */ + [SYMSTP213] = MSTP(&div4_clks[DIV4_HP], SYMSTPCR2, 13, 0), /* SDHI1 */ + [SYMSTP211] = MSTP(&div4_clks[DIV4_HP], SYMSTPCR2, 11, 0), /* SDHI2 */ + [CMMSTP003] = MSTP(&r_clk, CMMSTPCR0, 3, 0), /* KEYSC */ }; +#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } +#define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk } + static struct clk_lookup lookups[] = { - { - .clk = &peripheral_clk, - }, { - .clk = &r_clk, - }, { - .clk = &usb0_clk, - }, { - .clk = &keysc0_clk, - } + /* main clocks */ + CLKDEV_CON_ID("r_clk", &r_clk), + CLKDEV_CON_ID("extalb1", &sh7367_extalb1_clk), + CLKDEV_CON_ID("extal2", &sh7367_extal2_clk), + CLKDEV_CON_ID("extalb1_div2_clk", &extalb1_div2_clk), + CLKDEV_CON_ID("extal2_div2_clk", &extal2_div2_clk), + CLKDEV_CON_ID("pllc1_clk", &pllc1_clk), + CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk), + CLKDEV_CON_ID("pllc2_clk", &pllc2_clk), + + /* DIV4 clocks */ + CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]), + CLKDEV_CON_ID("g_clk", &div4_clks[DIV4_G]), + CLKDEV_CON_ID("b_clk", &div4_clks[DIV4_B]), + CLKDEV_CON_ID("zx_clk", &div4_clks[DIV4_ZX]), + CLKDEV_CON_ID("zt_clk", &div4_clks[DIV4_ZT]), + CLKDEV_CON_ID("z_clk", &div4_clks[DIV4_Z]), + CLKDEV_CON_ID("zd_clk", &div4_clks[DIV4_ZD]), + CLKDEV_CON_ID("hp_clk", &div4_clks[DIV4_HP]), + CLKDEV_CON_ID("zs_clk", &div4_clks[DIV4_ZS]), + CLKDEV_CON_ID("zb_clk", &div4_clks[DIV4_ZB]), + CLKDEV_CON_ID("zb3_clk", &div4_clks[DIV4_ZB3]), + CLKDEV_CON_ID("cp_clk", &div4_clks[DIV4_CP]), + + /* DIV6 clocks */ + CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]), + CLKDEV_CON_ID("siua_clk", &div6_clks[DIV6_SIUA]), + CLKDEV_CON_ID("siub_clk", &div6_clks[DIV6_SIUB]), + CLKDEV_CON_ID("msu_clk", &div6_clks[DIV6_MSU]), + CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]), + CLKDEV_CON_ID("mvi3_clk", &div6_clks[DIV6_MVI3]), + CLKDEV_CON_ID("mf1_clk", &div6_clks[DIV6_MF1]), + CLKDEV_CON_ID("mf2_clk", &div6_clks[DIV6_MF2]), + CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]), + CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]), + CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]), + CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]), + + /* MSTP32 clocks */ + CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[RTMSTP001]), /* IIC2 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[RTMSTP231]), /* VEU3 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[RTMSTP230]), /* VEU2 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[RTMSTP229]), /* VEU1 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[RTMSTP228]), /* VEU0 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[RTMSTP226]), /* VEU2H */ + CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[RTMSTP216]), /* IIC0 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.6", &mstp_clks[RTMSTP206]), /* JPU */ + CLKDEV_DEV_ID("sh-vou", &mstp_clks[RTMSTP205]), /* VOU */ + CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[RTMSTP201]), /* VPU */ + CLKDEV_DEV_ID("uio_pdrv_genirq.7", &mstp_clks[SYMSTP023]), /* SPU1 */ + CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[SYMSTP007]), /* SCIFA5 */ + CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[SYMSTP006]), /* SCIFB */ + CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[SYMSTP004]), /* SCIFA0 */ + CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[SYMSTP003]), /* SCIFA1 */ + CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[SYMSTP002]), /* SCIFA2 */ + CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[SYMSTP001]), /* SCIFA3 */ + CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[SYMSTP000]), /* SCIFA4 */ + CLKDEV_DEV_ID("sh_siu", &mstp_clks[SYMSTP231]), /* SIU */ + CLKDEV_CON_ID("cmt1", &mstp_clks[SYMSTP229]), /* CMT10 */ + CLKDEV_DEV_ID("sh_irda", &mstp_clks[SYMSTP225]), /* IRDA */ + CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[SYMSTP223]), /* IIC1 */ + CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[SYMSTP222]), /* USBHS */ + CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[SYMSTP222]), /* USBHS */ + CLKDEV_DEV_ID("sh_flctl", &mstp_clks[SYMSTP215]), /* FLCTL */ + CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[SYMSTP214]), /* SDHI0 */ + CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[SYMSTP213]), /* SDHI1 */ + CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[SYMSTP211]), /* SDHI2 */ + CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[CMMSTP003]), /* KEYSC */ }; void __init sh7367_clock_init(void) { - int i; + int k, ret = 0; + + for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) + ret = clk_register(main_clks[k]); + + if (!ret) + ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table); + + if (!ret) + ret = sh_clk_div6_register(div6_clks, DIV6_NR); + + if (!ret) + ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); + + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); - for (i = 0; i < ARRAY_SIZE(lookups); i++) { - lookups[i].con_id = lookups[i].clk->name; - clkdev_add(&lookups[i]); - } + if (!ret) + clk_init(); + else + panic("failed to setup sh7367 clocks\n"); } diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c new file mode 100644 index 000000000000..1364072934b4 --- /dev/null +++ b/arch/arm/mach-shmobile/clock-sh7372.c @@ -0,0 +1,397 @@ +/* + * SH7372 clock framework support + * + * Copyright (C) 2010 Magnus Damm + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/io.h> +#include <linux/sh_clk.h> +#include <mach/common.h> +#include <asm/clkdev.h> + +/* SH7372 registers */ +#define FRQCRA 0xe6150000 +#define FRQCRB 0xe6150004 +#define FRQCRC 0xe61500e0 +#define FRQCRD 0xe61500e4 +#define VCLKCR1 0xe6150008 +#define VCLKCR2 0xe615000c +#define VCLKCR3 0xe615001c +#define FMSICKCR 0xe6150010 +#define FMSOCKCR 0xe6150014 +#define FSIACKCR 0xe6150018 +#define FSIBCKCR 0xe6150090 +#define SUBCKCR 0xe6150080 +#define SPUCKCR 0xe6150084 +#define VOUCKCR 0xe6150088 +#define HDMICKCR 0xe6150094 +#define DSITCKCR 0xe6150060 +#define DSI0PCKCR 0xe6150064 +#define DSI1PCKCR 0xe6150098 +#define PLLC01CR 0xe6150028 +#define PLLC2CR 0xe615002c +#define SMSTPCR0 0xe6150130 +#define SMSTPCR1 0xe6150134 +#define SMSTPCR2 0xe6150138 +#define SMSTPCR3 0xe615013c +#define SMSTPCR4 0xe6150140 + +/* Fixed 32 KHz root clock from EXTALR pin */ +static struct clk r_clk = { + .rate = 32768, +}; + +/* + * 26MHz default rate for the EXTAL1 root input clock. + * If needed, reset this with clk_set_rate() from the platform code. + */ +struct clk sh7372_extal1_clk = { + .rate = 26666666, +}; + +/* + * 48MHz default rate for the EXTAL2 root input clock. + * If needed, reset this with clk_set_rate() from the platform code. + */ +struct clk sh7372_extal2_clk = { + .rate = 48000000, +}; + +/* A fixed divide-by-2 block */ +static unsigned long div2_recalc(struct clk *clk) +{ + return clk->parent->rate / 2; +} + +static struct clk_ops div2_clk_ops = { + .recalc = div2_recalc, +}; + +/* Divide extal1 by two */ +static struct clk extal1_div2_clk = { + .ops = &div2_clk_ops, + .parent = &sh7372_extal1_clk, +}; + +/* Divide extal2 by two */ +static struct clk extal2_div2_clk = { + .ops = &div2_clk_ops, + .parent = &sh7372_extal2_clk, +}; + +/* Divide extal2 by four */ +static struct clk extal2_div4_clk = { + .ops = &div2_clk_ops, + .parent = &extal2_div2_clk, +}; + +/* PLLC0 and PLLC1 */ +static unsigned long pllc01_recalc(struct clk *clk) +{ + unsigned long mult = 1; + + if (__raw_readl(PLLC01CR) & (1 << 14)) + mult = (((__raw_readl(clk->enable_reg) >> 24) & 0x3f) + 1) * 2; + + return clk->parent->rate * mult; +} + +static struct clk_ops pllc01_clk_ops = { + .recalc = pllc01_recalc, +}; + +static struct clk pllc0_clk = { + .ops = &pllc01_clk_ops, + .flags = CLK_ENABLE_ON_INIT, + .parent = &extal1_div2_clk, + .enable_reg = (void __iomem *)FRQCRC, +}; + +static struct clk pllc1_clk = { + .ops = &pllc01_clk_ops, + .flags = CLK_ENABLE_ON_INIT, + .parent = &extal1_div2_clk, + .enable_reg = (void __iomem *)FRQCRA, +}; + +/* Divide PLLC1 by two */ +static struct clk pllc1_div2_clk = { + .ops = &div2_clk_ops, + .parent = &pllc1_clk, +}; + +/* PLLC2 */ +static unsigned long pllc2_recalc(struct clk *clk) +{ + unsigned long mult = 1; + + if (__raw_readl(PLLC2CR) & (1 << 31)) + mult = (((__raw_readl(PLLC2CR) >> 24) & 0x3f) + 1) * 2; + + return clk->parent->rate * mult; +} + +static struct clk_ops pllc2_clk_ops = { + .recalc = pllc2_recalc, +}; + +static struct clk pllc2_clk = { + .ops = &pllc2_clk_ops, + .flags = CLK_ENABLE_ON_INIT, + .parent = &extal1_div2_clk, +}; + +static struct clk *main_clks[] = { + &r_clk, + &sh7372_extal1_clk, + &sh7372_extal2_clk, + &extal1_div2_clk, + &extal2_div2_clk, + &extal2_div4_clk, + &pllc0_clk, + &pllc1_clk, + &pllc1_div2_clk, + &pllc2_clk, +}; + +static void div4_kick(struct clk *clk) +{ + unsigned long value; + + /* set KICK bit in FRQCRB to update hardware setting */ + value = __raw_readl(FRQCRB); + value |= (1 << 31); + __raw_writel(value, FRQCRB); +} + +static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18, + 24, 32, 36, 48, 0, 72, 96, 0 }; + +static struct clk_div_mult_table div4_div_mult_table = { + .divisors = divisors, + .nr_divisors = ARRAY_SIZE(divisors), +}; + +static struct clk_div4_table div4_table = { + .div_mult_table = &div4_div_mult_table, + .kick = div4_kick, +}; + +enum { DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_CSIR, + DIV4_ZTR, DIV4_ZT, DIV4_ZX, DIV4_HP, + DIV4_ISPB, DIV4_S, DIV4_ZB, DIV4_ZB3, DIV4_CP, + DIV4_DDRP, DIV4_NR }; + +#define DIV4(_reg, _bit, _mask, _flags) \ + SH_CLK_DIV4(&pllc1_clk, _reg, _bit, _mask, _flags) + +static struct clk div4_clks[DIV4_NR] = { + [DIV4_I] = DIV4(FRQCRA, 20, 0x6fff, CLK_ENABLE_ON_INIT), + [DIV4_ZG] = DIV4(FRQCRA, 16, 0x6fff, CLK_ENABLE_ON_INIT), + [DIV4_B] = DIV4(FRQCRA, 8, 0x6fff, CLK_ENABLE_ON_INIT), + [DIV4_M1] = DIV4(FRQCRA, 4, 0x6fff, CLK_ENABLE_ON_INIT), + [DIV4_CSIR] = DIV4(FRQCRA, 0, 0x6fff, 0), + [DIV4_ZTR] = DIV4(FRQCRB, 20, 0x6fff, 0), + [DIV4_ZT] = DIV4(FRQCRB, 16, 0x6fff, 0), + [DIV4_ZX] = DIV4(FRQCRB, 12, 0x6fff, 0), + [DIV4_HP] = DIV4(FRQCRB, 4, 0x6fff, 0), + [DIV4_ISPB] = DIV4(FRQCRC, 20, 0x6fff, 0), + [DIV4_S] = DIV4(FRQCRC, 12, 0x6fff, 0), + [DIV4_ZB] = DIV4(FRQCRC, 8, 0x6fff, 0), + [DIV4_ZB3] = DIV4(FRQCRC, 4, 0x6fff, 0), + [DIV4_CP] = DIV4(FRQCRC, 0, 0x6fff, 0), + [DIV4_DDRP] = DIV4(FRQCRD, 0, 0x677c, 0), +}; + +enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_FMSI, DIV6_FMSO, + DIV6_FSIA, DIV6_FSIB, DIV6_SUB, DIV6_SPU, + DIV6_VOU, DIV6_HDMI, DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P, + DIV6_NR }; + +static struct clk div6_clks[DIV6_NR] = { + [DIV6_VCK1] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR1, 0), + [DIV6_VCK2] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR2, 0), + [DIV6_VCK3] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR3, 0), + [DIV6_FMSI] = SH_CLK_DIV6(&pllc1_div2_clk, FMSICKCR, 0), + [DIV6_FMSO] = SH_CLK_DIV6(&pllc1_div2_clk, FMSOCKCR, 0), + [DIV6_FSIA] = SH_CLK_DIV6(&pllc1_div2_clk, FSIACKCR, 0), + [DIV6_FSIB] = SH_CLK_DIV6(&pllc1_div2_clk, FSIBCKCR, 0), + [DIV6_SUB] = SH_CLK_DIV6(&sh7372_extal2_clk, SUBCKCR, 0), + [DIV6_SPU] = SH_CLK_DIV6(&pllc1_div2_clk, SPUCKCR, 0), + [DIV6_VOU] = SH_CLK_DIV6(&pllc1_div2_clk, VOUCKCR, 0), + [DIV6_HDMI] = SH_CLK_DIV6(&pllc1_div2_clk, HDMICKCR, 0), + [DIV6_DSIT] = SH_CLK_DIV6(&pllc1_div2_clk, DSITCKCR, 0), + [DIV6_DSI0P] = SH_CLK_DIV6(&pllc1_div2_clk, DSI0PCKCR, 0), + [DIV6_DSI1P] = SH_CLK_DIV6(&pllc1_div2_clk, DSI1PCKCR, 0), +}; + +enum { MSTP001, + MSTP131, MSTP130, + MSTP129, MSTP128, + MSTP118, MSTP117, MSTP116, + MSTP106, MSTP101, MSTP100, + MSTP223, + MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, + MSTP329, MSTP328, MSTP323, MSTP322, MSTP314, MSTP313, + MSTP415, MSTP410, MSTP411, MSTP406, MSTP403, + MSTP_NR }; + +#define MSTP(_parent, _reg, _bit, _flags) \ + SH_CLK_MSTP32(_parent, _reg, _bit, _flags) + +static struct clk mstp_clks[MSTP_NR] = { + [MSTP001] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR0, 1, 0), /* IIC2 */ + [MSTP131] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 31, 0), /* VEU3 */ + [MSTP130] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 30, 0), /* VEU2 */ + [MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* VEU1 */ + [MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* VEU0 */ + [MSTP118] = MSTP(&div6_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX */ + [MSTP117] = MSTP(&div6_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */ + [MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */ + [MSTP106] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 6, 0), /* JPU */ + [MSTP101] = MSTP(&div4_clks[DIV4_M1], SMSTPCR1, 1, 0), /* VPU */ + [MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */ + [MSTP223] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR2, 23, 0), /* SPU2 */ + [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */ + [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */ + [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */ + [MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */ + [MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */ + [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */ + [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */ + [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */ + [MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, CLK_ENABLE_ON_INIT), /* FSIA */ + [MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */ + [MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */ + [MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */ + [MSTP313] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */ + [MSTP415] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 15, 0), /* SDHI2 */ + [MSTP411] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 11, 0), /* IIC3 */ + [MSTP410] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 10, 0), /* IIC4 */ + [MSTP406] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 6, 0), /* USB1 */ + [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */ +}; + +#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } +#define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk } + +static struct clk_lookup lookups[] = { + /* main clocks */ + CLKDEV_CON_ID("r_clk", &r_clk), + CLKDEV_CON_ID("extal1", &sh7372_extal1_clk), + CLKDEV_CON_ID("extal2", &sh7372_extal2_clk), + CLKDEV_CON_ID("extal1_div2_clk", &extal1_div2_clk), + CLKDEV_CON_ID("extal2_div2_clk", &extal2_div2_clk), + CLKDEV_CON_ID("extal2_div4_clk", &extal2_div4_clk), + CLKDEV_CON_ID("pllc0_clk", &pllc0_clk), + CLKDEV_CON_ID("pllc1_clk", &pllc1_clk), + CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk), + CLKDEV_CON_ID("pllc2_clk", &pllc2_clk), + + /* DIV4 clocks */ + CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]), + CLKDEV_CON_ID("zg_clk", &div4_clks[DIV4_ZG]), + CLKDEV_CON_ID("b_clk", &div4_clks[DIV4_B]), + CLKDEV_CON_ID("m1_clk", &div4_clks[DIV4_M1]), + CLKDEV_CON_ID("csir_clk", &div4_clks[DIV4_CSIR]), + CLKDEV_CON_ID("ztr_clk", &div4_clks[DIV4_ZTR]), + CLKDEV_CON_ID("zt_clk", &div4_clks[DIV4_ZT]), + CLKDEV_CON_ID("zx_clk", &div4_clks[DIV4_ZX]), + CLKDEV_CON_ID("hp_clk", &div4_clks[DIV4_HP]), + CLKDEV_CON_ID("ispb_clk", &div4_clks[DIV4_ISPB]), + CLKDEV_CON_ID("s_clk", &div4_clks[DIV4_S]), + CLKDEV_CON_ID("zb_clk", &div4_clks[DIV4_ZB]), + CLKDEV_CON_ID("zb3_clk", &div4_clks[DIV4_ZB3]), + CLKDEV_CON_ID("cp_clk", &div4_clks[DIV4_CP]), + CLKDEV_CON_ID("ddrp_clk", &div4_clks[DIV4_DDRP]), + + /* DIV6 clocks */ + CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]), + CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]), + CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]), + CLKDEV_CON_ID("fmsi_clk", &div6_clks[DIV6_FMSI]), + CLKDEV_CON_ID("fmso_clk", &div6_clks[DIV6_FMSO]), + CLKDEV_CON_ID("fsia_clk", &div6_clks[DIV6_FSIA]), + CLKDEV_CON_ID("fsib_clk", &div6_clks[DIV6_FSIB]), + CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]), + CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]), + CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]), + CLKDEV_CON_ID("hdmi_clk", &div6_clks[DIV6_HDMI]), + CLKDEV_CON_ID("dsit_clk", &div6_clks[DIV6_DSIT]), + CLKDEV_CON_ID("dsi0p_clk", &div6_clks[DIV6_DSI0P]), + CLKDEV_CON_ID("dsi1p_clk", &div6_clks[DIV6_DSI1P]), + + /* MSTP32 clocks */ + CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[MSTP131]), /* VEU3 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[MSTP130]), /* VEU2 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[MSTP129]), /* VEU1 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[MSTP128]), /* VEU0 */ + CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */ + CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */ + CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[MSTP106]), /* JPU */ + CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[MSTP101]), /* VPU */ + CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.6", &mstp_clks[MSTP223]), /* SPU2DSP0 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.7", &mstp_clks[MSTP223]), /* SPU2DSP1 */ + CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */ + CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP206]), /* SCIFB */ + CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */ + CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */ + CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */ + CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */ + CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */ + CLKDEV_CON_ID("cmt1", &mstp_clks[MSTP329]), /* CMT10 */ + CLKDEV_DEV_ID("sh_fsi", &mstp_clks[MSTP328]), /* FSI */ + CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */ + CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP323]), /* USB0 */ + CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP323]), /* USB0 */ + CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */ + CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */ + CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]), /* SDHI2 */ + CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* IIC3 */ + CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* IIC4 */ + CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */ + CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */ + CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */ +}; + +void __init sh7372_clock_init(void) +{ + int k, ret = 0; + + for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) + ret = clk_register(main_clks[k]); + + if (!ret) + ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table); + + if (!ret) + ret = sh_clk_div6_register(div6_clks, DIV6_NR); + + if (!ret) + ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); + + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); + + if (!ret) + clk_init(); + else + panic("failed to setup sh7372 clocks\n"); + +} diff --git a/arch/arm/mach-shmobile/clock-sh7377.c b/arch/arm/mach-shmobile/clock-sh7377.c new file mode 100644 index 000000000000..e007c28cf0a8 --- /dev/null +++ b/arch/arm/mach-shmobile/clock-sh7377.c @@ -0,0 +1,369 @@ +/* + * SH7377 clock framework support + * + * Copyright (C) 2010 Magnus Damm + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/io.h> +#include <linux/sh_clk.h> +#include <mach/common.h> +#include <asm/clkdev.h> + +/* SH7377 registers */ +#define RTFRQCR 0xe6150000 +#define SYFRQCR 0xe6150004 +#define CMFRQCR 0xe61500E0 +#define VCLKCR1 0xe6150008 +#define VCLKCR2 0xe615000C +#define VCLKCR3 0xe615001C +#define FMSICKCR 0xe6150010 +#define FMSOCKCR 0xe6150014 +#define FSICKCR 0xe6150018 +#define PLLC1CR 0xe6150028 +#define PLLC2CR 0xe615002C +#define SUBUSBCKCR 0xe6150080 +#define SPUCKCR 0xe6150084 +#define MSUCKCR 0xe6150088 +#define MVI3CKCR 0xe6150090 +#define HDMICKCR 0xe6150094 +#define MFCK1CR 0xe6150098 +#define MFCK2CR 0xe615009C +#define DSITCKCR 0xe6150060 +#define DSIPCKCR 0xe6150064 +#define SMSTPCR0 0xe6150130 +#define SMSTPCR1 0xe6150134 +#define SMSTPCR2 0xe6150138 +#define SMSTPCR3 0xe615013C +#define SMSTPCR4 0xe6150140 + +/* Fixed 32 KHz root clock from EXTALR pin */ +static struct clk r_clk = { + .rate = 32768, +}; + +/* + * 26MHz default rate for the EXTALC1 root input clock. + * If needed, reset this with clk_set_rate() from the platform code. + */ +struct clk sh7377_extalc1_clk = { + .rate = 26666666, +}; + +/* + * 48MHz default rate for the EXTAL2 root input clock. + * If needed, reset this with clk_set_rate() from the platform code. + */ +struct clk sh7377_extal2_clk = { + .rate = 48000000, +}; + +/* A fixed divide-by-2 block */ +static unsigned long div2_recalc(struct clk *clk) +{ + return clk->parent->rate / 2; +} + +static struct clk_ops div2_clk_ops = { + .recalc = div2_recalc, +}; + +/* Divide extalc1 by two */ +static struct clk extalc1_div2_clk = { + .ops = &div2_clk_ops, + .parent = &sh7377_extalc1_clk, +}; + +/* Divide extal2 by two */ +static struct clk extal2_div2_clk = { + .ops = &div2_clk_ops, + .parent = &sh7377_extal2_clk, +}; + +/* Divide extal2 by four */ +static struct clk extal2_div4_clk = { + .ops = &div2_clk_ops, + .parent = &extal2_div2_clk, +}; + +/* PLLC1 */ +static unsigned long pllc1_recalc(struct clk *clk) +{ + unsigned long mult = 1; + + if (__raw_readl(PLLC1CR) & (1 << 14)) + mult = (((__raw_readl(RTFRQCR) >> 24) & 0x3f) + 1) * 2; + + return clk->parent->rate * mult; +} + +static struct clk_ops pllc1_clk_ops = { + .recalc = pllc1_recalc, +}; + +static struct clk pllc1_clk = { + .ops = &pllc1_clk_ops, + .flags = CLK_ENABLE_ON_INIT, + .parent = &extalc1_div2_clk, +}; + +/* Divide PLLC1 by two */ +static struct clk pllc1_div2_clk = { + .ops = &div2_clk_ops, + .parent = &pllc1_clk, +}; + +/* PLLC2 */ +static unsigned long pllc2_recalc(struct clk *clk) +{ + unsigned long mult = 1; + + if (__raw_readl(PLLC2CR) & (1 << 31)) + mult = (((__raw_readl(PLLC2CR) >> 24) & 0x3f) + 1) * 2; + + return clk->parent->rate * mult; +} + +static struct clk_ops pllc2_clk_ops = { + .recalc = pllc2_recalc, +}; + +static struct clk pllc2_clk = { + .ops = &pllc2_clk_ops, + .flags = CLK_ENABLE_ON_INIT, + .parent = &extalc1_div2_clk, +}; + +static struct clk *main_clks[] = { + &r_clk, + &sh7377_extalc1_clk, + &sh7377_extal2_clk, + &extalc1_div2_clk, + &extal2_div2_clk, + &extal2_div4_clk, + &pllc1_clk, + &pllc1_div2_clk, + &pllc2_clk, +}; + +static void div4_kick(struct clk *clk) +{ + unsigned long value; + + /* set KICK bit in SYFRQCR to update hardware setting */ + value = __raw_readl(SYFRQCR); + value |= (1 << 31); + __raw_writel(value, SYFRQCR); +} + +static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18, + 24, 32, 36, 48, 0, 72, 96, 0 }; + +static struct clk_div_mult_table div4_div_mult_table = { + .divisors = divisors, + .nr_divisors = ARRAY_SIZE(divisors), +}; + +static struct clk_div4_table div4_table = { + .div_mult_table = &div4_div_mult_table, + .kick = div4_kick, +}; + +enum { DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_CSIR, + DIV4_ZTR, DIV4_ZT, DIV4_Z, DIV4_HP, + DIV4_ZS, DIV4_ZB, DIV4_ZB3, DIV4_CP, DIV4_NR }; + +#define DIV4(_reg, _bit, _mask, _flags) \ + SH_CLK_DIV4(&pllc1_clk, _reg, _bit, _mask, _flags) + +static struct clk div4_clks[DIV4_NR] = { + [DIV4_I] = DIV4(RTFRQCR, 20, 0x6fff, CLK_ENABLE_ON_INIT), + [DIV4_ZG] = DIV4(RTFRQCR, 16, 0x6fff, CLK_ENABLE_ON_INIT), + [DIV4_B] = DIV4(RTFRQCR, 8, 0x6fff, CLK_ENABLE_ON_INIT), + [DIV4_M1] = DIV4(RTFRQCR, 4, 0x6fff, CLK_ENABLE_ON_INIT), + [DIV4_CSIR] = DIV4(RTFRQCR, 0, 0x6fff, 0), + [DIV4_ZTR] = DIV4(SYFRQCR, 20, 0x6fff, 0), + [DIV4_ZT] = DIV4(SYFRQCR, 16, 0x6fff, 0), + [DIV4_Z] = DIV4(SYFRQCR, 12, 0x6fff, 0), + [DIV4_HP] = DIV4(SYFRQCR, 4, 0x6fff, 0), + [DIV4_ZS] = DIV4(CMFRQCR, 12, 0x6fff, 0), + [DIV4_ZB] = DIV4(CMFRQCR, 8, 0x6fff, 0), + [DIV4_ZB3] = DIV4(CMFRQCR, 4, 0x6fff, 0), + [DIV4_CP] = DIV4(CMFRQCR, 0, 0x6fff, 0), +}; + +enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_FMSI, DIV6_FMSO, + DIV6_FSI, DIV6_SUB, DIV6_SPU, DIV6_MSU, DIV6_MVI3, DIV6_HDMI, + DIV6_MF1, DIV6_MF2, DIV6_DSIT, DIV6_DSIP, + DIV6_NR }; + +static struct clk div6_clks[] = { + [DIV6_VCK1] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR1, 0), + [DIV6_VCK2] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR2, 0), + [DIV6_VCK3] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR3, 0), + [DIV6_FMSI] = SH_CLK_DIV6(&pllc1_div2_clk, FMSICKCR, 0), + [DIV6_FMSO] = SH_CLK_DIV6(&pllc1_div2_clk, FMSOCKCR, 0), + [DIV6_FSI] = SH_CLK_DIV6(&pllc1_div2_clk, FSICKCR, 0), + [DIV6_SUB] = SH_CLK_DIV6(&sh7377_extal2_clk, SUBUSBCKCR, 0), + [DIV6_SPU] = SH_CLK_DIV6(&pllc1_div2_clk, SPUCKCR, 0), + [DIV6_MSU] = SH_CLK_DIV6(&pllc1_div2_clk, MSUCKCR, 0), + [DIV6_MVI3] = SH_CLK_DIV6(&pllc1_div2_clk, MVI3CKCR, 0), + [DIV6_HDMI] = SH_CLK_DIV6(&pllc1_div2_clk, HDMICKCR, 0), + [DIV6_MF1] = SH_CLK_DIV6(&pllc1_div2_clk, MFCK1CR, 0), + [DIV6_MF2] = SH_CLK_DIV6(&pllc1_div2_clk, MFCK2CR, 0), + [DIV6_DSIT] = SH_CLK_DIV6(&pllc1_div2_clk, DSITCKCR, 0), + [DIV6_DSIP] = SH_CLK_DIV6(&pllc1_div2_clk, DSIPCKCR, 0), +}; + +enum { MSTP001, + MSTP131, MSTP130, MSTP129, MSTP128, MSTP116, MSTP106, MSTP101, + MSTP223, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, + MSTP331, MSTP329, MSTP325, MSTP323, MSTP322, + MSTP315, MSTP314, MSTP313, + MSTP403, + MSTP_NR }; + +#define MSTP(_parent, _reg, _bit, _flags) \ + SH_CLK_MSTP32(_parent, _reg, _bit, _flags) + +static struct clk mstp_clks[] = { + [MSTP001] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR0, 1, 0), /* IIC2 */ + [MSTP131] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 31, 0), /* VEU3 */ + [MSTP130] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 30, 0), /* VEU2 */ + [MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* VEU1 */ + [MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* VEU0 */ + [MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */ + [MSTP106] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 6, 0), /* JPU */ + [MSTP101] = MSTP(&div4_clks[DIV4_M1], SMSTPCR1, 1, 0), /* VPU */ + [MSTP223] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR2, 23, 0), /* SPU2 */ + [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */ + [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */ + [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */ + [MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */ + [MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */ + [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */ + [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */ + [MSTP331] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 31, 0), /* SCIFA6 */ + [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */ + [MSTP325] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 25, 0), /* IRDA */ + [MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */ + [MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */ + [MSTP315] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 15, 0), /* FLCTL */ + [MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */ + [MSTP313] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */ + [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */ +}; + +#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } +#define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk } + +static struct clk_lookup lookups[] = { + /* main clocks */ + CLKDEV_CON_ID("r_clk", &r_clk), + CLKDEV_CON_ID("extalc1", &sh7377_extalc1_clk), + CLKDEV_CON_ID("extal2", &sh7377_extal2_clk), + CLKDEV_CON_ID("extalc1_div2_clk", &extalc1_div2_clk), + CLKDEV_CON_ID("extal2_div2_clk", &extal2_div2_clk), + CLKDEV_CON_ID("extal2_div4_clk", &extal2_div4_clk), + CLKDEV_CON_ID("pllc1_clk", &pllc1_clk), + CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk), + CLKDEV_CON_ID("pllc2_clk", &pllc2_clk), + + /* DIV4 clocks */ + CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]), + CLKDEV_CON_ID("zg_clk", &div4_clks[DIV4_ZG]), + CLKDEV_CON_ID("b_clk", &div4_clks[DIV4_B]), + CLKDEV_CON_ID("m1_clk", &div4_clks[DIV4_M1]), + CLKDEV_CON_ID("csir_clk", &div4_clks[DIV4_CSIR]), + CLKDEV_CON_ID("ztr_clk", &div4_clks[DIV4_ZTR]), + CLKDEV_CON_ID("zt_clk", &div4_clks[DIV4_ZT]), + CLKDEV_CON_ID("z_clk", &div4_clks[DIV4_Z]), + CLKDEV_CON_ID("hp_clk", &div4_clks[DIV4_HP]), + CLKDEV_CON_ID("zs_clk", &div4_clks[DIV4_ZS]), + CLKDEV_CON_ID("zb_clk", &div4_clks[DIV4_ZB]), + CLKDEV_CON_ID("zb3_clk", &div4_clks[DIV4_ZB3]), + CLKDEV_CON_ID("cp_clk", &div4_clks[DIV4_CP]), + + /* DIV6 clocks */ + CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]), + CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]), + CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]), + CLKDEV_CON_ID("fmsi_clk", &div6_clks[DIV6_FMSI]), + CLKDEV_CON_ID("fmso_clk", &div6_clks[DIV6_FMSO]), + CLKDEV_CON_ID("fsi_clk", &div6_clks[DIV6_FSI]), + CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]), + CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]), + CLKDEV_CON_ID("msu_clk", &div6_clks[DIV6_MSU]), + CLKDEV_CON_ID("mvi3_clk", &div6_clks[DIV6_MVI3]), + CLKDEV_CON_ID("hdmi_clk", &div6_clks[DIV6_HDMI]), + CLKDEV_CON_ID("mf1_clk", &div6_clks[DIV6_MF1]), + CLKDEV_CON_ID("mf2_clk", &div6_clks[DIV6_MF2]), + CLKDEV_CON_ID("dsit_clk", &div6_clks[DIV6_DSIT]), + CLKDEV_CON_ID("dsip_clk", &div6_clks[DIV6_DSIP]), + + /* MSTP32 clocks */ + CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[MSTP131]), /* VEU3 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[MSTP130]), /* VEU2 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[MSTP129]), /* VEU1 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[MSTP128]), /* VEU0 */ + CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[MSTP106]), /* JPU */ + CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[MSTP101]), /* VPU */ + CLKDEV_DEV_ID("uio_pdrv_genirq.6", &mstp_clks[MSTP223]), /* SPU2DSP0 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.7", &mstp_clks[MSTP223]), /* SPU2DSP1 */ + CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */ + CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP206]), /* SCIFB */ + CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */ + CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */ + CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */ + CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */ + CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */ + CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */ + CLKDEV_CON_ID("cmt1", &mstp_clks[MSTP329]), /* CMT10 */ + CLKDEV_DEV_ID("sh_irda", &mstp_clks[MSTP325]), /* IRDA */ + CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */ + CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USBHS */ + CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP322]), /* USBHS */ + CLKDEV_DEV_ID("sh_flctl", &mstp_clks[MSTP315]), /* FLCTL */ + CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */ + CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */ + CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */ +}; + +void __init sh7377_clock_init(void) +{ + int k, ret = 0; + + for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) + ret = clk_register(main_clks[k]); + + if (!ret) + ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table); + + if (!ret) + ret = sh_clk_div6_register(div6_clks, DIV6_NR); + + if (!ret) + ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); + + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); + + if (!ret) + clk_init(); + else + panic("failed to setup sh7377 clocks\n"); +} diff --git a/arch/arm/mach-shmobile/clock.c b/arch/arm/mach-shmobile/clock.c new file mode 100644 index 000000000000..b7c705a213a2 --- /dev/null +++ b/arch/arm/mach-shmobile/clock.c @@ -0,0 +1,44 @@ +/* + * SH-Mobile Timer + * + * Copyright (C) 2010 Magnus Damm + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/sh_clk.h> + +int __init clk_init(void) +{ + /* Kick the child clocks.. */ + recalculate_root_clocks(); + + /* Enable the necessary init clocks */ + clk_enable_init_clocks(); + + return 0; +} + +int __clk_get(struct clk *clk) +{ + return 1; +} +EXPORT_SYMBOL(__clk_get); + +void __clk_put(struct clk *clk) +{ +} +EXPORT_SYMBOL(__clk_put); diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h index 57903605cc51..efeef778a875 100644 --- a/arch/arm/mach-shmobile/include/mach/common.h +++ b/arch/arm/mach-shmobile/include/mach/common.h @@ -3,21 +3,31 @@ extern struct sys_timer shmobile_timer; extern void shmobile_setup_console(void); +struct clk; +extern int clk_init(void); extern void sh7367_init_irq(void); extern void sh7367_add_early_devices(void); extern void sh7367_add_standard_devices(void); extern void sh7367_clock_init(void); extern void sh7367_pinmux_init(void); +extern struct clk sh7367_extalb1_clk; +extern struct clk sh7367_extal2_clk; extern void sh7377_init_irq(void); extern void sh7377_add_early_devices(void); extern void sh7377_add_standard_devices(void); +extern void sh7377_clock_init(void); extern void sh7377_pinmux_init(void); +extern struct clk sh7377_extalc1_clk; +extern struct clk sh7377_extal2_clk; extern void sh7372_init_irq(void); extern void sh7372_add_early_devices(void); extern void sh7372_add_standard_devices(void); +extern void sh7372_clock_init(void); extern void sh7372_pinmux_init(void); +extern struct clk sh7372_extal1_clk; +extern struct clk sh7372_extal2_clk; #endif /* __ARCH_MACH_COMMON_H */ diff --git a/arch/arm/mach-shmobile/include/mach/irqs.h b/arch/arm/mach-shmobile/include/mach/irqs.h index 5179b72e1ee3..e881797648a9 100644 --- a/arch/arm/mach-shmobile/include/mach/irqs.h +++ b/arch/arm/mach-shmobile/include/mach/irqs.h @@ -4,7 +4,13 @@ #define NR_IRQS 512 #define NR_IRQS_LEGACY 8 +/* INTCA */ #define evt2irq(evt) (((evt) >> 5) - 16) #define irq2evt(irq) (((irq) + 16) << 5) +/* INTCS */ +#define INTCS_VECT_BASE 0x2200 +#define INTCS_VECT(n, vect) INTC_VECT((n), INTCS_VECT_BASE + (vect)) +#define intcs_evt2irq(evt) evt2irq(INTCS_VECT_BASE + (evt)) + #endif /* __ASM_MACH_IRQS_H */ diff --git a/arch/arm/mach-shmobile/include/mach/memory.h b/arch/arm/mach-shmobile/include/mach/memory.h index e188183f4dce..377584e57e03 100644 --- a/arch/arm/mach-shmobile/include/mach/memory.h +++ b/arch/arm/mach-shmobile/include/mach/memory.h @@ -4,4 +4,7 @@ #define PHYS_OFFSET UL(CONFIG_MEMORY_START) #define MEM_SIZE UL(CONFIG_MEMORY_SIZE) +/* DMA memory at 0xf6000000 - 0xffdfffff */ +#define CONSISTENT_DMA_SIZE (158 << 20) + #endif /* __ASM_MACH_MEMORY_H */ diff --git a/arch/arm/mach-shmobile/include/mach/sh7372.h b/arch/arm/mach-shmobile/include/mach/sh7372.h index dc34f00c56b8..c2d2d811059c 100644 --- a/arch/arm/mach-shmobile/include/mach/sh7372.h +++ b/arch/arm/mach-shmobile/include/mach/sh7372.h @@ -431,4 +431,28 @@ enum { GPIO_FN_SDENC_DV_CLKI, }; +/* DMA slave IDs */ +enum { + SHDMA_SLAVE_SCIF0_TX, + SHDMA_SLAVE_SCIF0_RX, + SHDMA_SLAVE_SCIF1_TX, + SHDMA_SLAVE_SCIF1_RX, + SHDMA_SLAVE_SCIF2_TX, + SHDMA_SLAVE_SCIF2_RX, + SHDMA_SLAVE_SCIF3_TX, + SHDMA_SLAVE_SCIF3_RX, + SHDMA_SLAVE_SCIF4_TX, + SHDMA_SLAVE_SCIF4_RX, + SHDMA_SLAVE_SCIF5_TX, + SHDMA_SLAVE_SCIF5_RX, + SHDMA_SLAVE_SCIF6_TX, + SHDMA_SLAVE_SCIF6_RX, + SHDMA_SLAVE_SDHI0_RX, + SHDMA_SLAVE_SDHI0_TX, + SHDMA_SLAVE_SDHI1_RX, + SHDMA_SLAVE_SDHI1_TX, + SHDMA_SLAVE_SDHI2_RX, + SHDMA_SLAVE_SDHI2_TX, +}; + #endif /* __ASM_SH7372_H__ */ diff --git a/arch/arm/mach-shmobile/include/mach/vmalloc.h b/arch/arm/mach-shmobile/include/mach/vmalloc.h index fb3c4f1ab252..4aecf6e3a859 100644 --- a/arch/arm/mach-shmobile/include/mach/vmalloc.h +++ b/arch/arm/mach-shmobile/include/mach/vmalloc.h @@ -1,6 +1,7 @@ #ifndef __ASM_MACH_VMALLOC_H #define __ASM_MACH_VMALLOC_H -#define VMALLOC_END (PAGE_OFFSET + 0x24000000) +/* Vmalloc at ... - 0xe5ffffff */ +#define VMALLOC_END 0xe6000000 #endif /* __ASM_MACH_VMALLOC_H */ diff --git a/arch/arm/mach-shmobile/intc-sh7367.c b/arch/arm/mach-shmobile/intc-sh7367.c index 5ff70cadfc32..1a20c489b20d 100644 --- a/arch/arm/mach-shmobile/intc-sh7367.c +++ b/arch/arm/mach-shmobile/intc-sh7367.c @@ -75,7 +75,7 @@ enum { ETM11, ARM11, USBHS, FLCTL, IIC1 }; -static struct intc_vect intca_vectors[] = { +static struct intc_vect intca_vectors[] __initdata = { INTC_VECT(IRQ0A, 0x0200), INTC_VECT(IRQ1A, 0x0220), INTC_VECT(IRQ2A, 0x0240), INTC_VECT(IRQ3A, 0x0260), INTC_VECT(IRQ4A, 0x0280), INTC_VECT(IRQ5A, 0x02a0), @@ -162,7 +162,7 @@ static struct intc_group intca_groups[] __initdata = { INTC_GROUP(IIC1, IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1), }; -static struct intc_mask_reg intca_mask_registers[] = { +static struct intc_mask_reg intca_mask_registers[] __initdata = { { 0xe6900040, 0xe6900060, 8, /* INTMSK00A / INTMSKCLR00A */ { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } }, { 0xe6900044, 0xe6900064, 8, /* INTMSK10A / INTMSKCLR10A */ @@ -211,7 +211,7 @@ static struct intc_mask_reg intca_mask_registers[] = { MISTY, CMT3, RWDT1, RWDT0 } }, }; -static struct intc_prio_reg intca_prio_registers[] = { +static struct intc_prio_reg intca_prio_registers[] __initdata = { { 0xe6900010, 0, 32, 4, /* INTPRI00A */ { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } }, { 0xe6900014, 0, 32, 4, /* INTPRI10A */ @@ -263,8 +263,178 @@ static struct intc_desc intca_desc __initdata = { intca_sense_registers, intca_ack_registers), }; +enum { + UNUSED_INTCS = 0, + + INTCS, + + /* interrupt sources INTCS */ + VIO2_VEU0, VIO2_VEU1, VIO2_VEU2, VIO2_VEU3, + VIO3_VOU, + RTDMAC_1_DEI0, RTDMAC_1_DEI1, RTDMAC_1_DEI2, RTDMAC_1_DEI3, + VIO1_CEU, VIO1_BEU0, VIO1_BEU1, VIO1_BEU2, + VPU, + SGX530, + _2DDMAC_2DDM0, _2DDMAC_2DDM1, _2DDMAC_2DDM2, _2DDMAC_2DDM3, + IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2, + IPMMU_IPMMUB, IPMMU_IPMMUS, + RTDMAC_2_DEI4, RTDMAC_2_DEI5, RTDMAC_2_DADERR, + MSIOF, + IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0, + TMU_TUNI0, TMU_TUNI1, TMU_TUNI2, + CMT, + TSIF, + IPMMUI, + MVI3, + ICB, + PEP, + ASA, + BEM, + VE2HO, + HQE, + JPEG, + LCDC, + + /* interrupt groups INTCS */ + _2DDMAC, RTDMAC_1, RTDMAC_2, VEU, BEU, IIC0, IPMMU, IIC2, +}; + +static struct intc_vect intcs_vectors[] = { + INTCS_VECT(VIO2_VEU0, 0x700), INTCS_VECT(VIO2_VEU1, 0x720), + INTCS_VECT(VIO2_VEU2, 0x740), INTCS_VECT(VIO2_VEU3, 0x760), + INTCS_VECT(VIO3_VOU, 0x780), + INTCS_VECT(RTDMAC_1_DEI0, 0x800), INTCS_VECT(RTDMAC_1_DEI1, 0x820), + INTCS_VECT(RTDMAC_1_DEI2, 0x840), INTCS_VECT(RTDMAC_1_DEI3, 0x860), + INTCS_VECT(VIO1_CEU, 0x880), INTCS_VECT(VIO1_BEU0, 0x8a0), + INTCS_VECT(VIO1_BEU1, 0x8c0), INTCS_VECT(VIO1_BEU2, 0x8e0), + INTCS_VECT(VPU, 0x980), + INTCS_VECT(SGX530, 0x9e0), + INTCS_VECT(_2DDMAC_2DDM0, 0xa00), INTCS_VECT(_2DDMAC_2DDM1, 0xa20), + INTCS_VECT(_2DDMAC_2DDM2, 0xa40), INTCS_VECT(_2DDMAC_2DDM3, 0xa60), + INTCS_VECT(IIC2_ALI2, 0xa80), INTCS_VECT(IIC2_TACKI2, 0xaa0), + INTCS_VECT(IIC2_WAITI2, 0xac0), INTCS_VECT(IIC2_DTEI2, 0xae0), + INTCS_VECT(IPMMU_IPMMUB, 0xb20), INTCS_VECT(IPMMU_IPMMUS, 0xb60), + INTCS_VECT(RTDMAC_2_DEI4, 0xb80), INTCS_VECT(RTDMAC_2_DEI5, 0xba0), + INTCS_VECT(RTDMAC_2_DADERR, 0xbc0), + INTCS_VECT(MSIOF, 0xd20), + INTCS_VECT(IIC0_ALI0, 0xe00), INTCS_VECT(IIC0_TACKI0, 0xe20), + INTCS_VECT(IIC0_WAITI0, 0xe40), INTCS_VECT(IIC0_DTEI0, 0xe60), + INTCS_VECT(TMU_TUNI0, 0xe80), INTCS_VECT(TMU_TUNI1, 0xea0), + INTCS_VECT(TMU_TUNI2, 0xec0), + INTCS_VECT(CMT, 0xf00), + INTCS_VECT(TSIF, 0xf20), + INTCS_VECT(IPMMUI, 0xf60), + INTCS_VECT(MVI3, 0x420), + INTCS_VECT(ICB, 0x480), + INTCS_VECT(PEP, 0x4a0), + INTCS_VECT(ASA, 0x4c0), + INTCS_VECT(BEM, 0x4e0), + INTCS_VECT(VE2HO, 0x520), + INTCS_VECT(HQE, 0x540), + INTCS_VECT(JPEG, 0x560), + INTCS_VECT(LCDC, 0x580), + + INTC_VECT(INTCS, 0xf80), +}; + +static struct intc_group intcs_groups[] __initdata = { + INTC_GROUP(_2DDMAC, _2DDMAC_2DDM0, _2DDMAC_2DDM1, + _2DDMAC_2DDM2, _2DDMAC_2DDM3), + INTC_GROUP(RTDMAC_1, RTDMAC_1_DEI0, RTDMAC_1_DEI1, + RTDMAC_1_DEI2, RTDMAC_1_DEI3), + INTC_GROUP(RTDMAC_2, RTDMAC_2_DEI4, RTDMAC_2_DEI5, RTDMAC_2_DADERR), + INTC_GROUP(VEU, VIO2_VEU0, VIO2_VEU1, VIO2_VEU2, VIO2_VEU3), + INTC_GROUP(BEU, VIO1_BEU0, VIO1_BEU1, VIO1_BEU2), + INTC_GROUP(IIC0, IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0), + INTC_GROUP(IPMMU, IPMMU_IPMMUS, IPMMU_IPMMUB), + INTC_GROUP(IIC2, IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2), +}; + +static struct intc_mask_reg intcs_mask_registers[] = { + { 0xffd20184, 0xffd201c4, 8, /* IMR1SA / IMCR1SA */ + { VIO1_BEU2, VIO1_BEU1, VIO1_BEU0, VIO1_CEU, + VIO2_VEU3, VIO2_VEU2, VIO2_VEU1, VIO2_VEU0 } }, + { 0xffd20188, 0xffd201c8, 8, /* IMR2SA / IMCR2SA */ + { VIO3_VOU, 0, VE2HO, VPU, + 0, 0, 0, 0 } }, + { 0xffd2018c, 0xffd201cc, 8, /* IMR3SA / IMCR3SA */ + { _2DDMAC_2DDM3, _2DDMAC_2DDM2, _2DDMAC_2DDM1, _2DDMAC_2DDM0, + BEM, ASA, PEP, ICB } }, + { 0xffd20190, 0xffd201d0, 8, /* IMR4SA / IMCR4SA */ + { 0, 0, MVI3, 0, + JPEG, HQE, 0, LCDC } }, + { 0xffd20194, 0xffd201d4, 8, /* IMR5SA / IMCR5SA */ + { 0, RTDMAC_2_DADERR, RTDMAC_2_DEI5, RTDMAC_2_DEI4, + RTDMAC_1_DEI3, RTDMAC_1_DEI2, RTDMAC_1_DEI1, RTDMAC_1_DEI0 } }, + { 0xffd20198, 0xffd201d8, 8, /* IMR6SA / IMCR6SA */ + { 0, 0, MSIOF, 0, + SGX530, 0, 0, 0 } }, + { 0xffd2019c, 0xffd201dc, 8, /* IMR7SA / IMCR7SA */ + { 0, TMU_TUNI2, TMU_TUNI1, TMU_TUNI0, + 0, 0, 0, 0 } }, + { 0xffd201a4, 0xffd201e4, 8, /* IMR9SA / IMCR9SA */ + { 0, 0, 0, CMT, + IIC2_DTEI2, IIC2_WAITI2, IIC2_TACKI2, IIC2_ALI2 } }, + { 0xffd201a8, 0xffd201e8, 8, /* IMR10SA / IMCR10SA */ + { IPMMU_IPMMUS, 0, IPMMU_IPMMUB, 0, + 0, 0, 0, 0 } }, + { 0xffd201ac, 0xffd201ec, 8, /* IMR11SA / IMCR11SA */ + { IIC0_DTEI0, IIC0_WAITI0, IIC0_TACKI0, IIC0_ALI0, + 0, 0, IPMMUI, TSIF } }, + { 0xffd20104, 0, 16, /* INTAMASK */ + { 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, INTCS } }, +}; + +/* Priority is needed for INTCA to receive the INTCS interrupt */ +static struct intc_prio_reg intcs_prio_registers[] = { + { 0xffd20000, 0, 16, 4, /* IPRAS */ { 0, MVI3, _2DDMAC, ICB } }, + { 0xffd20004, 0, 16, 4, /* IPRBS */ { JPEG, LCDC, 0, 0 } }, + { 0xffd20008, 0, 16, 4, /* IPRCS */ { BBIF2, 0, 0, 0 } }, + { 0xffd20010, 0, 16, 4, /* IPRES */ { RTDMAC_1, VIO1_CEU, 0, VPU } }, + { 0xffd20014, 0, 16, 4, /* IPRFS */ { 0, RTDMAC_2, 0, CMT } }, + { 0xffd20018, 0, 16, 4, /* IPRGS */ { TMU_TUNI0, TMU_TUNI1, + TMU_TUNI2, 0 } }, + { 0xffd2001c, 0, 16, 4, /* IPRHS */ { 0, VIO3_VOU, VEU, BEU } }, + { 0xffd20020, 0, 16, 4, /* IPRIS */ { 0, MSIOF, TSIF, IIC0 } }, + { 0xffd20024, 0, 16, 4, /* IPRJS */ { 0, SGX530, 0, 0 } }, + { 0xffd20028, 0, 16, 4, /* IPRKS */ { BEM, ASA, IPMMUI, PEP } }, + { 0xffd2002c, 0, 16, 4, /* IPRLS */ { IPMMU, 0, VE2HO, HQE } }, + { 0xffd20030, 0, 16, 4, /* IPRMS */ { IIC2, 0, 0, 0 } }, +}; + +static struct resource intcs_resources[] __initdata = { + [0] = { + .start = 0xffd20000, + .end = 0xffd2ffff, + .flags = IORESOURCE_MEM, + } +}; + +static struct intc_desc intcs_desc __initdata = { + .name = "sh7367-intcs", + .resource = intcs_resources, + .num_resources = ARRAY_SIZE(intcs_resources), + .hw = INTC_HW_DESC(intcs_vectors, intcs_groups, intcs_mask_registers, + intcs_prio_registers, NULL, NULL), +}; + +static void intcs_demux(unsigned int irq, struct irq_desc *desc) +{ + void __iomem *reg = (void *)get_irq_data(irq); + unsigned int evtcodeas = ioread32(reg); + + generic_handle_irq(intcs_evt2irq(evtcodeas)); +} + void __init sh7367_init_irq(void) { - /* INTCA */ + void __iomem *intevtsa = ioremap_nocache(0xffd20100, PAGE_SIZE); + register_intc_controller(&intca_desc); + register_intc_controller(&intcs_desc); + + /* demux using INTEVTSA */ + set_irq_data(evt2irq(0xf80), (void *)intevtsa); + set_irq_chained_handler(evt2irq(0xf80), intcs_demux); } diff --git a/arch/arm/mach-shmobile/intc-sh7372.c b/arch/arm/mach-shmobile/intc-sh7372.c index 3ce9d9bd5899..e3551b56cd03 100644 --- a/arch/arm/mach-shmobile/intc-sh7372.c +++ b/arch/arm/mach-shmobile/intc-sh7372.c @@ -319,17 +319,17 @@ static struct intc_prio_reg intca_prio_registers[] __initdata = { { 0xe6950034, 0, 16, 4, /* IPRNA3 */ { AP_ARM2, 0, 0, 0 } }, { 0xe6950038, 0, 16, 4, /* IPROA3 */ { MFIS2, CPORTR2S, CMT14, CMT15 } }, - { 0xe694003c, 0, 16, 4, /* IPRPA3 */ { 0, 0, + { 0xe695003c, 0, 16, 4, /* IPRPA3 */ { 0, 0, MMC_MMC_ERR, MMC_MMC_NOR } }, - { 0xe6940040, 0, 16, 4, /* IPRQA3 */ { IIC4_ALI4, IIC4_TACKI4, + { 0xe6950040, 0, 16, 4, /* IPRQA3 */ { IIC4_ALI4, IIC4_TACKI4, IIC4_WAITI4, IIC4_DTEI4 } }, - { 0xe6940044, 0, 16, 4, /* IPRRA3 */ { IIC3_ALI3, IIC3_TACKI3, + { 0xe6950044, 0, 16, 4, /* IPRRA3 */ { IIC3_ALI3, IIC3_TACKI3, IIC3_WAITI3, IIC3_DTEI3 } }, - { 0xe6940048, 0, 16, 4, /* IPRSA3 */ { 0/*ERI*/, 0/*RXI*/, + { 0xe6950048, 0, 16, 4, /* IPRSA3 */ { 0/*ERI*/, 0/*RXI*/, 0/*TXI*/, 0/*TEI*/} }, - { 0xe694004c, 0, 16, 4, /* IPRTA3 */ { USB0_USB0I1, USB0_USB0I0, + { 0xe695004c, 0, 16, 4, /* IPRTA3 */ { USB0_USB0I1, USB0_USB0I0, USB1_USB1I1, USB1_USB1I0 } }, - { 0xe6940050, 0, 16, 4, /* IPRUA3 */ { USBHSDMAC1_USHDMI, 0, 0, 0 } }, + { 0xe6950050, 0, 16, 4, /* IPRUA3 */ { USBHSDMAC1_USHDMI, 0, 0, 0 } }, }; static struct intc_sense_reg intca_sense_registers[] __initdata = { @@ -363,7 +363,227 @@ static struct intc_desc intca_desc __initdata = { intca_sense_registers, intca_ack_registers), }; +enum { + UNUSED_INTCS = 0, + + INTCS, + + /* interrupt sources INTCS */ + VEU_VEU0, VEU_VEU1, VEU_VEU2, VEU_VEU3, + RTDMAC_1_DEI0, RTDMAC_1_DEI1, RTDMAC_1_DEI2, RTDMAC_1_DEI3, + CEU, BEU_BEU0, BEU_BEU1, BEU_BEU2, + VPU, + TSIF1, + _3DG_SGX530, + _2DDMAC, + IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2, + IPMMU_IPMMUR, IPMMU_IPMMUR2, + RTDMAC_2_DEI4, RTDMAC_2_DEI5, RTDMAC_2_DADERR, + MSIOF, + IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0, + TMU_TUNI0, TMU_TUNI1, TMU_TUNI2, + CMT0, + TSIF0, + LMB, + CTI, + ICB, + JPU_JPEG, + LCDC, + LCRC, + RTDMAC2_1_DEI0, RTDMAC2_1_DEI1, RTDMAC2_1_DEI2, RTDMAC2_1_DEI3, + RTDMAC2_2_DEI4, RTDMAC2_2_DEI5, RTDMAC2_2_DADERR, + ISP, + LCDC1, + CSIRX, + DSITX_DSITX0, + DSITX_DSITX1, + TMU1_TUNI0, TMU1_TUNI1, TMU1_TUNI2, + CMT4, + DSITX1_DSITX1_0, + DSITX1_DSITX1_1, + CPORTS2R, + JPU6E, + + /* interrupt groups INTCS */ + RTDMAC_1, RTDMAC_2, VEU, BEU, IIC0, IPMMU, IIC2, + RTDMAC2_1, RTDMAC2_2, TMU1, DSITX, +}; + +static struct intc_vect intcs_vectors[] = { + INTCS_VECT(VEU_VEU0, 0x700), INTCS_VECT(VEU_VEU1, 0x720), + INTCS_VECT(VEU_VEU2, 0x740), INTCS_VECT(VEU_VEU3, 0x760), + INTCS_VECT(RTDMAC_1_DEI0, 0x800), INTCS_VECT(RTDMAC_1_DEI1, 0x820), + INTCS_VECT(RTDMAC_1_DEI2, 0x840), INTCS_VECT(RTDMAC_1_DEI3, 0x860), + INTCS_VECT(CEU, 0x880), INTCS_VECT(BEU_BEU0, 0x8a0), + INTCS_VECT(BEU_BEU1, 0x8c0), INTCS_VECT(BEU_BEU2, 0x8e0), + INTCS_VECT(VPU, 0x980), + INTCS_VECT(TSIF1, 0x9a0), + INTCS_VECT(_3DG_SGX530, 0x9e0), + INTCS_VECT(_2DDMAC, 0xa00), + INTCS_VECT(IIC2_ALI2, 0xa80), INTCS_VECT(IIC2_TACKI2, 0xaa0), + INTCS_VECT(IIC2_WAITI2, 0xac0), INTCS_VECT(IIC2_DTEI2, 0xae0), + INTCS_VECT(IPMMU_IPMMUR, 0xb00), INTCS_VECT(IPMMU_IPMMUR2, 0xb20), + INTCS_VECT(RTDMAC_2_DEI4, 0xb80), INTCS_VECT(RTDMAC_2_DEI5, 0xba0), + INTCS_VECT(RTDMAC_2_DADERR, 0xbc0), + INTCS_VECT(IIC0_ALI0, 0xe00), INTCS_VECT(IIC0_TACKI0, 0xe20), + INTCS_VECT(IIC0_WAITI0, 0xe40), INTCS_VECT(IIC0_DTEI0, 0xe60), + INTCS_VECT(TMU_TUNI0, 0xe80), INTCS_VECT(TMU_TUNI1, 0xea0), + INTCS_VECT(TMU_TUNI2, 0xec0), + INTCS_VECT(CMT0, 0xf00), + INTCS_VECT(TSIF0, 0xf20), + INTCS_VECT(LMB, 0xf60), + INTCS_VECT(CTI, 0x400), + INTCS_VECT(ICB, 0x480), + INTCS_VECT(JPU_JPEG, 0x560), + INTCS_VECT(LCDC, 0x580), + INTCS_VECT(LCRC, 0x5a0), + INTCS_VECT(RTDMAC2_1_DEI0, 0x1300), INTCS_VECT(RTDMAC2_1_DEI1, 0x1320), + INTCS_VECT(RTDMAC2_1_DEI2, 0x1340), INTCS_VECT(RTDMAC2_1_DEI3, 0x1360), + INTCS_VECT(RTDMAC2_2_DEI4, 0x1380), INTCS_VECT(RTDMAC2_2_DEI5, 0x13a0), + INTCS_VECT(RTDMAC2_2_DADERR, 0x13c0), + INTCS_VECT(ISP, 0x1720), + INTCS_VECT(LCDC1, 0x1780), + INTCS_VECT(CSIRX, 0x17a0), + INTCS_VECT(DSITX_DSITX0, 0x17c0), + INTCS_VECT(DSITX_DSITX1, 0x17e0), + INTCS_VECT(TMU1_TUNI0, 0x1900), INTCS_VECT(TMU1_TUNI1, 0x1920), + INTCS_VECT(TMU1_TUNI2, 0x1940), + INTCS_VECT(CMT4, 0x1980), + INTCS_VECT(DSITX1_DSITX1_0, 0x19a0), + INTCS_VECT(DSITX1_DSITX1_1, 0x19c0), + INTCS_VECT(CPORTS2R, 0x1a20), + INTCS_VECT(JPU6E, 0x1a80), + + INTC_VECT(INTCS, 0xf80), +}; + +static struct intc_group intcs_groups[] __initdata = { + INTC_GROUP(RTDMAC_1, RTDMAC_1_DEI0, RTDMAC_1_DEI1, + RTDMAC_1_DEI2, RTDMAC_1_DEI3), + INTC_GROUP(RTDMAC_2, RTDMAC_2_DEI4, RTDMAC_2_DEI5, RTDMAC_2_DADERR), + INTC_GROUP(VEU, VEU_VEU0, VEU_VEU1, VEU_VEU2, VEU_VEU3), + INTC_GROUP(BEU, BEU_BEU0, BEU_BEU1, BEU_BEU2), + INTC_GROUP(IIC0, IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0), + INTC_GROUP(IPMMU, IPMMU_IPMMUR, IPMMU_IPMMUR2), + INTC_GROUP(IIC2, IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2), + INTC_GROUP(RTDMAC2_1, RTDMAC2_1_DEI0, RTDMAC2_1_DEI1, + RTDMAC2_1_DEI2, RTDMAC2_1_DEI3), + INTC_GROUP(RTDMAC2_2, RTDMAC2_2_DEI4, + RTDMAC2_2_DEI5, RTDMAC2_2_DADERR), + INTC_GROUP(TMU1, TMU1_TUNI2, TMU1_TUNI1, TMU1_TUNI0), + INTC_GROUP(DSITX, DSITX_DSITX0, DSITX_DSITX1), +}; + +static struct intc_mask_reg intcs_mask_registers[] = { + { 0xffd20184, 0xffd201c4, 8, /* IMR1SA / IMCR1SA */ + { BEU_BEU2, BEU_BEU1, BEU_BEU0, CEU, + VEU_VEU3, VEU_VEU2, VEU_VEU1, VEU_VEU0 } }, + { 0xffd20188, 0xffd201c8, 8, /* IMR2SA / IMCR2SA */ + { 0, 0, 0, VPU, + 0, 0, 0, 0 } }, + { 0xffd2018c, 0xffd201cc, 8, /* IMR3SA / IMCR3SA */ + { 0, 0, 0, _2DDMAC, + 0, 0, 0, ICB } }, + { 0xffd20190, 0xffd201d0, 8, /* IMR4SA / IMCR4SA */ + { 0, 0, 0, CTI, + JPU_JPEG, 0, LCRC, LCDC } }, + { 0xffd20194, 0xffd201d4, 8, /* IMR5SA / IMCR5SA */ + { 0, RTDMAC_2_DADERR, RTDMAC_2_DEI5, RTDMAC_2_DEI4, + RTDMAC_1_DEI3, RTDMAC_1_DEI2, RTDMAC_1_DEI1, RTDMAC_1_DEI0 } }, + { 0xffd20198, 0xffd201d8, 8, /* IMR6SA / IMCR6SA */ + { 0, 0, MSIOF, 0, + _3DG_SGX530, 0, 0, 0 } }, + { 0xffd2019c, 0xffd201dc, 8, /* IMR7SA / IMCR7SA */ + { 0, TMU_TUNI2, TMU_TUNI1, TMU_TUNI0, + 0, 0, 0, 0 } }, + { 0xffd201a4, 0xffd201e4, 8, /* IMR9SA / IMCR9SA */ + { 0, 0, 0, CMT0, + IIC2_DTEI2, IIC2_WAITI2, IIC2_TACKI2, IIC2_ALI2 } }, + { 0xffd201a8, 0xffd201e8, 8, /* IMR10SA / IMCR10SA */ + { 0, 0, IPMMU_IPMMUR2, IPMMU_IPMMUR, + 0, 0, 0, 0 } }, + { 0xffd201ac, 0xffd201ec, 8, /* IMR11SA / IMCR11SA */ + { IIC0_DTEI0, IIC0_WAITI0, IIC0_TACKI0, IIC0_ALI0, + 0, TSIF1, LMB, TSIF0 } }, + { 0xffd50180, 0xffd501c0, 8, /* IMR0SA3 / IMCR0SA3 */ + { 0, RTDMAC2_2_DADERR, RTDMAC2_2_DEI5, RTDMAC2_2_DEI4, + RTDMAC2_1_DEI3, RTDMAC2_1_DEI2, RTDMAC2_1_DEI1, RTDMAC2_1_DEI0 } }, + { 0xffd50190, 0xffd501d0, 8, /* IMR4SA3 / IMCR4SA3 */ + { 0, ISP, 0, 0, + LCDC1, CSIRX, DSITX_DSITX0, DSITX_DSITX1 } }, + { 0xffd50198, 0xffd501d8, 8, /* IMR6SA3 / IMCR6SA3 */ + { 0, TMU1_TUNI2, TMU1_TUNI1, TMU1_TUNI0, + CMT4, DSITX1_DSITX1_0, DSITX1_DSITX1_1, 0 } }, + { 0xffd5019c, 0xffd501dc, 8, /* IMR7SA3 / IMCR7SA3 */ + { 0, CPORTS2R, 0, 0, + JPU6E, 0, 0, 0 } }, + { 0xffd20104, 0, 16, /* INTAMASK */ + { 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, INTCS } }, +}; + +/* Priority is needed for INTCA to receive the INTCS interrupt */ +static struct intc_prio_reg intcs_prio_registers[] = { + { 0xffd20000, 0, 16, 4, /* IPRAS */ { CTI, 0, _2DDMAC, ICB } }, + { 0xffd20004, 0, 16, 4, /* IPRBS */ { JPU_JPEG, LCDC, 0, LCRC } }, + { 0xffd20010, 0, 16, 4, /* IPRES */ { RTDMAC_1, CEU, 0, VPU } }, + { 0xffd20014, 0, 16, 4, /* IPRFS */ { 0, RTDMAC_2, 0, CMT0 } }, + { 0xffd20018, 0, 16, 4, /* IPRGS */ { TMU_TUNI0, TMU_TUNI1, + TMU_TUNI2, TSIF1 } }, + { 0xffd2001c, 0, 16, 4, /* IPRHS */ { 0, 0, VEU, BEU } }, + { 0xffd20020, 0, 16, 4, /* IPRIS */ { 0, MSIOF, TSIF0, IIC0 } }, + { 0xffd20024, 0, 16, 4, /* IPRJS */ { 0, _3DG_SGX530, 0, 0 } }, + { 0xffd20028, 0, 16, 4, /* IPRKS */ { 0, 0, LMB, 0 } }, + { 0xffd2002c, 0, 16, 4, /* IPRLS */ { IPMMU, 0, 0, 0 } }, + { 0xffd20030, 0, 16, 4, /* IPRMS */ { IIC2, 0, 0, 0 } }, + { 0xffd50000, 0, 16, 4, /* IPRAS3 */ { RTDMAC2_1, 0, 0, 0 } }, + { 0xffd50004, 0, 16, 4, /* IPRBS3 */ { RTDMAC2_2, 0, 0, 0 } }, + { 0xffd50020, 0, 16, 4, /* IPRIS3 */ { 0, ISP, 0, 0 } }, + { 0xffd50024, 0, 16, 4, /* IPRJS3 */ { LCDC1, CSIRX, DSITX, 0 } }, + { 0xffd50030, 0, 16, 4, /* IPRMS3 */ { TMU1, 0, 0, 0 } }, + { 0xffd50034, 0, 16, 4, /* IPRNS3 */ { CMT4, DSITX1_DSITX1_0, + DSITX1_DSITX1_1, 0 } }, + { 0xffd50038, 0, 16, 4, /* IPROS3 */ { 0, CPORTS2R, 0, 0 } }, + { 0xffd5003c, 0, 16, 4, /* IPRPS3 */ { JPU6E, 0, 0, 0 } }, +}; + +static struct resource intcs_resources[] __initdata = { + [0] = { + .start = 0xffd20000, + .end = 0xffd201ff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 0xffd50000, + .end = 0xffd501ff, + .flags = IORESOURCE_MEM, + } +}; + +static struct intc_desc intcs_desc __initdata = { + .name = "sh7372-intcs", + .resource = intcs_resources, + .num_resources = ARRAY_SIZE(intcs_resources), + .hw = INTC_HW_DESC(intcs_vectors, intcs_groups, intcs_mask_registers, + intcs_prio_registers, NULL, NULL), +}; + +static void intcs_demux(unsigned int irq, struct irq_desc *desc) +{ + void __iomem *reg = (void *)get_irq_data(irq); + unsigned int evtcodeas = ioread32(reg); + + generic_handle_irq(intcs_evt2irq(evtcodeas)); +} + void __init sh7372_init_irq(void) { + void __iomem *intevtsa = ioremap_nocache(0xffd20100, PAGE_SIZE); + register_intc_controller(&intca_desc); + register_intc_controller(&intcs_desc); + + /* demux using INTEVTSA */ + set_irq_data(evt2irq(0xf80), (void *)intevtsa); + set_irq_chained_handler(evt2irq(0xf80), intcs_demux); } diff --git a/arch/arm/mach-shmobile/intc-sh7377.c b/arch/arm/mach-shmobile/intc-sh7377.c index 5c781e2d1897..2cdeb8ccd821 100644 --- a/arch/arm/mach-shmobile/intc-sh7377.c +++ b/arch/arm/mach-shmobile/intc-sh7377.c @@ -90,7 +90,7 @@ enum { ICUSB, ICUDMC }; -static struct intc_vect intca_vectors[] = { +static struct intc_vect intca_vectors[] __initdata = { INTC_VECT(IRQ0A, 0x0200), INTC_VECT(IRQ1A, 0x0220), INTC_VECT(IRQ2A, 0x0240), INTC_VECT(IRQ3A, 0x0260), INTC_VECT(IRQ4A, 0x0280), INTC_VECT(IRQ5A, 0x02a0), @@ -202,7 +202,7 @@ static struct intc_group intca_groups[] __initdata = { INTC_GROUP(ICUDMC, ICUDMC_ICUDMC1, ICUDMC_ICUDMC2), }; -static struct intc_mask_reg intca_mask_registers[] = { +static struct intc_mask_reg intca_mask_registers[] __initdata = { { 0xe6900040, 0xe6900060, 8, /* INTMSK00A / INTMSKCLR00A */ { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } }, { 0xe6900044, 0xe6900064, 8, /* INTMSK10A / INTMSKCLR10A */ @@ -272,7 +272,7 @@ static struct intc_mask_reg intca_mask_registers[] = { SCIFA6, 0, 0, 0 } }, }; -static struct intc_prio_reg intca_prio_registers[] = { +static struct intc_prio_reg intca_prio_registers[] __initdata = { { 0xe6900010, 0, 32, 4, /* INTPRI00A */ { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } }, { 0xe6900014, 0, 32, 4, /* INTPRI10A */ @@ -346,7 +346,301 @@ static struct intc_desc intca_desc __initdata = { intca_sense_registers, intca_ack_registers), }; +/* this macro ignore entry which is also in INTCA */ +#define __IGNORE(a...) +#define __IGNORE0(a...) 0 + +enum { + UNUSED_INTCS = 0, + + INTCS, + + /* interrupt sources INTCS */ + VEU_VEU0, VEU_VEU1, VEU_VEU2, VEU_VEU3, + RTDMAC1_1_DEI0, RTDMAC1_1_DEI1, RTDMAC1_1_DEI2, RTDMAC1_1_DEI3, + CEU, + BEU_BEU0, BEU_BEU1, BEU_BEU2, + __IGNORE(MFI) + __IGNORE(BBIF2) + VPU, + TSIF1, + __IGNORE(SGX540) + _2DDMAC, + IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2, + IPMMU_IPMMUR, IPMMU_IPMMUR2, + RTDMAC1_2_DEI4, RTDMAC1_2_DEI5, RTDMAC1_2_DADERR, + __IGNORE(KEYSC) + __IGNORE(TTI20) + __IGNORE(MSIOF) + IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0, + TMU_TUNI0, TMU_TUNI1, TMU_TUNI2, + CMT0, + TSIF0, + __IGNORE(CMT2) + LMB, + __IGNORE(MSUG) + __IGNORE(MSU_MSU, MSU_MSU2) + __IGNORE(CTI) + MVI3, + __IGNORE(RWDT0) + __IGNORE(RWDT1) + ICB, + PEP, + ASA, + __IGNORE(_2DG) + HQE, + JPU, + LCDC0, + __IGNORE(LCRC) + RTDMAC2_1_DEI0, RTDMAC2_1_DEI1, RTDMAC2_1_DEI2, RTDMAC2_1_DEI3, + RTDMAC2_2_DEI4, RTDMAC2_2_DEI5, RTDMAC2_2_DADERR, + FRC, + LCDC1, + CSIRX, + DSITX_DSITX0, DSITX_DSITX1, + __IGNORE(SPU2_SPU0, SPU2_SPU1) + __IGNORE(FSI) + __IGNORE(FMSI) + __IGNORE(SCUV) + TMU1_TUNI10, TMU1_TUNI11, TMU1_TUNI12, + TSIF2, + CMT4, + __IGNORE(MFIS2) + CPORTS2R, + + /* interrupt groups INTCS */ + RTDMAC1_1, RTDMAC1_2, VEU, BEU, IIC0, __IGNORE(MSU) IPMMU, + IIC2, RTDMAC2_1, RTDMAC2_2, DSITX, __IGNORE(SPU2) TMU1, +}; + +#define INTCS_INTVECT 0x0F80 +static struct intc_vect intcs_vectors[] __initdata = { + INTCS_VECT(VEU_VEU0, 0x0700), INTCS_VECT(VEU_VEU1, 0x0720), + INTCS_VECT(VEU_VEU2, 0x0740), INTCS_VECT(VEU_VEU3, 0x0760), + INTCS_VECT(RTDMAC1_1_DEI0, 0x0800), INTCS_VECT(RTDMAC1_1_DEI1, 0x0820), + INTCS_VECT(RTDMAC1_1_DEI2, 0x0840), INTCS_VECT(RTDMAC1_1_DEI3, 0x0860), + INTCS_VECT(CEU, 0x0880), + INTCS_VECT(BEU_BEU0, 0x08A0), + INTCS_VECT(BEU_BEU1, 0x08C0), + INTCS_VECT(BEU_BEU2, 0x08E0), + __IGNORE(INTCS_VECT(MFI, 0x0900)) + __IGNORE(INTCS_VECT(BBIF2, 0x0960)) + INTCS_VECT(VPU, 0x0980), + INTCS_VECT(TSIF1, 0x09A0), + __IGNORE(INTCS_VECT(SGX540, 0x09E0)) + INTCS_VECT(_2DDMAC, 0x0A00), + INTCS_VECT(IIC2_ALI2, 0x0A80), INTCS_VECT(IIC2_TACKI2, 0x0AA0), + INTCS_VECT(IIC2_WAITI2, 0x0AC0), INTCS_VECT(IIC2_DTEI2, 0x0AE0), + INTCS_VECT(IPMMU_IPMMUR, 0x0B00), INTCS_VECT(IPMMU_IPMMUR2, 0x0B20), + INTCS_VECT(RTDMAC1_2_DEI4, 0x0B80), + INTCS_VECT(RTDMAC1_2_DEI5, 0x0BA0), + INTCS_VECT(RTDMAC1_2_DADERR, 0x0BC0), + __IGNORE(INTCS_VECT(KEYSC 0x0BE0)) + __IGNORE(INTCS_VECT(TTI20, 0x0C80)) + __IGNORE(INTCS_VECT(MSIOF, 0x0D20)) + INTCS_VECT(IIC0_ALI0, 0x0E00), INTCS_VECT(IIC0_TACKI0, 0x0E20), + INTCS_VECT(IIC0_WAITI0, 0x0E40), INTCS_VECT(IIC0_DTEI0, 0x0E60), + INTCS_VECT(TMU_TUNI0, 0x0E80), + INTCS_VECT(TMU_TUNI1, 0x0EA0), + INTCS_VECT(TMU_TUNI2, 0x0EC0), + INTCS_VECT(CMT0, 0x0F00), + INTCS_VECT(TSIF0, 0x0F20), + __IGNORE(INTCS_VECT(CMT2, 0x0F40)) + INTCS_VECT(LMB, 0x0F60), + __IGNORE(INTCS_VECT(MSUG, 0x0F80)) + __IGNORE(INTCS_VECT(MSU_MSU, 0x0FA0)) + __IGNORE(INTCS_VECT(MSU_MSU2, 0x0FC0)) + __IGNORE(INTCS_VECT(CTI, 0x0400)) + INTCS_VECT(MVI3, 0x0420), + __IGNORE(INTCS_VECT(RWDT0, 0x0440)) + __IGNORE(INTCS_VECT(RWDT1, 0x0460)) + INTCS_VECT(ICB, 0x0480), + INTCS_VECT(PEP, 0x04A0), + INTCS_VECT(ASA, 0x04C0), + __IGNORE(INTCS_VECT(_2DG, 0x04E0)) + INTCS_VECT(HQE, 0x0540), + INTCS_VECT(JPU, 0x0560), + INTCS_VECT(LCDC0, 0x0580), + __IGNORE(INTCS_VECT(LCRC, 0x05A0)) + INTCS_VECT(RTDMAC2_1_DEI0, 0x1300), INTCS_VECT(RTDMAC2_1_DEI1, 0x1320), + INTCS_VECT(RTDMAC2_1_DEI2, 0x1340), INTCS_VECT(RTDMAC2_1_DEI3, 0x1360), + INTCS_VECT(RTDMAC2_2_DEI4, 0x1380), INTCS_VECT(RTDMAC2_2_DEI5, 0x13A0), + INTCS_VECT(RTDMAC2_2_DADERR, 0x13C0), + INTCS_VECT(FRC, 0x1700), + INTCS_VECT(LCDC1, 0x1780), + INTCS_VECT(CSIRX, 0x17A0), + INTCS_VECT(DSITX_DSITX0, 0x17C0), INTCS_VECT(DSITX_DSITX1, 0x17E0), + __IGNORE(INTCS_VECT(SPU2_SPU0, 0x1800)) + __IGNORE(INTCS_VECT(SPU2_SPU1, 0x1820)) + __IGNORE(INTCS_VECT(FSI, 0x1840)) + __IGNORE(INTCS_VECT(FMSI, 0x1860)) + __IGNORE(INTCS_VECT(SCUV, 0x1880)) + INTCS_VECT(TMU1_TUNI10, 0x1900), INTCS_VECT(TMU1_TUNI11, 0x1920), + INTCS_VECT(TMU1_TUNI12, 0x1940), + INTCS_VECT(TSIF2, 0x1960), + INTCS_VECT(CMT4, 0x1980), + __IGNORE(INTCS_VECT(MFIS2, 0x1A00)) + INTCS_VECT(CPORTS2R, 0x1A20), + + INTC_VECT(INTCS, INTCS_INTVECT), +}; + +static struct intc_group intcs_groups[] __initdata = { + INTC_GROUP(RTDMAC1_1, + RTDMAC1_1_DEI0, RTDMAC1_1_DEI1, + RTDMAC1_1_DEI2, RTDMAC1_1_DEI3), + INTC_GROUP(RTDMAC1_2, + RTDMAC1_2_DEI4, RTDMAC1_2_DEI5, RTDMAC1_2_DADERR), + INTC_GROUP(VEU, VEU_VEU0, VEU_VEU1, VEU_VEU2, VEU_VEU3), + INTC_GROUP(BEU, BEU_BEU0, BEU_BEU1, BEU_BEU2), + INTC_GROUP(IIC0, IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0), + __IGNORE(INTC_GROUP(MSU, MSU_MSU, MSU_MSU2)) + INTC_GROUP(IPMMU, IPMMU_IPMMUR, IPMMU_IPMMUR2), + INTC_GROUP(IIC2, IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2), + INTC_GROUP(RTDMAC2_1, + RTDMAC2_1_DEI0, RTDMAC2_1_DEI1, + RTDMAC2_1_DEI2, RTDMAC2_1_DEI3), + INTC_GROUP(RTDMAC2_2, RTDMAC2_2_DEI4, RTDMAC2_2_DEI5, RTDMAC2_2_DADERR), + INTC_GROUP(DSITX, DSITX_DSITX0, DSITX_DSITX1), + __IGNORE(INTC_GROUP(SPU2, SPU2_SPU0, SPU2_SPU1)) + INTC_GROUP(TMU1, TMU1_TUNI10, TMU1_TUNI11, TMU1_TUNI12), +}; + +static struct intc_mask_reg intcs_mask_registers[] __initdata = { + { 0xE6940184, 0xE69401C4, 8, /* IMR1AS / IMCR1AS */ + { BEU_BEU2, BEU_BEU1, BEU_BEU0, CEU, + VEU_VEU3, VEU_VEU2, VEU_VEU1, VEU_VEU0 } }, + { 0xE6940188, 0xE69401C8, 8, /* IMR2AS / IMCR2AS */ + { 0, 0, 0, VPU, + __IGNORE0(BBIF2), 0, 0, __IGNORE0(MFI) } }, + { 0xE694018C, 0xE69401CC, 8, /* IMR3AS / IMCR3AS */ + { 0, 0, 0, _2DDMAC, + __IGNORE0(_2DG), ASA, PEP, ICB } }, + { 0xE6940190, 0xE69401D0, 8, /* IMR4AS / IMCR4AS */ + { 0, 0, MVI3, __IGNORE0(CTI), + JPU, HQE, __IGNORE0(LCRC), LCDC0 } }, + { 0xE6940194, 0xE69401D4, 8, /* IMR5AS / IMCR5AS */ + { __IGNORE0(KEYSC), RTDMAC1_2_DADERR, RTDMAC1_2_DEI5, RTDMAC1_2_DEI4, + RTDMAC1_1_DEI3, RTDMAC1_1_DEI2, RTDMAC1_1_DEI1, RTDMAC1_1_DEI0 } }, + __IGNORE({ 0xE6940198, 0xE69401D8, 8, /* IMR6AS / IMCR6AS */ + { 0, 0, MSIOF, 0, + SGX540, 0, TTI20, 0 } }) + { 0xE694019C, 0xE69401DC, 8, /* IMR7AS / IMCR7AS */ + { 0, TMU_TUNI2, TMU_TUNI1, TMU_TUNI0, + 0, 0, 0, 0 } }, + __IGNORE({ 0xE69401A0, 0xE69401E0, 8, /* IMR8AS / IMCR8AS */ + { 0, 0, 0, 0, + 0, MSU_MSU, MSU_MSU2, MSUG } }) + { 0xE69401A4, 0xE69401E4, 8, /* IMR9AS / IMCR9AS */ + { __IGNORE0(RWDT1), __IGNORE0(RWDT0), __IGNORE0(CMT2), CMT0, + IIC2_DTEI2, IIC2_WAITI2, IIC2_TACKI2, IIC2_ALI2 } }, + { 0xE69401A8, 0xE69401E8, 8, /* IMR10AS / IMCR10AS */ + { 0, 0, IPMMU_IPMMUR, IPMMU_IPMMUR2, + 0, 0, 0, 0 } }, + { 0xE69401AC, 0xE69401EC, 8, /* IMR11AS / IMCR11AS */ + { IIC0_DTEI0, IIC0_WAITI0, IIC0_TACKI0, IIC0_ALI0, + 0, TSIF1, LMB, TSIF0 } }, + { 0xE6950180, 0xE69501C0, 8, /* IMR0AS3 / IMCR0AS3 */ + { RTDMAC2_1_DEI0, RTDMAC2_1_DEI1, RTDMAC2_1_DEI2, RTDMAC2_1_DEI3, + RTDMAC2_2_DEI4, RTDMAC2_2_DEI5, RTDMAC2_2_DADERR, 0 } }, + { 0xE6950190, 0xE69501D0, 8, /* IMR4AS3 / IMCR4AS3 */ + { FRC, 0, 0, 0, + LCDC1, CSIRX, DSITX_DSITX0, DSITX_DSITX1 } }, + __IGNORE({ 0xE6950194, 0xE69501D4, 8, /* IMR5AS3 / IMCR5AS3 */ + {SPU2_SPU0, SPU2_SPU1, FSI, FMSI, + SCUV, 0, 0, 0 } }) + { 0xE6950198, 0xE69501D8, 8, /* IMR6AS3 / IMCR6AS3 */ + { TMU1_TUNI10, TMU1_TUNI11, TMU1_TUNI12, TSIF2, + CMT4, 0, 0, 0 } }, + { 0xE695019C, 0xE69501DC, 8, /* IMR7AS3 / IMCR7AS3 */ + { __IGNORE0(MFIS2), CPORTS2R, 0, 0, + 0, 0, 0, 0 } }, + { 0xFFD20104, 0, 16, /* INTAMASK */ + { 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, INTCS } } +}; + +static struct intc_prio_reg intcs_prio_registers[] __initdata = { + /* IPRAS */ + { 0xFFD20000, 0, 16, 4, { __IGNORE0(CTI), MVI3, _2DDMAC, ICB } }, + /* IPRBS */ + { 0xFFD20004, 0, 16, 4, { JPU, LCDC0, 0, __IGNORE0(LCRC) } }, + /* IPRCS */ + __IGNORE({ 0xFFD20008, 0, 16, 4, { BBIF2, 0, 0, 0 } }) + /* IPRES */ + { 0xFFD20010, 0, 16, 4, { RTDMAC1_1, CEU, __IGNORE0(MFI), VPU } }, + /* IPRFS */ + { 0xFFD20014, 0, 16, 4, + { __IGNORE0(KEYSC), RTDMAC1_2, __IGNORE0(CMT2), CMT0 } }, + /* IPRGS */ + { 0xFFD20018, 0, 16, 4, { TMU_TUNI0, TMU_TUNI1, TMU_TUNI2, TSIF1 } }, + /* IPRHS */ + { 0xFFD2001C, 0, 16, 4, { __IGNORE0(TTI20), 0, VEU, BEU } }, + /* IPRIS */ + { 0xFFD20020, 0, 16, 4, { 0, __IGNORE0(MSIOF), TSIF0, IIC0 } }, + /* IPRJS */ + __IGNORE({ 0xFFD20024, 0, 16, 4, { 0, SGX540, MSUG, MSU } }) + /* IPRKS */ + { 0xFFD20028, 0, 16, 4, { __IGNORE0(_2DG), ASA, LMB, PEP } }, + /* IPRLS */ + { 0xFFD2002C, 0, 16, 4, { IPMMU, 0, 0, HQE } }, + /* IPRMS */ + { 0xFFD20030, 0, 16, 4, + { IIC2, 0, __IGNORE0(RWDT1), __IGNORE0(RWDT0) } }, + /* IPRAS3 */ + { 0xFFD50000, 0, 16, 4, { RTDMAC2_1, 0, 0, 0 } }, + /* IPRBS3 */ + { 0xFFD50004, 0, 16, 4, { RTDMAC2_2, 0, 0, 0 } }, + /* IPRIS3 */ + { 0xFFD50020, 0, 16, 4, { FRC, 0, 0, 0 } }, + /* IPRJS3 */ + { 0xFFD50024, 0, 16, 4, { LCDC1, CSIRX, DSITX, 0 } }, + /* IPRKS3 */ + __IGNORE({ 0xFFD50028, 0, 16, 4, { SPU2, 0, FSI, FMSI } }) + /* IPRLS3 */ + __IGNORE({ 0xFFD5002C, 0, 16, 4, { SCUV, 0, 0, 0 } }) + /* IPRMS3 */ + { 0xFFD50030, 0, 16, 4, { TMU1, 0, 0, TSIF2 } }, + /* IPRNS3 */ + { 0xFFD50034, 0, 16, 4, { CMT4, 0, 0, 0 } }, + /* IPROS3 */ + { 0xFFD50038, 0, 16, 4, { __IGNORE0(MFIS2), CPORTS2R, 0, 0 } }, +}; + +static struct resource intcs_resources[] __initdata = { + [0] = { + .start = 0xffd20000, + .end = 0xffd500ff, + .flags = IORESOURCE_MEM, + } +}; + +static struct intc_desc intcs_desc __initdata = { + .name = "sh7377-intcs", + .resource = intcs_resources, + .num_resources = ARRAY_SIZE(intcs_resources), + .hw = INTC_HW_DESC(intcs_vectors, intcs_groups, + intcs_mask_registers, intcs_prio_registers, + NULL, NULL), +}; + +static void intcs_demux(unsigned int irq, struct irq_desc *desc) +{ + void __iomem *reg = (void *)get_irq_data(irq); + unsigned int evtcodeas = ioread32(reg); + + generic_handle_irq(intcs_evt2irq(evtcodeas)); +} + +#define INTEVTSA 0xFFD20100 void __init sh7377_init_irq(void) { + void __iomem *intevtsa = ioremap_nocache(INTEVTSA, PAGE_SIZE); + register_intc_controller(&intca_desc); + register_intc_controller(&intcs_desc); + + /* demux using INTEVTSA */ + set_irq_data(evt2irq(INTCS_INTVECT), (void *)intevtsa); + set_irq_chained_handler(evt2irq(INTCS_INTVECT), intcs_demux); } diff --git a/arch/arm/mach-shmobile/setup-sh7367.c b/arch/arm/mach-shmobile/setup-sh7367.c index eca90716140e..3148c11a550e 100644 --- a/arch/arm/mach-shmobile/setup-sh7367.c +++ b/arch/arm/mach-shmobile/setup-sh7367.c @@ -31,11 +31,13 @@ #include <asm/mach-types.h> #include <asm/mach/arch.h> +/* SCIFA0 */ static struct plat_sci_port scif0_platform_data = { .mapbase = 0xe6c40000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 80, 80, 80, 80 }, + .irqs = { evt2irq(0xc00), evt2irq(0xc00), + evt2irq(0xc00), evt2irq(0xc00) }, }; static struct platform_device scif0_device = { @@ -46,11 +48,13 @@ static struct platform_device scif0_device = { }, }; +/* SCIFA1 */ static struct plat_sci_port scif1_platform_data = { .mapbase = 0xe6c50000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 81, 81, 81, 81 }, + .irqs = { evt2irq(0xc20), evt2irq(0xc20), + evt2irq(0xc20), evt2irq(0xc20) }, }; static struct platform_device scif1_device = { @@ -61,11 +65,13 @@ static struct platform_device scif1_device = { }, }; +/* SCIFA2 */ static struct plat_sci_port scif2_platform_data = { .mapbase = 0xe6c60000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 82, 82, 82, 82 }, + .irqs = { evt2irq(0xc40), evt2irq(0xc40), + evt2irq(0xc40), evt2irq(0xc40) }, }; static struct platform_device scif2_device = { @@ -76,11 +82,13 @@ static struct platform_device scif2_device = { }, }; +/* SCIFA3 */ static struct plat_sci_port scif3_platform_data = { .mapbase = 0xe6c70000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 83, 83, 83, 83 }, + .irqs = { evt2irq(0xc60), evt2irq(0xc60), + evt2irq(0xc60), evt2irq(0xc60) }, }; static struct platform_device scif3_device = { @@ -91,11 +99,13 @@ static struct platform_device scif3_device = { }, }; +/* SCIFA4 */ static struct plat_sci_port scif4_platform_data = { .mapbase = 0xe6c80000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 89, 89, 89, 89 }, + .irqs = { evt2irq(0xd20), evt2irq(0xd20), + evt2irq(0xd20), evt2irq(0xd20) }, }; static struct platform_device scif4_device = { @@ -106,11 +116,13 @@ static struct platform_device scif4_device = { }, }; +/* SCIFA5 */ static struct plat_sci_port scif5_platform_data = { .mapbase = 0xe6cb0000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 90, 90, 90, 90 }, + .irqs = { evt2irq(0xd40), evt2irq(0xd40), + evt2irq(0xd40), evt2irq(0xd40) }, }; static struct platform_device scif5_device = { @@ -121,11 +133,13 @@ static struct platform_device scif5_device = { }, }; +/* SCIFB */ static struct plat_sci_port scif6_platform_data = { .mapbase = 0xe6c30000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 91, 91, 91, 91 }, + .irqs = { evt2irq(0xd60), evt2irq(0xd60), + evt2irq(0xd60), evt2irq(0xd60) }, }; static struct platform_device scif6_device = { @@ -153,7 +167,7 @@ static struct resource cmt10_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = 72, + .start = evt2irq(0xb00), /* CMT1_CMT10 */ .flags = IORESOURCE_IRQ, }, }; diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c index 1d1153290f59..e26686c9d0b6 100644 --- a/arch/arm/mach-shmobile/setup-sh7372.c +++ b/arch/arm/mach-shmobile/setup-sh7372.c @@ -26,17 +26,21 @@ #include <linux/input.h> #include <linux/io.h> #include <linux/serial_sci.h> +#include <linux/sh_dma.h> #include <linux/sh_intc.h> #include <linux/sh_timer.h> #include <mach/hardware.h> +#include <mach/sh7372.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> +/* SCIFA0 */ static struct plat_sci_port scif0_platform_data = { .mapbase = 0xe6c40000, .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 80, 80, 80, 80 }, + .type = PORT_SCIFA, + .irqs = { evt2irq(0x0c00), evt2irq(0x0c00), + evt2irq(0x0c00), evt2irq(0x0c00) }, }; static struct platform_device scif0_device = { @@ -47,11 +51,13 @@ static struct platform_device scif0_device = { }, }; +/* SCIFA1 */ static struct plat_sci_port scif1_platform_data = { .mapbase = 0xe6c50000, .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 81, 81, 81, 81 }, + .type = PORT_SCIFA, + .irqs = { evt2irq(0x0c20), evt2irq(0x0c20), + evt2irq(0x0c20), evt2irq(0x0c20) }, }; static struct platform_device scif1_device = { @@ -62,11 +68,13 @@ static struct platform_device scif1_device = { }, }; +/* SCIFA2 */ static struct plat_sci_port scif2_platform_data = { .mapbase = 0xe6c60000, .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 82, 82, 82, 82 }, + .type = PORT_SCIFA, + .irqs = { evt2irq(0x0c40), evt2irq(0x0c40), + evt2irq(0x0c40), evt2irq(0x0c40) }, }; static struct platform_device scif2_device = { @@ -77,11 +85,13 @@ static struct platform_device scif2_device = { }, }; +/* SCIFA3 */ static struct plat_sci_port scif3_platform_data = { .mapbase = 0xe6c70000, .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 83, 83, 83, 83 }, + .type = PORT_SCIFA, + .irqs = { evt2irq(0x0c60), evt2irq(0x0c60), + evt2irq(0x0c60), evt2irq(0x0c60) }, }; static struct platform_device scif3_device = { @@ -92,11 +102,13 @@ static struct platform_device scif3_device = { }, }; +/* SCIFA4 */ static struct plat_sci_port scif4_platform_data = { .mapbase = 0xe6c80000, .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 89, 89, 89, 89 }, + .type = PORT_SCIFA, + .irqs = { evt2irq(0x0d20), evt2irq(0x0d20), + evt2irq(0x0d20), evt2irq(0x0d20) }, }; static struct platform_device scif4_device = { @@ -107,11 +119,13 @@ static struct platform_device scif4_device = { }, }; +/* SCIFA5 */ static struct plat_sci_port scif5_platform_data = { .mapbase = 0xe6cb0000, .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 90, 90, 90, 90 }, + .type = PORT_SCIFA, + .irqs = { evt2irq(0x0d40), evt2irq(0x0d40), + evt2irq(0x0d40), evt2irq(0x0d40) }, }; static struct platform_device scif5_device = { @@ -122,11 +136,13 @@ static struct platform_device scif5_device = { }, }; +/* SCIFB */ static struct plat_sci_port scif6_platform_data = { .mapbase = 0xe6c30000, .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 91, 91, 91, 91 }, + .type = PORT_SCIFB, + .irqs = { evt2irq(0x0d60), evt2irq(0x0d60), + evt2irq(0x0d60), evt2irq(0x0d60) }, }; static struct platform_device scif6_device = { @@ -137,11 +153,12 @@ static struct platform_device scif6_device = { }, }; +/* CMT */ static struct sh_timer_config cmt10_platform_data = { .name = "CMT10", .channel_offset = 0x10, .timer_bit = 0, - .clk = "r_clk", + .clk = "cmt1", .clockevent_rating = 125, .clocksource_rating = 125, }; @@ -154,7 +171,7 @@ static struct resource cmt10_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = 72, + .start = evt2irq(0x0b00), /* CMT1_CMT10 */ .flags = IORESOURCE_IRQ, }, }; @@ -169,6 +186,337 @@ static struct platform_device cmt10_device = { .num_resources = ARRAY_SIZE(cmt10_resources), }; +/* I2C */ +static struct resource iic0_resources[] = { + [0] = { + .name = "IIC0", + .start = 0xFFF20000, + .end = 0xFFF20425 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = intcs_evt2irq(0xe00), /* IIC0_ALI0 */ + .end = intcs_evt2irq(0xe60), /* IIC0_DTEI0 */ + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device iic0_device = { + .name = "i2c-sh_mobile", + .id = 0, /* "i2c0" clock */ + .num_resources = ARRAY_SIZE(iic0_resources), + .resource = iic0_resources, +}; + +static struct resource iic1_resources[] = { + [0] = { + .name = "IIC1", + .start = 0xE6C20000, + .end = 0xE6C20425 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = evt2irq(0x780), /* IIC1_ALI1 */ + .end = evt2irq(0x7e0), /* IIC1_DTEI1 */ + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device iic1_device = { + .name = "i2c-sh_mobile", + .id = 1, /* "i2c1" clock */ + .num_resources = ARRAY_SIZE(iic1_resources), + .resource = iic1_resources, +}; + +/* DMA */ +/* Transmit sizes and respective CHCR register values */ +enum { + XMIT_SZ_8BIT = 0, + XMIT_SZ_16BIT = 1, + XMIT_SZ_32BIT = 2, + XMIT_SZ_64BIT = 7, + XMIT_SZ_128BIT = 3, + XMIT_SZ_256BIT = 4, + XMIT_SZ_512BIT = 5, +}; + +/* log2(size / 8) - used to calculate number of transfers */ +#define TS_SHIFT { \ + [XMIT_SZ_8BIT] = 0, \ + [XMIT_SZ_16BIT] = 1, \ + [XMIT_SZ_32BIT] = 2, \ + [XMIT_SZ_64BIT] = 3, \ + [XMIT_SZ_128BIT] = 4, \ + [XMIT_SZ_256BIT] = 5, \ + [XMIT_SZ_512BIT] = 6, \ +} + +#define TS_INDEX2VAL(i) ((((i) & 3) << 3) | \ + (((i) & 0xc) << (20 - 2))) + +static const struct sh_dmae_slave_config sh7372_dmae_slaves[] = { + { + .slave_id = SHDMA_SLAVE_SCIF0_TX, + .addr = 0xe6c40020, + .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), + .mid_rid = 0x21, + }, { + .slave_id = SHDMA_SLAVE_SCIF0_RX, + .addr = 0xe6c40024, + .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), + .mid_rid = 0x22, + }, { + .slave_id = SHDMA_SLAVE_SCIF1_TX, + .addr = 0xe6c50020, + .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), + .mid_rid = 0x25, + }, { + .slave_id = SHDMA_SLAVE_SCIF1_RX, + .addr = 0xe6c50024, + .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), + .mid_rid = 0x26, + }, { + .slave_id = SHDMA_SLAVE_SCIF2_TX, + .addr = 0xe6c60020, + .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), + .mid_rid = 0x29, + }, { + .slave_id = SHDMA_SLAVE_SCIF2_RX, + .addr = 0xe6c60024, + .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), + .mid_rid = 0x2a, + }, { + .slave_id = SHDMA_SLAVE_SCIF3_TX, + .addr = 0xe6c70020, + .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), + .mid_rid = 0x2d, + }, { + .slave_id = SHDMA_SLAVE_SCIF3_RX, + .addr = 0xe6c70024, + .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), + .mid_rid = 0x2e, + }, { + .slave_id = SHDMA_SLAVE_SCIF4_TX, + .addr = 0xe6c80020, + .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), + .mid_rid = 0x39, + }, { + .slave_id = SHDMA_SLAVE_SCIF4_RX, + .addr = 0xe6c80024, + .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), + .mid_rid = 0x3a, + }, { + .slave_id = SHDMA_SLAVE_SCIF5_TX, + .addr = 0xe6cb0020, + .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), + .mid_rid = 0x35, + }, { + .slave_id = SHDMA_SLAVE_SCIF5_RX, + .addr = 0xe6cb0024, + .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), + .mid_rid = 0x36, + }, { + .slave_id = SHDMA_SLAVE_SCIF6_TX, + .addr = 0xe6c30040, + .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), + .mid_rid = 0x3d, + }, { + .slave_id = SHDMA_SLAVE_SCIF6_RX, + .addr = 0xe6c30060, + .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), + .mid_rid = 0x3e, + }, { + .slave_id = SHDMA_SLAVE_SDHI0_TX, + .addr = 0xe6850030, + .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT), + .mid_rid = 0xc1, + }, { + .slave_id = SHDMA_SLAVE_SDHI0_RX, + .addr = 0xe6850030, + .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT), + .mid_rid = 0xc2, + }, { + .slave_id = SHDMA_SLAVE_SDHI1_TX, + .addr = 0xe6860030, + .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT), + .mid_rid = 0xc9, + }, { + .slave_id = SHDMA_SLAVE_SDHI1_RX, + .addr = 0xe6860030, + .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT), + .mid_rid = 0xca, + }, { + .slave_id = SHDMA_SLAVE_SDHI2_TX, + .addr = 0xe6870030, + .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT), + .mid_rid = 0xcd, + }, { + .slave_id = SHDMA_SLAVE_SDHI2_RX, + .addr = 0xe6870030, + .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT), + .mid_rid = 0xce, + }, +}; + +static const struct sh_dmae_channel sh7372_dmae_channels[] = { + { + .offset = 0, + .dmars = 0, + .dmars_bit = 0, + }, { + .offset = 0x10, + .dmars = 0, + .dmars_bit = 8, + }, { + .offset = 0x20, + .dmars = 4, + .dmars_bit = 0, + }, { + .offset = 0x30, + .dmars = 4, + .dmars_bit = 8, + }, { + .offset = 0x50, + .dmars = 8, + .dmars_bit = 0, + }, { + .offset = 0x60, + .dmars = 8, + .dmars_bit = 8, + } +}; + +static const unsigned int ts_shift[] = TS_SHIFT; + +static struct sh_dmae_pdata dma_platform_data = { + .slave = sh7372_dmae_slaves, + .slave_num = ARRAY_SIZE(sh7372_dmae_slaves), + .channel = sh7372_dmae_channels, + .channel_num = ARRAY_SIZE(sh7372_dmae_channels), + .ts_low_shift = 3, + .ts_low_mask = 0x18, + .ts_high_shift = (20 - 2), /* 2 bits for shifted low TS */ + .ts_high_mask = 0x00300000, + .ts_shift = ts_shift, + .ts_shift_num = ARRAY_SIZE(ts_shift), + .dmaor_init = DMAOR_DME, +}; + +/* Resource order important! */ +static struct resource sh7372_dmae0_resources[] = { + { + /* Channel registers and DMAOR */ + .start = 0xfe008020, + .end = 0xfe00808f, + .flags = IORESOURCE_MEM, + }, + { + /* DMARSx */ + .start = 0xfe009000, + .end = 0xfe00900b, + .flags = IORESOURCE_MEM, + }, + { + /* DMA error IRQ */ + .start = 246, + .end = 246, + .flags = IORESOURCE_IRQ, + }, + { + /* IRQ for channels 0-5 */ + .start = 240, + .end = 245, + .flags = IORESOURCE_IRQ, + }, +}; + +/* Resource order important! */ +static struct resource sh7372_dmae1_resources[] = { + { + /* Channel registers and DMAOR */ + .start = 0xfe018020, + .end = 0xfe01808f, + .flags = IORESOURCE_MEM, + }, + { + /* DMARSx */ + .start = 0xfe019000, + .end = 0xfe01900b, + .flags = IORESOURCE_MEM, + }, + { + /* DMA error IRQ */ + .start = 254, + .end = 254, + .flags = IORESOURCE_IRQ, + }, + { + /* IRQ for channels 0-5 */ + .start = 248, + .end = 253, + .flags = IORESOURCE_IRQ, + }, +}; + +/* Resource order important! */ +static struct resource sh7372_dmae2_resources[] = { + { + /* Channel registers and DMAOR */ + .start = 0xfe028020, + .end = 0xfe02808f, + .flags = IORESOURCE_MEM, + }, + { + /* DMARSx */ + .start = 0xfe029000, + .end = 0xfe02900b, + .flags = IORESOURCE_MEM, + }, + { + /* DMA error IRQ */ + .start = 262, + .end = 262, + .flags = IORESOURCE_IRQ, + }, + { + /* IRQ for channels 0-5 */ + .start = 256, + .end = 261, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device dma0_device = { + .name = "sh-dma-engine", + .id = 0, + .resource = sh7372_dmae0_resources, + .num_resources = ARRAY_SIZE(sh7372_dmae0_resources), + .dev = { + .platform_data = &dma_platform_data, + }, +}; + +static struct platform_device dma1_device = { + .name = "sh-dma-engine", + .id = 1, + .resource = sh7372_dmae1_resources, + .num_resources = ARRAY_SIZE(sh7372_dmae1_resources), + .dev = { + .platform_data = &dma_platform_data, + }, +}; + +static struct platform_device dma2_device = { + .name = "sh-dma-engine", + .id = 2, + .resource = sh7372_dmae2_resources, + .num_resources = ARRAY_SIZE(sh7372_dmae2_resources), + .dev = { + .platform_data = &dma_platform_data, + }, +}; + static struct platform_device *sh7372_early_devices[] __initdata = { &scif0_device, &scif1_device, @@ -178,6 +526,11 @@ static struct platform_device *sh7372_early_devices[] __initdata = { &scif5_device, &scif6_device, &cmt10_device, + &iic0_device, + &iic1_device, + &dma0_device, + &dma1_device, + &dma2_device, }; void __init sh7372_add_standard_devices(void) @@ -186,14 +539,8 @@ void __init sh7372_add_standard_devices(void) ARRAY_SIZE(sh7372_early_devices)); } -#define SMSTPCR3 0xe615013c -#define SMSTPCR3_CMT1 (1 << 29) - void __init sh7372_add_early_devices(void) { - /* enable clock to CMT1 */ - __raw_writel(__raw_readl(SMSTPCR3) & ~SMSTPCR3_CMT1, SMSTPCR3); - early_platform_add_devices(sh7372_early_devices, ARRAY_SIZE(sh7372_early_devices)); } diff --git a/arch/arm/mach-shmobile/setup-sh7377.c b/arch/arm/mach-shmobile/setup-sh7377.c index 60e37774c35c..bb4adf17dbf4 100644 --- a/arch/arm/mach-shmobile/setup-sh7377.c +++ b/arch/arm/mach-shmobile/setup-sh7377.c @@ -32,11 +32,13 @@ #include <asm/mach-types.h> #include <asm/mach/arch.h> +/* SCIFA0 */ static struct plat_sci_port scif0_platform_data = { .mapbase = 0xe6c40000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 80, 80, 80, 80 }, + .irqs = { evt2irq(0xc00), evt2irq(0xc00), + evt2irq(0xc00), evt2irq(0xc00) }, }; static struct platform_device scif0_device = { @@ -47,11 +49,13 @@ static struct platform_device scif0_device = { }, }; +/* SCIFA1 */ static struct plat_sci_port scif1_platform_data = { .mapbase = 0xe6c50000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 81, 81, 81, 81 }, + .irqs = { evt2irq(0xc20), evt2irq(0xc20), + evt2irq(0xc20), evt2irq(0xc20) }, }; static struct platform_device scif1_device = { @@ -62,11 +66,13 @@ static struct platform_device scif1_device = { }, }; +/* SCIFA2 */ static struct plat_sci_port scif2_platform_data = { .mapbase = 0xe6c60000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 82, 82, 82, 82 }, + .irqs = { evt2irq(0xc40), evt2irq(0xc40), + evt2irq(0xc40), evt2irq(0xc40) }, }; static struct platform_device scif2_device = { @@ -77,11 +83,13 @@ static struct platform_device scif2_device = { }, }; +/* SCIFA3 */ static struct plat_sci_port scif3_platform_data = { .mapbase = 0xe6c70000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 83, 83, 83, 83 }, + .irqs = { evt2irq(0xc60), evt2irq(0xc60), + evt2irq(0xc60), evt2irq(0xc60) }, }; static struct platform_device scif3_device = { @@ -92,11 +100,13 @@ static struct platform_device scif3_device = { }, }; +/* SCIFA4 */ static struct plat_sci_port scif4_platform_data = { .mapbase = 0xe6c80000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 89, 89, 89, 89 }, + .irqs = { evt2irq(0xd20), evt2irq(0xd20), + evt2irq(0xd20), evt2irq(0xd20) }, }; static struct platform_device scif4_device = { @@ -107,11 +117,13 @@ static struct platform_device scif4_device = { }, }; +/* SCIFA5 */ static struct plat_sci_port scif5_platform_data = { .mapbase = 0xe6cb0000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 90, 90, 90, 90 }, + .irqs = { evt2irq(0xd40), evt2irq(0xd40), + evt2irq(0xd40), evt2irq(0xd40) }, }; static struct platform_device scif5_device = { @@ -122,11 +134,13 @@ static struct platform_device scif5_device = { }, }; +/* SCIFA6 */ static struct plat_sci_port scif6_platform_data = { .mapbase = 0xe6cc0000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 196, 196, 196, 196 }, + .irqs = { intcs_evt2irq(0x1a80), intcs_evt2irq(0x1a80), + intcs_evt2irq(0x1a80), intcs_evt2irq(0x1a80) }, }; static struct platform_device scif6_device = { @@ -137,11 +151,13 @@ static struct platform_device scif6_device = { }, }; +/* SCIFB */ static struct plat_sci_port scif7_platform_data = { .mapbase = 0xe6c30000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 91, 91, 91, 91 }, + .irqs = { evt2irq(0xd60), evt2irq(0xd60), + evt2irq(0xd60), evt2irq(0xd60) }, }; static struct platform_device scif7_device = { @@ -169,7 +185,7 @@ static struct resource cmt10_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = 72, + .start = evt2irq(0xb00), /* CMT1_CMT10 */ .flags = IORESOURCE_IRQ, }, }; diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c index 6544855af2f1..fe84b9021c7a 100644 --- a/arch/arm/mach-ux500/clock.c +++ b/arch/arm/mach-ux500/clock.c @@ -16,6 +16,7 @@ #include <asm/clkdev.h> +#include <plat/mtu.h> #include <mach/hardware.h> #include "clock.h" @@ -59,6 +60,9 @@ #define PRCM_DMACLK_MGT 0x074 #define PRCM_B2R2CLK_MGT 0x078 #define PRCM_TVCLK_MGT 0x07C +#define PRCM_TCR 0x1C8 +#define PRCM_TCR_STOPPED (1 << 16) +#define PRCM_TCR_DOZE_MODE (1 << 17) #define PRCM_UNIPROCLK_MGT 0x278 #define PRCM_SSPCLK_MGT 0x280 #define PRCM_RNGCLK_MGT 0x284 @@ -120,10 +124,95 @@ void clk_disable(struct clk *clk) } EXPORT_SYMBOL(clk_disable); +/* + * The MTU has a separate, rather complex muxing setup + * with alternative parents (peripheral cluster or + * ULP or fixed 32768 Hz) depending on settings + */ +static unsigned long clk_mtu_get_rate(struct clk *clk) +{ + void __iomem *addr = __io_address(U8500_PRCMU_BASE) + + PRCM_TCR; + u32 tcr = readl(addr); + int mtu = (int) clk->data; + /* + * One of these is selected eventually + * TODO: Replace the constant with a reference + * to the ULP source once this is modeled. + */ + unsigned long clk32k = 32768; + unsigned long mturate; + unsigned long retclk; + + /* Get the rate from the parent as a default */ + if (clk->parent_periph) + mturate = clk_get_rate(clk->parent_periph); + else if (clk->parent_cluster) + mturate = clk_get_rate(clk->parent_cluster); + else + /* We need to be connected SOMEWHERE */ + BUG(); + + /* + * Are we in doze mode? + * In this mode the parent peripheral or the fixed 32768 Hz + * clock is fed into the block. + */ + if (!(tcr & PRCM_TCR_DOZE_MODE)) { + /* + * Here we're using the clock input from the APE ULP + * clock domain. But first: are the timers stopped? + */ + if (tcr & PRCM_TCR_STOPPED) { + clk32k = 0; + mturate = 0; + } else { + /* Else default mode: 0 and 2.4 MHz */ + clk32k = 0; + if (cpu_is_u5500()) + /* DB5500 divides by 8 */ + mturate /= 8; + else if (cpu_is_u8500ed()) { + /* + * This clocking setting must not be used + * in the ED chip, it is simply not + * connected anywhere! + */ + mturate = 0; + BUG(); + } else + /* + * In this mode the ulp38m4 clock is divided + * by a factor 16, on the DB8500 typically + * 38400000 / 16 ~ 2.4 MHz. + * TODO: Replace the constant with a reference + * to the ULP source once this is modeled. + */ + mturate = 38400000 / 16; + } + } + + /* Return the clock selected for this MTU */ + if (tcr & (1 << mtu)) + retclk = clk32k; + else + retclk = mturate; + + pr_info("MTU%d clock rate: %lu Hz\n", mtu, retclk); + return retclk; +} + unsigned long clk_get_rate(struct clk *clk) { unsigned long rate; + /* + * If there is a custom getrate callback for this clock, + * it will take precedence. + */ + if (clk->get_rate) + return clk->get_rate(clk); + if (clk->ops && clk->ops->get_rate) return clk->ops->get_rate(clk); @@ -341,8 +430,9 @@ static DEFINE_PRCC_CLK(5, usb_v1, 0, 0, NULL); /* Peripheral Cluster #6 */ -static DEFINE_PRCC_CLK(6, mtu1_v1, 8, -1, NULL); -static DEFINE_PRCC_CLK(6, mtu0_v1, 7, -1, NULL); +/* MTU ID in data */ +static DEFINE_PRCC_CLK_CUSTOM(6, mtu1_v1, 8, -1, NULL, clk_mtu_get_rate, 1); +static DEFINE_PRCC_CLK_CUSTOM(6, mtu0_v1, 7, -1, NULL, clk_mtu_get_rate, 0); static DEFINE_PRCC_CLK(6, cfgreg_v1, 6, 6, NULL); static DEFINE_PRCC_CLK(6, dmc_ed, 6, 6, NULL); static DEFINE_PRCC_CLK(6, hash1, 5, -1, NULL); @@ -357,8 +447,9 @@ static DEFINE_PRCC_CLK(6, rng_v1, 0, 0, &clk_rngclk); /* Peripheral Cluster #7 */ static DEFINE_PRCC_CLK(7, tzpc0_ed, 4, -1, NULL); -static DEFINE_PRCC_CLK(7, mtu1_ed, 3, -1, NULL); -static DEFINE_PRCC_CLK(7, mtu0_ed, 2, -1, NULL); +/* MTU ID in data */ +static DEFINE_PRCC_CLK_CUSTOM(7, mtu1_ed, 3, -1, NULL, clk_mtu_get_rate, 1); +static DEFINE_PRCC_CLK_CUSTOM(7, mtu0_ed, 2, -1, NULL, clk_mtu_get_rate, 0); static DEFINE_PRCC_CLK(7, wdg_ed, 1, -1, NULL); static DEFINE_PRCC_CLK(7, cfgreg_ed, 0, -1, NULL); @@ -503,15 +594,17 @@ static struct clk_lookup u8500_v1_clks[] = { CLK(uiccclk, "uicc", NULL), }; -static int __init clk_init(void) +int __init clk_init(void) { if (cpu_is_u8500ed()) { clk_prcmu_ops.enable = clk_prcmu_ed_enable; clk_prcmu_ops.disable = clk_prcmu_ed_disable; + clk_per6clk.rate = 100000000; } else if (cpu_is_u5500()) { /* Clock tree for U5500 not implemented yet */ clk_prcc_ops.enable = clk_prcc_ops.disable = NULL; clk_prcmu_ops.enable = clk_prcmu_ops.disable = NULL; + clk_per6clk.rate = 26000000; } clkdev_add_table(u8500_common_clks, ARRAY_SIZE(u8500_common_clks)); @@ -522,4 +615,3 @@ static int __init clk_init(void) return 0; } -arch_initcall(clk_init); diff --git a/arch/arm/mach-ux500/clock.h b/arch/arm/mach-ux500/clock.h index e4f99b65026f..a05802501527 100644 --- a/arch/arm/mach-ux500/clock.h +++ b/arch/arm/mach-ux500/clock.h @@ -28,6 +28,9 @@ struct clkops { * @ops: pointer to clkops struct used to control this clock * @name: name, for debugging * @enabled: refcount. positive if enabled, zero if disabled + * @get_rate: custom callback for getting the clock rate + * @data: custom per-clock data for example for the get_rate + * callback * @rate: fixed rate for clocks which don't implement * ops->getrate * @prcmu_cg_off: address offset of the combined enable/disable register @@ -67,6 +70,8 @@ struct clk { const struct clkops *ops; const char *name; unsigned int enabled; + unsigned long (*get_rate)(struct clk *); + void *data; unsigned long rate; struct list_head list; @@ -117,9 +122,26 @@ struct clk clk_##_name = { \ .parent_periph = _kernclk \ } +#define DEFINE_PRCC_CLK_CUSTOM(_pclust, _name, _bus_en, _kernel_en, _kernclk, _callback, _data) \ +struct clk clk_##_name = { \ + .name = #_name, \ + .ops = &clk_prcc_ops, \ + .cluster = _pclust, \ + .prcc_bus = _bus_en, \ + .prcc_kernel = _kernel_en, \ + .parent_cluster = &clk_per##_pclust##clk, \ + .parent_periph = _kernclk, \ + .get_rate = _callback, \ + .data = (void *) _data \ + } + + #define CLK(_clk, _devname, _conname) \ { \ .clk = &clk_##_clk, \ .dev_id = _devname, \ .con_id = _conname, \ } + +int __init clk_db8500_ed_fixup(void); +int __init clk_init(void); diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c index d81ad023963c..e0fd747e447a 100644 --- a/arch/arm/mach-ux500/cpu.c +++ b/arch/arm/mach-ux500/cpu.c @@ -62,6 +62,12 @@ void __init ux500_init_irq(void) { gic_dist_init(0, __io_address(UX500_GIC_DIST_BASE), 29); gic_cpu_init(0, __io_address(UX500_GIC_CPU_BASE)); + + /* + * Init clocks here so that they are available for system timer + * initialization. + */ + clk_init(); } #ifdef CONFIG_CACHE_L2X0 diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c index e6f73030d5f0..9b11eedba65f 100644 --- a/arch/arm/mach-vexpress/ct-ca9x4.c +++ b/arch/arm/mach-vexpress/ct-ca9x4.c @@ -2,6 +2,7 @@ * Versatile Express Core Tile Cortex A9x4 Support */ #include <linux/init.h> +#include <linux/gfp.h> #include <linux/device.h> #include <linux/dma-mapping.h> #include <linux/platform_device.h> diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 1ba6cf5a2c02..f6a999465323 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -678,10 +678,10 @@ void __init mem_init(void) void free_initmem(void) { #ifdef CONFIG_HAVE_TCM - extern char *__tcm_start, *__tcm_end; + extern char __tcm_start, __tcm_end; - totalram_pages += free_area(__phys_to_pfn(__pa(__tcm_start)), - __phys_to_pfn(__pa(__tcm_end)), + totalram_pages += free_area(__phys_to_pfn(__pa(&__tcm_start)), + __phys_to_pfn(__pa(&__tcm_end)), "TCM link"); #endif diff --git a/arch/arm/plat-mxc/clock.c b/arch/arm/plat-mxc/clock.c index 323ff8ccc877..2ed3ab173add 100644 --- a/arch/arm/plat-mxc/clock.c +++ b/arch/arm/plat-mxc/clock.c @@ -52,13 +52,14 @@ static void __clk_disable(struct clk *clk) { if (clk == NULL || IS_ERR(clk)) return; - - __clk_disable(clk->parent); - __clk_disable(clk->secondary); - WARN_ON(!clk->usecount); - if (!(--clk->usecount) && clk->disable) - clk->disable(clk); + + if (!(--clk->usecount)) { + if (clk->disable) + clk->disable(clk); + __clk_disable(clk->parent); + __clk_disable(clk->secondary); + } } static int __clk_enable(struct clk *clk) @@ -66,12 +67,13 @@ static int __clk_enable(struct clk *clk) if (clk == NULL || IS_ERR(clk)) return -EINVAL; - __clk_enable(clk->parent); - __clk_enable(clk->secondary); - - if (clk->usecount++ == 0 && clk->enable) - clk->enable(clk); + if (clk->usecount++ == 0) { + __clk_enable(clk->parent); + __clk_enable(clk->secondary); + if (clk->enable) + clk->enable(clk); + } return 0; } @@ -160,17 +162,28 @@ EXPORT_SYMBOL(clk_set_rate); int clk_set_parent(struct clk *clk, struct clk *parent) { int ret = -EINVAL; + struct clk *old; if (clk == NULL || IS_ERR(clk) || parent == NULL || IS_ERR(parent) || clk->set_parent == NULL) return ret; + if (clk->usecount) + clk_enable(parent); + mutex_lock(&clocks_mutex); ret = clk->set_parent(clk, parent); - if (ret == 0) + if (ret == 0) { + old = clk->parent; clk->parent = parent; + } else { + old = parent; + } mutex_unlock(&clocks_mutex); + if (clk->usecount) + clk_disable(old); + return ret; } EXPORT_SYMBOL(clk_set_parent); diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx25.h b/arch/arm/plat-mxc/include/mach/iomux-mx25.h index f39220d1b67a..e88d01a125a6 100644 --- a/arch/arm/plat-mxc/include/mach/iomux-mx25.h +++ b/arch/arm/plat-mxc/include/mach/iomux-mx25.h @@ -371,30 +371,33 @@ #define MX25_PAD_SD1_DATA3__FEC_CRS IOMUX_PAD(0x39c, 0x1a4, 0x10, 0x508, 2, NO_PAD_CTRL) #define MX25_PAD_SD1_DATA3__GPIO_2_28 IOMUX_PAD(0x39c, 0x1a4, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_KPP_ROW0__KPP_ROW0 IOMUX_PAD(0x3a0, 0x1a8, 0x10, 0, 0, PAD_CTL_PKE) +#define KPP_CTL_ROW (PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP) +#define KPP_CTL_COL (PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP | PAD_CTL_ODE) + +#define MX25_PAD_KPP_ROW0__KPP_ROW0 IOMUX_PAD(0x3a0, 0x1a8, 0x10, 0, 0, KPP_CTL_ROW) #define MX25_PAD_KPP_ROW0__GPIO_2_29 IOMUX_PAD(0x3a0, 0x1a8, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_KPP_ROW1__KPP_ROW1 IOMUX_PAD(0x3a4, 0x1ac, 0x10, 0, 0, PAD_CTL_PKE) +#define MX25_PAD_KPP_ROW1__KPP_ROW1 IOMUX_PAD(0x3a4, 0x1ac, 0x10, 0, 0, KPP_CTL_ROW) #define MX25_PAD_KPP_ROW1__GPIO_2_30 IOMUX_PAD(0x3a4, 0x1ac, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_KPP_ROW2__KPP_ROW2 IOMUX_PAD(0x3a8, 0x1b0, 0x10, 0, 0, PAD_CTL_PKE) +#define MX25_PAD_KPP_ROW2__KPP_ROW2 IOMUX_PAD(0x3a8, 0x1b0, 0x10, 0, 0, KPP_CTL_ROW) #define MX25_PAD_KPP_ROW2__CSI_D0 IOMUX_PAD(0x3a8, 0x1b0, 0x13, 0x488, 2, NO_PAD_CTRL) #define MX25_PAD_KPP_ROW2__GPIO_2_31 IOMUX_PAD(0x3a8, 0x1b0, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_KPP_ROW3__KPP_ROW3 IOMUX_PAD(0x3ac, 0x1b4, 0x10, 0, 0, PAD_CTL_PKE) +#define MX25_PAD_KPP_ROW3__KPP_ROW3 IOMUX_PAD(0x3ac, 0x1b4, 0x10, 0, 0, KPP_CTL_ROW) #define MX25_PAD_KPP_ROW3__CSI_LD1 IOMUX_PAD(0x3ac, 0x1b4, 0x13, 0x48c, 2, NO_PAD_CTRL) #define MX25_PAD_KPP_ROW3__GPIO_3_0 IOMUX_PAD(0x3ac, 0x1b4, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_KPP_COL0__KPP_COL0 IOMUX_PAD(0x3b0, 0x1b8, 0x10, 0, 0, PAD_CTL_PKE | PAD_CTL_ODE) +#define MX25_PAD_KPP_COL0__KPP_COL0 IOMUX_PAD(0x3b0, 0x1b8, 0x10, 0, 0, KPP_CTL_COL) #define MX25_PAD_KPP_COL0__GPIO_3_1 IOMUX_PAD(0x3b0, 0x1b8, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_KPP_COL1__KPP_COL1 IOMUX_PAD(0x3b4, 0x1bc, 0x10, 0, 0, PAD_CTL_PKE | PAD_CTL_ODE) +#define MX25_PAD_KPP_COL1__KPP_COL1 IOMUX_PAD(0x3b4, 0x1bc, 0x10, 0, 0, KPP_CTL_COL) #define MX25_PAD_KPP_COL1__GPIO_3_2 IOMUX_PAD(0x3b4, 0x1bc, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_KPP_COL2__KPP_COL2 IOMUX_PAD(0x3b8, 0x1c0, 0x10, 0, 0, PAD_CTL_PKE | PAD_CTL_ODE) +#define MX25_PAD_KPP_COL2__KPP_COL2 IOMUX_PAD(0x3b8, 0x1c0, 0x10, 0, 0, KPP_CTL_COL) #define MX25_PAD_KPP_COL2__GPIO_3_3 IOMUX_PAD(0x3b8, 0x1c0, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_KPP_COL3__KPP_COL3 IOMUX_PAD(0x3bc, 0x1c4, 0x10, 0, 0, PAD_CTL_PKE | PAD_CTL_ODE) +#define MX25_PAD_KPP_COL3__KPP_COL3 IOMUX_PAD(0x3bc, 0x1c4, 0x10, 0, 0, KPP_CTL_COL) #define MX25_PAD_KPP_COL3__GPIO_3_4 IOMUX_PAD(0x3bc, 0x1c4, 0x15, 0, 0, NO_PAD_CTRL) #define MX25_PAD_FEC_MDC__FEC_MDC IOMUX_PAD(0x3c0, 0x1c8, 0x10, 0, 0, NO_PAD_CTRL) diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx51.h b/arch/arm/plat-mxc/include/mach/iomux-mx51.h index ab0f95d953d0..38961c6a6f0d 100644 --- a/arch/arm/plat-mxc/include/mach/iomux-mx51.h +++ b/arch/arm/plat-mxc/include/mach/iomux-mx51.h @@ -38,6 +38,8 @@ typedef enum iomux_config { PAD_CTL_SRE_FAST) #define MX51_UART3_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_DSE_HIGH | \ PAD_CTL_SRE_FAST) +#define MX51_I2C_PAD_CTRL (PAD_CTL_SRE_FAST | PAD_CTL_ODE | \ + PAD_CTL_DSE_HIGH | PAD_CTL_PUS_100K_UP | PAD_CTL_HYS) #define MX51_USBH1_PAD_CTRL (PAD_CTL_SRE_FAST | PAD_CTL_DSE_HIGH | \ PAD_CTL_PUS_100K_UP | PAD_CTL_PUE | \ PAD_CTL_PKE | PAD_CTL_HYS) @@ -57,10 +59,12 @@ typedef enum iomux_config { /* PAD MUX ALT INPSE PATH PADCTRL */ -#define MX51_PAD_GPIO_2_0__EIM_D16 IOMUX_PAD(0x3f0, 0x05c, 1, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_D16__I2C1_SDA IOMUX_PAD(0x3f0, 0x05c, IOMUX_CONFIG_ALT4 | IOMUX_CONFIG_SION, \ + 0x09b4, 0, MX51_I2C_PAD_CTRL) #define MX51_PAD_GPIO_2_1__EIM_D17 IOMUX_PAD(0x3f4, 0x060, 1, 0x0, 0, NO_PAD_CTRL) #define MX51_PAD_GPIO_2_2__EIM_D18 IOMUX_PAD(0x3f8, 0x064, 1, 0x0, 0, NO_PAD_CTRL) -#define MX51_PAD_GPIO_2_3__EIM_D19 IOMUX_PAD(0x3fc, 0x068, 1, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_D19__I2C1_SCL IOMUX_PAD(0x3fc, 0x068, IOMUX_CONFIG_ALT4 | IOMUX_CONFIG_SION, \ + 0x09b0, 0, MX51_I2C_PAD_CTRL) #define MX51_PAD_GPIO_2_4__EIM_D20 IOMUX_PAD(0x400, 0x06c, 1, 0x0, 0, NO_PAD_CTRL) #define MX51_PAD_GPIO_2_5__EIM_D21 IOMUX_PAD(0x404, 0x070, 1, 0x0, 0, NO_PAD_CTRL) #define MX51_PAD_EIM_D21__GPIO_2_5 IOMUX_PAD(0x404, 0x070, IOMUX_CONFIG_ALT1, 0x0, 0, MX51_GPIO_PAD_CTRL) @@ -179,8 +183,8 @@ typedef enum iomux_config { #define MX51_PAD_GPIO_4_14__CSI2_HSYNC IOMUX_PAD(0x5E0, 0x1F0, 3, 0x0, 0, NO_PAD_CTRL) #define MX51_PAD_GPIO_4_15__CSI2_PIXCLK IOMUX_PAD(0x5E4, 0x1F4, 3, 0x0, 0, NO_PAD_CTRL) #define MX51_PAD_CSI2_PKE0__CSI2_PKE0 IOMUX_PAD(0x81C, 0x0, 0, 0x0, 0, NO_PAD_CTRL) -#define MX51_PAD_GPIO_4_16__I2C1_CLK IOMUX_PAD(0x5E8, 0x1F8, 3, 0x0, 0, NO_PAD_CTRL) -#define MX51_PAD_GPIO_4_17__I2C1_DAT IOMUX_PAD(0x5EC, 0x1FC, 3, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_I2C1_CLK__HSI2C_CLK IOMUX_PAD(0x5E8, 0x1F8, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_I2C1_DAT__HSI2C_DAT IOMUX_PAD(0x5EC, 0x1FC, IOMUX_CONFIG_ALT0, 0x0, 0, NO_PAD_CTRL) #define MX51_PAD_GPIO_4_18__AUD3_BB_TXD IOMUX_PAD(0x5F0, 0x200, 3, 0x0, 0, NO_PAD_CTRL) #define MX51_PAD_GPIO_4_19__AUD3_BB_RXD IOMUX_PAD(0x5F4, 0x204, 3, 0x0, 0, NO_PAD_CTRL) #define MX51_PAD_GPIO_4_20__AUD3_BB_CK IOMUX_PAD(0x5F8, 0x208, 3, 0x0, 0, NO_PAD_CTRL) @@ -213,8 +217,10 @@ typedef enum iomux_config { #define MX51_PAD_KEY_COL1__KEY_COL1 IOMUX_PAD(0x650, 0x260, 0, 0x0, 0, NO_PAD_CTRL) #define MX51_PAD_KEY_COL2__KEY_COL2 IOMUX_PAD(0x654, 0x264, 0, 0x0, 0, NO_PAD_CTRL) #define MX51_PAD_KEY_COL3__KEY_COL3 IOMUX_PAD(0x658, 0x268, 0, 0x0, 0, NO_PAD_CTRL) -#define MX51_PAD_KEY_COL4__KEY_COL4 IOMUX_PAD(0x65C, 0x26C, 0, 0x0, 0, NO_PAD_CTRL) -#define MX51_PAD_KEY_COL5__KEY_COL5 IOMUX_PAD(0x660, 0x270, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_KEY_COL4__I2C2_SCL IOMUX_PAD(0x65C, 0x26C, IOMUX_CONFIG_ALT3 | IOMUX_CONFIG_SION, \ + 0x09b8, 1, MX51_I2C_PAD_CTRL) +#define MX51_PAD_KEY_COL5__I2C2_SDA IOMUX_PAD(0x660, 0x270, IOMUX_CONFIG_ALT3 | IOMUX_CONFIG_SION, \ + 0x09bc, 1, MX51_I2C_PAD_CTRL) #define MX51_PAD_USBH1_CLK__USBH1_CLK IOMUX_PAD(0x678, 0x278, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL) #define MX51_PAD_USBH1_DIR__USBH1_DIR IOMUX_PAD(0x67C, 0x27C, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL) #define MX51_PAD_USBH1_STP__USBH1_STP IOMUX_PAD(0x680, 0x280, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL) diff --git a/arch/arm/plat-mxc/include/mach/mmc.h b/arch/arm/plat-mxc/include/mach/mmc.h index de2128dada5c..29115f405af9 100644 --- a/arch/arm/plat-mxc/include/mach/mmc.h +++ b/arch/arm/plat-mxc/include/mach/mmc.h @@ -31,6 +31,9 @@ struct imxmmc_platform_data { /* adjust slot voltage */ void (*setpower)(struct device *, unsigned int vdd); + + /* enable card detect using DAT3 */ + int dat3_card_detect; }; #endif diff --git a/arch/arm/plat-mxc/include/mach/mx25.h b/arch/arm/plat-mxc/include/mach/mx25.h index 4eb6e334bda5..35fb9f5e5d1c 100644 --- a/arch/arm/plat-mxc/include/mach/mx25.h +++ b/arch/arm/plat-mxc/include/mach/mx25.h @@ -34,11 +34,13 @@ #define MX25_NFC_BASE_ADDR 0xbb000000 #define MX25_DRYICE_BASE_ADDR 0x53ffc000 #define MX25_LCDC_BASE_ADDR 0x53fbc000 +#define MX25_KPP_BASE_ADDR 0x43fa8000 #define MX25_INT_DRYICE 25 #define MX25_INT_FEC 57 #define MX25_INT_NANDFC 33 #define MX25_INT_LCDC 39 +#define MX25_INT_KPP 24 #if defined(IMX_NEEDS_DEPRECATED_SYMBOLS) #define UART1_BASE_ADDR MX25_UART1_BASE_ADDR diff --git a/arch/arm/plat-mxc/include/mach/mxc_nand.h b/arch/arm/plat-mxc/include/mach/mxc_nand.h index 5d2d21d414e0..2d74748c5db7 100644 --- a/arch/arm/plat-mxc/include/mach/mxc_nand.h +++ b/arch/arm/plat-mxc/include/mach/mxc_nand.h @@ -20,9 +20,13 @@ #ifndef __ASM_ARCH_NAND_H #define __ASM_ARCH_NAND_H +#include <linux/mtd/partitions.h> + struct mxc_nand_platform_data { int width; /* data bus width in bytes */ int hw_ecc:1; /* 0 if supress hardware ECC */ int flash_bbt:1; /* set to 1 to use a flash based bbt */ + struct mtd_partition *parts; /* partition table */ + int nr_parts; /* size of parts */ }; #endif /* __ASM_ARCH_NAND_H */ diff --git a/arch/arm/plat-nomadik/timer.c b/arch/arm/plat-nomadik/timer.c index 0ff3798769ab..08aaa4a7f65f 100644 --- a/arch/arm/plat-nomadik/timer.c +++ b/arch/arm/plat-nomadik/timer.c @@ -13,7 +13,9 @@ #include <linux/irq.h> #include <linux/io.h> #include <linux/clockchips.h> +#include <linux/clk.h> #include <linux/jiffies.h> +#include <linux/err.h> #include <asm/mach/time.h> #include <plat/mtu.h> @@ -124,13 +126,25 @@ static struct irqaction nmdk_timer_irq = { void __init nmdk_timer_init(void) { unsigned long rate; - u32 cr = MTU_CRn_32BITS;; + struct clk *clk0; + struct clk *clk1; + u32 cr; + + clk0 = clk_get_sys("mtu0", NULL); + BUG_ON(IS_ERR(clk0)); + + clk1 = clk_get_sys("mtu1", NULL); + BUG_ON(IS_ERR(clk1)); + + clk_enable(clk0); + clk_enable(clk1); /* * Tick rate is 2.4MHz for Nomadik and 110MHz for ux500: * use a divide-by-16 counter if it's more than 16MHz */ - rate = CLOCK_TICK_RATE; + cr = MTU_CRn_32BITS;; + rate = clk_get_rate(clk0); if (rate > 16 << 20) { rate /= 16; cr |= MTU_CRn_PRESCALE_16; @@ -153,6 +167,14 @@ void __init nmdk_timer_init(void) nmdk_clksrc.name); /* Timer 1 is used for events, fix according to rate */ + cr = MTU_CRn_32BITS; + rate = clk_get_rate(clk1); + if (rate > 16 << 20) { + rate /= 16; + cr |= MTU_CRn_PRESCALE_16; + } else { + cr |= MTU_CRn_PRESCALE_1; + } writel(cr | MTU_CRn_ONESHOT, mtu_base + MTU_CR(1)); /* off, currently */ nmdk_clkevt.mult = div_sc(rate, NSEC_PER_SEC, nmdk_clkevt.shift); nmdk_clkevt.max_delta_ns = diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S index 66dc2d03b7fc..d66cead97d28 100644 --- a/arch/arm/vfp/vfphw.S +++ b/arch/arm/vfp/vfphw.S @@ -277,7 +277,7 @@ ENTRY(vfp_put_double) #ifdef CONFIG_VFPv3 @ d16 - d31 registers .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 -1: mcrr p11, 3, r1, r2, c\dr @ fmdrr r1, r2, d\dr +1: mcrr p11, 3, r0, r1, c\dr @ fmdrr r0, r1, d\dr mov pc, lr .org 1b + 8 .endr diff --git a/arch/blackfin/include/asm/elf.h b/arch/blackfin/include/asm/elf.h index 117713adea7f..e6c6812a9abd 100644 --- a/arch/blackfin/include/asm/elf.h +++ b/arch/blackfin/include/asm/elf.h @@ -119,6 +119,7 @@ do { \ #define ELF_CORE_COPY_REGS(pr_reg, regs) \ memcpy((char *) &pr_reg, (char *)regs, \ sizeof(struct pt_regs)); +#define ELF_CORE_COPY_FPREGS(...) 0 /* Blackfin has no FPU */ /* This yields a mask that user programs can use to figure out what instruction set this cpu supports. */ diff --git a/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h b/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h index 8b18b5359210..620834097632 100644 --- a/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h +++ b/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h @@ -1738,85 +1738,4 @@ #define nAFEXIT 0x0 #define SECSTAT 0xe0 /* Secure Status */ -/* Bit masks for NFC_CTL */ - -#define WR_DLY 0xf /* Write Strobe Delay */ -#define RD_DLY 0xf0 /* Read Strobe Delay */ -#define NWIDTH 0x100 /* NAND Data Width */ -#define nNWIDTH 0x0 -#define PG_SIZE 0x200 /* Page Size */ -#define nPG_SIZE 0x0 - -/* Bit masks for NFC_STAT */ - -#define NBUSY 0x1 /* Not Busy */ -#define nNBUSY 0x0 -#define WB_FULL 0x2 /* Write Buffer Full */ -#define nWB_FULL 0x0 -#define PG_WR_STAT 0x4 /* Page Write Pending */ -#define nPG_WR_STAT 0x0 -#define PG_RD_STAT 0x8 /* Page Read Pending */ -#define nPG_RD_STAT 0x0 -#define WB_EMPTY 0x10 /* Write Buffer Empty */ -#define nWB_EMPTY 0x0 - -/* Bit masks for NFC_IRQSTAT */ - -#define NBUSYIRQ 0x1 /* Not Busy IRQ */ -#define nNBUSYIRQ 0x0 -#define WB_OVF 0x2 /* Write Buffer Overflow */ -#define nWB_OVF 0x0 -#define WB_EDGE 0x4 /* Write Buffer Edge Detect */ -#define nWB_EDGE 0x0 -#define RD_RDY 0x8 /* Read Data Ready */ -#define nRD_RDY 0x0 -#define WR_DONE 0x10 /* Page Write Done */ -#define nWR_DONE 0x0 - -/* Bit masks for NFC_IRQMASK */ - -#define MASK_BUSYIRQ 0x1 /* Mask Not Busy IRQ */ -#define nMASK_BUSYIRQ 0x0 -#define MASK_WBOVF 0x2 /* Mask Write Buffer Overflow */ -#define nMASK_WBOVF 0x0 -#define MASK_WBEMPTY 0x4 /* Mask Write Buffer Empty */ -#define nMASK_WBEMPTY 0x0 -#define MASK_RDRDY 0x8 /* Mask Read Data Ready */ -#define nMASK_RDRDY 0x0 -#define MASK_WRDONE 0x10 /* Mask Write Done */ -#define nMASK_WRDONE 0x0 - -/* Bit masks for NFC_RST */ - -#define ECC_RST 0x1 /* ECC (and NFC counters) Reset */ -#define nECC_RST 0x0 - -/* Bit masks for NFC_PGCTL */ - -#define PG_RD_START 0x1 /* Page Read Start */ -#define nPG_RD_START 0x0 -#define PG_WR_START 0x2 /* Page Write Start */ -#define nPG_WR_START 0x0 - -/* Bit masks for NFC_ECC0 */ - -#define ECC0 0x7ff /* Parity Calculation Result0 */ - -/* Bit masks for NFC_ECC1 */ - -#define ECC1 0x7ff /* Parity Calculation Result1 */ - -/* Bit masks for NFC_ECC2 */ - -#define ECC2 0x7ff /* Parity Calculation Result2 */ - -/* Bit masks for NFC_ECC3 */ - -#define ECC3 0x7ff /* Parity Calculation Result3 */ - -/* Bit masks for NFC_COUNT */ - -#define ECCCNT 0x3ff /* Transfer Count */ - - #endif /* _DEF_BF52X_H */ diff --git a/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h b/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h index 0ed06c2366fe..54143441af5e 100644 --- a/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h +++ b/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h @@ -2044,66 +2044,6 @@ #define RESET_WDOG 0x4000 /* SW Reset Generated By Watchdog Timer */ #define RESET_SOFTWARE 0x8000 /* SW Reset Occurred Since Last Read Of SWRST */ -/* Bit masks for NFC_CTL */ - -#define WR_DLY 0xf /* Write Strobe Delay */ -#define RD_DLY 0xf0 /* Read Strobe Delay */ -#define NWIDTH 0x100 /* NAND Data Width */ -#define PG_SIZE 0x200 /* Page Size */ - -/* Bit masks for NFC_STAT */ - -#define NBUSY 0x1 /* Not Busy */ -#define WB_FULL 0x2 /* Write Buffer Full */ -#define PG_WR_STAT 0x4 /* Page Write Pending */ -#define PG_RD_STAT 0x8 /* Page Read Pending */ -#define WB_EMPTY 0x10 /* Write Buffer Empty */ - -/* Bit masks for NFC_IRQSTAT */ - -#define NBUSYIRQ 0x1 /* Not Busy IRQ */ -#define WB_OVF 0x2 /* Write Buffer Overflow */ -#define WB_EDGE 0x4 /* Write Buffer Edge Detect */ -#define RD_RDY 0x8 /* Read Data Ready */ -#define WR_DONE 0x10 /* Page Write Done */ - -/* Bit masks for NFC_IRQMASK */ - -#define MASK_BUSYIRQ 0x1 /* Mask Not Busy IRQ */ -#define MASK_WBOVF 0x2 /* Mask Write Buffer Overflow */ -#define MASK_WBEMPTY 0x4 /* Mask Write Buffer Empty */ -#define MASK_RDRDY 0x8 /* Mask Read Data Ready */ -#define MASK_WRDONE 0x10 /* Mask Write Done */ - -/* Bit masks for NFC_RST */ - -#define ECC_RST 0x1 /* ECC (and NFC counters) Reset */ - -/* Bit masks for NFC_PGCTL */ - -#define PG_RD_START 0x1 /* Page Read Start */ -#define PG_WR_START 0x2 /* Page Write Start */ - -/* Bit masks for NFC_ECC0 */ - -#define ECC0 0x7ff /* Parity Calculation Result0 */ - -/* Bit masks for NFC_ECC1 */ - -#define ECC1 0x7ff /* Parity Calculation Result1 */ - -/* Bit masks for NFC_ECC2 */ - -#define ECC2 0x7ff /* Parity Calculation Result2 */ - -/* Bit masks for NFC_ECC3 */ - -#define ECC3 0x7ff /* Parity Calculation Result3 */ - -/* Bit masks for NFC_COUNT */ - -#define ECCCNT 0x3ff /* Transfer Count */ - /* Bit masks for EPPIx_STATUS */ #define CFIFO_ERR 0x1 /* Chroma FIFO Error */ diff --git a/arch/cris/arch-v10/drivers/ds1302.c b/arch/cris/arch-v10/drivers/ds1302.c index 77630df94343..884275629ef7 100644 --- a/arch/cris/arch-v10/drivers/ds1302.c +++ b/arch/cris/arch-v10/drivers/ds1302.c @@ -19,6 +19,7 @@ #include <linux/module.h> #include <linux/miscdevice.h> #include <linux/delay.h> +#include <linux/smp_lock.h> #include <linux/bcd.h> #include <linux/capability.h> @@ -238,9 +239,7 @@ static unsigned char days_in_mo[] = /* ioctl that supports RTC_RD_TIME and RTC_SET_TIME (read and set time/date). */ -static int -rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, - unsigned long arg) +static int rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { unsigned long flags; @@ -354,6 +353,17 @@ rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, } } +static long rtc_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int ret; + + lock_kernel(); + ret = rtc_ioctl(file, cmd, arg); + unlock_kernel(); + + return ret; +} + static void print_rtc_status(void) { @@ -375,8 +385,8 @@ print_rtc_status(void) /* The various file operations we support. */ static const struct file_operations rtc_fops = { - .owner = THIS_MODULE, - .ioctl = rtc_ioctl, + .owner = THIS_MODULE, + .unlocked_ioctl = rtc_unlocked_ioctl, }; /* Probe for the chip by writing something to its RAM and try reading it back. */ diff --git a/arch/cris/arch-v10/drivers/pcf8563.c b/arch/cris/arch-v10/drivers/pcf8563.c index 1e90c1a9c849..7dcb1f85f42b 100644 --- a/arch/cris/arch-v10/drivers/pcf8563.c +++ b/arch/cris/arch-v10/drivers/pcf8563.c @@ -27,6 +27,7 @@ #include <linux/delay.h> #include <linux/bcd.h> #include <linux/mutex.h> +#include <linux/smp_lock.h> #include <asm/uaccess.h> #include <asm/system.h> @@ -53,7 +54,7 @@ static DEFINE_MUTEX(rtc_lock); /* Protect state etc */ static const unsigned char days_in_month[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; -int pcf8563_ioctl(struct inode *, struct file *, unsigned int, unsigned long); +static long pcf8563_unlocked_ioctl(struct file *, unsigned int, unsigned long); /* Cache VL bit value read at driver init since writing the RTC_SECOND * register clears the VL status. @@ -62,7 +63,7 @@ static int voltage_low; static const struct file_operations pcf8563_fops = { .owner = THIS_MODULE, - .ioctl = pcf8563_ioctl, + .unlocked_ioctl = pcf8563_unlocked_ioctl, }; unsigned char @@ -212,8 +213,7 @@ pcf8563_exit(void) * ioctl calls for this driver. Why return -ENOTTY upon error? Because * POSIX says so! */ -int pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) +static int pcf8563_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { /* Some sanity checks. */ if (_IOC_TYPE(cmd) != RTC_MAGIC) @@ -339,6 +339,17 @@ int pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, return 0; } +static long pcf8563_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + int ret; + + lock_kernel(); + return pcf8563_ioctl(filp, cmd, arg); + unlock_kernel(); + + return ret; +} + static int __init pcf8563_register(void) { if (pcf8563_init() < 0) { diff --git a/arch/cris/arch-v10/kernel/irq.c b/arch/cris/arch-v10/kernel/irq.c index 1a61efc13982..a0c0df8be9c8 100644 --- a/arch/cris/arch-v10/kernel/irq.c +++ b/arch/cris/arch-v10/kernel/irq.c @@ -17,8 +17,8 @@ #include <linux/kernel.h> #include <linux/init.h> -#define mask_irq(irq_nr) (*R_VECT_MASK_CLR = 1 << (irq_nr)); -#define unmask_irq(irq_nr) (*R_VECT_MASK_SET = 1 << (irq_nr)); +#define crisv10_mask_irq(irq_nr) (*R_VECT_MASK_CLR = 1 << (irq_nr)); +#define crisv10_unmask_irq(irq_nr) (*R_VECT_MASK_SET = 1 << (irq_nr)); /* don't use set_int_vector, it bypasses the linux interrupt handlers. it is * global just so that the kernel gdb can use it. @@ -116,12 +116,12 @@ static unsigned int startup_crisv10_irq(unsigned int irq) static void enable_crisv10_irq(unsigned int irq) { - unmask_irq(irq); + crisv10_unmask_irq(irq); } static void disable_crisv10_irq(unsigned int irq) { - mask_irq(irq); + crisv10_mask_irq(irq); } static void ack_crisv10_irq(unsigned int irq) diff --git a/arch/cris/arch-v10/lib/dmacopy.c b/arch/cris/arch-v10/lib/dmacopy.c index e5fb44f505c5..49f5b8ca5b47 100644 --- a/arch/cris/arch-v10/lib/dmacopy.c +++ b/arch/cris/arch-v10/lib/dmacopy.c @@ -1,5 +1,4 @@ -/* $Id: dmacopy.c,v 1.1 2001/12/17 13:59:27 bjornw Exp $ - * +/* * memcpy for large blocks, using memory-memory DMA channels 6 and 7 in Etrax */ @@ -13,11 +12,11 @@ void *dma_memcpy(void *pdst, unsigned int pn) { static etrax_dma_descr indma, outdma; - - D(printk("dma_memcpy %d bytes... ", pn)); + + D(printk(KERN_DEBUG "dma_memcpy %d bytes... ", pn)); #if 0 - *R_GEN_CONFIG = genconfig_shadow = + *R_GEN_CONFIG = genconfig_shadow = (genconfig_shadow & ~0x3c0000) | IO_STATE(R_GEN_CONFIG, dma6, intdma7) | IO_STATE(R_GEN_CONFIG, dma7, intdma6); @@ -32,11 +31,11 @@ void *dma_memcpy(void *pdst, *R_DMA_CH7_FIRST = &outdma; *R_DMA_CH6_CMD = IO_STATE(R_DMA_CH6_CMD, cmd, start); *R_DMA_CH7_CMD = IO_STATE(R_DMA_CH7_CMD, cmd, start); - - while(*R_DMA_CH7_CMD == 1) /* wait for completion */ ; - D(printk("done\n")); + while (*R_DMA_CH7_CMD == 1) + /* wait for completion */; + D(printk(KERN_DEBUG "done\n")); } diff --git a/arch/cris/arch-v10/lib/hw_settings.S b/arch/cris/arch-v10/lib/hw_settings.S index 56905aaa7b6e..c09f19f478a5 100644 --- a/arch/cris/arch-v10/lib/hw_settings.S +++ b/arch/cris/arch-v10/lib/hw_settings.S @@ -1,13 +1,11 @@ /* - * $Id: hw_settings.S,v 1.1 2001/12/17 13:59:27 bjornw Exp $ - * * This table is used by some tools to extract hardware parameters. * The table should be included in the kernel and the decompressor. * Don't forget to update the tools if you change this table. * * Copyright (C) 2001 Axis Communications AB * - * Authors: Mikael Starvik (starvik@axis.com) + * Authors: Mikael Starvik (starvik@axis.com) */ #define PA_SET_VALUE ((CONFIG_ETRAX_DEF_R_PORT_PA_DIR << 8) | \ @@ -15,13 +13,13 @@ #define PB_SET_VALUE ((CONFIG_ETRAX_DEF_R_PORT_PB_CONFIG << 16) | \ (CONFIG_ETRAX_DEF_R_PORT_PB_DIR << 8) | \ (CONFIG_ETRAX_DEF_R_PORT_PB_DATA)) - + .ascii "HW_PARAM_MAGIC" ; Magic number .dword 0xc0004000 ; Kernel start address ; Debug port #ifdef CONFIG_ETRAX_DEBUG_PORT0 - .dword 0 + .dword 0 #elif defined(CONFIG_ETRAX_DEBUG_PORT1) .dword 1 #elif defined(CONFIG_ETRAX_DEBUG_PORT2) @@ -30,7 +28,7 @@ .dword 3 #else .dword 4 ; No debug -#endif +#endif ; SDRAM or EDO DRAM? #ifdef CONFIG_ETRAX_SDRAM @@ -39,7 +37,7 @@ .dword 0 #endif - ; Register values + ; Register values .dword R_WAITSTATES .dword CONFIG_ETRAX_DEF_R_WAITSTATES .dword R_BUS_CONFIG @@ -56,7 +54,7 @@ .dword CONFIG_ETRAX_DEF_R_DRAM_TIMING #endif .dword R_PORT_PA_SET - .dword PA_SET_VALUE + .dword PA_SET_VALUE .dword R_PORT_PB_SET .dword PB_SET_VALUE .dword 0 ; No more register values diff --git a/arch/cris/arch-v32/drivers/Kconfig b/arch/cris/arch-v32/drivers/Kconfig index b9e328e688be..a2dd740c5907 100644 --- a/arch/cris/arch-v32/drivers/Kconfig +++ b/arch/cris/arch-v32/drivers/Kconfig @@ -360,24 +360,10 @@ config ETRAX_SER4_DSR_BIT string "Ser 4 DSR bit (empty = not used)" depends on ETRAX_SERIAL_PORT4 -config ETRAX_SER3_CD_BIT +config ETRAX_SER4_CD_BIT string "Ser 4 CD bit (empty = not used)" depends on ETRAX_SERIAL_PORT4 -config ETRAX_RS485 - bool "RS-485 support" - depends on ETRAXFS_SERIAL - help - Enables support for RS-485 serial communication. For a primer on - RS-485, see <http://www.hw.cz/english/docs/rs485/rs485.html>. - -config ETRAX_RS485_DISABLE_RECEIVER - bool "Disable serial receiver" - depends on ETRAX_RS485 - help - It is necessary to disable the serial receiver to avoid serial - loopback. Not all products are able to do this in software only. - config ETRAX_SYNCHRONOUS_SERIAL bool "Synchronous serial-port support" depends on ETRAX_ARCH_V32 diff --git a/arch/cris/arch-v32/drivers/i2c.c b/arch/cris/arch-v32/drivers/i2c.c index 506826399ae7..2fd6a740d895 100644 --- a/arch/cris/arch-v32/drivers/i2c.c +++ b/arch/cris/arch-v32/drivers/i2c.c @@ -649,10 +649,10 @@ i2c_release(struct inode *inode, struct file *filp) /* Main device API. ioctl's to write or read to/from i2c registers. */ -static int -i2c_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static long +i2c_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { + int ret; if(_IOC_TYPE(cmd) != ETRAXI2C_IOCTYPE) { return -ENOTTY; } @@ -665,9 +665,13 @@ i2c_ioctl(struct inode *inode, struct file *file, I2C_ARGREG(arg), I2C_ARGVALUE(arg))); - return i2c_writereg(I2C_ARGSLAVE(arg), + lock_kernel(); + ret = i2c_writereg(I2C_ARGSLAVE(arg), I2C_ARGREG(arg), I2C_ARGVALUE(arg)); + unlock_kernel(); + return ret; + case I2C_READREG: { unsigned char val; @@ -675,7 +679,9 @@ i2c_ioctl(struct inode *inode, struct file *file, D(printk("i2cr %d %d ", I2C_ARGSLAVE(arg), I2C_ARGREG(arg))); + lock_kernel(); val = i2c_readreg(I2C_ARGSLAVE(arg), I2C_ARGREG(arg)); + unlock_kernel(); D(printk("= %d\n", val)); return val; } @@ -688,10 +694,10 @@ i2c_ioctl(struct inode *inode, struct file *file, } static const struct file_operations i2c_fops = { - .owner = THIS_MODULE, - .ioctl = i2c_ioctl, - .open = i2c_open, - .release = i2c_release, + .owner = THIS_MODULE, + .unlocked_ioctl = i2c_ioctl, + .open = i2c_open, + .release = i2c_release, }; static int __init i2c_init(void) diff --git a/arch/cris/arch-v32/drivers/pcf8563.c b/arch/cris/arch-v32/drivers/pcf8563.c index f4478506e52c..bef6eb53b153 100644 --- a/arch/cris/arch-v32/drivers/pcf8563.c +++ b/arch/cris/arch-v32/drivers/pcf8563.c @@ -24,6 +24,7 @@ #include <linux/init.h> #include <linux/fs.h> #include <linux/ioctl.h> +#include <linux/smp_lock.h> #include <linux/delay.h> #include <linux/bcd.h> #include <linux/mutex.h> @@ -49,7 +50,7 @@ static DEFINE_MUTEX(rtc_lock); /* Protect state etc */ static const unsigned char days_in_month[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; -int pcf8563_ioctl(struct inode *, struct file *, unsigned int, unsigned long); +static long pcf8563_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); /* Cache VL bit value read at driver init since writing the RTC_SECOND * register clears the VL status. @@ -57,8 +58,8 @@ int pcf8563_ioctl(struct inode *, struct file *, unsigned int, unsigned long); static int voltage_low; static const struct file_operations pcf8563_fops = { - .owner = THIS_MODULE, - .ioctl = pcf8563_ioctl + .owner = THIS_MODULE, + .unlocked_ioctl = pcf8563_unlocked_ioctl, }; unsigned char @@ -208,8 +209,7 @@ pcf8563_exit(void) * ioctl calls for this driver. Why return -ENOTTY upon error? Because * POSIX says so! */ -int pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) +static int pcf8563_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { /* Some sanity checks. */ if (_IOC_TYPE(cmd) != RTC_MAGIC) @@ -335,6 +335,17 @@ int pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, return 0; } +static long pcf8563_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + int ret; + + lock_kernel(); + return pcf8563_ioctl(filp, cmd, arg); + unlock_kernel(); + + return ret; +} + static int __init pcf8563_register(void) { if (pcf8563_init() < 0) { diff --git a/arch/cris/arch-v32/kernel/crisksyms.c b/arch/cris/arch-v32/kernel/crisksyms.c index 64933e2c0f5b..bde8d1a10cad 100644 --- a/arch/cris/arch-v32/kernel/crisksyms.c +++ b/arch/cris/arch-v32/kernel/crisksyms.c @@ -24,5 +24,5 @@ EXPORT_SYMBOL(crisv32_io_get_name); EXPORT_SYMBOL(crisv32_io_get); /* Functions masking/unmasking interrupts */ -EXPORT_SYMBOL(mask_irq); -EXPORT_SYMBOL(unmask_irq); +EXPORT_SYMBOL(crisv32_mask_irq); +EXPORT_SYMBOL(crisv32_unmask_irq); diff --git a/arch/cris/arch-v32/kernel/irq.c b/arch/cris/arch-v32/kernel/irq.c index b6241198fb98..0b1febe44aa3 100644 --- a/arch/cris/arch-v32/kernel/irq.c +++ b/arch/cris/arch-v32/kernel/irq.c @@ -280,8 +280,7 @@ out: return cpu; } -void -mask_irq(int irq) +void crisv32_mask_irq(int irq) { int cpu; @@ -289,8 +288,7 @@ mask_irq(int irq) block_irq(irq, cpu); } -void -unmask_irq(int irq) +void crisv32_unmask_irq(int irq) { unblock_irq(irq, irq_cpu(irq)); } @@ -298,23 +296,23 @@ unmask_irq(int irq) static unsigned int startup_crisv32_irq(unsigned int irq) { - unmask_irq(irq); + crisv32_unmask_irq(irq); return 0; } static void shutdown_crisv32_irq(unsigned int irq) { - mask_irq(irq); + crisv32_mask_irq(irq); } static void enable_crisv32_irq(unsigned int irq) { - unmask_irq(irq); + crisv32_unmask_irq(irq); } static void disable_crisv32_irq(unsigned int irq) { - mask_irq(irq); + crisv32_mask_irq(irq); } static void ack_crisv32_irq(unsigned int irq) diff --git a/arch/cris/arch-v32/kernel/smp.c b/arch/cris/arch-v32/kernel/smp.c index 058adddf4e4b..84fed3b4b079 100644 --- a/arch/cris/arch-v32/kernel/smp.c +++ b/arch/cris/arch-v32/kernel/smp.c @@ -168,8 +168,8 @@ void __init smp_callin(void) /* Enable IRQ and idle */ REG_WR(intr_vect, irq_regs[cpu], rw_mask, vect_mask); - unmask_irq(IPI_INTR_VECT); - unmask_irq(TIMER0_INTR_VECT); + crisv32_unmask_irq(IPI_INTR_VECT); + crisv32_unmask_irq(TIMER0_INTR_VECT); preempt_disable(); notify_cpu_starting(cpu); local_irq_enable(); diff --git a/arch/cris/include/arch-v10/arch/irq.h b/arch/cris/include/arch-v10/arch/irq.h index 6248004eca1c..7d345947b3ee 100644 --- a/arch/cris/include/arch-v10/arch/irq.h +++ b/arch/cris/include/arch-v10/arch/irq.h @@ -93,15 +93,16 @@ void set_break_vector(int n, irqvectptr addr); "push $r10\n\t" /* push orig_r10 */ \ "clear.d [$sp=$sp-4]\n\t" /* frametype - this is a normal stackframe */ - /* BLOCK_IRQ and UNBLOCK_IRQ do the same as mask_irq and unmask_irq */ +/* BLOCK_IRQ and UNBLOCK_IRQ do the same as + * crisv10_mask_irq and crisv10_unmask_irq */ #define BLOCK_IRQ(mask,nr) \ "move.d " #mask ",$r0\n\t" \ - "move.d $r0,[0xb00000d8]\n\t" - + "move.d $r0,[0xb00000d8]\n\t" + #define UNBLOCK_IRQ(mask) \ "move.d " #mask ",$r0\n\t" \ - "move.d $r0,[0xb00000dc]\n\t" + "move.d $r0,[0xb00000dc]\n\t" #define IRQ_NAME2(nr) nr##_interrupt(void) #define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr) diff --git a/arch/cris/include/arch-v32/arch/irq.h b/arch/cris/include/arch-v32/arch/irq.h index 9e4c9fbdfddf..b31e9984f849 100644 --- a/arch/cris/include/arch-v32/arch/irq.h +++ b/arch/cris/include/arch-v32/arch/irq.h @@ -23,8 +23,8 @@ struct etrax_interrupt_vector { extern struct etrax_interrupt_vector *etrax_irv; /* head.S */ -void mask_irq(int irq); -void unmask_irq(int irq); +void crisv32_mask_irq(int irq); +void crisv32_unmask_irq(int irq); void set_exception_vector(int n, irqvectptr addr); diff --git a/arch/cris/include/asm/param.h b/arch/cris/include/asm/param.h index 0e47994e40be..484fcf8667c0 100644 --- a/arch/cris/include/asm/param.h +++ b/arch/cris/include/asm/param.h @@ -2,22 +2,9 @@ #define _ASMCRIS_PARAM_H /* Currently we assume that HZ=100 is good for CRIS. */ -#ifdef __KERNEL__ -# define HZ CONFIG_HZ /* Internal kernel timer frequency */ -# define USER_HZ 100 /* .. some user interfaces are in "ticks" */ -# define CLOCKS_PER_SEC (USER_HZ) /* like times() */ -#endif - -#ifndef HZ -#define HZ 100 -#endif #define EXEC_PAGESIZE 8192 -#ifndef NOGROUP -#define NOGROUP (-1) -#endif - -#define MAXHOSTNAMELEN 64 /* max length of hostname */ +#include <asm-generic/param.h> -#endif +#endif /* _ASMCRIS_PARAM_H */ diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 76818f926539..ad6c2768e85e 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -223,6 +223,36 @@ config TASK_SIZE hex "Size of user task space" if TASK_SIZE_BOOL default "0x80000000" +choice + prompt "Page size" + default MICROBLAZE_4K_PAGES + depends on ADVANCED_OPTIONS && !MMU + help + Select the kernel logical page size. Increasing the page size + will reduce software overhead at each page boundary, allow + hardware prefetch mechanisms to be more effective, and allow + larger dma transfers increasing IO efficiency and reducing + overhead. However the utilization of memory will increase. + For example, each cached file will using a multiple of the + page size to hold its contents and the difference between the + end of file and the end of page is wasted. + + If unsure, choose 4K_PAGES. + +config MICROBLAZE_4K_PAGES + bool "4k page size" + +config MICROBLAZE_8K_PAGES + bool "8k page size" + +config MICROBLAZE_16K_PAGES + bool "16k page size" + +config MICROBLAZE_32K_PAGES + bool "32k page size" + +endchoice + endmenu source "mm/Kconfig" diff --git a/arch/microblaze/include/asm/cacheflush.h b/arch/microblaze/include/asm/cacheflush.h index a6edd356cd08..401d0520fc97 100644 --- a/arch/microblaze/include/asm/cacheflush.h +++ b/arch/microblaze/include/asm/cacheflush.h @@ -17,6 +17,7 @@ /* Somebody depends on this; sigh... */ #include <linux/mm.h> +#include <linux/io.h> /* Look at Documentation/cachetlb.txt */ @@ -97,8 +98,10 @@ void microblaze_cache_init(void); #define copy_to_user_page(vma, page, vaddr, dst, src, len) \ do { \ + u32 addr = virt_to_phys(dst); \ + invalidate_icache_range((unsigned) (addr), (unsigned) (addr) + (len));\ memcpy((dst), (src), (len)); \ - flush_icache_range((unsigned) (dst), (unsigned) (dst) + (len)); \ + flush_dcache_range((unsigned) (addr), (unsigned) (addr) + (len));\ } while (0) #define copy_from_user_page(vma, page, vaddr, dst, src, len) \ diff --git a/arch/microblaze/include/asm/elf.h b/arch/microblaze/include/asm/elf.h index 7d4acf2b278e..732caf1be741 100644 --- a/arch/microblaze/include/asm/elf.h +++ b/arch/microblaze/include/asm/elf.h @@ -77,7 +77,7 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; #define ELF_DATA ELFDATA2MSB #endif -#define ELF_EXEC_PAGESIZE 4096 +#define ELF_EXEC_PAGESIZE PAGE_SIZE #define ELF_CORE_COPY_REGS(_dest, _regs) \ diff --git a/arch/microblaze/include/asm/exceptions.h b/arch/microblaze/include/asm/exceptions.h index 4c7b5d037c88..fa0e36657fdd 100644 --- a/arch/microblaze/include/asm/exceptions.h +++ b/arch/microblaze/include/asm/exceptions.h @@ -14,6 +14,11 @@ #define _ASM_MICROBLAZE_EXCEPTIONS_H #ifdef __KERNEL__ + +#ifndef CONFIG_MMU +#define EX_HANDLER_STACK_SIZ (4*19) +#endif + #ifndef __ASSEMBLY__ /* Macros to enable and disable HW exceptions in the MSR */ diff --git a/arch/microblaze/include/asm/page.h b/arch/microblaze/include/asm/page.h index de493f86d28f..1315434ab87f 100644 --- a/arch/microblaze/include/asm/page.h +++ b/arch/microblaze/include/asm/page.h @@ -23,8 +23,16 @@ #ifdef __KERNEL__ /* PAGE_SHIFT determines the page size */ -#define PAGE_SHIFT (12) -#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) +#if defined(CONFIG_MICROBLAZE_32K_PAGES) +#define PAGE_SHIFT 15 +#elif defined(CONFIG_MICROBLAZE_16K_PAGES) +#define PAGE_SHIFT 14 +#elif defined(CONFIG_MICROBLAZE_8K_PAGES) +#define PAGE_SHIFT 13 +#else +#define PAGE_SHIFT 12 +#endif +#define PAGE_SIZE (ASM_CONST(1) << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE-1)) #define LOAD_OFFSET ASM_CONST((CONFIG_KERNEL_START-CONFIG_KERNEL_BASE_ADDR)) diff --git a/arch/microblaze/include/asm/system.h b/arch/microblaze/include/asm/system.h index 48c4f0335e3f..4f8eaea21f88 100644 --- a/arch/microblaze/include/asm/system.h +++ b/arch/microblaze/include/asm/system.h @@ -45,7 +45,6 @@ extern struct task_struct *_switch_to(struct thread_info *prev, #define smp_rmb() rmb() #define smp_wmb() wmb() -void show_trace(struct task_struct *task, unsigned long *stack); void __bad_xchg(volatile void *ptr, int size); static inline unsigned long __xchg(unsigned long x, volatile void *ptr, diff --git a/arch/microblaze/include/asm/uaccess.h b/arch/microblaze/include/asm/uaccess.h index 26460d15b338..d840f4a2d3c9 100644 --- a/arch/microblaze/include/asm/uaccess.h +++ b/arch/microblaze/include/asm/uaccess.h @@ -359,7 +359,7 @@ extern long __user_bad(void); __copy_tofrom_user((__force void __user *)(to), \ (void __user *)(from), (n)) #define __copy_from_user_inatomic(to, from, n) \ - copy_from_user((to), (from), (n)) + __copy_from_user((to), (from), (n)) static inline long copy_from_user(void *to, const void __user *from, unsigned long n) @@ -373,7 +373,7 @@ static inline long copy_from_user(void *to, #define __copy_to_user(to, from, n) \ __copy_tofrom_user((void __user *)(to), \ (__force const void __user *)(from), (n)) -#define __copy_to_user_inatomic(to, from, n) copy_to_user((to), (from), (n)) +#define __copy_to_user_inatomic(to, from, n) __copy_to_user((to), (from), (n)) static inline long copy_to_user(void __user *to, const void *from, unsigned long n) diff --git a/arch/microblaze/include/asm/unwind.h b/arch/microblaze/include/asm/unwind.h new file mode 100644 index 000000000000..d248b7de4b13 --- /dev/null +++ b/arch/microblaze/include/asm/unwind.h @@ -0,0 +1,29 @@ +/* + * Backtrace support for Microblaze + * + * Copyright (C) 2010 Digital Design Corporation + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef __MICROBLAZE_UNWIND_H +#define __MICROBLAZE_UNWIND_H + +struct stack_trace; + +struct trap_handler_info { + unsigned long start_addr; + unsigned long end_addr; + const char *trap_name; +}; +extern struct trap_handler_info microblaze_trap_handlers; + +extern const char _hw_exception_handler; +extern const char ex_handler_unhandled; + +void microblaze_unwind(struct task_struct *task, struct stack_trace *trace); + +#endif /* __MICROBLAZE_UNWIND_H */ + diff --git a/arch/microblaze/kernel/Makefile b/arch/microblaze/kernel/Makefile index e51bc1520825..d66ddef53c07 100644 --- a/arch/microblaze/kernel/Makefile +++ b/arch/microblaze/kernel/Makefile @@ -17,7 +17,7 @@ extra-y := head.o vmlinux.lds obj-y += dma.o exceptions.o \ hw_exception_handler.o init_task.o intc.o irq.o of_device.o \ of_platform.o process.o prom.o prom_parse.o ptrace.o \ - setup.o signal.o sys_microblaze.o timer.o traps.o reset.o + reset.o setup.o signal.o sys_microblaze.o timer.o traps.o unwind.o obj-y += cpu/ diff --git a/arch/microblaze/kernel/cpu/mb.c b/arch/microblaze/kernel/cpu/mb.c index 4216eb1eaa32..7086e3564281 100644 --- a/arch/microblaze/kernel/cpu/mb.c +++ b/arch/microblaze/kernel/cpu/mb.c @@ -126,6 +126,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) cpuinfo.pvr_user1, cpuinfo.pvr_user2); + count += seq_printf(m, "Page size:\t%lu\n", PAGE_SIZE); return 0; } diff --git a/arch/microblaze/kernel/entry-nommu.S b/arch/microblaze/kernel/entry-nommu.S index 8cc18cd2cce6..ca84368570b6 100644 --- a/arch/microblaze/kernel/entry-nommu.S +++ b/arch/microblaze/kernel/entry-nommu.S @@ -588,3 +588,31 @@ sys_rt_sigsuspend_wrapper: #include "syscall_table.S" syscall_table_size=(.-sys_call_table) + +type_SYSCALL: + .ascii "SYSCALL\0" +type_IRQ: + .ascii "IRQ\0" +type_IRQ_PREEMPT: + .ascii "IRQ (PREEMPTED)\0" +type_SYSCALL_PREEMPT: + .ascii " SYSCALL (PREEMPTED)\0" + + /* + * Trap decoding for stack unwinder + * Tuples are (start addr, end addr, string) + * If return address lies on [start addr, end addr], + * unwinder displays 'string' + */ + + .align 4 +.global microblaze_trap_handlers +microblaze_trap_handlers: + /* Exact matches come first */ + .word ret_to_user ; .word ret_to_user ; .word type_SYSCALL + .word ret_from_intr; .word ret_from_intr ; .word type_IRQ + /* Fuzzy matches go here */ + .word ret_from_intr; .word no_intr_resched; .word type_IRQ_PREEMPT + .word work_pending ; .word no_work_pending; .word type_SYSCALL_PREEMPT + /* End of table */ + .word 0 ; .word 0 ; .word 0 diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S index c0ede25c5b99..ef1caae36445 100644 --- a/arch/microblaze/kernel/entry.S +++ b/arch/microblaze/kernel/entry.S @@ -1127,3 +1127,30 @@ ENTRY(_break) syscall_table_size=(.-sys_call_table) +type_SYSCALL: + .ascii "SYSCALL\0" +type_IRQ: + .ascii "IRQ\0" +type_IRQ_PREEMPT: + .ascii "IRQ (PREEMPTED)\0" +type_SYSCALL_PREEMPT: + .ascii " SYSCALL (PREEMPTED)\0" + + /* + * Trap decoding for stack unwinder + * Tuples are (start addr, end addr, string) + * If return address lies on [start addr, end addr], + * unwinder displays 'string' + */ + + .align 4 +.global microblaze_trap_handlers +microblaze_trap_handlers: + /* Exact matches come first */ + .word ret_from_trap; .word ret_from_trap ; .word type_SYSCALL + .word ret_from_irq ; .word ret_from_irq ; .word type_IRQ + /* Fuzzy matches go here */ + .word ret_from_irq ; .word no_intr_resched ; .word type_IRQ_PREEMPT + .word ret_from_trap; .word TRAP_return ; .word type_SYSCALL_PREEMPT + /* End of table */ + .word 0 ; .word 0 ; .word 0 diff --git a/arch/microblaze/kernel/head.S b/arch/microblaze/kernel/head.S index 1bf739888260..42434008209e 100644 --- a/arch/microblaze/kernel/head.S +++ b/arch/microblaze/kernel/head.S @@ -43,10 +43,10 @@ .global empty_zero_page .align 12 empty_zero_page: - .space 4096 + .space PAGE_SIZE .global swapper_pg_dir swapper_pg_dir: - .space 4096 + .space PAGE_SIZE #endif /* CONFIG_MMU */ diff --git a/arch/microblaze/kernel/hw_exception_handler.S b/arch/microblaze/kernel/hw_exception_handler.S index 995a2123635b..781195438ee6 100644 --- a/arch/microblaze/kernel/hw_exception_handler.S +++ b/arch/microblaze/kernel/hw_exception_handler.S @@ -78,9 +78,6 @@ #include <asm/asm-offsets.h> /* Helpful Macros */ -#ifndef CONFIG_MMU -#define EX_HANDLER_STACK_SIZ (4*19) -#endif #define NUM_TO_REG(num) r ## num #ifdef CONFIG_MMU @@ -988,6 +985,7 @@ ex_unaligned_fixup: .end _unaligned_data_exception #endif /* CONFIG_MMU */ +.global ex_handler_unhandled ex_handler_unhandled: /* FIXME add handle function for unhandled exception - dump register */ bri 0 diff --git a/arch/microblaze/kernel/irq.c b/arch/microblaze/kernel/irq.c index 8f120aca123d..842ef4950500 100644 --- a/arch/microblaze/kernel/irq.c +++ b/arch/microblaze/kernel/irq.c @@ -36,6 +36,7 @@ static u32 concurrent_irq; void __irq_entry do_IRQ(struct pt_regs *regs) { unsigned int irq; + trace_hardirqs_off(); struct pt_regs *old_regs = set_irq_regs(regs); irq_enter(); @@ -53,6 +54,7 @@ next_irq: irq_exit(); set_irq_regs(old_regs); + trace_hardirqs_on(); } int show_interrupts(struct seq_file *p, void *v) diff --git a/arch/microblaze/kernel/ptrace.c b/arch/microblaze/kernel/ptrace.c index a4a7770c6140..dc03ffc8174a 100644 --- a/arch/microblaze/kernel/ptrace.c +++ b/arch/microblaze/kernel/ptrace.c @@ -38,6 +38,8 @@ #include <asm/processor.h> #include <linux/uaccess.h> #include <asm/asm-offsets.h> +#include <asm/cacheflush.h> +#include <asm/io.h> /* Returns the address where the register at REG_OFFS in P is stashed away. */ static microblaze_reg_t *reg_save_addr(unsigned reg_offs, @@ -101,8 +103,21 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) microblaze_reg_t *reg_addr = reg_save_addr(addr, child); if (request == PTRACE_PEEKUSR) val = *reg_addr; - else + else { +#if 1 *reg_addr = data; +#else + /* MS potential problem on WB system + * Be aware that reg_addr is virtual address + * virt_to_phys conversion is necessary. + * This could be sensible solution. + */ + u32 paddr = virt_to_phys((u32)reg_addr); + invalidate_icache_range(paddr, paddr + 4); + *reg_addr = data; + flush_dcache_range(paddr, paddr + 4); +#endif + } } else rval = -EIO; diff --git a/arch/microblaze/kernel/stacktrace.c b/arch/microblaze/kernel/stacktrace.c index 123692f22647..84bc6686102c 100644 --- a/arch/microblaze/kernel/stacktrace.c +++ b/arch/microblaze/kernel/stacktrace.c @@ -14,52 +14,18 @@ #include <linux/thread_info.h> #include <linux/ptrace.h> #include <linux/module.h> +#include <asm/unwind.h> -/* FIXME initial support */ void save_stack_trace(struct stack_trace *trace) { - unsigned long *sp; - unsigned long addr; - asm("addik %0, r1, 0" : "=r" (sp)); - - while (!kstack_end(sp)) { - addr = *sp++; - if (__kernel_text_address(addr)) { - if (trace->skip > 0) - trace->skip--; - else - trace->entries[trace->nr_entries++] = addr; - - if (trace->nr_entries >= trace->max_entries) - break; - } - } + /* Exclude our helper functions from the trace*/ + trace->skip += 2; + microblaze_unwind(NULL, trace); } EXPORT_SYMBOL_GPL(save_stack_trace); void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) { - unsigned int *sp; - unsigned long addr; - - struct thread_info *ti = task_thread_info(tsk); - - if (tsk == current) - asm("addik %0, r1, 0" : "=r" (sp)); - else - sp = (unsigned int *)ti->cpu_context.r1; - - while (!kstack_end(sp)) { - addr = *sp++; - if (__kernel_text_address(addr)) { - if (trace->skip > 0) - trace->skip--; - else - trace->entries[trace->nr_entries++] = addr; - - if (trace->nr_entries >= trace->max_entries) - break; - } - } + microblaze_unwind(tsk, trace); } EXPORT_SYMBOL_GPL(save_stack_trace_tsk); diff --git a/arch/microblaze/kernel/traps.c b/arch/microblaze/kernel/traps.c index 75e49202a5ed..ba034d421ec2 100644 --- a/arch/microblaze/kernel/traps.c +++ b/arch/microblaze/kernel/traps.c @@ -16,13 +16,14 @@ #include <asm/exceptions.h> #include <asm/system.h> +#include <asm/unwind.h> void trap_init(void) { __enable_hw_exceptions(); } -static unsigned long kstack_depth_to_print = 24; +static unsigned long kstack_depth_to_print; /* 0 == entire stack */ static int __init kstack_setup(char *s) { @@ -30,31 +31,47 @@ static int __init kstack_setup(char *s) } __setup("kstack=", kstack_setup); -void show_trace(struct task_struct *task, unsigned long *stack) +void show_stack(struct task_struct *task, unsigned long *sp) { - unsigned long addr; - - if (!stack) - stack = (unsigned long *)&stack; + unsigned long words_to_show; + u32 fp = (u32) sp; + + if (fp == 0) { + if (task) { + fp = ((struct thread_info *) + (task->stack))->cpu_context.r1; + } else { + /* Pick up caller of dump_stack() */ + fp = (u32)&sp - 8; + } + } - printk(KERN_NOTICE "Call Trace: "); -#ifdef CONFIG_KALLSYMS - printk(KERN_NOTICE "\n"); -#endif - while (!kstack_end(stack)) { - addr = *stack++; - /* - * If the address is either in the text segment of the - * kernel, or in the region which contains vmalloc'ed - * memory, it *may* be the address of a calling - * routine; if so, print it so that someone tracing - * down the cause of the crash will be able to figure - * out the call path that was taken. - */ - if (kernel_text_address(addr)) - print_ip_sym(addr); + words_to_show = (THREAD_SIZE - (fp & (THREAD_SIZE - 1))) >> 2; + if (kstack_depth_to_print && (words_to_show > kstack_depth_to_print)) + words_to_show = kstack_depth_to_print; + + pr_info("Kernel Stack:\n"); + + /* + * Make the first line an 'odd' size if necessary to get + * remaining lines to start at an address multiple of 0x10 + */ + if (fp & 0xF) { + unsigned long line1_words = (0x10 - (fp & 0xF)) >> 2; + if (line1_words < words_to_show) { + print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 32, + 4, (void *)fp, line1_words << 2, 0); + fp += line1_words << 2; + words_to_show -= line1_words; + } } - printk(KERN_NOTICE "\n"); + print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 32, 4, (void *)fp, + words_to_show << 2, 0); + printk(KERN_INFO "\n\n"); + + pr_info("Call Trace:\n"); + microblaze_unwind(task, NULL); + pr_info("\n"); if (!task) task = current; @@ -62,34 +79,6 @@ void show_trace(struct task_struct *task, unsigned long *stack) debug_show_held_locks(task); } -void show_stack(struct task_struct *task, unsigned long *sp) -{ - unsigned long *stack; - int i; - - if (sp == NULL) { - if (task) - sp = (unsigned long *) ((struct thread_info *) - (task->stack))->cpu_context.r1; - else - sp = (unsigned long *)&sp; - } - - stack = sp; - - printk(KERN_INFO "\nStack:\n "); - - for (i = 0; i < kstack_depth_to_print; i++) { - if (kstack_end(sp)) - break; - if (i && ((i % 8) == 0)) - printk("\n "); - printk("%08lx ", *sp++); - } - printk("\n"); - show_trace(task, stack); -} - void dump_stack(void) { show_stack(NULL, NULL); diff --git a/arch/microblaze/kernel/unwind.c b/arch/microblaze/kernel/unwind.c new file mode 100644 index 000000000000..fefac5c33586 --- /dev/null +++ b/arch/microblaze/kernel/unwind.c @@ -0,0 +1,318 @@ +/* + * Backtrace support for Microblaze + * + * Copyright (C) 2010 Digital Design Corporation + * + * Based on arch/sh/kernel/cpu/sh5/unwind.c code which is: + * Copyright (C) 2004 Paul Mundt + * Copyright (C) 2004 Richard Curnow + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +/* #define DEBUG 1 */ +#include <linux/kallsyms.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/stacktrace.h> +#include <linux/types.h> +#include <linux/errno.h> +#include <linux/module.h> +#include <linux/io.h> +#include <asm/sections.h> +#include <asm/exceptions.h> +#include <asm/unwind.h> + +struct stack_trace; + +/* + * On Microblaze, finding the previous stack frame is a little tricky. + * At this writing (3/2010), Microblaze does not support CONFIG_FRAME_POINTERS, + * and even if it did, gcc (4.1.2) does not store the frame pointer at + * a consistent offset within each frame. To determine frame size, it is + * necessary to search for the assembly instruction that creates or reclaims + * the frame and extract the size from it. + * + * Microblaze stores the stack pointer in r1, and creates a frame via + * + * addik r1, r1, -FRAME_SIZE + * + * The frame is reclaimed via + * + * addik r1, r1, FRAME_SIZE + * + * Frame creation occurs at or near the top of a function. + * Depending on the compiler, reclaim may occur at the end, or before + * a mid-function return. + * + * A stack frame is usually not created in a leaf function. + * + */ + +/** + * get_frame_size - Extract the stack adjustment from an + * "addik r1, r1, adjust" instruction + * @instr : Microblaze instruction + * + * Return - Number of stack bytes the instruction reserves or reclaims + */ +inline long get_frame_size(unsigned long instr) +{ + return abs((s16)(instr & 0xFFFF)); +} + +/** + * find_frame_creation - Search backward to find the instruction that creates + * the stack frame (hopefully, for the same function the + * initial PC is in). + * @pc : Program counter at which to begin the search + * + * Return - PC at which stack frame creation occurs + * NULL if this cannot be found, i.e. a leaf function + */ +static unsigned long *find_frame_creation(unsigned long *pc) +{ + int i; + + /* NOTE: Distance to search is arbitrary + * 250 works well for most things, + * 750 picks up things like tcp_recvmsg(), + * 1000 needed for fat_fill_super() + */ + for (i = 0; i < 1000; i++, pc--) { + unsigned long instr; + s16 frame_size; + + if (!kernel_text_address((unsigned long) pc)) + return NULL; + + instr = *pc; + + /* addik r1, r1, foo ? */ + if ((instr & 0xFFFF0000) != 0x30210000) + continue; /* No */ + + frame_size = get_frame_size(instr); + if ((frame_size < 8) || (frame_size & 3)) { + pr_debug(" Invalid frame size %d at 0x%p\n", + frame_size, pc); + return NULL; + } + + pr_debug(" Found frame creation at 0x%p, size %d\n", pc, + frame_size); + return pc; + } + + return NULL; +} + +/** + * lookup_prev_stack_frame - Find the stack frame of the previous function. + * @fp : Frame (stack) pointer for current function + * @pc : Program counter within current function + * @leaf_return : r15 value within current function. If the current function + * is a leaf, this is the caller's return address. + * @pprev_fp : On exit, set to frame (stack) pointer for previous function + * @pprev_pc : On exit, set to current function caller's return address + * + * Return - 0 on success, -EINVAL if the previous frame cannot be found + */ +static int lookup_prev_stack_frame(unsigned long fp, unsigned long pc, + unsigned long leaf_return, + unsigned long *pprev_fp, + unsigned long *pprev_pc) +{ + unsigned long *prologue = NULL; + + /* _switch_to is a special leaf function */ + if (pc != (unsigned long) &_switch_to) + prologue = find_frame_creation((unsigned long *)pc); + + if (prologue) { + long frame_size = get_frame_size(*prologue); + + *pprev_fp = fp + frame_size; + *pprev_pc = *(unsigned long *)fp; + } else { + if (!leaf_return) + return -EINVAL; + *pprev_pc = leaf_return; + *pprev_fp = fp; + } + + /* NOTE: don't check kernel_text_address here, to allow display + * of userland return address + */ + return (!*pprev_pc || (*pprev_pc & 3)) ? -EINVAL : 0; +} + +static void microblaze_unwind_inner(struct task_struct *task, + unsigned long pc, unsigned long fp, + unsigned long leaf_return, + struct stack_trace *trace); + +/** + * unwind_trap - Unwind through a system trap, that stored previous state + * on the stack. + */ +#ifdef CONFIG_MMU +static inline void unwind_trap(struct task_struct *task, unsigned long pc, + unsigned long fp, struct stack_trace *trace) +{ + /* To be implemented */ +} +#else +static inline void unwind_trap(struct task_struct *task, unsigned long pc, + unsigned long fp, struct stack_trace *trace) +{ + const struct pt_regs *regs = (const struct pt_regs *) fp; + microblaze_unwind_inner(task, regs->pc, regs->r1, regs->r15, trace); +} +#endif + +/** + * microblaze_unwind_inner - Unwind the stack from the specified point + * @task : Task whose stack we are to unwind (may be NULL) + * @pc : Program counter from which we start unwinding + * @fp : Frame (stack) pointer from which we start unwinding + * @leaf_return : Value of r15 at pc. If the function is a leaf, this is + * the caller's return address. + * @trace : Where to store stack backtrace (PC values). + * NULL == print backtrace to kernel log + */ +void microblaze_unwind_inner(struct task_struct *task, + unsigned long pc, unsigned long fp, + unsigned long leaf_return, + struct stack_trace *trace) +{ + int ofs = 0; + + pr_debug(" Unwinding with PC=%p, FP=%p\n", (void *)pc, (void *)fp); + if (!pc || !fp || (pc & 3) || (fp & 3)) { + pr_debug(" Invalid state for unwind, aborting\n"); + return; + } + for (; pc != 0;) { + unsigned long next_fp, next_pc = 0; + unsigned long return_to = pc + 2 * sizeof(unsigned long); + const struct trap_handler_info *handler = + µblaze_trap_handlers; + + /* Is previous function the HW exception handler? */ + if ((return_to >= (unsigned long)&_hw_exception_handler) + &&(return_to < (unsigned long)&ex_handler_unhandled)) { + /* + * HW exception handler doesn't save all registers, + * so we open-code a special case of unwind_trap() + */ +#ifndef CONFIG_MMU + const struct pt_regs *regs = + (const struct pt_regs *) fp; +#endif + pr_info("HW EXCEPTION\n"); +#ifndef CONFIG_MMU + microblaze_unwind_inner(task, regs->r17 - 4, + fp + EX_HANDLER_STACK_SIZ, + regs->r15, trace); +#endif + return; + } + + /* Is previous function a trap handler? */ + for (; handler->start_addr; ++handler) { + if ((return_to >= handler->start_addr) + && (return_to <= handler->end_addr)) { + if (!trace) + pr_info("%s\n", handler->trap_name); + unwind_trap(task, pc, fp, trace); + return; + } + } + pc -= ofs; + + if (trace) { +#ifdef CONFIG_STACKTRACE + if (trace->skip > 0) + trace->skip--; + else + trace->entries[trace->nr_entries++] = pc; + + if (trace->nr_entries >= trace->max_entries) + break; +#endif + } else { + /* Have we reached userland? */ + if (unlikely(pc == task_pt_regs(task)->pc)) { + pr_info("[<%p>] PID %lu [%s]\n", + (void *) pc, + (unsigned long) task->pid, + task->comm); + break; + } else + print_ip_sym(pc); + } + + /* Stop when we reach anything not part of the kernel */ + if (!kernel_text_address(pc)) + break; + + if (lookup_prev_stack_frame(fp, pc, leaf_return, &next_fp, + &next_pc) == 0) { + ofs = sizeof(unsigned long); + pc = next_pc & ~3; + fp = next_fp; + leaf_return = 0; + } else { + pr_debug(" Failed to find previous stack frame\n"); + break; + } + + pr_debug(" Next PC=%p, next FP=%p\n", + (void *)next_pc, (void *)next_fp); + } +} + +/** + * microblaze_unwind - Stack unwinder for Microblaze (external entry point) + * @task : Task whose stack we are to unwind (NULL == current) + * @trace : Where to store stack backtrace (PC values). + * NULL == print backtrace to kernel log + */ +void microblaze_unwind(struct task_struct *task, struct stack_trace *trace) +{ + if (task) { + if (task == current) { + const struct pt_regs *regs = task_pt_regs(task); + microblaze_unwind_inner(task, regs->pc, regs->r1, + regs->r15, trace); + } else { + struct thread_info *thread_info = + (struct thread_info *)(task->stack); + const struct cpu_context *cpu_context = + &thread_info->cpu_context; + + microblaze_unwind_inner(task, + (unsigned long) &_switch_to, + cpu_context->r1, + cpu_context->r15, trace); + } + } else { + unsigned long pc, fp; + + __asm__ __volatile__ ("or %0, r1, r0" : "=r" (fp)); + + __asm__ __volatile__ ( + "brlid %0, 0f;" + "nop;" + "0:" + : "=r" (pc) + ); + + /* Since we are not a leaf function, use leaf_return = 0 */ + microblaze_unwind_inner(current, pc, fp, 0, trace); + } +} + diff --git a/arch/microblaze/kernel/vmlinux.lds.S b/arch/microblaze/kernel/vmlinux.lds.S index db72d7124602..b0de1a6b5513 100644 --- a/arch/microblaze/kernel/vmlinux.lds.S +++ b/arch/microblaze/kernel/vmlinux.lds.S @@ -55,7 +55,7 @@ SECTIONS { */ .sdata2 : AT(ADDR(.sdata2) - LOAD_OFFSET) { _ssrw = .; - . = ALIGN(4096); /* page aligned when MMU used - origin 0x8 */ + . = ALIGN(PAGE_SIZE); /* page aligned when MMU used */ *(.sdata2) . = ALIGN(8); _essrw = .; @@ -70,7 +70,7 @@ SECTIONS { /* Reserve some low RAM for r0 based memory references */ . = ALIGN(0x4) ; r0_ram = . ; - . = . + 4096; /* a page should be enough */ + . = . + PAGE_SIZE; /* a page should be enough */ /* Under the microblaze ABI, .sdata and .sbss must be contiguous */ . = ALIGN(8); @@ -120,7 +120,7 @@ SECTIONS { __init_end_before_initramfs = .; - .init.ramfs ALIGN(4096) : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { + .init.ramfs ALIGN(PAGE_SIZE) : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { __initramfs_start = .; *(.init.ramfs) __initramfs_end = .; @@ -132,11 +132,11 @@ SECTIONS { * so that __init_end == __bss_start. This will make image.elf * consistent with the image.bin */ - /* . = ALIGN(4096); */ + /* . = ALIGN(PAGE_SIZE); */ } __init_end = .; - .bss ALIGN (4096) : AT(ADDR(.bss) - LOAD_OFFSET) { + .bss ALIGN (PAGE_SIZE) : AT(ADDR(.bss) - LOAD_OFFSET) { /* page aligned when MMU used */ __bss_start = . ; *(.bss*) @@ -145,7 +145,7 @@ SECTIONS { __bss_stop = . ; _ebss = . ; } - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); _end = .; DISCARDS diff --git a/arch/microblaze/mm/init.c b/arch/microblaze/mm/init.c index cca3579d4268..573b97e7c14b 100644 --- a/arch/microblaze/mm/init.c +++ b/arch/microblaze/mm/init.c @@ -134,13 +134,8 @@ void __init setup_memory(void) * for 4GB of memory, using 4kB pages), plus 1 page * (in case the address isn't page-aligned). */ -#ifndef CONFIG_MMU - map_size = init_bootmem_node(NODE_DATA(0), PFN_UP(TOPHYS((u32)klimit)), - min_low_pfn, max_low_pfn); -#else - map_size = init_bootmem_node(&contig_page_data, + map_size = init_bootmem_node(NODE_DATA(0), PFN_UP(TOPHYS((u32)klimit)), min_low_pfn, max_low_pfn); -#endif lmb_reserve(PFN_UP(TOPHYS((u32)klimit)) << PAGE_SHIFT, map_size); /* free bootmem is whole main memory */ diff --git a/arch/mips/Kbuild b/arch/mips/Kbuild new file mode 100644 index 000000000000..e322d65f33a4 --- /dev/null +++ b/arch/mips/Kbuild @@ -0,0 +1,15 @@ +# Fail on warnings - also for files referenced in subdirs +# -Werror can be disabled for specific files using: +# CFLAGS_<file.o> := -Wno-error +subdir-ccflags-y := -Werror + +# platform specific definitions +include arch/mips/Kbuild.platforms +obj-y := $(platform-y) + +# mips object files +# The object files are linked as core-y files would be linked + +obj-y += kernel/ +obj-y += mm/ +obj-y += math-emu/ diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms new file mode 100644 index 000000000000..681b2d4d88f5 --- /dev/null +++ b/arch/mips/Kbuild.platforms @@ -0,0 +1,6 @@ +# All platforms listed in alphabetic order + +platforms += ar7 + +# include the platform specific files +include $(patsubst %, $(srctree)/arch/mips/%/Platform, $(platforms)) diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 0b9c01add0a0..ff71a5480b15 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -209,13 +209,7 @@ endif # # Board-dependent options and extra files # - -# -# Texas Instruments AR7 -# -core-$(CONFIG_AR7) += arch/mips/ar7/ -cflags-$(CONFIG_AR7) += -I$(srctree)/arch/mips/include/asm/mach-ar7 -load-$(CONFIG_AR7) += 0xffffffff94100000 +include $(srctree)/arch/mips/Kbuild.platforms # # Acer PICA 61, Mips Magnum 4000 and Olivetti M700. @@ -706,7 +700,8 @@ head-y := arch/mips/kernel/head.o arch/mips/kernel/init_task.o libs-y += arch/mips/lib/ -core-y += arch/mips/kernel/ arch/mips/mm/ arch/mips/math-emu/ +# See arch/mips/Kbuild for content of core part of the kernel +core-y += arch/mips/ drivers-$(CONFIG_OPROFILE) += arch/mips/oprofile/ @@ -733,35 +728,19 @@ vmlinux.32: vmlinux vmlinux.64: vmlinux $(OBJCOPY) -O $(64bit-bfd) $(OBJCOPYFLAGS) $< $@ -makeboot =$(Q)$(MAKE) $(build)=arch/mips/boot VMLINUX=$(vmlinux-32) $(1) -makezboot =$(Q)$(MAKE) $(build)=arch/mips/boot/compressed \ - VMLINUX_LOAD_ADDRESS=$(load-y) 32bit-bfd=$(32bit-bfd) $(1) - all: $(all-y) -vmlinuz: vmlinux FORCE - +@$(call makezboot,$@) - -vmlinuz.bin: vmlinux - +@$(call makezboot,$@) +# boot +vmlinux.bin vmlinux.ecoff vmlinux.srec: $(vmlinux-32) FORCE + $(Q)$(MAKE) $(build)=arch/mips/boot VMLINUX=$(vmlinux-32) arch/mips/boot/$@ -vmlinuz.ecoff: vmlinux - +@$(call makezboot,$@) +# boot/compressed +vmlinuz vmlinuz.bin vmlinuz.ecoff vmlinuz.srec: $(vmlinux-32) FORCE + $(Q)$(MAKE) $(build)=arch/mips/boot/compressed \ + VMLINUX_LOAD_ADDRESS=$(load-y) 32bit-bfd=$(32bit-bfd) $@ -vmlinuz.srec: vmlinux - +@$(call makezboot,$@) -vmlinux.bin: $(vmlinux-32) - +@$(call makeboot,$@) - -vmlinux.ecoff: $(vmlinux-32) - +@$(call makeboot,$@) - -vmlinux.srec: $(vmlinux-32) - +@$(call makeboot,$@) - -CLEAN_FILES += vmlinux.ecoff \ - vmlinux.srec +CLEAN_FILES += vmlinux.32 vmlinux.64 archprepare: ifdef CONFIG_MIPS32_N32 @@ -780,9 +759,9 @@ install: $(Q)install -D -m 644 System.map $(INSTALL_PATH)/System.map-$(KERNELRELEASE) archclean: - @$(MAKE) $(clean)=arch/mips/boot - @$(MAKE) $(clean)=arch/mips/boot/compressed - @$(MAKE) $(clean)=arch/mips/lasat + $(Q)$(MAKE) $(clean)=arch/mips/boot + $(Q)$(MAKE) $(clean)=arch/mips/boot/compressed + $(Q)$(MAKE) $(clean)=arch/mips/lasat define archhelp echo ' install - install kernel into $(INSTALL_PATH)' @@ -796,11 +775,3 @@ define archhelp echo echo ' These will be default as apropriate for a configured platform.' endef - -CLEAN_FILES += vmlinux.32 \ - vmlinux.64 \ - vmlinux.ecoff \ - vmlinuz \ - vmlinuz.ecoff \ - vmlinuz.bin \ - vmlinuz.srec diff --git a/arch/mips/ar7/Platform b/arch/mips/ar7/Platform new file mode 100644 index 000000000000..0bf85c416c6c --- /dev/null +++ b/arch/mips/ar7/Platform @@ -0,0 +1,6 @@ +# +# Texas Instruments AR7 +# +platform-$(CONFIG_AR7) += ar7/ +cflags-$(CONFIG_AR7) += -I$(srctree)/arch/mips/include/asm/mach-ar7 +load-$(CONFIG_AR7) += 0xffffffff94100000 diff --git a/arch/mips/boot/Makefile b/arch/mips/boot/Makefile index e39a08edcaaa..85bcb5adc7cb 100644 --- a/arch/mips/boot/Makefile +++ b/arch/mips/boot/Makefile @@ -11,35 +11,32 @@ # Some DECstations need all possible sections of an ECOFF executable # ifdef CONFIG_MACH_DECSTATION - E2EFLAGS = -a -else - E2EFLAGS = + e2eflag := -a endif # # Drop some uninteresting sections in the kernel. # This is only relevant for ELF kernels but doesn't hurt a.out # -drop-sections = .reginfo .mdebug .comment .note .pdr .options .MIPS.options -strip-flags = $(addprefix --remove-section=,$(drop-sections)) - -VMLINUX = vmlinux - -all: vmlinux.ecoff vmlinux.srec - -vmlinux.ecoff: $(obj)/elf2ecoff $(VMLINUX) - $(obj)/elf2ecoff $(VMLINUX) $(obj)/vmlinux.ecoff $(E2EFLAGS) - -$(obj)/elf2ecoff: $(obj)/elf2ecoff.c - $(HOSTCC) -o $@ $^ - -vmlinux.bin: $(VMLINUX) - $(OBJCOPY) -O binary $(strip-flags) $(VMLINUX) $(obj)/vmlinux.bin - -vmlinux.srec: $(VMLINUX) - $(OBJCOPY) -S -O srec $(strip-flags) $(VMLINUX) $(obj)/vmlinux.srec - -clean-files += elf2ecoff \ - vmlinux.bin \ - vmlinux.ecoff \ - vmlinux.srec +drop-sections := .reginfo .mdebug .comment .note .pdr .options .MIPS.options +strip-flags := $(addprefix --remove-section=,$(drop-sections)) + +hostprogs-y := elf2ecoff + +targets := vmlinux.ecoff +quiet_cmd_ecoff = ECOFF $@ + cmd_ecoff = $(obj)/elf2ecoff $(VMLINUX) $@ $(e2eflag) +$(obj)/vmlinux.ecoff: $(obj)/elf2ecoff $(VMLINUX) FORCE + $(call if_changed,ecoff) + +targets += vmlinux.bin +quiet_cmd_bin = OBJCOPY $@ + cmd_bin = $(OBJCOPY) -O binary $(strip-flags) $(VMLINUX) $@ +$(obj)/vmlinux.bin: $(VMLINUX) FORCE + $(call if_changed,bin) + +targets += vmlinux.srec +quiet_cmd_srec = OBJCOPY $@ + cmd_srec = $(OBJCOPY) -S -O srec $(strip-flags) $(VMLINUX) $@ +$(obj)/vmlinux.srec: $(VMLINUX) FORCE + $(call if_changed,srec) diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile index 790ddd397620..74a52d799346 100644 --- a/arch/mips/boot/compressed/Makefile +++ b/arch/mips/boot/compressed/Makefile @@ -33,15 +33,19 @@ KBUILD_AFLAGS := $(LINUXINCLUDE) $(KBUILD_AFLAGS) -D__ASSEMBLY__ \ -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) \ -DKERNEL_ENTRY=0x$(shell $(NM) $(objtree)/$(KBUILD_IMAGE) 2>/dev/null | grep " kernel_entry" | cut -f1 -d \ ) -obj-y := $(obj)/head.o $(obj)/decompress.o $(obj)/dbg.o +targets := head.o decompress.o dbg.o uart-16550.o uart-alchemy.o + +# decompressor objects (linked with vmlinuz) +vmlinuzobjs-y := $(obj)/head.o $(obj)/decompress.o $(obj)/dbg.o ifdef CONFIG_DEBUG_ZBOOT -obj-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART16550) += $(obj)/uart-16550.o -obj-$(CONFIG_MACH_ALCHEMY) += $(obj)/uart-alchemy.o +vmlinuzobjs-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART16550) += $(obj)/uart-16550.o +vmlinuzobjs-$(CONFIG_MACH_ALCHEMY) += $(obj)/uart-alchemy.o endif +targets += vmlinux.bin OBJCOPYFLAGS_vmlinux.bin := $(OBJCOPYFLAGS) -O binary -R .comment -S -$(obj)/vmlinux.bin: $(KBUILD_IMAGE) +$(obj)/vmlinux.bin: $(KBUILD_IMAGE) FORCE $(call if_changed,objcopy) suffix_$(CONFIG_KERNEL_GZIP) = gz @@ -52,30 +56,31 @@ tool_$(CONFIG_KERNEL_GZIP) = gzip tool_$(CONFIG_KERNEL_BZIP2) = bzip2 tool_$(CONFIG_KERNEL_LZMA) = lzma tool_$(CONFIG_KERNEL_LZO) = lzo -$(obj)/vmlinux.$(suffix_y): $(obj)/vmlinux.bin + +targets += vmlinux.gz vmlinux.bz2 vmlinux.lzma vmlinux.lzo +$(obj)/vmlinux.$(suffix_y): $(obj)/vmlinux.bin FORCE $(call if_changed,$(tool_y)) -$(obj)/piggy.o: $(obj)/vmlinux.$(suffix_y) $(obj)/dummy.o - $(Q)$(OBJCOPY) $(OBJCOPYFLAGS) \ - --add-section=.image=$< \ - --set-section-flags=.image=contents,alloc,load,readonly,data \ - $(obj)/dummy.o $@ +targets += piggy.o +OBJCOPYFLAGS_piggy.o := --add-section=.image=$(obj)/vmlinux.$(suffix_y) \ + --set-section-flags=.image=contents,alloc,load,readonly,data +$(obj)/piggy.o: $(obj)/dummy.o $(obj)/vmlinux.$(suffix_y) FORCE + $(call if_changed,objcopy) LDFLAGS_vmlinuz := $(LDFLAGS) -Ttext $(VMLINUZ_LOAD_ADDRESS) -T -vmlinuz: $(src)/ld.script $(obj-y) $(obj)/piggy.o - $(call if_changed,ld) +vmlinuz: $(src)/ld.script $(vmlinuzobjs-y) $(obj)/piggy.o + $(call cmd,ld) $(Q)$(OBJCOPY) $(OBJCOPYFLAGS) $@ # # Some DECstations need all possible sections of an ECOFF executable # ifdef CONFIG_MACH_DECSTATION - E2EFLAGS = -a -else - E2EFLAGS = + e2eflag := -a endif # elf2ecoff can only handle 32bit image +hostprogs-y := ../elf2ecoff ifdef CONFIG_32BIT VMLINUZ = vmlinuz @@ -83,23 +88,22 @@ else VMLINUZ = vmlinuz.32 endif +quiet_cmd_32 = OBJCOPY $@ + cmd_32 = $(OBJCOPY) -O $(32bit-bfd) $(OBJCOPYFLAGS) $< $@ vmlinuz.32: vmlinuz - $(Q)$(OBJCOPY) -O $(32bit-bfd) $(OBJCOPYFLAGS) $< $@ + $(call cmd,32) +quiet_cmd_ecoff = ECOFF $@ + cmd_ecoff = $< $(VMLINUZ) $@ $(e2eflag) vmlinuz.ecoff: $(obj)/../elf2ecoff $(VMLINUZ) - $(Q)$(obj)/../elf2ecoff $(VMLINUZ) vmlinuz.ecoff $(E2EFLAGS) - -$(obj)/../elf2ecoff: $(src)/../elf2ecoff.c - $(Q)$(HOSTCC) -o $@ $^ + $(call cmd,ecoff) OBJCOPYFLAGS_vmlinuz.bin := $(OBJCOPYFLAGS) -O binary vmlinuz.bin: vmlinuz - $(call if_changed,objcopy) + $(call cmd,objcopy) OBJCOPYFLAGS_vmlinuz.srec := $(OBJCOPYFLAGS) -S -O srec vmlinuz.srec: vmlinuz - $(call if_changed,objcopy) + $(call cmd,objcopy) -clean: -clean-files += *.o \ - vmlinu* +clean-files := $(objtree)/vmlinuz.* diff --git a/arch/mips/dec/promcon.c b/arch/mips/dec/promcon.c index 9f0972f5a702..c239c25b79ff 100644 --- a/arch/mips/dec/promcon.c +++ b/arch/mips/dec/promcon.c @@ -33,8 +33,7 @@ static int __init prom_console_setup(struct console *co, char *options) return 0; } -static struct console sercons = -{ +static struct console sercons = { .name = "ttyS", .write = prom_console_write, .setup = prom_console_setup, diff --git a/arch/mips/include/asm/mach-powertv/asic_reg_map.h b/arch/mips/include/asm/mach-powertv/asic_reg_map.h index 6f26cb09828e..20348e817b09 100644 --- a/arch/mips/include/asm/mach-powertv/asic_reg_map.h +++ b/arch/mips/include/asm/mach-powertv/asic_reg_map.h @@ -64,7 +64,7 @@ REGISTER_MAP_ELEMENT(int_level_0_1) REGISTER_MAP_ELEMENT(int_level_0_0) REGISTER_MAP_ELEMENT(int_docsis_en) REGISTER_MAP_ELEMENT(mips_pll_setup) -REGISTER_MAP_ELEMENT(usb_fs) +REGISTER_MAP_ELEMENT(fs432x4b4_usb_ctl) REGISTER_MAP_ELEMENT(test_bus) REGISTER_MAP_ELEMENT(crt_spare) REGISTER_MAP_ELEMENT(usb2_ohci_int_mask) diff --git a/arch/mips/include/asm/mach-powertv/dma-coherence.h b/arch/mips/include/asm/mach-powertv/dma-coherence.h index 5b8d5ebeb838..f76029c2406e 100644 --- a/arch/mips/include/asm/mach-powertv/dma-coherence.h +++ b/arch/mips/include/asm/mach-powertv/dma-coherence.h @@ -65,21 +65,21 @@ static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size) { if (is_kseg2(addr)) - return phys_to_bus(virt_to_phys_from_pte(addr)); + return phys_to_dma(virt_to_phys_from_pte(addr)); else - return phys_to_bus(virt_to_phys(addr)); + return phys_to_dma(virt_to_phys(addr)); } static inline dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page) { - return phys_to_bus(page_to_phys(page)); + return phys_to_dma(page_to_phys(page)); } static inline unsigned long plat_dma_addr_to_phys(struct device *dev, dma_addr_t dma_addr) { - return bus_to_phys(dma_addr); + return dma_to_phys(dma_addr); } static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr, diff --git a/arch/mips/include/asm/mach-powertv/ioremap.h b/arch/mips/include/asm/mach-powertv/ioremap.h index e6276d5146e8..076f2eeaa575 100644 --- a/arch/mips/include/asm/mach-powertv/ioremap.h +++ b/arch/mips/include/asm/mach-powertv/ioremap.h @@ -10,64 +10,101 @@ #define __ASM_MACH_POWERTV_IOREMAP_H #include <linux/types.h> +#include <linux/log2.h> +#include <linux/compiler.h> -#define LOW_MEM_BOUNDARY_PHYS 0x20000000 -#define LOW_MEM_BOUNDARY_MASK (~(LOW_MEM_BOUNDARY_PHYS - 1)) +#include <asm/pgtable-bits.h> +#include <asm/addrspace.h> + +/* We're going to mess with bits, so get sizes */ +#define IOR_BPC 8 /* Bits per char */ +#define IOR_PHYS_BITS (IOR_BPC * sizeof(phys_addr_t)) +#define IOR_DMA_BITS (IOR_BPC * sizeof(dma_addr_t)) /* - * The bus addresses are different than the physical addresses that - * the processor sees by an offset. This offset varies by ASIC - * version. Define a variable to hold the offset and some macros to - * make the conversion simpler. */ -extern unsigned long phys_to_bus_offset; - -#ifdef CONFIG_HIGHMEM -#define MEM_GAP_PHYS 0x60000000 + * Define the granularity of physical/DMA mapping in terms of the number + * of bits that defines the offset within a grain. These will be the + * least significant bits of the address. The rest of a physical or DMA + * address will be used to index into an appropriate table to find the + * offset to add to the address to yield the corresponding DMA or physical + * address, respectively. + */ +#define IOR_LSBITS 22 /* Bits in a grain */ + /* - * TODO: We will use the hard code for conversion between physical and - * bus until the bootloader releases their device tree to us. + * Compute the number of most significant address bits after removing those + * used for the offset within a grain and then compute the number of table + * entries for the conversion. */ -#define phys_to_bus(x) (((x) < LOW_MEM_BOUNDARY_PHYS) ? \ - ((x) + phys_to_bus_offset) : (x)) -#define bus_to_phys(x) (((x) < MEM_GAP_PHYS_ADDR) ? \ - ((x) - phys_to_bus_offset) : (x)) -#else -#define phys_to_bus(x) ((x) + phys_to_bus_offset) -#define bus_to_phys(x) ((x) - phys_to_bus_offset) -#endif +#define IOR_PHYS_MSBITS (IOR_PHYS_BITS - IOR_LSBITS) +#define IOR_NUM_PHYS_TO_DMA ((phys_addr_t) 1 << IOR_PHYS_MSBITS) + +#define IOR_DMA_MSBITS (IOR_DMA_BITS - IOR_LSBITS) +#define IOR_NUM_DMA_TO_PHYS ((dma_addr_t) 1 << IOR_DMA_MSBITS) /* - * Determine whether the address we are given is for an ASIC device - * Params: addr Address to check - * Returns: Zero if the address is not for ASIC devices, non-zero - * if it is. + * Define data structures used as elements in the arrays for the conversion + * between physical and DMA addresses. We do some slightly fancy math to + * compute the width of the offset element of the conversion tables so + * that we can have the smallest conversion tables. Next, round up the + * sizes to the next higher power of two, i.e. the offset element will have + * 8, 16, 32, 64, etc. bits. This eliminates the need to mask off any + * bits. Finally, we compute a shift value that puts the most significant + * bits of the offset into the most significant bits of the offset element. + * This makes it more efficient on processors without barrel shifters and + * easier to see the values if the conversion table is dumped in binary. */ -static inline int asic_is_device_addr(phys_t addr) +#define _IOR_OFFSET_WIDTH(n) (1 << order_base_2(n)) +#define IOR_OFFSET_WIDTH(n) \ + (_IOR_OFFSET_WIDTH(n) < 8 ? 8 : _IOR_OFFSET_WIDTH(n)) + +#define IOR_PHYS_OFFSET_BITS IOR_OFFSET_WIDTH(IOR_PHYS_MSBITS) +#define IOR_PHYS_SHIFT (IOR_PHYS_BITS - IOR_PHYS_OFFSET_BITS) + +#define IOR_DMA_OFFSET_BITS IOR_OFFSET_WIDTH(IOR_DMA_MSBITS) +#define IOR_DMA_SHIFT (IOR_DMA_BITS - IOR_DMA_OFFSET_BITS) + +struct ior_phys_to_dma { + dma_addr_t offset:IOR_DMA_OFFSET_BITS __packed + __aligned((IOR_DMA_OFFSET_BITS / IOR_BPC)); +}; + +struct ior_dma_to_phys { + dma_addr_t offset:IOR_PHYS_OFFSET_BITS __packed + __aligned((IOR_PHYS_OFFSET_BITS / IOR_BPC)); +}; + +extern struct ior_phys_to_dma _ior_phys_to_dma[IOR_NUM_PHYS_TO_DMA]; +extern struct ior_dma_to_phys _ior_dma_to_phys[IOR_NUM_DMA_TO_PHYS]; + +static inline dma_addr_t _phys_to_dma_offset_raw(phys_addr_t phys) { - return !((phys_t)addr & (phys_t) LOW_MEM_BOUNDARY_MASK); + return (dma_addr_t)_ior_phys_to_dma[phys >> IOR_LSBITS].offset; } -/* - * Determine whether the address we are given is external RAM mappable - * into KSEG1. - * Params: addr Address to check - * Returns: Zero if the address is not for external RAM and - */ -static inline int asic_is_lowmem_ram_addr(phys_t addr) +static inline dma_addr_t _dma_to_phys_offset_raw(dma_addr_t dma) { - /* - * The RAM always starts at the following address in the processor's - * physical address space - */ - static const phys_t phys_ram_base = 0x10000000; - phys_t bus_ram_base; + return (dma_addr_t)_ior_dma_to_phys[dma >> IOR_LSBITS].offset; +} - bus_ram_base = phys_to_bus_offset + phys_ram_base; +/* These are not portable and should not be used in drivers. Drivers should + * be using ioremap() and friends to map physical addreses to virtual + * addresses and dma_map*() and friends to map virtual addresses into DMA + * addresses and back. + */ +static inline dma_addr_t phys_to_dma(phys_addr_t phys) +{ + return phys + (_phys_to_dma_offset_raw(phys) << IOR_PHYS_SHIFT); +} - return addr >= bus_ram_base && - addr < (bus_ram_base + (LOW_MEM_BOUNDARY_PHYS - phys_ram_base)); +static inline phys_addr_t dma_to_phys(dma_addr_t dma) +{ + return dma + (_dma_to_phys_offset_raw(dma) << IOR_DMA_SHIFT); } +extern void ioremap_add_map(dma_addr_t phys, phys_addr_t alias, + dma_addr_t size); + /* * Allow physical addresses to be fixed up to help peripherals located * outside the low 32-bit range -- generic pass-through version. @@ -77,10 +114,50 @@ static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) return phys_addr; } -static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size, +/* + * Handle the special case of addresses the area aliased into the first + * 512 MiB of the processor's physical address space. These turn into either + * kseg0 or kseg1 addresses, depending on flags. + */ +static inline void __iomem *plat_ioremap(phys_t start, unsigned long size, unsigned long flags) { - return NULL; + phys_addr_t start_offset; + void __iomem *result = NULL; + + /* Start by checking to see whether this is an aliased address */ + start_offset = _dma_to_phys_offset_raw(start); + + /* + * If: + * o the memory is aliased into the first 512 MiB, and + * o the start and end are in the same RAM bank, and + * o we don't have a zero size or wrap around, and + * o we are supposed to create an uncached mapping, + * handle this is a kseg0 or kseg1 address + */ + if (start_offset != 0) { + phys_addr_t last; + dma_addr_t dma_to_phys_offset; + + last = start + size - 1; + dma_to_phys_offset = + _dma_to_phys_offset_raw(last) << IOR_DMA_SHIFT; + + if (dma_to_phys_offset == start_offset && + size != 0 && start <= last) { + phys_t adjusted_start; + adjusted_start = start + start_offset; + if (flags == _CACHE_UNCACHED) + result = (void __iomem *) (unsigned long) + CKSEG1ADDR(adjusted_start); + else + result = (void __iomem *) (unsigned long) + CKSEG0ADDR(adjusted_start); + } + } + + return result; } static inline int plat_iounmap(const volatile void __iomem *addr) diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 7a6ac501cbb5..ff5ec2e0184e 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -101,6 +101,4 @@ obj-$(CONFIG_HAVE_STD_PC_SERIAL_PORT) += 8250-platform.o obj-$(CONFIG_MIPS_CPUFREQ) += cpufreq/ -EXTRA_CFLAGS += -Werror - CPPFLAGS_vmlinux.lds := $(KBUILD_CFLAGS) diff --git a/arch/mips/math-emu/Makefile b/arch/mips/math-emu/Makefile index d547efdeedc2..96607230d9ea 100644 --- a/arch/mips/math-emu/Makefile +++ b/arch/mips/math-emu/Makefile @@ -10,4 +10,3 @@ obj-y := cp1emu.o ieee754m.o ieee754d.o ieee754dp.o ieee754sp.o ieee754.o \ sp_scalb.o sp_simple.o sp_tint.o sp_fint.o sp_tlong.o sp_flong.o \ dp_sqrt.o sp_sqrt.o kernel_linkage.o dsemul.o -EXTRA_CFLAGS += -Werror diff --git a/arch/mips/math-emu/dp_modf.c b/arch/mips/math-emu/dp_modf.c index 25861a42c36f..a8570e5c3efc 100644 --- a/arch/mips/math-emu/dp_modf.c +++ b/arch/mips/math-emu/dp_modf.c @@ -29,7 +29,7 @@ /* modf function is always exact for a finite number */ -ieee754dp ieee754dp_modf(ieee754dp x, ieee754dp * ip) +ieee754dp ieee754dp_modf(ieee754dp x, ieee754dp *ip) { COMPXDP; diff --git a/arch/mips/math-emu/dp_tint.c b/arch/mips/math-emu/dp_tint.c index 77b2b7ccf28a..24478623c117 100644 --- a/arch/mips/math-emu/dp_tint.c +++ b/arch/mips/math-emu/dp_tint.c @@ -69,8 +69,7 @@ int ieee754dp_tint(ieee754dp x) round = 0; sticky = residue != 0; xm = 0; - } - else { + } else { residue = xm << (64 - DP_MBITS + xe); round = (residue >> 63) != 0; sticky = (residue << 1) != 0; diff --git a/arch/mips/math-emu/dp_tlong.c b/arch/mips/math-emu/dp_tlong.c index d71113e07164..0f07ec2be3f9 100644 --- a/arch/mips/math-emu/dp_tlong.c +++ b/arch/mips/math-emu/dp_tlong.c @@ -71,8 +71,7 @@ s64 ieee754dp_tlong(ieee754dp x) round = 0; sticky = residue != 0; xm = 0; - } - else { + } else { /* Shifting a u64 64 times does not work, * so we do it in two steps. Be aware that xe * may be -1 */ diff --git a/arch/mips/math-emu/sp_modf.c b/arch/mips/math-emu/sp_modf.c index 4b1dbac796f8..76568946b4c0 100644 --- a/arch/mips/math-emu/sp_modf.c +++ b/arch/mips/math-emu/sp_modf.c @@ -29,7 +29,7 @@ /* modf function is always exact for a finite number */ -ieee754sp ieee754sp_modf(ieee754sp x, ieee754sp * ip) +ieee754sp ieee754sp_modf(ieee754sp x, ieee754sp *ip) { COMPXSP; diff --git a/arch/mips/math-emu/sp_tint.c b/arch/mips/math-emu/sp_tint.c index 1d73d2abe0b5..352dc3a5f1af 100644 --- a/arch/mips/math-emu/sp_tint.c +++ b/arch/mips/math-emu/sp_tint.c @@ -72,8 +72,7 @@ int ieee754sp_tint(ieee754sp x) round = 0; sticky = residue != 0; xm = 0; - } - else { + } else { /* Shifting a u32 32 times does not work, * so we do it in two steps. Be aware that xe * may be -1 */ diff --git a/arch/mips/math-emu/sp_tlong.c b/arch/mips/math-emu/sp_tlong.c index 4be21aa81fbf..92cd9c511a10 100644 --- a/arch/mips/math-emu/sp_tlong.c +++ b/arch/mips/math-emu/sp_tlong.c @@ -71,8 +71,7 @@ s64 ieee754sp_tlong(ieee754sp x) round = 0; sticky = residue != 0; xm = 0; - } - else { + } else { residue = xm << (32 - SP_MBITS + xe); round = (residue >> 31) != 0; sticky = (residue << 1) != 0; diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile index f0e435599707..d679c772d082 100644 --- a/arch/mips/mm/Makefile +++ b/arch/mips/mm/Makefile @@ -34,5 +34,3 @@ obj-$(CONFIG_IP22_CPU_SCACHE) += sc-ip22.o obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o obj-$(CONFIG_RM7000_CPU_SCACHE) += sc-rm7k.o obj-$(CONFIG_MIPS_CPU_SCACHE) += sc-mips.o - -EXTRA_CFLAGS += -Werror diff --git a/arch/mips/pci/ops-titan-ht.c b/arch/mips/pci/ops-titan-ht.c index 749c1922d420..57d54adc9e20 100644 --- a/arch/mips/pci/ops-titan-ht.c +++ b/arch/mips/pci/ops-titan-ht.c @@ -32,7 +32,7 @@ #include <asm/titan_dep.h> static int titan_ht_config_read_dword(struct pci_bus *bus, unsigned int devfn, - int offset, u32 * val) + int offset, u32 *val) { volatile uint32_t address; int busno; @@ -64,7 +64,7 @@ static int titan_ht_config_read_dword(struct pci_bus *bus, unsigned int devfn, } static int titan_ht_config_read(struct pci_bus *bus, unsigned int devfn, - int offset, int size, u32 * val) + int offset, int size, u32 *val) { uint32_t dword; diff --git a/arch/mips/pmc-sierra/yosemite/ht-irq.c b/arch/mips/pmc-sierra/yosemite/ht-irq.c index 5aec4057314e..86b98e98fb4f 100644 --- a/arch/mips/pmc-sierra/yosemite/ht-irq.c +++ b/arch/mips/pmc-sierra/yosemite/ht-irq.c @@ -35,18 +35,17 @@ */ void __init titan_ht_pcibios_fixup_bus(struct pci_bus *bus) { - struct pci_bus *current_bus = bus; - struct pci_dev *devices; - struct list_head *devices_link; + struct pci_bus *current_bus = bus; + struct pci_dev *devices; + struct list_head *devices_link; list_for_each(devices_link, &(current_bus->devices)) { - devices = pci_dev_b(devices_link); - if (devices == NULL) - continue; + devices = pci_dev_b(devices_link); + if (devices == NULL) + continue; } /* * PLX and SPKT related changes go here */ - } diff --git a/arch/mips/powertv/Makefile b/arch/mips/powertv/Makefile index 0a0d73c0564f..e9fe1c6efe16 100644 --- a/arch/mips/powertv/Makefile +++ b/arch/mips/powertv/Makefile @@ -23,6 +23,7 @@ # under Linux. # -obj-y += init.o memory.o reset.o time.o powertv_setup.o asic/ pci/ +obj-y += init.o ioremap.o memory.o powertv_setup.o reset.o time.o \ + asic/ pci/ EXTRA_CFLAGS += -Wall -Werror diff --git a/arch/mips/powertv/asic/asic-calliope.c b/arch/mips/powertv/asic/asic-calliope.c index 1ae6623444b2..0a170e0ffeaa 100644 --- a/arch/mips/powertv/asic/asic-calliope.c +++ b/arch/mips/powertv/asic/asic-calliope.c @@ -77,7 +77,7 @@ const struct register_map calliope_register_map __initdata = { .int_docsis_en = {.phys = CALLIOPE_ADDR(0xA028F4)}, .mips_pll_setup = {.phys = CALLIOPE_ADDR(0x980000)}, - .usb_fs = {.phys = CALLIOPE_ADDR(0x980030)}, + .fs432x4b4_usb_ctl = {.phys = CALLIOPE_ADDR(0x980030)}, .test_bus = {.phys = CALLIOPE_ADDR(0x9800CC)}, .crt_spare = {.phys = CALLIOPE_ADDR(0x9800d4)}, .usb2_ohci_int_mask = {.phys = CALLIOPE_ADDR(0x9A000c)}, diff --git a/arch/mips/powertv/asic/asic-cronus.c b/arch/mips/powertv/asic/asic-cronus.c index 5bb64bfb508b..bbc0c122be5e 100644 --- a/arch/mips/powertv/asic/asic-cronus.c +++ b/arch/mips/powertv/asic/asic-cronus.c @@ -77,13 +77,13 @@ const struct register_map cronus_register_map __initdata = { .int_docsis_en = {.phys = CRONUS_ADDR(0x2A28F4)}, .mips_pll_setup = {.phys = CRONUS_ADDR(0x1C0000)}, - .usb_fs = {.phys = CRONUS_ADDR(0x1C0018)}, + .fs432x4b4_usb_ctl = {.phys = CRONUS_ADDR(0x1C0028)}, .test_bus = {.phys = CRONUS_ADDR(0x1C00CC)}, .crt_spare = {.phys = CRONUS_ADDR(0x1c00d4)}, .usb2_ohci_int_mask = {.phys = CRONUS_ADDR(0x20000C)}, .usb2_strap = {.phys = CRONUS_ADDR(0x200014)}, .ehci_hcapbase = {.phys = CRONUS_ADDR(0x21FE00)}, - .ohci_hc_revision = {.phys = CRONUS_ADDR(0x1E0000)}, + .ohci_hc_revision = {.phys = CRONUS_ADDR(0x21fc00)}, .bcm1_bs_lmi_steer = {.phys = CRONUS_ADDR(0x2E0008)}, .usb2_control = {.phys = CRONUS_ADDR(0x2E004C)}, .usb2_stbus_obc = {.phys = CRONUS_ADDR(0x21FF00)}, diff --git a/arch/mips/powertv/asic/asic-zeus.c b/arch/mips/powertv/asic/asic-zeus.c index 095cbe10ebb9..4a05bb096476 100644 --- a/arch/mips/powertv/asic/asic-zeus.c +++ b/arch/mips/powertv/asic/asic-zeus.c @@ -77,7 +77,7 @@ const struct register_map zeus_register_map __initdata = { .int_docsis_en = {.phys = ZEUS_ADDR(0x2828F4)}, .mips_pll_setup = {.phys = ZEUS_ADDR(0x1a0000)}, - .usb_fs = {.phys = ZEUS_ADDR(0x1a0018)}, + .fs432x4b4_usb_ctl = {.phys = ZEUS_ADDR(0x1a0018)}, .test_bus = {.phys = ZEUS_ADDR(0x1a0238)}, .crt_spare = {.phys = ZEUS_ADDR(0x1a0090)}, .usb2_ohci_int_mask = {.phys = ZEUS_ADDR(0x1e000c)}, diff --git a/arch/mips/powertv/asic/asic_devices.c b/arch/mips/powertv/asic/asic_devices.c index 8ee77887306a..2276c18eb73b 100644 --- a/arch/mips/powertv/asic/asic_devices.c +++ b/arch/mips/powertv/asic/asic_devices.c @@ -80,8 +80,8 @@ static bool usb_configured; * Don't recommend to use it directly, it is usually used by kernel internally. * Portable code should be using interfaces such as ioremp, dma_map_single, etc. */ -unsigned long phys_to_bus_offset; -EXPORT_SYMBOL(phys_to_bus_offset); +unsigned long phys_to_dma_offset; +EXPORT_SYMBOL(phys_to_dma_offset); /* * @@ -180,9 +180,9 @@ static void __init fs_update(int pe, int md, int sdiv, int disable_div_by_3) val = ((sdiv << 29) | (md << 24) | (pe<<8) | (sout<<3) | (byp<<2) | (nsb<<1) | (disable_div_by_3<<5)); - asic_write(val, usb_fs); - asic_write(val | (en_prg<<4), usb_fs); - asic_write(val | (en_prg<<4) | pwr, usb_fs); + asic_write(val, fs432x4b4_usb_ctl); + asic_write(val | (en_prg<<4), fs432x4b4_usb_ctl); + asic_write(val | (en_prg<<4) | pwr, fs432x4b4_usb_ctl); } /* @@ -532,10 +532,10 @@ void __init configure_platform(void) switch (asic) { case ASIC_ZEUS: - phys_to_bus_offset = 0x30000000; + phys_to_dma_offset = 0x30000000; break; case ASIC_CALLIOPE: - phys_to_bus_offset = 0x10000000; + phys_to_dma_offset = 0x10000000; break; case ASIC_CRONUSLITE: /* Fall through */ @@ -545,10 +545,10 @@ void __init configure_platform(void) * 0x2XXXXXXX. If 0x10000000 aliases into 0x60000000- * 0x6XXXXXXX, the offset should be 0x50000000, not 0x10000000. */ - phys_to_bus_offset = 0x10000000; + phys_to_dma_offset = 0x10000000; break; default: - phys_to_bus_offset = 0x00000000; + phys_to_dma_offset = 0x00000000; break; } } @@ -602,7 +602,7 @@ void __init platform_alloc_bootmem(void) int size = gp_resources[i].end - gp_resources[i].start + 1; if ((gp_resources[i].start != 0) && ((gp_resources[i].flags & IORESOURCE_MEM) != 0)) { - reserve_bootmem(bus_to_phys(gp_resources[i].start), + reserve_bootmem(dma_to_phys(gp_resources[i].start), size, 0); total += gp_resources[i].end - gp_resources[i].start + 1; @@ -626,7 +626,7 @@ void __init platform_alloc_bootmem(void) else { gp_resources[i].start = - phys_to_bus(virt_to_phys(mem)); + phys_to_dma(virt_to_phys(mem)); gp_resources[i].end = gp_resources[i].start + size - 1; total += size; @@ -690,7 +690,7 @@ static void __init pmem_setup_resource(void) if (resource && pmemaddr && pmemlen) { /* The address provided by bootloader is in kseg0. Convert to * a bus address. */ - resource->start = phys_to_bus(pmemaddr - 0x80000000); + resource->start = phys_to_dma(pmemaddr - 0x80000000); resource->end = resource->start + pmemlen - 1; pr_info("persistent memory: start=0x%x end=0x%x\n", diff --git a/arch/mips/powertv/ioremap.c b/arch/mips/powertv/ioremap.c new file mode 100644 index 000000000000..a77c6f62fe23 --- /dev/null +++ b/arch/mips/powertv/ioremap.c @@ -0,0 +1,136 @@ +/* + * ioremap.c + * + * Support for mapping between dma_addr_t values a phys_addr_t values. + * + * Copyright (C) 2005-2009 Scientific-Atlanta, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Author: David VomLehn <dvomlehn@cisco.com> + * + * Description: Defines the platform resources for the SA settop. + * + * NOTE: The bootloader allocates persistent memory at an address which is + * 16 MiB below the end of the highest address in KSEG0. All fixed + * address memory reservations must avoid this region. + */ + +#include <linux/kernel.h> +#include <linux/module.h> + +#include <asm/mach-powertv/ioremap.h> + +/* + * Define the sizes of and masks for grains in physical and DMA space. The + * values are the same but the types are not. + */ +#define IOR_PHYS_GRAIN ((phys_addr_t) 1 << IOR_LSBITS) +#define IOR_PHYS_GRAIN_MASK (IOR_PHYS_GRAIN - 1) + +#define IOR_DMA_GRAIN ((dma_addr_t) 1 << IOR_LSBITS) +#define IOR_DMA_GRAIN_MASK (IOR_DMA_GRAIN - 1) + +/* + * Values that, when accessed by an index derived from a phys_addr_t and + * added to phys_addr_t value, yield a DMA address + */ +struct ior_phys_to_dma _ior_phys_to_dma[IOR_NUM_PHYS_TO_DMA]; +EXPORT_SYMBOL(_ior_phys_to_dma); + +/* + * Values that, when accessed by an index derived from a dma_addr_t and + * added to that dma_addr_t value, yield a physical address + */ +struct ior_dma_to_phys _ior_dma_to_phys[IOR_NUM_DMA_TO_PHYS]; +EXPORT_SYMBOL(_ior_dma_to_phys); + +/** + * setup_dma_to_phys - set up conversion from DMA to physical addresses + * @dma_idx: Top IOR_LSBITS bits of the DMA address, i.e. an index + * into the array _dma_to_phys. + * @delta: Value that, when added to the DMA address, will yield the + * physical address + * @s: Number of bytes in the section of memory with the given delta + * between DMA and physical addresses. + */ +static void setup_dma_to_phys(dma_addr_t dma, phys_addr_t delta, dma_addr_t s) +{ + int dma_idx, first_idx, last_idx; + phys_addr_t first, last; + + /* + * Calculate the first and last indices, rounding the first up and + * the second down. + */ + first = dma & ~IOR_DMA_GRAIN_MASK; + last = (dma + s - 1) & ~IOR_DMA_GRAIN_MASK; + first_idx = first >> IOR_LSBITS; /* Convert to indices */ + last_idx = last >> IOR_LSBITS; + + for (dma_idx = first_idx; dma_idx <= last_idx; dma_idx++) + _ior_dma_to_phys[dma_idx].offset = delta >> IOR_DMA_SHIFT; +} + +/** + * setup_phys_to_dma - set up conversion from DMA to physical addresses + * @phys_idx: Top IOR_LSBITS bits of the DMA address, i.e. an index + * into the array _phys_to_dma. + * @delta: Value that, when added to the DMA address, will yield the + * physical address + * @s: Number of bytes in the section of memory with the given delta + * between DMA and physical addresses. + */ +static void setup_phys_to_dma(phys_addr_t phys, dma_addr_t delta, phys_addr_t s) +{ + int phys_idx, first_idx, last_idx; + phys_addr_t first, last; + + /* + * Calculate the first and last indices, rounding the first up and + * the second down. + */ + first = phys & ~IOR_PHYS_GRAIN_MASK; + last = (phys + s - 1) & ~IOR_PHYS_GRAIN_MASK; + first_idx = first >> IOR_LSBITS; /* Convert to indices */ + last_idx = last >> IOR_LSBITS; + + for (phys_idx = first_idx; phys_idx <= last_idx; phys_idx++) + _ior_phys_to_dma[phys_idx].offset = delta >> IOR_PHYS_SHIFT; +} + +/** + * ioremap_add_map - add to the physical and DMA address conversion arrays + * @phys: Process's view of the address of the start of the memory chunk + * @dma: DMA address of the start of the memory chunk + * @size: Size, in bytes, of the chunk of memory + * + * NOTE: It might be obvious, but the assumption is that all @size bytes have + * the same offset between the physical address and the DMA address. + */ +void ioremap_add_map(phys_addr_t phys, phys_addr_t dma, phys_addr_t size) +{ + if (size == 0) + return; + + if ((dma & IOR_DMA_GRAIN_MASK) != 0 || + (phys & IOR_PHYS_GRAIN_MASK) != 0 || + (size & IOR_PHYS_GRAIN_MASK) != 0) + pr_crit("Memory allocation must be in chunks of 0x%x bytes\n", + IOR_PHYS_GRAIN); + + setup_dma_to_phys(dma, phys - dma, size); + setup_phys_to_dma(phys, dma - phys, size); +} diff --git a/arch/mips/powertv/memory.c b/arch/mips/powertv/memory.c index f49eb3d0358b..c463cd39c713 100644 --- a/arch/mips/powertv/memory.c +++ b/arch/mips/powertv/memory.c @@ -30,28 +30,140 @@ #include <asm/sections.h> #include <asm/mips-boards/prom.h> +#include <asm/mach-powertv/asic.h> +#include <asm/mach-powertv/ioremap.h> #include "init.h" /* Memory constants */ #define KIBIBYTE(n) ((n) * 1024) /* Number of kibibytes */ #define MEBIBYTE(n) ((n) * KIBIBYTE(1024)) /* Number of mebibytes */ -#define DEFAULT_MEMSIZE MEBIBYTE(256) /* If no memsize provided */ -#define LOW_MEM_MAX MEBIBYTE(252) /* Max usable low mem */ -#define RES_BOOTLDR_MEMSIZE MEBIBYTE(1) /* Memory reserved for bldr */ -#define BOOT_MEM_SIZE KIBIBYTE(256) /* Memory reserved for bldr */ -#define PHYS_MEM_START 0x10000000 /* Start of physical memory */ +#define DEFAULT_MEMSIZE MEBIBYTE(128) /* If no memsize provided */ -char __initdata cmdline[COMMAND_LINE_SIZE]; +#define BLDR_SIZE KIBIBYTE(256) /* Memory reserved for bldr */ +#define RV_SIZE MEBIBYTE(4) /* Size of reset vector */ -void __init prom_meminit(void) +#define LOW_MEM_END 0x20000000 /* Highest low memory address */ +#define BLDR_ALIAS 0x10000000 /* Bootloader address */ +#define RV_PHYS 0x1fc00000 /* Reset vector address */ +#define LOW_RAM_END RV_PHYS /* End of real RAM in low mem */ + +/* + * Very low-level conversion from processor physical address to device + * DMA address for the first bank of memory. + */ +#define PHYS_TO_DMA(paddr) ((paddr) + (CONFIG_LOW_RAM_DMA - LOW_RAM_ALIAS)) + +unsigned long ptv_memsize; + +/* + * struct low_mem_reserved - Items in low memmory that are reserved + * @start: Physical address of item + * @size: Size, in bytes, of this item + * @is_aliased: True if this is RAM aliased from another location. If false, + * it is something other than aliased RAM and the RAM in the + * unaliased address is still visible outside of low memory. + */ +struct low_mem_reserved { + phys_addr_t start; + phys_addr_t size; + bool is_aliased; +}; + +/* + * Must be in ascending address order + */ +struct low_mem_reserved low_mem_reserved[] = { + {BLDR_ALIAS, BLDR_SIZE, true}, /* Bootloader RAM */ + {RV_PHYS, RV_SIZE, false}, /* Reset vector */ +}; + +/* + * struct mem_layout - layout of a piece of the system RAM + * @phys: Physical address of the start of this piece of RAM. This is the + * address at which both the processor and I/O devices see the + * RAM. + * @alias: Alias of this piece of memory in order to make it appear in + * the low memory part of the processor's address space. I/O + * devices don't see anything here. + * @size: Size, in bytes, of this piece of RAM + */ +struct mem_layout { + phys_addr_t phys; + phys_addr_t alias; + phys_addr_t size; +}; + +/* + * struct mem_layout_list - list descriptor for layouts of system RAM pieces + * @family: Specifies the family being described + * @n: Number of &struct mem_layout elements + * @layout: Pointer to the list of &mem_layout structures + */ +struct mem_layout_list { + enum family_type family; + size_t n; + struct mem_layout *layout; +}; + +static struct mem_layout f1500_layout[] = { + {0x20000000, 0x10000000, MEBIBYTE(256)}, +}; + +static struct mem_layout f4500_layout[] = { + {0x40000000, 0x10000000, MEBIBYTE(256)}, + {0x20000000, 0x20000000, MEBIBYTE(32)}, +}; + +static struct mem_layout f8500_layout[] = { + {0x40000000, 0x10000000, MEBIBYTE(256)}, + {0x20000000, 0x20000000, MEBIBYTE(32)}, + {0x30000000, 0x30000000, MEBIBYTE(32)}, +}; + +static struct mem_layout fx600_layout[] = { + {0x20000000, 0x10000000, MEBIBYTE(256)}, + {0x60000000, 0x60000000, MEBIBYTE(128)}, +}; + +static struct mem_layout_list layout_list[] = { + {FAMILY_1500, ARRAY_SIZE(f1500_layout), f1500_layout}, + {FAMILY_1500VZE, ARRAY_SIZE(f1500_layout), f1500_layout}, + {FAMILY_1500VZF, ARRAY_SIZE(f1500_layout), f1500_layout}, + {FAMILY_4500, ARRAY_SIZE(f4500_layout), f4500_layout}, + {FAMILY_8500, ARRAY_SIZE(f8500_layout), f8500_layout}, + {FAMILY_8500RNG, ARRAY_SIZE(f8500_layout), f8500_layout}, + {FAMILY_4600, ARRAY_SIZE(fx600_layout), fx600_layout}, + {FAMILY_4600VZA, ARRAY_SIZE(fx600_layout), fx600_layout}, + {FAMILY_8600, ARRAY_SIZE(fx600_layout), fx600_layout}, + {FAMILY_8600VZB, ARRAY_SIZE(fx600_layout), fx600_layout}, +}; + +/* If we can't determine the layout, use this */ +static struct mem_layout default_layout[] = { + {0x20000000, 0x10000000, MEBIBYTE(128)}, +}; + +/** + * register_non_ram - register low memory not available for RAM usage + */ +static __init void register_non_ram(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(low_mem_reserved); i++) + add_memory_region(low_mem_reserved[i].start, + low_mem_reserved[i].size, BOOT_MEM_RESERVED); +} + +/** + * get_memsize - get the size of memory as a single bank + */ +static phys_addr_t get_memsize(void) { + phys_addr_t memsize = 0; char *memsize_str; - unsigned long memsize = 0; - unsigned int physend; - char *ptr; - int low_mem; - int high_mem; + char cmdline[COMMAND_LINE_SIZE], *ptr; /* Check the command line first for a memsize directive */ strcpy(cmdline, arcs_cmdline); @@ -73,96 +185,156 @@ void __init prom_meminit(void) if (memsize == 0) { if (_prom_memsize != 0) { memsize = _prom_memsize; - pr_info("_prom_memsize = 0x%lx\n", memsize); + pr_info("_prom_memsize = 0x%x\n", memsize); /* add in memory that the bootloader doesn't * report */ - memsize += BOOT_MEM_SIZE; + memsize += BLDR_SIZE; } else { memsize = DEFAULT_MEMSIZE; pr_info("Memsize not passed by bootloader, " - "defaulting to 0x%lx\n", memsize); + "defaulting to 0x%x\n", memsize); } } } - physend = PFN_ALIGN(&_end) - 0x80000000; - if (memsize > LOW_MEM_MAX) { - low_mem = LOW_MEM_MAX; - high_mem = memsize - low_mem; - } else { - low_mem = memsize; - high_mem = 0; + return memsize; +} + +/** + * register_low_ram - register an aliased section of RAM + * @p: Alias address of memory + * @n: Number of bytes in this section of memory + * + * Returns the number of bytes registered + * + */ +static __init phys_addr_t register_low_ram(phys_addr_t p, phys_addr_t n) +{ + phys_addr_t s; + int i; + phys_addr_t orig_n; + + orig_n = n; + + BUG_ON(p + n > RV_PHYS); + + for (i = 0; n != 0 && i < ARRAY_SIZE(low_mem_reserved); i++) { + phys_addr_t start; + phys_addr_t size; + + start = low_mem_reserved[i].start; + size = low_mem_reserved[i].size; + + /* Handle memory before this low memory section */ + if (p < start) { + phys_addr_t s; + s = min(n, start - p); + add_memory_region(p, s, BOOT_MEM_RAM); + p += s; + n -= s; + } + + /* Handle the low memory section itself. If it's aliased, + * we reduce the number of byes left, but if not, the RAM + * is available elsewhere and we don't reduce the number of + * bytes remaining. */ + if (p == start) { + if (low_mem_reserved[i].is_aliased) { + s = min(n, size); + n -= s; + p += s; + } else + p += n; + } } + return orig_n - n; +} + /* - * TODO: We will use the hard code for memory configuration until - * the bootloader releases their device tree to us. + * register_ram - register real RAM + * @p: Address of memory as seen by devices + * @alias: If the memory is seen at an additional address by the processor, + * this will be the address, otherwise it is the same as @p. + * @n: Number of bytes in this section of memory */ +static __init void register_ram(phys_addr_t p, phys_addr_t alias, + phys_addr_t n) +{ /* - * Add the memory reserved for use by the bootloader to the - * memory map. - */ - add_memory_region(PHYS_MEM_START, RES_BOOTLDR_MEMSIZE, - BOOT_MEM_RESERVED); -#ifdef CONFIG_HIGHMEM_256_128 - /* - * Add memory in low for general use by the kernel and its friends - * (like drivers, applications, etc). - */ - add_memory_region(PHYS_MEM_START + RES_BOOTLDR_MEMSIZE, - LOW_MEM_MAX - RES_BOOTLDR_MEMSIZE, BOOT_MEM_RAM); - /* - * Add the memory reserved for reset vector. - */ - add_memory_region(0x1fc00000, MEBIBYTE(4), BOOT_MEM_RESERVED); - /* - * Add the memory reserved. - */ - add_memory_region(0x20000000, MEBIBYTE(1024 + 75), BOOT_MEM_RESERVED); - /* - * Add memory in high for general use by the kernel and its friends - * (like drivers, applications, etc). - * - * 75MB is reserved for devices which are using the memory in high. - */ - add_memory_region(0x60000000 + MEBIBYTE(75), MEBIBYTE(128 - 75), - BOOT_MEM_RAM); -#elif defined CONFIG_HIGHMEM_128_128 - /* - * Add memory in low for general use by the kernel and its friends - * (like drivers, applications, etc). - */ - add_memory_region(PHYS_MEM_START + RES_BOOTLDR_MEMSIZE, - MEBIBYTE(128) - RES_BOOTLDR_MEMSIZE, BOOT_MEM_RAM); - /* - * Add the memory reserved. - */ - add_memory_region(PHYS_MEM_START + MEBIBYTE(128), - MEBIBYTE(128 + 1024 + 75), BOOT_MEM_RESERVED); - /* - * Add memory in high for general use by the kernel and its friends - * (like drivers, applications, etc). - * - * 75MB is reserved for devices which are using the memory in high. - */ - add_memory_region(0x60000000 + MEBIBYTE(75), MEBIBYTE(128 - 75), - BOOT_MEM_RAM); -#else - /* Add low memory regions for either: - * - no-highmemory configuration case -OR- - * - highmemory "HIGHMEM_LOWBANK_ONLY" case - */ - /* - * Add memory for general use by the kernel and its friends - * (like drivers, applications, etc). + * If some or all of this memory has an alias, break it into the + * aliased and non-aliased portion. */ - add_memory_region(PHYS_MEM_START + RES_BOOTLDR_MEMSIZE, - low_mem - RES_BOOTLDR_MEMSIZE, BOOT_MEM_RAM); + if (p != alias) { + phys_addr_t alias_size; + phys_addr_t registered; + + alias_size = min(n, LOW_RAM_END - alias); + registered = register_low_ram(alias, alias_size); + ioremap_add_map(alias, p, n); + n -= registered; + p += registered; + } + +#ifdef CONFIG_HIGHMEM + if (n != 0) { + add_memory_region(p, n, BOOT_MEM_RAM); + ioremap_add_map(p, p, n); + } +#endif +} + +/** + * register_address_space - register things in the address space + * @memsize: Number of bytes of RAM installed + * + * Takes the given number of bytes of RAM and registers as many of the regions, + * or partial regions, as it can. So, the default configuration might have + * two regions with 256 MiB each. If the memsize passed in on the command line + * is 384 MiB, it will register the first region with 256 MiB and the second + * with 128 MiB. + */ +static __init void register_address_space(phys_addr_t memsize) +{ + int i; + phys_addr_t size; + size_t n; + struct mem_layout *layout; + enum family_type family; + /* - * Add the memory reserved for reset vector. + * Register all of the things that aren't available to the kernel as + * memory. */ - add_memory_region(0x1fc00000, MEBIBYTE(4), BOOT_MEM_RESERVED); -#endif + register_non_ram(); + + /* Find the appropriate memory description */ + family = platform_get_family(); + + for (i = 0; i < ARRAY_SIZE(layout_list); i++) { + if (layout_list[i].family == family) + break; + } + + if (i == ARRAY_SIZE(layout_list)) { + n = ARRAY_SIZE(default_layout); + layout = default_layout; + } else { + n = layout_list[i].n; + layout = layout_list[i].layout; + } + + for (i = 0; memsize != 0 && i < n; i++) { + size = min(memsize, layout[i].size); + register_ram(layout[i].phys, layout[i].alias, size); + memsize -= size; + } +} + +void __init prom_meminit(void) +{ + ptv_memsize = get_memsize(); + register_address_space(ptv_memsize); } void __init prom_free_prom_memory(void) diff --git a/arch/mips/sgi-ip27/ip27-klconfig.c b/arch/mips/sgi-ip27/ip27-klconfig.c index dd830b3670d1..7afe14688003 100644 --- a/arch/mips/sgi-ip27/ip27-klconfig.c +++ b/arch/mips/sgi-ip27/ip27-klconfig.c @@ -48,7 +48,7 @@ klinfo_t *find_first_component(lboard_t *brd, unsigned char struct_type) return find_component(brd, (klinfo_t *)NULL, struct_type); } -lboard_t * find_lboard(lboard_t *start, unsigned char brd_type) +lboard_t *find_lboard(lboard_t *start, unsigned char brd_type) { /* Search all boards stored on this node. */ while (start) { @@ -60,7 +60,7 @@ lboard_t * find_lboard(lboard_t *start, unsigned char brd_type) return (lboard_t *)NULL; } -lboard_t * find_lboard_class(lboard_t *start, unsigned char brd_type) +lboard_t *find_lboard_class(lboard_t *start, unsigned char brd_type) { /* Search all boards stored on this node. */ while (start) { @@ -78,7 +78,7 @@ cnodeid_t get_cpu_cnode(cpuid_t cpu) return CPUID_TO_COMPACT_NODEID(cpu); } -klcpu_t * nasid_slice_to_cpuinfo(nasid_t nasid, int slice) +klcpu_t *nasid_slice_to_cpuinfo(nasid_t nasid, int slice) { lboard_t *brd; klcpu_t *acpu; @@ -97,7 +97,7 @@ klcpu_t * nasid_slice_to_cpuinfo(nasid_t nasid, int slice) return (klcpu_t *)NULL; } -klcpu_t * sn_get_cpuinfo(cpuid_t cpu) +klcpu_t *sn_get_cpuinfo(cpuid_t cpu) { nasid_t nasid; int slice; diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 66a315e06dce..328774bd41ee 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -351,7 +351,7 @@ config ARCH_ENABLE_MEMORY_HOTREMOVE config KEXEC bool "kexec system call (EXPERIMENTAL)" - depends on PPC_BOOK3S && EXPERIMENTAL + depends on (PPC_BOOK3S || (FSL_BOOKE && !SMP)) && EXPERIMENTAL help kexec is a system call that implements the ability to shutdown your current kernel, and to start another kernel. It is like a reboot diff --git a/arch/powerpc/boot/4xx.c b/arch/powerpc/boot/4xx.c index 27db8938827a..9d3bd4c45a24 100644 --- a/arch/powerpc/boot/4xx.c +++ b/arch/powerpc/boot/4xx.c @@ -519,7 +519,7 @@ void ibm440ep_fixup_clocks(unsigned int sys_clk, { unsigned int plb_clk = __ibm440eplike_fixup_clocks(sys_clk, tmr_clk, 0); - /* serial clocks beed fixup based on int/ext */ + /* serial clocks need fixup based on int/ext */ eplike_fixup_uart_clk(0, "/plb/opb/serial@ef600300", ser_clk, plb_clk); eplike_fixup_uart_clk(1, "/plb/opb/serial@ef600400", ser_clk, plb_clk); eplike_fixup_uart_clk(2, "/plb/opb/serial@ef600500", ser_clk, plb_clk); @@ -532,7 +532,7 @@ void ibm440gx_fixup_clocks(unsigned int sys_clk, { unsigned int plb_clk = __ibm440eplike_fixup_clocks(sys_clk, tmr_clk, 1); - /* serial clocks beed fixup based on int/ext */ + /* serial clocks need fixup based on int/ext */ eplike_fixup_uart_clk(0, "/plb/opb/serial@40000200", ser_clk, plb_clk); eplike_fixup_uart_clk(1, "/plb/opb/serial@40000300", ser_clk, plb_clk); } @@ -543,10 +543,10 @@ void ibm440spe_fixup_clocks(unsigned int sys_clk, { unsigned int plb_clk = __ibm440eplike_fixup_clocks(sys_clk, tmr_clk, 1); - /* serial clocks beed fixup based on int/ext */ - eplike_fixup_uart_clk(0, "/plb/opb/serial@10000200", ser_clk, plb_clk); - eplike_fixup_uart_clk(1, "/plb/opb/serial@10000300", ser_clk, plb_clk); - eplike_fixup_uart_clk(2, "/plb/opb/serial@10000600", ser_clk, plb_clk); + /* serial clocks need fixup based on int/ext */ + eplike_fixup_uart_clk(0, "/plb/opb/serial@f0000200", ser_clk, plb_clk); + eplike_fixup_uart_clk(1, "/plb/opb/serial@f0000300", ser_clk, plb_clk); + eplike_fixup_uart_clk(2, "/plb/opb/serial@f0000600", ser_clk, plb_clk); } void ibm405gp_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk) diff --git a/arch/powerpc/boot/dts/icon.dts b/arch/powerpc/boot/dts/icon.dts new file mode 100644 index 000000000000..abcd0caeccae --- /dev/null +++ b/arch/powerpc/boot/dts/icon.dts @@ -0,0 +1,447 @@ +/* + * Device Tree Source for Mosaix Technologies, Inc. ICON board + * + * Copyright 2010 DENX Software Engineering, Stefan Roese <sr@denx.de> + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without + * any warranty of any kind, whether express or implied. + */ + +/dts-v1/; + +/ { + #address-cells = <2>; + #size-cells = <2>; + model = "mosaixtech,icon"; + compatible = "mosaixtech,icon"; + dcr-parent = <&{/cpus/cpu@0}>; + + aliases { + ethernet0 = &EMAC0; + serial0 = &UART0; + serial1 = &UART1; + serial2 = &UART2; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + model = "PowerPC,440SPe"; + reg = <0x00000000>; + clock-frequency = <0>; /* Filled in by U-Boot */ + timebase-frequency = <0>; /* Filled in by U-Boot */ + i-cache-line-size = <32>; + d-cache-line-size = <32>; + i-cache-size = <32768>; + d-cache-size = <32768>; + dcr-controller; + dcr-access-method = "native"; + reset-type = <2>; /* Use chip-reset */ + }; + }; + + memory { + device_type = "memory"; + reg = <0x0 0x00000000 0x0 0x00000000>; /* Filled in by U-Boot */ + }; + + UIC0: interrupt-controller0 { + compatible = "ibm,uic-440spe","ibm,uic"; + interrupt-controller; + cell-index = <0>; + dcr-reg = <0x0c0 0x009>; + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + }; + + UIC1: interrupt-controller1 { + compatible = "ibm,uic-440spe","ibm,uic"; + interrupt-controller; + cell-index = <1>; + dcr-reg = <0x0d0 0x009>; + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + interrupts = <0x1e 0x4 0x1f 0x4>; /* cascade */ + interrupt-parent = <&UIC0>; + }; + + UIC2: interrupt-controller2 { + compatible = "ibm,uic-440spe","ibm,uic"; + interrupt-controller; + cell-index = <2>; + dcr-reg = <0x0e0 0x009>; + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + interrupts = <0xa 0x4 0xb 0x4>; /* cascade */ + interrupt-parent = <&UIC0>; + }; + + UIC3: interrupt-controller3 { + compatible = "ibm,uic-440spe","ibm,uic"; + interrupt-controller; + cell-index = <3>; + dcr-reg = <0x0f0 0x009>; + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + interrupts = <0x10 0x4 0x11 0x4>; /* cascade */ + interrupt-parent = <&UIC0>; + }; + + SDR0: sdr { + compatible = "ibm,sdr-440spe"; + dcr-reg = <0x00e 0x002>; + }; + + CPR0: cpr { + compatible = "ibm,cpr-440spe"; + dcr-reg = <0x00c 0x002>; + }; + + MQ0: mq { + compatible = "ibm,mq-440spe"; + dcr-reg = <0x040 0x020>; + }; + + plb { + compatible = "ibm,plb-440spe", "ibm,plb-440gp", "ibm,plb4"; + #address-cells = <2>; + #size-cells = <1>; + /* addr-child addr-parent size */ + ranges = <0x4 0x00100000 0x4 0x00100000 0x00001000 + 0x4 0x00200000 0x4 0x00200000 0x00000400 + 0x4 0xe0000000 0x4 0xe0000000 0x20000000 + 0xc 0x00000000 0xc 0x00000000 0x20000000 + 0xd 0x00000000 0xd 0x00000000 0x80000000 + 0xd 0x80000000 0xd 0x80000000 0x80000000 + 0xe 0x00000000 0xe 0x00000000 0x80000000 + 0xe 0x80000000 0xe 0x80000000 0x80000000 + 0xf 0x00000000 0xf 0x00000000 0x80000000 + 0xf 0x80000000 0xf 0x80000000 0x80000000>; + clock-frequency = <0>; /* Filled in by U-Boot */ + + SDRAM0: sdram { + compatible = "ibm,sdram-440spe", "ibm,sdram-405gp"; + dcr-reg = <0x010 0x002>; + }; + + MAL0: mcmal { + compatible = "ibm,mcmal-440spe", "ibm,mcmal2"; + dcr-reg = <0x180 0x062>; + num-tx-chans = <2>; + num-rx-chans = <1>; + interrupt-parent = <&MAL0>; + interrupts = <0x0 0x1 0x2 0x3 0x4>; + #interrupt-cells = <1>; + #address-cells = <0>; + #size-cells = <0>; + interrupt-map = </*TXEOB*/ 0x0 &UIC1 0x6 0x4 + /*RXEOB*/ 0x1 &UIC1 0x7 0x4 + /*SERR*/ 0x2 &UIC1 0x1 0x4 + /*TXDE*/ 0x3 &UIC1 0x2 0x4 + /*RXDE*/ 0x4 &UIC1 0x3 0x4>; + }; + + POB0: opb { + compatible = "ibm,opb-440spe", "ibm,opb-440gp", "ibm,opb"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0xe0000000 0x00000004 0xe0000000 0x20000000>; + clock-frequency = <0>; /* Filled in by U-Boot */ + + EBC0: ebc { + compatible = "ibm,ebc-440spe", "ibm,ebc-440gp", "ibm,ebc"; + dcr-reg = <0x012 0x002>; + #address-cells = <2>; + #size-cells = <1>; + clock-frequency = <0>; /* Filled in by U-Boot */ + /* ranges property is supplied by U-Boot */ + interrupts = <0x5 0x1>; + interrupt-parent = <&UIC1>; + + nor_flash@0,0 { + compatible = "cfi-flash"; + bank-width = <2>; + reg = <0x00000000 0x00000000 0x01000000>; + #address-cells = <1>; + #size-cells = <1>; + partition@0 { + label = "kernel"; + reg = <0x00000000 0x001e0000>; + }; + partition@1e0000 { + label = "dtb"; + reg = <0x001e0000 0x00020000>; + }; + partition@200000 { + label = "root"; + reg = <0x00200000 0x00200000>; + }; + partition@400000 { + label = "user"; + reg = <0x00400000 0x00b60000>; + }; + partition@f60000 { + label = "env"; + reg = <0x00f60000 0x00040000>; + }; + partition@fa0000 { + label = "u-boot"; + reg = <0x00fa0000 0x00060000>; + }; + }; + + SysACE_CompactFlash: sysace@1,0 { + compatible = "xlnx,sysace"; + interrupt-parent = <&UIC2>; + interrupts = <24 0x4>; + reg = <0x00000001 0x00000000 0x10000>; + }; + }; + + UART0: serial@f0000200 { + device_type = "serial"; + compatible = "ns16550"; + reg = <0xf0000200 0x00000008>; + virtual-reg = <0xa0000200>; + clock-frequency = <0>; /* Filled in by U-Boot */ + current-speed = <115200>; + interrupt-parent = <&UIC0>; + interrupts = <0x0 0x4>; + }; + + UART1: serial@f0000300 { + device_type = "serial"; + compatible = "ns16550"; + reg = <0xf0000300 0x00000008>; + virtual-reg = <0xa0000300>; + clock-frequency = <0>; + current-speed = <0>; + interrupt-parent = <&UIC0>; + interrupts = <0x1 0x4>; + }; + + + UART2: serial@f0000600 { + device_type = "serial"; + compatible = "ns16550"; + reg = <0xf0000600 0x00000008>; + virtual-reg = <0xa0000600>; + clock-frequency = <0>; + current-speed = <0>; + interrupt-parent = <&UIC1>; + interrupts = <0x5 0x4>; + }; + + IIC0: i2c@f0000400 { + compatible = "ibm,iic-440spe", "ibm,iic-440gp", "ibm,iic"; + reg = <0xf0000400 0x00000014>; + interrupt-parent = <&UIC0>; + interrupts = <0x2 0x4>; + }; + + IIC1: i2c@f0000500 { + compatible = "ibm,iic-440spe", "ibm,iic-440gp", "ibm,iic"; + reg = <0xf0000500 0x00000014>; + interrupt-parent = <&UIC0>; + interrupts = <0x3 0x4>; + #address-cells = <1>; + #size-cells = <0>; + + rtc@68 { + compatible = "stm,m41t00"; + reg = <0x68>; + }; + }; + + EMAC0: ethernet@f0000800 { + linux,network-index = <0x0>; + device_type = "network"; + compatible = "ibm,emac-440spe", "ibm,emac4"; + interrupt-parent = <&UIC1>; + interrupts = <0x1c 0x4 0x1d 0x4>; + reg = <0xf0000800 0x00000074>; + local-mac-address = [000000000000]; + mal-device = <&MAL0>; + mal-tx-channel = <0>; + mal-rx-channel = <0>; + cell-index = <0>; + max-frame-size = <9000>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; + phy-mode = "gmii"; + phy-map = <0x00000000>; + has-inverted-stacr-oc; + has-new-stacr-staopc; + }; + }; + + PCIX0: pci@c0ec00000 { + device_type = "pci"; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + compatible = "ibm,plb-pcix-440spe", "ibm,plb-pcix"; + primary; + large-inbound-windows; + enable-msi-hole; + reg = <0x0000000c 0x0ec00000 0x00000008 /* Config space access */ + 0x00000000 0x00000000 0x00000000 /* no IACK cycles */ + 0x0000000c 0x0ed00000 0x00000004 /* Special cycles */ + 0x0000000c 0x0ec80000 0x00000100 /* Internal registers */ + 0x0000000c 0x0ec80100 0x000000fc>; /* Internal messaging registers */ + + /* Outbound ranges, one memory and one IO, + * later cannot be changed + */ + ranges = <0x02000000 0x00000000 0x80000000 0x0000000d 0x80000000 0x00000000 0x80000000 + 0x01000000 0x00000000 0x00000000 0x0000000c 0x08000000 0x00000000 0x00010000>; + + /* Inbound 4GB range starting at 0 */ + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x1 0x00000000>; + + /* This drives busses 0 to 0xf */ + bus-range = <0x0 0xf>; + + /* PCI-X interrupt (SM502) is routed to extIRQ10 (UIC1, 19) */ + interrupt-map-mask = <0x0 0x0 0x0 0x0>; + interrupt-map = <0x0 0x0 0x0 0x0 &UIC1 19 0x8>; + }; + + PCIE0: pciex@d00000000 { + device_type = "pci"; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + compatible = "ibm,plb-pciex-440spe", "ibm,plb-pciex"; + primary; + port = <0x0>; /* port number */ + reg = <0x0000000d 0x00000000 0x20000000 /* Config space access */ + 0x0000000c 0x10000000 0x00001000>; /* Registers */ + dcr-reg = <0x100 0x020>; + sdr-base = <0x300>; + + /* Outbound ranges, one memory and one IO, + * later cannot be changed + */ + ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x00000000 0x00000000 0x80000000 + 0x01000000 0x00000000 0x00000000 0x0000000f 0x80000000 0x00000000 0x00010000>; + + /* Inbound 4GB range starting at 0 */ + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x1 0x00000000>; + + /* This drives busses 0x10 to 0x1f */ + bus-range = <0x10 0x1f>; + + /* Legacy interrupts (note the weird polarity, the bridge seems + * to invert PCIe legacy interrupts). + * We are de-swizzling here because the numbers are actually for + * port of the root complex virtual P2P bridge. But I want + * to avoid putting a node for it in the tree, so the numbers + * below are basically de-swizzled numbers. + * The real slot is on idsel 0, so the swizzling is 1:1 + */ + interrupt-map-mask = <0x0 0x0 0x0 0x7>; + interrupt-map = < + 0x0 0x0 0x0 0x1 &UIC3 0x0 0x4 /* swizzled int A */ + 0x0 0x0 0x0 0x2 &UIC3 0x1 0x4 /* swizzled int B */ + 0x0 0x0 0x0 0x3 &UIC3 0x2 0x4 /* swizzled int C */ + 0x0 0x0 0x0 0x4 &UIC3 0x3 0x4 /* swizzled int D */>; + }; + + PCIE1: pciex@d20000000 { + device_type = "pci"; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + compatible = "ibm,plb-pciex-440spe", "ibm,plb-pciex"; + primary; + port = <0x1>; /* port number */ + reg = <0x0000000d 0x20000000 0x20000000 /* Config space access */ + 0x0000000c 0x10001000 0x00001000>; /* Registers */ + dcr-reg = <0x120 0x020>; + sdr-base = <0x340>; + + /* Outbound ranges, one memory and one IO, + * later cannot be changed + */ + ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x80000000 0x00000000 0x80000000 + 0x01000000 0x00000000 0x00000000 0x0000000f 0x80010000 0x00000000 0x00010000>; + + /* Inbound 4GB range starting at 0 */ + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x1 0x00000000>; + + /* This drives busses 0x20 to 0x2f */ + bus-range = <0x20 0x2f>; + + /* Legacy interrupts (note the weird polarity, the bridge seems + * to invert PCIe legacy interrupts). + * We are de-swizzling here because the numbers are actually for + * port of the root complex virtual P2P bridge. But I want + * to avoid putting a node for it in the tree, so the numbers + * below are basically de-swizzled numbers. + * The real slot is on idsel 0, so the swizzling is 1:1 + */ + interrupt-map-mask = <0x0 0x0 0x0 0x7>; + interrupt-map = < + 0x0 0x0 0x0 0x1 &UIC3 0x4 0x4 /* swizzled int A */ + 0x0 0x0 0x0 0x2 &UIC3 0x5 0x4 /* swizzled int B */ + 0x0 0x0 0x0 0x3 &UIC3 0x6 0x4 /* swizzled int C */ + 0x0 0x0 0x0 0x4 &UIC3 0x7 0x4 /* swizzled int D */>; + }; + + I2O: i2o@400100000 { + compatible = "ibm,i2o-440spe"; + reg = <0x00000004 0x00100000 0x100>; + dcr-reg = <0x060 0x020>; + }; + + DMA0: dma0@400100100 { + compatible = "ibm,dma-440spe"; + cell-index = <0>; + reg = <0x00000004 0x00100100 0x100>; + dcr-reg = <0x060 0x020>; + interrupt-parent = <&DMA0>; + interrupts = <0 1>; + #interrupt-cells = <1>; + #address-cells = <0>; + #size-cells = <0>; + interrupt-map = < + 0 &UIC0 0x14 4 + 1 &UIC1 0x16 4>; + }; + + DMA1: dma1@400100200 { + compatible = "ibm,dma-440spe"; + cell-index = <1>; + reg = <0x00000004 0x00100200 0x100>; + dcr-reg = <0x060 0x020>; + interrupt-parent = <&DMA1>; + interrupts = <0 1>; + #interrupt-cells = <1>; + #address-cells = <0>; + #size-cells = <0>; + interrupt-map = < + 0 &UIC0 0x16 4 + 1 &UIC1 0x16 4>; + }; + + xor-accel@400200000 { + compatible = "amcc,xor-accelerator"; + reg = <0x00000004 0x00200000 0x400>; + interrupt-parent = <&UIC1>; + interrupts = <0x1f 4>; + }; + }; + + chosen { + linux,stdout-path = "/plb/opb/serial@f0000200"; + }; +}; diff --git a/arch/powerpc/boot/dts/katmai.dts b/arch/powerpc/boot/dts/katmai.dts index 8cf2c0c88c05..7c3be5e45748 100644 --- a/arch/powerpc/boot/dts/katmai.dts +++ b/arch/powerpc/boot/dts/katmai.dts @@ -44,6 +44,7 @@ d-cache-size = <32768>; dcr-controller; dcr-access-method = "native"; + reset-type = <2>; /* Use chip-reset */ }; }; diff --git a/arch/powerpc/boot/dts/mpc8548cds.dts b/arch/powerpc/boot/dts/mpc8548cds.dts index 4173af387c63..0f5262452682 100644 --- a/arch/powerpc/boot/dts/mpc8548cds.dts +++ b/arch/powerpc/boot/dts/mpc8548cds.dts @@ -20,10 +20,8 @@ aliases { ethernet0 = &enet0; ethernet1 = &enet1; -/* ethernet2 = &enet2; ethernet3 = &enet3; -*/ serial0 = &serial0; serial1 = &serial1; pci0 = &pci0; @@ -254,7 +252,6 @@ }; }; -/* eTSEC 3/4 are currently broken enet2: ethernet@26000 { #address-cells = <1>; #size-cells = <1>; @@ -310,7 +307,6 @@ }; }; }; - */ serial0: serial@4500 { cell-index = <0>; diff --git a/arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts b/arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts index 5bd1011fde96..3375c2ab0c32 100644 --- a/arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts +++ b/arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts @@ -215,6 +215,18 @@ clock-frequency = <0>; }; + msi@41600 { + compatible = "fsl,mpc8572-msi", "fsl,mpic-msi"; + reg = <0x41600 0x80>; + msi-available-ranges = <0 0x80>; + interrupts = < + 0xe0 0 + 0xe1 0 + 0xe2 0 + 0xe3 0>; + interrupt-parent = <&mpic>; + }; + global-utilities@e0000 { //global utilities block compatible = "fsl,mpc8572-guts"; reg = <0xe0000 0x1000>; @@ -243,8 +255,7 @@ protected-sources = < 31 32 33 37 38 39 /* enet2 enet3 */ 76 77 78 79 26 42 /* dma2 pci2 serial*/ - 0xe0 0xe1 0xe2 0xe3 /* msi */ - 0xe4 0xe5 0xe6 0xe7 + 0xe4 0xe5 0xe6 0xe7 /* msi */ >; }; }; diff --git a/arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts b/arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts index 0efc3456e297..e7b477f6a3fe 100644 --- a/arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts +++ b/arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts @@ -154,12 +154,8 @@ msi@41600 { compatible = "fsl,mpc8572-msi", "fsl,mpic-msi"; reg = <0x41600 0x80>; - msi-available-ranges = <0 0x100>; + msi-available-ranges = <0x80 0x80>; interrupts = < - 0xe0 0 - 0xe1 0 - 0xe2 0 - 0xe3 0 0xe4 0 0xe5 0 0xe6 0 @@ -190,6 +186,7 @@ 0x1 0x2 0x3 0x4 /* pci slot */ 0x9 0xa 0xb 0xc /* usb */ 0x6 0x7 0xe 0x5 /* Audio elgacy SATA */ + 0xe0 0xe1 0xe2 0xe3 /* msi */ >; }; }; diff --git a/arch/powerpc/boot/dts/p1021mds.dts b/arch/powerpc/boot/dts/p1021mds.dts new file mode 100644 index 000000000000..7fad2df25981 --- /dev/null +++ b/arch/powerpc/boot/dts/p1021mds.dts @@ -0,0 +1,698 @@ +/* + * P1021 MDS Device Tree Source + * + * Copyright 2010 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 as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +/dts-v1/; +/ { + model = "fsl,P1021"; + compatible = "fsl,P1021MDS"; + #address-cells = <2>; + #size-cells = <2>; + + aliases { + serial0 = &serial0; + serial1 = &serial1; + ethernet0 = &enet0; + ethernet1 = &enet1; + ethernet2 = &enet2; + ethernet3 = &enet3; + ethernet4 = &enet4; + pci0 = &pci0; + pci1 = &pci1; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + PowerPC,P1021@0 { + device_type = "cpu"; + reg = <0x0>; + next-level-cache = <&L2>; + }; + + PowerPC,P1021@1 { + device_type = "cpu"; + reg = <0x1>; + next-level-cache = <&L2>; + }; + }; + + memory { + device_type = "memory"; + }; + + localbus@ffe05000 { + #address-cells = <2>; + #size-cells = <1>; + compatible = "fsl,p1021-elbc", "fsl,elbc", "simple-bus"; + reg = <0 0xffe05000 0 0x1000>; + interrupts = <19 2>; + interrupt-parent = <&mpic>; + + /* NAND Flash, BCSR, PMC0/1*/ + ranges = <0x0 0x0 0x0 0xfc000000 0x02000000 + 0x1 0x0 0x0 0xf8000000 0x00008000 + 0x2 0x0 0x0 0xf8010000 0x00020000 + 0x3 0x0 0x0 0xf8020000 0x00020000>; + + nand@0,0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "fsl,p1021-fcm-nand", + "fsl,elbc-fcm-nand"; + reg = <0x0 0x0 0x40000>; + + partition@0 { + /* This location must not be altered */ + /* 1MB for u-boot Bootloader Image */ + reg = <0x0 0x00100000>; + label = "NAND (RO) U-Boot Image"; + read-only; + }; + + partition@100000 { + /* 1MB for DTB Image */ + reg = <0x00100000 0x00100000>; + label = "NAND (RO) DTB Image"; + read-only; + }; + + partition@200000 { + /* 4MB for Linux Kernel Image */ + reg = <0x00200000 0x00400000>; + label = "NAND (RO) Linux Kernel Image"; + read-only; + }; + + partition@600000 { + /* 5MB for Compressed Root file System Image */ + reg = <0x00600000 0x00500000>; + label = "NAND (RO) Compressed RFS Image"; + read-only; + }; + + partition@b00000 { + /* 6MB for JFFS2 based Root file System */ + reg = <0x00a00000 0x00600000>; + label = "NAND (RW) JFFS2 Root File System"; + }; + + partition@1100000 { + /* 14MB for JFFS2 based Root file System */ + reg = <0x01100000 0x00e00000>; + label = "NAND (RW) Writable User area"; + }; + + partition@1f00000 { + /* 1MB for microcode */ + reg = <0x01f00000 0x00100000>; + label = "NAND (RO) QE Ucode"; + read-only; + }; + }; + + bcsr@1,0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "fsl,p1021mds-bcsr"; + reg = <1 0 0x8000>; + ranges = <0 1 0 0x8000>; + }; + + pib@2,0 { + compatible = "fsl,p1021mds-pib"; + reg = <2 0 0x10000>; + }; + + pib@3,0 { + compatible = "fsl,p1021mds-pib"; + reg = <3 0 0x10000>; + }; + }; + + soc@ffe00000 { + + #address-cells = <1>; + #size-cells = <1>; + device_type = "soc"; + compatible = "fsl,p1021-immr", "simple-bus"; + ranges = <0x0 0x0 0xffe00000 0x100000>; + bus-frequency = <0>; // Filled out by uboot. + + ecm-law@0 { + compatible = "fsl,ecm-law"; + reg = <0x0 0x1000>; + fsl,num-laws = <12>; + }; + + ecm@1000 { + compatible = "fsl,p1021-ecm", "fsl,ecm"; + reg = <0x1000 0x1000>; + interrupts = <16 2>; + interrupt-parent = <&mpic>; + }; + + memory-controller@2000 { + compatible = "fsl,p1021-memory-controller"; + reg = <0x2000 0x1000>; + interrupt-parent = <&mpic>; + interrupts = <16 2>; + }; + + i2c@3000 { + #address-cells = <1>; + #size-cells = <0>; + cell-index = <0>; + compatible = "fsl-i2c"; + reg = <0x3000 0x100>; + interrupts = <43 2>; + interrupt-parent = <&mpic>; + dfsrr; + rtc@68 { + compatible = "dallas,ds1374"; + reg = <0x68>; + }; + }; + + i2c@3100 { + #address-cells = <1>; + #size-cells = <0>; + cell-index = <1>; + compatible = "fsl-i2c"; + reg = <0x3100 0x100>; + interrupts = <43 2>; + interrupt-parent = <&mpic>; + dfsrr; + }; + + serial0: serial@4500 { + cell-index = <0>; + device_type = "serial"; + compatible = "ns16550"; + reg = <0x4500 0x100>; + clock-frequency = <0>; + interrupts = <42 2>; + interrupt-parent = <&mpic>; + }; + + serial1: serial@4600 { + cell-index = <1>; + device_type = "serial"; + compatible = "ns16550"; + reg = <0x4600 0x100>; + clock-frequency = <0>; + interrupts = <42 2>; + interrupt-parent = <&mpic>; + }; + + spi@7000 { + cell-index = <0>; + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,espi"; + reg = <0x7000 0x1000>; + interrupts = <59 0x2>; + interrupt-parent = <&mpic>; + espi,num-ss-bits = <4>; + mode = "cpu"; + + fsl_m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "fsl,espi-flash"; + reg = <0>; + linux,modalias = "fsl_m25p80"; + spi-max-frequency = <40000000>; /* input clock */ + partition@u-boot { + label = "u-boot-spi"; + reg = <0x00000000 0x00100000>; + read-only; + }; + partition@kernel { + label = "kernel-spi"; + reg = <0x00100000 0x00500000>; + read-only; + }; + partition@dtb { + label = "dtb-spi"; + reg = <0x00600000 0x00100000>; + read-only; + }; + partition@fs { + label = "file system-spi"; + reg = <0x00700000 0x00900000>; + }; + }; + }; + + gpio: gpio-controller@f000 { + #gpio-cells = <2>; + compatible = "fsl,mpc8572-gpio"; + reg = <0xf000 0x100>; + interrupts = <47 0x2>; + interrupt-parent = <&mpic>; + gpio-controller; + }; + + L2: l2-cache-controller@20000 { + compatible = "fsl,p1021-l2-cache-controller"; + reg = <0x20000 0x1000>; + cache-line-size = <32>; // 32 bytes + cache-size = <0x40000>; // L2,256K + interrupt-parent = <&mpic>; + interrupts = <16 2>; + }; + + dma@21300 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "fsl,eloplus-dma"; + reg = <0x21300 0x4>; + ranges = <0x0 0x21100 0x200>; + cell-index = <0>; + dma-channel@0 { + compatible = "fsl,eloplus-dma-channel"; + reg = <0x0 0x80>; + cell-index = <0>; + interrupt-parent = <&mpic>; + interrupts = <20 2>; + }; + dma-channel@80 { + compatible = "fsl,eloplus-dma-channel"; + reg = <0x80 0x80>; + cell-index = <1>; + interrupt-parent = <&mpic>; + interrupts = <21 2>; + }; + dma-channel@100 { + compatible = "fsl,eloplus-dma-channel"; + reg = <0x100 0x80>; + cell-index = <2>; + interrupt-parent = <&mpic>; + interrupts = <22 2>; + }; + dma-channel@180 { + compatible = "fsl,eloplus-dma-channel"; + reg = <0x180 0x80>; + cell-index = <3>; + interrupt-parent = <&mpic>; + interrupts = <23 2>; + }; + }; + + usb@22000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl-usb2-dr"; + reg = <0x22000 0x1000>; + interrupt-parent = <&mpic>; + interrupts = <28 0x2>; + phy_type = "ulpi"; + }; + + mdio@24000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,etsec2-mdio"; + reg = <0x24000 0x1000 0xb0030 0x4>; + + phy0: ethernet-phy@0 { + interrupt-parent = <&mpic>; + interrupts = <1 1>; + reg = <0x0>; + }; + phy1: ethernet-phy@1 { + interrupt-parent = <&mpic>; + interrupts = <2 1>; + reg = <0x1>; + }; + phy4: ethernet-phy@4 { + interrupt-parent = <&mpic>; + reg = <0x4>; + }; + }; + + mdio@25000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,etsec2-tbi"; + reg = <0x25000 0x1000 0xb1030 0x4>; + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + enet0: ethernet@B0000 { + #address-cells = <1>; + #size-cells = <1>; + cell-index = <0>; + device_type = "network"; + model = "eTSEC"; + compatible = "fsl,etsec2"; + fsl,num_rx_queues = <0x8>; + fsl,num_tx_queues = <0x8>; + local-mac-address = [ 00 00 00 00 00 00 ]; + interrupt-parent = <&mpic>; + phy-handle = <&phy0>; + phy-connection-type = "rgmii-id"; + queue-group@0{ + #address-cells = <1>; + #size-cells = <1>; + reg = <0xB0000 0x1000>; + interrupts = <29 2 30 2 34 2>; + }; + queue-group@1{ + #address-cells = <1>; + #size-cells = <1>; + reg = <0xB4000 0x1000>; + interrupts = <17 2 18 2 24 2>; + }; + }; + + enet1: ethernet@B1000 { + #address-cells = <1>; + #size-cells = <1>; + cell-index = <0>; + device_type = "network"; + model = "eTSEC"; + compatible = "fsl,etsec2"; + fsl,num_rx_queues = <0x8>; + fsl,num_tx_queues = <0x8>; + local-mac-address = [ 00 00 00 00 00 00 ]; + interrupt-parent = <&mpic>; + phy-handle = <&phy4>; + tbi-handle = <&tbi0>; + phy-connection-type = "sgmii"; + queue-group@0{ + #address-cells = <1>; + #size-cells = <1>; + reg = <0xB1000 0x1000>; + interrupts = <35 2 36 2 40 2>; + }; + queue-group@1{ + #address-cells = <1>; + #size-cells = <1>; + reg = <0xB5000 0x1000>; + interrupts = <51 2 52 2 67 2>; + }; + }; + + enet2: ethernet@B2000 { + #address-cells = <1>; + #size-cells = <1>; + cell-index = <0>; + device_type = "network"; + model = "eTSEC"; + compatible = "fsl,etsec2"; + fsl,num_rx_queues = <0x8>; + fsl,num_tx_queues = <0x8>; + local-mac-address = [ 00 00 00 00 00 00 ]; + interrupt-parent = <&mpic>; + phy-handle = <&phy1>; + phy-connection-type = "rgmii-id"; + queue-group@0{ + #address-cells = <1>; + #size-cells = <1>; + reg = <0xB2000 0x1000>; + interrupts = <31 2 32 2 33 2>; + }; + queue-group@1{ + #address-cells = <1>; + #size-cells = <1>; + reg = <0xB6000 0x1000>; + interrupts = <25 2 26 2 27 2>; + }; + }; + + sdhci@2e000 { + compatible = "fsl,p1021-esdhc", "fsl,esdhc"; + reg = <0x2e000 0x1000>; + interrupts = <72 0x2>; + interrupt-parent = <&mpic>; + /* Filled in by U-Boot */ + clock-frequency = <0>; + }; + + crypto@30000 { + compatible = "fsl,sec3.3", "fsl,sec3.1", + "fsl,sec3.0", "fsl,sec2.4", + "fsl,sec2.2", "fsl,sec2.1", "fsl,sec2.0"; + reg = <0x30000 0x10000>; + interrupts = <45 2 58 2>; + interrupt-parent = <&mpic>; + fsl,num-channels = <4>; + fsl,channel-fifo-len = <24>; + fsl,exec-units-mask = <0x97c>; + fsl,descriptor-types-mask = <0x3a30abf>; + }; + + mpic: pic@40000 { + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <2>; + reg = <0x40000 0x40000>; + compatible = "chrp,open-pic"; + device_type = "open-pic"; + }; + + msi@41600 { + compatible = "fsl,p1021-msi", "fsl,mpic-msi"; + reg = <0x41600 0x80>; + msi-available-ranges = <0 0x100>; + interrupts = < + 0xe0 0 + 0xe1 0 + 0xe2 0 + 0xe3 0 + 0xe4 0 + 0xe5 0 + 0xe6 0 + 0xe7 0>; + interrupt-parent = <&mpic>; + }; + + global-utilities@e0000 { //global utilities block + compatible = "fsl,p1021-guts"; + reg = <0xe0000 0x1000>; + fsl,has-rstcr; + }; + + par_io@e0100 { + #address-cells = <1>; + #size-cells = <1>; + reg = <0xe0100 0x60>; + ranges = <0x0 0xe0100 0x60>; + device_type = "par_io"; + num-ports = <3>; + pio1: ucc_pin@01 { + pio-map = < + /* port pin dir open_drain assignment has_irq */ + 0x1 0x13 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */ + 0x1 0x14 0x3 0x0 0x1 0x0 /* QE_MUX_MDIO */ + 0x0 0x17 0x2 0x0 0x2 0x0 /* CLK12 */ + 0x0 0x18 0x2 0x0 0x1 0x0 /* CLK9 +*/ + 0x0 0x7 0x1 0x0 0x2 0x0 /* ENET1_TXD0_SER1_TXD0 */ + 0x0 0x9 0x1 0x0 0x2 0x0 /* ENET1_TXD1_SER1_TXD1 */ + 0x0 0xb 0x1 0x0 0x2 0x0 /* ENET1_TXD2_SER1_TXD2 */ + 0x0 0xc 0x1 0x0 0x2 0x0 /* ENET1_TXD3_SER1_TXD3 */ + 0x0 0x6 0x2 0x0 0x2 0x0 /* ENET1_RXD0_SER1_RXD0 */ + 0x0 0xa 0x2 0x0 0x2 0x0 /* ENET1_RXD1_SER1_RXD1 */ + 0x0 0xe 0x2 0x0 0x2 0x0 /* ENET1_RXD2_SER1_RXD2 */ + 0x0 0xf 0x2 0x0 0x2 0x0 /* ENET1_RXD3_SER1_RXD3 */ + 0x0 0x5 0x1 0x0 0x2 0x0 /* ENET1_TX_EN_SER1_RTS_B */ + 0x0 0xd 0x1 0x0 0x2 0x0 /* ENET1_TX_ER */ + 0x0 0x4 0x2 0x0 0x2 0x0 /* ENET1_RX_DV_SER1_CTS_B */ + 0x0 0x8 0x2 0x0 0x2 0x0 /* ENET1_RX_ER_SER1_CD_B */ + 0x0 0x11 0x2 0x0 0x2 0x0 /* ENET1_CRS */ + 0x0 0x10 0x2 0x0 0x2 0x0>; /* ENET1_COL */ + }; + + pio2: ucc_pin@02 { + pio-map = < + /* port pin dir open_drain assignment has_irq */ + 0x1 0x13 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */ + 0x1 0x14 0x3 0x0 0x1 0x0 /* QE_MUX_MDIO */ + 0x1 0xb 0x2 0x0 0x1 0x0 /* CLK13 */ + 0x1 0x7 0x1 0x0 0x2 0x0 /* ENET5_TXD0_SER5_TXD0 */ + 0x1 0xa 0x1 0x0 0x2 0x0 /* ENET5_TXD1_SER5_TXD1 */ + 0x1 0x6 0x2 0x0 0x2 0x0 /* ENET5_RXD0_SER5_RXD0 */ + 0x1 0x9 0x2 0x0 0x2 0x0 /* ENET5_RXD1_SER5_RXD1 */ + 0x1 0x5 0x1 0x0 0x2 0x0 /* ENET5_TX_EN_SER5_RTS_B */ + 0x1 0x4 0x2 0x0 0x2 0x0 /* ENET5_RX_DV_SER5_CTS_B */ + 0x1 0x8 0x2 0x0 0x2 0x0>; /* ENET5_RX_ER_SER5_CD_B */ + }; + }; + }; + + pci0: pcie@ffe09000 { + compatible = "fsl,mpc8548-pcie"; + device_type = "pci"; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + reg = <0 0xffe09000 0 0x1000>; + bus-range = <0 255>; + ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000 + 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>; + clock-frequency = <33333333>; + interrupt-parent = <&mpic>; + interrupts = <16 2>; + interrupt-map-mask = <0xf800 0 0 7>; + interrupt-map = < + /* IDSEL 0x0 */ + 0000 0 0 1 &mpic 4 1 + 0000 0 0 2 &mpic 5 1 + 0000 0 0 3 &mpic 6 1 + 0000 0 0 4 &mpic 7 1 + >; + pcie@0 { + reg = <0x0 0x0 0x0 0x0 0x0>; + #size-cells = <2>; + #address-cells = <3>; + device_type = "pci"; + ranges = <0x2000000 0x0 0xa0000000 + 0x2000000 0x0 0xa0000000 + 0x0 0x20000000 + + 0x1000000 0x0 0x0 + 0x1000000 0x0 0x0 + 0x0 0x100000>; + }; + }; + + pci1: pcie@ffe0a000 { + compatible = "fsl,mpc8548-pcie"; + device_type = "pci"; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + reg = <0 0xffe0a000 0 0x1000>; + bus-range = <0 255>; + ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000 + 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>; + clock-frequency = <33333333>; + interrupt-parent = <&mpic>; + interrupts = <16 2>; + interrupt-map-mask = <0xf800 0 0 7>; + interrupt-map = < + /* IDSEL 0x0 */ + 0000 0 0 1 &mpic 0 1 + 0000 0 0 2 &mpic 1 1 + 0000 0 0 3 &mpic 2 1 + 0000 0 0 4 &mpic 3 1 + >; + pcie@0 { + reg = <0x0 0x0 0x0 0x0 0x0>; + #size-cells = <2>; + #address-cells = <3>; + device_type = "pci"; + ranges = <0x2000000 0x0 0xc0000000 + 0x2000000 0x0 0xc0000000 + 0x0 0x20000000 + + 0x1000000 0x0 0x0 + 0x1000000 0x0 0x0 + 0x0 0x100000>; + }; + }; + + qe@ffe80000 { + #address-cells = <1>; + #size-cells = <1>; + device_type = "qe"; + compatible = "fsl,qe"; + ranges = <0x0 0x0 0xffe80000 0x40000>; + reg = <0 0xffe80000 0 0x480>; + brg-frequency = <0>; + bus-frequency = <0>; + fsl,qe-num-riscs = <1>; + fsl,qe-num-snums = <28>; + + qeic: interrupt-controller@80 { + interrupt-controller; + compatible = "fsl,qe-ic"; + #address-cells = <0>; + #interrupt-cells = <1>; + reg = <0x80 0x80>; + interrupts = <63 2 60 2>; //high:47 low:44 + interrupt-parent = <&mpic>; + }; + + enet3: ucc@2000 { + device_type = "network"; + compatible = "ucc_geth"; + cell-index = <1>; + reg = <0x2000 0x200>; + interrupts = <32>; + interrupt-parent = <&qeic>; + local-mac-address = [ 00 00 00 00 00 00 ]; + rx-clock-name = "clk12"; + tx-clock-name = "clk9"; + pio-handle = <&pio1>; + phy-handle = <&qe_phy0>; + phy-connection-type = "mii"; + }; + + mdio@2120 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x2120 0x18>; + compatible = "fsl,ucc-mdio"; + + qe_phy0: ethernet-phy@0 { + interrupt-parent = <&mpic>; + interrupts = <4 1>; + reg = <0x0>; + device_type = "ethernet-phy"; + }; + qe_phy1: ethernet-phy@03 { + interrupt-parent = <&mpic>; + interrupts = <5 1>; + reg = <0x3>; + device_type = "ethernet-phy"; + }; + tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + enet4: ucc@2400 { + device_type = "network"; + compatible = "ucc_geth"; + cell-index = <5>; + reg = <0x2400 0x200>; + interrupts = <40>; + interrupt-parent = <&qeic>; + local-mac-address = [ 00 00 00 00 00 00 ]; + rx-clock-name = "none"; + tx-clock-name = "clk13"; + pio-handle = <&pio2>; + phy-handle = <&qe_phy1>; + phy-connection-type = "rmii"; + }; + + muram@10000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "fsl,qe-muram", "fsl,cpm-muram"; + ranges = <0x0 0x10000 0x6000>; + + data-only@0 { + compatible = "fsl,qe-muram-data", + "fsl,cpm-muram-data"; + reg = <0x0 0x6000>; + }; + }; + }; +}; diff --git a/arch/powerpc/boot/dts/redwood.dts b/arch/powerpc/boot/dts/redwood.dts index d2af32e2bf7a..81636c01d906 100644 --- a/arch/powerpc/boot/dts/redwood.dts +++ b/arch/powerpc/boot/dts/redwood.dts @@ -234,10 +234,132 @@ has-inverted-stacr-oc; has-new-stacr-staopc; }; + }; + PCIE0: pciex@d00000000 { + device_type = "pci"; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + compatible = "ibm,plb-pciex-460sx", "ibm,plb-pciex"; + primary; + port = <0x0>; /* port number */ + reg = <0x0000000d 0x00000000 0x20000000 /* Config space access */ + 0x0000000c 0x10000000 0x00001000>; /* Registers */ + dcr-reg = <0x100 0x020>; + sdr-base = <0x300>; + + /* Outbound ranges, one memory and one IO, + * later cannot be changed + */ + ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x00000000 0x00000000 0x80000000 + 0x01000000 0x00000000 0x00000000 0x0000000f 0x80000000 0x00000000 0x00010000>; + + /* Inbound 2GB range starting at 0 */ + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>; + /* This drives busses 10 to 0x1f */ + bus-range = <0x10 0x1f>; + + /* Legacy interrupts (note the weird polarity, the bridge seems + * to invert PCIe legacy interrupts). + * We are de-swizzling here because the numbers are actually for + * port of the root complex virtual P2P bridge. But I want + * to avoid putting a node for it in the tree, so the numbers + * below are basically de-swizzled numbers. + * The real slot is on idsel 0, so the swizzling is 1:1 + */ + interrupt-map-mask = <0x0 0x0 0x0 0x7>; + interrupt-map = < + 0x0 0x0 0x0 0x1 &UIC3 0x0 0x4 /* swizzled int A */ + 0x0 0x0 0x0 0x2 &UIC3 0x1 0x4 /* swizzled int B */ + 0x0 0x0 0x0 0x3 &UIC3 0x2 0x4 /* swizzled int C */ + 0x0 0x0 0x0 0x4 &UIC3 0x3 0x4 /* swizzled int D */>; + }; + + PCIE1: pciex@d20000000 { + device_type = "pci"; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + compatible = "ibm,plb-pciex-460sx", "ibm,plb-pciex"; + primary; + port = <0x1>; /* port number */ + reg = <0x0000000d 0x20000000 0x20000000 /* Config space access */ + 0x0000000c 0x10001000 0x00001000>; /* Registers */ + dcr-reg = <0x120 0x020>; + sdr-base = <0x340>; + + /* Outbound ranges, one memory and one IO, + * later cannot be changed + */ + ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x80000000 0x00000000 0x80000000 + 0x01000000 0x00000000 0x00000000 0x0000000f 0x80010000 0x00000000 0x00010000>; + + /* Inbound 2GB range starting at 0 */ + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>; + + /* This drives busses 10 to 0x1f */ + bus-range = <0x20 0x2f>; + + /* Legacy interrupts (note the weird polarity, the bridge seems + * to invert PCIe legacy interrupts). + * We are de-swizzling here because the numbers are actually for + * port of the root complex virtual P2P bridge. But I want + * to avoid putting a node for it in the tree, so the numbers + * below are basically de-swizzled numbers. + * The real slot is on idsel 0, so the swizzling is 1:1 + */ + interrupt-map-mask = <0x0 0x0 0x0 0x7>; + interrupt-map = < + 0x0 0x0 0x0 0x1 &UIC3 0x4 0x4 /* swizzled int A */ + 0x0 0x0 0x0 0x2 &UIC3 0x5 0x4 /* swizzled int B */ + 0x0 0x0 0x0 0x3 &UIC3 0x6 0x4 /* swizzled int C */ + 0x0 0x0 0x0 0x4 &UIC3 0x7 0x4 /* swizzled int D */>; + }; + + PCIE2: pciex@d40000000 { + device_type = "pci"; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + compatible = "ibm,plb-pciex-460sx", "ibm,plb-pciex"; + primary; + port = <0x2>; /* port number */ + reg = <0x0000000d 0x40000000 0x20000000 /* Config space access */ + 0x0000000c 0x10002000 0x00001000>; /* Registers */ + dcr-reg = <0x140 0x020>; + sdr-base = <0x370>; + + /* Outbound ranges, one memory and one IO, + * later cannot be changed + */ + ranges = <0x02000000 0x00000000 0x80000000 0x0000000f 0x00000000 0x00000000 0x80000000 + 0x01000000 0x00000000 0x00000000 0x0000000f 0x80020000 0x00000000 0x00010000>; + + /* Inbound 2GB range starting at 0 */ + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>; + + /* This drives busses 10 to 0x1f */ + bus-range = <0x30 0x3f>; + + /* Legacy interrupts (note the weird polarity, the bridge seems + * to invert PCIe legacy interrupts). + * We are de-swizzling here because the numbers are actually for + * port of the root complex virtual P2P bridge. But I want + * to avoid putting a node for it in the tree, so the numbers + * below are basically de-swizzled numbers. + * The real slot is on idsel 0, so the swizzling is 1:1 + */ + interrupt-map-mask = <0x0 0x0 0x0 0x7>; + interrupt-map = < + 0x0 0x0 0x0 0x1 &UIC3 0x8 0x4 /* swizzled int A */ + 0x0 0x0 0x0 0x2 &UIC3 0x9 0x4 /* swizzled int B */ + 0x0 0x0 0x0 0x3 &UIC3 0xa 0x4 /* swizzled int C */ + 0x0 0x0 0x0 0x4 &UIC3 0xb 0x4 /* swizzled int D */>; }; }; + chosen { linux,stdout-path = "/plb/opb/serial@ef600200"; }; diff --git a/arch/powerpc/configs/44x/icon_defconfig b/arch/powerpc/configs/44x/icon_defconfig new file mode 100644 index 000000000000..277f88c2750f --- /dev/null +++ b/arch/powerpc/configs/44x/icon_defconfig @@ -0,0 +1,1451 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.34-rc7 +# Fri May 21 17:40:22 2010 +# +# CONFIG_PPC64 is not set + +# +# Processor support +# +# CONFIG_PPC_BOOK3S_32 is not set +# CONFIG_PPC_85xx is not set +# CONFIG_PPC_8xx is not set +# CONFIG_40x is not set +CONFIG_44x=y +# CONFIG_E200 is not set +CONFIG_4xx=y +CONFIG_BOOKE=y +CONFIG_PTE_64BIT=y +CONFIG_PHYS_64BIT=y +CONFIG_PPC_MMU_NOHASH=y +CONFIG_PPC_MMU_NOHASH_32=y +# CONFIG_PPC_MM_SLICES is not set +CONFIG_NOT_COHERENT_CACHE=y +CONFIG_PPC32=y +CONFIG_WORD_SIZE=32 +CONFIG_ARCH_PHYS_ADDR_T_64BIT=y +CONFIG_MMU=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set +# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set +CONFIG_IRQ_PER_CPU=y +CONFIG_NR_IRQS=512 +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_ARCH_HAS_ILOG2_U32=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +# CONFIG_ARCH_NO_VIRT_TO_BUS is not set +CONFIG_PPC=y +CONFIG_EARLY_PRINTK=y +CONFIG_GENERIC_NVRAM=y +CONFIG_SCHED_OMIT_FRAME_POINTER=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_PPC_OF=y +CONFIG_OF=y +CONFIG_PPC_UDBG_16550=y +# CONFIG_GENERIC_TBSYNC is not set +CONFIG_AUDIT_ARCH=y +CONFIG_GENERIC_BUG=y +CONFIG_DTC=y +# CONFIG_DEFAULT_UIMAGE is not set +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_PPC_DCR_NATIVE=y +# CONFIG_PPC_DCR_MMIO is not set +CONFIG_PPC_DCR=y +CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y +CONFIG_PPC_ADV_DEBUG_REGS=y +CONFIG_PPC_ADV_DEBUG_IACS=4 +CONFIG_PPC_ADV_DEBUG_DACS=2 +CONFIG_PPC_ADV_DEBUG_DVCS=2 +CONFIG_PPC_ADV_DEBUG_DAC_RANGE=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +# CONFIG_LOGBUFFER is not set +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_HAVE_PERF_EVENTS=y + +# +# Kernel Performance Events And Counters +# +# CONFIG_PERF_EVENTS is not set +# CONFIG_PERF_COUNTERS is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_PCI_QUIRKS=y +CONFIG_SLUB_DEBUG=y +CONFIG_COMPAT_BRK=y +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_HAVE_IOREMAP_PROT=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_HAVE_DMA_API_DEBUG=y + +# +# GCOV-based kernel profiling +# +# CONFIG_SLOW_WORK is not set +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +CONFIG_LBDAF=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set +# CONFIG_FREEZER is not set +CONFIG_PPC4xx_PCI_EXPRESS=y + +# +# Platform support +# +# CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +# CONFIG_PQ2ADS is not set +# CONFIG_BAMBOO is not set +# CONFIG_EBONY is not set +# CONFIG_SAM440EP is not set +# CONFIG_SEQUOIA is not set +# CONFIG_TAISHAN is not set +# CONFIG_KATMAI is not set +# CONFIG_RAINIER is not set +# CONFIG_WARP is not set +# CONFIG_ARCHES is not set +# CONFIG_CANYONLANDS is not set +# CONFIG_GLACIER is not set +# CONFIG_REDWOOD is not set +# CONFIG_EIGER is not set +# CONFIG_YOSEMITE is not set +CONFIG_ICON=y +# CONFIG_XILINX_VIRTEX440_GENERIC_BOARD is not set +CONFIG_PPC44x_SIMPLE=y +# CONFIG_PPC4xx_GPIO is not set +CONFIG_440SPe=y +CONFIG_STDBINUTILS=y +# CONFIG_IPIC is not set +# CONFIG_MPIC is not set +# CONFIG_MPIC_WEIRD is not set +# CONFIG_PPC_I8259 is not set +# CONFIG_PPC_RTAS is not set +# CONFIG_MMIO_NVRAM is not set +# CONFIG_PPC_MPC106 is not set +# CONFIG_PPC_970_NAP is not set +# CONFIG_PPC_INDIRECT_IO is not set +# CONFIG_GENERIC_IOMAP is not set +# CONFIG_CPU_FREQ is not set +# CONFIG_FSL_ULI1575 is not set +# CONFIG_SIMPLE_GPIO is not set + +# +# Kernel options +# +CONFIG_HIGHMEM=y +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +# CONFIG_SCHED_HRTICK is not set +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_HAVE_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_MATH_EMULATION is not set +# CONFIG_IOMMU_HELPER is not set +# CONFIG_SWIOTLB is not set +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_HAS_WALK_MEMORY=y +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y +CONFIG_SPARSE_IRQ=y +CONFIG_MAX_ACTIVE_REGIONS=32 +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_MIGRATION=y +CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_PPC_4K_PAGES=y +# CONFIG_PPC_16K_PAGES is not set +# CONFIG_PPC_64K_PAGES is not set +# CONFIG_PPC_256K_PAGES is not set +CONFIG_FORCE_MAX_ZONEORDER=11 +CONFIG_PROC_DEVICETREE=y +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="" +CONFIG_EXTRA_TARGETS="" +# CONFIG_ARCH_HAS_NMI_WATCHDOG is not set +CONFIG_SECCOMP=y +CONFIG_ISA_DMA_API=y + +# +# Bus options +# +CONFIG_ZONE_DMA=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_PPC_INDIRECT_PCI=y +CONFIG_4xx_SOC=y +CONFIG_PPC_PCI_CHOICE=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_SYSCALL=y +CONFIG_PCIEPORTBUS=y +CONFIG_PCIEAER=y +# CONFIG_PCIE_ECRC is not set +# CONFIG_PCIEAER_INJECT is not set +# CONFIG_PCIEASPM is not set +CONFIG_ARCH_SUPPORTS_MSI=y +# CONFIG_PCI_MSI is not set +# CONFIG_PCI_DEBUG is not set +# CONFIG_PCI_STUB is not set +# CONFIG_PCI_IOV is not set +# CONFIG_PCCARD is not set +# CONFIG_HOTPLUG_PCI is not set +# CONFIG_HAS_RAPIDIO is not set + +# +# Advanced setup +# +# CONFIG_ADVANCED_OPTIONS is not set + +# +# Default settings for advanced configuration options are used +# +CONFIG_LOWMEM_SIZE=0x30000000 +CONFIG_PAGE_OFFSET=0xc0000000 +CONFIG_KERNEL_START=0xc0000000 +CONFIG_PHYSICAL_START=0x00000000 +CONFIG_TASK_SIZE=0xc0000000 +CONFIG_CONSISTENT_SIZE=0x00200000 +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +CONFIG_WIRELESS=y +# CONFIG_CFG80211 is not set +# CONFIG_LIB80211 is not set + +# +# CFG80211 needs to be enabled for MAC80211 +# +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_CONNECTOR=y +CONFIG_PROC_EVENTS=y +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_OF_PARTS=y +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +CONFIG_MTD_PHYSMAP_OF=y +# CONFIG_MTD_INTEL_VR_NOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +CONFIG_OF_FLATTREE=y +CONFIG_OF_DYNAMIC=y +CONFIG_OF_DEVICE=y +CONFIG_OF_I2C=y +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_DRBD is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=35000 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_XILINX_SYSACE=y +# CONFIG_BLK_DEV_HD is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +CONFIG_SCSI_SAS_ATTRS=y +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +# CONFIG_SCSI_LOWLEVEL is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_FUSION=y +# CONFIG_FUSION_SPI is not set +# CONFIG_FUSION_FC is not set +CONFIG_FUSION_SAS=y +CONFIG_FUSION_MAX_SGE=128 +CONFIG_FUSION_CTL=y +CONFIG_FUSION_LOGGING=y + +# +# IEEE 1394 (FireWire) support +# + +# +# You can enable one or both FireWire driver stacks. +# + +# +# The newer stack is recommended. +# +# CONFIG_FIREWIRE is not set +# CONFIG_IEEE1394 is not set +# CONFIG_I2O is not set +# CONFIG_MACINTOSH_DRIVERS is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_ARCNET is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_ETHOC is not set +# CONFIG_DNET is not set +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +CONFIG_IBM_NEW_EMAC=y +CONFIG_IBM_NEW_EMAC_RXB=128 +CONFIG_IBM_NEW_EMAC_TXB=64 +CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32 +CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256 +CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0 +# CONFIG_IBM_NEW_EMAC_DEBUG 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=y +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_NET_PCI is not set +# CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set +# CONFIG_ATL2 is not set +# CONFIG_XILINX_EMACLITE is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +# CONFIG_TR is not set +# CONFIG_WLAN is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_VMXNET3 is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=640 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ADP5588 is not set +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_QT2160 is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_MAX7359 is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +# CONFIG_MOUSE_PS2_ALPS is not set +# CONFIG_MOUSE_PS2_LOGIPS2PP is not set +# CONFIG_MOUSE_PS2_SYNAPTICS is not set +# CONFIG_MOUSE_PS2_TRACKPOINT is not set +# CONFIG_MOUSE_PS2_ELANTECH is not set +# CONFIG_MOUSE_PS2_SENTELIC is not set +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_MOUSE_SYNAPTICS_I2C is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_XILINX_XPS_PS2 is not set +# CONFIG_SERIO_ALTERA_PS2 is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_NOZOMI is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_PCI is not set +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +# CONFIG_SERIAL_8250_MANY_PORTS is not set +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_RSA is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_UARTLITE is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_SERIAL_OF_PLATFORM=y +# CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set +# CONFIG_SERIAL_TIMBERDALE is not set +# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_HVC_UDBG is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_NVRAM is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_BOOTCOUNT is not set +# CONFIG_DISPLAY_PDSP1880 is not set +# CONFIG_MUCMC52_IO is not set +# CONFIG_UC101_IO is not set +# CONFIG_SRAM is not set +# CONFIG_TCG_TPM is not set +CONFIG_DEVPORT=y +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_HELPER_AUTO=y + +# +# I2C Hardware Bus support +# + +# +# PC SMBus host controller drivers +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_ISCH is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +CONFIG_I2C_IBM_IIC=y +# CONFIG_I2C_MPC is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_SPI is not set + +# +# PPS support +# +# CONFIG_PPS is not set +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +# CONFIG_GPIOLIB is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set +CONFIG_MFD_SM501=y +# CONFIG_HTC_PASIC3 is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_LPC_SCH is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +# CONFIG_AGP is not set +CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 +# CONFIG_DRM is not set +# CONFIG_VGASTATE is not set +CONFIG_VIDEO_OUTPUT_CONTROL=m +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_OF is not set +# CONFIG_FB_CT65550 is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_VGA16 is not set +# CONFIG_FB_UVESA is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_S3 is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_VIA is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_VT8623 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_ARK is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_CARMINE is not set +CONFIG_FB_SM501=y +# CONFIG_FB_IBM_GXT4500 is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_SOUND is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HIDRAW is not set +# CONFIG_HID_PID is not set + +# +# Special HID drivers +# +# CONFIG_USB_SUPPORT is not set +# CONFIG_UWB is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_INFINIBAND is not set +# CONFIG_EDAC is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +CONFIG_RTC_DRV_DS1307=y +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set + +# +# SPI RTC drivers +# + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +# CONFIG_RTC_DRV_GENERIC is not set +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# TI VLYNQ +# +# CONFIG_STAGING is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT4_FS is not set +CONFIG_JBD=y +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +# CONFIG_MSDOS_FS is not set +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_YAFFS_FS is not set +# CONFIG_LOGFS is not set +CONFIG_CRAMFS=y +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=y +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +CONFIG_NLS_ISO8859_15=y +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set +# CONFIG_DLM is not set +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_DECOMPRESS_GZIP=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_HAVE_LMB=y +CONFIG_NLATTR=y +CONFIG_GENERIC_ATOMIC64=y + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_HIGHMEM is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +CONFIG_SYSCTL_SYSCALL_CHECK=y +# CONFIG_DEBUG_PAGEALLOC is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_ENABLE_DEFAULT_TRACERS is not set +# CONFIG_BOOT_TRACER is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_PPC_DISABLE_WERROR is not set +CONFIG_PPC_WERROR=y +CONFIG_PRINT_STACK_DEPTH=64 +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_CODE_PATCHING_SELFTEST is not set +# CONFIG_FTR_FIXUP_SELFTEST is not set +# CONFIG_MSI_BITMAP_SELFTEST is not set +# CONFIG_XMON is not set +# CONFIG_IRQSTACKS is not set +# CONFIG_BDI_SWITCH is not set +# CONFIG_PPC_EARLY_DEBUG is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_LRW is not set +CONFIG_CRYPTO_PCBC=y +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_DEV_HIFN_795X is not set +# CONFIG_CRYPTO_DEV_PPC4XX is not set +# CONFIG_PPC_CLOCK is not set +# CONFIG_VIRTUALIZATION is not set diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index e3cba4e1eb34..b0b21134f61a 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h @@ -70,6 +70,7 @@ struct pt_regs; extern int machine_check_generic(struct pt_regs *regs); extern int machine_check_4xx(struct pt_regs *regs); extern int machine_check_440A(struct pt_regs *regs); +extern int machine_check_e500mc(struct pt_regs *regs); extern int machine_check_e500(struct pt_regs *regs); extern int machine_check_e200(struct pt_regs *regs); extern int machine_check_47x(struct pt_regs *regs); diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h index a6ca6da1430b..2a9cd74a841e 100644 --- a/arch/powerpc/include/asm/kexec.h +++ b/arch/powerpc/include/asm/kexec.h @@ -2,6 +2,18 @@ #define _ASM_POWERPC_KEXEC_H #ifdef __KERNEL__ +#ifdef CONFIG_FSL_BOOKE + +/* + * On FSL-BookE we setup a 1:1 mapping which covers the first 2GiB of memory + * and therefore we can only deal with memory within this range + */ +#define KEXEC_SOURCE_MEMORY_LIMIT (2 * 1024 * 1024 * 1024UL) +#define KEXEC_DESTINATION_MEMORY_LIMIT (2 * 1024 * 1024 * 1024UL) +#define KEXEC_CONTROL_MEMORY_LIMIT (2 * 1024 * 1024 * 1024UL) + +#else + /* * Maximum page that is mapped directly into kernel memory. * XXX: Since we copy virt we can use any page we allocate @@ -21,6 +33,7 @@ /* TASK_SIZE, probably left over from use_mm ?? */ #define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE #endif +#endif #define KEXEC_CONTROL_PAGE_SIZE 4096 diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h index 5304a37ba425..2360317179a9 100644 --- a/arch/powerpc/include/asm/reg_booke.h +++ b/arch/powerpc/include/asm/reg_booke.h @@ -4,6 +4,12 @@ * are not true Book E PowerPCs, they borrowed a number of features * before Book E was finalized, and are included here as well. Unfortunatly, * they sometimes used different locations than true Book E CPUs did. + * + * 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. + * + * Copyright 2009-2010 Freescale Semiconductor, Inc. */ #ifdef __KERNEL__ #ifndef __ASM_POWERPC_REG_BOOKE_H__ @@ -88,6 +94,7 @@ #define SPRN_IVOR35 0x213 /* Interrupt Vector Offset Register 35 */ #define SPRN_IVOR36 0x214 /* Interrupt Vector Offset Register 36 */ #define SPRN_IVOR37 0x215 /* Interrupt Vector Offset Register 37 */ +#define SPRN_MCARU 0x239 /* Machine Check Address Register Upper */ #define SPRN_MCSRR0 0x23A /* Machine Check Save and Restore Register 0 */ #define SPRN_MCSRR1 0x23B /* Machine Check Save and Restore Register 1 */ #define SPRN_MCSR 0x23C /* Machine Check Status Register */ @@ -196,8 +203,11 @@ #define PPC47x_MCSR_IPR 0x00400000 /* Imprecise Machine Check Exception */ #ifdef CONFIG_E500 +/* All e500 */ #define MCSR_MCP 0x80000000UL /* Machine Check Input Pin */ #define MCSR_ICPERR 0x40000000UL /* I-Cache Parity Error */ + +/* e500v1/v2 */ #define MCSR_DCP_PERR 0x20000000UL /* D-Cache Push Parity Error */ #define MCSR_DCPERR 0x10000000UL /* D-Cache Parity Error */ #define MCSR_BUS_IAERR 0x00000080UL /* Instruction Address Error */ @@ -209,12 +219,20 @@ #define MCSR_BUS_IPERR 0x00000002UL /* Instruction parity Error */ #define MCSR_BUS_RPERR 0x00000001UL /* Read parity Error */ -/* e500 parts may set unused bits in MCSR; mask these off */ -#define MCSR_MASK (MCSR_MCP | MCSR_ICPERR | MCSR_DCP_PERR | \ - MCSR_DCPERR | MCSR_BUS_IAERR | MCSR_BUS_RAERR | \ - MCSR_BUS_WAERR | MCSR_BUS_IBERR | MCSR_BUS_RBERR | \ - MCSR_BUS_WBERR | MCSR_BUS_IPERR | MCSR_BUS_RPERR) +/* e500mc */ +#define MCSR_DCPERR_MC 0x20000000UL /* D-Cache Parity Error */ +#define MCSR_L2MMU_MHIT 0x04000000UL /* Hit on multiple TLB entries */ +#define MCSR_NMI 0x00100000UL /* Non-Maskable Interrupt */ +#define MCSR_MAV 0x00080000UL /* MCAR address valid */ +#define MCSR_MEA 0x00040000UL /* MCAR is effective address */ +#define MCSR_IF 0x00010000UL /* Instruction Fetch */ +#define MCSR_LD 0x00008000UL /* Load */ +#define MCSR_ST 0x00004000UL /* Store */ +#define MCSR_LDG 0x00002000UL /* Guarded Load */ +#define MCSR_TLBSYNC 0x00000002UL /* Multiple tlbsyncs detected */ +#define MCSR_BSL2_ERR 0x00000001UL /* Backside L2 cache error */ #endif + #ifdef CONFIG_E200 #define MCSR_MCP 0x80000000UL /* Machine Check Input Pin */ #define MCSR_CP_PERR 0x20000000UL /* Cache Push Parity Error */ @@ -225,11 +243,6 @@ #define MCSR_BUS_DRERR 0x00000008UL /* Read Bus Error on data load */ #define MCSR_BUS_WRERR 0x00000004UL /* Write Bus Error on buffered store or cache line push */ - -/* e200 parts may set unused bits in MCSR; mask these off */ -#define MCSR_MASK (MCSR_MCP | MCSR_CP_PERR | MCSR_CPERR | \ - MCSR_EXCP_ERR | MCSR_BUS_IRERR | MCSR_BUS_DRERR | \ - MCSR_BUS_WRERR) #endif /* Bit definitions for the DBSR. */ diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 877326320e74..58d0572de6f9 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -57,8 +57,12 @@ obj-$(CONFIG_CRASH_DUMP) += crash_dump.o obj-$(CONFIG_E500) += idle_e500.o obj-$(CONFIG_6xx) += idle_6xx.o l2cr_6xx.o cpu_setup_6xx.o obj-$(CONFIG_TAU) += tau_6xx.o -obj-$(CONFIG_HIBERNATION) += swsusp.o suspend.o \ - swsusp_$(CONFIG_WORD_SIZE).o +obj-$(CONFIG_HIBERNATION) += swsusp.o suspend.o +ifeq ($(CONFIG_FSL_BOOKE),y) +obj-$(CONFIG_HIBERNATION) += swsusp_booke.o +else +obj-$(CONFIG_HIBERNATION) += swsusp_$(CONFIG_WORD_SIZE).o +endif obj64-$(CONFIG_HIBERNATION) += swsusp_asm64.o obj-$(CONFIG_MODULES) += module.o module_$(CONFIG_WORD_SIZE).o obj-$(CONFIG_44x) += cpu_setup_44x.o diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 9556be903e96..87aa0f3c6047 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -1840,7 +1840,7 @@ static struct cpu_spec __initdata cpu_specs[] = { .oprofile_cpu_type = "ppc/e500mc", .oprofile_type = PPC_OPROFILE_FSL_EMB, .cpu_setup = __setup_cpu_e500mc, - .machine_check = machine_check_e500, + .machine_check = machine_check_e500mc, .platform = "ppce500mc", }, { /* default match */ diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c index 8c066d6a8e4b..b46f2e09bd81 100644 --- a/arch/powerpc/kernel/crash.c +++ b/arch/powerpc/kernel/crash.c @@ -163,6 +163,7 @@ static void crash_kexec_prepare_cpus(int cpu) } /* wait for all the CPUs to hit real mode but timeout if they don't come in */ +#ifdef CONFIG_PPC_STD_MMU_64 static void crash_kexec_wait_realmode(int cpu) { unsigned int msecs; @@ -187,6 +188,7 @@ static void crash_kexec_wait_realmode(int cpu) } mb(); } +#endif /* * This function will be called by secondary cpus or by kexec cpu @@ -445,7 +447,9 @@ void default_machine_crash_shutdown(struct pt_regs *regs) crash_kexec_prepare_cpus(crashing_cpu); cpu_set(crashing_cpu, cpus_in_crash); crash_kexec_stop_spus(); +#ifdef CONFIG_PPC_STD_MMU_64 crash_kexec_wait_realmode(crashing_cpu); +#endif if (ppc_md.kexec_cpu_down) ppc_md.kexec_cpu_down(1, 0); } diff --git a/arch/powerpc/kernel/fsl_booke_entry_mapping.S b/arch/powerpc/kernel/fsl_booke_entry_mapping.S new file mode 100644 index 000000000000..beb4d78a2304 --- /dev/null +++ b/arch/powerpc/kernel/fsl_booke_entry_mapping.S @@ -0,0 +1,237 @@ + +/* 1. Find the index of the entry we're executing in */ + bl invstr /* Find our address */ +invstr: mflr r6 /* Make it accessible */ + mfmsr r7 + rlwinm r4,r7,27,31,31 /* extract MSR[IS] */ + mfspr r7, SPRN_PID0 + slwi r7,r7,16 + or r7,r7,r4 + mtspr SPRN_MAS6,r7 + tlbsx 0,r6 /* search MSR[IS], SPID=PID0 */ + mfspr r7,SPRN_MAS1 + andis. r7,r7,MAS1_VALID@h + bne match_TLB + + mfspr r7,SPRN_MMUCFG + rlwinm r7,r7,21,28,31 /* extract MMUCFG[NPIDS] */ + cmpwi r7,3 + bne match_TLB /* skip if NPIDS != 3 */ + + mfspr r7,SPRN_PID1 + slwi r7,r7,16 + or r7,r7,r4 + mtspr SPRN_MAS6,r7 + tlbsx 0,r6 /* search MSR[IS], SPID=PID1 */ + mfspr r7,SPRN_MAS1 + andis. r7,r7,MAS1_VALID@h + bne match_TLB + mfspr r7, SPRN_PID2 + slwi r7,r7,16 + or r7,r7,r4 + mtspr SPRN_MAS6,r7 + tlbsx 0,r6 /* Fall through, we had to match */ + +match_TLB: + mfspr r7,SPRN_MAS0 + rlwinm r3,r7,16,20,31 /* Extract MAS0(Entry) */ + + mfspr r7,SPRN_MAS1 /* Insure IPROT set */ + oris r7,r7,MAS1_IPROT@h + mtspr SPRN_MAS1,r7 + tlbwe + +/* 2. Invalidate all entries except the entry we're executing in */ + mfspr r9,SPRN_TLB1CFG + andi. r9,r9,0xfff + li r6,0 /* Set Entry counter to 0 */ +1: lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ + rlwimi r7,r6,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r6) */ + mtspr SPRN_MAS0,r7 + tlbre + mfspr r7,SPRN_MAS1 + rlwinm r7,r7,0,2,31 /* Clear MAS1 Valid and IPROT */ + cmpw r3,r6 + beq skpinv /* Dont update the current execution TLB */ + mtspr SPRN_MAS1,r7 + tlbwe + isync +skpinv: addi r6,r6,1 /* Increment */ + cmpw r6,r9 /* Are we done? */ + bne 1b /* If not, repeat */ + + /* Invalidate TLB0 */ + li r6,0x04 + tlbivax 0,r6 + TLBSYNC + /* Invalidate TLB1 */ + li r6,0x0c + tlbivax 0,r6 + TLBSYNC + +/* 3. Setup a temp mapping and jump to it */ + andi. r5, r3, 0x1 /* Find an entry not used and is non-zero */ + addi r5, r5, 0x1 + lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ + rlwimi r7,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */ + mtspr SPRN_MAS0,r7 + tlbre + + /* grab and fixup the RPN */ + mfspr r6,SPRN_MAS1 /* extract MAS1[SIZE] */ + rlwinm r6,r6,25,27,31 + li r8,-1 + addi r6,r6,10 + slw r6,r8,r6 /* convert to mask */ + + bl 1f /* Find our address */ +1: mflr r7 + + mfspr r8,SPRN_MAS3 +#ifdef CONFIG_PHYS_64BIT + mfspr r23,SPRN_MAS7 +#endif + and r8,r6,r8 + subfic r9,r6,-4096 + and r9,r9,r7 + + or r25,r8,r9 + ori r8,r25,(MAS3_SX|MAS3_SW|MAS3_SR) + + /* Just modify the entry ID and EPN for the temp mapping */ + lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ + rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */ + mtspr SPRN_MAS0,r7 + xori r6,r4,1 /* Setup TMP mapping in the other Address space */ + slwi r6,r6,12 + oris r6,r6,(MAS1_VALID|MAS1_IPROT)@h + ori r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_4K))@l + mtspr SPRN_MAS1,r6 + mfspr r6,SPRN_MAS2 + li r7,0 /* temp EPN = 0 */ + rlwimi r7,r6,0,20,31 + mtspr SPRN_MAS2,r7 + mtspr SPRN_MAS3,r8 + tlbwe + + xori r6,r4,1 + slwi r6,r6,5 /* setup new context with other address space */ + bl 1f /* Find our address */ +1: mflr r9 + rlwimi r7,r9,0,20,31 + addi r7,r7,(2f - 1b) + mtspr SPRN_SRR0,r7 + mtspr SPRN_SRR1,r6 + rfi +2: +/* 4. Clear out PIDs & Search info */ + li r6,0 + mtspr SPRN_MAS6,r6 + mtspr SPRN_PID0,r6 + + mfspr r7,SPRN_MMUCFG + rlwinm r7,r7,21,28,31 /* extract MMUCFG[NPIDS] */ + cmpwi r7,3 + bne 2f /* skip if NPIDS != 3 */ + + mtspr SPRN_PID1,r6 + mtspr SPRN_PID2,r6 + +/* 5. Invalidate mapping we started in */ +2: + lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ + rlwimi r7,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */ + mtspr SPRN_MAS0,r7 + tlbre + mfspr r6,SPRN_MAS1 + rlwinm r6,r6,0,2,0 /* clear IPROT */ + mtspr SPRN_MAS1,r6 + tlbwe + /* Invalidate TLB1 */ + li r9,0x0c + tlbivax 0,r9 + TLBSYNC + +/* The mapping only needs to be cache-coherent on SMP */ +#ifdef CONFIG_SMP +#define M_IF_SMP MAS2_M +#else +#define M_IF_SMP 0 +#endif + +#if defined(ENTRY_MAPPING_BOOT_SETUP) + +/* 6. Setup KERNELBASE mapping in TLB1[0] */ + lis r6,0x1000 /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */ + mtspr SPRN_MAS0,r6 + lis r6,(MAS1_VALID|MAS1_IPROT)@h + ori r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_64M))@l + mtspr SPRN_MAS1,r6 + lis r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@h + ori r6,r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@l + mtspr SPRN_MAS2,r6 + mtspr SPRN_MAS3,r8 + tlbwe + +/* 7. Jump to KERNELBASE mapping */ + lis r6,(KERNELBASE & ~0xfff)@h + ori r6,r6,(KERNELBASE & ~0xfff)@l + +#elif defined(ENTRY_MAPPING_KEXEC_SETUP) +/* + * 6. Setup a 1:1 mapping in TLB1. Esel 0 is unsued, 1 or 2 contains the tmp + * mapping so we start at 3. We setup 8 mappings, each 256MiB in size. This + * will cover the first 2GiB of memory. + */ + + lis r10, (MAS1_VALID|MAS1_IPROT)@h + ori r10,r10, (MAS1_TSIZE(BOOK3E_PAGESZ_256M))@l + li r11, 0 + li r0, 8 + mtctr r0 + +next_tlb_setup: + addi r0, r11, 3 + rlwinm r0, r0, 16, 4, 15 // Compute esel + rlwinm r9, r11, 28, 0, 3 // Compute [ER]PN + oris r0, r0, (MAS0_TLBSEL(1))@h + mtspr SPRN_MAS0,r0 + mtspr SPRN_MAS1,r10 + mtspr SPRN_MAS2,r9 + ori r9, r9, (MAS3_SX|MAS3_SW|MAS3_SR) + mtspr SPRN_MAS3,r9 + tlbwe + addi r11, r11, 1 + bdnz+ next_tlb_setup + +/* 7. Jump to our 1:1 mapping */ + li r6, 0 + +#else + #error You need to specify the mapping or not use this at all. +#endif + + lis r7,MSR_KERNEL@h + ori r7,r7,MSR_KERNEL@l + bl 1f /* Find our address */ +1: mflr r9 + rlwimi r6,r9,0,20,31 + addi r6,r6,(2f - 1b) + add r6, r6, r25 + mtspr SPRN_SRR0,r6 + mtspr SPRN_SRR1,r7 + rfi /* start execution out of TLB1[0] entry */ + +/* 8. Clear out the temp mapping */ +2: lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ + rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */ + mtspr SPRN_MAS0,r7 + tlbre + mfspr r8,SPRN_MAS1 + rlwinm r8,r8,0,2,0 /* clear IPROT */ + mtspr SPRN_MAS1,r8 + tlbwe + /* Invalidate TLB1 */ + li r9,0x0c + tlbivax 0,r9 + TLBSYNC diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index edd4a57fd29e..4faeba247854 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -94,204 +94,10 @@ _ENTRY(_start); */ _ENTRY(__early_start) -/* 1. Find the index of the entry we're executing in */ - bl invstr /* Find our address */ -invstr: mflr r6 /* Make it accessible */ - mfmsr r7 - rlwinm r4,r7,27,31,31 /* extract MSR[IS] */ - mfspr r7, SPRN_PID0 - slwi r7,r7,16 - or r7,r7,r4 - mtspr SPRN_MAS6,r7 - tlbsx 0,r6 /* search MSR[IS], SPID=PID0 */ - mfspr r7,SPRN_MAS1 - andis. r7,r7,MAS1_VALID@h - bne match_TLB - - mfspr r7,SPRN_MMUCFG - rlwinm r7,r7,21,28,31 /* extract MMUCFG[NPIDS] */ - cmpwi r7,3 - bne match_TLB /* skip if NPIDS != 3 */ - - mfspr r7,SPRN_PID1 - slwi r7,r7,16 - or r7,r7,r4 - mtspr SPRN_MAS6,r7 - tlbsx 0,r6 /* search MSR[IS], SPID=PID1 */ - mfspr r7,SPRN_MAS1 - andis. r7,r7,MAS1_VALID@h - bne match_TLB - mfspr r7, SPRN_PID2 - slwi r7,r7,16 - or r7,r7,r4 - mtspr SPRN_MAS6,r7 - tlbsx 0,r6 /* Fall through, we had to match */ - -match_TLB: - mfspr r7,SPRN_MAS0 - rlwinm r3,r7,16,20,31 /* Extract MAS0(Entry) */ - - mfspr r7,SPRN_MAS1 /* Insure IPROT set */ - oris r7,r7,MAS1_IPROT@h - mtspr SPRN_MAS1,r7 - tlbwe - -/* 2. Invalidate all entries except the entry we're executing in */ - mfspr r9,SPRN_TLB1CFG - andi. r9,r9,0xfff - li r6,0 /* Set Entry counter to 0 */ -1: lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ - rlwimi r7,r6,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r6) */ - mtspr SPRN_MAS0,r7 - tlbre - mfspr r7,SPRN_MAS1 - rlwinm r7,r7,0,2,31 /* Clear MAS1 Valid and IPROT */ - cmpw r3,r6 - beq skpinv /* Dont update the current execution TLB */ - mtspr SPRN_MAS1,r7 - tlbwe - isync -skpinv: addi r6,r6,1 /* Increment */ - cmpw r6,r9 /* Are we done? */ - bne 1b /* If not, repeat */ - - /* Invalidate TLB0 */ - li r6,0x04 - tlbivax 0,r6 - TLBSYNC - /* Invalidate TLB1 */ - li r6,0x0c - tlbivax 0,r6 - TLBSYNC - -/* 3. Setup a temp mapping and jump to it */ - andi. r5, r3, 0x1 /* Find an entry not used and is non-zero */ - addi r5, r5, 0x1 - lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ - rlwimi r7,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */ - mtspr SPRN_MAS0,r7 - tlbre - - /* grab and fixup the RPN */ - mfspr r6,SPRN_MAS1 /* extract MAS1[SIZE] */ - rlwinm r6,r6,25,27,31 - li r8,-1 - addi r6,r6,10 - slw r6,r8,r6 /* convert to mask */ - - bl 1f /* Find our address */ -1: mflr r7 - - mfspr r8,SPRN_MAS3 -#ifdef CONFIG_PHYS_64BIT - mfspr r23,SPRN_MAS7 -#endif - and r8,r6,r8 - subfic r9,r6,-4096 - and r9,r9,r7 - - or r25,r8,r9 - ori r8,r25,(MAS3_SX|MAS3_SW|MAS3_SR) - - /* Just modify the entry ID and EPN for the temp mapping */ - lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ - rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */ - mtspr SPRN_MAS0,r7 - xori r6,r4,1 /* Setup TMP mapping in the other Address space */ - slwi r6,r6,12 - oris r6,r6,(MAS1_VALID|MAS1_IPROT)@h - ori r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_4K))@l - mtspr SPRN_MAS1,r6 - mfspr r6,SPRN_MAS2 - li r7,0 /* temp EPN = 0 */ - rlwimi r7,r6,0,20,31 - mtspr SPRN_MAS2,r7 - mtspr SPRN_MAS3,r8 - tlbwe - - xori r6,r4,1 - slwi r6,r6,5 /* setup new context with other address space */ - bl 1f /* Find our address */ -1: mflr r9 - rlwimi r7,r9,0,20,31 - addi r7,r7,(2f - 1b) - mtspr SPRN_SRR0,r7 - mtspr SPRN_SRR1,r6 - rfi -2: -/* 4. Clear out PIDs & Search info */ - li r6,0 - mtspr SPRN_MAS6,r6 - mtspr SPRN_PID0,r6 - - mfspr r7,SPRN_MMUCFG - rlwinm r7,r7,21,28,31 /* extract MMUCFG[NPIDS] */ - cmpwi r7,3 - bne 2f /* skip if NPIDS != 3 */ - mtspr SPRN_PID1,r6 - mtspr SPRN_PID2,r6 - -/* 5. Invalidate mapping we started in */ -2: - lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ - rlwimi r7,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */ - mtspr SPRN_MAS0,r7 - tlbre - mfspr r6,SPRN_MAS1 - rlwinm r6,r6,0,2,0 /* clear IPROT */ - mtspr SPRN_MAS1,r6 - tlbwe - /* Invalidate TLB1 */ - li r9,0x0c - tlbivax 0,r9 - TLBSYNC - -/* The mapping only needs to be cache-coherent on SMP */ -#ifdef CONFIG_SMP -#define M_IF_SMP MAS2_M -#else -#define M_IF_SMP 0 -#endif - -/* 6. Setup KERNELBASE mapping in TLB1[0] */ - lis r6,0x1000 /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */ - mtspr SPRN_MAS0,r6 - lis r6,(MAS1_VALID|MAS1_IPROT)@h - ori r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_64M))@l - mtspr SPRN_MAS1,r6 - lis r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@h - ori r6,r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@l - mtspr SPRN_MAS2,r6 - mtspr SPRN_MAS3,r8 - tlbwe - -/* 7. Jump to KERNELBASE mapping */ - lis r6,(KERNELBASE & ~0xfff)@h - ori r6,r6,(KERNELBASE & ~0xfff)@l - lis r7,MSR_KERNEL@h - ori r7,r7,MSR_KERNEL@l - bl 1f /* Find our address */ -1: mflr r9 - rlwimi r6,r9,0,20,31 - addi r6,r6,(2f - 1b) - mtspr SPRN_SRR0,r6 - mtspr SPRN_SRR1,r7 - rfi /* start execution out of TLB1[0] entry */ - -/* 8. Clear out the temp mapping */ -2: lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ - rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */ - mtspr SPRN_MAS0,r7 - tlbre - mfspr r8,SPRN_MAS1 - rlwinm r8,r8,0,2,0 /* clear IPROT */ - mtspr SPRN_MAS1,r8 - tlbwe - /* Invalidate TLB1 */ - li r9,0x0c - tlbivax 0,r9 - TLBSYNC +#define ENTRY_MAPPING_BOOT_SETUP +#include "fsl_booke_entry_mapping.S" +#undef ENTRY_MAPPING_BOOT_SETUP /* Establish the interrupt vector offsets */ SET_IVOR(0, CriticalInput); diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index 8043d1b73cf0..dc66d52dcff5 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S @@ -711,6 +711,22 @@ relocate_new_kernel: /* r4 = reboot_code_buffer */ /* r5 = start_address */ +#ifdef CONFIG_FSL_BOOKE + + mr r29, r3 + mr r30, r4 + mr r31, r5 + +#define ENTRY_MAPPING_KEXEC_SETUP +#include "fsl_booke_entry_mapping.S" +#undef ENTRY_MAPPING_KEXEC_SETUP + + mr r3, r29 + mr r4, r30 + mr r5, r31 + + li r0, 0 +#else li r0, 0 /* @@ -727,6 +743,7 @@ relocate_new_kernel: rfi 1: +#endif /* from this point address translation is turned off */ /* and interrupts are disabled */ diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index bc9f39d2598b..3b4dcc82a4c1 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c @@ -101,7 +101,7 @@ EXPORT_SYMBOL(pci_dram_offset); EXPORT_SYMBOL(start_thread); EXPORT_SYMBOL(kernel_thread); -#ifndef CONFIG_BOOKE +#ifdef CONFIG_PPC_FPU EXPORT_SYMBOL_GPL(cvt_df); EXPORT_SYMBOL_GPL(cvt_fd); #endif diff --git a/arch/powerpc/kernel/swsusp_booke.S b/arch/powerpc/kernel/swsusp_booke.S new file mode 100644 index 000000000000..11a39307dd71 --- /dev/null +++ b/arch/powerpc/kernel/swsusp_booke.S @@ -0,0 +1,193 @@ +/* + * Based on swsusp_32.S, modified for FSL BookE by + * Anton Vorontsov <avorontsov@ru.mvista.com> + * Copyright (c) 2009-2010 MontaVista Software, LLC. + */ + +#include <linux/threads.h> +#include <asm/processor.h> +#include <asm/page.h> +#include <asm/cputable.h> +#include <asm/thread_info.h> +#include <asm/ppc_asm.h> +#include <asm/asm-offsets.h> +#include <asm/mmu.h> + +/* + * Structure for storing CPU registers on the save area. + */ +#define SL_SP 0 +#define SL_PC 4 +#define SL_MSR 8 +#define SL_TCR 0xc +#define SL_SPRG0 0x10 +#define SL_SPRG1 0x14 +#define SL_SPRG2 0x18 +#define SL_SPRG3 0x1c +#define SL_SPRG4 0x20 +#define SL_SPRG5 0x24 +#define SL_SPRG6 0x28 +#define SL_SPRG7 0x2c +#define SL_TBU 0x30 +#define SL_TBL 0x34 +#define SL_R2 0x38 +#define SL_CR 0x3c +#define SL_LR 0x40 +#define SL_R12 0x44 /* r12 to r31 */ +#define SL_SIZE (SL_R12 + 80) + + .section .data + .align 5 + +_GLOBAL(swsusp_save_area) + .space SL_SIZE + + + .section .text + .align 5 + +_GLOBAL(swsusp_arch_suspend) + lis r11,swsusp_save_area@h + ori r11,r11,swsusp_save_area@l + + mflr r0 + stw r0,SL_LR(r11) + mfcr r0 + stw r0,SL_CR(r11) + stw r1,SL_SP(r11) + stw r2,SL_R2(r11) + stmw r12,SL_R12(r11) + + /* Save MSR & TCR */ + mfmsr r4 + stw r4,SL_MSR(r11) + mfspr r4,SPRN_TCR + stw r4,SL_TCR(r11) + + /* Get a stable timebase and save it */ +1: mfspr r4,SPRN_TBRU + stw r4,SL_TBU(r11) + mfspr r5,SPRN_TBRL + stw r5,SL_TBL(r11) + mfspr r3,SPRN_TBRU + cmpw r3,r4 + bne 1b + + /* Save SPRGs */ + mfsprg r4,0 + stw r4,SL_SPRG0(r11) + mfsprg r4,1 + stw r4,SL_SPRG1(r11) + mfsprg r4,2 + stw r4,SL_SPRG2(r11) + mfsprg r4,3 + stw r4,SL_SPRG3(r11) + mfsprg r4,4 + stw r4,SL_SPRG4(r11) + mfsprg r4,5 + stw r4,SL_SPRG5(r11) + mfsprg r4,6 + stw r4,SL_SPRG6(r11) + mfsprg r4,7 + stw r4,SL_SPRG7(r11) + + /* Call the low level suspend stuff (we should probably have made + * a stackframe... + */ + bl swsusp_save + + /* Restore LR from the save area */ + lis r11,swsusp_save_area@h + ori r11,r11,swsusp_save_area@l + lwz r0,SL_LR(r11) + mtlr r0 + + blr + +_GLOBAL(swsusp_arch_resume) + sync + + /* Load ptr the list of pages to copy in r3 */ + lis r11,(restore_pblist)@h + ori r11,r11,restore_pblist@l + lwz r3,0(r11) + + /* Copy the pages. This is a very basic implementation, to + * be replaced by something more cache efficient */ +1: + li r0,256 + mtctr r0 + lwz r5,pbe_address(r3) /* source */ + lwz r6,pbe_orig_address(r3) /* destination */ +2: + lwz r8,0(r5) + lwz r9,4(r5) + lwz r10,8(r5) + lwz r11,12(r5) + addi r5,r5,16 + stw r8,0(r6) + stw r9,4(r6) + stw r10,8(r6) + stw r11,12(r6) + addi r6,r6,16 + bdnz 2b + lwz r3,pbe_next(r3) + cmpwi 0,r3,0 + bne 1b + + bl flush_dcache_L1 + bl flush_instruction_cache + + lis r11,swsusp_save_area@h + ori r11,r11,swsusp_save_area@l + + lwz r4,SL_SPRG0(r11) + mtsprg 0,r4 + lwz r4,SL_SPRG1(r11) + mtsprg 1,r4 + lwz r4,SL_SPRG2(r11) + mtsprg 2,r4 + lwz r4,SL_SPRG3(r11) + mtsprg 3,r4 + lwz r4,SL_SPRG4(r11) + mtsprg 4,r4 + lwz r4,SL_SPRG5(r11) + mtsprg 5,r4 + lwz r4,SL_SPRG6(r11) + mtsprg 6,r4 + lwz r4,SL_SPRG7(r11) + mtsprg 7,r4 + + /* restore the MSR */ + lwz r3,SL_MSR(r11) + mtmsr r3 + + /* Restore TB */ + li r3,0 + mtspr SPRN_TBWL,r3 + lwz r3,SL_TBU(r11) + lwz r4,SL_TBL(r11) + mtspr SPRN_TBWU,r3 + mtspr SPRN_TBWL,r4 + + /* Restore TCR and clear any pending bits in TSR. */ + lwz r4,SL_TCR(r11) + mtspr SPRN_TCR,r4 + lis r4, (TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS)@h + mtspr SPRN_TSR,r4 + + /* Kick decrementer */ + li r0,1 + mtdec r0 + + /* Restore the callee-saved registers and return */ + lwz r0,SL_CR(r11) + mtcr r0 + lwz r2,SL_R2(r11) + lmw r12,SL_R12(r11) + lwz r1,SL_SP(r11) + lwz r0,SL_LR(r11) + mtlr r0 + + li r3,0 + blr diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 3031fc712ad0..25fc33984c2b 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -1,5 +1,6 @@ /* * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * Copyright 2007-2010 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 @@ -305,7 +306,7 @@ static inline int check_io_access(struct pt_regs *regs) #ifndef CONFIG_FSL_BOOKE #define get_mc_reason(regs) ((regs)->dsisr) #else -#define get_mc_reason(regs) (mfspr(SPRN_MCSR) & MCSR_MASK) +#define get_mc_reason(regs) (mfspr(SPRN_MCSR)) #endif #define REASON_FP ESR_FP #define REASON_ILLEGAL (ESR_PIL | ESR_PUO) @@ -421,6 +422,91 @@ int machine_check_47x(struct pt_regs *regs) return 0; } #elif defined(CONFIG_E500) +int machine_check_e500mc(struct pt_regs *regs) +{ + unsigned long mcsr = mfspr(SPRN_MCSR); + unsigned long reason = mcsr; + int recoverable = 1; + + printk("Machine check in kernel mode.\n"); + printk("Caused by (from MCSR=%lx): ", reason); + + if (reason & MCSR_MCP) + printk("Machine Check Signal\n"); + + if (reason & MCSR_ICPERR) { + printk("Instruction Cache Parity Error\n"); + + /* + * This is recoverable by invalidating the i-cache. + */ + mtspr(SPRN_L1CSR1, mfspr(SPRN_L1CSR1) | L1CSR1_ICFI); + while (mfspr(SPRN_L1CSR1) & L1CSR1_ICFI) + ; + + /* + * This will generally be accompanied by an instruction + * fetch error report -- only treat MCSR_IF as fatal + * if it wasn't due to an L1 parity error. + */ + reason &= ~MCSR_IF; + } + + if (reason & MCSR_DCPERR_MC) { + printk("Data Cache Parity Error\n"); + recoverable = 0; + } + + if (reason & MCSR_L2MMU_MHIT) { + printk("Hit on multiple TLB entries\n"); + recoverable = 0; + } + + if (reason & MCSR_NMI) + printk("Non-maskable interrupt\n"); + + if (reason & MCSR_IF) { + printk("Instruction Fetch Error Report\n"); + recoverable = 0; + } + + if (reason & MCSR_LD) { + printk("Load Error Report\n"); + recoverable = 0; + } + + if (reason & MCSR_ST) { + printk("Store Error Report\n"); + recoverable = 0; + } + + if (reason & MCSR_LDG) { + printk("Guarded Load Error Report\n"); + recoverable = 0; + } + + if (reason & MCSR_TLBSYNC) + printk("Simultaneous tlbsync operations\n"); + + if (reason & MCSR_BSL2_ERR) { + printk("Level 2 Cache Error\n"); + recoverable = 0; + } + + if (reason & MCSR_MAV) { + u64 addr; + + addr = mfspr(SPRN_MCAR); + addr |= (u64)mfspr(SPRN_MCARU) << 32; + + printk("Machine Check %s Address: %#llx\n", + reason & MCSR_MEA ? "Effective" : "Physical", addr); + } + + mtspr(SPRN_MCSR, mcsr); + return mfspr(SPRN_MCSR) == 0 && recoverable; +} + int machine_check_e500(struct pt_regs *regs) { unsigned long reason = get_mc_reason(regs); diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig index eeba0a70e466..69d668c072ae 100644 --- a/arch/powerpc/platforms/44x/Kconfig +++ b/arch/powerpc/platforms/44x/Kconfig @@ -171,6 +171,17 @@ config ISS4xx help This option enables support for the IBM ISS simulation environment +config ICON + bool "Icon" + depends on 44x + default n + select PPC44x_SIMPLE + select 440SPe + select PCI + select PPC4xx_PCI_EXPRESS + help + This option enables support for the AMCC PPC440SPe evaluation board. + #config LUAN # bool "Luan" # depends on 44x diff --git a/arch/powerpc/platforms/44x/ppc44x_simple.c b/arch/powerpc/platforms/44x/ppc44x_simple.c index e8c23ccaa1fc..5f7a29d7f590 100644 --- a/arch/powerpc/platforms/44x/ppc44x_simple.c +++ b/arch/powerpc/platforms/44x/ppc44x_simple.c @@ -61,7 +61,8 @@ static char *board[] __initdata = { "amcc,redwood", "amcc,sequoia", "amcc,taishan", - "amcc,yosemite" + "amcc,yosemite", + "mosaixtech,icon" }; static int __init ppc44x_probe(void) diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig index 4dac9b0525a4..e9dca280a4d2 100644 --- a/arch/powerpc/platforms/512x/Kconfig +++ b/arch/powerpc/platforms/512x/Kconfig @@ -1,29 +1,24 @@ config PPC_MPC512x - bool + bool "512x-based boards" + depends on 6xx select FSL_SOC select IPIC select PPC_CLOCK select PPC_PCI_CHOICE select FSL_PCI if PCI -config PPC_MPC5121 - bool - select PPC_MPC512x - config MPC5121_ADS bool "Freescale MPC5121E ADS" - depends on 6xx + depends on PPC_MPC512x select DEFAULT_UIMAGE - select PPC_MPC5121 select MPC5121_ADS_CPLD help This option enables support for the MPC5121E ADS board. config MPC5121_GENERIC bool "Generic support for simple MPC5121 based boards" - depends on 6xx + depends on PPC_MPC512x select DEFAULT_UIMAGE - select PPC_MPC5121 help This option enables support for simple MPC5121 based boards which do not need custom platform specific setup. diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c index f0684c8ac960..8fe87fc61485 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c @@ -1,5 +1,5 @@ /* - * Copyright (C) Freescale Semicondutor, Inc. 2006-2007. All rights reserved. + * Copyright (C) Freescale Semicondutor, Inc. 2006-2010. All rights reserved. * * Author: Andy Fleming <afleming@freescale.com> * @@ -154,6 +154,10 @@ static int mpc8568_mds_phy_fixups(struct phy_device *phydev) * Setup the architecture * */ +#ifdef CONFIG_SMP +extern void __init mpc85xx_smp_init(void); +#endif + static void __init mpc85xx_mds_setup_arch(void) { struct device_node *np; @@ -194,6 +198,10 @@ static void __init mpc85xx_mds_setup_arch(void) } #endif +#ifdef CONFIG_SMP + mpc85xx_smp_init(); +#endif + #ifdef CONFIG_QUICC_ENGINE np = of_find_compatible_node(NULL, NULL, "fsl,qe"); if (!np) { @@ -271,9 +279,49 @@ static void __init mpc85xx_mds_setup_arch(void) BCSR_UCC_RGMII, BCSR_UCC_RTBI); } + } else if (machine_is(p1021_mds)) { +#define BCSR11_ENET_MICRST (0x1 << 5) + /* Reset Micrel PHY */ + clrbits8(&bcsr_regs[11], BCSR11_ENET_MICRST); + setbits8(&bcsr_regs[11], BCSR11_ENET_MICRST); } + iounmap(bcsr_regs); } + + if (machine_is(p1021_mds)) { +#define MPC85xx_PMUXCR_OFFSET 0x60 +#define MPC85xx_PMUXCR_QE0 0x00008000 +#define MPC85xx_PMUXCR_QE3 0x00001000 +#define MPC85xx_PMUXCR_QE9 0x00000040 +#define MPC85xx_PMUXCR_QE12 0x00000008 + static __be32 __iomem *pmuxcr; + + np = of_find_node_by_name(NULL, "global-utilities"); + + if (np) { + pmuxcr = of_iomap(np, 0) + MPC85xx_PMUXCR_OFFSET; + + if (!pmuxcr) + printk(KERN_EMERG "Error: Alternate function" + " signal multiplex control register not" + " mapped!\n"); + else + /* P1021 has pins muxed for QE and other functions. To + * enable QE UEC mode, we need to set bit QE0 for UCC1 + * in Eth mode, QE0 and QE3 for UCC5 in Eth mode, QE9 + * and QE12 for QE MII management singals in PMUXCR + * register. + */ + setbits32(pmuxcr, MPC85xx_PMUXCR_QE0 | + MPC85xx_PMUXCR_QE3 | + MPC85xx_PMUXCR_QE9 | + MPC85xx_PMUXCR_QE12); + + of_node_put(np); + } + + } #endif /* CONFIG_QUICC_ENGINE */ #ifdef CONFIG_SWIOTLB @@ -330,6 +378,16 @@ static struct of_device_id mpc85xx_ids[] = { {}, }; +static struct of_device_id p1021_ids[] = { + { .type = "soc", }, + { .compatible = "soc", }, + { .compatible = "simple-bus", }, + { .type = "qe", }, + { .compatible = "fsl,qe", }, + { .compatible = "gianfar", }, + {}, +}; + static int __init mpc85xx_publish_devices(void) { if (machine_is(mpc8568_mds)) @@ -342,11 +400,22 @@ static int __init mpc85xx_publish_devices(void) return 0; } + +static int __init p1021_publish_devices(void) +{ + /* Publish the QE devices */ + of_platform_bus_probe(NULL, p1021_ids, NULL); + + return 0; +} + machine_device_initcall(mpc8568_mds, mpc85xx_publish_devices); machine_device_initcall(mpc8569_mds, mpc85xx_publish_devices); +machine_device_initcall(p1021_mds, p1021_publish_devices); machine_arch_initcall(mpc8568_mds, swiotlb_setup_bus_notifier); machine_arch_initcall(mpc8569_mds, swiotlb_setup_bus_notifier); +machine_arch_initcall(p1021_mds, swiotlb_setup_bus_notifier); static void __init mpc85xx_mds_pic_init(void) { @@ -366,7 +435,7 @@ static void __init mpc85xx_mds_pic_init(void) mpic = mpic_alloc(np, r.start, MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN | - MPIC_BROKEN_FRR_NIRQS, + MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU, 0, 256, " OpenPIC "); BUG_ON(mpic == NULL); of_node_put(np); @@ -380,7 +449,11 @@ static void __init mpc85xx_mds_pic_init(void) if (!np) return; } - qe_ic_init(np, 0, qe_ic_cascade_muxed_mpic, NULL); + if (machine_is(p1021_mds)) + qe_ic_init(np, 0, qe_ic_cascade_low_mpic, + qe_ic_cascade_high_mpic); + else + qe_ic_init(np, 0, qe_ic_cascade_muxed_mpic, NULL); of_node_put(np); #endif /* CONFIG_QUICC_ENGINE */ } @@ -426,3 +499,26 @@ define_machine(mpc8569_mds) { .pcibios_fixup_bus = fsl_pcibios_fixup_bus, #endif }; + +static int __init p1021_mds_probe(void) +{ + unsigned long root = of_get_flat_dt_root(); + + return of_flat_dt_is_compatible(root, "fsl,P1021MDS"); + +} + +define_machine(p1021_mds) { + .name = "P1021 MDS", + .probe = p1021_mds_probe, + .setup_arch = mpc85xx_mds_setup_arch, + .init_IRQ = mpc85xx_mds_pic_init, + .get_irq = mpic_get_irq, + .restart = fsl_rstcr_restart, + .calibrate_decr = generic_calibrate_decr, + .progress = udbg_progress, +#ifdef CONFIG_PCI + .pcibios_fixup_bus = fsl_pcibios_fixup_bus, +#endif +}; + diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index a7be144f5874..0f5bee90ee4e 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2008 Freescale Semiconductor, Inc. All rights reserved. + * Copyright (C) 2007-2010 Freescale Semiconductor, Inc. * * Author: Tony Li <tony.li@freescale.com> * Jason Jin <Jason.jin@freescale.com> @@ -22,14 +22,20 @@ #include <asm/prom.h> #include <asm/hw_irq.h> #include <asm/ppc-pci.h> +#include <asm/mpic.h> #include "fsl_msi.h" +LIST_HEAD(msi_head); + struct fsl_msi_feature { u32 fsl_pic_ip; u32 msiir_offset; }; -static struct fsl_msi *fsl_msi; +struct fsl_msi_cascade_data { + struct fsl_msi *msi_data; + int index; +}; static inline u32 fsl_msi_read(u32 __iomem *base, unsigned int reg) { @@ -54,10 +60,12 @@ static struct irq_chip fsl_msi_chip = { static int fsl_msi_host_map(struct irq_host *h, unsigned int virq, irq_hw_number_t hw) { + struct fsl_msi *msi_data = h->host_data; struct irq_chip *chip = &fsl_msi_chip; irq_to_desc(virq)->status |= IRQ_TYPE_EDGE_FALLING; + set_irq_chip_data(virq, msi_data); set_irq_chip_and_handler(virq, chip, handle_edge_irq); return 0; @@ -96,11 +104,12 @@ static int fsl_msi_check_device(struct pci_dev *pdev, int nvec, int type) static void fsl_teardown_msi_irqs(struct pci_dev *pdev) { struct msi_desc *entry; - struct fsl_msi *msi_data = fsl_msi; + struct fsl_msi *msi_data; list_for_each_entry(entry, &pdev->msi_list, list) { if (entry->irq == NO_IRQ) continue; + msi_data = get_irq_data(entry->irq); set_irq_msi(entry->irq, NULL); msi_bitmap_free_hwirqs(&msi_data->bitmap, virq_to_hw(entry->irq), 1); @@ -111,9 +120,10 @@ static void fsl_teardown_msi_irqs(struct pci_dev *pdev) } static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq, - struct msi_msg *msg) + struct msi_msg *msg, + struct fsl_msi *fsl_msi_data) { - struct fsl_msi *msi_data = fsl_msi; + struct fsl_msi *msi_data = fsl_msi_data; struct pci_controller *hose = pci_bus_to_host(pdev->bus); u32 base = 0; @@ -130,14 +140,19 @@ static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq, static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) { - int rc, hwirq; + int rc, hwirq = -ENOMEM; unsigned int virq; struct msi_desc *entry; struct msi_msg msg; - struct fsl_msi *msi_data = fsl_msi; + struct fsl_msi *msi_data; list_for_each_entry(entry, &pdev->msi_list, list) { - hwirq = msi_bitmap_alloc_hwirqs(&msi_data->bitmap, 1); + list_for_each_entry(msi_data, &msi_head, list) { + hwirq = msi_bitmap_alloc_hwirqs(&msi_data->bitmap, 1); + if (hwirq >= 0) + break; + } + if (hwirq < 0) { rc = hwirq; pr_debug("%s: fail allocating msi interrupt\n", @@ -154,25 +169,31 @@ static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) rc = -ENOSPC; goto out_free; } + set_irq_data(virq, msi_data); set_irq_msi(virq, entry); - fsl_compose_msi_msg(pdev, hwirq, &msg); + fsl_compose_msi_msg(pdev, hwirq, &msg, msi_data); write_msi_msg(virq, &msg); } return 0; out_free: + /* free by the caller of this function */ return rc; } static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc) { unsigned int cascade_irq; - struct fsl_msi *msi_data = fsl_msi; + struct fsl_msi *msi_data; int msir_index = -1; u32 msir_value = 0; u32 intr_index; u32 have_shift = 0; + struct fsl_msi_cascade_data *cascade_data; + + cascade_data = (struct fsl_msi_cascade_data *)get_irq_data(irq); + msi_data = cascade_data->msi_data; raw_spin_lock(&desc->lock); if ((msi_data->feature & FSL_PIC_IP_MASK) == FSL_PIC_IP_IPIC) { @@ -187,13 +208,13 @@ static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc) if (unlikely(desc->status & IRQ_INPROGRESS)) goto unlock; - msir_index = (int)desc->handler_data; + msir_index = cascade_data->index; if (msir_index >= NR_MSI_REG) cascade_irq = NO_IRQ; desc->status |= IRQ_INPROGRESS; - switch (fsl_msi->feature & FSL_PIC_IP_MASK) { + switch (msi_data->feature & FSL_PIC_IP_MASK) { case FSL_PIC_IP_MPIC: msir_value = fsl_msi_read(msi_data->msi_regs, msir_index * 0x10); @@ -229,6 +250,30 @@ unlock: raw_spin_unlock(&desc->lock); } +static int fsl_of_msi_remove(struct of_device *ofdev) +{ + struct fsl_msi *msi = ofdev->dev.platform_data; + int virq, i; + struct fsl_msi_cascade_data *cascade_data; + + if (msi->list.prev != NULL) + list_del(&msi->list); + for (i = 0; i < NR_MSI_REG; i++) { + virq = msi->msi_virqs[i]; + if (virq != NO_IRQ) { + cascade_data = get_irq_data(virq); + kfree(cascade_data); + irq_dispose_mapping(virq); + } + } + if (msi->bitmap.bitmap) + msi_bitmap_free(&msi->bitmap); + iounmap(msi->msi_regs); + kfree(msi); + + return 0; +} + static int __devinit fsl_of_msi_probe(struct of_device *dev, const struct of_device_id *match) { @@ -239,15 +284,18 @@ static int __devinit fsl_of_msi_probe(struct of_device *dev, int virt_msir; const u32 *p; struct fsl_msi_feature *features = match->data; + struct fsl_msi_cascade_data *cascade_data = NULL; + int len; + u32 offset; printk(KERN_DEBUG "Setting up Freescale MSI support\n"); msi = kzalloc(sizeof(struct fsl_msi), GFP_KERNEL); if (!msi) { dev_err(&dev->dev, "No memory for MSI structure\n"); - err = -ENOMEM; - goto error_out; + return -ENOMEM; } + dev->dev.platform_data = msi; msi->irqhost = irq_alloc_host(dev->dev.of_node, IRQ_HOST_MAP_LINEAR, NR_MSI_IRQS, &fsl_msi_host_ops, 0); @@ -298,27 +346,47 @@ static int __devinit fsl_of_msi_probe(struct of_device *dev, err = -EINVAL; goto error_out; } + offset = 0; + p = of_get_property(dev->node, "msi-available-ranges", &len); + if (p) + offset = *p / IRQS_PER_MSI_REG; count /= sizeof(u32); - for (i = 0; i < count / 2; i++) { - if (i > NR_MSI_REG) - break; + for (i = 0; i < min(count / 2, NR_MSI_REG); i++) { virt_msir = irq_of_parse_and_map(dev->dev.of_node, i); if (virt_msir != NO_IRQ) { - set_irq_data(virt_msir, (void *)i); + cascade_data = kzalloc( + sizeof(struct fsl_msi_cascade_data), + GFP_KERNEL); + if (!cascade_data) { + dev_err(&dev->dev, + "No memory for MSI cascade data\n"); + err = -ENOMEM; + goto error_out; + } + msi->msi_virqs[i] = virt_msir; + cascade_data->index = i + offset; + cascade_data->msi_data = msi; + set_irq_data(virt_msir, (void *)cascade_data); set_irq_chained_handler(virt_msir, fsl_msi_cascade); } } - fsl_msi = msi; + list_add_tail(&msi->list, &msi_head); - WARN_ON(ppc_md.setup_msi_irqs); - ppc_md.setup_msi_irqs = fsl_setup_msi_irqs; - ppc_md.teardown_msi_irqs = fsl_teardown_msi_irqs; - ppc_md.msi_check_device = fsl_msi_check_device; + /* The multiple setting ppc_md.setup_msi_irqs will not harm things */ + if (!ppc_md.setup_msi_irqs) { + ppc_md.setup_msi_irqs = fsl_setup_msi_irqs; + ppc_md.teardown_msi_irqs = fsl_teardown_msi_irqs; + ppc_md.msi_check_device = fsl_msi_check_device; + } else if (ppc_md.setup_msi_irqs != fsl_setup_msi_irqs) { + dev_err(&dev->dev, "Different MSI driver already installed!\n"); + err = -ENODEV; + goto error_out; + } return 0; error_out: - kfree(msi); + fsl_of_msi_remove(dev); return err; } @@ -351,6 +419,7 @@ static struct of_platform_driver fsl_of_msi_driver = { .of_match_table = fsl_of_msi_ids, }, .probe = fsl_of_msi_probe, + .remove = fsl_of_msi_remove, }; static __init int fsl_of_msi_init(void) diff --git a/arch/powerpc/sysdev/fsl_msi.h b/arch/powerpc/sysdev/fsl_msi.h index 331c7e7025b7..624580c252d7 100644 --- a/arch/powerpc/sysdev/fsl_msi.h +++ b/arch/powerpc/sysdev/fsl_msi.h @@ -32,8 +32,11 @@ struct fsl_msi { u32 msi_addr_hi; void __iomem *msi_regs; u32 feature; + int msi_virqs[NR_MSI_REG]; struct msi_bitmap bitmap; + + struct list_head list; /* support multiple MSI banks */ }; #endif /* _POWERPC_SYSDEV_FSL_MSI_H */ diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c index 106d767bf65b..156aa7d36258 100644 --- a/arch/powerpc/sysdev/ppc4xx_pci.c +++ b/arch/powerpc/sysdev/ppc4xx_pci.c @@ -974,6 +974,123 @@ static struct ppc4xx_pciex_hwops ppc460ex_pcie_hwops __initdata = .setup_utl = ppc460ex_pciex_init_utl, }; +static int __init ppc460sx_pciex_core_init(struct device_node *np) +{ + /* HSS drive amplitude */ + mtdcri(SDR0, PESDR0_460SX_HSSL0DAMP, 0xB9843211); + mtdcri(SDR0, PESDR0_460SX_HSSL1DAMP, 0xB9843211); + mtdcri(SDR0, PESDR0_460SX_HSSL2DAMP, 0xB9843211); + mtdcri(SDR0, PESDR0_460SX_HSSL3DAMP, 0xB9843211); + mtdcri(SDR0, PESDR0_460SX_HSSL4DAMP, 0xB9843211); + mtdcri(SDR0, PESDR0_460SX_HSSL5DAMP, 0xB9843211); + mtdcri(SDR0, PESDR0_460SX_HSSL6DAMP, 0xB9843211); + mtdcri(SDR0, PESDR0_460SX_HSSL7DAMP, 0xB9843211); + + mtdcri(SDR0, PESDR1_460SX_HSSL0DAMP, 0xB9843211); + mtdcri(SDR0, PESDR1_460SX_HSSL1DAMP, 0xB9843211); + mtdcri(SDR0, PESDR1_460SX_HSSL2DAMP, 0xB9843211); + mtdcri(SDR0, PESDR1_460SX_HSSL3DAMP, 0xB9843211); + + mtdcri(SDR0, PESDR2_460SX_HSSL0DAMP, 0xB9843211); + mtdcri(SDR0, PESDR2_460SX_HSSL1DAMP, 0xB9843211); + mtdcri(SDR0, PESDR2_460SX_HSSL2DAMP, 0xB9843211); + mtdcri(SDR0, PESDR2_460SX_HSSL3DAMP, 0xB9843211); + + /* HSS TX pre-emphasis */ + mtdcri(SDR0, PESDR0_460SX_HSSL0COEFA, 0xDCB98987); + mtdcri(SDR0, PESDR0_460SX_HSSL1COEFA, 0xDCB98987); + mtdcri(SDR0, PESDR0_460SX_HSSL2COEFA, 0xDCB98987); + mtdcri(SDR0, PESDR0_460SX_HSSL3COEFA, 0xDCB98987); + mtdcri(SDR0, PESDR0_460SX_HSSL4COEFA, 0xDCB98987); + mtdcri(SDR0, PESDR0_460SX_HSSL5COEFA, 0xDCB98987); + mtdcri(SDR0, PESDR0_460SX_HSSL6COEFA, 0xDCB98987); + mtdcri(SDR0, PESDR0_460SX_HSSL7COEFA, 0xDCB98987); + + mtdcri(SDR0, PESDR1_460SX_HSSL0COEFA, 0xDCB98987); + mtdcri(SDR0, PESDR1_460SX_HSSL1COEFA, 0xDCB98987); + mtdcri(SDR0, PESDR1_460SX_HSSL2COEFA, 0xDCB98987); + mtdcri(SDR0, PESDR1_460SX_HSSL3COEFA, 0xDCB98987); + + mtdcri(SDR0, PESDR2_460SX_HSSL0COEFA, 0xDCB98987); + mtdcri(SDR0, PESDR2_460SX_HSSL1COEFA, 0xDCB98987); + mtdcri(SDR0, PESDR2_460SX_HSSL2COEFA, 0xDCB98987); + mtdcri(SDR0, PESDR2_460SX_HSSL3COEFA, 0xDCB98987); + + /* HSS TX calibration control */ + mtdcri(SDR0, PESDR0_460SX_HSSL1CALDRV, 0x22222222); + mtdcri(SDR0, PESDR1_460SX_HSSL1CALDRV, 0x22220000); + mtdcri(SDR0, PESDR2_460SX_HSSL1CALDRV, 0x22220000); + + /* HSS TX slew control */ + mtdcri(SDR0, PESDR0_460SX_HSSSLEW, 0xFFFFFFFF); + mtdcri(SDR0, PESDR1_460SX_HSSSLEW, 0xFFFF0000); + mtdcri(SDR0, PESDR2_460SX_HSSSLEW, 0xFFFF0000); + + udelay(100); + + /* De-assert PLLRESET */ + dcri_clrset(SDR0, PESDR0_PLLLCT2, 0x00000100, 0); + + /* Reset DL, UTL, GPL before configuration */ + mtdcri(SDR0, PESDR0_460SX_RCSSET, + PESDRx_RCSSET_RSTDL | PESDRx_RCSSET_RSTGU); + mtdcri(SDR0, PESDR1_460SX_RCSSET, + PESDRx_RCSSET_RSTDL | PESDRx_RCSSET_RSTGU); + mtdcri(SDR0, PESDR2_460SX_RCSSET, + PESDRx_RCSSET_RSTDL | PESDRx_RCSSET_RSTGU); + + udelay(100); + + /* + * If bifurcation is not enabled, u-boot would have disabled the + * third PCIe port + */ + if (((mfdcri(SDR0, PESDR1_460SX_HSSCTLSET) & 0x00000001) == + 0x00000001)) { + printk(KERN_INFO "PCI: PCIE bifurcation setup successfully.\n"); + printk(KERN_INFO "PCI: Total 3 PCIE ports are present\n"); + return 3; + } + + printk(KERN_INFO "PCI: Total 2 PCIE ports are present\n"); + return 2; +} + +static int ppc460sx_pciex_init_port_hw(struct ppc4xx_pciex_port *port) +{ + + if (port->endpoint) + dcri_clrset(SDR0, port->sdr_base + PESDRn_UTLSET2, + 0x01000000, 0); + else + dcri_clrset(SDR0, port->sdr_base + PESDRn_UTLSET2, + 0, 0x01000000); + + /*Gen-1*/ + mtdcri(SDR0, port->sdr_base + PESDRn_460SX_RCEI, 0x08000000); + + dcri_clrset(SDR0, port->sdr_base + PESDRn_RCSSET, + (PESDRx_RCSSET_RSTGU | PESDRx_RCSSET_RSTDL), + PESDRx_RCSSET_RSTPYN); + + port->has_ibpre = 1; + + return 0; +} + +static int ppc460sx_pciex_init_utl(struct ppc4xx_pciex_port *port) +{ + /* Max 128 Bytes */ + out_be32 (port->utl_base + PEUTL_PBBSZ, 0x00000000); + return 0; +} + +static struct ppc4xx_pciex_hwops ppc460sx_pcie_hwops __initdata = { + .core_init = ppc460sx_pciex_core_init, + .port_init_hw = ppc460sx_pciex_init_port_hw, + .setup_utl = ppc460sx_pciex_init_utl, +}; + #endif /* CONFIG_44x */ #ifdef CONFIG_40x @@ -1089,6 +1206,8 @@ static int __init ppc4xx_pciex_check_core_init(struct device_node *np) } if (of_device_is_compatible(np, "ibm,plb-pciex-460ex")) ppc4xx_pciex_hwops = &ppc460ex_pcie_hwops; + if (of_device_is_compatible(np, "ibm,plb-pciex-460sx")) + ppc4xx_pciex_hwops = &ppc460sx_pcie_hwops; #endif /* CONFIG_44x */ #ifdef CONFIG_40x if (of_device_is_compatible(np, "ibm,plb-pciex-405ex")) diff --git a/arch/powerpc/sysdev/ppc4xx_pci.h b/arch/powerpc/sysdev/ppc4xx_pci.h index d04e40b306fb..56d9e5deccbf 100644 --- a/arch/powerpc/sysdev/ppc4xx_pci.h +++ b/arch/powerpc/sysdev/ppc4xx_pci.h @@ -324,6 +324,64 @@ #define PESDR0_460EX_IHS2 0x036D /* + * 460SX addtional DCRs + */ +#define PESDRn_460SX_RCEI 0x02 + +#define PESDR0_460SX_HSSL0DAMP 0x320 +#define PESDR0_460SX_HSSL1DAMP 0x321 +#define PESDR0_460SX_HSSL2DAMP 0x322 +#define PESDR0_460SX_HSSL3DAMP 0x323 +#define PESDR0_460SX_HSSL4DAMP 0x324 +#define PESDR0_460SX_HSSL5DAMP 0x325 +#define PESDR0_460SX_HSSL6DAMP 0x326 +#define PESDR0_460SX_HSSL7DAMP 0x327 + +#define PESDR1_460SX_HSSL0DAMP 0x354 +#define PESDR1_460SX_HSSL1DAMP 0x355 +#define PESDR1_460SX_HSSL2DAMP 0x356 +#define PESDR1_460SX_HSSL3DAMP 0x357 + +#define PESDR2_460SX_HSSL0DAMP 0x384 +#define PESDR2_460SX_HSSL1DAMP 0x385 +#define PESDR2_460SX_HSSL2DAMP 0x386 +#define PESDR2_460SX_HSSL3DAMP 0x387 + +#define PESDR0_460SX_HSSL0COEFA 0x328 +#define PESDR0_460SX_HSSL1COEFA 0x329 +#define PESDR0_460SX_HSSL2COEFA 0x32A +#define PESDR0_460SX_HSSL3COEFA 0x32B +#define PESDR0_460SX_HSSL4COEFA 0x32C +#define PESDR0_460SX_HSSL5COEFA 0x32D +#define PESDR0_460SX_HSSL6COEFA 0x32E +#define PESDR0_460SX_HSSL7COEFA 0x32F + +#define PESDR1_460SX_HSSL0COEFA 0x358 +#define PESDR1_460SX_HSSL1COEFA 0x359 +#define PESDR1_460SX_HSSL2COEFA 0x35A +#define PESDR1_460SX_HSSL3COEFA 0x35B + +#define PESDR2_460SX_HSSL0COEFA 0x388 +#define PESDR2_460SX_HSSL1COEFA 0x389 +#define PESDR2_460SX_HSSL2COEFA 0x38A +#define PESDR2_460SX_HSSL3COEFA 0x38B + +#define PESDR0_460SX_HSSL1CALDRV 0x339 +#define PESDR1_460SX_HSSL1CALDRV 0x361 +#define PESDR2_460SX_HSSL1CALDRV 0x391 + +#define PESDR0_460SX_HSSSLEW 0x338 +#define PESDR1_460SX_HSSSLEW 0x360 +#define PESDR2_460SX_HSSSLEW 0x390 + +#define PESDR0_460SX_HSSCTLSET 0x31E +#define PESDR1_460SX_HSSCTLSET 0x352 +#define PESDR2_460SX_HSSCTLSET 0x382 + +#define PESDR0_460SX_RCSSET 0x304 +#define PESDR1_460SX_RCSSET 0x344 +#define PESDR2_460SX_RCSSET 0x374 +/* * Of the above, some are common offsets from the base */ #define PESDRn_UTLSET1 0x00 diff --git a/arch/s390/appldata/appldata_os.c b/arch/s390/appldata/appldata_os.c index 55c80ffd42b9..92f1cb745d69 100644 --- a/arch/s390/appldata/appldata_os.c +++ b/arch/s390/appldata/appldata_os.c @@ -181,7 +181,7 @@ static int __init appldata_os_init(void) goto out; } - appldata_os_data = kzalloc(max_size, GFP_DMA); + appldata_os_data = kzalloc(max_size, GFP_KERNEL | GFP_DMA); if (appldata_os_data == NULL) { rc = -ENOMEM; goto out; diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c index 639380a0c45c..22cfd634c355 100644 --- a/arch/s390/kernel/module.c +++ b/arch/s390/kernel/module.c @@ -55,8 +55,10 @@ void *module_alloc(unsigned long size) /* Free memory returned from module_alloc */ void module_free(struct module *mod, void *module_region) { - vfree(mod->arch.syminfo); - mod->arch.syminfo = NULL; + if (mod) { + vfree(mod->arch.syminfo); + mod->arch.syminfo = NULL; + } vfree(module_region); } diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 8093e6f47f49..ae3705816878 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -761,7 +761,7 @@ static int __init kvm_s390_init(void) * to hold the maximum amount of facilites. On the other hand, we * only set facilities that are known to work in KVM. */ - facilities = (unsigned long long *) get_zeroed_page(GFP_DMA); + facilities = (unsigned long long *) get_zeroed_page(GFP_KERNEL|GFP_DMA); if (!facilities) { kvm_exit(); return -ENOMEM; diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c index eff3c5989b46..702276f5e2fa 100644 --- a/arch/s390/kvm/sigp.c +++ b/arch/s390/kvm/sigp.c @@ -113,7 +113,7 @@ static int __inject_sigp_stop(struct kvm_s390_local_interrupt *li, int action) { struct kvm_s390_interrupt_info *inti; - inti = kzalloc(sizeof(*inti), GFP_KERNEL); + inti = kzalloc(sizeof(*inti), GFP_ATOMIC); if (!inti) return -ENOMEM; inti->type = KVM_S390_SIGP_STOP; diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c index eb6a2ef5f82e..4bddf8d3a150 100644 --- a/arch/s390/mm/cmm.c +++ b/arch/s390/mm/cmm.c @@ -427,7 +427,7 @@ static struct notifier_block cmm_power_notifier = { .notifier_call = cmm_power_event, }; -static int cmm_init(void) +static int __init cmm_init(void) { int rc = -ENOMEM; @@ -467,7 +467,7 @@ out_sysctl: } module_init(cmm_init); -static void cmm_exit(void) +static void __exit cmm_exit(void) { unregister_sysctl_table(cmm_sysctl_header); #ifdef CONFIG_CMM_IUCV diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c index 6409fd57eb04..3cc95dd0a3a6 100644 --- a/arch/s390/mm/extmem.c +++ b/arch/s390/mm/extmem.c @@ -105,7 +105,7 @@ static int dcss_set_subcodes(void) { #ifdef CONFIG_64BIT - char *name = kmalloc(8 * sizeof(char), GFP_DMA); + char *name = kmalloc(8 * sizeof(char), GFP_KERNEL | GFP_DMA); unsigned long rx, ry; int rc; @@ -252,12 +252,13 @@ dcss_diag_translate_rc (int vm_rc) { static int query_segment_type (struct dcss_segment *seg) { - struct qin64 *qin = kmalloc (sizeof(struct qin64), GFP_DMA); - struct qout64 *qout = kmalloc (sizeof(struct qout64), GFP_DMA); - - int diag_cc, rc, i; unsigned long dummy, vmrc; + int diag_cc, rc, i; + struct qout64 *qout; + struct qin64 *qin; + qin = kmalloc(sizeof(*qin), GFP_KERNEL | GFP_DMA); + qout = kmalloc(sizeof(*qout), GFP_KERNEL | GFP_DMA); if ((qin == NULL) || (qout == NULL)) { rc = -ENOMEM; goto out_free; @@ -286,7 +287,7 @@ query_segment_type (struct dcss_segment *seg) copy data for the new format. */ if (segext_scode == DCSS_SEGEXT) { struct qout64_old *qout_old; - qout_old = kzalloc(sizeof(struct qout64_old), GFP_DMA); + qout_old = kzalloc(sizeof(*qout_old), GFP_KERNEL | GFP_DMA); if (qout_old == NULL) { rc = -ENOMEM; goto out_free; @@ -407,11 +408,11 @@ segment_overlaps_others (struct dcss_segment *seg) static int __segment_load (char *name, int do_nonshared, unsigned long *addr, unsigned long *end) { - struct dcss_segment *seg = kmalloc(sizeof(struct dcss_segment), - GFP_DMA); - int rc, diag_cc; unsigned long start_addr, end_addr, dummy; + struct dcss_segment *seg; + int rc, diag_cc; + seg = kmalloc(sizeof(*seg), GFP_KERNEL | GFP_DMA); if (seg == NULL) { rc = -ENOMEM; goto out; diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index 49714258732e..3845258242ac 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c @@ -26,7 +26,6 @@ #include <linux/mmc/host.h> #include <linux/input.h> #include <linux/input/sh_keysc.h> -#include <linux/mfd/sh_mobile_sdhi.h> #include <video/sh_mobile_lcdc.h> #include <sound/sh_fsi.h> #include <media/sh_mobile_ceu.h> diff --git a/arch/sh/kernel/dwarf.c b/arch/sh/kernel/dwarf.c index 886d7d83ace3..49c09c7d5b77 100644 --- a/arch/sh/kernel/dwarf.c +++ b/arch/sh/kernel/dwarf.c @@ -49,6 +49,8 @@ static DEFINE_SPINLOCK(dwarf_fde_lock); static struct dwarf_cie *cached_cie; +static unsigned int dwarf_unwinder_ready; + /** * dwarf_frame_alloc_reg - allocate memory for a DWARF register * @frame: the DWARF frame whose list of registers we insert on @@ -582,6 +584,13 @@ struct dwarf_frame *dwarf_unwind_stack(unsigned long pc, unsigned long addr; /* + * If we've been called in to before initialization has + * completed, bail out immediately. + */ + if (!dwarf_unwinder_ready) + return NULL; + + /* * If we're starting at the top of the stack we need get the * contents of a physical register to get the CFA in order to * begin the virtual unwinding of the stack. @@ -1167,7 +1176,7 @@ void module_dwarf_cleanup(struct module *mod) */ static int __init dwarf_unwinder_init(void) { - int err; + int err = -ENOMEM; dwarf_frame_cachep = kmem_cache_create("dwarf_frames", sizeof(struct dwarf_frame), 0, @@ -1181,11 +1190,15 @@ static int __init dwarf_unwinder_init(void) mempool_alloc_slab, mempool_free_slab, dwarf_frame_cachep); + if (!dwarf_frame_pool) + goto out; dwarf_reg_pool = mempool_create(DWARF_REG_MIN_REQ, mempool_alloc_slab, mempool_free_slab, dwarf_reg_cachep); + if (!dwarf_reg_pool) + goto out; err = dwarf_parse_section(__start_eh_frame, __stop_eh_frame, NULL); if (err) @@ -1195,11 +1208,13 @@ static int __init dwarf_unwinder_init(void) if (err) goto out; + dwarf_unwinder_ready = 1; + return 0; out: printk(KERN_ERR "Failed to initialise DWARF unwinder: %d\n", err); dwarf_unwinder_cleanup(); - return -EINVAL; + return err; } early_initcall(dwarf_unwinder_init); diff --git a/arch/sh/kernel/return_address.c b/arch/sh/kernel/return_address.c index cbf1dd5372b2..5124aeb28c3f 100644 --- a/arch/sh/kernel/return_address.c +++ b/arch/sh/kernel/return_address.c @@ -24,6 +24,8 @@ void *return_address(unsigned int depth) struct dwarf_frame *tmp; tmp = dwarf_unwind_stack(ra, frame); + if (!tmp) + return NULL; if (frame) dwarf_free_frame(frame); diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h index 8d8797eae5d7..08b92bc18fcb 100644 --- a/arch/x86/include/asm/pci_x86.h +++ b/arch/x86/include/asm/pci_x86.h @@ -30,6 +30,7 @@ #define PCI_HAS_IO_ECS 0x40000 #define PCI_NOASSIGN_ROMS 0x80000 #define PCI_ROOT_NO_CRS 0x100000 +#define PCI_NOASSIGN_BARS 0x200000 extern unsigned int pci_probe; extern unsigned long pirq_table_addr; diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index 215a27ae050d..a0772af64efb 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c @@ -125,6 +125,23 @@ void __init dmi_check_skip_isa_align(void) static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) { struct resource *rom_r = &dev->resource[PCI_ROM_RESOURCE]; + struct resource *bar_r; + int bar; + + if (pci_probe & PCI_NOASSIGN_BARS) { + /* + * If the BIOS did not assign the BAR, zero out the + * resource so the kernel doesn't attmept to assign + * it later on in pci_assign_unassigned_resources + */ + for (bar = 0; bar <= PCI_STD_RESOURCE_END; bar++) { + bar_r = &dev->resource[bar]; + if (bar_r->start == 0 && bar_r->end != 0) { + bar_r->flags = 0; + bar_r->end = 0; + } + } + } if (pci_probe & PCI_NOASSIGN_ROMS) { if (rom_r->parent) @@ -509,6 +526,9 @@ char * __devinit pcibios_setup(char *str) } else if (!strcmp(str, "norom")) { pci_probe |= PCI_NOASSIGN_ROMS; return NULL; + } else if (!strcmp(str, "nobar")) { + pci_probe |= PCI_NOASSIGN_BARS; + return NULL; } else if (!strcmp(str, "assign-busses")) { pci_probe |= PCI_ASSIGN_ALL_BUSSES; return NULL; diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index ebe228d02b08..52e5dbbb1941 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -84,10 +84,10 @@ config XTENSA_VARIANT_S6000 endchoice config XTENSA_UNALIGNED_USER - bool "Unaligned memory access in use space" + bool "Unaligned memory access in user space" help - The Xtensa architecture currently does not handle unaligned - memory accesses in hardware but through an exception handler. + Xtensa processors are often not configured to handle unaligned + memory accesses in hardware, but rather through an exception handler. Per default, unaligned memory accesses are disabled in user space. Say Y here to enable unaligned memory access in user space. @@ -157,8 +157,15 @@ config XTENSA_PLATFORM_ISS config XTENSA_PLATFORM_XT2000 bool "XT2000" help - XT2000 is the name of Tensilica's feature-rich emulation platform. - This hardware is capable of running a full Linux distribution. + XT2000 is the name of Tensilica's older emulation platform. + +config XTENSA_PLATFORM_XTAVNET + bool "XTAVNET" + select XTENSA_CALIBRATE_CCOUNT + select ETHOC + help + Selects support for the Tensilica-configured Avnet emulation boards. + These include the LX60 (XT-AV60), LX200 (XT-AV200), and LX110 (XT-AV110). config XTENSA_PLATFORM_S6105 bool "S6105" diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile index 4caffac3ca2e..34d8427622eb 100644 --- a/arch/xtensa/Makefile +++ b/arch/xtensa/Makefile @@ -24,6 +24,7 @@ export VARIANT # Platform configuration platform-$(CONFIG_XTENSA_PLATFORM_XT2000) := xt2000 +platform-$(CONFIG_XTENSA_PLATFORM_XTAVNET) := xtavnet platform-$(CONFIG_XTENSA_PLATFORM_ISS) := iss platform-$(CONFIG_XTENSA_PLATFORM_S6105) := s6105 @@ -35,6 +36,8 @@ KBUILD_CFLAGS += -ffreestanding KBUILD_CFLAGS += -pipe -mlongcalls +KBUILD_CFLAGS += $(call cc-option,-mforce-no-pic,) + vardirs := $(patsubst %,arch/xtensa/variants/%/,$(variant-y)) plfdirs := $(patsubst %,arch/xtensa/platforms/%/,$(platform-y)) @@ -59,7 +62,9 @@ ifneq ($(VARIANT),) ifneq ($(COMPILE_ARCH), xtensa) ifndef CROSS_COMPILE - CROSS_COMPILE = xtensa_$(VARIANT)- + CROSS_COMPILE := $(call cc-cross-prefix, xtensa_$(VARIANT)- \ + xtensa-linux-uclibc- xtensa_$(VARIANT)-linux-uclibc- \ + xtensa-linux-gnu- xtensa_$(VARIANT)-linux-gnu-) endif endif endif diff --git a/arch/xtensa/boot/Makefile b/arch/xtensa/boot/Makefile index 40aa55b485be..8657c62fc78b 100644 --- a/arch/xtensa/boot/Makefile +++ b/arch/xtensa/boot/Makefile @@ -23,6 +23,7 @@ subdir-y := lib bootdir-$(CONFIG_XTENSA_PLATFORM_ISS) += boot-elf bootdir-$(CONFIG_XTENSA_PLATFORM_XT2000) += boot-redboot boot-elf +bootdir-$(CONFIG_XTENSA_PLATFORM_XTAVNET) += boot-redboot boot-elf zImage zImage.initrd Image Image.initrd: $(bootdir-y) diff --git a/arch/xtensa/configs/iss_defconfig b/arch/xtensa/configs/iss_defconfig index f19854035e61..61bac9d62255 100644 --- a/arch/xtensa/configs/iss_defconfig +++ b/arch/xtensa/configs/iss_defconfig @@ -77,6 +77,7 @@ CONFIG_XTENSA_ISS_NETWORK=y # # Bus options # +CONFIG_PCI=n # # PCCARD (PCMCIA/CardBus) support diff --git a/arch/xtensa/include/asm/cacheflush.h b/arch/xtensa/include/asm/cacheflush.h index a508f2f73bd7..376cd9d5f455 100644 --- a/arch/xtensa/include/asm/cacheflush.h +++ b/arch/xtensa/include/asm/cacheflush.h @@ -115,6 +115,7 @@ extern void flush_cache_page(struct vm_area_struct*, unsigned long, unsigned lon #define flush_cache_vmap(start,end) do { } while (0) #define flush_cache_vunmap(start,end) do { } while (0) +#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0 #define flush_dcache_page(page) do { } while (0) #define flush_cache_page(vma,addr,pfn) do { } while (0) diff --git a/arch/xtensa/include/asm/coprocessor.h b/arch/xtensa/include/asm/coprocessor.h index 65a285d8d3fb..04bc285df1a7 100644 --- a/arch/xtensa/include/asm/coprocessor.h +++ b/arch/xtensa/include/asm/coprocessor.h @@ -1,11 +1,11 @@ /* - * include/asm-xtensa/coprocessor.h + * arch/xtensa/include/asm/coprocessor.h * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2003 - 2007 Tensilica Inc. + * Copyright (C) 2003-2010 Tensilica Inc. */ @@ -14,9 +14,10 @@ #include <linux/stringify.h> #include <variant/tie.h> +#include <variant/core.h> #include <asm/types.h> -#ifdef __ASSEMBLY__ +#if defined(__ASSEMBLY__) && !defined(LINKER_SCRIPT) # include <variant/tie-asm.h> .macro xchal_sa_start a b @@ -69,7 +70,7 @@ -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLY__ && !LINKER_SCRIPT */ /* * XTENSA_HAVE_COPROCESSOR(x) returns 1 if coprocessor x is configured. diff --git a/arch/xtensa/include/asm/elf.h b/arch/xtensa/include/asm/elf.h index 5eb6d695e987..6e65eadaae14 100644 --- a/arch/xtensa/include/asm/elf.h +++ b/arch/xtensa/include/asm/elf.h @@ -14,6 +14,7 @@ #define _XTENSA_ELF_H #include <asm/ptrace.h> +#include <asm/coprocessor.h> /* Xtensa processor ELF architecture-magic number */ diff --git a/arch/xtensa/include/asm/io.h b/arch/xtensa/include/asm/io.h index d04cd3a625fa..145db5cc6191 100644 --- a/arch/xtensa/include/asm/io.h +++ b/arch/xtensa/include/asm/io.h @@ -1,11 +1,11 @@ /* - * include/asm-xtensa/io.h + * arch/xtensa/include/asm/io.h * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2001 - 2005 Tensilica Inc. + * Copyright (C) 2001-2010 Tensilica Inc. */ #ifndef _XTENSA_IO_H @@ -63,40 +63,33 @@ static inline void * phys_to_virt(unsigned long address) #define bus_to_virt(x) phys_to_virt(x) /* - * Return the virtual (cached) address for the specified bus memory. + * Return the virtual (uncached) address for the specified bus memory + * (which is, for now, simply a physical address). * Note that we currently don't support any address outside the KIO segment. + * See also arch/mips/include/asm/io.h for nice comments. */ -static inline void *ioremap(unsigned long offset, unsigned long size) +static inline void __iomem *__ioremap(unsigned long offset, unsigned long size) { #ifdef CONFIG_MMU if (offset >= XCHAL_KIO_PADDR - && offset < XCHAL_KIO_PADDR + XCHAL_KIO_SIZE) - return (void*)(offset-XCHAL_KIO_PADDR+XCHAL_KIO_BYPASS_VADDR); + && offset <= XCHAL_KIO_PADDR + XCHAL_KIO_SIZE - 1) + return (void __iomem *)(offset - XCHAL_KIO_PADDR + XCHAL_KIO_BYPASS_VADDR); else BUG(); #else - return (void *)offset; + return (void __iomem *)offset; #endif } -static inline void *ioremap_nocache(unsigned long offset, unsigned long size) -{ -#ifdef CONFIG_MMU - if (offset >= XCHAL_KIO_PADDR - && offset < XCHAL_KIO_PADDR + XCHAL_KIO_SIZE) - return (void*)(offset-XCHAL_KIO_PADDR+XCHAL_KIO_CACHED_VADDR); - else - BUG(); -#else - return (void *)offset; -#endif -} +#define ioremap(offset, size) __ioremap(offset, size) +#define ioremap_nocache(offset, size) __ioremap(offset, size) -static inline void iounmap(void *addr) +static inline void iounmap(void __iomem *addr) { } + /* * Generic I/O */ @@ -191,6 +184,13 @@ extern void outsl (unsigned long port, const void *src, unsigned long count); #endif +#ifndef CONFIG_GENERIC_IOMAP +/* Partial Simple MMIO */ +#define ioread32(a) __raw_readl(a) +#define iowrite32(v,a) __raw_writel((v),(a)) +#endif + + /* * Convert a physical pointer to a virtual kernel pointer for /dev/mem access */ diff --git a/arch/xtensa/include/asm/irq.h b/arch/xtensa/include/asm/irq.h index 4c0ccc9c4f4c..6af436f4429d 100644 --- a/arch/xtensa/include/asm/irq.h +++ b/arch/xtensa/include/asm/irq.h @@ -1,11 +1,11 @@ /* - * include/asm-xtensa/irq.h + * arch/xtensa/include/asm/irq.h * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2001 - 2005 Tensilica Inc. + * Copyright (C) 2001-2010 Tensilica Inc. */ #ifndef _XTENSA_IRQ_H @@ -22,6 +22,9 @@ static inline void variant_irq_enable(unsigned int irq) { } static inline void variant_irq_disable(unsigned int irq) { } #endif +/* This number is used when no interrupt has been assigned. */ +#define NO_IRQ (-1) + #ifndef VARIANT_NR_IRQS # define VARIANT_NR_IRQS 0 #endif diff --git a/arch/xtensa/include/asm/pgalloc.h b/arch/xtensa/include/asm/pgalloc.h index 4f4a7987eded..40cf9bceda2c 100644 --- a/arch/xtensa/include/asm/pgalloc.h +++ b/arch/xtensa/include/asm/pgalloc.h @@ -14,6 +14,7 @@ #ifdef __KERNEL__ #include <linux/highmem.h> +#include <linux/slab.h> /* * Allocating and freeing a pmd is trivial: the 1-entry pmd is diff --git a/arch/xtensa/include/asm/processor.h b/arch/xtensa/include/asm/processor.h index 0ea4937c0b61..3acb26e8dead 100644 --- a/arch/xtensa/include/asm/processor.h +++ b/arch/xtensa/include/asm/processor.h @@ -12,7 +12,6 @@ #define _XTENSA_PROCESSOR_H #include <variant/core.h> -#include <asm/coprocessor.h> #include <platform/hardware.h> #include <linux/compiler.h> diff --git a/arch/xtensa/include/asm/ptrace.h b/arch/xtensa/include/asm/ptrace.h index 3c549f798727..0d42c934b66f 100644 --- a/arch/xtensa/include/asm/ptrace.h +++ b/arch/xtensa/include/asm/ptrace.h @@ -77,6 +77,8 @@ #ifndef __ASSEMBLY__ +#include <asm/coprocessor.h> + /* * This struct defines the way the registers are stored on the * kernel stack during a system call or other kernel entry. diff --git a/arch/xtensa/include/asm/serial.h b/arch/xtensa/include/asm/serial.h index a8a2493260f6..c55a0e2b47ca 100644 --- a/arch/xtensa/include/asm/serial.h +++ b/arch/xtensa/include/asm/serial.h @@ -1,5 +1,5 @@ /* - * include/asm-xtensa/serial.h + * arch/xtensa/include/asm/serial.h * * Configuration details for 8250, 16450, 16550, etc. serial ports * @@ -7,12 +7,20 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2001 - 2005 Tensilica Inc. + * Copyright (C) 2001-2010 Tensilica Inc. */ #ifndef _XTENSA_SERIAL_H #define _XTENSA_SERIAL_H +#include <asm/irq.h> #include <platform/serial.h> +/* The 8250 driver treats IRQ 0 as absent. For the Xtensa architecture, + interrupt 0 is valid, must compare against NO_IRQ instead. */ +#ifdef is_real_interrupt +#undef is_real_interrupt +#define is_real_interrupt(irq) ((irq) != NO_IRQ) +#endif + #endif /* _XTENSA_SERIAL_H */ diff --git a/arch/xtensa/kernel/Makefile b/arch/xtensa/kernel/Makefile index 6f56d95f2c1e..e426a4ec7f22 100644 --- a/arch/xtensa/kernel/Makefile +++ b/arch/xtensa/kernel/Makefile @@ -23,12 +23,12 @@ obj-$(CONFIG_MODULES) += xtensa_ksyms.o module.o # # Replicate rules in scripts/Makefile.build -sed-y = -e 's/(\(\.[a-z]*it\|\.ref\|\)\.text)/(\1.literal \1.text)/g' \ - -e 's/(\(\.text\.[a-z]*\))/(\1.literal \1)/g' +sed-y = -e 's/\*(\(\.[a-z]*it\|\.ref\|\)\.text)/*(\1.literal \1.text)/g' \ + -e 's/\*(\(\.text\.[a-z]*\))/*(\1.literal \1)/g' quiet_cmd__cpp_lds_S = LDS $@ - cmd__cpp_lds_S = $(CPP) $(cpp_flags) -P -C -Uxtensa -D__ASSEMBLY__ $< \ - | sed $(sed-y) >$@ + cmd__cpp_lds_S = $(CPP) $(cpp_flags) -P -C -Uxtensa -D__ASSEMBLY__ \ + -DLINKER_SCRIPT $< | sed $(sed-y) >$@ $(obj)/vmlinux.lds: $(src)/vmlinux.lds.S FORCE $(call if_changed_dep,_cpp_lds_S) diff --git a/arch/xtensa/kernel/asm-offsets.c b/arch/xtensa/kernel/asm-offsets.c index 070ff8af3a21..7dc3f9157185 100644 --- a/arch/xtensa/kernel/asm-offsets.c +++ b/arch/xtensa/kernel/asm-offsets.c @@ -13,6 +13,7 @@ */ #include <asm/processor.h> +#include <asm/coprocessor.h> #include <linux/types.h> #include <linux/stddef.h> diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index 77fc9f6dc016..5fd01f6aaf37 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S @@ -16,6 +16,7 @@ #include <linux/linkage.h> #include <asm/asm-offsets.h> #include <asm/processor.h> +#include <asm/coprocessor.h> #include <asm/thread_info.h> #include <asm/uaccess.h> #include <asm/unistd.h> diff --git a/arch/xtensa/kernel/head.S b/arch/xtensa/kernel/head.S index d215adcfd4ea..3ef91a73652d 100644 --- a/arch/xtensa/kernel/head.S +++ b/arch/xtensa/kernel/head.S @@ -184,8 +184,8 @@ _startup: * Now clear the BSS segment. */ - movi a2, _bss_start # start of BSS - movi a3, _bss_end # end of BSS + movi a2, __bss_start # start of BSS + movi a3, __bss_stop # end of BSS __loopt a2, a3, a4, 2 s32i a0, a2, 0 diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c index 19df764f6399..88ba96e2df25 100644 --- a/arch/xtensa/kernel/time.c +++ b/arch/xtensa/kernel/time.c @@ -31,7 +31,7 @@ unsigned long ccount_per_jiffy; /* per 1/HZ */ unsigned long nsec_per_ccount; /* nsec per ccount increment */ #endif -static cycle_t ccount_read(void) +static cycle_t ccount_read(struct clocksource *cs) { return (cycle_t)get_ccount(); } diff --git a/arch/xtensa/platforms/iss/network.c b/arch/xtensa/platforms/iss/network.c index 87e218f98ef4..f717e20d961b 100644 --- a/arch/xtensa/platforms/iss/network.c +++ b/arch/xtensa/platforms/iss/network.c @@ -623,6 +623,19 @@ static struct platform_driver iss_net_driver = { static int driver_registered; +static const struct net_device_ops iss_netdev_ops = { + .ndo_open = iss_net_open, + .ndo_stop = iss_net_close, + .ndo_get_stats = iss_net_get_stats, + .ndo_start_xmit = iss_net_start_xmit, + .ndo_validate_addr = eth_validate_addr, + .ndo_change_mtu = iss_net_change_mtu, + .ndo_set_mac_address = iss_net_set_mac, + //.ndo_do_ioctl = iss_net_ioctl, + .ndo_tx_timeout = iss_net_tx_timeout, + .ndo_set_multicast_list = iss_net_set_multicast_list, +}; + static int iss_net_configure(int index, char *init) { struct net_device *dev; @@ -686,15 +699,8 @@ static int iss_net_configure(int index, char *init) */ snprintf(dev->name, sizeof dev->name, "eth%d", index); + dev->netdev_ops = &iss_netdev_ops; dev->mtu = lp->mtu; - dev->open = iss_net_open; - dev->hard_start_xmit = iss_net_start_xmit; - dev->stop = iss_net_close; - dev->get_stats = iss_net_get_stats; - dev->set_multicast_list = iss_net_set_multicast_list; - dev->tx_timeout = iss_net_tx_timeout; - dev->set_mac_address = iss_net_set_mac; - dev->change_mtu = iss_net_change_mtu; dev->watchdog_timeo = (HZ >> 1); dev->irq = -1; diff --git a/arch/xtensa/platforms/xtavnet/Makefile b/arch/xtensa/platforms/xtavnet/Makefile new file mode 100644 index 000000000000..06b120b40015 --- /dev/null +++ b/arch/xtensa/platforms/xtavnet/Makefile @@ -0,0 +1,10 @@ +# Makefile for the Tensilica Avnet-based Emulation Boards +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# +# Note 2! The CFLAGS definitions are in the main makefile... + +obj-y = setup.o lcd.o + diff --git a/arch/xtensa/platforms/xtavnet/include/platform/hardware.h b/arch/xtensa/platforms/xtavnet/include/platform/hardware.h new file mode 100644 index 000000000000..5301be745113 --- /dev/null +++ b/arch/xtensa/platforms/xtavnet/include/platform/hardware.h @@ -0,0 +1,85 @@ +/* + * arch/xtensa/platforms/xtavnet/include/platform/hardware.h + * + * This file contains the hardware configuration of Tensilica Avnet boards + * (XT-AV60, XT-AV110, XT-AV200, derived from Avnet LX60, LX110, LX200 + * boards respectively). + * + * Copyright (C) 2006-2010 Tensilica Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef __XTAVNET_HARDWARE_H +#define __XTAVNET_HARDWARE_H + +#include <variant/core.h> + +/* Memory configuration. */ + +#define PLATFORM_DEFAULT_MEM_START 0x00000000 +#define PLATFORM_DEFAULT_MEM_SIZE 0x04000000 + +/* Interrupt configuration. */ + +#define PLATFORM_NR_IRQS 2 + +/* + * Default assignment of XTAVnet devices to external interrupts. + * + * CONFIG_ARCH_HAS_SMP means the hardware supports SMP, ie. is Xtensa MX. + * + * Systems with SMP support (MX) have an External Interrupt Distributor + * between external interrupts and the core's interrupts. The first three + * core interrupts are used for IPI (interprocessor interrupts), so + * external (board device) interrupts end up shifted up by 3. + */ + +/* UART interrupt: */ +#ifdef CONFIG_ARCH_HAS_SMP +#define UART_INTNUM XCHAL_EXTINT3_NUM +#else +#define UART_INTNUM XCHAL_EXTINT0_NUM +#endif + +/* Ethernet interrupt: */ +#ifdef CONFIG_ARCH_HAS_SMP +#define OETH_IRQ XCHAL_EXTINT4_NUM +#else +#define OETH_IRQ XCHAL_EXTINT1_NUM +#endif + +/* + * Device addresses and parameters. + */ + +/* UART */ +#define UART_PADDR 0xFD050020 + +/* LCD instruction and data virt. addresses. */ +#define LCD_INSTR_ADDR (char*)(0xFD040000) +#define LCD_DATA_ADDR (char*)(0xFD040004) + +/* Misc. */ +#define XTAVNET_FPGAREGS_VADDR 0xFD020000 +/* Clock frequency in Hz (read-only): */ +#define XTAVNET_CLKFRQ_VADDR (XTAVNET_FPGAREGS_VADDR + 0x04) +/* Setting of 8 DIP switches: */ +#define DIP_SWITCHES_VADDR (XTAVNET_FPGAREGS_VADDR + 0x0C) +/* Software reset (write 0xdead): */ +#define XTAVNET_SWRST_VADDR (XTAVNET_FPGAREGS_VADDR + 0x10) + +/* OpenCores Ethernet controller: */ +#define OETH_REGS_PADDR IOADDR(0xD030000) /* regs + RX/TX descriptors */ +#define OETH_REGS_VADDR 0xFD030000 +#define OETH_REGS_SIZE 0x1000 +#define OETH_SRAMBUFF_PADDR 0xFD800000 +#define OETH_SRAMBUFF_SIZE (5*0x600 + 5*0x600) /* 5*rx buffs + 5*tx buffs */ +/*#define OETH_SRAMBUFF_SIZE 0x3C00*/ /* probably 0x4000 ? */ +/* The MAC address for these boards is 00:50:c2:13:6f:xx. + The last byte (here as zero) is read from the DIP switches on the board. */ +#define OETH_MACADDR 0x00, 0x50, 0xc2, 0x13, 0x6f, 0 + +#endif /* __XTAVNET_HARDWARE_H */ diff --git a/arch/xtensa/platforms/xtavnet/include/platform/lcd.h b/arch/xtensa/platforms/xtavnet/include/platform/lcd.h new file mode 100644 index 000000000000..67de96acb2f9 --- /dev/null +++ b/arch/xtensa/platforms/xtavnet/include/platform/lcd.h @@ -0,0 +1,22 @@ +/* + * arch/xtensa/platforms/xtavnet/include/platform/lcd.h + * + * Copyright (C) 2001-2006 Tensilica Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef __XTAVNET_LCD_H +#define __XTAVNET_LCD_H + +/* Display string STR at position POS on the LCD. */ +void lcd_disp_at_pos(char *str, unsigned char pos); + +/* Shift the contents of the LCD display left or right. */ +void lcd_shiftleft(void); +void lcd_shiftright(void); + +#endif + diff --git a/arch/xtensa/platforms/xtavnet/include/platform/serial.h b/arch/xtensa/platforms/xtavnet/include/platform/serial.h new file mode 100644 index 000000000000..a0cb0caff152 --- /dev/null +++ b/arch/xtensa/platforms/xtavnet/include/platform/serial.h @@ -0,0 +1 @@ +#include <asm-generic/serial.h> diff --git a/arch/xtensa/platforms/xtavnet/lcd.c b/arch/xtensa/platforms/xtavnet/lcd.c new file mode 100644 index 000000000000..283986f158ad --- /dev/null +++ b/arch/xtensa/platforms/xtavnet/lcd.c @@ -0,0 +1,79 @@ +/* + * Driver for the LCD display on the Tensilica LX60 Board. + * This code has no effect on the LX200 board. (LX110: TBD) + * + * Copyright (C) 2001-2006 Tensilica Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +/* + * + * FIXME: this code is from the examples from the LX60 user guide. + * + * The lcd_pause function does busy waiting, which is probably not + * great. Maybe the code could be changed to use kernel timers, or + * change the hardware to not need to wait. + */ + +#include <linux/init.h> + +#include <platform/hardware.h> +#include <asm/processor.h> +#include <platform/lcd.h> +#include <linux/delay.h> + +#define LCD_PAUSE_ITERATIONS 4000 +#define LCD_CLEAR 0x1 +#define LCD_DISPLAY_ON 0xc + +/* 8bit and 2 lines display */ +#define LCD_DISPLAY_MODE8BIT 0x38 +#define LCD_DISPLAY_POS 0x80 +#define LCD_SHIFT_LEFT 0x18 +#define LCD_SHIFT_RIGHT 0x1c + +static int __init lcd_init(void) +{ + *LCD_INSTR_ADDR = LCD_DISPLAY_MODE8BIT; + mdelay(5); + *LCD_INSTR_ADDR = LCD_DISPLAY_MODE8BIT; + udelay(200); + *LCD_INSTR_ADDR = LCD_DISPLAY_MODE8BIT; + udelay(50); + *LCD_INSTR_ADDR = LCD_DISPLAY_ON; + udelay(50); + *LCD_INSTR_ADDR = LCD_CLEAR; + mdelay(10); + lcd_disp_at_pos("XTENSA LINUX", 0); + + return 0; +} + +void lcd_disp_at_pos (char *str, unsigned char pos) +{ + *LCD_INSTR_ADDR = LCD_DISPLAY_POS | pos; + udelay(100); + while (*str != 0){ + *LCD_DATA_ADDR = *str; + udelay(200); + str++; + } +} + +void lcd_shiftleft(void) +{ + *LCD_INSTR_ADDR = LCD_SHIFT_LEFT; + udelay(50); +} + +void lcd_shiftright(void) +{ + *LCD_INSTR_ADDR = LCD_SHIFT_RIGHT; + udelay(50); +} + +arch_initcall(lcd_init); + diff --git a/arch/xtensa/platforms/xtavnet/setup.c b/arch/xtensa/platforms/xtavnet/setup.c new file mode 100644 index 000000000000..256fcb2b2af4 --- /dev/null +++ b/arch/xtensa/platforms/xtavnet/setup.c @@ -0,0 +1,269 @@ +/* + * arch/xtensa/platform-xtavnet/setup.c + * + * Setup/initialization for Tensilica Avnet boards (XT-AV60, XT-AV110, XT-AV200, + * derived from Avnet LX60, LX110, LX200 boards respectively). + * For details, see "Tensilica Avnet LX### (XT-AV###) Board User's Guide" + * (where ### is 60, 110, or 200). + * + * Authors: Chris Zankel <chris@zankel.net> + * Joe Taylor <joe@tensilica.com> + * Pete Delaney <piet@tensilica.com> + * Marc Gauthier <marc@tensilica.com> <marc@alumni.uwaterloo.ca> + * + * Copyright 2001-2010 Tensilica Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License, version 2. See the file "COPYING" in the main directory of this + * archive for more details. + */ + +#include <linux/stddef.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/errno.h> +#include <linux/reboot.h> +#include <linux/kdev_t.h> +#include <linux/types.h> +#include <linux/major.h> +#include <linux/console.h> +#include <linux/delay.h> +#include <linux/stringify.h> +#include <linux/platform_device.h> +#include <linux/serial_8250.h> +#include <asm/timex.h> + +#include <linux/etherdevice.h> +#include <net/ethoc.h> + +#include <asm/processor.h> +#include <asm/platform.h> +#include <asm/bootparam.h> +#include <platform/lcd.h> +#include <platform/hardware.h> +#include <variant/core.h> + +/* For doing extra init. beyond what the ethoc driver does. */ +struct oeth_regs { + unsigned moder; /* Mode Register */ + unsigned int_src; /* Interrupt Source Register */ + unsigned int_mask; /* Interrupt Mask Register */ + unsigned ipgt; /* Back to Bak Inter Packet Gap Register */ + unsigned ipgr1; /* Non Back to Back Inter Packet Gap Register 1 */ + unsigned ipgr2; /* Non Back to Back Inter Packet Gap Register 2 */ + unsigned packet_len; /* Packet Length Register (min. and max.) */ + unsigned collconf; /* Collision and Retry Configuration Register */ + unsigned tx_bd_num; /* Transmit Buffer Descriptor Number Register */ + unsigned ctrlmoder; /* Control Module Mode Register */ + unsigned miimoder; /* MII Mode Register */ + unsigned miicommand; /* MII Command Register */ + unsigned miiaddress; /* MII Address Register */ + unsigned miitx_data; /* MII Transmit Data Register */ + unsigned miirx_data; /* MII Receive Data Register */ + unsigned miistatus; /* MII Status Register */ + unsigned mac_addr0; /* MAC Individual Address Register 0 */ + unsigned mac_addr1; /* MAC Individual Address Register 1 */ + unsigned hash_addr0; /* Hash Register 0 */ + unsigned hash_addr1; /* Hash Register 1 */ +}; +/* MODER Register */ +#define OETH_MODER_RST 0x00000800 /* Reset MAC */ +/* MII Mode Register */ +#define OETH_MIIMODER_CLKDIV 0x000000FF /* Clock Divider */ + + + +void platform_halt(void) +{ + /* Just display HALT on LCD display, and loop. */ + lcd_disp_at_pos(" HALT ", 0); + local_irq_disable(); + while (1); +} + +void platform_power_off(void) +{ + /* No software-controlled power-off, just display POWEROFF and loop. */ + lcd_disp_at_pos ("POWEROFF", 0); + local_irq_disable(); + while (1); +} + +void platform_restart(void) +{ + /* Software-initiated board reset. */ + *(volatile unsigned *)XTAVNET_SWRST_VADDR = 0xdead; +} + +void platform_heartbeat(void) +{ + /* Executes every timer tick. */ +} + + +/* + * Called from time_init(). "Calibrating" is a misnomer, here we just read + * the clock rate from the board specific FPGA registers. + */ +void platform_calibrate_ccount(void) +{ + long clk_freq = *(long *)XTAVNET_CLKFRQ_VADDR; + + ccount_per_jiffy = clk_freq / HZ; + nsec_per_ccount = 1000000000UL / clk_freq; +} + + +/*---------------------------------------------------------------------------- + * Ethernet -- OpenCores Ethernet MAC (ethoc driver) + */ + +static struct resource ethoc_res[] = { + [0] = { /* register space */ + .start = OETH_REGS_PADDR, + .end = OETH_REGS_PADDR + OETH_REGS_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { /* buffer space */ + .start = OETH_SRAMBUFF_PADDR, + .end = OETH_SRAMBUFF_PADDR + OETH_SRAMBUFF_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [2] = { /* IRQ number */ + .start = OETH_IRQ, + .end = OETH_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct ethoc_platform_data ethoc_pdata = { + .hwaddr = { OETH_MACADDR }, /* last byte written in setup below */ + .phy_id = -1, +}; + +static struct platform_device ethoc_device = { + .name = "ethoc", + .id = -1, + .num_resources = ARRAY_SIZE(ethoc_res), + .resource = ethoc_res, + .dev = { + .platform_data = ðoc_pdata, + }, +}; + + +/*---------------------------------------------------------------------------- + * UART + */ + +static struct resource serial_resource = { + .start = UART_PADDR, + .end = UART_PADDR + 0x1f, + .flags = IORESOURCE_MEM, +}; + +static struct plat_serial8250_port serial_platform_data[] = { + [0] = { + .mapbase = UART_PADDR, + .irq = UART_INTNUM, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, + .iotype = UPIO_MEM32, + .regshift = 2, + .uartclk = 0, /* set in xtavnet_init() */ + }, + { }, +}; + +static struct platform_device xtavnet_uart = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev = { + .platform_data = serial_platform_data, + }, + .num_resources = 1, + .resource = &serial_resource, +}; + + +/*---------------------------------------------------------------------------- + */ + +/* platform devices */ +static struct platform_device *platform_devices[] = { + ðoc_device, + &xtavnet_uart, +}; + + + +/* very early init */ +void __init platform_setup(char **cmdline) +{ + if (cmdline) { + if (cmdline[0]) + printk("XTAVnet: platform_setup(cmdline[0]:'%s')\n", cmdline[0]); + else + printk("XTAVnet: platform_setup(cmdline[0]:<null>)\n"); + } +} + +/* early initialization, before secondary cpu's have been brought up */ + +void platform_init(bp_tag_t *bootparams) +{ + printk("\n"); + if( bootparams ) + printk("XTAVnet: platform_init(bootparams:0x%x)\n", (unsigned)bootparams); +} + +static int xtavnet_init(void) +{ + volatile struct oeth_regs *regs = (volatile struct oeth_regs*)OETH_REGS_VADDR; + + /* + * Do some of the initialization missing in the ETHOC driver. + * (Perhaps not all necessary, but was in a previously used driver.) + */ + + /* Reset the controller. */ + regs->moder = OETH_MODER_RST; /* Reset ON */ + regs->moder &= ~OETH_MODER_RST; /* Reset OFF */ + + regs->packet_len = (64 << 16) | 1536; + regs->ipgr1 = 0x0000000c; + regs->ipgr2 = 0x00000012; + regs->collconf = 0x000f003f; + regs->ctrlmoder = 0; + regs->miimoder = (OETH_MIIMODER_CLKDIV & 0x2); + + /* + * Setup dynamic info in platform device init structures. + */ + + /* Ethernet MAC address. */ + ethoc_pdata.hwaddr[5] = *(u32*)DIP_SWITCHES_VADDR; + + /* Clock rate varies among FPGA bitstreams; board specific FPGA register + * reports the actual clock rate. */ + serial_platform_data[0].uartclk = *(long *)XTAVNET_CLKFRQ_VADDR; + + + /* register platform devices */ + platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); + + /* ETHOC driver is a bit quiet; at least display Ethernet MAC, so user + knows whether they set it correctly on the DIP switches. */ + printk("XTAVnet: Ethernet MAC %02x:%02x:%02x:%02x:%02x:%02x\n", + ethoc_pdata.hwaddr[0], ethoc_pdata.hwaddr[1], ethoc_pdata.hwaddr[2], + ethoc_pdata.hwaddr[3], ethoc_pdata.hwaddr[4], ethoc_pdata.hwaddr[5]); + + return 0; +} + + +/* + * Register to be done during do_initcalls(). + */ +arch_initcall(xtavnet_init); + + diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c index db3946e9c66b..216e1e948ff6 100644 --- a/drivers/acpi/apei/apei-base.c +++ b/drivers/acpi/apei/apei-base.c @@ -34,6 +34,7 @@ #include <linux/module.h> #include <linux/init.h> #include <linux/acpi.h> +#include <linux/slab.h> #include <linux/io.h> #include <linux/kref.h> #include <linux/rculist.h> diff --git a/drivers/acpi/atomicio.c b/drivers/acpi/atomicio.c index 814b19249616..8f8bd736d4ff 100644 --- a/drivers/acpi/atomicio.c +++ b/drivers/acpi/atomicio.c @@ -31,6 +31,7 @@ #include <linux/kref.h> #include <linux/rculist.h> #include <linux/interrupt.h> +#include <linux/slab.h> #include <acpi/atomicio.h> #define ACPI_PFX "ACPI: " diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 9e01e96fee94..8344375dc015 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -128,7 +128,7 @@ config TXX9_DMAC config SH_DMAE tristate "Renesas SuperH DMAC support" - depends on SUPERH && SH_DMA + depends on (SUPERH && SH_DMA) || (ARM && ARCH_SHMOBILE) depends on !SH_DMA_API select DMA_ENGINE help diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index a2a519fd2a24..fb64cf36ba61 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c @@ -816,7 +816,7 @@ static irqreturn_t sh_dmae_interrupt(int irq, void *data) return ret; } -#if defined(CONFIG_CPU_SH4) +#if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE) static irqreturn_t sh_dmae_err(int irq, void *data) { struct sh_dmae_device *shdev = (struct sh_dmae_device *)data; @@ -1057,7 +1057,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev) /* Default transfer size of 32 bytes requires 32-byte alignment */ shdev->common.copy_align = LOG2_DEFAULT_XFER_SIZE; -#if defined(CONFIG_CPU_SH4) +#if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE) chanirq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 1); if (!chanirq_res) @@ -1082,7 +1082,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev) #else chanirq_res = errirq_res; -#endif /* CONFIG_CPU_SH4 */ +#endif /* CONFIG_CPU_SH4 || CONFIG_ARCH_SHMOBILE */ if (chanirq_res->start == chanirq_res->end && !platform_get_resource(pdev, IORESOURCE_IRQ, 1)) { @@ -1129,7 +1129,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev) chan_probe_err: sh_dmae_chan_remove(shdev); eirqres: -#if defined(CONFIG_CPU_SH4) +#if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE) free_irq(errirq, shdev); eirq_err: #endif diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 87ab0568bb0e..dec387d3f04d 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -529,7 +529,7 @@ config I2C_SH7760 config I2C_SH_MOBILE tristate "SuperH Mobile I2C Controller" - depends on SUPERH + depends on SUPERH || ARCH_SHMOBILE help If you say yes to this option, support will be included for the built-in I2C interface on the Renesas SH-Mobile processor. diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c index ffb405d7c6f2..598c49acaeb5 100644 --- a/drivers/i2c/busses/i2c-sh_mobile.c +++ b/drivers/i2c/busses/i2c-sh_mobile.c @@ -119,8 +119,10 @@ struct sh_mobile_i2c_data { struct i2c_adapter adap; struct clk *clk; + u_int8_t icic; u_int8_t iccl; u_int8_t icch; + u_int8_t flags; spinlock_t lock; wait_queue_head_t wait; @@ -129,15 +131,17 @@ struct sh_mobile_i2c_data { int sr; }; +#define IIC_FLAG_HAS_ICIC67 (1 << 0) + #define NORMAL_SPEED 100000 /* FAST_SPEED 400000 */ /* Register offsets */ -#define ICDR(pd) (pd->reg + 0x00) -#define ICCR(pd) (pd->reg + 0x04) -#define ICSR(pd) (pd->reg + 0x08) -#define ICIC(pd) (pd->reg + 0x0c) -#define ICCL(pd) (pd->reg + 0x10) -#define ICCH(pd) (pd->reg + 0x14) +#define ICDR 0x00 +#define ICCR 0x04 +#define ICSR 0x08 +#define ICIC 0x0c +#define ICCL 0x10 +#define ICCH 0x14 /* Register bits */ #define ICCR_ICE 0x80 @@ -155,11 +159,32 @@ struct sh_mobile_i2c_data { #define ICSR_WAIT 0x02 #define ICSR_DTE 0x01 +#define ICIC_ICCLB8 0x80 +#define ICIC_ICCHB8 0x40 #define ICIC_ALE 0x08 #define ICIC_TACKE 0x04 #define ICIC_WAITE 0x02 #define ICIC_DTEE 0x01 +static void iic_wr(struct sh_mobile_i2c_data *pd, int offs, unsigned char data) +{ + if (offs == ICIC) + data |= pd->icic; + + iowrite8(data, pd->reg + offs); +} + +static unsigned char iic_rd(struct sh_mobile_i2c_data *pd, int offs) +{ + return ioread8(pd->reg + offs); +} + +static void iic_set_clr(struct sh_mobile_i2c_data *pd, int offs, + unsigned char set, unsigned char clr) +{ + iic_wr(pd, offs, (iic_rd(pd, offs) | set) & ~clr); +} + static void activate_ch(struct sh_mobile_i2c_data *pd) { unsigned long i2c_clk; @@ -187,6 +212,14 @@ static void activate_ch(struct sh_mobile_i2c_data *pd) else pd->iccl = (u_int8_t)(num/denom); + /* one more bit of ICCL in ICIC */ + if (pd->flags & IIC_FLAG_HAS_ICIC67) { + if ((num/denom) > 0xff) + pd->icic |= ICIC_ICCLB8; + else + pd->icic &= ~ICIC_ICCLB8; + } + /* Calculate the value for icch. From the data sheet: icch = (p clock / transfer rate) * (H / (L + H)) */ num = i2c_clk * 4; @@ -196,25 +229,33 @@ static void activate_ch(struct sh_mobile_i2c_data *pd) else pd->icch = (u_int8_t)(num/denom); + /* one more bit of ICCH in ICIC */ + if (pd->flags & IIC_FLAG_HAS_ICIC67) { + if ((num/denom) > 0xff) + pd->icic |= ICIC_ICCHB8; + else + pd->icic &= ~ICIC_ICCHB8; + } + /* Enable channel and configure rx ack */ - iowrite8(ioread8(ICCR(pd)) | ICCR_ICE, ICCR(pd)); + iic_set_clr(pd, ICCR, ICCR_ICE, 0); /* Mask all interrupts */ - iowrite8(0, ICIC(pd)); + iic_wr(pd, ICIC, 0); /* Set the clock */ - iowrite8(pd->iccl, ICCL(pd)); - iowrite8(pd->icch, ICCH(pd)); + iic_wr(pd, ICCL, pd->iccl); + iic_wr(pd, ICCH, pd->icch); } static void deactivate_ch(struct sh_mobile_i2c_data *pd) { /* Clear/disable interrupts */ - iowrite8(0, ICSR(pd)); - iowrite8(0, ICIC(pd)); + iic_wr(pd, ICSR, 0); + iic_wr(pd, ICIC, 0); /* Disable channel */ - iowrite8(ioread8(ICCR(pd)) & ~ICCR_ICE, ICCR(pd)); + iic_set_clr(pd, ICCR, 0, ICCR_ICE); /* Disable clock and mark device as idle */ clk_disable(pd->clk); @@ -233,35 +274,35 @@ static unsigned char i2c_op(struct sh_mobile_i2c_data *pd, switch (op) { case OP_START: /* issue start and trigger DTE interrupt */ - iowrite8(0x94, ICCR(pd)); + iic_wr(pd, ICCR, 0x94); break; case OP_TX_FIRST: /* disable DTE interrupt and write data */ - iowrite8(ICIC_WAITE | ICIC_ALE | ICIC_TACKE, ICIC(pd)); - iowrite8(data, ICDR(pd)); + iic_wr(pd, ICIC, ICIC_WAITE | ICIC_ALE | ICIC_TACKE); + iic_wr(pd, ICDR, data); break; case OP_TX: /* write data */ - iowrite8(data, ICDR(pd)); + iic_wr(pd, ICDR, data); break; case OP_TX_STOP: /* write data and issue a stop afterwards */ - iowrite8(data, ICDR(pd)); - iowrite8(0x90, ICCR(pd)); + iic_wr(pd, ICDR, data); + iic_wr(pd, ICCR, 0x90); break; case OP_TX_TO_RX: /* select read mode */ - iowrite8(0x81, ICCR(pd)); + iic_wr(pd, ICCR, 0x81); break; case OP_RX: /* just read data */ - ret = ioread8(ICDR(pd)); + ret = iic_rd(pd, ICDR); break; case OP_RX_STOP: /* enable DTE interrupt, issue stop */ - iowrite8(ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE, - ICIC(pd)); - iowrite8(0xc0, ICCR(pd)); + iic_wr(pd, ICIC, + ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE); + iic_wr(pd, ICCR, 0xc0); break; case OP_RX_STOP_DATA: /* enable DTE interrupt, read data, issue stop */ - iowrite8(ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE, - ICIC(pd)); - ret = ioread8(ICDR(pd)); - iowrite8(0xc0, ICCR(pd)); + iic_wr(pd, ICIC, + ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE); + ret = iic_rd(pd, ICDR); + iic_wr(pd, ICCR, 0xc0); break; } @@ -367,7 +408,7 @@ static irqreturn_t sh_mobile_i2c_isr(int irq, void *dev_id) unsigned char sr; int wakeup; - sr = ioread8(ICSR(pd)); + sr = iic_rd(pd, ICSR); pd->sr |= sr; /* remember state */ dev_dbg(pd->dev, "i2c_isr 0x%02x 0x%02x %s %d %d!\n", sr, pd->sr, @@ -376,7 +417,7 @@ static irqreturn_t sh_mobile_i2c_isr(int irq, void *dev_id) if (sr & (ICSR_AL | ICSR_TACK)) { /* don't interrupt transaction - continue to issue stop */ - iowrite8(sr & ~(ICSR_AL | ICSR_TACK), ICSR(pd)); + iic_wr(pd, ICSR, sr & ~(ICSR_AL | ICSR_TACK)); wakeup = 0; } else if (pd->msg->flags & I2C_M_RD) wakeup = sh_mobile_i2c_isr_rx(pd); @@ -384,7 +425,7 @@ static irqreturn_t sh_mobile_i2c_isr(int irq, void *dev_id) wakeup = sh_mobile_i2c_isr_tx(pd); if (sr & ICSR_WAIT) /* TODO: add delay here to support slow acks */ - iowrite8(sr & ~ICSR_WAIT, ICSR(pd)); + iic_wr(pd, ICSR, sr & ~ICSR_WAIT); if (wakeup) { pd->sr |= SW_DONE; @@ -402,21 +443,21 @@ static int start_ch(struct sh_mobile_i2c_data *pd, struct i2c_msg *usr_msg) } /* Initialize channel registers */ - iowrite8(ioread8(ICCR(pd)) & ~ICCR_ICE, ICCR(pd)); + iic_set_clr(pd, ICCR, 0, ICCR_ICE); /* Enable channel and configure rx ack */ - iowrite8(ioread8(ICCR(pd)) | ICCR_ICE, ICCR(pd)); + iic_set_clr(pd, ICCR, ICCR_ICE, 0); /* Set the clock */ - iowrite8(pd->iccl, ICCL(pd)); - iowrite8(pd->icch, ICCH(pd)); + iic_wr(pd, ICCL, pd->iccl); + iic_wr(pd, ICCH, pd->icch); pd->msg = usr_msg; pd->pos = -1; pd->sr = 0; /* Enable all interrupts to begin with */ - iowrite8(ICIC_WAITE | ICIC_ALE | ICIC_TACKE | ICIC_DTEE, ICIC(pd)); + iic_wr(pd, ICIC, ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE); return 0; } @@ -451,7 +492,7 @@ static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter, retry_count = 1000; again: - val = ioread8(ICSR(pd)); + val = iic_rd(pd, ICSR); dev_dbg(pd->dev, "val 0x%02x pd->sr 0x%02x\n", val, pd->sr); @@ -576,6 +617,12 @@ static int sh_mobile_i2c_probe(struct platform_device *dev) goto err_irq; } + /* The IIC blocks on SH-Mobile ARM processors + * come with two new bits in ICIC. + */ + if (size > 0x17) + pd->flags |= IIC_FLAG_HAS_ICIC67; + /* Enable Runtime PM for this device. * * Also tell the Runtime PM core to ignore children diff --git a/drivers/infiniband/hw/qib/qib_fs.c b/drivers/infiniband/hw/qib/qib_fs.c index edef8527eb34..844954bf417b 100644 --- a/drivers/infiniband/hw/qib/qib_fs.c +++ b/drivers/infiniband/hw/qib/qib_fs.c @@ -542,10 +542,8 @@ static int qibfs_fill_super(struct super_block *sb, void *data, int silent) list_for_each_entry_safe(dd, tmp, &qib_dev_list, list) { spin_unlock_irqrestore(&qib_devs_lock, flags); ret = add_cntr_files(sb, dd); - if (ret) { - deactivate_super(sb); + if (ret) goto bail; - } spin_lock_irqsave(&qib_devs_lock, flags); } diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.c b/drivers/isdn/hardware/mISDN/hfcsusb.c index b3b7e2879bac..8700474747e8 100644 --- a/drivers/isdn/hardware/mISDN/hfcsusb.c +++ b/drivers/isdn/hardware/mISDN/hfcsusb.c @@ -97,8 +97,10 @@ static int write_reg(struct hfcsusb *hw, __u8 reg, __u8 val) hw->name, __func__, reg, val); spin_lock(&hw->ctrl_lock); - if (hw->ctrl_cnt >= HFC_CTRL_BUFSIZE) + if (hw->ctrl_cnt >= HFC_CTRL_BUFSIZE) { + spin_unlock(&hw->ctrl_lock); return 1; + } buf = &hw->ctrl_buff[hw->ctrl_in_idx]; buf->hfcs_reg = reg; buf->reg_val = val; diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index e171e77f6129..f06d06e7fdfa 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -249,7 +249,7 @@ config MMC_IMX config MMC_MSM7X00A tristate "Qualcomm MSM 7X00A SDCC Controller Support" - depends on MMC && ARCH_MSM + depends on MMC && ARCH_MSM && !ARCH_MSM7X30 help This provides support for the SD/MMC cell found in the MSM 7X00A controllers from Qualcomm. diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index d9d4a72e0ec7..fdf33e837a73 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c @@ -119,6 +119,7 @@ struct mxcmci_host { int detect_irq; int dma; int do_dma; + int default_irq_mask; int use_sdio; unsigned int power_mode; struct imxmmc_platform_data *pdata; @@ -228,7 +229,7 @@ static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data) static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_command *cmd, unsigned int cmdat) { - u32 int_cntr; + u32 int_cntr = host->default_irq_mask; unsigned long flags; WARN_ON(host->cmd != NULL); @@ -275,7 +276,7 @@ static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_command *cmd, static void mxcmci_finish_request(struct mxcmci_host *host, struct mmc_request *req) { - u32 int_cntr = 0; + u32 int_cntr = host->default_irq_mask; unsigned long flags; spin_lock_irqsave(&host->lock, flags); @@ -585,6 +586,9 @@ static irqreturn_t mxcmci_irq(int irq, void *devid) (stat & (STATUS_DATA_TRANS_DONE | STATUS_WRITE_OP_DONE))) mxcmci_data_done(host, stat); #endif + if (host->default_irq_mask && + (stat & (STATUS_CARD_INSERTION | STATUS_CARD_REMOVAL))) + mmc_detect_change(host->mmc, msecs_to_jiffies(200)); return IRQ_HANDLED; } @@ -809,6 +813,12 @@ static int mxcmci_probe(struct platform_device *pdev) else mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; + if (host->pdata && host->pdata->dat3_card_detect) + host->default_irq_mask = + INT_CARD_INSERTION_EN | INT_CARD_REMOVAL_EN; + else + host->default_irq_mask = 0; + host->res = r; host->irq = irq; @@ -835,7 +845,7 @@ static int mxcmci_probe(struct platform_device *pdev) /* recommended in data sheet */ writew(0x2db4, host->base + MMC_REG_READ_TO); - writel(0, host->base + MMC_REG_INT_CNTR); + writel(host->default_irq_mask, host->base + MMC_REG_INT_CNTR); #ifdef HAS_DMA host->dma = imx_dma_request_by_prio(DRIVER_NAME, DMA_PRIO_LOW); diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 82e94389824e..0d76b169482f 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -623,8 +623,7 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, else host->buf_start = column + mtd->writesize; - if (mtd->writesize > 512) - command = NAND_CMD_READ0; /* only READ0 is valid */ + command = NAND_CMD_READ0; /* only READ0 is valid */ send_cmd(host, command, false); mxc_do_addr_cycle(mtd, column, page_addr); @@ -639,31 +638,11 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, break; case NAND_CMD_SEQIN: - if (column >= mtd->writesize) { - /* - * FIXME: before send SEQIN command for write OOB, - * We must read one page out. - * For K9F1GXX has no READ1 command to set current HW - * pointer to spare area, we must write the whole page - * including OOB together. - */ - if (mtd->writesize > 512) - /* call ourself to read a page */ - mxc_nand_command(mtd, NAND_CMD_READ0, 0, - page_addr); - - host->buf_start = column; - - /* Set program pointer to spare region */ - if (mtd->writesize == 512) - send_cmd(host, NAND_CMD_READOOB, false); - } else { - host->buf_start = column; + if (column >= mtd->writesize) + /* call ourself to read a page */ + mxc_nand_command(mtd, NAND_CMD_READ0, 0, page_addr); - /* Set program pointer to page start */ - if (mtd->writesize == 512) - send_cmd(host, NAND_CMD_READ0, false); - } + host->buf_start = column; send_cmd(host, command, false); mxc_do_addr_cycle(mtd, column, page_addr); @@ -853,6 +832,8 @@ static int __init mxcnd_probe(struct platform_device *pdev) parse_mtd_partitions(mtd, part_probes, &host->parts, 0); if (nr_parts > 0) add_mtd_partitions(mtd, host->parts, nr_parts); + else if (pdata->parts) + add_mtd_partitions(mtd, pdata->parts, pdata->nr_parts); else #endif { diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 9d11dbf5e4da..9e305d7fb4bd 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -1429,7 +1429,7 @@ int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd, wrb = wrb_from_mccq(adapter); if (!wrb) { status = -EBUSY; - goto err; + goto err_unlock; } req = cmd->va; sge = nonembedded_sgl(wrb); @@ -1457,7 +1457,10 @@ int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd, else status = adapter->flash_status; -err: + return status; + +err_unlock: + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -1497,7 +1500,7 @@ err: return status; } -extern int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac, +int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac, struct be_dma_mem *nonemb_cmd) { struct be_mcc_wrb *wrb; @@ -1662,7 +1665,7 @@ err: return status; } -extern int be_cmd_get_seeprom_data(struct be_adapter *adapter, +int be_cmd_get_seeprom_data(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd) { struct be_mcc_wrb *wrb; diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c index 5d45084b287d..48e91b6242ce 100644 --- a/drivers/net/fs_enet/mac-fcc.c +++ b/drivers/net/fs_enet/mac-fcc.c @@ -504,17 +504,54 @@ static int get_regs_len(struct net_device *dev) } /* Some transmit errors cause the transmitter to shut - * down. We now issue a restart transmit. Since the - * errors close the BD and update the pointers, the restart - * _should_ pick up without having to reset any of our - * pointers either. Also, To workaround 8260 device erratum - * CPM37, we must disable and then re-enable the transmitter - * following a Late Collision, Underrun, or Retry Limit error. + * down. We now issue a restart transmit. + * Also, to workaround 8260 device erratum CPM37, we must + * disable and then re-enable the transmitterfollowing a + * Late Collision, Underrun, or Retry Limit error. + * In addition, tbptr may point beyond BDs beyond still marked + * as ready due to internal pipelining, so we need to look back + * through the BDs and adjust tbptr to point to the last BD + * marked as ready. This may result in some buffers being + * retransmitted. */ static void tx_restart(struct net_device *dev) { struct fs_enet_private *fep = netdev_priv(dev); fcc_t __iomem *fccp = fep->fcc.fccp; + const struct fs_platform_info *fpi = fep->fpi; + fcc_enet_t __iomem *ep = fep->fcc.ep; + cbd_t __iomem *curr_tbptr; + cbd_t __iomem *recheck_bd; + cbd_t __iomem *prev_bd; + cbd_t __iomem *last_tx_bd; + + last_tx_bd = fep->tx_bd_base + (fpi->tx_ring * sizeof(cbd_t)); + + /* get the current bd held in TBPTR and scan back from this point */ + recheck_bd = curr_tbptr = (cbd_t __iomem *) + ((R32(ep, fen_genfcc.fcc_tbptr) - fep->ring_mem_addr) + + fep->ring_base); + + prev_bd = (recheck_bd == fep->tx_bd_base) ? last_tx_bd : recheck_bd - 1; + + /* Move through the bds in reverse, look for the earliest buffer + * that is not ready. Adjust TBPTR to the following buffer */ + while ((CBDR_SC(prev_bd) & BD_ENET_TX_READY) != 0) { + /* Go back one buffer */ + recheck_bd = prev_bd; + + /* update the previous buffer */ + prev_bd = (prev_bd == fep->tx_bd_base) ? last_tx_bd : prev_bd - 1; + + /* We should never see all bds marked as ready, check anyway */ + if (recheck_bd == curr_tbptr) + break; + } + /* Now update the TBPTR and dirty flag to the current buffer */ + W32(ep, fen_genfcc.fcc_tbptr, + (uint) (((void *)recheck_bd - fep->ring_base) + + fep->ring_mem_addr)); + fep->dirty_tx = recheck_bd; C32(fccp, fcc_gfmr, FCC_GFMR_ENT); udelay(10); diff --git a/drivers/net/mac8390.c b/drivers/net/mac8390.c index 1136c9a22b67..c7476a45c3ea 100644 --- a/drivers/net/mac8390.c +++ b/drivers/net/mac8390.c @@ -157,6 +157,8 @@ static void dayna_block_output(struct net_device *dev, int count, #define memcpy_fromio(a, b, c) memcpy((a), (void *)(b), (c)) #define memcpy_toio(a, b, c) memcpy((void *)(a), (b), (c)) +#define memcmp_withio(a, b, c) memcmp((a), (void *)(b), (c)) + /* Slow Sane (16-bit chunk memory read/write) Cabletron uses this */ static void slow_sane_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); @@ -164,8 +166,8 @@ static void slow_sane_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); static void slow_sane_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page); -static void word_memcpy_tocard(void *tp, const void *fp, int count); -static void word_memcpy_fromcard(void *tp, const void *fp, int count); +static void word_memcpy_tocard(unsigned long tp, const void *fp, int count); +static void word_memcpy_fromcard(void *tp, unsigned long fp, int count); static enum mac8390_type __init mac8390_ident(struct nubus_dev *dev) { @@ -245,9 +247,9 @@ static enum mac8390_access __init mac8390_testio(volatile unsigned long membase) unsigned long outdata = 0xA5A0B5B0; unsigned long indata = 0x00000000; /* Try writing 32 bits */ - memcpy(membase, &outdata, 4); + memcpy_toio(membase, &outdata, 4); /* Now compare them */ - if (memcmp((char *)&outdata, (char *)membase, 4) == 0) + if (memcmp_withio(&outdata, membase, 4) == 0) return ACCESS_32; /* Write 16 bit output */ word_memcpy_tocard(membase, &outdata, 4); @@ -731,7 +733,7 @@ static void sane_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { unsigned long hdr_start = (ring_page - WD_START_PG)<<8; - memcpy_fromio((void *)hdr, (char *)dev->mem_start + hdr_start, 4); + memcpy_fromio(hdr, dev->mem_start + hdr_start, 4); /* Fix endianness */ hdr->count = swab16(hdr->count); } @@ -745,14 +747,13 @@ static void sane_block_input(struct net_device *dev, int count, if (xfer_start + count > ei_status.rmem_end) { /* We must wrap the input move. */ int semi_count = ei_status.rmem_end - xfer_start; - memcpy_fromio(skb->data, (char *)dev->mem_start + xfer_base, + memcpy_fromio(skb->data, dev->mem_start + xfer_base, semi_count); count -= semi_count; - memcpy_toio(skb->data + semi_count, - (char *)ei_status.rmem_start, count); - } else { - memcpy_fromio(skb->data, (char *)dev->mem_start + xfer_base, + memcpy_fromio(skb->data + semi_count, ei_status.rmem_start, count); + } else { + memcpy_fromio(skb->data, dev->mem_start + xfer_base, count); } } @@ -761,7 +762,7 @@ static void sane_block_output(struct net_device *dev, int count, { long shmem = (start_page - WD_START_PG)<<8; - memcpy_toio((char *)dev->mem_start + shmem, buf, count); + memcpy_toio(dev->mem_start + shmem, buf, count); } /* dayna block input/output */ @@ -812,7 +813,7 @@ static void slow_sane_get_8390_hdr(struct net_device *dev, int ring_page) { unsigned long hdr_start = (ring_page - WD_START_PG)<<8; - word_memcpy_fromcard(hdr, (char *)dev->mem_start + hdr_start, 4); + word_memcpy_fromcard(hdr, dev->mem_start + hdr_start, 4); /* Register endianism - fix here rather than 8390.c */ hdr->count = (hdr->count&0xFF)<<8|(hdr->count>>8); } @@ -826,15 +827,14 @@ static void slow_sane_block_input(struct net_device *dev, int count, if (xfer_start + count > ei_status.rmem_end) { /* We must wrap the input move. */ int semi_count = ei_status.rmem_end - xfer_start; - word_memcpy_fromcard(skb->data, - (char *)dev->mem_start + xfer_base, + word_memcpy_fromcard(skb->data, dev->mem_start + xfer_base, semi_count); count -= semi_count; word_memcpy_fromcard(skb->data + semi_count, - (char *)ei_status.rmem_start, count); + ei_status.rmem_start, count); } else { - word_memcpy_fromcard(skb->data, - (char *)dev->mem_start + xfer_base, count); + word_memcpy_fromcard(skb->data, dev->mem_start + xfer_base, + count); } } @@ -843,12 +843,12 @@ static void slow_sane_block_output(struct net_device *dev, int count, { long shmem = (start_page - WD_START_PG)<<8; - word_memcpy_tocard((char *)dev->mem_start + shmem, buf, count); + word_memcpy_tocard(dev->mem_start + shmem, buf, count); } -static void word_memcpy_tocard(void *tp, const void *fp, int count) +static void word_memcpy_tocard(unsigned long tp, const void *fp, int count) { - volatile unsigned short *to = tp; + volatile unsigned short *to = (void *)tp; const unsigned short *from = fp; count++; @@ -858,10 +858,10 @@ static void word_memcpy_tocard(void *tp, const void *fp, int count) *to++ = *from++; } -static void word_memcpy_fromcard(void *tp, const void *fp, int count) +static void word_memcpy_fromcard(void *tp, unsigned long fp, int count) { unsigned short *to = tp; - const volatile unsigned short *from = fp; + const volatile unsigned short *from = (const void *)fp; count++; count /= 2; diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c index 82ab532a4923..a93dc18a45c3 100644 --- a/drivers/net/wireless/ath/ar9170/usb.c +++ b/drivers/net/wireless/ath/ar9170/usb.c @@ -739,17 +739,27 @@ err_out: static void ar9170_usb_firmware_failed(struct ar9170_usb *aru) { struct device *parent = aru->udev->dev.parent; + struct usb_device *udev; + + /* + * Store a copy of the usb_device pointer locally. + * This is because device_release_driver initiates + * ar9170_usb_disconnect, which in turn frees our + * driver context (aru). + */ + udev = aru->udev; complete(&aru->firmware_loading_complete); /* unbind anything failed */ if (parent) device_lock(parent); - device_release_driver(&aru->udev->dev); + + device_release_driver(&udev->dev); if (parent) device_unlock(parent); - usb_put_dev(aru->udev); + usb_put_dev(udev); } static void ar9170_usb_firmware_finish(const struct firmware *fw, void *context) diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 3db19172b43b..859aa4ab0769 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1198,7 +1198,7 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) int r; ath_print(common, ATH_DBG_FATAL, - "Unable to stop TxDMA. Reset HAL!\n"); + "Failed to stop TX DMA. Resetting hardware!\n"); spin_lock_bh(&sc->sc_resetlock); r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false); @@ -1728,6 +1728,8 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, } else bf->bf_isnullfunc = false; + bf->bf_tx_aborted = false; + return 0; } @@ -1989,7 +1991,7 @@ static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf, int nbad = 0; int isaggr = 0; - if (bf->bf_tx_aborted) + if (bf->bf_lastbf->bf_tx_aborted) return 0; isaggr = bf_isaggr(bf); diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c index a115bfa9513a..7a377f5b7662 100644 --- a/drivers/net/wireless/libertas/rx.c +++ b/drivers/net/wireless/libertas/rx.c @@ -329,9 +329,8 @@ static int process_rxed_802_11_packet(struct lbs_private *priv, /* create the exported radio header */ /* radiotap header */ - radiotap_hdr.hdr.it_version = 0; - /* XXX must check this value for pad */ - radiotap_hdr.hdr.it_pad = 0; + memset(&radiotap_hdr, 0, sizeof(radiotap_hdr)); + /* XXX must check radiotap_hdr.hdr.it_pad for pad */ radiotap_hdr.hdr.it_len = cpu_to_le16 (sizeof(struct rx_radiotap_hdr)); radiotap_hdr.hdr.it_present = cpu_to_le32 (RX_RADIOTAP_PRESENT); radiotap_hdr.rate = convert_mv_rate_to_radiotap(prxpd->rx_rate); diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 699161327d65..0f8b84b7224c 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -413,7 +413,7 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, */ rt2x00_desc_read(txi, 0, &word); rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN, - skb->len - TXINFO_DESC_SIZE); + skb->len + TXWI_DESC_SIZE); rt2x00_set_field32(&word, TXINFO_W0_WIV, !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags)); rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2); diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c index 5f5e8d2e3552..d3985e7deab7 100644 --- a/drivers/pci/hotplug/shpchp_hpc.c +++ b/drivers/pci/hotplug/shpchp_hpc.c @@ -113,7 +113,7 @@ #define CON_PFAULT_INTR_MASK (1 << 28) #define MRL_CHANGE_SERR_MASK (1 << 29) #define CON_PFAULT_SERR_MASK (1 << 30) -#define SLOT_REG_RSVDZ_MASK (1 << 15) | (7 << 21) +#define SLOT_REG_RSVDZ_MASK ((1 << 15) | (7 << 21)) /* * SHPC Command Code definitnions diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index 8af4f619bba2..fc0b5a93e1de 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c @@ -727,20 +727,21 @@ static void aer_isr_one_error(struct pcie_device *p_device, static int get_e_source(struct aer_rpc *rpc, struct aer_err_source *e_src) { unsigned long flags; - int ret = 0; /* Lock access to Root error producer/consumer index */ spin_lock_irqsave(&rpc->e_lock, flags); - if (rpc->prod_idx != rpc->cons_idx) { - *e_src = rpc->e_sources[rpc->cons_idx]; - rpc->cons_idx++; - if (rpc->cons_idx == AER_ERROR_SOURCES_MAX) - rpc->cons_idx = 0; - ret = 1; + if (rpc->prod_idx == rpc->cons_idx) { + spin_unlock_irqrestore(&rpc->e_lock, flags); + return 0; } + + *e_src = rpc->e_sources[rpc->cons_idx]; + rpc->cons_idx++; + if (rpc->cons_idx == AER_ERROR_SOURCES_MAX) + rpc->cons_idx = 0; spin_unlock_irqrestore(&rpc->e_lock, flags); - return ret; + return 1; } /** diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index b7512cf08c58..f213fecf1d47 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -2112,6 +2112,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS480, quirk_disabl DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3336, quirk_disable_all_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3351, quirk_disable_all_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3364, quirk_disable_all_msi); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8380_0, quirk_disable_all_msi); /* Disable MSI on chipsets that are known to not support it */ static void __devinit quirk_disable_msi(struct pci_dev *dev) @@ -2123,12 +2124,29 @@ static void __devinit quirk_disable_msi(struct pci_dev *dev) } } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_msi); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x9602, quirk_disable_msi); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ASUSTEK, 0x9602, quirk_disable_msi); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AI, 0x9602, quirk_disable_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, 0xa238, quirk_disable_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x5a3f, quirk_disable_msi); +/* + * The APC bridge device in AMD 780 family northbridges has some random + * OEM subsystem ID in its vendor ID register (erratum 18), so instead + * we use the possible vendor/device IDs of the host bridge for the + * declared quirk, and search for the APC bridge by slot number. + */ +static void __devinit quirk_amd_780_apc_msi(struct pci_dev *host_bridge) +{ + struct pci_dev *apc_bridge; + + apc_bridge = pci_get_slot(host_bridge->bus, PCI_DEVFN(1, 0)); + if (apc_bridge) { + if (apc_bridge->device == 0x9602) + quirk_disable_msi(apc_bridge); + pci_dev_put(apc_bridge); + } +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x9600, quirk_amd_780_apc_msi); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x9601, quirk_amd_780_apc_msi); + /* Go through the list of Hypertransport capabilities and * return 1 if a HT MSI capability is found and enabled */ static int __devinit msi_ht_cap_enabled(struct pci_dev *dev) diff --git a/drivers/rtc/rtc-davinci.c b/drivers/rtc/rtc-davinci.c index 92a8f6cacda9..34647fc1ee98 100644 --- a/drivers/rtc/rtc-davinci.c +++ b/drivers/rtc/rtc-davinci.c @@ -29,6 +29,7 @@ #include <linux/bcd.h> #include <linux/platform_device.h> #include <linux/io.h> +#include <linux/slab.h> /* * The DaVinci RTC is a simple RTC with the following diff --git a/drivers/s390/cio/itcw.c b/drivers/s390/cio/itcw.c index 17da9ab932ed..a0ae29564774 100644 --- a/drivers/s390/cio/itcw.c +++ b/drivers/s390/cio/itcw.c @@ -42,7 +42,7 @@ * size_t size; * * size = itcw_calc_size(1, 2, 0); - * buffer = kmalloc(size, GFP_DMA); + * buffer = kmalloc(size, GFP_KERNEL | GFP_DMA); * if (!buffer) * return -ENOMEM; * itcw = itcw_init(buffer, size, ITCW_OP_READ, 1, 2, 0); diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c index 30463862603b..9330edb323e2 100644 --- a/drivers/serial/68328serial.c +++ b/drivers/serial/68328serial.c @@ -78,10 +78,6 @@ struct m68k_serial *m68k_consinfo = 0; #define M68K_CLOCK (16667000) /* FIXME: 16MHz is likely wrong */ -#ifdef CONFIG_CONSOLE -extern wait_queue_head_t keypress_wait; -#endif - struct tty_driver *serial_driver; /* number of characters left in xmit buffer before we ask for more */ @@ -300,10 +296,6 @@ static void receive_chars(struct m68k_serial *info, unsigned short rx) return; #endif /* CONFIG_MAGIC_SYSRQ */ } - /* It is a 'keyboard interrupt' ;-) */ -#ifdef CONFIG_CONSOLE - wake_up(&keypress_wait); -#endif } if(!tty) diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c index 84a35f699016..1a88b363005c 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/serial/mpc52xx_uart.c @@ -113,7 +113,9 @@ struct psc_ops { unsigned char (*read_char)(struct uart_port *port); void (*cw_disable_ints)(struct uart_port *port); void (*cw_restore_ints)(struct uart_port *port); - unsigned long (*getuartclk)(void *p); + unsigned int (*set_baudrate)(struct uart_port *port, + struct ktermios *new, + struct ktermios *old); int (*clock)(struct uart_port *port, int enable); int (*fifoc_init)(void); void (*fifoc_uninit)(void); @@ -121,6 +123,16 @@ struct psc_ops { irqreturn_t (*handle_irq)(struct uart_port *port); }; +/* setting the prescaler and divisor reg is common for all chips */ +static inline void mpc52xx_set_divisor(struct mpc52xx_psc __iomem *psc, + u16 prescaler, unsigned int divisor) +{ + /* select prescaler */ + out_be16(&psc->mpc52xx_psc_clock_select, prescaler); + out_8(&psc->ctur, divisor >> 8); + out_8(&psc->ctlr, divisor & 0xff); +} + #ifdef CONFIG_PPC_MPC52xx #define FIFO_52xx(port) ((struct mpc52xx_psc_fifo __iomem *)(PSC(port)+1)) static void mpc52xx_psc_fifo_init(struct uart_port *port) @@ -128,9 +140,6 @@ static void mpc52xx_psc_fifo_init(struct uart_port *port) struct mpc52xx_psc __iomem *psc = PSC(port); struct mpc52xx_psc_fifo __iomem *fifo = FIFO_52xx(port); - /* /32 prescaler */ - out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00); - out_8(&fifo->rfcntl, 0x00); out_be16(&fifo->rfalarm, 0x1ff); out_8(&fifo->tfcntl, 0x07); @@ -219,15 +228,47 @@ static void mpc52xx_psc_cw_restore_ints(struct uart_port *port) out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask); } -/* Search for bus-frequency property in this node or a parent */ -static unsigned long mpc52xx_getuartclk(void *p) +static unsigned int mpc5200_psc_set_baudrate(struct uart_port *port, + struct ktermios *new, + struct ktermios *old) { - /* - * 5200 UARTs have a / 32 prescaler - * but the generic serial code assumes 16 - * so return ipb freq / 2 - */ - return mpc5xxx_get_bus_frequency(p) / 2; + unsigned int baud; + unsigned int divisor; + + /* The 5200 has a fixed /32 prescaler, uartclk contains the ipb freq */ + baud = uart_get_baud_rate(port, new, old, + port->uartclk / (32 * 0xffff) + 1, + port->uartclk / 32); + divisor = (port->uartclk + 16 * baud) / (32 * baud); + + /* enable the /32 prescaler and set the divisor */ + mpc52xx_set_divisor(PSC(port), 0xdd00, divisor); + return baud; +} + +static unsigned int mpc5200b_psc_set_baudrate(struct uart_port *port, + struct ktermios *new, + struct ktermios *old) +{ + unsigned int baud; + unsigned int divisor; + u16 prescaler; + + /* The 5200B has a selectable /4 or /32 prescaler, uartclk contains the + * ipb freq */ + baud = uart_get_baud_rate(port, new, old, + port->uartclk / (32 * 0xffff) + 1, + port->uartclk / 4); + divisor = (port->uartclk + 2 * baud) / (4 * baud); + + /* select the proper prescaler and set the divisor */ + if (divisor > 0xffff) { + divisor = (divisor + 4) / 8; + prescaler = 0xdd00; /* /32 */ + } else + prescaler = 0xff00; /* /4 */ + mpc52xx_set_divisor(PSC(port), prescaler, divisor); + return baud; } static void mpc52xx_psc_get_irq(struct uart_port *port, struct device_node *np) @@ -258,7 +299,28 @@ static struct psc_ops mpc52xx_psc_ops = { .read_char = mpc52xx_psc_read_char, .cw_disable_ints = mpc52xx_psc_cw_disable_ints, .cw_restore_ints = mpc52xx_psc_cw_restore_ints, - .getuartclk = mpc52xx_getuartclk, + .set_baudrate = mpc5200_psc_set_baudrate, + .get_irq = mpc52xx_psc_get_irq, + .handle_irq = mpc52xx_psc_handle_irq, +}; + +static struct psc_ops mpc5200b_psc_ops = { + .fifo_init = mpc52xx_psc_fifo_init, + .raw_rx_rdy = mpc52xx_psc_raw_rx_rdy, + .raw_tx_rdy = mpc52xx_psc_raw_tx_rdy, + .rx_rdy = mpc52xx_psc_rx_rdy, + .tx_rdy = mpc52xx_psc_tx_rdy, + .tx_empty = mpc52xx_psc_tx_empty, + .stop_rx = mpc52xx_psc_stop_rx, + .start_tx = mpc52xx_psc_start_tx, + .stop_tx = mpc52xx_psc_stop_tx, + .rx_clr_irq = mpc52xx_psc_rx_clr_irq, + .tx_clr_irq = mpc52xx_psc_tx_clr_irq, + .write_char = mpc52xx_psc_write_char, + .read_char = mpc52xx_psc_read_char, + .cw_disable_ints = mpc52xx_psc_cw_disable_ints, + .cw_restore_ints = mpc52xx_psc_cw_restore_ints, + .set_baudrate = mpc5200b_psc_set_baudrate, .get_irq = mpc52xx_psc_get_irq, .handle_irq = mpc52xx_psc_handle_irq, }; @@ -392,9 +454,35 @@ static void mpc512x_psc_cw_restore_ints(struct uart_port *port) out_be32(&FIFO_512x(port)->rximr, port->read_status_mask & 0x7f); } -static unsigned long mpc512x_getuartclk(void *p) +static unsigned int mpc512x_psc_set_baudrate(struct uart_port *port, + struct ktermios *new, + struct ktermios *old) { - return mpc5xxx_get_bus_frequency(p); + unsigned int baud; + unsigned int divisor; + + /* + * The "MPC5121e Microcontroller Reference Manual, Rev. 3" says on + * pg. 30-10 that the chip supports a /32 and a /10 prescaler. + * Furthermore, it states that "After reset, the prescaler by 10 + * for the UART mode is selected", but the reset register value is + * 0x0000 which means a /32 prescaler. This is wrong. + * + * In reality using /32 prescaler doesn't work, as it is not supported! + * Use /16 or /10 prescaler, see "MPC5121e Hardware Design Guide", + * Chapter 4.1 PSC in UART Mode. + * Calculate with a /16 prescaler here. + */ + + /* uartclk contains the ips freq */ + baud = uart_get_baud_rate(port, new, old, + port->uartclk / (16 * 0xffff) + 1, + port->uartclk / 16); + divisor = (port->uartclk + 8 * baud) / (16 * baud); + + /* enable the /16 prescaler and set the divisor */ + mpc52xx_set_divisor(PSC(port), 0xdd00, divisor); + return baud; } /* Init PSC FIFO Controller */ @@ -498,7 +586,7 @@ static struct psc_ops mpc512x_psc_ops = { .read_char = mpc512x_psc_read_char, .cw_disable_ints = mpc512x_psc_cw_disable_ints, .cw_restore_ints = mpc512x_psc_cw_restore_ints, - .getuartclk = mpc512x_getuartclk, + .set_baudrate = mpc512x_psc_set_baudrate, .clock = mpc512x_psc_clock, .fifoc_init = mpc512x_psc_fifoc_init, .fifoc_uninit = mpc512x_psc_fifoc_uninit, @@ -666,8 +754,8 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new, struct mpc52xx_psc __iomem *psc = PSC(port); unsigned long flags; unsigned char mr1, mr2; - unsigned short ctr; - unsigned int j, baud, quot; + unsigned int j; + unsigned int baud; /* Prepare what we're gonna write */ mr1 = 0; @@ -704,16 +792,9 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new, mr2 |= MPC52xx_PSC_MODE_TXCTS; } - baud = uart_get_baud_rate(port, new, old, 0, port->uartclk/16); - quot = uart_get_divisor(port, baud); - ctr = quot & 0xffff; - /* Get the lock */ spin_lock_irqsave(&port->lock, flags); - /* Update the per-port timeout */ - uart_update_timeout(port, new->c_cflag, baud); - /* Do our best to flush TX & RX, so we don't lose anything */ /* But we don't wait indefinitely ! */ j = 5000000; /* Maximum wait */ @@ -737,8 +818,10 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new, out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1); out_8(&psc->mode, mr1); out_8(&psc->mode, mr2); - out_8(&psc->ctur, ctr >> 8); - out_8(&psc->ctlr, ctr & 0xff); + baud = psc_ops->set_baudrate(port, new, old); + + /* Update the per-port timeout */ + uart_update_timeout(port, new->c_cflag, baud); if (UART_ENABLE_MS(port, new->c_cflag)) mpc52xx_uart_enable_ms(port); @@ -1118,7 +1201,7 @@ mpc52xx_console_setup(struct console *co, char *options) return ret; } - uartclk = psc_ops->getuartclk(np); + uartclk = mpc5xxx_get_bus_frequency(np); if (uartclk == 0) { pr_debug("Could not find uart clock frequency!\n"); return -EINVAL; @@ -1201,6 +1284,7 @@ static struct uart_driver mpc52xx_uart_driver = { static struct of_device_id mpc52xx_uart_of_match[] = { #ifdef CONFIG_PPC_MPC52xx + { .compatible = "fsl,mpc5200b-psc-uart", .data = &mpc5200b_psc_ops, }, { .compatible = "fsl,mpc5200-psc-uart", .data = &mpc52xx_psc_ops, }, /* binding used by old lite5200 device trees: */ { .compatible = "mpc5200-psc-uart", .data = &mpc52xx_psc_ops, }, @@ -1233,7 +1317,10 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match) pr_debug("Found %s assigned to ttyPSC%x\n", mpc52xx_uart_nodes[idx]->full_name, idx); - uartclk = psc_ops->getuartclk(op->dev.of_node); + /* set the uart clock to the input clock of the psc, the different + * prescalers are taken into account in the set_baudrate() methods + * of the respective chip */ + uartclk = mpc5xxx_get_bus_frequency(op->dev.of_node); if (uartclk == 0) { dev_dbg(&op->dev, "Could not find uart clock frequency!\n"); return -EINVAL; diff --git a/drivers/serial/msm_serial.c b/drivers/serial/msm_serial.c index ecdc0facf7ee..f8c816e7725d 100644 --- a/drivers/serial/msm_serial.c +++ b/drivers/serial/msm_serial.c @@ -41,19 +41,6 @@ struct msm_port { unsigned int imr; }; -#define UART_TO_MSM(uart_port) ((struct msm_port *) uart_port) - -static inline void msm_write(struct uart_port *port, unsigned int val, - unsigned int off) -{ - __raw_writel(val, port->membase + off); -} - -static inline unsigned int msm_read(struct uart_port *port, unsigned int off) -{ - return __raw_readl(port->membase + off); -} - static void msm_stop_tx(struct uart_port *port) { struct msm_port *msm_port = UART_TO_MSM(port); @@ -320,11 +307,7 @@ static void msm_init_clock(struct uart_port *port) struct msm_port *msm_port = UART_TO_MSM(port); clk_enable(msm_port->clk); - - msm_write(port, 0xC0, UART_MREG); - msm_write(port, 0xB2, UART_NREG); - msm_write(port, 0x7D, UART_DREG); - msm_write(port, 0x1C, UART_MNDREG); + msm_serial_set_mnd_regs(port); } static int msm_startup(struct uart_port *port) @@ -706,6 +689,8 @@ static int __init msm_serial_probe(struct platform_device *pdev) if (unlikely(IS_ERR(msm_port->clk))) return PTR_ERR(msm_port->clk); port->uartclk = clk_get_rate(msm_port->clk); + printk(KERN_INFO "uartclk = %d\n", port->uartclk); + resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (unlikely(!resource)) diff --git a/drivers/serial/msm_serial.h b/drivers/serial/msm_serial.h index 689f1fa0e84e..f6ca9ca79e98 100644 --- a/drivers/serial/msm_serial.h +++ b/drivers/serial/msm_serial.h @@ -114,4 +114,60 @@ #define UART_MISR 0x0010 #define UART_ISR 0x0014 +#define UART_TO_MSM(uart_port) ((struct msm_port *) uart_port) + +static inline +void msm_write(struct uart_port *port, unsigned int val, unsigned int off) +{ + __raw_writel(val, port->membase + off); +} + +static inline +unsigned int msm_read(struct uart_port *port, unsigned int off) +{ + return __raw_readl(port->membase + off); +} + +/* + * Setup the MND registers to use the TCXO clock. + */ +static inline void msm_serial_set_mnd_regs_tcxo(struct uart_port *port) +{ + msm_write(port, 0x06, UART_MREG); + msm_write(port, 0xF1, UART_NREG); + msm_write(port, 0x0F, UART_DREG); + msm_write(port, 0x1A, UART_MNDREG); +} + +/* + * Setup the MND registers to use the TCXO clock divided by 4. + */ +static inline void msm_serial_set_mnd_regs_tcxoby4(struct uart_port *port) +{ + msm_write(port, 0x18, UART_MREG); + msm_write(port, 0xF6, UART_NREG); + msm_write(port, 0x0F, UART_DREG); + msm_write(port, 0x0A, UART_MNDREG); +} + +static inline +void msm_serial_set_mnd_regs_from_uartclk(struct uart_port *port) +{ + if (port->uartclk == 19200000) + msm_serial_set_mnd_regs_tcxo(port); + else + msm_serial_set_mnd_regs_tcxoby4(port); +} + +/* + * TROUT has a specific defect that makes it report it's uartclk + * as 19.2Mhz (TCXO) when it's actually 4.8Mhz (TCXO/4). This special + * cases TROUT to use the right clock. + */ +#ifdef CONFIG_MACH_TROUT +#define msm_serial_set_mnd_regs msm_serial_set_mnd_regs_tcxoby4 +#else +#define msm_serial_set_mnd_regs msm_serial_set_mnd_regs_from_uartclk +#endif + #endif /* __DRIVERS_SERIAL_MSM_SERIAL_H */ diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 5f90fcd7d107..c291b3add1d2 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -346,6 +346,27 @@ static int scif_rxfill(struct uart_port *port) return sci_in(port, SCFDR) & SCIF2_RFDC_MASK; } } +#elif defined(CONFIG_ARCH_SH7372) +static int scif_txfill(struct uart_port *port) +{ + if (port->type == PORT_SCIFA) + return sci_in(port, SCFDR) >> 8; + else + return sci_in(port, SCTFDR); +} + +static int scif_txroom(struct uart_port *port) +{ + return port->fifosize - scif_txfill(port); +} + +static int scif_rxfill(struct uart_port *port) +{ + if (port->type == PORT_SCIFA) + return sci_in(port, SCFDR) & SCIF_RFDC_MASK; + else + return sci_in(port, SCRFDR); +} #else static int scif_txfill(struct uart_port *port) { @@ -683,7 +704,7 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr) u16 ssr = sci_in(port, SCxSR); /* Disable future Rx interrupts */ - if (port->type == PORT_SCIFA) { + if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { disable_irq_nosync(irq); scr |= 0x4000; } else { @@ -928,7 +949,7 @@ static void sci_dma_tx_complete(void *arg) if (!uart_circ_empty(xmit)) { schedule_work(&s->work_tx); - } else if (port->type == PORT_SCIFA) { + } else if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { u16 ctrl = sci_in(port, SCSCR); sci_out(port, SCSCR, ctrl & ~SCI_CTRL_FLAGS_TIE); } @@ -1184,7 +1205,7 @@ static void sci_start_tx(struct uart_port *port) unsigned short ctrl; #ifdef CONFIG_SERIAL_SH_SCI_DMA - if (port->type == PORT_SCIFA) { + if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { u16 new, scr = sci_in(port, SCSCR); if (s->chan_tx) new = scr | 0x8000; @@ -1197,7 +1218,7 @@ static void sci_start_tx(struct uart_port *port) s->cookie_tx < 0) schedule_work(&s->work_tx); #endif - if (!s->chan_tx || port->type == PORT_SCIFA) { + if (!s->chan_tx || port->type == PORT_SCIFA || port->type == PORT_SCIFB) { /* Set TIE (Transmit Interrupt Enable) bit in SCSCR */ ctrl = sci_in(port, SCSCR); sci_out(port, SCSCR, ctrl | SCI_CTRL_FLAGS_TIE); @@ -1210,7 +1231,7 @@ static void sci_stop_tx(struct uart_port *port) /* Clear TIE (Transmit Interrupt Enable) bit in SCSCR */ ctrl = sci_in(port, SCSCR); - if (port->type == PORT_SCIFA) + if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) ctrl &= ~0x8000; ctrl &= ~SCI_CTRL_FLAGS_TIE; sci_out(port, SCSCR, ctrl); @@ -1222,7 +1243,7 @@ static void sci_start_rx(struct uart_port *port) /* Set RIE (Receive Interrupt Enable) bit in SCSCR */ ctrl |= sci_in(port, SCSCR); - if (port->type == PORT_SCIFA) + if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) ctrl &= ~0x4000; sci_out(port, SCSCR, ctrl); } @@ -1233,7 +1254,7 @@ static void sci_stop_rx(struct uart_port *port) /* Clear RIE (Receive Interrupt Enable) bit in SCSCR */ ctrl = sci_in(port, SCSCR); - if (port->type == PORT_SCIFA) + if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) ctrl &= ~0x4000; ctrl &= ~(SCI_CTRL_FLAGS_RIE | SCI_CTRL_FLAGS_REIE); sci_out(port, SCSCR, ctrl); @@ -1271,7 +1292,7 @@ static void rx_timer_fn(unsigned long arg) struct uart_port *port = &s->port; u16 scr = sci_in(port, SCSCR); - if (port->type == PORT_SCIFA) { + if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { scr &= ~0x4000; enable_irq(s->irqs[1]); } @@ -1524,6 +1545,8 @@ static const char *sci_type(struct uart_port *port) return "scif"; case PORT_SCIFA: return "scifa"; + case PORT_SCIFB: + return "scifb"; } return NULL; @@ -1612,6 +1635,9 @@ static int __devinit sci_init_single(struct platform_device *dev, port->line = index; switch (p->type) { + case PORT_SCIFB: + port->fifosize = 256; + break; case PORT_SCIFA: port->fifosize = 64; break; diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h index f70c49f915fa..9b52f77a9305 100644 --- a/drivers/serial/sh-sci.h +++ b/drivers/serial/sh-sci.h @@ -322,7 +322,7 @@ #define CPU_SCIx_FNS(name, sci_offset, sci_size, scif_offset, scif_size)\ static inline unsigned int sci_##name##_in(struct uart_port *port) \ { \ - if (port->type == PORT_SCIF) { \ + if (port->type == PORT_SCIF || port->type == PORT_SCIFB) { \ SCI_IN(scif_size, scif_offset) \ } else { /* PORT_SCI or PORT_SCIFA */ \ SCI_IN(sci_size, sci_offset); \ @@ -330,7 +330,7 @@ } \ static inline void sci_##name##_out(struct uart_port *port, unsigned int value) \ { \ - if (port->type == PORT_SCIF) { \ + if (port->type == PORT_SCIF || port->type == PORT_SCIFB) { \ SCI_OUT(scif_size, scif_offset, value) \ } else { /* PORT_SCI or PORT_SCIFA */ \ SCI_OUT(sci_size, sci_offset, value); \ @@ -384,8 +384,12 @@ defined(CONFIG_CPU_SUBTYPE_SH7720) || \ defined(CONFIG_CPU_SUBTYPE_SH7721) || \ defined(CONFIG_ARCH_SH7367) || \ - defined(CONFIG_ARCH_SH7377) || \ - defined(CONFIG_ARCH_SH7372) + defined(CONFIG_ARCH_SH7377) +#define SCIF_FNS(name, scif_offset, scif_size) \ + CPU_SCIF_FNS(name, scif_offset, scif_size) +#elif defined(CONFIG_ARCH_SH7372) +#define SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scifb_offset, sh4_scifb_size) \ + CPU_SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scifb_offset, sh4_scifb_size) #define SCIF_FNS(name, scif_offset, scif_size) \ CPU_SCIF_FNS(name, scif_offset, scif_size) #else @@ -422,8 +426,7 @@ defined(CONFIG_CPU_SUBTYPE_SH7720) || \ defined(CONFIG_CPU_SUBTYPE_SH7721) || \ defined(CONFIG_ARCH_SH7367) || \ - defined(CONFIG_ARCH_SH7377) || \ - defined(CONFIG_ARCH_SH7372) + defined(CONFIG_ARCH_SH7377) SCIF_FNS(SCSMR, 0x00, 16) SCIF_FNS(SCBRR, 0x04, 8) @@ -436,6 +439,20 @@ SCIF_FNS(SCFDR, 0x1c, 16) SCIF_FNS(SCxTDR, 0x20, 8) SCIF_FNS(SCxRDR, 0x24, 8) SCIF_FNS(SCLSR, 0x00, 0) +#elif defined(CONFIG_ARCH_SH7372) +SCIF_FNS(SCSMR, 0x00, 16) +SCIF_FNS(SCBRR, 0x04, 8) +SCIF_FNS(SCSCR, 0x08, 16) +SCIF_FNS(SCTDSR, 0x0c, 16) +SCIF_FNS(SCFER, 0x10, 16) +SCIF_FNS(SCxSR, 0x14, 16) +SCIF_FNS(SCFCR, 0x18, 16) +SCIF_FNS(SCFDR, 0x1c, 16) +SCIF_FNS(SCTFDR, 0x38, 16) +SCIF_FNS(SCRFDR, 0x3c, 16) +SCIx_FNS(SCxTDR, 0x20, 8, 0x40, 8) +SCIx_FNS(SCxRDR, 0x24, 8, 0x60, 8) +SCIF_FNS(SCLSR, 0x00, 0) #elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\ defined(CONFIG_CPU_SUBTYPE_SH7724) SCIx_FNS(SCSMR, 0x00, 16, 0x00, 16) diff --git a/drivers/sh/Makefile b/drivers/sh/Makefile index 78bb5127abd0..08fc653a825c 100644 --- a/drivers/sh/Makefile +++ b/drivers/sh/Makefile @@ -1,9 +1,10 @@ # # Makefile for the SuperH specific drivers. # +obj-y := clk.o intc.o + obj-$(CONFIG_SUPERHYWAY) += superhyway/ obj-$(CONFIG_MAPLE) += maple/ + obj-$(CONFIG_GENERIC_GPIO) += pfc.o -obj-$(CONFIG_SUPERH) += clk.o obj-$(CONFIG_SH_CLK_CPG) += clk-cpg.o -obj-y += intc.o diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index 989e2752cc36..6dcda86be6eb 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c @@ -625,9 +625,12 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus, ssb_printk(KERN_ERR PFX "No SPROM available!\n"); return -ENODEV; } - - bus->sprom_offset = (bus->chipco.dev->id.revision < 31) ? - SSB_SPROM_BASE1 : SSB_SPROM_BASE31; + if (bus->chipco.dev) { /* can be unavailible! */ + bus->sprom_offset = (bus->chipco.dev->id.revision < 31) ? + SSB_SPROM_BASE1 : SSB_SPROM_BASE31; + } else { + bus->sprom_offset = SSB_SPROM_BASE1; + } buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL); if (!buf) diff --git a/drivers/ssb/sprom.c b/drivers/ssb/sprom.c index 007bc3a03486..4f7cc8d13277 100644 --- a/drivers/ssb/sprom.c +++ b/drivers/ssb/sprom.c @@ -185,6 +185,7 @@ bool ssb_is_sprom_available(struct ssb_bus *bus) /* this routine differs from specs as we do not access SPROM directly on PCMCIA */ if (bus->bustype == SSB_BUSTYPE_PCI && + bus->chipco.dev && /* can be unavailible! */ bus->chipco.dev->id.revision >= 31) return bus->chipco.capabilities & SSB_CHIPCO_CAP_SPROM; diff --git a/drivers/staging/tm6000/tm6000-alsa.c b/drivers/staging/tm6000/tm6000-alsa.c index bc89f9d28002..34045162bddf 100644 --- a/drivers/staging/tm6000/tm6000-alsa.c +++ b/drivers/staging/tm6000/tm6000-alsa.c @@ -15,6 +15,7 @@ #include <linux/device.h> #include <linux/interrupt.h> #include <linux/usb.h> +#include <linux/slab.h> #include <asm/delay.h> #include <sound/core.h> diff --git a/drivers/staging/tm6000/tm6000-cards.c b/drivers/staging/tm6000/tm6000-cards.c index 6143e20d139d..4ae92b17b503 100644 --- a/drivers/staging/tm6000/tm6000-cards.c +++ b/drivers/staging/tm6000/tm6000-cards.c @@ -24,6 +24,7 @@ #include <linux/i2c.h> #include <linux/usb.h> #include <linux/version.h> +#include <linux/slab.h> #include <media/v4l2-common.h> #include <media/tuner.h> #include <media/tvaudio.h> diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c index bfbc53bd2912..a597fbcc6f3f 100644 --- a/drivers/staging/tm6000/tm6000-core.c +++ b/drivers/staging/tm6000/tm6000-core.c @@ -22,6 +22,7 @@ #include <linux/module.h> #include <linux/kernel.h> +#include <linux/slab.h> #include <linux/usb.h> #include <linux/i2c.h> #include "tm6000.h" diff --git a/drivers/staging/tm6000/tm6000-dvb.c b/drivers/staging/tm6000/tm6000-dvb.c index eafc89c22b6b..f87c8d89ba62 100644 --- a/drivers/staging/tm6000/tm6000-dvb.c +++ b/drivers/staging/tm6000/tm6000-dvb.c @@ -18,6 +18,7 @@ */ #include <linux/kernel.h> +#include <linux/slab.h> #include <linux/usb.h> #include "tm6000.h" diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 1e6fec487973..3dc10381e0c2 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -1895,6 +1895,13 @@ config FB_W100 If unsure, say N. +config SH_MIPI_DSI + tristate + depends on (SUPERH || ARCH_SHMOBILE) && HAVE_CLK + +config SH_LCD_MIPI_DSI + bool + config FB_SH_MOBILE_LCDC tristate "SuperH Mobile LCDC framebuffer support" depends on FB && (SUPERH || ARCH_SHMOBILE) && HAVE_CLK @@ -1903,6 +1910,7 @@ config FB_SH_MOBILE_LCDC select FB_SYS_IMAGEBLIT select FB_SYS_FOPS select FB_DEFERRED_IO + select SH_MIPI_DSI if SH_LCD_MIPI_DSI ---help--- Frame buffer driver for the on-chip SH-Mobile LCD controller. diff --git a/drivers/video/Makefile b/drivers/video/Makefile index ddc2af2ba45b..3c3bf867ef18 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -123,6 +123,7 @@ obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o obj-$(CONFIG_FB_PS3) += ps3fb.o obj-$(CONFIG_FB_SM501) += sm501fb.o obj-$(CONFIG_FB_XILINX) += xilinxfb.o +obj-$(CONFIG_SH_MIPI_DSI) += sh_mipi_dsi.o obj-$(CONFIG_FB_SH_MOBILE_LCDC) += sh_mobile_lcdcfb.o obj-$(CONFIG_FB_OMAP) += omap/ obj-y += omap2/ diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c new file mode 100644 index 000000000000..017ae9f47d36 --- /dev/null +++ b/drivers/video/sh_mipi_dsi.c @@ -0,0 +1,505 @@ +/* + * Renesas SH-mobile MIPI DSI support + * + * Copyright (C) 2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de> + * + * This is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + */ + +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/init.h> +#include <linux/io.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/string.h> +#include <linux/types.h> + +#include <video/mipi_display.h> +#include <video/sh_mipi_dsi.h> +#include <video/sh_mobile_lcdc.h> + +#define CMTSRTCTR 0x80d0 +#define CMTSRTREQ 0x8070 + +#define DSIINTE 0x0060 + +/* E.g., sh7372 has 2 MIPI-DSIs - one for each LCDC */ +#define MAX_SH_MIPI_DSI 2 + +struct sh_mipi { + void __iomem *base; + struct clk *dsit_clk; + struct clk *dsip_clk; +}; + +static struct sh_mipi *mipi_dsi[MAX_SH_MIPI_DSI]; + +/* Protect the above array */ +static DEFINE_MUTEX(array_lock); + +static struct sh_mipi *sh_mipi_by_handle(int handle) +{ + if (handle >= ARRAY_SIZE(mipi_dsi) || handle < 0) + return NULL; + + return mipi_dsi[handle]; +} + +static int sh_mipi_send_short(struct sh_mipi *mipi, u8 dsi_cmd, + u8 cmd, u8 param) +{ + u32 data = (dsi_cmd << 24) | (cmd << 16) | (param << 8); + int cnt = 100; + + /* transmit a short packet to LCD panel */ + iowrite32(1 | data, mipi->base + 0x80d0); /* CMTSRTCTR */ + iowrite32(1, mipi->base + 0x8070); /* CMTSRTREQ */ + + while ((ioread32(mipi->base + 0x8070) & 1) && --cnt) + udelay(1); + + return cnt ? 0 : -ETIMEDOUT; +} + +#define LCD_CHAN2MIPI(c) ((c) < LCDC_CHAN_MAINLCD || (c) > LCDC_CHAN_SUBLCD ? \ + -EINVAL : (c) - 1) + +static int sh_mipi_dcs(int handle, u8 cmd) +{ + struct sh_mipi *mipi = sh_mipi_by_handle(LCD_CHAN2MIPI(handle)); + if (!mipi) + return -ENODEV; + return sh_mipi_send_short(mipi, MIPI_DSI_DCS_SHORT_WRITE, cmd, 0); +} + +static int sh_mipi_dcs_param(int handle, u8 cmd, u8 param) +{ + struct sh_mipi *mipi = sh_mipi_by_handle(LCD_CHAN2MIPI(handle)); + if (!mipi) + return -ENODEV; + return sh_mipi_send_short(mipi, MIPI_DSI_DCS_SHORT_WRITE_PARAM, cmd, + param); +} + +static void sh_mipi_dsi_enable(struct sh_mipi *mipi, bool enable) +{ + /* + * enable LCDC data tx, transition to LPS after completion of each HS + * packet + */ + iowrite32(0x00000002 | enable, mipi->base + 0x8000); /* DTCTR */ +} + +static void sh_mipi_shutdown(struct platform_device *pdev) +{ + struct sh_mipi *mipi = platform_get_drvdata(pdev); + + sh_mipi_dsi_enable(mipi, false); +} + +static void mipi_display_on(void *arg) +{ + struct sh_mipi *mipi = arg; + + sh_mipi_dsi_enable(mipi, true); +} + +static void mipi_display_off(void *arg) +{ + struct sh_mipi *mipi = arg; + + sh_mipi_dsi_enable(mipi, false); +} + +static int __init sh_mipi_setup(struct sh_mipi *mipi, + struct sh_mipi_dsi_info *pdata) +{ + void __iomem *base = mipi->base; + struct sh_mobile_lcdc_chan_cfg *ch = pdata->lcd_chan; + u32 pctype, datatype, pixfmt; + u32 linelength; + bool yuv; + + /* Select data format */ + switch (pdata->data_format) { + case MIPI_RGB888: + pctype = 0; + datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24; + pixfmt = MIPI_DCS_PIXEL_FMT_24BIT; + linelength = ch->lcd_cfg.xres * 3; + yuv = false; + break; + case MIPI_RGB565: + pctype = 1; + datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16; + pixfmt = MIPI_DCS_PIXEL_FMT_16BIT; + linelength = ch->lcd_cfg.xres * 2; + yuv = false; + break; + case MIPI_RGB666_LP: + pctype = 2; + datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18; + pixfmt = MIPI_DCS_PIXEL_FMT_24BIT; + linelength = ch->lcd_cfg.xres * 3; + yuv = false; + break; + case MIPI_RGB666: + pctype = 3; + datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18; + pixfmt = MIPI_DCS_PIXEL_FMT_18BIT; + linelength = (ch->lcd_cfg.xres * 18 + 7) / 8; + yuv = false; + break; + case MIPI_BGR888: + pctype = 8; + datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24; + pixfmt = MIPI_DCS_PIXEL_FMT_24BIT; + linelength = ch->lcd_cfg.xres * 3; + yuv = false; + break; + case MIPI_BGR565: + pctype = 9; + datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16; + pixfmt = MIPI_DCS_PIXEL_FMT_16BIT; + linelength = ch->lcd_cfg.xres * 2; + yuv = false; + break; + case MIPI_BGR666_LP: + pctype = 0xa; + datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18; + pixfmt = MIPI_DCS_PIXEL_FMT_24BIT; + linelength = ch->lcd_cfg.xres * 3; + yuv = false; + break; + case MIPI_BGR666: + pctype = 0xb; + datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18; + pixfmt = MIPI_DCS_PIXEL_FMT_18BIT; + linelength = (ch->lcd_cfg.xres * 18 + 7) / 8; + yuv = false; + break; + case MIPI_YUYV: + pctype = 4; + datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16; + pixfmt = MIPI_DCS_PIXEL_FMT_16BIT; + linelength = ch->lcd_cfg.xres * 2; + yuv = true; + break; + case MIPI_UYVY: + pctype = 5; + datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16; + pixfmt = MIPI_DCS_PIXEL_FMT_16BIT; + linelength = ch->lcd_cfg.xres * 2; + yuv = true; + break; + case MIPI_YUV420_L: + pctype = 6; + datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12; + pixfmt = MIPI_DCS_PIXEL_FMT_12BIT; + linelength = (ch->lcd_cfg.xres * 12 + 7) / 8; + yuv = true; + break; + case MIPI_YUV420: + pctype = 7; + datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12; + pixfmt = MIPI_DCS_PIXEL_FMT_12BIT; + /* Length of U/V line */ + linelength = (ch->lcd_cfg.xres + 1) / 2; + yuv = true; + break; + default: + return -EINVAL; + } + + if ((yuv && ch->interface_type != YUV422) || + (!yuv && ch->interface_type != RGB24)) + return -EINVAL; + + /* reset DSI link */ + iowrite32(0x00000001, base); /* SYSCTRL */ + /* Hold reset for 100 cycles of the slowest of bus, HS byte and LP clock */ + udelay(50); + iowrite32(0x00000000, base); /* SYSCTRL */ + + /* setup DSI link */ + + /* + * Default = ULPS enable | + * Contention detection enabled | + * EoT packet transmission enable | + * CRC check enable | + * ECC check enable + * additionally enable first two lanes + */ + iowrite32(0x00003703, base + 0x04); /* SYSCONF */ + /* + * T_wakeup = 0x7000 + * T_hs-trail = 3 + * T_hs-prepare = 3 + * T_clk-trail = 3 + * T_clk-prepare = 2 + */ + iowrite32(0x70003332, base + 0x08); /* TIMSET */ + /* no responses requested */ + iowrite32(0x00000000, base + 0x18); /* RESREQSET0 */ + /* request response to packets of type 0x28 */ + iowrite32(0x00000100, base + 0x1c); /* RESREQSET1 */ + /* High-speed transmission timeout, default 0xffffffff */ + iowrite32(0x0fffffff, base + 0x20); /* HSTTOVSET */ + /* LP reception timeout, default 0xffffffff */ + iowrite32(0x0fffffff, base + 0x24); /* LPRTOVSET */ + /* Turn-around timeout, default 0xffffffff */ + iowrite32(0x0fffffff, base + 0x28); /* TATOVSET */ + /* Peripheral reset timeout, default 0xffffffff */ + iowrite32(0x0fffffff, base + 0x2c); /* PRTOVSET */ + /* Enable timeout counters */ + iowrite32(0x00000f00, base + 0x30); /* DSICTRL */ + /* Interrupts not used, disable all */ + iowrite32(0, base + DSIINTE); + /* DSI-Tx bias on */ + iowrite32(0x00000001, base + 0x70); /* PHYCTRL */ + udelay(200); + /* Deassert resets, power on, set multiplier */ + iowrite32(0x03070b01, base + 0x70); /* PHYCTRL */ + + /* setup l-bridge */ + + /* + * Enable transmission of all packets, + * transmit LPS after each HS packet completion + */ + iowrite32(0x00000006, base + 0x8000); /* DTCTR */ + /* VSYNC width = 2 (<< 17) */ + iowrite32(0x00040000 | (pctype << 12) | datatype, base + 0x8020); /* VMCTR1 */ + /* + * Non-burst mode with sync pulses: VSE and HSE are output, + * HSA period allowed, no commands in LP + */ + iowrite32(0x00e00000, base + 0x8024); /* VMCTR2 */ + /* + * 0x660 = 1632 bytes per line (RGB24, 544 pixels: see + * sh_mobile_lcdc_info.ch[0].lcd_cfg.xres), HSALEN = 1 - default + * (unused, since VMCTR2[HSABM] = 0) + */ + iowrite32(1 | (linelength << 16), base + 0x8028); /* VMLEN1 */ + + msleep(5); + + /* setup LCD panel */ + + /* cf. drivers/video/omap/lcd_mipid.c */ + sh_mipi_dcs(ch->chan, MIPI_DCS_EXIT_SLEEP_MODE); + msleep(120); + /* + * [7] - Page Address Mode + * [6] - Column Address Mode + * [5] - Page / Column Address Mode + * [4] - Display Device Line Refresh Order + * [3] - RGB/BGR Order + * [2] - Display Data Latch Data Order + * [1] - Flip Horizontal + * [0] - Flip Vertical + */ + sh_mipi_dcs_param(ch->chan, MIPI_DCS_SET_ADDRESS_MODE, 0x00); + /* cf. set_data_lines() */ + sh_mipi_dcs_param(ch->chan, MIPI_DCS_SET_PIXEL_FORMAT, + pixfmt << 4); + sh_mipi_dcs(ch->chan, MIPI_DCS_SET_DISPLAY_ON); + + return 0; +} + +static int __init sh_mipi_probe(struct platform_device *pdev) +{ + struct sh_mipi *mipi; + struct sh_mipi_dsi_info *pdata = pdev->dev.platform_data; + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + unsigned long rate, f_current; + int idx = pdev->id, ret; + char dsip_clk[] = "dsi.p_clk"; + + if (!res || idx >= ARRAY_SIZE(mipi_dsi) || !pdata) + return -ENODEV; + + mutex_lock(&array_lock); + if (idx < 0) + for (idx = 0; idx < ARRAY_SIZE(mipi_dsi) && mipi_dsi[idx]; idx++) + ; + + if (idx == ARRAY_SIZE(mipi_dsi)) { + ret = -EBUSY; + goto efindslot; + } + + mipi = kzalloc(sizeof(*mipi), GFP_KERNEL); + if (!mipi) { + ret = -ENOMEM; + goto ealloc; + } + + if (!request_mem_region(res->start, resource_size(res), pdev->name)) { + dev_err(&pdev->dev, "MIPI register region already claimed\n"); + ret = -EBUSY; + goto ereqreg; + } + + mipi->base = ioremap(res->start, resource_size(res)); + if (!mipi->base) { + ret = -ENOMEM; + goto emap; + } + + mipi->dsit_clk = clk_get(&pdev->dev, "dsit_clk"); + if (IS_ERR(mipi->dsit_clk)) { + ret = PTR_ERR(mipi->dsit_clk); + goto eclktget; + } + + f_current = clk_get_rate(mipi->dsit_clk); + /* 80MHz required by the datasheet */ + rate = clk_round_rate(mipi->dsit_clk, 80000000); + if (rate > 0 && rate != f_current) + ret = clk_set_rate(mipi->dsit_clk, rate); + else + ret = rate; + if (ret < 0) + goto esettrate; + + dev_dbg(&pdev->dev, "DSI-T clk %lu -> %lu\n", f_current, rate); + + sprintf(dsip_clk, "dsi%1.1dp_clk", idx); + mipi->dsip_clk = clk_get(&pdev->dev, dsip_clk); + if (IS_ERR(mipi->dsip_clk)) { + ret = PTR_ERR(mipi->dsip_clk); + goto eclkpget; + } + + f_current = clk_get_rate(mipi->dsip_clk); + /* Between 10 and 50MHz */ + rate = clk_round_rate(mipi->dsip_clk, 24000000); + if (rate > 0 && rate != f_current) + ret = clk_set_rate(mipi->dsip_clk, rate); + else + ret = rate; + if (ret < 0) + goto esetprate; + + dev_dbg(&pdev->dev, "DSI-P clk %lu -> %lu\n", f_current, rate); + + msleep(10); + + ret = clk_enable(mipi->dsit_clk); + if (ret < 0) + goto eclkton; + + ret = clk_enable(mipi->dsip_clk); + if (ret < 0) + goto eclkpon; + + mipi_dsi[idx] = mipi; + + ret = sh_mipi_setup(mipi, pdata); + if (ret < 0) + goto emipisetup; + + mutex_unlock(&array_lock); + platform_set_drvdata(pdev, mipi); + + /* Set up LCDC callbacks */ + pdata->lcd_chan->board_cfg.board_data = mipi; + pdata->lcd_chan->board_cfg.display_on = mipi_display_on; + pdata->lcd_chan->board_cfg.display_off = mipi_display_off; + + return 0; + +emipisetup: + mipi_dsi[idx] = NULL; + clk_disable(mipi->dsip_clk); +eclkpon: + clk_disable(mipi->dsit_clk); +eclkton: +esetprate: + clk_put(mipi->dsip_clk); +eclkpget: +esettrate: + clk_put(mipi->dsit_clk); +eclktget: + iounmap(mipi->base); +emap: + release_mem_region(res->start, resource_size(res)); +ereqreg: + kfree(mipi); +ealloc: +efindslot: + mutex_unlock(&array_lock); + + return ret; +} + +static int __exit sh_mipi_remove(struct platform_device *pdev) +{ + struct sh_mipi_dsi_info *pdata = pdev->dev.platform_data; + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + struct sh_mipi *mipi = platform_get_drvdata(pdev); + int i, ret; + + mutex_lock(&array_lock); + + for (i = 0; i < ARRAY_SIZE(mipi_dsi) && mipi_dsi[i] != mipi; i++) + ; + + if (i == ARRAY_SIZE(mipi_dsi)) { + ret = -EINVAL; + } else { + ret = 0; + mipi_dsi[i] = NULL; + } + + mutex_unlock(&array_lock); + + if (ret < 0) + return ret; + + pdata->lcd_chan->board_cfg.display_on = NULL; + pdata->lcd_chan->board_cfg.display_off = NULL; + pdata->lcd_chan->board_cfg.board_data = NULL; + + clk_disable(mipi->dsip_clk); + clk_disable(mipi->dsit_clk); + clk_put(mipi->dsit_clk); + clk_put(mipi->dsip_clk); + iounmap(mipi->base); + if (res) + release_mem_region(res->start, resource_size(res)); + platform_set_drvdata(pdev, NULL); + kfree(mipi); + + return 0; +} + +static struct platform_driver sh_mipi_driver = { + .remove = __exit_p(sh_mipi_remove), + .shutdown = sh_mipi_shutdown, + .driver = { + .name = "sh-mipi-dsi", + }, +}; + +static int __init sh_mipi_init(void) +{ + return platform_driver_probe(&sh_mipi_driver, sh_mipi_probe); +} +module_init(sh_mipi_init); + +static void __exit sh_mipi_exit(void) +{ + platform_driver_unregister(&sh_mipi_driver); +} +module_exit(sh_mipi_exit); + +MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>"); +MODULE_DESCRIPTION("SuperH / ARM-shmobile MIPI DSI driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index e8c769944812..12c451a711e9 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c @@ -991,13 +991,13 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) priv->ch[j].lcdc = priv; memcpy(&priv->ch[j].cfg, &pdata->ch[i], sizeof(pdata->ch[i])); - error = sh_mobile_lcdc_check_interface(&priv->ch[i]); + error = sh_mobile_lcdc_check_interface(&priv->ch[j]); if (error) { dev_err(&pdev->dev, "unsupported interface type\n"); goto err1; } - init_waitqueue_head(&priv->ch[i].frame_end_wait); - init_completion(&priv->ch[i].vsync_completion); + init_waitqueue_head(&priv->ch[j].frame_end_wait); + init_completion(&priv->ch[j].vsync_completion); priv->ch[j].pan_offset = 0; switch (pdata->ch[i].chan) { diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c index 980548390048..3ee5e63cfa4f 100644 --- a/drivers/video/tdfxfb.c +++ b/drivers/video/tdfxfb.c @@ -1571,8 +1571,8 @@ out_err_iobase: if (default_par->mtrr_handle >= 0) mtrr_del(default_par->mtrr_handle, info->fix.smem_start, info->fix.smem_len); - release_mem_region(pci_resource_start(pdev, 2), - pci_resource_len(pdev, 2)); + release_region(pci_resource_start(pdev, 2), + pci_resource_len(pdev, 2)); out_err_screenbase: if (info->screen_base) iounmap(info->screen_base); diff --git a/fs/ceph/Kconfig b/fs/ceph/Kconfig index 04b8280582a9..4c49d18303db 100644 --- a/fs/ceph/Kconfig +++ b/fs/ceph/Kconfig @@ -25,3 +25,13 @@ config CEPH_FS_PRETTYDEBUG If unsure, say N. +config CEPH_RBD + bool "Rados block device (RBD)" + depends on CEPH_FS + select CONFIG_BLOCK + default y + help + If you say Y here, ceph will include rbd, the RADOS block + device which stripes a block device over objects stored in + the Ceph distributed object store. + diff --git a/fs/ceph/Makefile b/fs/ceph/Makefile index 6a660e610be8..d2f6326c01dc 100644 --- a/fs/ceph/Makefile +++ b/fs/ceph/Makefile @@ -18,6 +18,8 @@ ceph-objs := super.o inode.o dir.o file.o addr.o ioctl.o \ auth_x.o \ ceph_fs.o ceph_strings.o ceph_hash.o ceph_frag.o +obj-$(CONFIG_RBD) += rbd.o + else #Otherwise we were called directly from the command # line; invoke the kernel build system. diff --git a/fs/ceph/README b/fs/ceph/README index 18352fab37c0..e2046ec8e54a 100644 --- a/fs/ceph/README +++ b/fs/ceph/README @@ -7,6 +7,7 @@ src/include/ceph_fs.h fs/ceph/ceph_fs.h src/include/ceph_fs.cc fs/ceph/ceph_fs.c src/include/msgr.h fs/ceph/msgr.h src/include/rados.h fs/ceph/rados.h +src/include/rbd_types.h fs/ceph/rbd_types.h src/include/ceph_strings.cc fs/ceph/ceph_strings.c src/include/ceph_frag.h fs/ceph/ceph_frag.h src/include/ceph_frag.cc fs/ceph/ceph_frag.c diff --git a/fs/ceph/debugfs.c b/fs/ceph/debugfs.c index 3be33fb066cc..c5d6a01d1214 100644 --- a/fs/ceph/debugfs.c +++ b/fs/ceph/debugfs.c @@ -440,9 +440,14 @@ int ceph_debugfs_client_init(struct ceph_client *client) if (!client->debugfs_congestion_kb) goto out; - sprintf(name, "../../bdi/%s", dev_name(client->sb->s_bdi->dev)); - client->debugfs_bdi = debugfs_create_symlink("bdi", client->debugfs_dir, - name); + if (client->backing_dev_info.dev) { + sprintf(name, "../../bdi/%s", + dev_name(client->backing_dev_info.dev)); + client->debugfs_bdi = + debugfs_create_symlink("bdi", + client->debugfs_dir, + name); + } return 0; diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 6251a1574b94..4c21b51c833a 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -363,6 +363,52 @@ static int copy_user_to_page_vector(struct page **pages, return len; } +int ceph_copy_to_page_vector(struct page **pages, + const char *data, + loff_t off, size_t len) +{ + int i = 0; + size_t po = off & ~PAGE_CACHE_MASK; + size_t left = len; + size_t l; + + while (left > 0) { + l = min_t(size_t, PAGE_CACHE_SIZE-po, left); + memcpy(page_address(pages[i]) + po, data, l); + data += l; + left -= l; + po += l; + if (po == PAGE_CACHE_SIZE) { + po = 0; + i++; + } + } + return len; +} + +int ceph_copy_from_page_vector(struct page **pages, + char *data, + loff_t off, size_t len) +{ + int i = 0; + size_t po = off & ~PAGE_CACHE_MASK; + size_t left = len; + size_t l; + + while (left > 0) { + l = min_t(size_t, PAGE_CACHE_SIZE-po, left); + memcpy(data, page_address(pages[i]) + po, l); + data += l; + left -= l; + po += l; + if (po == PAGE_CACHE_SIZE) { + po = 0; + i++; + } + } + return len; +} + /* * copy user data from a page vector into a user pointer */ diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index 64b8b1f7863d..8785ca41becd 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -9,6 +9,8 @@ #include <linux/slab.h> #include <linux/socket.h> #include <linux/string.h> +#include <linux/bio.h> +#include <linux/blkdev.h> #include <net/tcp.h> #include "super.h" @@ -539,8 +541,11 @@ static void prepare_write_message(struct ceph_connection *con) if (le32_to_cpu(m->hdr.data_len) > 0) { /* initialize page iterator */ con->out_msg_pos.page = 0; - con->out_msg_pos.page_pos = - le16_to_cpu(m->hdr.data_off) & ~PAGE_MASK; + if (m->pages) + con->out_msg_pos.page_pos = + le16_to_cpu(m->hdr.data_off) & ~PAGE_MASK; + else + con->out_msg_pos.page_pos = 0; con->out_msg_pos.data_pos = 0; con->out_msg_pos.did_page_crc = 0; con->out_more = 1; /* data + footer will follow */ @@ -722,6 +727,31 @@ out: return ret; /* done! */ } +#ifdef CONFIG_BLOCK +static void init_bio_iter(struct bio *bio, struct bio **iter, int *seg) +{ + if (!bio) { + *iter = NULL; + *seg = 0; + return; + } + *iter = bio; + *seg = bio->bi_idx; +} + +static void iter_bio_next(struct bio **bio_iter, int *seg) +{ + if (*bio_iter == NULL) + return; + + BUG_ON(*seg >= (*bio_iter)->bi_vcnt); + + (*seg)++; + if (*seg == (*bio_iter)->bi_vcnt) + init_bio_iter((*bio_iter)->bi_next, bio_iter, seg); +} +#endif + /* * Write as much message data payload as we can. If we finish, queue * up the footer. @@ -741,9 +771,16 @@ static int write_partial_msg_pages(struct ceph_connection *con) con, con->out_msg, con->out_msg_pos.page, con->out_msg->nr_pages, con->out_msg_pos.page_pos); - while (con->out_msg_pos.page < con->out_msg->nr_pages) { +#ifdef CONFIG_BLOCK + if (msg->bio && !msg->bio_iter) + init_bio_iter(msg->bio, &msg->bio_iter, &msg->bio_seg); +#endif + + while (data_len - con->out_msg_pos.data_pos > 0) { struct page *page = NULL; void *kaddr = NULL; + int max_write = PAGE_SIZE; + int page_shift = 0; /* * if we are calculating the data crc (the default), we need @@ -759,13 +796,24 @@ static int write_partial_msg_pages(struct ceph_connection *con) struct page, lru); if (crc) kaddr = kmap(page); +#ifdef CONFIG_BLOCK + } else if (msg->bio) { + struct bio_vec *bv; + + bv = bio_iovec_idx(msg->bio_iter, msg->bio_seg); + page = bv->bv_page; + page_shift = bv->bv_offset; + if (crc) + kaddr = kmap(page) + page_shift; + max_write = bv->bv_len; +#endif } else { page = con->msgr->zero_page; if (crc) kaddr = page_address(con->msgr->zero_page); } - len = min((int)(PAGE_SIZE - con->out_msg_pos.page_pos), - (int)(data_len - con->out_msg_pos.data_pos)); + len = min_t(int, max_write - con->out_msg_pos.page_pos, + data_len - con->out_msg_pos.data_pos); if (crc && !con->out_msg_pos.did_page_crc) { void *base = kaddr + con->out_msg_pos.page_pos; u32 tmpcrc = le32_to_cpu(con->out_msg->footer.data_crc); @@ -777,11 +825,12 @@ static int write_partial_msg_pages(struct ceph_connection *con) } ret = kernel_sendpage(con->sock, page, - con->out_msg_pos.page_pos, len, + con->out_msg_pos.page_pos + page_shift, + len, MSG_DONTWAIT | MSG_NOSIGNAL | MSG_MORE); - if (crc && (msg->pages || msg->pagelist)) + if (crc && (msg->pages || msg->pagelist || msg->bio)) kunmap(page); if (ret <= 0) @@ -796,6 +845,10 @@ static int write_partial_msg_pages(struct ceph_connection *con) if (msg->pagelist) list_move_tail(&page->lru, &msg->pagelist->head); +#ifdef CONFIG_BLOCK + if (msg->bio) + iter_bio_next(&msg->bio_iter, &msg->bio_seg); +#endif } } @@ -1302,8 +1355,7 @@ static int read_partial_message_section(struct ceph_connection *con, struct kvec *section, unsigned int sec_len, u32 *crc) { - int left; - int ret; + int ret, left; BUG_ON(!section); @@ -1326,13 +1378,83 @@ static int read_partial_message_section(struct ceph_connection *con, static struct ceph_msg *ceph_alloc_msg(struct ceph_connection *con, struct ceph_msg_header *hdr, int *skip); + + +static int read_partial_message_pages(struct ceph_connection *con, + struct page **pages, + unsigned data_len, int datacrc) +{ + void *p; + int ret; + int left; + + left = min((int)(data_len - con->in_msg_pos.data_pos), + (int)(PAGE_SIZE - con->in_msg_pos.page_pos)); + /* (page) data */ + BUG_ON(pages == NULL); + p = kmap(pages[con->in_msg_pos.page]); + ret = ceph_tcp_recvmsg(con->sock, p + con->in_msg_pos.page_pos, + left); + if (ret > 0 && datacrc) + con->in_data_crc = + crc32c(con->in_data_crc, + p + con->in_msg_pos.page_pos, ret); + kunmap(pages[con->in_msg_pos.page]); + if (ret <= 0) + return ret; + con->in_msg_pos.data_pos += ret; + con->in_msg_pos.page_pos += ret; + if (con->in_msg_pos.page_pos == PAGE_SIZE) { + con->in_msg_pos.page_pos = 0; + con->in_msg_pos.page++; + } + + return ret; +} + +#ifdef CONFIG_BLOCK +static int read_partial_message_bio(struct ceph_connection *con, + struct bio **bio_iter, int *bio_seg, + unsigned data_len, int datacrc) +{ + struct bio_vec *bv = bio_iovec_idx(*bio_iter, *bio_seg); + void *p; + int ret, left; + + if (IS_ERR(bv)) + return PTR_ERR(bv); + + left = min((int)(data_len - con->in_msg_pos.data_pos), + (int)(bv->bv_len - con->in_msg_pos.page_pos)); + + p = kmap(bv->bv_page) + bv->bv_offset; + + ret = ceph_tcp_recvmsg(con->sock, p + con->in_msg_pos.page_pos, + left); + if (ret > 0 && datacrc) + con->in_data_crc = + crc32c(con->in_data_crc, + p + con->in_msg_pos.page_pos, ret); + kunmap(bv->bv_page); + if (ret <= 0) + return ret; + con->in_msg_pos.data_pos += ret; + con->in_msg_pos.page_pos += ret; + if (con->in_msg_pos.page_pos == bv->bv_len) { + con->in_msg_pos.page_pos = 0; + iter_bio_next(bio_iter, bio_seg); + } + + return ret; +} +#endif + /* * read (part of) a message. */ static int read_partial_message(struct ceph_connection *con) { struct ceph_msg *m = con->in_msg; - void *p; int ret; int to, left; unsigned front_len, middle_len, data_len, data_off; @@ -1417,7 +1539,10 @@ static int read_partial_message(struct ceph_connection *con) m->middle->vec.iov_len = 0; con->in_msg_pos.page = 0; - con->in_msg_pos.page_pos = data_off & ~PAGE_MASK; + if (m->pages) + con->in_msg_pos.page_pos = data_off & ~PAGE_MASK; + else + con->in_msg_pos.page_pos = 0; con->in_msg_pos.data_pos = 0; } @@ -1434,27 +1559,29 @@ static int read_partial_message(struct ceph_connection *con) if (ret <= 0) return ret; } +#ifdef CONFIG_BLOCK + if (m->bio && !m->bio_iter) + init_bio_iter(m->bio, &m->bio_iter, &m->bio_seg); +#endif /* (page) data */ while (con->in_msg_pos.data_pos < data_len) { - left = min((int)(data_len - con->in_msg_pos.data_pos), - (int)(PAGE_SIZE - con->in_msg_pos.page_pos)); - BUG_ON(m->pages == NULL); - p = kmap(m->pages[con->in_msg_pos.page]); - ret = ceph_tcp_recvmsg(con->sock, p + con->in_msg_pos.page_pos, - left); - if (ret > 0 && datacrc) - con->in_data_crc = - crc32c(con->in_data_crc, - p + con->in_msg_pos.page_pos, ret); - kunmap(m->pages[con->in_msg_pos.page]); - if (ret <= 0) - return ret; - con->in_msg_pos.data_pos += ret; - con->in_msg_pos.page_pos += ret; - if (con->in_msg_pos.page_pos == PAGE_SIZE) { - con->in_msg_pos.page_pos = 0; - con->in_msg_pos.page++; + if (m->pages) { + ret = read_partial_message_pages(con, m->pages, + data_len, datacrc); + if (ret <= 0) + return ret; +#ifdef CONFIG_BLOCK + } else if (m->bio) { + + ret = read_partial_message_bio(con, + &m->bio_iter, &m->bio_seg, + data_len, datacrc); + if (ret <= 0) + return ret; +#endif + } else { + BUG_ON(1); } } @@ -2130,6 +2257,9 @@ struct ceph_msg *ceph_msg_new(int type, int front_len, gfp_t flags) m->nr_pages = 0; m->pages = NULL; m->pagelist = NULL; + m->bio = NULL; + m->bio_iter = NULL; + m->bio_seg = 0; dout("ceph_msg_new %p front %d\n", m, front_len); return m; diff --git a/fs/ceph/messenger.h b/fs/ceph/messenger.h index 76fbc957bc13..aea42b9fbee3 100644 --- a/fs/ceph/messenger.h +++ b/fs/ceph/messenger.h @@ -82,6 +82,9 @@ struct ceph_msg { struct ceph_pagelist *pagelist; /* instead of pages */ struct list_head list_head; struct kref kref; + struct bio *bio; /* instead of pages/pagelist */ + struct bio *bio_iter; /* bio iterator */ + int bio_seg; /* current bio segment */ bool front_is_vmalloc; bool more_to_follow; bool needs_out_seq; diff --git a/fs/ceph/mon_client.c b/fs/ceph/mon_client.c index 21c62e9b7d1d..b319b91fb60a 100644 --- a/fs/ceph/mon_client.c +++ b/fs/ceph/mon_client.c @@ -349,7 +349,7 @@ out: } /* - * statfs + * generic requests (e.g., statfs, poolop) */ static struct ceph_mon_generic_request *__lookup_generic_req( struct ceph_mon_client *monc, u64 tid) @@ -440,6 +440,35 @@ static struct ceph_msg *get_generic_reply(struct ceph_connection *con, return m; } +static int do_generic_request(struct ceph_mon_client *monc, + struct ceph_mon_generic_request *req) +{ + int err; + + /* register request */ + mutex_lock(&monc->mutex); + req->tid = ++monc->last_tid; + req->request->hdr.tid = cpu_to_le64(req->tid); + __insert_generic_request(monc, req); + monc->num_generic_requests++; + ceph_con_send(monc->con, ceph_msg_get(req->request)); + mutex_unlock(&monc->mutex); + + err = wait_for_completion_interruptible(&req->completion); + + mutex_lock(&monc->mutex); + rb_erase(&req->node, &monc->generic_request_tree); + monc->num_generic_requests--; + mutex_unlock(&monc->mutex); + + if (!err) + err = req->result; + return err; +} + +/* + * statfs + */ static void handle_statfs_reply(struct ceph_mon_client *monc, struct ceph_msg *msg) { @@ -466,7 +495,7 @@ static void handle_statfs_reply(struct ceph_mon_client *monc, return; bad: - pr_err("corrupt generic reply, no tid\n"); + pr_err("corrupt generic reply, tid %llu\n", tid); ceph_msg_dump(msg); } @@ -485,6 +514,7 @@ int ceph_monc_do_statfs(struct ceph_mon_client *monc, struct ceph_statfs *buf) kref_init(&req->kref); req->buf = buf; + req->buf_len = sizeof(*buf); init_completion(&req->completion); err = -ENOMEM; @@ -502,33 +532,134 @@ int ceph_monc_do_statfs(struct ceph_mon_client *monc, struct ceph_statfs *buf) h->monhdr.session_mon_tid = 0; h->fsid = monc->monmap->fsid; - /* register request */ - mutex_lock(&monc->mutex); - req->tid = ++monc->last_tid; - req->request->hdr.tid = cpu_to_le64(req->tid); - __insert_generic_request(monc, req); - monc->num_generic_requests++; - mutex_unlock(&monc->mutex); + err = do_generic_request(monc, req); - /* send request and wait */ - ceph_con_send(monc->con, ceph_msg_get(req->request)); - err = wait_for_completion_interruptible(&req->completion); +out: + kref_put(&req->kref, release_generic_request); + return err; +} + +/* + * pool ops + */ +static int get_poolop_reply_buf(const char *src, size_t src_len, + char *dst, size_t dst_len) +{ + u32 buf_len; + + if (src_len != sizeof(u32) + dst_len) + return -EINVAL; + + buf_len = le32_to_cpu(*(u32 *)src); + if (buf_len != dst_len) + return -EINVAL; + + memcpy(dst, src + sizeof(u32), dst_len); + return 0; +} + +static void handle_poolop_reply(struct ceph_mon_client *monc, + struct ceph_msg *msg) +{ + struct ceph_mon_generic_request *req; + struct ceph_mon_poolop_reply *reply = msg->front.iov_base; + u64 tid = le64_to_cpu(msg->hdr.tid); + + if (msg->front.iov_len < sizeof(*reply)) + goto bad; + dout("handle_poolop_reply %p tid %llu\n", msg, tid); mutex_lock(&monc->mutex); - rb_erase(&req->node, &monc->generic_request_tree); - monc->num_generic_requests--; + req = __lookup_generic_req(monc, tid); + if (req) { + if (req->buf_len && + get_poolop_reply_buf(msg->front.iov_base + sizeof(*reply), + msg->front.iov_len - sizeof(*reply), + req->buf, req->buf_len) < 0) { + mutex_unlock(&monc->mutex); + goto bad; + } + req->result = le32_to_cpu(reply->reply_code); + get_generic_request(req); + } mutex_unlock(&monc->mutex); + if (req) { + complete(&req->completion); + put_generic_request(req); + } + return; - if (!err) - err = req->result; +bad: + pr_err("corrupt generic reply, tid %llu\n", tid); + ceph_msg_dump(msg); +} + +/* + * Do a synchronous pool op. + */ +int ceph_monc_do_poolop(struct ceph_mon_client *monc, u32 op, + u32 pool, u64 snapid, + char *buf, int len) +{ + struct ceph_mon_generic_request *req; + struct ceph_mon_poolop *h; + int err; + + req = kzalloc(sizeof(*req), GFP_NOFS); + if (!req) + return -ENOMEM; + + kref_init(&req->kref); + req->buf = buf; + req->buf_len = len; + init_completion(&req->completion); + + err = -ENOMEM; + req->request = ceph_msg_new(CEPH_MSG_POOLOP, sizeof(*h), GFP_NOFS); + if (!req->request) + goto out; + req->reply = ceph_msg_new(CEPH_MSG_POOLOP_REPLY, 1024, GFP_NOFS); + if (!req->reply) + goto out; + + /* fill out request */ + req->request->hdr.version = cpu_to_le16(2); + h = req->request->front.iov_base; + h->monhdr.have_version = 0; + h->monhdr.session_mon = cpu_to_le16(-1); + h->monhdr.session_mon_tid = 0; + h->fsid = monc->monmap->fsid; + h->pool = cpu_to_le32(pool); + h->op = cpu_to_le32(op); + h->auid = 0; + h->snapid = cpu_to_le64(snapid); + h->name_len = 0; + + err = do_generic_request(monc, req); out: kref_put(&req->kref, release_generic_request); return err; } +int ceph_monc_create_snapid(struct ceph_mon_client *monc, + u32 pool, u64 *snapid) +{ + return ceph_monc_do_poolop(monc, POOL_OP_CREATE_UNMANAGED_SNAP, + pool, 0, (char *)snapid, sizeof(*snapid)); + +} + +int ceph_monc_delete_snapid(struct ceph_mon_client *monc, + u32 pool, u64 snapid) +{ + return ceph_monc_do_poolop(monc, POOL_OP_CREATE_UNMANAGED_SNAP, + pool, snapid, 0, 0); + +} + /* - * Resend pending statfs requests. + * Resend pending generic requests. */ static void __resend_generic_request(struct ceph_mon_client *monc) { @@ -780,12 +911,17 @@ static void dispatch(struct ceph_connection *con, struct ceph_msg *msg) handle_statfs_reply(monc, msg); break; + case CEPH_MSG_POOLOP_REPLY: + handle_poolop_reply(monc, msg); + break; + case CEPH_MSG_MON_MAP: ceph_monc_handle_map(monc, msg); break; case CEPH_MSG_MDS_MAP: - ceph_mdsc_handle_map(&monc->client->mdsc, msg); + if (monc->client->have_mdsc) + ceph_mdsc_handle_map(&monc->client->mdsc, msg); break; case CEPH_MSG_OSD_MAP: @@ -817,6 +953,7 @@ static struct ceph_msg *mon_alloc_msg(struct ceph_connection *con, case CEPH_MSG_MON_SUBSCRIBE_ACK: m = ceph_msg_get(monc->m_subscribe_ack); break; + case CEPH_MSG_POOLOP_REPLY: case CEPH_MSG_STATFS_REPLY: return get_generic_reply(con, hdr, skip); case CEPH_MSG_AUTH_REPLY: diff --git a/fs/ceph/mon_client.h b/fs/ceph/mon_client.h index 174d794321d0..8e396f2c0963 100644 --- a/fs/ceph/mon_client.h +++ b/fs/ceph/mon_client.h @@ -50,6 +50,7 @@ struct ceph_mon_generic_request { struct rb_node node; int result; void *buf; + int buf_len; struct completion completion; struct ceph_msg *request; /* original request */ struct ceph_msg *reply; /* and reply */ @@ -111,6 +112,10 @@ extern int ceph_monc_open_session(struct ceph_mon_client *monc); extern int ceph_monc_validate_auth(struct ceph_mon_client *monc); +extern int ceph_monc_create_snapid(struct ceph_mon_client *monc, + u32 pool, u64 *snapid); +extern int ceph_monc_delete_snapid(struct ceph_mon_client *monc, + u32 pool, u64 snapid); #endif diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index d25b4add85b4..d7515e89573f 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -6,6 +6,9 @@ #include <linux/pagemap.h> #include <linux/slab.h> #include <linux/uaccess.h> +#ifdef CONFIG_BLOCK +#include <linux/bio.h> +#endif #include "super.h" #include "osd_client.h" @@ -22,6 +25,35 @@ static int __kick_requests(struct ceph_osd_client *osdc, static void kick_requests(struct ceph_osd_client *osdc, struct ceph_osd *osd); +void ceph_calc_raw_layout(struct ceph_osd_client *osdc, + struct ceph_file_layout *layout, + u64 snapid, + u64 off, u64 len, u64 *bno, + struct ceph_osd_request *req) +{ + struct ceph_osd_request_head *reqhead = req->r_request->front.iov_base; + struct ceph_osd_op *op = (void *)(reqhead + 1); + u64 orig_len = len; + u64 objoff, objlen; /* extent in object */ + + reqhead->snapid = cpu_to_le64(snapid); + + /* object extent? */ + ceph_calc_file_object_mapping(layout, off, &len, bno, + &objoff, &objlen); + if (len < orig_len) + dout(" skipping last %llu, final file extent %llu~%llu\n", + orig_len - len, off, len); + + op->extent.offset = cpu_to_le64(objoff); + op->extent.length = cpu_to_le64(objlen); + req->r_num_pages = calc_pages_for(off, len); + + dout("calc_layout bno=%llx %llu~%llu (%d pages)\n", + *bno, objoff, objlen, req->r_num_pages); + +} + /* * Implement client access to distributed object storage cluster. * @@ -48,34 +80,17 @@ static void kick_requests(struct ceph_osd_client *osdc, struct ceph_osd *osd); * fill osd op in request message. */ static void calc_layout(struct ceph_osd_client *osdc, - struct ceph_vino vino, struct ceph_file_layout *layout, + struct ceph_vino vino, + struct ceph_file_layout *layout, u64 off, u64 *plen, struct ceph_osd_request *req) { - struct ceph_osd_request_head *reqhead = req->r_request->front.iov_base; - struct ceph_osd_op *op = (void *)(reqhead + 1); - u64 orig_len = *plen; - u64 objoff, objlen; /* extent in object */ u64 bno; - reqhead->snapid = cpu_to_le64(vino.snap); - - /* object extent? */ - ceph_calc_file_object_mapping(layout, off, plen, &bno, - &objoff, &objlen); - if (*plen < orig_len) - dout(" skipping last %llu, final file extent %llu~%llu\n", - orig_len - *plen, off, *plen); + ceph_calc_raw_layout(osdc, layout, vino.snap, off, *plen, &bno, req); sprintf(req->r_oid, "%llx.%08llx", vino.ino, bno); req->r_oid_len = strlen(req->r_oid); - - op->extent.offset = cpu_to_le64(objoff); - op->extent.length = cpu_to_le64(objlen); - req->r_num_pages = calc_pages_for(off, *plen); - - dout("calc_layout %s (%d) %llu~%llu (%d pages)\n", - req->r_oid, req->r_oid_len, objoff, objlen, req->r_num_pages); } /* @@ -101,6 +116,10 @@ void ceph_osdc_release_request(struct kref *kref) if (req->r_own_pages) ceph_release_page_vector(req->r_pages, req->r_num_pages); +#ifdef CONFIG_BLOCK + if (req->r_bio) + bio_put(req->r_bio); +#endif ceph_put_snap_context(req->r_snapc); if (req->r_mempool) mempool_free(req, req->r_osdc->req_mempool); @@ -108,43 +127,35 @@ void ceph_osdc_release_request(struct kref *kref) kfree(req); } -/* - * build new request AND message, calculate layout, and adjust file - * extent as needed. - * - * if the file was recently truncated, we include information about its - * old and new size so that the object can be updated appropriately. (we - * avoid synchronously deleting truncated objects because it's slow.) - * - * if @do_sync, include a 'startsync' command so that the osd will flush - * data quickly. - */ -struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc, - struct ceph_file_layout *layout, - struct ceph_vino vino, - u64 off, u64 *plen, - int opcode, int flags, +struct ceph_osd_request *ceph_osdc_alloc_request(struct ceph_osd_client *osdc, + int flags, struct ceph_snap_context *snapc, int do_sync, - u32 truncate_seq, - u64 truncate_size, - struct timespec *mtime, - bool use_mempool, int num_reply) + bool use_mempool, + gfp_t gfp_flags, + struct page **pages, + struct bio *bio) { struct ceph_osd_request *req; struct ceph_msg *msg; - struct ceph_osd_request_head *head; - struct ceph_osd_op *op; - void *p; int num_op = 1 + do_sync; - size_t msg_size = sizeof(*head) + num_op*sizeof(*op); - int i; + size_t msg_size = sizeof(struct ceph_osd_request_head) + + num_op*sizeof(struct ceph_osd_op); + + if (use_mempool) { + req = mempool_alloc(osdc->req_mempool, gfp_flags); + memset(req, 0, sizeof(*req)); + } else { + req = kzalloc(sizeof(*req), gfp_flags); + } + if (!req) + return NULL; if (use_mempool) { - req = mempool_alloc(osdc->req_mempool, GFP_NOFS); + req = mempool_alloc(osdc->req_mempool, gfp_flags); memset(req, 0, sizeof(*req)); } else { - req = kzalloc(sizeof(*req), GFP_NOFS); + req = kzalloc(sizeof(*req), gfp_flags); } if (req == NULL) return NULL; @@ -164,7 +175,7 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc, msg = ceph_msgpool_get(&osdc->msgpool_op_reply, 0); else msg = ceph_msg_new(CEPH_MSG_OSD_OPREPLY, - OSD_OPREPLY_FRONT_LEN, GFP_NOFS); + OSD_OPREPLY_FRONT_LEN, gfp_flags); if (!msg) { ceph_osdc_put_request(req); return NULL; @@ -178,18 +189,54 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc, if (use_mempool) msg = ceph_msgpool_get(&osdc->msgpool_op, 0); else - msg = ceph_msg_new(CEPH_MSG_OSD_OP, msg_size, GFP_NOFS); + msg = ceph_msg_new(CEPH_MSG_OSD_OP, msg_size, gfp_flags); if (!msg) { ceph_osdc_put_request(req); return NULL; } msg->hdr.type = cpu_to_le16(CEPH_MSG_OSD_OP); memset(msg->front.iov_base, 0, msg->front.iov_len); + + req->r_request = msg; + req->r_pages = pages; +#ifdef CONFIG_BLOCK + if (bio) { + req->r_bio = bio; + bio_get(req->r_bio); + } +#endif + + return req; +} + +/* + * build new request AND message + * + */ +void ceph_osdc_build_request(struct ceph_osd_request *req, + u64 off, u64 *plen, + int opcode, + struct ceph_snap_context *snapc, + int do_sync, + u32 truncate_seq, + u64 truncate_size, + struct timespec *mtime, + const char *oid, + int oid_len) +{ + struct ceph_msg *msg = req->r_request; + struct ceph_osd_request_head *head; + struct ceph_osd_op *op; + void *p; + int num_op = 1 + do_sync; + size_t msg_size = sizeof(*head) + num_op*sizeof(*op); + int i; + int flags = req->r_flags; + head = msg->front.iov_base; op = (void *)(head + 1); p = (void *)(op + num_op); - req->r_request = msg; req->r_snapc = ceph_get_snap_context(snapc); head->client_inc = cpu_to_le32(1); /* always, for now. */ @@ -199,10 +246,6 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc, head->num_ops = cpu_to_le16(num_op); op->op = cpu_to_le16(opcode); - /* calculate max write size */ - calc_layout(osdc, vino, layout, off, plen, req); - req->r_file_layout = *layout; /* keep a copy */ - if (flags & CEPH_OSD_FLAG_WRITE) { req->r_request->hdr.data_off = cpu_to_le16(off); req->r_request->hdr.data_len = cpu_to_le32(*plen); @@ -212,9 +255,9 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc, op->extent.truncate_seq = cpu_to_le32(truncate_seq); /* fill in oid */ - head->object_len = cpu_to_le32(req->r_oid_len); - memcpy(p, req->r_oid, req->r_oid_len); - p += req->r_oid_len; + head->object_len = cpu_to_le32(oid_len); + memcpy(p, oid, oid_len); + p += oid_len; if (do_sync) { op++; @@ -233,6 +276,50 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc, msg_size = p - msg->front.iov_base; msg->front.iov_len = msg_size; msg->hdr.front_len = cpu_to_le32(msg_size); + return; +} + +/* + * build new request AND message, calculate layout, and adjust file + * extent as needed. + * + * if the file was recently truncated, we include information about its + * old and new size so that the object can be updated appropriately. (we + * avoid synchronously deleting truncated objects because it's slow.) + * + * if @do_sync, include a 'startsync' command so that the osd will flush + * data quickly. + */ +struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc, + struct ceph_file_layout *layout, + struct ceph_vino vino, + u64 off, u64 *plen, + int opcode, int flags, + struct ceph_snap_context *snapc, + int do_sync, + u32 truncate_seq, + u64 truncate_size, + struct timespec *mtime, + bool use_mempool, int num_reply) +{ + struct ceph_osd_request *req = + ceph_osdc_alloc_request(osdc, flags, + snapc, do_sync, + use_mempool, + GFP_NOFS, NULL, NULL); + if (IS_ERR(req)) + return req; + + /* calculate max write size */ + calc_layout(osdc, vino, layout, off, plen, req); + req->r_file_layout = *layout; /* keep a copy */ + + ceph_osdc_build_request(req, off, plen, opcode, + snapc, do_sync, + truncate_seq, truncate_size, + mtime, + req->r_oid, req->r_oid_len); + return req; } @@ -1104,6 +1191,9 @@ int ceph_osdc_start_request(struct ceph_osd_client *osdc, req->r_request->pages = req->r_pages; req->r_request->nr_pages = req->r_num_pages; +#ifdef CONFIG_BLOCK + req->r_request->bio = req->r_bio; +#endif register_request(osdc, req); @@ -1422,6 +1512,9 @@ static struct ceph_msg *get_reply(struct ceph_connection *con, } m->pages = req->r_pages; m->nr_pages = req->r_num_pages; +#ifdef CONFIG_BLOCK + m->bio = req->r_bio; +#endif } *skip = 0; req->r_con_filling_msg = ceph_con_get(con); diff --git a/fs/ceph/osd_client.h b/fs/ceph/osd_client.h index ce776989ef6a..2daa3fcae63e 100644 --- a/fs/ceph/osd_client.h +++ b/fs/ceph/osd_client.h @@ -68,6 +68,7 @@ struct ceph_osd_request { struct list_head r_unsafe_item; struct inode *r_inode; /* for use by callbacks */ + void *r_priv; /* ditto */ char r_oid[40]; /* object name */ int r_oid_len; @@ -80,6 +81,9 @@ struct ceph_osd_request { struct page **r_pages; /* pages for data payload */ int r_pages_from_pool; int r_own_pages; /* if true, i own page list */ +#ifdef CONFIG_BLOCK + struct bio *r_bio; /* instead of pages */ +#endif }; struct ceph_osd_client { @@ -119,6 +123,32 @@ extern void ceph_osdc_handle_reply(struct ceph_osd_client *osdc, extern void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg); +extern void ceph_calc_raw_layout(struct ceph_osd_client *osdc, + struct ceph_file_layout *layout, + u64 snapid, + u64 off, u64 len, u64 *bno, + struct ceph_osd_request *req); + +extern struct ceph_osd_request *ceph_osdc_alloc_request(struct ceph_osd_client *osdc, + int flags, + struct ceph_snap_context *snapc, + int do_sync, + bool use_mempool, + gfp_t gfp_flags, + struct page **pages, + struct bio *bio); + +extern void ceph_osdc_build_request(struct ceph_osd_request *req, + u64 off, u64 *plen, + int opcode, + struct ceph_snap_context *snapc, + int do_sync, + u32 truncate_seq, + u64 truncate_size, + struct timespec *mtime, + const char *oid, + int oid_len); + extern struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *, struct ceph_file_layout *layout, struct ceph_vino vino, diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c index ddc656fb5c05..11aac1c60943 100644 --- a/fs/ceph/osdmap.c +++ b/fs/ceph/osdmap.c @@ -417,6 +417,19 @@ static struct ceph_pg_pool_info *__lookup_pg_pool(struct rb_root *root, int id) return NULL; } +int ceph_pg_poolid_by_name(struct ceph_osdmap *map, const char *name) +{ + struct rb_node *rbp; + + for (rbp = rb_first(&map->pg_pools); rbp; rbp = rb_next(rbp)) { + struct ceph_pg_pool_info *pi = + rb_entry(rbp, struct ceph_pg_pool_info, node); + if (pi->name && strcmp(pi->name, name) == 0) + return pi->id; + } + return -ENOENT; +} + static void __remove_pg_pool(struct rb_root *root, struct ceph_pg_pool_info *pi) { rb_erase(&pi->node, root); diff --git a/fs/ceph/osdmap.h b/fs/ceph/osdmap.h index 970b547e510d..a592b211be39 100644 --- a/fs/ceph/osdmap.h +++ b/fs/ceph/osdmap.h @@ -125,4 +125,6 @@ extern int ceph_calc_pg_acting(struct ceph_osdmap *osdmap, struct ceph_pg pgid, extern int ceph_calc_pg_primary(struct ceph_osdmap *osdmap, struct ceph_pg pgid); +extern int ceph_pg_poolid_by_name(struct ceph_osdmap *map, const char *name); + #endif diff --git a/fs/ceph/rbd.c b/fs/ceph/rbd.c new file mode 100644 index 000000000000..a745f3f3481c --- /dev/null +++ b/fs/ceph/rbd.c @@ -0,0 +1,1803 @@ +/* + rbd.c -- Export ceph rados objects as a Linux block device + + + based on drivers/block/osdblk.c: + + Copyright 2009 Red Hat, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + + + + Instructions for use + -------------------- + + 1) Map a Linux block device to an existing rbd image. + + Usage: <mon ip addr> <options> <pool name> <rbd image name> + + $ echo "192.168.0.1 name=admin rbd foo" > /sys/class/rbd/add + + + 2) List all active blkdev<->object mappings. + + In this example, we have performed step #1 twice, creating two blkdevs, + mapped to two separate rados objects in the rados rbd pool + + $ cat /sys/class/rbd/list + 0 254 rbd foo + 1 253 rbd bar + + The columns, in order, are: + - blkdev unique id + - blkdev assigned major + - rados pool name + - rados block device name + + + 3) Remove an active blkdev<->rbd image mapping. + + In this example, we remove the mapping with blkdev unique id 1. + + $ echo 1 > /sys/class/rbd/remove + + + NOTE: The actual creation and deletion of rados objects is outside the scope + of this driver. + + */ + +#include "super.h" +#include "osd_client.h" +#include "rbd_types.h" +#include "mon_client.h" + +#include <linux/kernel.h> +#include <linux/device.h> +#include <linux/module.h> +#include <linux/fs.h> +#include <linux/blkdev.h> + +#define DRV_NAME "rbd" +#define DRV_NAME_LONG "rbd (rados block device)" + +enum { + RBD_MINORS_PER_MAJOR = 256, /* max minors per blkdev */ +}; + +#define RBD_MAX_POOL_NAME_SIZE 64 + +#define RBD_STRIPE_UNIT (1 << 22) + +#define RBD_MAX_OPT_LEN 1024 +#define RBD_MAX_SNAP_NAME_LEN 32 + +#define RBD_SNAP_OP_CREATE 0x1 +#define RBD_SNAP_OP_SET 0x2 + +#define RBD_SNAP_HEAD_NAME "head" + +struct rbd_obj_header { + u64 image_size; + __u8 obj_order; + __u8 crypt_type; + __u8 comp_type; + struct rw_semaphore snap_rwsem; + struct ceph_snap_context *snapc; + size_t snap_names_len; + u32 snap_seq; + u32 total_snaps; + + char *snap_names; + u64 *snap_sizes; +}; + +struct rbd_request { + struct request *rq; /* blk layer request */ + struct bio *bio; /* cloned bio */ + struct page **pages; /* list of used pages */ + u64 len; +}; + +struct rbd_client_node { + struct ceph_client *client; + const char *opt; + struct kref kref; + struct list_head node; +}; + +#define DEV_NAME_LEN 32 + +struct rbd_device { + int id; /* blkdev unique id */ + + int major; /* blkdev assigned major */ + struct gendisk *disk; /* blkdev's gendisk and rq */ + struct request_queue *q; + + struct ceph_client *client; /* associated OSD */ + + char name[DEV_NAME_LEN]; /* blkdev name, e.g. rbd3 */ + + spinlock_t lock; /* queue lock */ + + struct rbd_obj_header header; + char obj[RBD_MAX_OBJ_NAME_SIZE]; /* rbd image name */ + int obj_len; + char pool_name[RBD_MAX_POOL_NAME_SIZE]; + int poolid; + + u32 cur_snap; /* index+1 of current snapshot within snap context + 0 - for the head */ + int read_only; + + struct list_head node; + struct rbd_client_node *client_node; +}; + +static spinlock_t node_lock; /* protects client get/put */ + +static struct class *class_rbd; /* /sys/class/rbd */ +static DEFINE_MUTEX(ctl_mutex); /* Serialize open/close/setup/teardown */ +static LIST_HEAD(rbddev_list); +static LIST_HEAD(node_list); + + +static int rbd_open(struct block_device *bdev, fmode_t mode) +{ + struct gendisk *disk = bdev->bd_disk; + struct rbd_device *rbd_dev = disk->private_data; + + if (mode & FMODE_WRITE && rbd_dev->read_only) + return -EROFS; + + return 0; +} + +static const struct block_device_operations rbd_bd_ops = { + .owner = THIS_MODULE, + .open = rbd_open, +}; + +/* + * Initialize ceph client for a specific device. + */ +static int rbd_init_client(struct rbd_device *rbd_dev, + struct ceph_mount_args *args) +{ + struct ceph_osd_client *osdc; + int ret; + dout("rbd_init_device\n"); + rbd_dev->client = ceph_create_client(args, 0); + if (IS_ERR(rbd_dev->client)) + return PTR_ERR(rbd_dev->client); + + ret = ceph_open_session(rbd_dev->client); + if (ret < 0) + goto done_err; + + osdc = &rbd_dev->client->osdc; + ret = ceph_pg_poolid_by_name(osdc->osdmap, + rbd_dev->pool_name); + if (ret < 0) + goto done_err; + + rbd_dev->poolid = ret; + return 0; + +done_err: + ceph_destroy_client(rbd_dev->client); + rbd_dev->client = NULL; + return ret; +} + +/* + * Find a ceph client with specific addr and configuration. + */ +static struct rbd_client_node *__get_client_node(struct ceph_mount_args *args) +{ + struct rbd_client_node *client_node; + + if (args->flags & CEPH_OPT_NOSHARE) + return NULL; + + list_for_each_entry(client_node, &node_list, node) + if (ceph_compare_mount_args(args, client_node->client) == 0) + return client_node; + return NULL; +} + +/* + * Get a ceph client with specific addr and configuration, if one does + * not exist create it. + */ +static int rbd_get_client(struct rbd_device *rbd_dev, const char *mon_addr, + char *opt) +{ + struct rbd_client_node *client_node; + struct ceph_mount_args *args; + int ret; + + + args = parse_mount_args(0, opt, mon_addr, NULL); + if (IS_ERR(args)) + return PTR_ERR(args); + + spin_lock(&node_lock); + + client_node = __get_client_node(args); + if (client_node) { + ceph_destroy_mount_args(args); + + kref_get(&client_node->kref); + rbd_dev->client_node = client_node; + rbd_dev->client = client_node->client; + spin_unlock(&node_lock); + return 0; + } + + spin_unlock(&node_lock); + + ret = -ENOMEM; + client_node = kmalloc(sizeof(struct rbd_client_node), GFP_KERNEL); + if (!client_node) + goto out_args; + + ret = rbd_init_client(rbd_dev, args); + if (ret < 0) + goto out_free; + + client_node->client = rbd_dev->client; + client_node->opt = kstrdup(opt, GFP_KERNEL); + kref_init(&client_node->kref); + INIT_LIST_HEAD(&client_node->node); + + rbd_dev->client_node = client_node; + + spin_lock(&node_lock); + list_add_tail(&client_node->node, &node_list); + spin_unlock(&node_lock); + + return 0; + +out_free: + kfree(client_node); +out_args: + ceph_destroy_mount_args(args); + return ret; +} + +/* + * Destroy ceph client + */ +static void rbd_release_client(struct kref *kref) +{ + struct rbd_client_node *node = + container_of(kref, struct rbd_client_node, kref); + + dout("rbd_release_client\n"); + + spin_lock(&node_lock); + list_del(&node->node); + spin_unlock(&node_lock); + + ceph_destroy_client(node->client); + kfree(node->opt); + kfree(node); +} + +/* + * Drop reference to ceph client node. If it's not referenced anymore, release + * it. + */ +static void rbd_put_client(struct rbd_device *rbd_dev) +{ + if (!rbd_dev->client_node) + return; + + kref_put(&rbd_dev->client_node->kref, rbd_release_client); + rbd_dev->client_node = NULL; +} + +static int snap_index(struct rbd_obj_header *header, int snap_num) +{ + return header->total_snaps - snap_num; +} + +static u64 cur_snap_id(struct rbd_device *rbd_dev) +{ + struct rbd_obj_header *header = &rbd_dev->header; + + if (!rbd_dev->cur_snap) + return 0; + + return header->snapc->snaps[snap_index(header, rbd_dev->cur_snap)]; +} + + +/* + * Create a new header structure, translate header format from the on-disk + * header. + */ +static int rbd_header_from_disk(struct rbd_obj_header *header, + struct rbd_obj_header_ondisk *ondisk, + int allocated_snaps, + gfp_t gfp_flags) +{ + int i; + u32 snap_count = le32_to_cpu(ondisk->snap_count); + int ret = -ENOMEM; + + init_rwsem(&header->snap_rwsem); + + header->snap_names_len = le64_to_cpu(ondisk->snap_names_len); + header->snapc = kmalloc(sizeof(struct ceph_snap_context) + + snap_count * + sizeof(struct rbd_obj_snap_ondisk), + gfp_flags); + if (!header->snapc) + return -ENOMEM; + if (snap_count) { + header->snap_names = kmalloc(header->snap_names_len, + GFP_KERNEL); + if (!header->snap_names) + goto err_snapc; + header->snap_sizes = kmalloc(snap_count * sizeof(u64), + GFP_KERNEL); + if (!header->snap_sizes) + goto err_names; + } else { + header->snap_names = NULL; + header->snap_sizes = NULL; + } + + header->image_size = le64_to_cpu(ondisk->image_size); + header->obj_order = ondisk->obj_order; + header->crypt_type = ondisk->crypt_type; + header->comp_type = ondisk->comp_type; + + atomic_set(&header->snapc->nref, 1); + header->snap_seq = le32_to_cpu(ondisk->snap_seq); + header->snapc->num_snaps = snap_count; + header->total_snaps = snap_count; + + if (snap_count && + allocated_snaps == snap_count) { + for (i = 0; i < snap_count; i++) { + header->snapc->snaps[i] = + le64_to_cpu(ondisk->snaps[i].id); + header->snap_sizes[i] = + le64_to_cpu(ondisk->snaps[i].image_size); + } + + /* copy snapshot names */ + memcpy(header->snap_names, &ondisk->snaps[i], + header->snap_names_len); + } + + return 0; + +err_names: + kfree(header->snap_names); +err_snapc: + kfree(header->snapc); + return ret; +} + +/* + * Create a new header structure, translate header format from the on-disk + * header. + */ +static int rbd_header_to_disk(struct rbd_obj_header_ondisk **ondisk, + struct rbd_obj_header_ondisk *old_ondisk, + struct rbd_obj_header *header, + gfp_t gfp_flags) +{ + int i; + + down_read(&header->snap_rwsem); + *ondisk = kmalloc(sizeof(struct rbd_obj_header_ondisk) + + header->snap_names_len + + header->total_snaps * + sizeof(struct rbd_obj_snap_ondisk), + gfp_flags); + if (!*ondisk) + return -ENOMEM; + + memcpy(*ondisk, old_ondisk, sizeof(*old_ondisk)); + + (*ondisk)->snap_seq = cpu_to_le32(header->snap_seq); + (*ondisk)->snap_count = cpu_to_le32(header->total_snaps); + (*ondisk)->snap_names_len = cpu_to_le64(header->snap_names_len); + + if (header->total_snaps) { + for (i = 0; i < header->total_snaps; i++) { + (*ondisk)->snaps[i].id = + cpu_to_le64(header->snapc->snaps[i]); + (*ondisk)->snaps[i].image_size = + cpu_to_le64(header->snap_sizes[i]); + } + + /* copy snapshot names */ + memcpy(&(*ondisk)->snaps[i], header->snap_names, + header->snap_names_len); + } + up_read(&header->snap_rwsem); + + return 0; +} + +static int rbd_header_add_snap(struct rbd_device *dev, + const char *snap_name, + gfp_t gfp_flags) +{ + struct rbd_obj_header *header = &dev->header; + struct ceph_snap_context *new_snapc; + char *p; + int name_len = strlen(snap_name); + u64 *snaps = header->snapc->snaps; + u64 *new_sizes; + char *new_names; + u64 new_snapid; + int i; + int ret = -EINVAL; + + down_write(&header->snap_rwsem); + + /* we can create a snapshot only if we're pointing at the head */ + if (dev->cur_snap) + goto done; + + ret = -EEXIST; + p = header->snap_names; + for (i = 0; i < header->total_snaps; i++, p += strlen(p) + 1) { + if (strcmp(snap_name, p) == 0) + goto done; + } + + ret = -ENOMEM; + new_snapc = kmalloc(sizeof(struct rbd_obj_header) + + (header->total_snaps + 1) * sizeof(u64), + gfp_flags); + if (!new_snapc) + goto done; + new_names = kmalloc(header->snap_names_len + name_len + 1, gfp_flags); + if (!new_names) + goto err_snapc; + new_sizes = kmalloc((header->total_snaps + 1) * sizeof(u64), + gfp_flags); + if (!new_sizes) + goto err_names; + + atomic_set(&new_snapc->nref, 1); + new_snapc->num_snaps = header->total_snaps + 1; + if (header->total_snaps) + memcpy(&new_snapc->snaps[1], snaps, + (header->total_snaps) * sizeof(u64)); + + ret = ceph_monc_create_snapid(&dev->client->monc, dev->poolid, + &new_snapid); + dout("created snapid=%lld\n", new_snapid); + if (ret < 0) + goto err_sizes; + + new_snapc->seq = new_snapid; /* we're still pointing at the head */ + header->snap_seq = new_snapid; + new_snapc->snaps[0] = new_snapid; + + /* copy snap names */ + if (header->snap_names) + memcpy(new_names + name_len + 1, header->snap_names, + header->snap_names_len); + + memcpy(new_names, snap_name, name_len + 1); + header->snap_names_len += name_len + 1; + + /* copy snap image sizes */ + if (header->snap_sizes) + memcpy(new_sizes, header->snap_sizes, + header->total_snaps * sizeof(u64)); + new_sizes[new_snapc->num_snaps - 1] = header->image_size; + + header->total_snaps = new_snapc->num_snaps; + + kfree(header->snapc); + header->snapc = new_snapc; + kfree(header->snap_names); + header->snap_names = new_names; + kfree(header->snap_sizes); + header->snap_sizes = new_sizes; + + ret = 0; +done: + up_write(&header->snap_rwsem); + return ret; +err_sizes: + kfree(new_sizes); +err_names: + kfree(new_names); +err_snapc: + kfree(new_snapc); + up_write(&header->snap_rwsem); + return ret; +} + +static int rbd_header_set_snap(struct rbd_device *dev, + const char *snap_name, + u64 *size) +{ + struct rbd_obj_header *header = &dev->header; + struct ceph_snap_context *snapc = header->snapc; + char *p; + int i; + int ret = -ENOENT; + + down_write(&header->snap_rwsem); + + if (!snap_name || + !*snap_name || + strcmp(snap_name, "-") == 0 || + strcmp(snap_name, RBD_SNAP_HEAD_NAME) == 0) { + if (header->total_snaps) + snapc->seq = header->snap_seq; + else + snapc->seq = 0; + dev->cur_snap = 0; + dev->read_only = 0; + if (size) + *size = header->image_size; + } else { + p = header->snap_names; + for (i = 0; i < header->total_snaps; i++, p += strlen(p) + 1) { + if (strcmp(snap_name, p) == 0) + break; + } + if (i == header->total_snaps) + goto done; + + snapc->seq = snapc->snaps[i]; + dev->cur_snap = header->total_snaps - i; + dev->read_only = 1; + if (size) + *size = header->snap_sizes[i]; + } + + ret = 0; +done: + up_write(&header->snap_rwsem); + return ret; +} + +static void rbd_header_free(struct rbd_obj_header *header) +{ + kfree(header->snapc); + kfree(header->snap_names); + kfree(header->snap_sizes); +} + +/* + * get the actual striped segment name, offset and length + */ +static u64 rbd_get_segment(struct rbd_obj_header *header, + const char *obj_name, + u64 ofs, u64 len, + char *seg_name, u64 *segofs) +{ + u64 seg = ofs >> header->obj_order; + + if (seg_name) + snprintf(seg_name, RBD_MAX_SEG_NAME_SIZE, + "%s.%012llx", obj_name, seg); + + ofs = ofs & ((1 << header->obj_order) - 1); + len = min_t(u64, len, (1 << header->obj_order) - ofs); + + if (segofs) + *segofs = ofs; + + return len; +} + +static void bio_chain_put(struct bio *chain) +{ + struct bio *tmp; + + while (chain) { + tmp = chain; + chain = chain->bi_next; + + bio_put(tmp); + } +} + +/* + * zeros a bio chain, starting at specific offset + */ +static void zero_bio_chain(struct bio *chain, int start_ofs) +{ + struct bio_vec *bv; + unsigned long flags; + void *buf; + int i; + int pos = 0; + + while (chain) { + bio_for_each_segment(bv, chain, i) { + if (pos + bv->bv_len > start_ofs) { + int remainder = max(start_ofs - pos, 0); + buf = bvec_kmap_irq(bv, &flags); + memset(buf + remainder, 0, + bv->bv_len - remainder); + bvec_kunmap_irq(bv, &flags); + } + pos += bv->bv_len; + } + + chain = chain->bi_next; + } +} + +/* + * bio_chain_clone - clone a chain of bios up to a certain length. + * might return a bio_pair that will need to be released. + */ +static struct bio *bio_chain_clone(struct bio **old, struct bio **next, + struct bio_pair **bp, + int len, gfp_t gfpmask) +{ + struct bio *tmp, *old_chain = *old, *new_chain = NULL, *tail = NULL; + int total = 0; + + if (*bp) { + bio_pair_release(*bp); + *bp = NULL; + } + + while (old_chain && (total < len)) { + tmp = bio_kmalloc(gfpmask, old_chain->bi_max_vecs); + if (!tmp) + goto err_out; + + if (total + old_chain->bi_size > len) { + struct bio_pair *bp; + + /* + * this split can only happen with a single paged bio, + * split_bio will BUG_ON if this is not the case + */ + dout("bio_chain_clone split! total=%d remaining=%d" + "bi_size=%d\n", + (int)total, (int)len-total, + (int)old_chain->bi_size); + + /* split the bio. We'll release it either in the next + call, or it will have to be released outside */ + bp = bio_split(old_chain, (len - total) / 512ULL); + if (!bp) + goto err_out; + + __bio_clone(tmp, &bp->bio1); + + *next = &bp->bio2; + } else { + __bio_clone(tmp, old_chain); + *next = old_chain->bi_next; + } + + tmp->bi_bdev = NULL; + gfpmask &= ~__GFP_WAIT; + tmp->bi_next = NULL; + + if (!new_chain) { + new_chain = tail = tmp; + } else { + tail->bi_next = tmp; + tail = tmp; + } + old_chain = old_chain->bi_next; + + total += tmp->bi_size; + } + + BUG_ON(total < len); + + if (tail) + tail->bi_next = NULL; + + *old = old_chain; + + return new_chain; + +err_out: + dout("bio_chain_clone with err\n"); + bio_chain_put(new_chain); + return NULL; +} + +/* + * Send ceph osd request + */ +static int rbd_do_request(struct request *rq, + struct rbd_device *dev, + struct ceph_snap_context *snapc, + u64 snapid, + const char *obj, u64 ofs, u64 len, + struct bio *bio, + struct page **pages, + int num_pages, + int opcode, int flags, + int num_reply, + void (*rbd_cb)(struct ceph_osd_request *req, + struct ceph_msg *msg)) +{ + struct ceph_osd_request *req; + struct ceph_file_layout *layout; + int ret; + u64 bno; + struct timespec mtime = CURRENT_TIME; + struct rbd_request *req_data; + struct ceph_osd_request_head *reqhead; + struct rbd_obj_header *header = &dev->header; + + ret = -ENOMEM; + req_data = kzalloc(sizeof(*req_data), GFP_NOFS); + if (!req_data) + goto done; + + dout("rbd_do_request len=%lld ofs=%lld\n", len, ofs); + + down_read(&header->snap_rwsem); + + req = ceph_osdc_alloc_request(&dev->client->osdc, flags, + snapc, 0, + false, + GFP_NOFS, pages, bio); + if (IS_ERR(req)) { + up_read(&header->snap_rwsem); + ret = PTR_ERR(req); + goto done_pages; + } + + req->r_callback = rbd_cb; + + req_data->rq = rq; + req_data->bio = bio; + req_data->pages = pages; + req_data->len = len; + + req->r_priv = req_data; + + reqhead = req->r_request->front.iov_base; + reqhead->snapid = cpu_to_le64(CEPH_NOSNAP); + + strncpy(req->r_oid, obj, sizeof(req->r_oid)); + req->r_oid_len = strlen(req->r_oid); + + layout = &req->r_file_layout; + memset(layout, 0, sizeof(*layout)); + layout->fl_stripe_unit = RBD_STRIPE_UNIT; + layout->fl_stripe_count = 1; + layout->fl_object_size = RBD_STRIPE_UNIT; + layout->fl_pg_preferred = -1; + layout->fl_pg_pool = dev->poolid; + ceph_calc_raw_layout(&dev->client->osdc, layout, snapid, + ofs, len, &bno, req); + + ceph_osdc_build_request(req, ofs, &len, opcode, + snapc, 0, + 0, 0, + &mtime, + req->r_oid, req->r_oid_len); + up_read(&header->snap_rwsem); + + ret = ceph_osdc_start_request(&dev->client->osdc, req, false); + if (ret < 0) + goto done_err; + + if (!rbd_cb) { + ret = ceph_osdc_wait_request(&dev->client->osdc, req); + ceph_osdc_put_request(req); + } + return ret; + +done_err: + bio_chain_put(req_data->bio); + ceph_osdc_put_request(req); +done_pages: + kfree(req_data); +done: + if (rq) + blk_end_request(rq, ret, len); + return ret; +} + +/* + * Ceph osd op callback + */ +static void rbd_req_cb(struct ceph_osd_request *req, struct ceph_msg *msg) +{ + struct rbd_request *req_data = req->r_priv; + struct ceph_osd_reply_head *replyhead; + struct ceph_osd_op *op; + __s32 rc; + u64 bytes; + int read_op; + + /* parse reply */ + replyhead = msg->front.iov_base; + WARN_ON(le32_to_cpu(replyhead->num_ops) == 0); + op = (void *)(replyhead + 1); + rc = le32_to_cpu(replyhead->result); + bytes = le64_to_cpu(op->extent.length); + + dout("rbd_req_cb bytes=%lld rc=%d\n", bytes, rc); + + read_op = (le32_to_cpu(op->op) == CEPH_OSD_OP_READ); + + if (rc == -ENOENT && read_op) { + zero_bio_chain(req_data->bio, 0); + rc = 0; + } else if (rc == 0 && read_op && bytes < req_data->len) { + zero_bio_chain(req_data->bio, bytes); + bytes = req_data->len; + } + + blk_end_request(req_data->rq, rc, bytes); + + if (req_data->bio) + bio_chain_put(req_data->bio); + + ceph_osdc_put_request(req); + kfree(req_data); +} + +/* + * Do a synchronous ceph osd operation + */ +static int rbd_req_sync_op(struct rbd_device *dev, + struct ceph_snap_context *snapc, + u64 snapid, + int opcode, int flags, + int num_reply, + const char *obj, + u64 ofs, u64 len, + char *buf) +{ + int ret; + struct page **pages; + int num_pages; + + num_pages = calc_pages_for(ofs , len); + pages = ceph_alloc_page_vector(num_pages, GFP_KERNEL); + if (!pages) + return -ENOMEM; + + if (flags & CEPH_OSD_FLAG_WRITE) { + ret = ceph_copy_to_page_vector(pages, buf, ofs, len); + if (ret < 0) + goto done; + } + + ret = rbd_do_request(NULL, dev, snapc, snapid, + obj, ofs, len, NULL, + pages, num_pages, + opcode, + flags, + 2, + NULL); + if (ret < 0) + goto done; + + if (flags & CEPH_OSD_FLAG_READ) + ret = ceph_copy_from_page_vector(pages, buf, ofs, ret); + +done: + ceph_release_page_vector(pages, num_pages); + return ret; +} + +/* + * Do an asynchronous ceph osd operation + */ +static int rbd_do_op(struct request *rq, + struct rbd_device *rbd_dev , + struct ceph_snap_context *snapc, + u64 snapid, + int opcode, int flags, int num_reply, + u64 ofs, u64 len, + struct bio *bio) +{ + char *seg_name; + u64 seg_ofs; + u64 seg_len; + int ret; + + seg_name = kmalloc(RBD_MAX_SEG_NAME_SIZE + 1, GFP_NOIO); + if (!seg_name) + return -ENOMEM; + + seg_len = rbd_get_segment(&rbd_dev->header, + rbd_dev->obj, + ofs, len, + seg_name, &seg_ofs); + if (seg_len < 0) + return seg_len; + + /* we've taken care of segment sizes earlier when we + cloned the bios. We should never have a segment + truncated at this point */ + BUG_ON(seg_len < len); + + ret = rbd_do_request(rq, rbd_dev, snapc, snapid, + seg_name, seg_ofs, seg_len, + bio, + NULL, 0, + opcode, + flags, + num_reply, + rbd_req_cb); + kfree(seg_name); + return ret; +} + +/* + * Request async osd write + */ +static int rbd_req_write(struct request *rq, + struct rbd_device *rbd_dev, + struct ceph_snap_context *snapc, + u64 ofs, u64 len, + struct bio *bio) +{ + return rbd_do_op(rq, rbd_dev, snapc, CEPH_NOSNAP, + CEPH_OSD_OP_WRITE, + CEPH_OSD_FLAG_WRITE | CEPH_OSD_FLAG_ONDISK, + 2, + ofs, len, bio); +} + +/* + * Request sync osd write + */ +static int rbd_req_sync_write(struct rbd_device *dev, + struct ceph_snap_context *snapc, + u64 snapid, + const char *obj, + u64 ofs, u64 len, + char *buf) +{ + return rbd_req_sync_op(dev, snapc, snapid, + CEPH_OSD_OP_WRITE, + CEPH_OSD_FLAG_WRITE | CEPH_OSD_FLAG_ONDISK, + 2, obj, ofs, len, buf); +} + +/* + * Request async osd read + */ +static int rbd_req_read(struct request *rq, + struct rbd_device *rbd_dev, + u64 snapid, + u64 ofs, u64 len, + struct bio *bio) +{ + return rbd_do_op(rq, rbd_dev, NULL, + (snapid ? snapid : CEPH_NOSNAP), + CEPH_OSD_OP_READ, + CEPH_OSD_FLAG_READ, + 2, + ofs, len, bio); +} + +/* + * Request sync osd read + */ +static int rbd_req_sync_read(struct rbd_device *dev, + struct ceph_snap_context *snapc, + u64 snapid, + const char *obj, + u64 ofs, u64 len, + char *buf) +{ + return rbd_req_sync_op(dev, NULL, + (snapid ? snapid : CEPH_NOSNAP), + CEPH_OSD_OP_READ, + CEPH_OSD_FLAG_READ, + 1, obj, ofs, len, buf); +} + +/* + * block device queue callback + */ +static void rbd_rq_fn(struct request_queue *q) +{ + struct rbd_device *rbd_dev = q->queuedata; + struct request *rq; + struct bio_pair *bp = NULL; + + rq = blk_fetch_request(q); + + while (1) { + struct bio *bio; + struct bio *rq_bio, *next_bio = NULL; + bool do_write; + int size, op_size = 0; + u64 ofs; + + /* peek at request from block layer */ + if (!rq) + break; + + dout("fetched request\n"); + + /* filter out block requests we don't understand */ + if (!blk_fs_request(rq) && !blk_barrier_rq(rq)) { + __blk_end_request_all(rq, 0); + goto next; + } + + /* deduce our operation (read, write) */ + do_write = (rq_data_dir(rq) == WRITE); + + size = blk_rq_bytes(rq); + ofs = blk_rq_pos(rq) * 512ULL; + rq_bio = rq->bio; + if (do_write && rbd_dev->read_only) { + __blk_end_request_all(rq, -EROFS); + goto next; + } + + spin_unlock_irq(q->queue_lock); + + dout("%s 0x%x bytes at 0x%llx\n", + do_write ? "write" : "read", + size, blk_rq_pos(rq) * 512ULL); + + do { + /* a bio clone to be passed down to OSD req */ + dout("rq->bio->bi_vcnt=%d\n", rq->bio->bi_vcnt); + op_size = rbd_get_segment(&rbd_dev->header, + rbd_dev->obj, + ofs, size, + NULL, NULL); + bio = bio_chain_clone(&rq_bio, &next_bio, &bp, + op_size, GFP_ATOMIC); + if (!bio) { + spin_lock_irq(q->queue_lock); + __blk_end_request_all(rq, -ENOMEM); + goto next; + } + + /* init OSD command: write or read */ + if (do_write) + rbd_req_write(rq, rbd_dev, + rbd_dev->header.snapc, + ofs, + op_size, bio); + else + rbd_req_read(rq, rbd_dev, + cur_snap_id(rbd_dev), + ofs, + op_size, bio); + + size -= op_size; + ofs += op_size; + + rq_bio = next_bio; + } while (size > 0); + + if (bp) + bio_pair_release(bp); + + spin_lock_irq(q->queue_lock); +next: + rq = blk_fetch_request(q); + } +} + +/* + * a queue callback. Makes sure that we don't create a bio that spans across + * multiple osd objects. One exception would be with a single page bios, + * which we handle later at bio_chain_clone + */ +static int rbd_merge_bvec(struct request_queue *q, struct bvec_merge_data *bmd, + struct bio_vec *bvec) +{ + sector_t sector = bmd->bi_sector + get_start_sect(bmd->bi_bdev); + unsigned int chunk_sectors = (RBD_STRIPE_UNIT >> 9); + unsigned int bio_sectors = bmd->bi_size >> 9; + int max; + + max = (chunk_sectors - ((sector & (chunk_sectors - 1)) + + bio_sectors)) << 9; + if (max < 0) + max = 0; /* bio_add cannot handle a negative return */ + if (max <= bvec->bv_len && bio_sectors == 0) + return bvec->bv_len; + return max; +} + +static void rbd_free_disk(struct rbd_device *rbd_dev) +{ + struct gendisk *disk = rbd_dev->disk; + + if (!disk) + return; + + rbd_header_free(&rbd_dev->header); + + if (disk->flags & GENHD_FL_UP) + del_gendisk(disk); + if (disk->queue) + blk_cleanup_queue(disk->queue); + put_disk(disk); +} + +static char *rbd_alloc_md_name(struct rbd_device *rbd_dev, gfp_t gfp_flags) +{ + char *obj_md_name = kmalloc(strlen(rbd_dev->obj) + sizeof(RBD_SUFFIX), + gfp_flags); + if (!obj_md_name) + return NULL; + sprintf(obj_md_name, "%s%s", rbd_dev->obj, RBD_SUFFIX); + + return obj_md_name; +} + +static int rbd_read_header(struct rbd_device *rbd_dev, + struct rbd_obj_header *header) +{ + ssize_t rc; + char *obj_md_name; + struct rbd_obj_header_ondisk *dh; + int snap_count = 0; + u64 snap_names_len = 0; + + obj_md_name = rbd_alloc_md_name(rbd_dev, GFP_KERNEL); + if (!obj_md_name) + return -ENOMEM; + + while (1) { + int len = sizeof(*dh) + + snap_count * sizeof(struct rbd_obj_snap_ondisk) + + snap_names_len; + + rc = -ENOMEM; + dh = kmalloc(len, GFP_KERNEL); + if (!dh) + goto out_obj_md; + + rc = rbd_req_sync_read(rbd_dev, + NULL, CEPH_NOSNAP, + obj_md_name, + 0, len, + (char *)dh); + if (rc < 0) + goto out_dh; + + rc = rbd_header_from_disk(header, dh, snap_count, GFP_KERNEL); + if (rc < 0) + goto out_dh; + + if (snap_count != header->total_snaps) { + snap_count = header->total_snaps; + snap_names_len = header->snap_names_len; + rbd_header_free(header); + kfree(dh); + continue; + } + break; + } + +out_dh: + kfree(dh); +out_obj_md: + kfree(obj_md_name); + return rc; +} + +/* + * only read the first part of the ondisk header, without the snaps info + */ +static int rbd_read_ondisk_header_nosnap(struct rbd_device *rbd_dev, + struct rbd_obj_header *header, + struct rbd_obj_header_ondisk *dh) +{ + ssize_t rc; + char *obj_md_name; + int len; + + obj_md_name = rbd_alloc_md_name(rbd_dev, GFP_KERNEL); + if (!obj_md_name) + return -ENOMEM; + + len = sizeof(struct rbd_obj_header_ondisk); + + rc = rbd_req_sync_read(rbd_dev, + NULL, CEPH_NOSNAP, + obj_md_name, + 0, len, + (char *)dh); + if (rc > 0 && rc < len) + rc = -EIO; + + kfree(obj_md_name); + return rc; +} + +static int rbd_write_header(struct rbd_device *rbd_dev, + struct rbd_obj_header_ondisk *dh, + struct rbd_obj_header *header) +{ + ssize_t rc; + char *obj_md_name; + int snap_count = header->total_snaps; + u64 snap_names_len = header->snap_names_len; + int len; + + obj_md_name = rbd_alloc_md_name(rbd_dev, GFP_KERNEL); + if (!obj_md_name) + return -ENOMEM; + + len = sizeof(*dh) + + snap_count * sizeof(struct rbd_obj_snap_ondisk) + + snap_names_len; + + rc = rbd_req_sync_write(rbd_dev, + NULL, CEPH_NOSNAP, + obj_md_name, + 0, len, + (char *)dh); + kfree(obj_md_name); + return rc; +} + +static int rbd_update_snaps(struct rbd_device *rbd_dev) +{ + int ret; + struct rbd_obj_header h; + + ret = rbd_read_header(rbd_dev, &h); + if (ret < 0) + return ret; + + down_write(&rbd_dev->header.snap_rwsem); + + kfree(rbd_dev->header.snapc); + kfree(rbd_dev->header.snap_names); + kfree(rbd_dev->header.snap_sizes); + + rbd_dev->header.total_snaps = h.total_snaps; + rbd_dev->header.snapc = h.snapc; + rbd_dev->header.snap_names = h.snap_names; + rbd_dev->header.snap_sizes = h.snap_sizes; + + up_write(&rbd_dev->header.snap_rwsem); + + return 0; +} + +static int rbd_init_disk(struct rbd_device *rbd_dev) +{ + struct gendisk *disk; + struct request_queue *q; + int rc; + u64 total_size; + const char *snap = NULL; + + /* contact OSD, request size info about the object being mapped */ + rc = rbd_read_header(rbd_dev, &rbd_dev->header); + if (rc) + return rc; + + if (rbd_dev->client->mount_args) + snap = rbd_dev->client->mount_args->snap; + rc = rbd_header_set_snap(rbd_dev, snap, &total_size); + if (rc) + return rc; + + /* create gendisk info */ + rc = -ENOMEM; + disk = alloc_disk(RBD_MINORS_PER_MAJOR); + if (!disk) + goto out; + + sprintf(disk->disk_name, DRV_NAME "%d", rbd_dev->id); + disk->major = rbd_dev->major; + disk->first_minor = 0; + disk->fops = &rbd_bd_ops; + disk->private_data = rbd_dev; + + /* init rq */ + rc = -ENOMEM; + q = blk_init_queue(rbd_rq_fn, &rbd_dev->lock); + if (!q) + goto out_disk; + blk_queue_merge_bvec(q, rbd_merge_bvec); + disk->queue = q; + + q->queuedata = rbd_dev; + + rbd_dev->disk = disk; + rbd_dev->q = q; + + /* finally, announce the disk to the world */ + set_capacity(disk, total_size / 512ULL); + add_disk(disk); + + pr_info("%s: added with size 0x%llx\n", + disk->disk_name, (unsigned long long)total_size); + return 0; + +out_disk: + put_disk(disk); +out: + return rc; +} + +/******************************************************************** + * /sys/class/rbd/ + * add map rados objects to blkdev + * remove unmap rados objects + * list show mappings + *******************************************************************/ + +static void class_rbd_release(struct class *cls) +{ + kfree(cls); +} + +static ssize_t class_rbd_list(struct class *c, + struct class_attribute *attr, + char *data) +{ + int n = 0; + struct list_head *tmp; + + mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); + + list_for_each(tmp, &rbddev_list) { + struct rbd_device *rbd_dev; + + rbd_dev = list_entry(tmp, struct rbd_device, node); + n += sprintf(data+n, "%d %d client%lld %s %s\n", + rbd_dev->id, + rbd_dev->major, + ceph_client_id(rbd_dev->client), + rbd_dev->pool_name, + rbd_dev->obj); + } + + mutex_unlock(&ctl_mutex); + return n; +} + +static ssize_t class_rbd_add(struct class *c, + struct class_attribute *attr, + const char *buf, size_t count) +{ + struct rbd_device *rbd_dev; + ssize_t rc = -ENOMEM; + int irc, new_id = 0; + struct list_head *tmp; + char *mon_dev_name; + char *opt; + + if (!try_module_get(THIS_MODULE)) + return -ENODEV; + + mon_dev_name = kmalloc(RBD_MAX_OPT_LEN, GFP_KERNEL); + if (!mon_dev_name) + goto err_out_mod; + + opt = kmalloc(RBD_MAX_OPT_LEN, GFP_KERNEL); + if (!opt) + goto err_mon_dev; + + /* new rbd_device object */ + rbd_dev = kzalloc(sizeof(*rbd_dev), GFP_KERNEL); + if (!rbd_dev) + goto err_out_opt; + + /* static rbd_device initialization */ + spin_lock_init(&rbd_dev->lock); + INIT_LIST_HEAD(&rbd_dev->node); + + /* generate unique id: find highest unique id, add one */ + mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); + + list_for_each(tmp, &rbddev_list) { + struct rbd_device *rbd_dev; + + rbd_dev = list_entry(tmp, struct rbd_device, node); + if (rbd_dev->id >= new_id) + new_id = rbd_dev->id + 1; + } + + rbd_dev->id = new_id; + + /* add to global list */ + list_add_tail(&rbd_dev->node, &rbddev_list); + + /* parse add command */ + if (sscanf(buf, "%" __stringify(RBD_MAX_OPT_LEN) "s " + "%" __stringify(RBD_MAX_OPT_LEN) "s " + "%" __stringify(RBD_MAX_POOL_NAME_SIZE) "s " + "%" __stringify(RBD_MAX_OBJ_NAME_SIZE) "s", + mon_dev_name, opt, rbd_dev->pool_name, + rbd_dev->obj) != 4) { + rc = -EINVAL; + goto err_out_slot; + } + + rbd_dev->obj_len = strlen(rbd_dev->obj); + + /* initialize rest of new object */ + snprintf(rbd_dev->name, DEV_NAME_LEN, DRV_NAME "%d", rbd_dev->id); + rc = rbd_get_client(rbd_dev, mon_dev_name, opt); + if (rc < 0) + goto err_out_slot; + + mutex_unlock(&ctl_mutex); + /* register our block device */ + irc = register_blkdev(0, rbd_dev->name); + if (irc < 0) { + rc = irc; + goto err_out_client; + } + rbd_dev->major = irc; + + /* set up and announce blkdev mapping */ + rc = rbd_init_disk(rbd_dev); + if (rc) + goto err_out_blkdev; + + return count; + +err_out_blkdev: + unregister_blkdev(rbd_dev->major, rbd_dev->name); +err_out_client: + rbd_put_client(rbd_dev); + mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); +err_out_slot: + list_del_init(&rbd_dev->node); + mutex_unlock(&ctl_mutex); + + kfree(rbd_dev); +err_out_opt: + kfree(opt); +err_mon_dev: + kfree(mon_dev_name); +err_out_mod: + dout("Error adding device %s\n", buf); + module_put(THIS_MODULE); + return rc; +} + +static struct rbd_device *__rbd_get_dev(unsigned long id) +{ + struct list_head *tmp; + struct rbd_device *rbd_dev = NULL; + + list_for_each(tmp, &rbddev_list) { + rbd_dev = list_entry(tmp, struct rbd_device, node); + if (rbd_dev->id == id) + break; + + rbd_dev = NULL; + } + + return rbd_dev; +} + +static ssize_t class_rbd_remove(struct class *c, + struct class_attribute *attr, + const char *buf, + size_t count) +{ + struct rbd_device *rbd_dev = NULL; + int target_id, rc; + unsigned long ul; + + rc = strict_strtoul(buf, 10, &ul); + if (rc) + return rc; + + /* convert to int; abort if we lost anything in the conversion */ + target_id = (int) ul; + if (target_id != ul) + return -EINVAL; + + /* remove object from list immediately */ + mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); + + rbd_dev = __rbd_get_dev(target_id); + if (rbd_dev) + list_del_init(&rbd_dev->node); + + mutex_unlock(&ctl_mutex); + + if (!rbd_dev) + return -ENOENT; + + rbd_put_client(rbd_dev); + + /* clean up and free blkdev and associated OSD connection */ + rbd_free_disk(rbd_dev); + unregister_blkdev(rbd_dev->major, rbd_dev->name); + kfree(rbd_dev); + + /* release module ref */ + module_put(THIS_MODULE); + + return count; +} + +static void get_size_and_suffix(u64 orig_size, u64 *size, char *suffix) +{ + if (orig_size >= 1024*1024*1024) { + *size = orig_size / (1024*1024*1024); + *suffix = 'G'; + } else if (orig_size >= 1024*1024) { + *size = orig_size / (1024*1024); + *suffix = 'M'; + } else if (orig_size >= 1024) { + *size = orig_size / 1024; + *suffix = 'K'; + } else { + *size = orig_size; + *suffix = ' '; + } +} + +static ssize_t class_rbd_snaps_list(struct class *c, + struct class_attribute *attr, + char *data) +{ + struct rbd_device *rbd_dev = NULL; + struct list_head *tmp; + struct rbd_obj_header *header; + char size_suffix; + u64 size; + int i, n = 0, max = PAGE_SIZE; + int ret; + + mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); + + list_for_each(tmp, &rbddev_list) { + char *names, *p; + struct ceph_snap_context *snapc; + + rbd_dev = list_entry(tmp, struct rbd_device, node); + header = &rbd_dev->header; + names = header->snap_names; + snapc = header->snapc; + n += snprintf(data + n, max - n, + "snapshots for device id %d:\n", + rbd_dev->id); + if (n == max) + break; + + down_read(&header->snap_rwsem); + + get_size_and_suffix(header->image_size, &size, + &size_suffix); + n += snprintf(data + n, max - n, "%s\t%lld%c%s\n", + RBD_SNAP_HEAD_NAME, + size, size_suffix, + (!rbd_dev->cur_snap ? + " (*)" : "")); + if (n == max) + break; + + p = names; + for (i = 0; i < header->total_snaps; i++, p += strlen(p) + 1) { + get_size_and_suffix(header->snap_sizes[i], &size, + &size_suffix); + n += snprintf(data + n, max - n, "%s\t%lld%c%s\n", + p, size, size_suffix, + (rbd_dev->cur_snap && + (snap_index(header, i) == rbd_dev->cur_snap) ? + " (*)" : "")); + if (n == max) + break; + } + + up_read(&header->snap_rwsem); + } + + + ret = n; + mutex_unlock(&ctl_mutex); + return ret; +} + +static ssize_t class_rbd_snaps_refresh(struct class *c, + struct class_attribute *attr, + const char *buf, + size_t count) +{ + struct rbd_device *rbd_dev = NULL; + int target_id, rc; + unsigned long ul; + int ret = count; + + rc = strict_strtoul(buf, 10, &ul); + if (rc) + return rc; + + /* convert to int; abort if we lost anything in the conversion */ + target_id = (int) ul; + if (target_id != ul) + return -EINVAL; + + mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); + + rbd_dev = __rbd_get_dev(target_id); + if (!rbd_dev) { + ret = -ENOENT; + goto done; + } + + rc = rbd_update_snaps(rbd_dev); + if (rc < 0) + ret = rc; + +done: + mutex_unlock(&ctl_mutex); + return ret; +} + +static ssize_t class_rbd_snaps_op(struct class *c, + struct class_attribute *attr, + const char *buf, + size_t count, + int snaps_op) +{ + struct rbd_device *rbd_dev = NULL; + int target_id, ret; + char *name; + struct rbd_obj_header_ondisk old_ondisk, *new_ondisk; + + name = kmalloc(RBD_MAX_SNAP_NAME_LEN + 1, GFP_KERNEL); + if (!name) + return -ENOMEM; + + /* parse snaps add command */ + if (sscanf(buf, "%d " + "%" __stringify(RBD_MAX_SNAP_NAME_LEN) "s", + &target_id, + name) != 2) { + ret = -EINVAL; + goto done; + } + + mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); + + rbd_dev = __rbd_get_dev(target_id); + if (!rbd_dev) { + ret = -ENOENT; + goto done_unlock; + } + + ret = rbd_read_ondisk_header_nosnap(rbd_dev, + &rbd_dev->header, + &old_ondisk); + if (ret < 0) + goto done_unlock; + + switch (snaps_op) { + case RBD_SNAP_OP_CREATE: + ret = rbd_header_add_snap(rbd_dev, + name, GFP_KERNEL); + break; + case RBD_SNAP_OP_SET: + ret = rbd_header_set_snap(rbd_dev, name, NULL); + break; + default: + ret = -EINVAL; + } + if (ret < 0) + goto done_unlock; + + ret = rbd_header_to_disk(&new_ondisk, &old_ondisk, + &rbd_dev->header, GFP_KERNEL); + if (ret < 0) + goto done_unlock; + + ret = rbd_write_header(rbd_dev, new_ondisk, &rbd_dev->header); + if (ret < 0) + goto done_unlock; + + ret = count; +done_unlock: + mutex_unlock(&ctl_mutex); +done: + kfree(name); + return ret; +} + +static ssize_t class_rbd_snap_create(struct class *c, + struct class_attribute *attr, + const char *buf, + size_t count) +{ + return class_rbd_snaps_op(c, attr, buf, count, + RBD_SNAP_OP_CREATE); +} + +static struct class_attribute class_rbd_attrs[] = { + __ATTR(add, 0200, NULL, class_rbd_add), + __ATTR(remove, 0200, NULL, class_rbd_remove), + __ATTR(list, 0444, class_rbd_list, NULL), + __ATTR(snaps_refresh, 0200, NULL, class_rbd_snaps_refresh), + __ATTR(snap_create, 0200, NULL, class_rbd_snap_create), + __ATTR(snaps_list, 0444, class_rbd_snaps_list, NULL), + __ATTR_NULL +}; + +/* + * create control files in sysfs + * /sys/class/rbd/... + */ +static int rbd_sysfs_init(void) +{ + int ret = -ENOMEM; + + class_rbd = kzalloc(sizeof(*class_rbd), GFP_KERNEL); + if (!class_rbd) + goto out; + + class_rbd->name = DRV_NAME; + class_rbd->owner = THIS_MODULE; + class_rbd->class_release = class_rbd_release; + class_rbd->class_attrs = class_rbd_attrs; + + ret = class_register(class_rbd); + if (ret) + goto out_class; + return 0; + +out_class: + kfree(class_rbd); + class_rbd = NULL; + pr_err(DRV_NAME ": failed to create class rbd\n"); +out: + return ret; +} + +static void rbd_sysfs_cleanup(void) +{ + if (class_rbd) + class_destroy(class_rbd); + class_rbd = NULL; +} + +int __init rbd_init(void) +{ + int rc; + + rc = rbd_sysfs_init(); + if (rc) + return rc; + spin_lock_init(&node_lock); + pr_info("loaded " DRV_NAME_LONG); + return 0; +} + +void __exit rbd_exit(void) +{ + rbd_sysfs_cleanup(); +} diff --git a/fs/ceph/rbd.h b/fs/ceph/rbd.h new file mode 100644 index 000000000000..68e0a5c69dc8 --- /dev/null +++ b/fs/ceph/rbd.h @@ -0,0 +1,8 @@ +#ifndef _FS_CEPH_RBD +#define _FS_CEPH_RBD + +extern void rbd_set_osdc(struct ceph_osd_client *o); +extern int __init rbd_init(void); +extern void __exit rbd_exit(void); + +#endif diff --git a/fs/ceph/rbd_types.h b/fs/ceph/rbd_types.h new file mode 100644 index 000000000000..b73ac12ad0d6 --- /dev/null +++ b/fs/ceph/rbd_types.h @@ -0,0 +1,48 @@ +#ifndef _FS_CEPH_RBD +#define _FS_CEPH_RBD + +#include <linux/types.h> + +/* + * rbd image 'foo' consists of objects + * foo.rbd - image metadata + * foo.00000000 + * foo.00000001 + * ... - data + */ + +#define RBD_SUFFIX ".rbd" +#define RBD_DIRECTORY "rbd_directory" + +#define RBD_DEFAULT_OBJ_ORDER 22 /* 4MB */ + +#define RBD_MAX_OBJ_NAME_SIZE 96 +#define RBD_MAX_SEG_NAME_SIZE 128 + +#define RBD_COMP_NONE 0 +#define RBD_CRYPT_NONE 0 + +static const char rbd_text[] = "<<< Rados Block Device Image >>>\n"; +static const char rbd_signature[] = "RBD"; +static const char rbd_version[] = "001.002"; + +struct rbd_obj_snap_ondisk { + __le64 id; + __le64 image_size; +} __attribute__((packed)); + +struct rbd_obj_header_ondisk { + char text[64]; + char signature[4]; + char version[8]; + __le64 image_size; + __u8 obj_order; + __u8 crypt_type; + __u8 comp_type; + __le64 snap_seq; + __le32 snap_count; + __le64 snap_names_len; + struct rbd_obj_snap_ondisk snaps[0]; +} __attribute__((packed)); + +#endif diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 4e0bee240b9d..c14d2623c9b5 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -18,6 +18,7 @@ #include "super.h" #include "mon_client.h" #include "auth.h" +#include "rbd.h" /* * Ceph superblock operations @@ -342,6 +343,7 @@ enum { Opt_snapdirname, Opt_name, Opt_secret, + Opt_snap, Opt_last_string, /* string args above */ Opt_ip, @@ -374,6 +376,7 @@ static match_table_t arg_tokens = { {Opt_snapdirname, "snapdirname=%s"}, {Opt_name, "name=%s"}, {Opt_secret, "secret=%s"}, + {Opt_snap, "snap=%s"}, /* string args above */ {Opt_ip, "ip=%s"}, {Opt_noshare, "noshare"}, @@ -387,14 +390,15 @@ static match_table_t arg_tokens = { }; -static struct ceph_mount_args *parse_mount_args(int flags, char *options, - const char *dev_name, - const char **path) +struct ceph_mount_args *parse_mount_args(int flags, char *options, + const char *dev_name, + const char **path) { struct ceph_mount_args *args; const char *c; int err = -ENOMEM; substring_t argstr[MAX_OPT_ARGS]; + const char *end_path; args = kzalloc(sizeof(*args), GFP_KERNEL); if (!args) @@ -426,23 +430,29 @@ static struct ceph_mount_args *parse_mount_args(int flags, char *options, err = -EINVAL; if (!dev_name) goto out; - *path = strstr(dev_name, ":/"); - if (*path == NULL) { - pr_err("device name is missing path (no :/ in %s)\n", - dev_name); - goto out; + + if (path) { + *path = strstr(dev_name, ":/"); + if (*path == NULL) { + pr_err("device name is missing path (no :/ in %s)\n", + dev_name); + goto out; + } + end_path = *path; + + /* path on server */ + *path += 2; + dout("server path '%s'\n", *path); + } else { + end_path = dev_name + strlen(dev_name); } /* get mon ip(s) */ - err = ceph_parse_ips(dev_name, *path, args->mon_addr, + err = ceph_parse_ips(dev_name, end_path, args->mon_addr, CEPH_MAX_MON, &args->num_mon); if (err < 0) goto out; - /* path on server */ - *path += 2; - dout("server path '%s'\n", *path); - /* parse mount options */ while ((c = strsep(&options, ",")) != NULL) { int token, intval, ret; @@ -501,6 +511,11 @@ static struct ceph_mount_args *parse_mount_args(int flags, char *options, argstr[0].to-argstr[0].from, GFP_KERNEL); break; + case Opt_snap: + args->snap = kstrndup(argstr[0].from, + argstr[0].to-argstr[0].from, + GFP_KERNEL); + break; /* misc */ case Opt_wsize: @@ -569,22 +584,70 @@ out: return ERR_PTR(err); } -static void destroy_mount_args(struct ceph_mount_args *args) +void ceph_destroy_mount_args(struct ceph_mount_args *args) { dout("destroy_mount_args %p\n", args); kfree(args->snapdir_name); - args->snapdir_name = NULL; kfree(args->name); - args->name = NULL; kfree(args->secret); - args->secret = NULL; + kfree(args->snap); kfree(args); } +static int strcmp_null(const char *s1, const char *s2) +{ + if (!s1 && !s2) + return 0; + if (s1 && !s2) + return -1; + if (!s1 && s2) + return 1; + return strcmp(s1, s2); +} + +int ceph_compare_mount_args(struct ceph_mount_args *new_args, + struct ceph_client *client) +{ + struct ceph_mount_args *args1 = new_args; + struct ceph_mount_args *args2 = client->mount_args; + int ofs = offsetof(struct ceph_mount_args, mon_addr); + int i; + int ret; + + ret = memcmp(args1, args2, ofs); + if (ret) + return ret; + + ret = strcmp_null(args1->snapdir_name, args2->snapdir_name); + if (ret) + return ret; + + ret = strcmp_null(args1->name, args2->name); + if (ret) + return ret; + + ret = strcmp_null(args1->secret, args2->secret); + if (ret) + return ret; + + ret = strcmp_null(args1->snap, args2->snap); + if (ret) + return ret; + + for (i = 0; i < args1->num_mon; i++) { + if (ceph_monmap_contains(client->monc.monmap, + &args1->mon_addr[i])) + return 0; + } + + return -1; +} + /* * create a fresh client instance */ -static struct ceph_client *ceph_create_client(struct ceph_mount_args *args) +struct ceph_client *ceph_create_client(struct ceph_mount_args *args, + int need_mdsc) { struct ceph_client *client; int err = -ENOMEM; @@ -639,9 +702,13 @@ static struct ceph_client *ceph_create_client(struct ceph_mount_args *args) err = ceph_osdc_init(&client->osdc, client); if (err < 0) goto fail_monc; - err = ceph_mdsc_init(&client->mdsc, client); - if (err < 0) - goto fail_osdc; + if (need_mdsc) { + err = ceph_mdsc_init(&client->mdsc, client); + if (err < 0) + goto fail_osdc; + client->have_mdsc = 1; + } + return client; fail_osdc: @@ -663,7 +730,12 @@ fail: return ERR_PTR(err); } -static void ceph_destroy_client(struct ceph_client *client) +u64 ceph_client_id(struct ceph_client *client) +{ + return client->monc.auth->global_id; +} + +void ceph_destroy_client(struct ceph_client *client) { dout("destroy_client %p\n", client); @@ -693,7 +765,7 @@ static void ceph_destroy_client(struct ceph_client *client) ceph_messenger_destroy(client->msgr); mempool_destroy(client->wb_pagevec_pool); - destroy_mount_args(client->mount_args); + ceph_destroy_mount_args(client->mount_args); kfree(client); dout("destroy_client %p done\n", client); @@ -712,7 +784,7 @@ int ceph_check_fsid(struct ceph_client *client, struct ceph_fsid *fsid) } } else { pr_info("client%lld fsid " FSID_FORMAT "\n", - client->monc.auth->global_id, PR_FSID(fsid)); + ceph_client_id(client), PR_FSID(fsid)); memcpy(&client->fsid, fsid, sizeof(*fsid)); ceph_debugfs_client_init(client); client->have_fsid = true; @@ -774,17 +846,12 @@ static struct dentry *open_root_dentry(struct ceph_client *client, /* * mount: join the ceph cluster, and open root directory. */ -static int ceph_mount(struct ceph_client *client, struct vfsmount *mnt, - const char *path) +static int __ceph_open_session(struct ceph_client *client, + unsigned long started) { struct ceph_entity_addr *myaddr = NULL; int err; unsigned long timeout = client->mount_args->mount_timeout * HZ; - unsigned long started = jiffies; /* note the start time */ - struct dentry *root; - - dout("mount start\n"); - mutex_lock(&client->mount_mutex); /* initialize the messenger */ if (client->msgr == NULL) { @@ -792,9 +859,8 @@ static int ceph_mount(struct ceph_client *client, struct vfsmount *mnt, myaddr = &client->mount_args->my_addr; client->msgr = ceph_messenger_create(myaddr); if (IS_ERR(client->msgr)) { - err = PTR_ERR(client->msgr); client->msgr = NULL; - goto out; + return PTR_ERR(client->msgr); } client->msgr->nocrc = ceph_test_opt(client, NOCRC); } @@ -802,26 +868,58 @@ static int ceph_mount(struct ceph_client *client, struct vfsmount *mnt, /* open session, and wait for mon, mds, and osd maps */ err = ceph_monc_open_session(&client->monc); if (err < 0) - goto out; + return err; while (!have_mon_and_osd_map(client)) { err = -EIO; if (timeout && time_after_eq(jiffies, started + timeout)) - goto out; + return err; /* wait */ dout("mount waiting for mon_map\n"); err = wait_event_interruptible_timeout(client->auth_wq, - have_mon_and_osd_map(client) || (client->auth_err < 0), - timeout); + have_mon_and_osd_map(client) || (client->auth_err < 0), + timeout); if (err == -EINTR || err == -ERESTARTSYS) - goto out; - if (client->auth_err < 0) { - err = client->auth_err; - goto out; - } + return err; + if (client->auth_err < 0) + return client->auth_err; } + return 0; +} + +int ceph_open_session(struct ceph_client *client) +{ + int ret; + unsigned long started = jiffies; /* note the start time */ + + dout("open_session start\n"); + mutex_lock(&client->mount_mutex); + + ret = __ceph_open_session(client, started); + + mutex_unlock(&client->mount_mutex); + return ret; +} + +/* + * mount: join the ceph cluster, and open root directory. + */ +static int ceph_mount(struct ceph_client *client, struct vfsmount *mnt, + const char *path) +{ + int err; + unsigned long started = jiffies; /* note the start time */ + struct dentry *root; + + dout("mount start\n"); + mutex_lock(&client->mount_mutex); + + err = __ceph_open_session(client, started); + if (err < 0) + goto out; + dout("mount opening root\n"); root = open_root_dentry(client, "", started); if (IS_ERR(root)) { @@ -963,7 +1061,7 @@ static int ceph_get_sb(struct file_system_type *fs_type, } /* create client (which we may/may not use) */ - client = ceph_create_client(args); + client = ceph_create_client(args, 1); if (IS_ERR(client)) { err = PTR_ERR(client); goto out_final; @@ -1053,8 +1151,14 @@ static int __init init_ceph(void) CEPH_MONC_PROTOCOL, CEPH_MDSC_PROTOCOL, CEPH_OSDC_PROTOCOL, CEPH_OSDMAP_VERSION, CEPH_OSDMAP_VERSION_EXT, CEPH_OSDMAP_INC_VERSION, CEPH_OSDMAP_INC_VERSION_EXT); + + ret = rbd_init(); + if (ret) + goto out_fs; return 0; +out_fs: + unregister_filesystem(&ceph_fs_type); out_icache: destroy_caches(); out_msgr: @@ -1068,6 +1172,7 @@ out: static void __exit exit_ceph(void) { dout("exit_ceph\n"); + rbd_exit(); unregister_filesystem(&ceph_fs_type); ceph_caps_finalize(); destroy_caches(); diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 10a4a406e887..b46de1f40ec9 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -48,14 +48,11 @@ #define ceph_test_opt(client, opt) \ (!!((client)->mount_args->flags & CEPH_OPT_##opt)) - struct ceph_mount_args { int sb_flags; int flags; struct ceph_fsid fsid; struct ceph_entity_addr my_addr; - int num_mon; - struct ceph_entity_addr *mon_addr; int mount_timeout; int osd_idle_ttl; int osd_timeout; @@ -67,9 +64,17 @@ struct ceph_mount_args { int cap_release_safety; int max_readdir; /* max readdir result (entires) */ int max_readdir_bytes; /* max readdir result (bytes) */ + + /* any type that can't be simply compared or doesn't need + need to be compared should go beyond this point, + ceph_compare_mount_args() should be updated accordingly */ + struct ceph_entity_addr *mon_addr; /* should be the first + pointer type of args */ + int num_mon; char *snapdir_name; /* default ".snap" */ char *name; char *secret; + char *snap; /* rbd snapshot */ }; /* @@ -139,6 +144,8 @@ struct ceph_client { int min_caps; /* min caps i added */ + int have_mdsc; + struct ceph_messenger *msgr; /* messenger instance */ struct ceph_mon_client monc; struct ceph_mds_client mdsc; @@ -737,6 +744,17 @@ extern struct kmem_cache *ceph_file_cachep; extern const char *ceph_msg_type_name(int type); extern int ceph_check_fsid(struct ceph_client *client, struct ceph_fsid *fsid); +extern struct ceph_mount_args *parse_mount_args(int flags, char *options, + const char *dev_name, + const char **path); +extern void ceph_destroy_mount_args(struct ceph_mount_args *args); +extern int ceph_compare_mount_args(struct ceph_mount_args *new_args, + struct ceph_client *client); +extern struct ceph_client *ceph_create_client(struct ceph_mount_args *args, + int need_mdsc); +extern u64 ceph_client_id(struct ceph_client *client); +extern void ceph_destroy_client(struct ceph_client *client); +extern int ceph_open_session(struct ceph_client *client); #define FSID_FORMAT "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-" \ "%02x%02x%02x%02x%02x%02x" @@ -847,6 +865,13 @@ extern int ceph_mmap(struct file *file, struct vm_area_struct *vma); /* file.c */ extern const struct file_operations ceph_file_fops; extern const struct address_space_operations ceph_aops; +extern int ceph_copy_to_page_vector(struct page **pages, + const char *data, + loff_t off, size_t len); +extern int ceph_copy_from_page_vector(struct page **pages, + char *data, + loff_t off, size_t len); +extern struct page **ceph_alloc_page_vector(int num_pages, gfp_t flags); extern int ceph_open(struct inode *inode, struct file *file); extern struct dentry *ceph_lookup_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd, int mode, @@ -896,4 +921,9 @@ static inline struct inode *get_dentry_parent_inode(struct dentry *dentry) return NULL; } +#ifndef CONFIG_RBD +static inline int __init rbd_init(void) { return 0; } +static inline void __exit rbd_exit(void) {} +#endif + #endif /* _FS_CEPH_SUPER_H */ diff --git a/fs/logfs/dir.c b/fs/logfs/dir.c index 72d1893ddd36..e780b659b4c5 100644 --- a/fs/logfs/dir.c +++ b/fs/logfs/dir.c @@ -821,7 +821,7 @@ const struct inode_operations logfs_dir_iops = { }; const struct file_operations logfs_dir_fops = { .fsync = logfs_fsync, - .ioctl = logfs_ioctl, + .unlocked_ioctl = logfs_ioctl, .readdir = logfs_readdir, .read = generic_read_dir, }; diff --git a/fs/logfs/file.c b/fs/logfs/file.c index abe1cafbd4c2..0f91548383e0 100644 --- a/fs/logfs/file.c +++ b/fs/logfs/file.c @@ -181,9 +181,9 @@ static int logfs_releasepage(struct page *page, gfp_t only_xfs_uses_this) } -int logfs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, - unsigned long arg) +long logfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { + struct inode *inode = file->f_path.dentry->d_inode; struct logfs_inode *li = logfs_inode(inode); unsigned int oldflags, flags; int err; @@ -251,7 +251,7 @@ const struct file_operations logfs_reg_fops = { .aio_read = generic_file_aio_read, .aio_write = generic_file_aio_write, .fsync = logfs_fsync, - .ioctl = logfs_ioctl, + .unlocked_ioctl = logfs_ioctl, .llseek = generic_file_llseek, .mmap = generic_file_readonly_mmap, .open = generic_file_open, diff --git a/fs/logfs/logfs.h b/fs/logfs/logfs.h index c838c4d72111..a6e8487e3844 100644 --- a/fs/logfs/logfs.h +++ b/fs/logfs/logfs.h @@ -504,8 +504,8 @@ extern const struct inode_operations logfs_reg_iops; extern const struct file_operations logfs_reg_fops; extern const struct address_space_operations logfs_reg_aops; int logfs_readpage(struct file *file, struct page *page); -int logfs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, - unsigned long arg); +long logfs_ioctl(struct file *file, unsigned int cmd, + unsigned long arg); int logfs_fsync(struct file *file, int datasync); /* gc.c */ diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index eb78e7e22077..c8dd03c3f0fd 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c @@ -143,8 +143,6 @@ struct nfs4_cb_compound_hdr { u32 minorversion; /* res */ int status; - u32 taglen; - char *tag; }; static struct { @@ -293,13 +291,14 @@ nfs4_xdr_enc_cb_recall(struct rpc_rqst *req, __be32 *p, static int decode_cb_compound_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr){ __be32 *p; + u32 taglen; READ_BUF(8); READ32(hdr->status); - READ32(hdr->taglen); - READ_BUF(hdr->taglen + 4); - hdr->tag = (char *)p; - p += XDR_QUADLEN(hdr->taglen); + /* We've got no use for the tag; ignore it: */ + READ32(taglen); + READ_BUF(taglen + 4); + p += XDR_QUADLEN(taglen); READ32(hdr->nops); return 0; } @@ -667,7 +666,14 @@ static void nfsd4_cb_recall_done(struct rpc_task *task, void *calldata) } switch (task->tk_status) { - case -EIO: + case 0: + return; + case -EBADHANDLE: + case -NFS4ERR_BAD_STATEID: + /* Race: client probably got cb_recall + * before open reply granting delegation */ + break; + default: /* Network partition? */ atomic_set(&clp->cl_cb_set, 0); warn_no_callback_path(clp, task->tk_status); @@ -676,14 +682,6 @@ static void nfsd4_cb_recall_done(struct rpc_task *task, void *calldata) nfsd4_cb_recall(dp); return; } - case -EBADHANDLE: - case -NFS4ERR_BAD_STATEID: - /* Race: client probably got cb_recall - * before open reply granting delegation */ - break; - default: - /* success, or error we can't handle */ - return; } if (dp->dl_retries--) { rpc_delay(task, 2*HZ); @@ -752,7 +750,6 @@ static void _nfsd4_cb_recall(struct nfs4_delegation *dp) .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_RECALL], .rpc_cred = callback_cred }; - int status; if (clnt == NULL) return; /* Client is shutting down; give up. */ @@ -760,10 +757,7 @@ static void _nfsd4_cb_recall(struct nfs4_delegation *dp) args->args_op = dp; msg.rpc_argp = args; dp->dl_retries = 1; - status = rpc_call_async(clnt, &msg, RPC_TASK_SOFT, - &nfsd4_cb_recall_ops, dp); - if (status) - nfs4_put_delegation(dp); + rpc_call_async(clnt, &msg, RPC_TASK_SOFT, &nfsd4_cb_recall_ops, dp); } void nfsd4_do_callback_rpc(struct work_struct *w) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 12f7109720c2..117670864af0 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -2255,6 +2255,13 @@ find_delegation_file(struct nfs4_file *fp, stateid_t *stid) return NULL; } +int share_access_to_flags(u32 share_access) +{ + share_access &= ~NFS4_SHARE_WANT_MASK; + + return share_access == NFS4_SHARE_ACCESS_READ ? RD_STATE : WR_STATE; +} + static __be32 nfs4_check_deleg(struct nfs4_file *fp, struct nfsd4_open *open, struct nfs4_delegation **dp) @@ -2265,8 +2272,7 @@ nfs4_check_deleg(struct nfs4_file *fp, struct nfsd4_open *open, *dp = find_delegation_file(fp, &open->op_delegate_stateid); if (*dp == NULL) goto out; - flags = open->op_share_access == NFS4_SHARE_ACCESS_READ ? - RD_STATE : WR_STATE; + flags = share_access_to_flags(open->op_share_access); status = nfs4_check_delegmode(*dp, flags); if (status) *dp = NULL; @@ -2358,6 +2364,7 @@ nfs4_upgrade_open(struct svc_rqst *rqstp, struct svc_fh *cur_fh, struct nfs4_sta struct file *filp = stp->st_vfs_file; struct inode *inode = filp->f_path.dentry->d_inode; unsigned int share_access, new_writer; + u32 op_share_access; __be32 status; set_access(&share_access, stp->st_access_bmap); @@ -2380,8 +2387,9 @@ nfs4_upgrade_open(struct svc_rqst *rqstp, struct svc_fh *cur_fh, struct nfs4_sta return status; } /* remember the open */ - filp->f_mode |= open->op_share_access; - __set_bit(open->op_share_access, &stp->st_access_bmap); + op_share_access = open->op_share_access & ~NFS4_SHARE_WANT_MASK; + filp->f_mode |= op_share_access; + __set_bit(op_share_access, &stp->st_access_bmap); __set_bit(open->op_share_deny, &stp->st_deny_bmap); return nfs_ok; diff --git a/fs/nilfs2/btree.h b/fs/nilfs2/btree.h index af638d59e3bf..43c8c5b541fd 100644 --- a/fs/nilfs2/btree.h +++ b/fs/nilfs2/btree.h @@ -75,8 +75,6 @@ struct nilfs_btree_path { extern struct kmem_cache *nilfs_btree_path_cache; -int nilfs_btree_path_cache_init(void); -void nilfs_btree_path_cache_destroy(void); int nilfs_btree_init(struct nilfs_bmap *); int nilfs_btree_convert_and_insert(struct nilfs_bmap *, __u64, __u64, const __u64 *, const __u64 *, int); diff --git a/fs/nilfs2/recovery.c b/fs/nilfs2/recovery.c index bae2a516b4ee..f5d9c3f954ae 100644 --- a/fs/nilfs2/recovery.c +++ b/fs/nilfs2/recovery.c @@ -91,27 +91,9 @@ static int nilfs_warn_segment_error(int err) return -EINVAL; } -static void store_segsum_info(struct nilfs_segsum_info *ssi, - struct nilfs_segment_summary *sum, - unsigned int blocksize) -{ - ssi->flags = le16_to_cpu(sum->ss_flags); - ssi->seg_seq = le64_to_cpu(sum->ss_seq); - ssi->ctime = le64_to_cpu(sum->ss_create); - ssi->next = le64_to_cpu(sum->ss_next); - ssi->nblocks = le32_to_cpu(sum->ss_nblocks); - ssi->nfinfo = le32_to_cpu(sum->ss_nfinfo); - ssi->sumbytes = le32_to_cpu(sum->ss_sumbytes); - - ssi->nsumblk = DIV_ROUND_UP(ssi->sumbytes, blocksize); - ssi->nfileblk = ssi->nblocks - ssi->nsumblk - !!NILFS_SEG_HAS_SR(ssi); - - /* need to verify ->ss_bytes field if read ->ss_cno */ -} - /** - * calc_crc_cont - check CRC of blocks continuously - * @sbi: nilfs_sb_info + * nilfs_compute_checksum - compute checksum of blocks continuously + * @nilfs: nilfs object * @bhs: buffer head of start block * @sum: place to store result * @offset: offset bytes in the first block @@ -119,23 +101,25 @@ static void store_segsum_info(struct nilfs_segsum_info *ssi, * @start: DBN of start block * @nblock: number of blocks to be checked */ -static int calc_crc_cont(struct nilfs_sb_info *sbi, struct buffer_head *bhs, - u32 *sum, unsigned long offset, u64 check_bytes, - sector_t start, unsigned long nblock) +static int nilfs_compute_checksum(struct the_nilfs *nilfs, + struct buffer_head *bhs, u32 *sum, + unsigned long offset, u64 check_bytes, + sector_t start, unsigned long nblock) { - unsigned long blocksize = sbi->s_super->s_blocksize; + unsigned int blocksize = nilfs->ns_blocksize; unsigned long size; u32 crc; BUG_ON(offset >= blocksize); check_bytes -= offset; size = min_t(u64, check_bytes, blocksize - offset); - crc = crc32_le(sbi->s_nilfs->ns_crc_seed, + crc = crc32_le(nilfs->ns_crc_seed, (unsigned char *)bhs->b_data + offset, size); if (--nblock > 0) { do { - struct buffer_head *bh - = sb_bread(sbi->s_super, ++start); + struct buffer_head *bh; + + bh = __bread(nilfs->ns_bdev, ++start, blocksize); if (!bh) return -EIO; check_bytes -= size; @@ -150,12 +134,12 @@ static int calc_crc_cont(struct nilfs_sb_info *sbi, struct buffer_head *bhs, /** * nilfs_read_super_root_block - read super root block - * @sb: super_block + * @nilfs: nilfs object * @sr_block: disk block number of the super root block * @pbh: address of a buffer_head pointer to return super root buffer * @check: CRC check flag */ -int nilfs_read_super_root_block(struct super_block *sb, sector_t sr_block, +int nilfs_read_super_root_block(struct the_nilfs *nilfs, sector_t sr_block, struct buffer_head **pbh, int check) { struct buffer_head *bh_sr; @@ -164,7 +148,7 @@ int nilfs_read_super_root_block(struct super_block *sb, sector_t sr_block, int ret; *pbh = NULL; - bh_sr = sb_bread(sb, sr_block); + bh_sr = __bread(nilfs->ns_bdev, sr_block, nilfs->ns_blocksize); if (unlikely(!bh_sr)) { ret = NILFS_SEG_FAIL_IO; goto failed; @@ -174,12 +158,13 @@ int nilfs_read_super_root_block(struct super_block *sb, sector_t sr_block, if (check) { unsigned bytes = le16_to_cpu(sr->sr_bytes); - if (bytes == 0 || bytes > sb->s_blocksize) { + if (bytes == 0 || bytes > nilfs->ns_blocksize) { ret = NILFS_SEG_FAIL_CHECKSUM_SUPER_ROOT; goto failed_bh; } - if (calc_crc_cont(NILFS_SB(sb), bh_sr, &crc, - sizeof(sr->sr_sum), bytes, sr_block, 1)) { + if (nilfs_compute_checksum( + nilfs, bh_sr, &crc, sizeof(sr->sr_sum), bytes, + sr_block, 1)) { ret = NILFS_SEG_FAIL_IO; goto failed_bh; } @@ -199,64 +184,76 @@ int nilfs_read_super_root_block(struct super_block *sb, sector_t sr_block, } /** - * load_segment_summary - read segment summary of the specified partial segment - * @sbi: nilfs_sb_info - * @pseg_start: start disk block number of partial segment - * @seg_seq: sequence number requested - * @ssi: pointer to nilfs_segsum_info struct to store information + * nilfs_read_log_header - read summary header of the specified log + * @nilfs: nilfs object + * @start_blocknr: start block number of the log + * @sum: pointer to return segment summary structure */ -static int -load_segment_summary(struct nilfs_sb_info *sbi, sector_t pseg_start, - u64 seg_seq, struct nilfs_segsum_info *ssi) +static struct buffer_head * +nilfs_read_log_header(struct the_nilfs *nilfs, sector_t start_blocknr, + struct nilfs_segment_summary **sum) { struct buffer_head *bh_sum; - struct nilfs_segment_summary *sum; + + bh_sum = __bread(nilfs->ns_bdev, start_blocknr, nilfs->ns_blocksize); + if (bh_sum) + *sum = (struct nilfs_segment_summary *)bh_sum->b_data; + return bh_sum; +} + +/** + * nilfs_validate_log - verify consistency of log + * @nilfs: nilfs object + * @seg_seq: sequence number of segment + * @bh_sum: buffer head of summary block + * @sum: segment summary struct + */ +static int nilfs_validate_log(struct the_nilfs *nilfs, u64 seg_seq, + struct buffer_head *bh_sum, + struct nilfs_segment_summary *sum) +{ unsigned long nblock; u32 crc; - int ret = NILFS_SEG_FAIL_IO; + int ret; - bh_sum = sb_bread(sbi->s_super, pseg_start); - if (!bh_sum) + ret = NILFS_SEG_FAIL_MAGIC; + if (le32_to_cpu(sum->ss_magic) != NILFS_SEGSUM_MAGIC) goto out; - sum = (struct nilfs_segment_summary *)bh_sum->b_data; - - /* Check consistency of segment summary */ - if (le32_to_cpu(sum->ss_magic) != NILFS_SEGSUM_MAGIC) { - ret = NILFS_SEG_FAIL_MAGIC; - goto failed; - } - store_segsum_info(ssi, sum, sbi->s_super->s_blocksize); - if (seg_seq != ssi->seg_seq) { - ret = NILFS_SEG_FAIL_SEQ; - goto failed; - } + ret = NILFS_SEG_FAIL_SEQ; + if (le64_to_cpu(sum->ss_seq) != seg_seq) + goto out; - nblock = ssi->nblocks; - if (unlikely(nblock == 0 || - nblock > sbi->s_nilfs->ns_blocks_per_segment)) { + nblock = le32_to_cpu(sum->ss_nblocks); + ret = NILFS_SEG_FAIL_CONSISTENCY; + if (unlikely(nblock == 0 || nblock > nilfs->ns_blocks_per_segment)) /* This limits the number of blocks read in the CRC check */ - ret = NILFS_SEG_FAIL_CONSISTENCY; - goto failed; - } - if (calc_crc_cont(sbi, bh_sum, &crc, sizeof(sum->ss_datasum), - ((u64)nblock << sbi->s_super->s_blocksize_bits), - pseg_start, nblock)) { - ret = NILFS_SEG_FAIL_IO; - goto failed; - } - if (crc == le32_to_cpu(sum->ss_datasum)) - ret = 0; - else - ret = NILFS_SEG_FAIL_CHECKSUM_FULL; - failed: - brelse(bh_sum); - out: + goto out; + + ret = NILFS_SEG_FAIL_IO; + if (nilfs_compute_checksum(nilfs, bh_sum, &crc, sizeof(sum->ss_datasum), + ((u64)nblock << nilfs->ns_blocksize_bits), + bh_sum->b_blocknr, nblock)) + goto out; + + ret = NILFS_SEG_FAIL_CHECKSUM_FULL; + if (crc != le32_to_cpu(sum->ss_datasum)) + goto out; + ret = 0; +out: return ret; } -static void *segsum_get(struct super_block *sb, struct buffer_head **pbh, - unsigned int *offset, unsigned int bytes) +/** + * nilfs_read_summary_info - read an item on summary blocks of a log + * @nilfs: nilfs object + * @pbh: the current buffer head on summary blocks [in, out] + * @offset: the current byte offset on summary blocks [in, out] + * @bytes: byte size of the item to be read + */ +static void *nilfs_read_summary_info(struct the_nilfs *nilfs, + struct buffer_head **pbh, + unsigned int *offset, unsigned int bytes) { void *ptr; sector_t blocknr; @@ -265,7 +262,8 @@ static void *segsum_get(struct super_block *sb, struct buffer_head **pbh, if (bytes > (*pbh)->b_size - *offset) { blocknr = (*pbh)->b_blocknr; brelse(*pbh); - *pbh = sb_bread(sb, blocknr + 1); + *pbh = __bread(nilfs->ns_bdev, blocknr + 1, + nilfs->ns_blocksize); if (unlikely(!*pbh)) return NULL; *offset = 0; @@ -275,9 +273,18 @@ static void *segsum_get(struct super_block *sb, struct buffer_head **pbh, return ptr; } -static void segsum_skip(struct super_block *sb, struct buffer_head **pbh, - unsigned int *offset, unsigned int bytes, - unsigned long count) +/** + * nilfs_skip_summary_info - skip items on summary blocks of a log + * @nilfs: nilfs object + * @pbh: the current buffer head on summary blocks [in, out] + * @offset: the current byte offset on summary blocks [in, out] + * @bytes: byte size of the item to be skipped + * @count: number of items to be skipped + */ +static void nilfs_skip_summary_info(struct the_nilfs *nilfs, + struct buffer_head **pbh, + unsigned int *offset, unsigned int bytes, + unsigned long count) { unsigned int rest_item_in_current_block = ((*pbh)->b_size - *offset) / bytes; @@ -294,36 +301,46 @@ static void segsum_skip(struct super_block *sb, struct buffer_head **pbh, *offset = bytes * (count - (bcnt - 1) * nitem_per_block); brelse(*pbh); - *pbh = sb_bread(sb, blocknr + bcnt); + *pbh = __bread(nilfs->ns_bdev, blocknr + bcnt, + nilfs->ns_blocksize); } } -static int -collect_blocks_from_segsum(struct nilfs_sb_info *sbi, sector_t sum_blocknr, - struct nilfs_segsum_info *ssi, - struct list_head *head) +/** + * nilfs_scan_dsync_log - get block information of a log written for data sync + * @nilfs: nilfs object + * @start_blocknr: start block number of the log + * @sum: log summary information + * @head: list head to add nilfs_recovery_block struct + */ +static int nilfs_scan_dsync_log(struct the_nilfs *nilfs, sector_t start_blocknr, + struct nilfs_segment_summary *sum, + struct list_head *head) { struct buffer_head *bh; unsigned int offset; - unsigned long nfinfo = ssi->nfinfo; - sector_t blocknr = sum_blocknr + ssi->nsumblk; + u32 nfinfo, sumbytes; + sector_t blocknr; ino_t ino; int err = -EIO; + nfinfo = le32_to_cpu(sum->ss_nfinfo); if (!nfinfo) return 0; - bh = sb_bread(sbi->s_super, sum_blocknr); + sumbytes = le32_to_cpu(sum->ss_sumbytes); + blocknr = start_blocknr + DIV_ROUND_UP(sumbytes, nilfs->ns_blocksize); + bh = __bread(nilfs->ns_bdev, start_blocknr, nilfs->ns_blocksize); if (unlikely(!bh)) goto out; - offset = le16_to_cpu( - ((struct nilfs_segment_summary *)bh->b_data)->ss_bytes); + offset = le16_to_cpu(sum->ss_bytes); for (;;) { unsigned long nblocks, ndatablk, nnodeblk; struct nilfs_finfo *finfo; - finfo = segsum_get(sbi->s_super, &bh, &offset, sizeof(*finfo)); + finfo = nilfs_read_summary_info(nilfs, &bh, &offset, + sizeof(*finfo)); if (unlikely(!finfo)) goto out; @@ -336,8 +353,8 @@ collect_blocks_from_segsum(struct nilfs_sb_info *sbi, sector_t sum_blocknr, struct nilfs_recovery_block *rb; struct nilfs_binfo_v *binfo; - binfo = segsum_get(sbi->s_super, &bh, &offset, - sizeof(*binfo)); + binfo = nilfs_read_summary_info(nilfs, &bh, &offset, + sizeof(*binfo)); if (unlikely(!binfo)) goto out; @@ -355,9 +372,9 @@ collect_blocks_from_segsum(struct nilfs_sb_info *sbi, sector_t sum_blocknr, } if (--nfinfo == 0) break; - blocknr += nnodeblk; /* always 0 for the data sync segments */ - segsum_skip(sbi->s_super, &bh, &offset, sizeof(__le64), - nnodeblk); + blocknr += nnodeblk; /* always 0 for data sync logs */ + nilfs_skip_summary_info(nilfs, &bh, &offset, sizeof(__le64), + nnodeblk); if (unlikely(!bh)) goto out; } @@ -467,14 +484,14 @@ static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs, return err; } -static int nilfs_recovery_copy_block(struct nilfs_sb_info *sbi, +static int nilfs_recovery_copy_block(struct the_nilfs *nilfs, struct nilfs_recovery_block *rb, struct page *page) { struct buffer_head *bh_org; void *kaddr; - bh_org = sb_bread(sbi->s_super, rb->blocknr); + bh_org = __bread(nilfs->ns_bdev, rb->blocknr, nilfs->ns_blocksize); if (unlikely(!bh_org)) return -EIO; @@ -485,13 +502,14 @@ static int nilfs_recovery_copy_block(struct nilfs_sb_info *sbi, return 0; } -static int recover_dsync_blocks(struct nilfs_sb_info *sbi, - struct list_head *head, - unsigned long *nr_salvaged_blocks) +static int nilfs_recover_dsync_blocks(struct the_nilfs *nilfs, + struct nilfs_sb_info *sbi, + struct list_head *head, + unsigned long *nr_salvaged_blocks) { struct inode *inode; struct nilfs_recovery_block *rb, *n; - unsigned blocksize = sbi->s_super->s_blocksize; + unsigned blocksize = nilfs->ns_blocksize; struct page *page; loff_t pos; int err = 0, err2 = 0; @@ -511,7 +529,7 @@ static int recover_dsync_blocks(struct nilfs_sb_info *sbi, if (unlikely(err)) goto failed_inode; - err = nilfs_recovery_copy_block(sbi, rb, page); + err = nilfs_recovery_copy_block(nilfs, rb, page); if (unlikely(err)) goto failed_page; @@ -551,18 +569,20 @@ static int recover_dsync_blocks(struct nilfs_sb_info *sbi, /** * nilfs_do_roll_forward - salvage logical segments newer than the latest * checkpoint + * @nilfs: nilfs object * @sbi: nilfs_sb_info - * @nilfs: the_nilfs * @ri: pointer to a nilfs_recovery_info */ static int nilfs_do_roll_forward(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, struct nilfs_recovery_info *ri) { - struct nilfs_segsum_info ssi; + struct buffer_head *bh_sum = NULL; + struct nilfs_segment_summary *sum; sector_t pseg_start; sector_t seg_start, seg_end; /* Starting/ending DBN of full segment */ unsigned long nsalvaged_blocks = 0; + unsigned int flags; u64 seg_seq; __u64 segnum, nextnum = 0; int empty_seg = 0; @@ -581,8 +601,14 @@ static int nilfs_do_roll_forward(struct the_nilfs *nilfs, nilfs_get_segment_range(nilfs, segnum, &seg_start, &seg_end); while (segnum != ri->ri_segnum || pseg_start <= ri->ri_pseg_start) { + brelse(bh_sum); + bh_sum = nilfs_read_log_header(nilfs, pseg_start, &sum); + if (!bh_sum) { + err = -EIO; + goto failed; + } - ret = load_segment_summary(sbi, pseg_start, seg_seq, &ssi); + ret = nilfs_validate_log(nilfs, seg_seq, bh_sum, sum); if (ret) { if (ret == NILFS_SEG_FAIL_IO) { err = -EIO; @@ -590,33 +616,38 @@ static int nilfs_do_roll_forward(struct the_nilfs *nilfs, } goto strayed; } - if (unlikely(NILFS_SEG_HAS_SR(&ssi))) + + flags = le16_to_cpu(sum->ss_flags); + if (flags & NILFS_SS_SR) goto confused; /* Found a valid partial segment; do recovery actions */ - nextnum = nilfs_get_segnum_of_block(nilfs, ssi.next); + nextnum = nilfs_get_segnum_of_block(nilfs, + le64_to_cpu(sum->ss_next)); empty_seg = 0; - nilfs->ns_ctime = ssi.ctime; - if (!(ssi.flags & NILFS_SS_GC)) - nilfs->ns_nongc_ctime = ssi.ctime; + nilfs->ns_ctime = le64_to_cpu(sum->ss_create); + if (!(flags & NILFS_SS_GC)) + nilfs->ns_nongc_ctime = nilfs->ns_ctime; switch (state) { case RF_INIT_ST: - if (!NILFS_SEG_LOGBGN(&ssi) || !NILFS_SEG_DSYNC(&ssi)) + if (!(flags & NILFS_SS_LOGBGN) || + !(flags & NILFS_SS_SYNDT)) goto try_next_pseg; state = RF_DSYNC_ST; /* Fall through */ case RF_DSYNC_ST: - if (!NILFS_SEG_DSYNC(&ssi)) + if (!(flags & NILFS_SS_SYNDT)) goto confused; - err = collect_blocks_from_segsum( - sbi, pseg_start, &ssi, &dsync_blocks); + err = nilfs_scan_dsync_log(nilfs, pseg_start, sum, + &dsync_blocks); if (unlikely(err)) goto failed; - if (NILFS_SEG_LOGEND(&ssi)) { - err = recover_dsync_blocks( - sbi, &dsync_blocks, &nsalvaged_blocks); + if (flags & NILFS_SS_LOGEND) { + err = nilfs_recover_dsync_blocks( + nilfs, sbi, &dsync_blocks, + &nsalvaged_blocks); if (unlikely(err)) goto failed; state = RF_INIT_ST; @@ -627,7 +658,7 @@ static int nilfs_do_roll_forward(struct the_nilfs *nilfs, try_next_pseg: if (pseg_start == ri->ri_lsegs_end) break; - pseg_start += ssi.nblocks; + pseg_start += le32_to_cpu(sum->ss_nblocks); if (pseg_start < seg_end) continue; goto feed_segment; @@ -652,8 +683,9 @@ static int nilfs_do_roll_forward(struct the_nilfs *nilfs, ri->ri_need_recovery = NILFS_RECOVERY_ROLLFORWARD_DONE; } out: + brelse(bh_sum); dispose_recovery_list(&dsync_blocks); - nilfs_detach_writer(sbi->s_nilfs, sbi); + nilfs_detach_writer(nilfs, sbi); return err; confused: @@ -667,7 +699,6 @@ static int nilfs_do_roll_forward(struct the_nilfs *nilfs, } static void nilfs_finish_roll_forward(struct the_nilfs *nilfs, - struct nilfs_sb_info *sbi, struct nilfs_recovery_info *ri) { struct buffer_head *bh; @@ -677,7 +708,7 @@ static void nilfs_finish_roll_forward(struct the_nilfs *nilfs, nilfs_get_segnum_of_block(nilfs, ri->ri_super_root)) return; - bh = sb_getblk(sbi->s_super, ri->ri_lsegs_start); + bh = __getblk(nilfs->ns_bdev, ri->ri_lsegs_start, nilfs->ns_blocksize); BUG_ON(!bh); memset(bh->b_data, 0, bh->b_size); set_buffer_dirty(bh); @@ -690,9 +721,8 @@ static void nilfs_finish_roll_forward(struct the_nilfs *nilfs, } /** - * nilfs_recover_logical_segments - salvage logical segments written after - * the latest super root - * @nilfs: the_nilfs + * nilfs_salvage_orphan_logs - salvage logs written after the latest checkpoint + * @nilfs: nilfs object * @sbi: nilfs_sb_info * @ri: pointer to a nilfs_recovery_info struct to store search results. * @@ -709,9 +739,9 @@ static void nilfs_finish_roll_forward(struct the_nilfs *nilfs, * * %-ENOMEM - Insufficient memory available. */ -int nilfs_recover_logical_segments(struct the_nilfs *nilfs, - struct nilfs_sb_info *sbi, - struct nilfs_recovery_info *ri) +int nilfs_salvage_orphan_logs(struct the_nilfs *nilfs, + struct nilfs_sb_info *sbi, + struct nilfs_recovery_info *ri) { int err; @@ -751,7 +781,7 @@ int nilfs_recover_logical_segments(struct the_nilfs *nilfs, goto failed; } - nilfs_finish_roll_forward(nilfs, sbi, ri); + nilfs_finish_roll_forward(nilfs, ri); } failed: @@ -762,7 +792,6 @@ int nilfs_recover_logical_segments(struct the_nilfs *nilfs, /** * nilfs_search_super_root - search the latest valid super root * @nilfs: the_nilfs - * @sbi: nilfs_sb_info * @ri: pointer to a nilfs_recovery_info struct to store search results. * * nilfs_search_super_root() looks for the latest super-root from a partial @@ -776,13 +805,16 @@ int nilfs_recover_logical_segments(struct the_nilfs *nilfs, * * %-EIO - I/O error */ -int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, +int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_recovery_info *ri) { - struct nilfs_segsum_info ssi; + struct buffer_head *bh_sum = NULL; + struct nilfs_segment_summary *sum; sector_t pseg_start, pseg_end, sr_pseg_start = 0; sector_t seg_start, seg_end; /* range of full segment (block number) */ sector_t b, end; + unsigned long nblocks; + unsigned int flags; u64 seg_seq; __u64 segnum, nextnum = 0; __u64 cno; @@ -801,17 +833,24 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, /* Read ahead segment */ b = seg_start; while (b <= seg_end) - sb_breadahead(sbi->s_super, b++); + __breadahead(nilfs->ns_bdev, b++, nilfs->ns_blocksize); for (;;) { - /* Load segment summary */ - ret = load_segment_summary(sbi, pseg_start, seg_seq, &ssi); + brelse(bh_sum); + ret = NILFS_SEG_FAIL_IO; + bh_sum = nilfs_read_log_header(nilfs, pseg_start, &sum); + if (!bh_sum) + goto failed; + + ret = nilfs_validate_log(nilfs, seg_seq, bh_sum, sum); if (ret) { if (ret == NILFS_SEG_FAIL_IO) goto failed; goto strayed; } - pseg_end = pseg_start + ssi.nblocks - 1; + + nblocks = le32_to_cpu(sum->ss_nblocks); + pseg_end = pseg_start + nblocks - 1; if (unlikely(pseg_end > seg_end)) { ret = NILFS_SEG_FAIL_CONSISTENCY; goto strayed; @@ -821,11 +860,13 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, ri->ri_pseg_start = pseg_start; ri->ri_seq = seg_seq; ri->ri_segnum = segnum; - nextnum = nilfs_get_segnum_of_block(nilfs, ssi.next); + nextnum = nilfs_get_segnum_of_block(nilfs, + le64_to_cpu(sum->ss_next)); ri->ri_nextnum = nextnum; empty_seg = 0; - if (!NILFS_SEG_HAS_SR(&ssi) && !scan_newer) { + flags = le16_to_cpu(sum->ss_flags); + if (!(flags & NILFS_SS_SR) && !scan_newer) { /* This will never happen because a superblock (last_segment) always points to a pseg having a super root. */ @@ -836,14 +877,15 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, if (pseg_start == seg_start) { nilfs_get_segment_range(nilfs, nextnum, &b, &end); while (b <= end) - sb_breadahead(sbi->s_super, b++); + __breadahead(nilfs->ns_bdev, b++, + nilfs->ns_blocksize); } - if (!NILFS_SEG_HAS_SR(&ssi)) { - if (!ri->ri_lsegs_start && NILFS_SEG_LOGBGN(&ssi)) { + if (!(flags & NILFS_SS_SR)) { + if (!ri->ri_lsegs_start && (flags & NILFS_SS_LOGBGN)) { ri->ri_lsegs_start = pseg_start; ri->ri_lsegs_start_seq = seg_seq; } - if (NILFS_SEG_LOGEND(&ssi)) + if (flags & NILFS_SS_LOGEND) ri->ri_lsegs_end = pseg_start; goto try_next_pseg; } @@ -854,12 +896,12 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, ri->ri_lsegs_start = ri->ri_lsegs_end = 0; nilfs_dispose_segment_list(&segments); - nilfs->ns_pseg_offset = (sr_pseg_start = pseg_start) - + ssi.nblocks - seg_start; + sr_pseg_start = pseg_start; + nilfs->ns_pseg_offset = pseg_start + nblocks - seg_start; nilfs->ns_seg_seq = seg_seq; nilfs->ns_segnum = segnum; nilfs->ns_cno = cno; /* nilfs->ns_cno = ri->ri_cno + 1 */ - nilfs->ns_ctime = ssi.ctime; + nilfs->ns_ctime = le64_to_cpu(sum->ss_create); nilfs->ns_nextnum = nextnum; if (scan_newer) @@ -870,15 +912,9 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, scan_newer = 1; } - /* reset region for roll-forward */ - pseg_start += ssi.nblocks; - if (pseg_start < seg_end) - continue; - goto feed_segment; - try_next_pseg: /* Standing on a course, or met an inconsistent state */ - pseg_start += ssi.nblocks; + pseg_start += nblocks; if (pseg_start < seg_end) continue; goto feed_segment; @@ -909,6 +945,7 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, super_root_found: /* Updating pointers relating to the latest checkpoint */ + brelse(bh_sum); list_splice_tail(&segments, &ri->ri_used_segments); nilfs->ns_last_pseg = sr_pseg_start; nilfs->ns_last_seq = nilfs->ns_seg_seq; @@ -916,6 +953,7 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, return 0; failed: + brelse(bh_sum); nilfs_dispose_segment_list(&segments); return (ret < 0) ? ret : nilfs_warn_segment_error(ret); } diff --git a/fs/nilfs2/segbuf.h b/fs/nilfs2/segbuf.h index fdf1c3b6d673..b04f08cc2397 100644 --- a/fs/nilfs2/segbuf.h +++ b/fs/nilfs2/segbuf.h @@ -54,17 +54,6 @@ struct nilfs_segsum_info { sector_t next; }; -/* macro for the flags */ -#define NILFS_SEG_HAS_SR(sum) ((sum)->flags & NILFS_SS_SR) -#define NILFS_SEG_LOGBGN(sum) ((sum)->flags & NILFS_SS_LOGBGN) -#define NILFS_SEG_LOGEND(sum) ((sum)->flags & NILFS_SS_LOGEND) -#define NILFS_SEG_DSYNC(sum) ((sum)->flags & NILFS_SS_SYNDT) -#define NILFS_SEG_SIMPLEX(sum) \ - (((sum)->flags & (NILFS_SS_LOGBGN | NILFS_SS_LOGEND)) == \ - (NILFS_SS_LOGBGN | NILFS_SS_LOGEND)) - -#define NILFS_SEG_EMPTY(sum) ((sum)->nblocks == (sum)->nsumblk) - /** * struct nilfs_segment_buffer - Segment buffer * @sb_super: back pointer to a superblock struct @@ -127,8 +116,6 @@ struct nilfs_segment_buffer { extern struct kmem_cache *nilfs_segbuf_cachep; -int __init nilfs_init_segbuf_cache(void); -void nilfs_destroy_segbuf_cache(void); struct nilfs_segment_buffer *nilfs_segbuf_new(struct super_block *); void nilfs_segbuf_free(struct nilfs_segment_buffer *); void nilfs_segbuf_map(struct nilfs_segment_buffer *, __u64, unsigned long, @@ -143,6 +130,19 @@ int nilfs_segbuf_extend_payload(struct nilfs_segment_buffer *, struct buffer_head **); void nilfs_segbuf_fill_in_segsum(struct nilfs_segment_buffer *); +static inline int nilfs_segbuf_simplex(struct nilfs_segment_buffer *segbuf) +{ + unsigned int flags = segbuf->sb_sum.flags; + + return (flags & (NILFS_SS_LOGBGN | NILFS_SS_LOGEND)) == + (NILFS_SS_LOGBGN | NILFS_SS_LOGEND); +} + +static inline int nilfs_segbuf_empty(struct nilfs_segment_buffer *segbuf) +{ + return segbuf->sb_sum.nblocks == segbuf->sb_sum.nsumblk; +} + static inline void nilfs_segbuf_add_segsum_buffer(struct nilfs_segment_buffer *segbuf, struct buffer_head *bh) diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index c9201649cc49..1f7881ca01c4 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c @@ -1914,12 +1914,12 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci) } } - if (!NILFS_SEG_SIMPLEX(&segbuf->sb_sum)) { - if (NILFS_SEG_LOGBGN(&segbuf->sb_sum)) { + if (!nilfs_segbuf_simplex(segbuf)) { + if (segbuf->sb_sum.flags & NILFS_SS_LOGBGN) { set_bit(NILFS_SC_UNCLOSED, &sci->sc_flags); sci->sc_lseg_stime = jiffies; } - if (NILFS_SEG_LOGEND(&segbuf->sb_sum)) + if (segbuf->sb_sum.flags & NILFS_SS_LOGEND) clear_bit(NILFS_SC_UNCLOSED, &sci->sc_flags); } } @@ -2082,7 +2082,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode) /* Avoid empty segment */ if (sci->sc_stage.scnt == NILFS_ST_DONE && - NILFS_SEG_EMPTY(&sci->sc_curseg->sb_sum)) { + nilfs_segbuf_empty(sci->sc_curseg)) { nilfs_segctor_abort_construction(sci, nilfs, 1); goto out; } diff --git a/fs/nilfs2/segment.h b/fs/nilfs2/segment.h index dca142361ccf..17c487bd8152 100644 --- a/fs/nilfs2/segment.h +++ b/fs/nilfs2/segment.h @@ -221,8 +221,6 @@ enum { extern struct kmem_cache *nilfs_transaction_cachep; /* segment.c */ -extern int nilfs_init_transaction_cache(void); -extern void nilfs_destroy_transaction_cache(void); extern void nilfs_relax_pressure_in_lock(struct super_block *); extern int nilfs_construct_segment(struct super_block *); @@ -236,13 +234,13 @@ extern int nilfs_attach_segment_constructor(struct nilfs_sb_info *); extern void nilfs_detach_segment_constructor(struct nilfs_sb_info *); /* recovery.c */ -extern int nilfs_read_super_root_block(struct super_block *, sector_t, +extern int nilfs_read_super_root_block(struct the_nilfs *, sector_t, struct buffer_head **, int); -extern int nilfs_search_super_root(struct the_nilfs *, struct nilfs_sb_info *, +extern int nilfs_search_super_root(struct the_nilfs *, struct nilfs_recovery_info *); -extern int nilfs_recover_logical_segments(struct the_nilfs *, - struct nilfs_sb_info *, - struct nilfs_recovery_info *); +extern int nilfs_salvage_orphan_logs(struct the_nilfs *, + struct nilfs_sb_info *, + struct nilfs_recovery_info *); extern void nilfs_dispose_segment_list(struct list_head *); #endif /* _NILFS_SEGMENT_H */ diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 03b34b738993..414ef68931cf 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c @@ -1130,13 +1130,13 @@ static void nilfs_segbuf_init_once(void *obj) static void nilfs_destroy_cachep(void) { - if (nilfs_inode_cachep) + if (nilfs_inode_cachep) kmem_cache_destroy(nilfs_inode_cachep); - if (nilfs_transaction_cachep) + if (nilfs_transaction_cachep) kmem_cache_destroy(nilfs_transaction_cachep); - if (nilfs_segbuf_cachep) + if (nilfs_segbuf_cachep) kmem_cache_destroy(nilfs_segbuf_cachep); - if (nilfs_btree_path_cache) + if (nilfs_btree_path_cache) kmem_cache_destroy(nilfs_btree_path_cache); } diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c index 8c1097327abc..9f2cb01994d0 100644 --- a/fs/nilfs2/the_nilfs.c +++ b/fs/nilfs2/the_nilfs.c @@ -159,8 +159,7 @@ void put_nilfs(struct the_nilfs *nilfs) kfree(nilfs); } -static int nilfs_load_super_root(struct the_nilfs *nilfs, - struct nilfs_sb_info *sbi, sector_t sr_block) +static int nilfs_load_super_root(struct the_nilfs *nilfs, sector_t sr_block) { struct buffer_head *bh_sr; struct nilfs_super_root *raw_sr; @@ -169,7 +168,7 @@ static int nilfs_load_super_root(struct the_nilfs *nilfs, unsigned inode_size; int err; - err = nilfs_read_super_root_block(sbi->s_super, sr_block, &bh_sr, 1); + err = nilfs_read_super_root_block(nilfs, sr_block, &bh_sr, 1); if (unlikely(err)) return err; @@ -285,13 +284,13 @@ int load_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi) nilfs_init_recovery_info(&ri); - err = nilfs_search_super_root(nilfs, sbi, &ri); + err = nilfs_search_super_root(nilfs, &ri); if (unlikely(err)) { printk(KERN_ERR "NILFS: error searching super root.\n"); goto failed; } - err = nilfs_load_super_root(nilfs, sbi, ri.ri_super_root); + err = nilfs_load_super_root(nilfs, ri.ri_super_root); if (unlikely(err)) { printk(KERN_ERR "NILFS: error loading super root.\n"); goto failed; @@ -320,7 +319,7 @@ int load_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi) goto failed_unload; } - err = nilfs_recover_logical_segments(nilfs, sbi, &ri); + err = nilfs_salvage_orphan_logs(nilfs, sbi, &ri); if (err) goto failed_unload; @@ -604,6 +603,7 @@ int init_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, char *data) when reloading fails. */ } nilfs->ns_blocksize_bits = sb->s_blocksize_bits; + nilfs->ns_blocksize = blocksize; err = nilfs_store_disk_layout(nilfs, sbp); if (err) diff --git a/fs/nilfs2/the_nilfs.h b/fs/nilfs2/the_nilfs.h index 1ab974533697..85df47f0730f 100644 --- a/fs/nilfs2/the_nilfs.h +++ b/fs/nilfs2/the_nilfs.h @@ -82,6 +82,7 @@ enum { * @ns_gc_inodes: dummy inodes to keep live blocks * @ns_gc_inodes_h: hash list to keep dummy inode holding live blocks * @ns_blocksize_bits: bit length of block size + * @ns_blocksize: block size * @ns_nsegments: number of segments in filesystem * @ns_blocks_per_segment: number of blocks per segment * @ns_r_segments_percentage: reserved segments percentage @@ -168,6 +169,7 @@ struct the_nilfs { /* Disk layout information (static) */ unsigned int ns_blocksize_bits; + unsigned int ns_blocksize; unsigned long ns_nsegments; unsigned long ns_blocks_per_segment; unsigned long ns_r_segments_percentage; diff --git a/fs/ocfs2/reservations.c b/fs/ocfs2/reservations.c index 40650021fc24..d8b6e4259b80 100644 --- a/fs/ocfs2/reservations.c +++ b/fs/ocfs2/reservations.c @@ -26,7 +26,6 @@ #include <linux/fs.h> #include <linux/types.h> -#include <linux/slab.h> #include <linux/highmem.h> #include <linux/bitops.h> #include <linux/list.h> diff --git a/fs/udf/file.c b/fs/udf/file.c index 94e06d6bddbd..6e450e01a1bb 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c @@ -36,7 +36,6 @@ #include <linux/pagemap.h> #include <linux/buffer_head.h> #include <linux/aio.h> -#include <linux/smp_lock.h> #include "udf_i.h" #include "udf_sb.h" diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 9c8019c78c92..44f0b2de153e 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c @@ -585,11 +585,20 @@ xfs_vn_fallocate( bf.l_len = len; xfs_ilock(ip, XFS_IOLOCK_EXCL); + + /* check the new inode size is valid before allocating */ + if (!(mode & FALLOC_FL_KEEP_SIZE) && + offset + len > i_size_read(inode)) { + new_size = offset + len; + error = inode_newsize_ok(inode, new_size); + if (error) + goto out_unlock; + } + error = -xfs_change_file_space(ip, XFS_IOC_RESVSP, &bf, 0, XFS_ATTR_NOLOCK); - if (!error && !(mode & FALLOC_FL_KEEP_SIZE) && - offset + len > i_size_read(inode)) - new_size = offset + len; + if (error) + goto out_unlock; /* Change file size if needed */ if (new_size) { @@ -600,6 +609,7 @@ xfs_vn_fallocate( error = -xfs_setattr(ip, &iattr, XFS_ATTR_NOLOCK); } +out_unlock: xfs_iunlock(ip, XFS_IOLOCK_EXCL); out_error: return error; diff --git a/fs/xfs/linux-2.6/xfs_quotaops.c b/fs/xfs/linux-2.6/xfs_quotaops.c index 9ac8aea91529..067cafbfc635 100644 --- a/fs/xfs/linux-2.6/xfs_quotaops.c +++ b/fs/xfs/linux-2.6/xfs_quotaops.c @@ -23,7 +23,6 @@ #include "xfs_ag.h" #include "xfs_mount.h" #include "xfs_quota.h" -#include "xfs_log.h" #include "xfs_trans.h" #include "xfs_bmap_btree.h" #include "xfs_inode.h" diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c index 3884e20bc14e..ef7f0218bccb 100644 --- a/fs/xfs/linux-2.6/xfs_sync.c +++ b/fs/xfs/linux-2.6/xfs_sync.c @@ -164,10 +164,6 @@ xfs_inode_ag_iterator( struct xfs_perag *pag; pag = xfs_perag_get(mp, ag); - if (!pag->pag_ici_init) { - xfs_perag_put(pag); - continue; - } error = xfs_inode_ag_walk(mp, pag, execute, flags, tag, exclusive, &nr); xfs_perag_put(pag); @@ -867,12 +863,7 @@ xfs_reclaim_inode_shrink( down_read(&xfs_mount_list_lock); list_for_each_entry(mp, &xfs_mount_list, m_mplist) { for (ag = 0; ag < mp->m_sb.sb_agcount; ag++) { - pag = xfs_perag_get(mp, ag); - if (!pag->pag_ici_init) { - xfs_perag_put(pag); - continue; - } reclaimable += pag->pag_ici_reclaimable; xfs_perag_put(pag); } diff --git a/fs/xfs/linux-2.6/xfs_trace.c b/fs/xfs/linux-2.6/xfs_trace.c index 207fa77f63ae..d12be8470cba 100644 --- a/fs/xfs/linux-2.6/xfs_trace.c +++ b/fs/xfs/linux-2.6/xfs_trace.c @@ -50,7 +50,6 @@ #include "quota/xfs_dquot_item.h" #include "quota/xfs_dquot.h" #include "xfs_log_recover.h" -#include "xfs_buf_item.h" #include "xfs_inode_item.h" /* diff --git a/fs/xfs/linux-2.6/xfs_trace.h b/fs/xfs/linux-2.6/xfs_trace.h index ff6bc797baf2..73d5aa117384 100644 --- a/fs/xfs/linux-2.6/xfs_trace.h +++ b/fs/xfs/linux-2.6/xfs_trace.h @@ -82,33 +82,6 @@ DECLARE_EVENT_CLASS(xfs_attr_list_class, ) ) -#define DEFINE_PERAG_REF_EVENT(name) \ -TRACE_EVENT(name, \ - TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, int refcount, \ - unsigned long caller_ip), \ - TP_ARGS(mp, agno, refcount, caller_ip), \ - TP_STRUCT__entry( \ - __field(dev_t, dev) \ - __field(xfs_agnumber_t, agno) \ - __field(int, refcount) \ - __field(unsigned long, caller_ip) \ - ), \ - TP_fast_assign( \ - __entry->dev = mp->m_super->s_dev; \ - __entry->agno = agno; \ - __entry->refcount = refcount; \ - __entry->caller_ip = caller_ip; \ - ), \ - TP_printk("dev %d:%d agno %u refcount %d caller %pf", \ - MAJOR(__entry->dev), MINOR(__entry->dev), \ - __entry->agno, \ - __entry->refcount, \ - (char *)__entry->caller_ip) \ -); - -DEFINE_PERAG_REF_EVENT(xfs_perag_get) -DEFINE_PERAG_REF_EVENT(xfs_perag_put) - #define DEFINE_ATTR_LIST_EVENT(name) \ DEFINE_EVENT(xfs_attr_list_class, name, \ TP_PROTO(struct xfs_attr_list_context *ctx), \ @@ -122,6 +95,37 @@ DEFINE_ATTR_LIST_EVENT(xfs_attr_list_add); DEFINE_ATTR_LIST_EVENT(xfs_attr_list_wrong_blk); DEFINE_ATTR_LIST_EVENT(xfs_attr_list_notfound); +DECLARE_EVENT_CLASS(xfs_perag_class, + TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, int refcount, + unsigned long caller_ip), + TP_ARGS(mp, agno, refcount, caller_ip), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_agnumber_t, agno) + __field(int, refcount) + __field(unsigned long, caller_ip) + ), + TP_fast_assign( + __entry->dev = mp->m_super->s_dev; + __entry->agno = agno; + __entry->refcount = refcount; + __entry->caller_ip = caller_ip; + ), + TP_printk("dev %d:%d agno %u refcount %d caller %pf", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->agno, + __entry->refcount, + (char *)__entry->caller_ip) +); + +#define DEFINE_PERAG_REF_EVENT(name) \ +DEFINE_EVENT(xfs_perag_class, name, \ + TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, int refcount, \ + unsigned long caller_ip), \ + TP_ARGS(mp, agno, refcount, caller_ip)) +DEFINE_PERAG_REF_EVENT(xfs_perag_get); +DEFINE_PERAG_REF_EVENT(xfs_perag_put); + TRACE_EVENT(xfs_attr_list_node_descend, TP_PROTO(struct xfs_attr_list_context *ctx, struct xfs_da_node_entry *btree), @@ -775,165 +779,181 @@ DEFINE_LOGGRANT_EVENT(xfs_log_ungrant_enter); DEFINE_LOGGRANT_EVENT(xfs_log_ungrant_exit); DEFINE_LOGGRANT_EVENT(xfs_log_ungrant_sub); -#define DEFINE_RW_EVENT(name) \ -TRACE_EVENT(name, \ - TP_PROTO(struct xfs_inode *ip, size_t count, loff_t offset, int flags), \ - TP_ARGS(ip, count, offset, flags), \ - TP_STRUCT__entry( \ - __field(dev_t, dev) \ - __field(xfs_ino_t, ino) \ - __field(xfs_fsize_t, size) \ - __field(xfs_fsize_t, new_size) \ - __field(loff_t, offset) \ - __field(size_t, count) \ - __field(int, flags) \ - ), \ - TP_fast_assign( \ - __entry->dev = VFS_I(ip)->i_sb->s_dev; \ - __entry->ino = ip->i_ino; \ - __entry->size = ip->i_d.di_size; \ - __entry->new_size = ip->i_new_size; \ - __entry->offset = offset; \ - __entry->count = count; \ - __entry->flags = flags; \ - ), \ - TP_printk("dev %d:%d ino 0x%llx size 0x%llx new_size 0x%llx " \ - "offset 0x%llx count 0x%zx ioflags %s", \ - MAJOR(__entry->dev), MINOR(__entry->dev), \ - __entry->ino, \ - __entry->size, \ - __entry->new_size, \ - __entry->offset, \ - __entry->count, \ - __print_flags(__entry->flags, "|", XFS_IO_FLAGS)) \ +DECLARE_EVENT_CLASS(xfs_file_class, + TP_PROTO(struct xfs_inode *ip, size_t count, loff_t offset, int flags), + TP_ARGS(ip, count, offset, flags), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_ino_t, ino) + __field(xfs_fsize_t, size) + __field(xfs_fsize_t, new_size) + __field(loff_t, offset) + __field(size_t, count) + __field(int, flags) + ), + TP_fast_assign( + __entry->dev = VFS_I(ip)->i_sb->s_dev; + __entry->ino = ip->i_ino; + __entry->size = ip->i_d.di_size; + __entry->new_size = ip->i_new_size; + __entry->offset = offset; + __entry->count = count; + __entry->flags = flags; + ), + TP_printk("dev %d:%d ino 0x%llx size 0x%llx new_size 0x%llx " + "offset 0x%llx count 0x%zx ioflags %s", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, + __entry->size, + __entry->new_size, + __entry->offset, + __entry->count, + __print_flags(__entry->flags, "|", XFS_IO_FLAGS)) ) + +#define DEFINE_RW_EVENT(name) \ +DEFINE_EVENT(xfs_file_class, name, \ + TP_PROTO(struct xfs_inode *ip, size_t count, loff_t offset, int flags), \ + TP_ARGS(ip, count, offset, flags)) DEFINE_RW_EVENT(xfs_file_read); DEFINE_RW_EVENT(xfs_file_buffered_write); DEFINE_RW_EVENT(xfs_file_direct_write); DEFINE_RW_EVENT(xfs_file_splice_read); DEFINE_RW_EVENT(xfs_file_splice_write); - -#define DEFINE_PAGE_EVENT(name) \ -TRACE_EVENT(name, \ - TP_PROTO(struct inode *inode, struct page *page, unsigned long off), \ - TP_ARGS(inode, page, off), \ - TP_STRUCT__entry( \ - __field(dev_t, dev) \ - __field(xfs_ino_t, ino) \ - __field(pgoff_t, pgoff) \ - __field(loff_t, size) \ - __field(unsigned long, offset) \ - __field(int, delalloc) \ - __field(int, unmapped) \ - __field(int, unwritten) \ - ), \ - TP_fast_assign( \ - int delalloc = -1, unmapped = -1, unwritten = -1; \ - \ - if (page_has_buffers(page)) \ - xfs_count_page_state(page, &delalloc, \ - &unmapped, &unwritten); \ - __entry->dev = inode->i_sb->s_dev; \ - __entry->ino = XFS_I(inode)->i_ino; \ - __entry->pgoff = page_offset(page); \ - __entry->size = i_size_read(inode); \ - __entry->offset = off; \ - __entry->delalloc = delalloc; \ - __entry->unmapped = unmapped; \ - __entry->unwritten = unwritten; \ - ), \ - TP_printk("dev %d:%d ino 0x%llx pgoff 0x%lx size 0x%llx offset %lx " \ - "delalloc %d unmapped %d unwritten %d", \ - MAJOR(__entry->dev), MINOR(__entry->dev), \ - __entry->ino, \ - __entry->pgoff, \ - __entry->size, \ - __entry->offset, \ - __entry->delalloc, \ - __entry->unmapped, \ - __entry->unwritten) \ +DECLARE_EVENT_CLASS(xfs_page_class, + TP_PROTO(struct inode *inode, struct page *page, unsigned long off), + TP_ARGS(inode, page, off), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_ino_t, ino) + __field(pgoff_t, pgoff) + __field(loff_t, size) + __field(unsigned long, offset) + __field(int, delalloc) + __field(int, unmapped) + __field(int, unwritten) + ), + TP_fast_assign( + int delalloc = -1, unmapped = -1, unwritten = -1; + + if (page_has_buffers(page)) + xfs_count_page_state(page, &delalloc, + &unmapped, &unwritten); + __entry->dev = inode->i_sb->s_dev; + __entry->ino = XFS_I(inode)->i_ino; + __entry->pgoff = page_offset(page); + __entry->size = i_size_read(inode); + __entry->offset = off; + __entry->delalloc = delalloc; + __entry->unmapped = unmapped; + __entry->unwritten = unwritten; + ), + TP_printk("dev %d:%d ino 0x%llx pgoff 0x%lx size 0x%llx offset %lx " + "delalloc %d unmapped %d unwritten %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, + __entry->pgoff, + __entry->size, + __entry->offset, + __entry->delalloc, + __entry->unmapped, + __entry->unwritten) ) + +#define DEFINE_PAGE_EVENT(name) \ +DEFINE_EVENT(xfs_page_class, name, \ + TP_PROTO(struct inode *inode, struct page *page, unsigned long off), \ + TP_ARGS(inode, page, off)) DEFINE_PAGE_EVENT(xfs_writepage); DEFINE_PAGE_EVENT(xfs_releasepage); DEFINE_PAGE_EVENT(xfs_invalidatepage); -#define DEFINE_IOMAP_EVENT(name) \ -TRACE_EVENT(name, \ - TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count, \ - int flags, struct xfs_bmbt_irec *irec), \ - TP_ARGS(ip, offset, count, flags, irec), \ - TP_STRUCT__entry( \ - __field(dev_t, dev) \ - __field(xfs_ino_t, ino) \ - __field(loff_t, size) \ - __field(loff_t, new_size) \ - __field(loff_t, offset) \ - __field(size_t, count) \ - __field(int, flags) \ - __field(xfs_fileoff_t, startoff) \ - __field(xfs_fsblock_t, startblock) \ - __field(xfs_filblks_t, blockcount) \ - ), \ - TP_fast_assign( \ - __entry->dev = VFS_I(ip)->i_sb->s_dev; \ - __entry->ino = ip->i_ino; \ - __entry->size = ip->i_d.di_size; \ - __entry->new_size = ip->i_new_size; \ - __entry->offset = offset; \ - __entry->count = count; \ - __entry->flags = flags; \ - __entry->startoff = irec ? irec->br_startoff : 0; \ - __entry->startblock = irec ? irec->br_startblock : 0; \ - __entry->blockcount = irec ? irec->br_blockcount : 0; \ - ), \ - TP_printk("dev %d:%d ino 0x%llx size 0x%llx new_size 0x%llx " \ - "offset 0x%llx count %zd flags %s " \ - "startoff 0x%llx startblock %lld blockcount 0x%llx", \ - MAJOR(__entry->dev), MINOR(__entry->dev), \ - __entry->ino, \ - __entry->size, \ - __entry->new_size, \ - __entry->offset, \ - __entry->count, \ - __print_flags(__entry->flags, "|", BMAPI_FLAGS), \ - __entry->startoff, \ - (__int64_t)__entry->startblock, \ - __entry->blockcount) \ +DECLARE_EVENT_CLASS(xfs_iomap_class, + TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count, + int flags, struct xfs_bmbt_irec *irec), + TP_ARGS(ip, offset, count, flags, irec), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_ino_t, ino) + __field(loff_t, size) + __field(loff_t, new_size) + __field(loff_t, offset) + __field(size_t, count) + __field(int, flags) + __field(xfs_fileoff_t, startoff) + __field(xfs_fsblock_t, startblock) + __field(xfs_filblks_t, blockcount) + ), + TP_fast_assign( + __entry->dev = VFS_I(ip)->i_sb->s_dev; + __entry->ino = ip->i_ino; + __entry->size = ip->i_d.di_size; + __entry->new_size = ip->i_new_size; + __entry->offset = offset; + __entry->count = count; + __entry->flags = flags; + __entry->startoff = irec ? irec->br_startoff : 0; + __entry->startblock = irec ? irec->br_startblock : 0; + __entry->blockcount = irec ? irec->br_blockcount : 0; + ), + TP_printk("dev %d:%d ino 0x%llx size 0x%llx new_size 0x%llx " + "offset 0x%llx count %zd flags %s " + "startoff 0x%llx startblock %lld blockcount 0x%llx", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, + __entry->size, + __entry->new_size, + __entry->offset, + __entry->count, + __print_flags(__entry->flags, "|", BMAPI_FLAGS), + __entry->startoff, + (__int64_t)__entry->startblock, + __entry->blockcount) ) + +#define DEFINE_IOMAP_EVENT(name) \ +DEFINE_EVENT(xfs_iomap_class, name, \ + TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count, \ + int flags, struct xfs_bmbt_irec *irec), \ + TP_ARGS(ip, offset, count, flags, irec)) DEFINE_IOMAP_EVENT(xfs_iomap_enter); DEFINE_IOMAP_EVENT(xfs_iomap_found); DEFINE_IOMAP_EVENT(xfs_iomap_alloc); -#define DEFINE_SIMPLE_IO_EVENT(name) \ -TRACE_EVENT(name, \ - TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count), \ - TP_ARGS(ip, offset, count), \ - TP_STRUCT__entry( \ - __field(dev_t, dev) \ - __field(xfs_ino_t, ino) \ - __field(loff_t, size) \ - __field(loff_t, new_size) \ - __field(loff_t, offset) \ - __field(size_t, count) \ - ), \ - TP_fast_assign( \ - __entry->dev = VFS_I(ip)->i_sb->s_dev; \ - __entry->ino = ip->i_ino; \ - __entry->size = ip->i_d.di_size; \ - __entry->new_size = ip->i_new_size; \ - __entry->offset = offset; \ - __entry->count = count; \ - ), \ - TP_printk("dev %d:%d ino 0x%llx size 0x%llx new_size 0x%llx " \ - "offset 0x%llx count %zd", \ - MAJOR(__entry->dev), MINOR(__entry->dev), \ - __entry->ino, \ - __entry->size, \ - __entry->new_size, \ - __entry->offset, \ - __entry->count) \ +DECLARE_EVENT_CLASS(xfs_simple_io_class, + TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count), + TP_ARGS(ip, offset, count), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_ino_t, ino) + __field(loff_t, size) + __field(loff_t, new_size) + __field(loff_t, offset) + __field(size_t, count) + ), + TP_fast_assign( + __entry->dev = VFS_I(ip)->i_sb->s_dev; + __entry->ino = ip->i_ino; + __entry->size = ip->i_d.di_size; + __entry->new_size = ip->i_new_size; + __entry->offset = offset; + __entry->count = count; + ), + TP_printk("dev %d:%d ino 0x%llx size 0x%llx new_size 0x%llx " + "offset 0x%llx count %zd", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, + __entry->size, + __entry->new_size, + __entry->offset, + __entry->count) ); + +#define DEFINE_SIMPLE_IO_EVENT(name) \ +DEFINE_EVENT(xfs_simple_io_class, name, \ + TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count), \ + TP_ARGS(ip, offset, count)) DEFINE_SIMPLE_IO_EVENT(xfs_delalloc_enospc); DEFINE_SIMPLE_IO_EVENT(xfs_unwritten_convert); diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index 38e764146644..2d8b7bc792c9 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c @@ -249,8 +249,10 @@ xfs_qm_hold_quotafs_ref( if (!xfs_Gqm) { xfs_Gqm = xfs_Gqm_init(); - if (!xfs_Gqm) + if (!xfs_Gqm) { + mutex_unlock(&xfs_Gqm_lock); return ENOMEM; + } } /* diff --git a/fs/xfs/xfs_ag.h b/fs/xfs/xfs_ag.h index 401f364ad36c..4917d4eed4ed 100644 --- a/fs/xfs/xfs_ag.h +++ b/fs/xfs/xfs_ag.h @@ -227,7 +227,6 @@ typedef struct xfs_perag { atomic_t pagf_fstrms; /* # of filestreams active in this AG */ - int pag_ici_init; /* incore inode cache initialised */ rwlock_t pag_ici_lock; /* incore inode lock */ struct radix_tree_root pag_ici_root; /* incore inode cache root */ int pag_ici_reclaimable; /* reclaimable inodes */ diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index 6845db90818f..f44a367907a8 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c @@ -382,9 +382,6 @@ xfs_iget( /* get the perag structure and ensure that it's inode capable */ pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ino)); - if (!pag->pagi_inodeok) - return EINVAL; - ASSERT(pag->pag_ici_init); agino = XFS_INO_TO_AGINO(mp, ino); again: diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 8cd6e8d8fe9c..6ba7765026f6 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -2649,8 +2649,6 @@ xfs_iflush_cluster( int i; pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino)); - ASSERT(pag->pagi_inodeok); - ASSERT(pag->pag_ici_init); inodes_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog; ilist_size = inodes_per_cluster * sizeof(xfs_inode_t *); diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 14a69aec2c0b..ed0684cc50ee 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -132,15 +132,10 @@ xlog_align( int nbblks, xfs_buf_t *bp) { - xfs_daddr_t offset; - xfs_caddr_t ptr; + xfs_daddr_t offset = blk_no & ((xfs_daddr_t)log->l_sectBBsize - 1); - offset = blk_no & ((xfs_daddr_t) log->l_sectBBsize - 1); - ptr = XFS_BUF_PTR(bp) + BBTOB(offset); - - ASSERT(ptr + BBTOB(nbblks) <= XFS_BUF_PTR(bp) + XFS_BUF_SIZE(bp)); - - return ptr; + ASSERT(BBTOB(offset + nbblks) <= XFS_BUF_SIZE(bp)); + return XFS_BUF_PTR(bp) + BBTOB(offset); } diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index d7bf38c8cd1c..d59f4e8bedcf 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -268,10 +268,10 @@ xfs_sb_validate_fsb_count( #if XFS_BIG_BLKNOS /* Limited by ULONG_MAX of page cache index */ if (nblocks >> (PAGE_CACHE_SHIFT - sbp->sb_blocklog) > ULONG_MAX) - return E2BIG; + return EFBIG; #else /* Limited by UINT_MAX of sectors */ if (nblocks << (sbp->sb_blocklog - BBSHIFT) > UINT_MAX) - return E2BIG; + return EFBIG; #endif return 0; } @@ -393,7 +393,7 @@ xfs_mount_validate_sb( xfs_sb_validate_fsb_count(sbp, sbp->sb_rblocks)) { xfs_fs_mount_cmn_err(flags, "file system too large to be mounted on this system."); - return XFS_ERROR(E2BIG); + return XFS_ERROR(EFBIG); } if (unlikely(sbp->sb_inprogress)) { @@ -413,17 +413,6 @@ xfs_mount_validate_sb( return 0; } -STATIC void -xfs_initialize_perag_icache( - xfs_perag_t *pag) -{ - if (!pag->pag_ici_init) { - rwlock_init(&pag->pag_ici_lock); - INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC); - pag->pag_ici_init = 1; - } -} - int xfs_initialize_perag( xfs_mount_t *mp, @@ -436,13 +425,8 @@ xfs_initialize_perag( xfs_agino_t agino; xfs_ino_t ino; xfs_sb_t *sbp = &mp->m_sb; - xfs_ino_t max_inum = XFS_MAXINUMBER_32; int error = -ENOMEM; - /* Check to see if the filesystem can overflow 32 bit inodes */ - agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks - 1, 0); - ino = XFS_AGINO_TO_INO(mp, agcount - 1, agino); - /* * Walk the current per-ag tree so we don't try to initialise AGs * that already exist (growfs case). Allocate and insert all the @@ -456,11 +440,18 @@ xfs_initialize_perag( } if (!first_initialised) first_initialised = index; + pag = kmem_zalloc(sizeof(*pag), KM_MAYFAIL); if (!pag) goto out_unwind; + pag->pag_agno = index; + pag->pag_mount = mp; + rwlock_init(&pag->pag_ici_lock); + INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC); + if (radix_tree_preload(GFP_NOFS)) goto out_unwind; + spin_lock(&mp->m_perag_lock); if (radix_tree_insert(&mp->m_perag_tree, index, pag)) { BUG(); @@ -469,25 +460,26 @@ xfs_initialize_perag( error = -EEXIST; goto out_unwind; } - pag->pag_agno = index; - pag->pag_mount = mp; spin_unlock(&mp->m_perag_lock); radix_tree_preload_end(); } - /* Clear the mount flag if no inode can overflow 32 bits - * on this filesystem, or if specifically requested.. + /* + * If we mount with the inode64 option, or no inode overflows + * the legacy 32-bit address space clear the inode32 option. */ - if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) && ino > max_inum) { + agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks - 1, 0); + ino = XFS_AGINO_TO_INO(mp, agcount - 1, agino); + + if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) && ino > XFS_MAXINUMBER_32) mp->m_flags |= XFS_MOUNT_32BITINODES; - } else { + else mp->m_flags &= ~XFS_MOUNT_32BITINODES; - } - /* If we can overflow then setup the ag headers accordingly */ if (mp->m_flags & XFS_MOUNT_32BITINODES) { - /* Calculate how much should be reserved for inodes to - * meet the max inode percentage. + /* + * Calculate how much should be reserved for inodes to meet + * the max inode percentage. */ if (mp->m_maxicount) { __uint64_t icount; @@ -500,30 +492,28 @@ xfs_initialize_perag( } else { max_metadata = agcount; } + for (index = 0; index < agcount; index++) { ino = XFS_AGINO_TO_INO(mp, index, agino); - if (ino > max_inum) { + if (ino > XFS_MAXINUMBER_32) { index++; break; } - /* This ag is preferred for inodes */ pag = xfs_perag_get(mp, index); pag->pagi_inodeok = 1; if (index < max_metadata) pag->pagf_metadata = 1; - xfs_initialize_perag_icache(pag); xfs_perag_put(pag); } } else { - /* Setup default behavior for smaller filesystems */ for (index = 0; index < agcount; index++) { pag = xfs_perag_get(mp, index); pag->pagi_inodeok = 1; - xfs_initialize_perag_icache(pag); xfs_perag_put(pag); } } + if (maxagi) *maxagi = index; return 0; @@ -1009,7 +999,7 @@ xfs_check_sizes(xfs_mount_t *mp) d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks); if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_dblocks) { cmn_err(CE_WARN, "XFS: size check 1 failed"); - return XFS_ERROR(E2BIG); + return XFS_ERROR(EFBIG); } error = xfs_read_buf(mp, mp->m_ddev_targp, d - XFS_FSS_TO_BB(mp, 1), @@ -1019,7 +1009,7 @@ xfs_check_sizes(xfs_mount_t *mp) } else { cmn_err(CE_WARN, "XFS: size check 2 failed"); if (error == ENOSPC) - error = XFS_ERROR(E2BIG); + error = XFS_ERROR(EFBIG); return error; } @@ -1027,7 +1017,7 @@ xfs_check_sizes(xfs_mount_t *mp) d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks); if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_logblocks) { cmn_err(CE_WARN, "XFS: size check 3 failed"); - return XFS_ERROR(E2BIG); + return XFS_ERROR(EFBIG); } error = xfs_read_buf(mp, mp->m_logdev_targp, d - XFS_FSB_TO_BB(mp, 1), @@ -1037,7 +1027,7 @@ xfs_check_sizes(xfs_mount_t *mp) } else { cmn_err(CE_WARN, "XFS: size check 3 failed"); if (error == ENOSPC) - error = XFS_ERROR(E2BIG); + error = XFS_ERROR(EFBIG); return error; } } @@ -1254,7 +1244,7 @@ xfs_mountfs( * Allocate and initialize the per-ag data. */ spin_lock_init(&mp->m_perag_lock); - INIT_RADIX_TREE(&mp->m_perag_tree, GFP_NOFS); + INIT_RADIX_TREE(&mp->m_perag_tree, GFP_ATOMIC); error = xfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi); if (error) { cmn_err(CE_WARN, "XFS: Failed per-ag init: %d", error); diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 6be05f756d59..16445518506d 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -2247,7 +2247,7 @@ xfs_rtmount_init( cmn_err(CE_WARN, "XFS: realtime mount -- %llu != %llu", (unsigned long long) XFS_BB_TO_FSB(mp, d), (unsigned long long) mp->m_sb.sb_rblocks); - return XFS_ERROR(E2BIG); + return XFS_ERROR(EFBIG); } error = xfs_read_buf(mp, mp->m_rtdev_targp, d - XFS_FSB_TO_BB(mp, 1), @@ -2256,7 +2256,7 @@ xfs_rtmount_init( cmn_err(CE_WARN, "XFS: realtime mount -- xfs_read_buf failed, returned %d", error); if (error == ENOSPC) - return XFS_ERROR(E2BIG); + return XFS_ERROR(EFBIG); return error; } xfs_buf_relse(bp); diff --git a/fs/xfs/xfs_rtalloc.h b/fs/xfs/xfs_rtalloc.h index b2d67adb6a08..ff614c29b441 100644 --- a/fs/xfs/xfs_rtalloc.h +++ b/fs/xfs/xfs_rtalloc.h @@ -147,7 +147,16 @@ xfs_growfs_rt( # define xfs_rtfree_extent(t,b,l) (ENOSYS) # define xfs_rtpick_extent(m,t,l,rb) (ENOSYS) # define xfs_growfs_rt(mp,in) (ENOSYS) -# define xfs_rtmount_init(m) (((mp)->m_sb.sb_rblocks == 0)? 0 : (ENOSYS)) +static inline int /* error */ +xfs_rtmount_init( + xfs_mount_t *mp) /* file system mount structure */ +{ + if (mp->m_sb.sb_rblocks == 0) + return 0; + + cmn_err(CE_WARN, "XFS: Not built with CONFIG_XFS_RT"); + return ENOSYS; +} # define xfs_rtmount_inodes(m) (((mp)->m_sb.sb_rblocks == 0)? 0 : (ENOSYS)) # define xfs_rtunmount_inodes(m) #endif /* CONFIG_XFS_RT */ diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index ce558efa2ea0..28547dfce037 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -48,134 +48,489 @@ kmem_zone_t *xfs_trans_zone; + /* - * Reservation functions here avoid a huge stack in xfs_trans_init - * due to register overflow from temporaries in the calculations. + * Various log reservation values. + * + * These are based on the size of the file system block because that is what + * most transactions manipulate. Each adds in an additional 128 bytes per + * item logged to try to account for the overhead of the transaction mechanism. + * + * Note: Most of the reservations underestimate the number of allocation + * groups into which they could free extents in the xfs_bmap_finish() call. + * This is because the number in the worst case is quite high and quite + * unusual. In order to fix this we need to change xfs_bmap_finish() to free + * extents in only a single AG at a time. This will require changes to the + * EFI code as well, however, so that the EFI for the extents not freed is + * logged again in each transaction. See SGI PV #261917. + * + * Reservation functions here avoid a huge stack in xfs_trans_init due to + * register overflow from temporaries in the calculations. + */ + + +/* + * In a write transaction we can allocate a maximum of 2 + * extents. This gives: + * the inode getting the new extents: inode size + * the inode's bmap btree: max depth * block size + * the agfs of the ags from which the extents are allocated: 2 * sector + * the superblock free block counter: sector size + * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size + * And the bmap_finish transaction can free bmap blocks in a join: + * the agfs of the ags containing the blocks: 2 * sector size + * the agfls of the ags containing the blocks: 2 * sector size + * the super block free block counter: sector size + * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size */ STATIC uint -xfs_calc_write_reservation(xfs_mount_t *mp) +xfs_calc_write_reservation( + struct xfs_mount *mp) { - return XFS_CALC_WRITE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); + return XFS_DQUOT_LOGRES(mp) + + MAX((mp->m_sb.sb_inodesize + + XFS_FSB_TO_B(mp, XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)) + + 2 * mp->m_sb.sb_sectsize + + mp->m_sb.sb_sectsize + + XFS_ALLOCFREE_LOG_RES(mp, 2) + + 128 * (4 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + + XFS_ALLOCFREE_LOG_COUNT(mp, 2))), + (2 * mp->m_sb.sb_sectsize + + 2 * mp->m_sb.sb_sectsize + + mp->m_sb.sb_sectsize + + XFS_ALLOCFREE_LOG_RES(mp, 2) + + 128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2)))); } +/* + * In truncating a file we free up to two extents at once. We can modify: + * the inode being truncated: inode size + * the inode's bmap btree: (max depth + 1) * block size + * And the bmap_finish transaction can free the blocks and bmap blocks: + * the agf for each of the ags: 4 * sector size + * the agfl for each of the ags: 4 * sector size + * the super block to reflect the freed blocks: sector size + * worst case split in allocation btrees per extent assuming 4 extents: + * 4 exts * 2 trees * (2 * max depth - 1) * block size + * the inode btree: max depth * blocksize + * the allocation btrees: 2 trees * (max depth - 1) * block size + */ STATIC uint -xfs_calc_itruncate_reservation(xfs_mount_t *mp) +xfs_calc_itruncate_reservation( + struct xfs_mount *mp) { - return XFS_CALC_ITRUNCATE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); + return XFS_DQUOT_LOGRES(mp) + + MAX((mp->m_sb.sb_inodesize + + XFS_FSB_TO_B(mp, XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + 1) + + 128 * (2 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK))), + (4 * mp->m_sb.sb_sectsize + + 4 * mp->m_sb.sb_sectsize + + mp->m_sb.sb_sectsize + + XFS_ALLOCFREE_LOG_RES(mp, 4) + + 128 * (9 + XFS_ALLOCFREE_LOG_COUNT(mp, 4)) + + 128 * 5 + + XFS_ALLOCFREE_LOG_RES(mp, 1) + + 128 * (2 + XFS_IALLOC_BLOCKS(mp) + mp->m_in_maxlevels + + XFS_ALLOCFREE_LOG_COUNT(mp, 1)))); } +/* + * In renaming a files we can modify: + * the four inodes involved: 4 * inode size + * the two directory btrees: 2 * (max depth + v2) * dir block size + * the two directory bmap btrees: 2 * max depth * block size + * And the bmap_finish transaction can free dir and bmap blocks (two sets + * of bmap blocks) giving: + * the agf for the ags in which the blocks live: 3 * sector size + * the agfl for the ags in which the blocks live: 3 * sector size + * the superblock for the free block count: sector size + * the allocation btrees: 3 exts * 2 trees * (2 * max depth - 1) * block size + */ STATIC uint -xfs_calc_rename_reservation(xfs_mount_t *mp) +xfs_calc_rename_reservation( + struct xfs_mount *mp) { - return XFS_CALC_RENAME_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); + return XFS_DQUOT_LOGRES(mp) + + MAX((4 * mp->m_sb.sb_inodesize + + 2 * XFS_DIROP_LOG_RES(mp) + + 128 * (4 + 2 * XFS_DIROP_LOG_COUNT(mp))), + (3 * mp->m_sb.sb_sectsize + + 3 * mp->m_sb.sb_sectsize + + mp->m_sb.sb_sectsize + + XFS_ALLOCFREE_LOG_RES(mp, 3) + + 128 * (7 + XFS_ALLOCFREE_LOG_COUNT(mp, 3)))); } +/* + * For creating a link to an inode: + * the parent directory inode: inode size + * the linked inode: inode size + * the directory btree could split: (max depth + v2) * dir block size + * the directory bmap btree could join or split: (max depth + v2) * blocksize + * And the bmap_finish transaction can free some bmap blocks giving: + * the agf for the ag in which the blocks live: sector size + * the agfl for the ag in which the blocks live: sector size + * the superblock for the free block count: sector size + * the allocation btrees: 2 trees * (2 * max depth - 1) * block size + */ STATIC uint -xfs_calc_link_reservation(xfs_mount_t *mp) +xfs_calc_link_reservation( + struct xfs_mount *mp) { - return XFS_CALC_LINK_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); + return XFS_DQUOT_LOGRES(mp) + + MAX((mp->m_sb.sb_inodesize + + mp->m_sb.sb_inodesize + + XFS_DIROP_LOG_RES(mp) + + 128 * (2 + XFS_DIROP_LOG_COUNT(mp))), + (mp->m_sb.sb_sectsize + + mp->m_sb.sb_sectsize + + mp->m_sb.sb_sectsize + + XFS_ALLOCFREE_LOG_RES(mp, 1) + + 128 * (3 + XFS_ALLOCFREE_LOG_COUNT(mp, 1)))); } +/* + * For removing a directory entry we can modify: + * the parent directory inode: inode size + * the removed inode: inode size + * the directory btree could join: (max depth + v2) * dir block size + * the directory bmap btree could join or split: (max depth + v2) * blocksize + * And the bmap_finish transaction can free the dir and bmap blocks giving: + * the agf for the ag in which the blocks live: 2 * sector size + * the agfl for the ag in which the blocks live: 2 * sector size + * the superblock for the free block count: sector size + * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size + */ STATIC uint -xfs_calc_remove_reservation(xfs_mount_t *mp) +xfs_calc_remove_reservation( + struct xfs_mount *mp) { - return XFS_CALC_REMOVE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); + return XFS_DQUOT_LOGRES(mp) + + MAX((mp->m_sb.sb_inodesize + + mp->m_sb.sb_inodesize + + XFS_DIROP_LOG_RES(mp) + + 128 * (2 + XFS_DIROP_LOG_COUNT(mp))), + (2 * mp->m_sb.sb_sectsize + + 2 * mp->m_sb.sb_sectsize + + mp->m_sb.sb_sectsize + + XFS_ALLOCFREE_LOG_RES(mp, 2) + + 128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2)))); } +/* + * For symlink we can modify: + * the parent directory inode: inode size + * the new inode: inode size + * the inode btree entry: 1 block + * the directory btree: (max depth + v2) * dir block size + * the directory inode's bmap btree: (max depth + v2) * block size + * the blocks for the symlink: 1 kB + * Or in the first xact we allocate some inodes giving: + * the agi and agf of the ag getting the new inodes: 2 * sectorsize + * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize + * the inode btree: max depth * blocksize + * the allocation btrees: 2 trees * (2 * max depth - 1) * block size + */ STATIC uint -xfs_calc_symlink_reservation(xfs_mount_t *mp) +xfs_calc_symlink_reservation( + struct xfs_mount *mp) { - return XFS_CALC_SYMLINK_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); + return XFS_DQUOT_LOGRES(mp) + + MAX((mp->m_sb.sb_inodesize + + mp->m_sb.sb_inodesize + + XFS_FSB_TO_B(mp, 1) + + XFS_DIROP_LOG_RES(mp) + + 1024 + + 128 * (4 + XFS_DIROP_LOG_COUNT(mp))), + (2 * mp->m_sb.sb_sectsize + + XFS_FSB_TO_B(mp, XFS_IALLOC_BLOCKS(mp)) + + XFS_FSB_TO_B(mp, mp->m_in_maxlevels) + + XFS_ALLOCFREE_LOG_RES(mp, 1) + + 128 * (2 + XFS_IALLOC_BLOCKS(mp) + mp->m_in_maxlevels + + XFS_ALLOCFREE_LOG_COUNT(mp, 1)))); } +/* + * For create we can modify: + * the parent directory inode: inode size + * the new inode: inode size + * the inode btree entry: block size + * the superblock for the nlink flag: sector size + * the directory btree: (max depth + v2) * dir block size + * the directory inode's bmap btree: (max depth + v2) * block size + * Or in the first xact we allocate some inodes giving: + * the agi and agf of the ag getting the new inodes: 2 * sectorsize + * the superblock for the nlink flag: sector size + * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize + * the inode btree: max depth * blocksize + * the allocation btrees: 2 trees * (max depth - 1) * block size + */ STATIC uint -xfs_calc_create_reservation(xfs_mount_t *mp) +xfs_calc_create_reservation( + struct xfs_mount *mp) { - return XFS_CALC_CREATE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); + return XFS_DQUOT_LOGRES(mp) + + MAX((mp->m_sb.sb_inodesize + + mp->m_sb.sb_inodesize + + mp->m_sb.sb_sectsize + + XFS_FSB_TO_B(mp, 1) + + XFS_DIROP_LOG_RES(mp) + + 128 * (3 + XFS_DIROP_LOG_COUNT(mp))), + (3 * mp->m_sb.sb_sectsize + + XFS_FSB_TO_B(mp, XFS_IALLOC_BLOCKS(mp)) + + XFS_FSB_TO_B(mp, mp->m_in_maxlevels) + + XFS_ALLOCFREE_LOG_RES(mp, 1) + + 128 * (2 + XFS_IALLOC_BLOCKS(mp) + mp->m_in_maxlevels + + XFS_ALLOCFREE_LOG_COUNT(mp, 1)))); } +/* + * Making a new directory is the same as creating a new file. + */ STATIC uint -xfs_calc_mkdir_reservation(xfs_mount_t *mp) +xfs_calc_mkdir_reservation( + struct xfs_mount *mp) { - return XFS_CALC_MKDIR_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); + return xfs_calc_create_reservation(mp); } +/* + * In freeing an inode we can modify: + * the inode being freed: inode size + * the super block free inode counter: sector size + * the agi hash list and counters: sector size + * the inode btree entry: block size + * the on disk inode before ours in the agi hash list: inode cluster size + * the inode btree: max depth * blocksize + * the allocation btrees: 2 trees * (max depth - 1) * block size + */ STATIC uint -xfs_calc_ifree_reservation(xfs_mount_t *mp) +xfs_calc_ifree_reservation( + struct xfs_mount *mp) { - return XFS_CALC_IFREE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); + return XFS_DQUOT_LOGRES(mp) + + mp->m_sb.sb_inodesize + + mp->m_sb.sb_sectsize + + mp->m_sb.sb_sectsize + + XFS_FSB_TO_B(mp, 1) + + MAX((__uint16_t)XFS_FSB_TO_B(mp, 1), + XFS_INODE_CLUSTER_SIZE(mp)) + + 128 * 5 + + XFS_ALLOCFREE_LOG_RES(mp, 1) + + 128 * (2 + XFS_IALLOC_BLOCKS(mp) + mp->m_in_maxlevels + + XFS_ALLOCFREE_LOG_COUNT(mp, 1)); } +/* + * When only changing the inode we log the inode and possibly the superblock + * We also add a bit of slop for the transaction stuff. + */ STATIC uint -xfs_calc_ichange_reservation(xfs_mount_t *mp) +xfs_calc_ichange_reservation( + struct xfs_mount *mp) { - return XFS_CALC_ICHANGE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); + return XFS_DQUOT_LOGRES(mp) + + mp->m_sb.sb_inodesize + + mp->m_sb.sb_sectsize + + 512; + } +/* + * Growing the data section of the filesystem. + * superblock + * agi and agf + * allocation btrees + */ STATIC uint -xfs_calc_growdata_reservation(xfs_mount_t *mp) +xfs_calc_growdata_reservation( + struct xfs_mount *mp) { - return XFS_CALC_GROWDATA_LOG_RES(mp); + return mp->m_sb.sb_sectsize * 3 + + XFS_ALLOCFREE_LOG_RES(mp, 1) + + 128 * (3 + XFS_ALLOCFREE_LOG_COUNT(mp, 1)); } +/* + * Growing the rt section of the filesystem. + * In the first set of transactions (ALLOC) we allocate space to the + * bitmap or summary files. + * superblock: sector size + * agf of the ag from which the extent is allocated: sector size + * bmap btree for bitmap/summary inode: max depth * blocksize + * bitmap/summary inode: inode size + * allocation btrees for 1 block alloc: 2 * (2 * maxdepth - 1) * blocksize + */ STATIC uint -xfs_calc_growrtalloc_reservation(xfs_mount_t *mp) +xfs_calc_growrtalloc_reservation( + struct xfs_mount *mp) { - return XFS_CALC_GROWRTALLOC_LOG_RES(mp); + return 2 * mp->m_sb.sb_sectsize + + XFS_FSB_TO_B(mp, XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)) + + mp->m_sb.sb_inodesize + + XFS_ALLOCFREE_LOG_RES(mp, 1) + + 128 * (3 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + + XFS_ALLOCFREE_LOG_COUNT(mp, 1)); } +/* + * Growing the rt section of the filesystem. + * In the second set of transactions (ZERO) we zero the new metadata blocks. + * one bitmap/summary block: blocksize + */ STATIC uint -xfs_calc_growrtzero_reservation(xfs_mount_t *mp) +xfs_calc_growrtzero_reservation( + struct xfs_mount *mp) { - return XFS_CALC_GROWRTZERO_LOG_RES(mp); + return mp->m_sb.sb_blocksize + 128; } +/* + * Growing the rt section of the filesystem. + * In the third set of transactions (FREE) we update metadata without + * allocating any new blocks. + * superblock: sector size + * bitmap inode: inode size + * summary inode: inode size + * one bitmap block: blocksize + * summary blocks: new summary size + */ STATIC uint -xfs_calc_growrtfree_reservation(xfs_mount_t *mp) +xfs_calc_growrtfree_reservation( + struct xfs_mount *mp) { - return XFS_CALC_GROWRTFREE_LOG_RES(mp); + return mp->m_sb.sb_sectsize + + 2 * mp->m_sb.sb_inodesize + + mp->m_sb.sb_blocksize + + mp->m_rsumsize + + 128 * 5; } +/* + * Logging the inode modification timestamp on a synchronous write. + * inode + */ STATIC uint -xfs_calc_swrite_reservation(xfs_mount_t *mp) +xfs_calc_swrite_reservation( + struct xfs_mount *mp) { - return XFS_CALC_SWRITE_LOG_RES(mp); + return mp->m_sb.sb_inodesize + 128; } +/* + * Logging the inode mode bits when writing a setuid/setgid file + * inode + */ STATIC uint xfs_calc_writeid_reservation(xfs_mount_t *mp) { - return XFS_CALC_WRITEID_LOG_RES(mp); + return mp->m_sb.sb_inodesize + 128; } +/* + * Converting the inode from non-attributed to attributed. + * the inode being converted: inode size + * agf block and superblock (for block allocation) + * the new block (directory sized) + * bmap blocks for the new directory block + * allocation btrees + */ STATIC uint -xfs_calc_addafork_reservation(xfs_mount_t *mp) +xfs_calc_addafork_reservation( + struct xfs_mount *mp) { - return XFS_CALC_ADDAFORK_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); + return XFS_DQUOT_LOGRES(mp) + + mp->m_sb.sb_inodesize + + mp->m_sb.sb_sectsize * 2 + + mp->m_dirblksize + + XFS_FSB_TO_B(mp, XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1) + + XFS_ALLOCFREE_LOG_RES(mp, 1) + + 128 * (4 + XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1 + + XFS_ALLOCFREE_LOG_COUNT(mp, 1)); } +/* + * Removing the attribute fork of a file + * the inode being truncated: inode size + * the inode's bmap btree: max depth * block size + * And the bmap_finish transaction can free the blocks and bmap blocks: + * the agf for each of the ags: 4 * sector size + * the agfl for each of the ags: 4 * sector size + * the super block to reflect the freed blocks: sector size + * worst case split in allocation btrees per extent assuming 4 extents: + * 4 exts * 2 trees * (2 * max depth - 1) * block size + */ STATIC uint -xfs_calc_attrinval_reservation(xfs_mount_t *mp) +xfs_calc_attrinval_reservation( + struct xfs_mount *mp) { - return XFS_CALC_ATTRINVAL_LOG_RES(mp); + return MAX((mp->m_sb.sb_inodesize + + XFS_FSB_TO_B(mp, XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) + + 128 * (1 + XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK))), + (4 * mp->m_sb.sb_sectsize + + 4 * mp->m_sb.sb_sectsize + + mp->m_sb.sb_sectsize + + XFS_ALLOCFREE_LOG_RES(mp, 4) + + 128 * (9 + XFS_ALLOCFREE_LOG_COUNT(mp, 4)))); } +/* + * Setting an attribute. + * the inode getting the attribute + * the superblock for allocations + * the agfs extents are allocated from + * the attribute btree * max depth + * the inode allocation btree + * Since attribute transaction space is dependent on the size of the attribute, + * the calculation is done partially at mount time and partially at runtime. + */ STATIC uint -xfs_calc_attrset_reservation(xfs_mount_t *mp) +xfs_calc_attrset_reservation( + struct xfs_mount *mp) { - return XFS_CALC_ATTRSET_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); + return XFS_DQUOT_LOGRES(mp) + + mp->m_sb.sb_inodesize + + mp->m_sb.sb_sectsize + + XFS_FSB_TO_B(mp, XFS_DA_NODE_MAXDEPTH) + + 128 * (2 + XFS_DA_NODE_MAXDEPTH); } +/* + * Removing an attribute. + * the inode: inode size + * the attribute btree could join: max depth * block size + * the inode bmap btree could join or split: max depth * block size + * And the bmap_finish transaction can free the attr blocks freed giving: + * the agf for the ag in which the blocks live: 2 * sector size + * the agfl for the ag in which the blocks live: 2 * sector size + * the superblock for the free block count: sector size + * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size + */ STATIC uint -xfs_calc_attrrm_reservation(xfs_mount_t *mp) +xfs_calc_attrrm_reservation( + struct xfs_mount *mp) { - return XFS_CALC_ATTRRM_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp); + return XFS_DQUOT_LOGRES(mp) + + MAX((mp->m_sb.sb_inodesize + + XFS_FSB_TO_B(mp, XFS_DA_NODE_MAXDEPTH) + + XFS_FSB_TO_B(mp, XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) + + 128 * (1 + XFS_DA_NODE_MAXDEPTH + + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK))), + (2 * mp->m_sb.sb_sectsize + + 2 * mp->m_sb.sb_sectsize + + mp->m_sb.sb_sectsize + + XFS_ALLOCFREE_LOG_RES(mp, 2) + + 128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2)))); } +/* + * Clearing a bad agino number in an agi hash bucket. + */ STATIC uint -xfs_calc_clear_agi_bucket_reservation(xfs_mount_t *mp) +xfs_calc_clear_agi_bucket_reservation( + struct xfs_mount *mp) { - return XFS_CALC_CLEAR_AGI_BUCKET_LOG_RES(mp); + return mp->m_sb.sb_sectsize + 128; } /* @@ -184,11 +539,10 @@ xfs_calc_clear_agi_bucket_reservation(xfs_mount_t *mp) */ void xfs_trans_init( - xfs_mount_t *mp) + struct xfs_mount *mp) { - xfs_trans_reservations_t *resp; + struct xfs_trans_reservations *resp = &mp->m_reservations; - resp = &(mp->m_reservations); resp->tr_write = xfs_calc_write_reservation(mp); resp->tr_itruncate = xfs_calc_itruncate_reservation(mp); resp->tr_rename = xfs_calc_rename_reservation(mp); diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 8c69e7824f68..e639e8e9a2a9 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -300,24 +300,6 @@ xfs_lic_desc_to_chunk(xfs_log_item_desc_t *dp) /* - * Various log reservation values. - * These are based on the size of the file system block - * because that is what most transactions manipulate. - * Each adds in an additional 128 bytes per item logged to - * try to account for the overhead of the transaction mechanism. - * - * Note: - * Most of the reservations underestimate the number of allocation - * groups into which they could free extents in the xfs_bmap_finish() - * call. This is because the number in the worst case is quite high - * and quite unusual. In order to fix this we need to change - * xfs_bmap_finish() to free extents in only a single AG at a time. - * This will require changes to the EFI code as well, however, so that - * the EFI for the extents not freed is logged again in each transaction. - * See bug 261917. - */ - -/* * Per-extent log reservation for the allocation btree changes * involved in freeing or allocating an extent. * 2 trees * (2 blocks/level * max depth - 1) * block size @@ -341,429 +323,36 @@ xfs_lic_desc_to_chunk(xfs_log_item_desc_t *dp) (XFS_DAENTER_BLOCKS(mp, XFS_DATA_FORK) + \ XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK) + 1) -/* - * In a write transaction we can allocate a maximum of 2 - * extents. This gives: - * the inode getting the new extents: inode size - * the inode's bmap btree: max depth * block size - * the agfs of the ags from which the extents are allocated: 2 * sector - * the superblock free block counter: sector size - * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size - * And the bmap_finish transaction can free bmap blocks in a join: - * the agfs of the ags containing the blocks: 2 * sector size - * the agfls of the ags containing the blocks: 2 * sector size - * the super block free block counter: sector size - * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size - */ -#define XFS_CALC_WRITE_LOG_RES(mp) \ - (MAX( \ - ((mp)->m_sb.sb_inodesize + \ - XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)) + \ - (2 * (mp)->m_sb.sb_sectsize) + \ - (mp)->m_sb.sb_sectsize + \ - XFS_ALLOCFREE_LOG_RES(mp, 2) + \ - (128 * (4 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + XFS_ALLOCFREE_LOG_COUNT(mp, 2)))),\ - ((2 * (mp)->m_sb.sb_sectsize) + \ - (2 * (mp)->m_sb.sb_sectsize) + \ - (mp)->m_sb.sb_sectsize + \ - XFS_ALLOCFREE_LOG_RES(mp, 2) + \ - (128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2)))))) #define XFS_WRITE_LOG_RES(mp) ((mp)->m_reservations.tr_write) - -/* - * In truncating a file we free up to two extents at once. We can modify: - * the inode being truncated: inode size - * the inode's bmap btree: (max depth + 1) * block size - * And the bmap_finish transaction can free the blocks and bmap blocks: - * the agf for each of the ags: 4 * sector size - * the agfl for each of the ags: 4 * sector size - * the super block to reflect the freed blocks: sector size - * worst case split in allocation btrees per extent assuming 4 extents: - * 4 exts * 2 trees * (2 * max depth - 1) * block size - * the inode btree: max depth * blocksize - * the allocation btrees: 2 trees * (max depth - 1) * block size - */ -#define XFS_CALC_ITRUNCATE_LOG_RES(mp) \ - (MAX( \ - ((mp)->m_sb.sb_inodesize + \ - XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + 1) + \ - (128 * (2 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)))), \ - ((4 * (mp)->m_sb.sb_sectsize) + \ - (4 * (mp)->m_sb.sb_sectsize) + \ - (mp)->m_sb.sb_sectsize + \ - XFS_ALLOCFREE_LOG_RES(mp, 4) + \ - (128 * (9 + XFS_ALLOCFREE_LOG_COUNT(mp, 4))) + \ - (128 * 5) + \ - XFS_ALLOCFREE_LOG_RES(mp, 1) + \ - (128 * (2 + XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels + \ - XFS_ALLOCFREE_LOG_COUNT(mp, 1)))))) - #define XFS_ITRUNCATE_LOG_RES(mp) ((mp)->m_reservations.tr_itruncate) - -/* - * In renaming a files we can modify: - * the four inodes involved: 4 * inode size - * the two directory btrees: 2 * (max depth + v2) * dir block size - * the two directory bmap btrees: 2 * max depth * block size - * And the bmap_finish transaction can free dir and bmap blocks (two sets - * of bmap blocks) giving: - * the agf for the ags in which the blocks live: 3 * sector size - * the agfl for the ags in which the blocks live: 3 * sector size - * the superblock for the free block count: sector size - * the allocation btrees: 3 exts * 2 trees * (2 * max depth - 1) * block size - */ -#define XFS_CALC_RENAME_LOG_RES(mp) \ - (MAX( \ - ((4 * (mp)->m_sb.sb_inodesize) + \ - (2 * XFS_DIROP_LOG_RES(mp)) + \ - (128 * (4 + 2 * XFS_DIROP_LOG_COUNT(mp)))), \ - ((3 * (mp)->m_sb.sb_sectsize) + \ - (3 * (mp)->m_sb.sb_sectsize) + \ - (mp)->m_sb.sb_sectsize + \ - XFS_ALLOCFREE_LOG_RES(mp, 3) + \ - (128 * (7 + XFS_ALLOCFREE_LOG_COUNT(mp, 3)))))) - #define XFS_RENAME_LOG_RES(mp) ((mp)->m_reservations.tr_rename) - -/* - * For creating a link to an inode: - * the parent directory inode: inode size - * the linked inode: inode size - * the directory btree could split: (max depth + v2) * dir block size - * the directory bmap btree could join or split: (max depth + v2) * blocksize - * And the bmap_finish transaction can free some bmap blocks giving: - * the agf for the ag in which the blocks live: sector size - * the agfl for the ag in which the blocks live: sector size - * the superblock for the free block count: sector size - * the allocation btrees: 2 trees * (2 * max depth - 1) * block size - */ -#define XFS_CALC_LINK_LOG_RES(mp) \ - (MAX( \ - ((mp)->m_sb.sb_inodesize + \ - (mp)->m_sb.sb_inodesize + \ - XFS_DIROP_LOG_RES(mp) + \ - (128 * (2 + XFS_DIROP_LOG_COUNT(mp)))), \ - ((mp)->m_sb.sb_sectsize + \ - (mp)->m_sb.sb_sectsize + \ - (mp)->m_sb.sb_sectsize + \ - XFS_ALLOCFREE_LOG_RES(mp, 1) + \ - (128 * (3 + XFS_ALLOCFREE_LOG_COUNT(mp, 1)))))) - #define XFS_LINK_LOG_RES(mp) ((mp)->m_reservations.tr_link) - -/* - * For removing a directory entry we can modify: - * the parent directory inode: inode size - * the removed inode: inode size - * the directory btree could join: (max depth + v2) * dir block size - * the directory bmap btree could join or split: (max depth + v2) * blocksize - * And the bmap_finish transaction can free the dir and bmap blocks giving: - * the agf for the ag in which the blocks live: 2 * sector size - * the agfl for the ag in which the blocks live: 2 * sector size - * the superblock for the free block count: sector size - * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size - */ -#define XFS_CALC_REMOVE_LOG_RES(mp) \ - (MAX( \ - ((mp)->m_sb.sb_inodesize + \ - (mp)->m_sb.sb_inodesize + \ - XFS_DIROP_LOG_RES(mp) + \ - (128 * (2 + XFS_DIROP_LOG_COUNT(mp)))), \ - ((2 * (mp)->m_sb.sb_sectsize) + \ - (2 * (mp)->m_sb.sb_sectsize) + \ - (mp)->m_sb.sb_sectsize + \ - XFS_ALLOCFREE_LOG_RES(mp, 2) + \ - (128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2)))))) - #define XFS_REMOVE_LOG_RES(mp) ((mp)->m_reservations.tr_remove) - -/* - * For symlink we can modify: - * the parent directory inode: inode size - * the new inode: inode size - * the inode btree entry: 1 block - * the directory btree: (max depth + v2) * dir block size - * the directory inode's bmap btree: (max depth + v2) * block size - * the blocks for the symlink: 1 kB - * Or in the first xact we allocate some inodes giving: - * the agi and agf of the ag getting the new inodes: 2 * sectorsize - * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize - * the inode btree: max depth * blocksize - * the allocation btrees: 2 trees * (2 * max depth - 1) * block size - */ -#define XFS_CALC_SYMLINK_LOG_RES(mp) \ - (MAX( \ - ((mp)->m_sb.sb_inodesize + \ - (mp)->m_sb.sb_inodesize + \ - XFS_FSB_TO_B(mp, 1) + \ - XFS_DIROP_LOG_RES(mp) + \ - 1024 + \ - (128 * (4 + XFS_DIROP_LOG_COUNT(mp)))), \ - (2 * (mp)->m_sb.sb_sectsize + \ - XFS_FSB_TO_B((mp), XFS_IALLOC_BLOCKS((mp))) + \ - XFS_FSB_TO_B((mp), (mp)->m_in_maxlevels) + \ - XFS_ALLOCFREE_LOG_RES(mp, 1) + \ - (128 * (2 + XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels + \ - XFS_ALLOCFREE_LOG_COUNT(mp, 1)))))) - #define XFS_SYMLINK_LOG_RES(mp) ((mp)->m_reservations.tr_symlink) - -/* - * For create we can modify: - * the parent directory inode: inode size - * the new inode: inode size - * the inode btree entry: block size - * the superblock for the nlink flag: sector size - * the directory btree: (max depth + v2) * dir block size - * the directory inode's bmap btree: (max depth + v2) * block size - * Or in the first xact we allocate some inodes giving: - * the agi and agf of the ag getting the new inodes: 2 * sectorsize - * the superblock for the nlink flag: sector size - * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize - * the inode btree: max depth * blocksize - * the allocation btrees: 2 trees * (max depth - 1) * block size - */ -#define XFS_CALC_CREATE_LOG_RES(mp) \ - (MAX( \ - ((mp)->m_sb.sb_inodesize + \ - (mp)->m_sb.sb_inodesize + \ - (mp)->m_sb.sb_sectsize + \ - XFS_FSB_TO_B(mp, 1) + \ - XFS_DIROP_LOG_RES(mp) + \ - (128 * (3 + XFS_DIROP_LOG_COUNT(mp)))), \ - (3 * (mp)->m_sb.sb_sectsize + \ - XFS_FSB_TO_B((mp), XFS_IALLOC_BLOCKS((mp))) + \ - XFS_FSB_TO_B((mp), (mp)->m_in_maxlevels) + \ - XFS_ALLOCFREE_LOG_RES(mp, 1) + \ - (128 * (2 + XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels + \ - XFS_ALLOCFREE_LOG_COUNT(mp, 1)))))) - #define XFS_CREATE_LOG_RES(mp) ((mp)->m_reservations.tr_create) - -/* - * Making a new directory is the same as creating a new file. - */ -#define XFS_CALC_MKDIR_LOG_RES(mp) XFS_CALC_CREATE_LOG_RES(mp) - #define XFS_MKDIR_LOG_RES(mp) ((mp)->m_reservations.tr_mkdir) - -/* - * In freeing an inode we can modify: - * the inode being freed: inode size - * the super block free inode counter: sector size - * the agi hash list and counters: sector size - * the inode btree entry: block size - * the on disk inode before ours in the agi hash list: inode cluster size - * the inode btree: max depth * blocksize - * the allocation btrees: 2 trees * (max depth - 1) * block size - */ -#define XFS_CALC_IFREE_LOG_RES(mp) \ - ((mp)->m_sb.sb_inodesize + \ - (mp)->m_sb.sb_sectsize + \ - (mp)->m_sb.sb_sectsize + \ - XFS_FSB_TO_B((mp), 1) + \ - MAX((__uint16_t)XFS_FSB_TO_B((mp), 1), XFS_INODE_CLUSTER_SIZE(mp)) + \ - (128 * 5) + \ - XFS_ALLOCFREE_LOG_RES(mp, 1) + \ - (128 * (2 + XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels + \ - XFS_ALLOCFREE_LOG_COUNT(mp, 1)))) - - #define XFS_IFREE_LOG_RES(mp) ((mp)->m_reservations.tr_ifree) - -/* - * When only changing the inode we log the inode and possibly the superblock - * We also add a bit of slop for the transaction stuff. - */ -#define XFS_CALC_ICHANGE_LOG_RES(mp) ((mp)->m_sb.sb_inodesize + \ - (mp)->m_sb.sb_sectsize + 512) - #define XFS_ICHANGE_LOG_RES(mp) ((mp)->m_reservations.tr_ichange) - -/* - * Growing the data section of the filesystem. - * superblock - * agi and agf - * allocation btrees - */ -#define XFS_CALC_GROWDATA_LOG_RES(mp) \ - ((mp)->m_sb.sb_sectsize * 3 + \ - XFS_ALLOCFREE_LOG_RES(mp, 1) + \ - (128 * (3 + XFS_ALLOCFREE_LOG_COUNT(mp, 1)))) - #define XFS_GROWDATA_LOG_RES(mp) ((mp)->m_reservations.tr_growdata) - -/* - * Growing the rt section of the filesystem. - * In the first set of transactions (ALLOC) we allocate space to the - * bitmap or summary files. - * superblock: sector size - * agf of the ag from which the extent is allocated: sector size - * bmap btree for bitmap/summary inode: max depth * blocksize - * bitmap/summary inode: inode size - * allocation btrees for 1 block alloc: 2 * (2 * maxdepth - 1) * blocksize - */ -#define XFS_CALC_GROWRTALLOC_LOG_RES(mp) \ - (2 * (mp)->m_sb.sb_sectsize + \ - XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)) + \ - (mp)->m_sb.sb_inodesize + \ - XFS_ALLOCFREE_LOG_RES(mp, 1) + \ - (128 * \ - (3 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + \ - XFS_ALLOCFREE_LOG_COUNT(mp, 1)))) - #define XFS_GROWRTALLOC_LOG_RES(mp) ((mp)->m_reservations.tr_growrtalloc) - -/* - * Growing the rt section of the filesystem. - * In the second set of transactions (ZERO) we zero the new metadata blocks. - * one bitmap/summary block: blocksize - */ -#define XFS_CALC_GROWRTZERO_LOG_RES(mp) \ - ((mp)->m_sb.sb_blocksize + 128) - #define XFS_GROWRTZERO_LOG_RES(mp) ((mp)->m_reservations.tr_growrtzero) - -/* - * Growing the rt section of the filesystem. - * In the third set of transactions (FREE) we update metadata without - * allocating any new blocks. - * superblock: sector size - * bitmap inode: inode size - * summary inode: inode size - * one bitmap block: blocksize - * summary blocks: new summary size - */ -#define XFS_CALC_GROWRTFREE_LOG_RES(mp) \ - ((mp)->m_sb.sb_sectsize + \ - 2 * (mp)->m_sb.sb_inodesize + \ - (mp)->m_sb.sb_blocksize + \ - (mp)->m_rsumsize + \ - (128 * 5)) - #define XFS_GROWRTFREE_LOG_RES(mp) ((mp)->m_reservations.tr_growrtfree) - -/* - * Logging the inode modification timestamp on a synchronous write. - * inode - */ -#define XFS_CALC_SWRITE_LOG_RES(mp) \ - ((mp)->m_sb.sb_inodesize + 128) - #define XFS_SWRITE_LOG_RES(mp) ((mp)->m_reservations.tr_swrite) - /* * Logging the inode timestamps on an fsync -- same as SWRITE * as long as SWRITE logs the entire inode core */ #define XFS_FSYNC_TS_LOG_RES(mp) ((mp)->m_reservations.tr_swrite) - -/* - * Logging the inode mode bits when writing a setuid/setgid file - * inode - */ -#define XFS_CALC_WRITEID_LOG_RES(mp) \ - ((mp)->m_sb.sb_inodesize + 128) - #define XFS_WRITEID_LOG_RES(mp) ((mp)->m_reservations.tr_swrite) - -/* - * Converting the inode from non-attributed to attributed. - * the inode being converted: inode size - * agf block and superblock (for block allocation) - * the new block (directory sized) - * bmap blocks for the new directory block - * allocation btrees - */ -#define XFS_CALC_ADDAFORK_LOG_RES(mp) \ - ((mp)->m_sb.sb_inodesize + \ - (mp)->m_sb.sb_sectsize * 2 + \ - (mp)->m_dirblksize + \ - XFS_FSB_TO_B(mp, (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1)) + \ - XFS_ALLOCFREE_LOG_RES(mp, 1) + \ - (128 * (4 + (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1) + \ - XFS_ALLOCFREE_LOG_COUNT(mp, 1)))) - #define XFS_ADDAFORK_LOG_RES(mp) ((mp)->m_reservations.tr_addafork) - -/* - * Removing the attribute fork of a file - * the inode being truncated: inode size - * the inode's bmap btree: max depth * block size - * And the bmap_finish transaction can free the blocks and bmap blocks: - * the agf for each of the ags: 4 * sector size - * the agfl for each of the ags: 4 * sector size - * the super block to reflect the freed blocks: sector size - * worst case split in allocation btrees per extent assuming 4 extents: - * 4 exts * 2 trees * (2 * max depth - 1) * block size - */ -#define XFS_CALC_ATTRINVAL_LOG_RES(mp) \ - (MAX( \ - ((mp)->m_sb.sb_inodesize + \ - XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) + \ - (128 * (1 + XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)))), \ - ((4 * (mp)->m_sb.sb_sectsize) + \ - (4 * (mp)->m_sb.sb_sectsize) + \ - (mp)->m_sb.sb_sectsize + \ - XFS_ALLOCFREE_LOG_RES(mp, 4) + \ - (128 * (9 + XFS_ALLOCFREE_LOG_COUNT(mp, 4)))))) - #define XFS_ATTRINVAL_LOG_RES(mp) ((mp)->m_reservations.tr_attrinval) - -/* - * Setting an attribute. - * the inode getting the attribute - * the superblock for allocations - * the agfs extents are allocated from - * the attribute btree * max depth - * the inode allocation btree - * Since attribute transaction space is dependent on the size of the attribute, - * the calculation is done partially at mount time and partially at runtime. - */ -#define XFS_CALC_ATTRSET_LOG_RES(mp) \ - ((mp)->m_sb.sb_inodesize + \ - (mp)->m_sb.sb_sectsize + \ - XFS_FSB_TO_B((mp), XFS_DA_NODE_MAXDEPTH) + \ - (128 * (2 + XFS_DA_NODE_MAXDEPTH))) - #define XFS_ATTRSET_LOG_RES(mp, ext) \ ((mp)->m_reservations.tr_attrset + \ (ext * (mp)->m_sb.sb_sectsize) + \ (ext * XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK))) + \ (128 * (ext + (ext * XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK))))) - -/* - * Removing an attribute. - * the inode: inode size - * the attribute btree could join: max depth * block size - * the inode bmap btree could join or split: max depth * block size - * And the bmap_finish transaction can free the attr blocks freed giving: - * the agf for the ag in which the blocks live: 2 * sector size - * the agfl for the ag in which the blocks live: 2 * sector size - * the superblock for the free block count: sector size - * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size - */ -#define XFS_CALC_ATTRRM_LOG_RES(mp) \ - (MAX( \ - ((mp)->m_sb.sb_inodesize + \ - XFS_FSB_TO_B((mp), XFS_DA_NODE_MAXDEPTH) + \ - XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) + \ - (128 * (1 + XFS_DA_NODE_MAXDEPTH + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)))), \ - ((2 * (mp)->m_sb.sb_sectsize) + \ - (2 * (mp)->m_sb.sb_sectsize) + \ - (mp)->m_sb.sb_sectsize + \ - XFS_ALLOCFREE_LOG_RES(mp, 2) + \ - (128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2)))))) - #define XFS_ATTRRM_LOG_RES(mp) ((mp)->m_reservations.tr_attrrm) - -/* - * Clearing a bad agino number in an agi hash bucket. - */ -#define XFS_CALC_CLEAR_AGI_BUCKET_LOG_RES(mp) \ - ((mp)->m_sb.sb_sectsize + 128) - #define XFS_CLEAR_AGI_BUCKET_LOG_RES(mp) ((mp)->m_reservations.tr_clearagi) diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 9d376be0ea38..a06bd62504fc 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -267,7 +267,7 @@ xfs_setattr( if (code) { ASSERT(tp == NULL); lock_flags &= ~XFS_ILOCK_EXCL; - ASSERT(lock_flags == XFS_IOLOCK_EXCL); + ASSERT(lock_flags == XFS_IOLOCK_EXCL || !need_iolock); goto error_return; } tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_SIZE); diff --git a/include/asm-generic/atomic.h b/include/asm-generic/atomic.h index 058129e9b04c..e53347fbf1da 100644 --- a/include/asm-generic/atomic.h +++ b/include/asm-generic/atomic.h @@ -57,11 +57,11 @@ static inline int atomic_add_return(int i, atomic_t *v) unsigned long flags; int temp; - local_irq_save(flags); + raw_local_irq_save(flags); /* Don't trace it in a irqsoff handler */ temp = v->counter; temp += i; v->counter = temp; - local_irq_restore(flags); + raw_local_irq_restore(flags); return temp; } @@ -78,11 +78,11 @@ static inline int atomic_sub_return(int i, atomic_t *v) unsigned long flags; int temp; - local_irq_save(flags); + raw_local_irq_save(flags); /* Don't trace it in a irqsoff handler */ temp = v->counter; temp -= i; v->counter = temp; - local_irq_restore(flags); + raw_local_irq_restore(flags); return temp; } @@ -135,9 +135,9 @@ static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr) unsigned long flags; mask = ~mask; - local_irq_save(flags); + raw_local_irq_save(flags); /* Don't trace it in a irqsoff handler */ *addr &= mask; - local_irq_restore(flags); + raw_local_irq_restore(flags); } #define atomic_xchg(ptr, v) (xchg(&(ptr)->counter, (v))) diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index f10db6e5f3b5..522832023a69 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -186,6 +186,9 @@ #define PORT_ALTERA_JTAGUART 91 #define PORT_ALTERA_UART 92 +/* SH-SCI */ +#define PORT_SCIFB 93 + #ifdef __KERNEL__ #include <linux/compiler.h> diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h index f5364a1de68b..baed2122c5a6 100644 --- a/include/linux/serial_sci.h +++ b/include/linux/serial_sci.h @@ -2,9 +2,7 @@ #define __LINUX_SERIAL_SCI_H #include <linux/serial_core.h> -#ifdef CONFIG_SERIAL_SH_SCI_DMA -#include <asm/dmaengine.h> -#endif +#include <linux/sh_dma.h> /* * Generic header for SuperH SCI(F) (used by sh/sh64/h8300 and related parts) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 7cdfb4d52847..bf243fc54959 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -501,7 +501,7 @@ static inline struct sk_buff *alloc_skb_fclone(unsigned int size, return __alloc_skb(size, priority, 1, -1); } -extern int skb_recycle_check(struct sk_buff *skb, int skb_size); +extern bool skb_recycle_check(struct sk_buff *skb, int skb_size); extern struct sk_buff *skb_morph(struct sk_buff *dst, struct sk_buff *src); extern struct sk_buff *skb_clone(struct sk_buff *skb, diff --git a/include/video/mipi_display.h b/include/video/mipi_display.h new file mode 100644 index 000000000000..ddcc8ca7316b --- /dev/null +++ b/include/video/mipi_display.h @@ -0,0 +1,130 @@ +/* + * Defines for Mobile Industry Processor Interface (MIPI(R)) + * Display Working Group standards: DSI, DCS, DBI, DPI + * + * Copyright (C) 2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de> + * Copyright (C) 2006 Nokia Corporation + * Author: Imre Deak <imre.deak@nokia.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 MIPI_DISPLAY_H +#define MIPI_DISPLAY_H + +/* MIPI DSI Processor-to-Peripheral transaction types */ +enum { + MIPI_DSI_V_SYNC_START = 0x01, + MIPI_DSI_V_SYNC_END = 0x11, + MIPI_DSI_H_SYNC_START = 0x21, + MIPI_DSI_H_SYNC_END = 0x31, + + MIPI_DSI_COLOR_MODE_OFF = 0x02, + MIPI_DSI_COLOR_MODE_ON = 0x12, + MIPI_DSI_SHUTDOWN_PERIPHERAL = 0x22, + MIPI_DSI_TURN_ON_PERIPHERAL = 0x32, + + MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM = 0x03, + MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM = 0x13, + MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM = 0x23, + + MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM = 0x04, + MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM = 0x14, + MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM = 0x24, + + MIPI_DSI_DCS_SHORT_WRITE = 0x05, + MIPI_DSI_DCS_SHORT_WRITE_PARAM = 0x15, + + MIPI_DSI_DCS_READ = 0x06, + + MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE = 0x37, + + MIPI_DSI_END_OF_TRANSMISSION = 0x08, + + MIPI_DSI_NULL_PACKET = 0x09, + MIPI_DSI_BLANKING_PACKET = 0x19, + MIPI_DSI_GENERIC_LONG_WRITE = 0x29, + MIPI_DSI_DCS_LONG_WRITE = 0x39, + + MIPI_DSI_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20 = 0x0c, + MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR24 = 0x1c, + MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16 = 0x2c, + + MIPI_DSI_PACKED_PIXEL_STREAM_30 = 0x0d, + MIPI_DSI_PACKED_PIXEL_STREAM_36 = 0x1d, + MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12 = 0x3d, + + MIPI_DSI_PACKED_PIXEL_STREAM_16 = 0x0e, + MIPI_DSI_PACKED_PIXEL_STREAM_18 = 0x1e, + MIPI_DSI_PIXEL_STREAM_3BYTE_18 = 0x2e, + MIPI_DSI_PACKED_PIXEL_STREAM_24 = 0x3e, +}; + +/* MIPI DSI Peripheral-to-Processor transaction types */ +enum { + MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT = 0x02, + MIPI_DSI_RX_END_OF_TRANSMISSION = 0x08, + MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE = 0x11, + MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE = 0x12, + MIPI_DSI_RX_GENERIC_LONG_READ_RESPONSE = 0x1a, + MIPI_DSI_RX_DCS_LONG_READ_RESPONSE = 0x1c, + MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE = 0x21, + MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE = 0x22, +}; + +/* MIPI DCS commands */ +enum { + MIPI_DCS_NOP = 0x00, + MIPI_DCS_SOFT_RESET = 0x01, + MIPI_DCS_GET_DISPLAY_ID = 0x04, + MIPI_DCS_GET_RED_CHANNEL = 0x06, + MIPI_DCS_GET_GREEN_CHANNEL = 0x07, + MIPI_DCS_GET_BLUE_CHANNEL = 0x08, + MIPI_DCS_GET_DISPLAY_STATUS = 0x09, + MIPI_DCS_GET_POWER_MODE = 0x0A, + MIPI_DCS_GET_ADDRESS_MODE = 0x0B, + MIPI_DCS_GET_PIXEL_FORMAT = 0x0C, + MIPI_DCS_GET_DISPLAY_MODE = 0x0D, + MIPI_DCS_GET_SIGNAL_MODE = 0x0E, + MIPI_DCS_GET_DIAGNOSTIC_RESULT = 0x0F, + MIPI_DCS_ENTER_SLEEP_MODE = 0x10, + MIPI_DCS_EXIT_SLEEP_MODE = 0x11, + MIPI_DCS_ENTER_PARTIAL_MODE = 0x12, + MIPI_DCS_ENTER_NORMAL_MODE = 0x13, + MIPI_DCS_EXIT_INVERT_MODE = 0x20, + MIPI_DCS_ENTER_INVERT_MODE = 0x21, + MIPI_DCS_SET_GAMMA_CURVE = 0x26, + MIPI_DCS_SET_DISPLAY_OFF = 0x28, + MIPI_DCS_SET_DISPLAY_ON = 0x29, + MIPI_DCS_SET_COLUMN_ADDRESS = 0x2A, + MIPI_DCS_SET_PAGE_ADDRESS = 0x2B, + MIPI_DCS_WRITE_MEMORY_START = 0x2C, + MIPI_DCS_WRITE_LUT = 0x2D, + MIPI_DCS_READ_MEMORY_START = 0x2E, + MIPI_DCS_SET_PARTIAL_AREA = 0x30, + MIPI_DCS_SET_SCROLL_AREA = 0x33, + MIPI_DCS_SET_TEAR_OFF = 0x34, + MIPI_DCS_SET_TEAR_ON = 0x35, + MIPI_DCS_SET_ADDRESS_MODE = 0x36, + MIPI_DCS_SET_SCROLL_START = 0x37, + MIPI_DCS_EXIT_IDLE_MODE = 0x38, + MIPI_DCS_ENTER_IDLE_MODE = 0x39, + MIPI_DCS_SET_PIXEL_FORMAT = 0x3A, + MIPI_DCS_WRITE_MEMORY_CONTINUE = 0x3C, + MIPI_DCS_READ_MEMORY_CONTINUE = 0x3E, + MIPI_DCS_SET_TEAR_SCANLINE = 0x44, + MIPI_DCS_GET_SCANLINE = 0x45, + MIPI_DCS_READ_DDB_START = 0xA1, + MIPI_DCS_READ_DDB_CONTINUE = 0xA8, +}; + +/* MIPI DCS pixel formats */ +#define MIPI_DCS_PIXEL_FMT_24BIT 7 +#define MIPI_DCS_PIXEL_FMT_18BIT 6 +#define MIPI_DCS_PIXEL_FMT_16BIT 5 +#define MIPI_DCS_PIXEL_FMT_12BIT 3 +#define MIPI_DCS_PIXEL_FMT_8BIT 2 +#define MIPI_DCS_PIXEL_FMT_3BIT 1 + +#endif diff --git a/include/video/sh_mipi_dsi.h b/include/video/sh_mipi_dsi.h new file mode 100644 index 000000000000..18bca08f9f59 --- /dev/null +++ b/include/video/sh_mipi_dsi.h @@ -0,0 +1,35 @@ +/* + * Public SH-mobile MIPI DSI header + * + * Copyright (C) 2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de> + * + * 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 VIDEO_SH_MIPI_DSI_H +#define VIDEO_SH_MIPI_DSI_H + +enum sh_mipi_dsi_data_fmt { + MIPI_RGB888, + MIPI_RGB565, + MIPI_RGB666_LP, + MIPI_RGB666, + MIPI_BGR888, + MIPI_BGR565, + MIPI_BGR666_LP, + MIPI_BGR666, + MIPI_YUYV, + MIPI_UYVY, + MIPI_YUV420_L, + MIPI_YUV420, +}; + +struct sh_mobile_lcdc_chan_cfg; + +struct sh_mipi_dsi_info { + enum sh_mipi_dsi_data_fmt data_format; + struct sh_mobile_lcdc_chan_cfg *lcd_chan; +}; + +#endif diff --git a/include/video/sh_mobile_lcdc.h b/include/video/sh_mobile_lcdc.h index 288205457713..24393449960f 100644 --- a/include/video/sh_mobile_lcdc.h +++ b/include/video/sh_mobile_lcdc.h @@ -3,24 +3,27 @@ #include <linux/fb.h> -enum { RGB8, /* 24bpp, 8:8:8 */ - RGB9, /* 18bpp, 9:9 */ - RGB12A, /* 24bpp, 12:12 */ - RGB12B, /* 12bpp */ - RGB16, /* 16bpp */ - RGB18, /* 18bpp */ - RGB24, /* 24bpp */ - SYS8A, /* 24bpp, 8:8:8 */ - SYS8B, /* 18bpp, 8:8:2 */ - SYS8C, /* 18bpp, 2:8:8 */ - SYS8D, /* 16bpp, 8:8 */ - SYS9, /* 18bpp, 9:9 */ - SYS12, /* 24bpp, 12:12 */ - SYS16A, /* 16bpp */ - SYS16B, /* 18bpp, 16:2 */ - SYS16C, /* 18bpp, 2:16 */ - SYS18, /* 18bpp */ - SYS24 };/* 24bpp */ +enum { + RGB8, /* 24bpp, 8:8:8 */ + RGB9, /* 18bpp, 9:9 */ + RGB12A, /* 24bpp, 12:12 */ + RGB12B, /* 12bpp */ + RGB16, /* 16bpp */ + RGB18, /* 18bpp */ + RGB24, /* 24bpp */ + YUV422, /* 16bpp */ + SYS8A, /* 24bpp, 8:8:8 */ + SYS8B, /* 18bpp, 8:8:2 */ + SYS8C, /* 18bpp, 2:8:8 */ + SYS8D, /* 16bpp, 8:8 */ + SYS9, /* 18bpp, 9:9 */ + SYS12, /* 24bpp, 12:12 */ + SYS16A, /* 16bpp */ + SYS16B, /* 18bpp, 16:2 */ + SYS16C, /* 18bpp, 2:16 */ + SYS18, /* 18bpp */ + SYS24, /* 24bpp */ +}; enum { LCDC_CHAN_DISABLED = 0, LCDC_CHAN_MAINLCD, diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 5108232f93d4..c93fd3faac2d 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -176,7 +176,6 @@ static struct inode *mqueue_get_inode(struct super_block *sb, } return inode; out_inode: - make_bad_inode(inode); iput(inode); return NULL; } diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index e722e9d62221..ab392d55eca1 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -528,7 +528,7 @@ config LOCKDEP bool depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT select STACKTRACE - select FRAME_POINTER if !MIPS && !PPC && !ARM_UNWIND && !S390 + select FRAME_POINTER if !MIPS && !PPC && !ARM_UNWIND && !S390 && !MICROBLAZE select KALLSYMS select KALLSYMS_ALL @@ -958,13 +958,13 @@ config FAULT_INJECTION_STACKTRACE_FILTER depends on FAULT_INJECTION_DEBUG_FS && STACKTRACE_SUPPORT depends on !X86_64 select STACKTRACE - select FRAME_POINTER if !PPC && !S390 + select FRAME_POINTER if !PPC && !S390 && !MICROBLAZE help Provide stacktrace filter for fault-injection capabilities config LATENCYTOP bool "Latency measuring infrastructure" - select FRAME_POINTER if !MIPS && !PPC && !S390 + select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE select KALLSYMS select KALLSYMS_ALL select STACKTRACE diff --git a/net/caif/cfserl.c b/net/caif/cfserl.c index cb4325a3dc83..965c5baace40 100644 --- a/net/caif/cfserl.c +++ b/net/caif/cfserl.c @@ -59,16 +59,18 @@ static int cfserl_receive(struct cflayer *l, struct cfpkt *newpkt) u8 stx = CFSERL_STX; int ret; u16 expectlen = 0; + caif_assert(newpkt != NULL); spin_lock(&layr->sync); if (layr->incomplete_frm != NULL) { - layr->incomplete_frm = cfpkt_append(layr->incomplete_frm, newpkt, expectlen); pkt = layr->incomplete_frm; - if (pkt == NULL) + if (pkt == NULL) { + spin_unlock(&layr->sync); return -ENOMEM; + } } else { pkt = newpkt; } diff --git a/net/core/skbuff.c b/net/core/skbuff.c index f8abf68e3988..4e7ac09c281a 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -482,22 +482,22 @@ EXPORT_SYMBOL(consume_skb); * reference count dropping and cleans up the skbuff as if it * just came from __alloc_skb(). */ -int skb_recycle_check(struct sk_buff *skb, int skb_size) +bool skb_recycle_check(struct sk_buff *skb, int skb_size) { struct skb_shared_info *shinfo; if (irqs_disabled()) - return 0; + return false; if (skb_is_nonlinear(skb) || skb->fclone != SKB_FCLONE_UNAVAILABLE) - return 0; + return false; skb_size = SKB_DATA_ALIGN(skb_size + NET_SKB_PAD); if (skb_end_pointer(skb) - skb->head < skb_size) - return 0; + return false; if (skb_shared(skb) || skb_cloned(skb)) - return 0; + return false; skb_release_head_state(skb); @@ -509,7 +509,7 @@ int skb_recycle_check(struct sk_buff *skb, int skb_size) skb->data = skb->head + NET_SKB_PAD; skb_reset_tail_pointer(skb); - return 1; + return true; } EXPORT_SYMBOL(skb_recycle_check); @@ -2996,7 +2996,11 @@ void skb_tstamp_tx(struct sk_buff *orig_skb, memset(serr, 0, sizeof(*serr)); serr->ee.ee_errno = ENOMSG; serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING; + + bh_lock_sock(sk); err = sock_queue_err_skb(sk, skb); + bh_unlock_sock(sk); + if (err) kfree_skb(skb); } diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 58585748bdac..50678f9a2763 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -634,7 +634,9 @@ void __udp4_lib_err(struct sk_buff *skb, u32 info, struct udp_table *udptable) if (!harderr || sk->sk_state != TCP_ESTABLISHED) goto out; } else { + bh_lock_sock(sk); ip_icmp_error(sk, skb, err, uh->dest, info, (u8 *)(uh+1)); + bh_unlock_sock(sk); } sk->sk_err = err; sk->sk_error_report(sk); diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 294cbe8b0725..252d76199c41 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -814,7 +814,7 @@ struct dst_entry * ip6_route_output(struct net *net, struct sock *sk, { int flags = 0; - if (fl->oif || rt6_need_strict(&fl->fl6_dst)) + if ((sk && sk->sk_bound_dev_if) || rt6_need_strict(&fl->fl6_dst)) flags |= RT6_LOOKUP_F_IFACE; if (!ipv6_addr_any(&fl->fl6_src)) diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 87be58673b55..3048f906c042 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -466,9 +466,11 @@ void __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt, if (sk->sk_state != TCP_ESTABLISHED && !np->recverr) goto out; - if (np->recverr) + if (np->recverr) { + bh_lock_sock(sk); ipv6_icmp_error(sk, skb, err, uh->dest, ntohl(info), (u8 *)(uh+1)); - + bh_unlock_sock(sk); + } sk->sk_err = err; sk->sk_error_report(sk); out: diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 5d218c530a4e..32be11e4c4d9 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -5,7 +5,7 @@ #include <linux/nl80211.h> #include "ieee80211_i.h" -enum ieee80211_chan_mode +static enum ieee80211_chan_mode __ieee80211_get_channel_mode(struct ieee80211_local *local, struct ieee80211_sub_if_data *ignore) { diff --git a/net/phonet/pep.c b/net/phonet/pep.c index 7b048a35ca58..94d72e85a475 100644 --- a/net/phonet/pep.c +++ b/net/phonet/pep.c @@ -1045,12 +1045,12 @@ static void pep_sock_unhash(struct sock *sk) lock_sock(sk); if ((1 << sk->sk_state) & ~(TCPF_CLOSE|TCPF_LISTEN)) { skparent = pn->listener; - sk_del_node_init(sk); release_sock(sk); - sk = skparent; pn = pep_sk(skparent); - lock_sock(sk); + lock_sock(skparent); + sk_del_node_init(sk); + sk = skparent; } /* Unhash a listening sock only when it is closed * and all of its active connected pipes are closed. */ diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c index 10ed0d55f759..f68832798db2 100644 --- a/net/rds/ib_cm.c +++ b/net/rds/ib_cm.c @@ -475,6 +475,7 @@ int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id, err = rds_ib_setup_qp(conn); if (err) { rds_ib_conn_error(conn, "rds_ib_setup_qp failed (%d)\n", err); + mutex_unlock(&conn->c_cm_lock); goto out; } diff --git a/net/rds/iw_cm.c b/net/rds/iw_cm.c index a9d951b4fbae..b5dd6ac39be8 100644 --- a/net/rds/iw_cm.c +++ b/net/rds/iw_cm.c @@ -452,6 +452,7 @@ int rds_iw_cm_handle_connect(struct rdma_cm_id *cm_id, err = rds_iw_setup_qp(conn); if (err) { rds_iw_conn_error(conn, "rds_iw_setup_qp failed (%d)\n", err); + mutex_unlock(&conn->c_cm_lock); goto out; } |