]> Pileus Git - ~andy/linux/commitdiff
Merge branch 'for-3.5/gpio-pinmux' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorOlof Johansson <olof@lixom.net>
Thu, 10 May 2012 06:43:04 +0000 (23:43 -0700)
committerOlof Johansson <olof@lixom.net>
Thu, 10 May 2012 06:43:04 +0000 (23:43 -0700)
By Stephen Warren
via Stephen Warren
* 'for-3.5/gpio-pinmux' of git://git.kernel.org/pub/scm/linux/kernel/git/swarren/linux-tegra:
  pinctrl: tegra: error reporting cleanup
  pinctrl: tegra: debugfs enhancements
  pinctrl: tegra: refactor probe handling
  ARM: dt: tegra20: add pinmux to device tree
  ARM: dt: tegra cardhu: add pinmux to device tree
  ARM: tegra: Remove pre-pinctrl pinmux driver
  ARM: tegra: Switch to new pinctrl driver
  gpio: tegra: Hide tegra_gpio_enable/disable()
  ARM: tegra: seaboard: Don't gpio_request() ISL29018_IRQ
  gpio: tegra: configure pins during irq_set_type
  ARM: tegra: Remove VBUS_GPIO handling from board files
  usb: ehci-tegra: Add vbus_gpio to platform data

283 files changed:
Documentation/DocBook/media/v4l/pixfmt-nv12m.xml
Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml
Documentation/arm/SPEAr/overview.txt
Documentation/devicetree/bindings/arm/spear.txt
Documentation/devicetree/bindings/pinctrl/pinctrl_spear.txt [new file with mode: 0644]
MAINTAINERS
Makefile
arch/arm/boot/dts/spear300-evb.dts [new file with mode: 0644]
arch/arm/boot/dts/spear300.dtsi [new file with mode: 0644]
arch/arm/boot/dts/spear310-evb.dts [new file with mode: 0644]
arch/arm/boot/dts/spear310.dtsi [new file with mode: 0644]
arch/arm/boot/dts/spear320-evb.dts [new file with mode: 0644]
arch/arm/boot/dts/spear320.dtsi [new file with mode: 0644]
arch/arm/boot/dts/spear3xx.dtsi [new file with mode: 0644]
arch/arm/boot/dts/spear600-evb.dts
arch/arm/boot/dts/spear600.dtsi
arch/arm/configs/imx_v4_v5_defconfig
arch/arm/configs/spear3xx_defconfig
arch/arm/configs/spear6xx_defconfig
arch/arm/configs/u8500_defconfig
arch/arm/mach-at91/at91rm9200_devices.c
arch/arm/mach-at91/at91rm9200_time.c
arch/arm/mach-at91/board-rm9200ek.c
arch/arm/mach-at91/board-sam9261ek.c
arch/arm/mach-at91/clock.c
arch/arm/mach-at91/include/mach/at91_pmc.h
arch/arm/mach-at91/setup.c
arch/arm/mach-bcmring/core.c
arch/arm/mach-imx/imx27-dt.c
arch/arm/mach-imx/mm-imx5.c
arch/arm/mach-omap1/mux.c
arch/arm/mach-omap1/timer.c
arch/arm/mach-omap2/board-4430sdp.c
arch/arm/mach-omap2/board-generic.c
arch/arm/mach-omap2/board-omap4panda.c
arch/arm/mach-omap2/omap_hwmod.c
arch/arm/mach-omap2/omap_hwmod_2420_data.c
arch/arm/mach-omap2/omap_hwmod_2430_data.c
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
arch/arm/mach-omap2/omap_hwmod_44xx_data.c
arch/arm/mach-omap2/serial.c
arch/arm/mach-omap2/twl-common.c
arch/arm/mach-omap2/twl-common.h
arch/arm/mach-spear3xx/Kconfig
arch/arm/mach-spear3xx/Makefile
arch/arm/mach-spear3xx/Makefile.boot
arch/arm/mach-spear3xx/clock.c
arch/arm/mach-spear3xx/include/mach/generic.h
arch/arm/mach-spear3xx/include/mach/hardware.h
arch/arm/mach-spear3xx/include/mach/spear.h
arch/arm/mach-spear3xx/spear300.c
arch/arm/mach-spear3xx/spear300_evb.c [deleted file]
arch/arm/mach-spear3xx/spear310.c
arch/arm/mach-spear3xx/spear310_evb.c [deleted file]
arch/arm/mach-spear3xx/spear320.c
arch/arm/mach-spear3xx/spear320_evb.c [deleted file]
arch/arm/mach-spear3xx/spear3xx.c
arch/arm/mach-spear6xx/Makefile.boot
arch/arm/mach-spear6xx/clock.c
arch/arm/mach-spear6xx/spear6xx.c
arch/arm/mach-ux500/Kconfig
arch/arm/mach-ux500/Makefile
arch/arm/mach-ux500/board-mop500-msp.c [new file with mode: 0644]
arch/arm/mach-ux500/board-mop500-msp.h [new file with mode: 0644]
arch/arm/mach-ux500/board-mop500-pins.c
arch/arm/mach-ux500/board-mop500.c
arch/arm/mach-ux500/board-mop500.h
arch/arm/mach-ux500/clock.c
arch/arm/mach-ux500/cpu.c
arch/arm/mach-ux500/devices-db8500.h
arch/arm/mach-ux500/include/mach/msp.h [new file with mode: 0644]
arch/arm/mach-ux500/pins-db8500.h
arch/arm/mach-ux500/pins.c [new file with mode: 0644]
arch/arm/mach-ux500/pins.h [new file with mode: 0644]
arch/arm/mach-ux500/platsmp.c
arch/arm/plat-nomadik/include/plat/gpio-nomadik.h
arch/arm/plat-nomadik/include/plat/pincfg.h
arch/arm/plat-omap/include/plat/omap_hwmod.h
arch/arm/plat-omap/sram.c
arch/arm/plat-spear/Kconfig
arch/arm/plat-spear/Makefile
arch/arm/plat-spear/include/plat/padmux.h [deleted file]
arch/arm/plat-spear/include/plat/pl080.h [new file with mode: 0644]
arch/arm/plat-spear/padmux.c [deleted file]
arch/arm/plat-spear/pl080.c [new file with mode: 0644]
arch/ia64/include/asm/futex.h
arch/ia64/kernel/perfmon.c
arch/m68k/configs/m5275evb_defconfig
arch/m68k/platform/527x/config.c
arch/m68k/platform/68EZ328/Makefile
arch/m68k/platform/68VZ328/Makefile
arch/m68k/platform/68VZ328/bootlogo.h [moved from arch/m68k/platform/68EZ328/bootlogo.h with 99% similarity]
arch/m68k/platform/coldfire/device.c
arch/s390/Kconfig
arch/s390/defconfig
arch/s390/include/asm/facility.h
arch/s390/include/asm/pgalloc.h
arch/s390/include/asm/swab.h
arch/s390/include/asm/tlb.h
arch/s390/kernel/head.S
arch/s390/kernel/irq.c
arch/s390/kernel/perf_cpum_cf.c
arch/s390/mm/maccess.c
arch/s390/mm/pgtable.c
arch/sparc/kernel/leon_smp.c
arch/sparc/kernel/sys_sparc_64.c
arch/tile/kernel/single_step.c
arch/x86/ia32/ia32_aout.c
arch/x86/kvm/pmu.c
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c
arch/x86/lib/insn.c
crypto/sha512_generic.c
drivers/acpi/acpica/hwxface.c
drivers/acpi/osl.c
drivers/acpi/reboot.c
drivers/ata/ata_piix.c
drivers/ata/libata-core.c
drivers/ata/libata-scsi.c
drivers/ata/libata-transport.c
drivers/ata/libata.h
drivers/ata/sata_mv.c
drivers/block/virtio_blk.c
drivers/block/xen-blkback/xenbus.c
drivers/crypto/ixp4xx_crypto.c
drivers/crypto/talitos.c
drivers/dma/Kconfig
drivers/gpio/gpio-nomadik.c
drivers/gpu/drm/drm_bufs.c
drivers/gpu/drm/drm_crtc.c
drivers/gpu/drm/drm_fops.c
drivers/gpu/drm/drm_usb.c
drivers/gpu/drm/exynos/exynos_drm_gem.c
drivers/gpu/drm/gma500/mdfld_dsi_output.h
drivers/gpu/drm/i810/i810_dma.c
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_fb.c
drivers/gpu/drm/i915/intel_lvds.c
drivers/gpu/drm/i915/intel_panel.c
drivers/gpu/drm/nouveau/nouveau_pm.c
drivers/gpu/drm/nouveau/nv50_sor.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/radeon_connectors.c
drivers/gpu/drm/radeon/radeon_irq_kms.c
drivers/gpu/drm/radeon/rv770.c
drivers/gpu/drm/radeon/si.c
drivers/hid/Kconfig
drivers/hid/hid-tivo.c
drivers/hwmon/ads1015.c
drivers/hwmon/fam15h_power.c
drivers/input/misc/Kconfig
drivers/input/misc/twl6040-vibra.c
drivers/leds/leds-atmel-pwm.c
drivers/media/common/tuners/xc5000.c
drivers/media/common/tuners/xc5000.h
drivers/media/dvb/dvb-core/dvb_frontend.c
drivers/media/dvb/frontends/drxk_hard.c
drivers/media/rc/winbond-cir.c
drivers/media/video/Kconfig
drivers/media/video/mt9m032.c
drivers/mfd/Kconfig
drivers/mfd/asic3.c
drivers/mfd/omap-usb-host.c
drivers/mfd/rc5t583.c
drivers/mfd/twl6040-core.c
drivers/mmc/card/block.c
drivers/mmc/card/queue.c
drivers/mmc/core/bus.c
drivers/mmc/core/cd-gpio.c
drivers/mmc/core/core.c
drivers/mmc/host/dw_mmc.c
drivers/mmc/host/omap_hsmmc.c
drivers/mmc/host/sdhci-esdhc-imx.c
drivers/mmc/host/sdhci.c
drivers/pci/pci.c
drivers/pinctrl/Kconfig
drivers/pinctrl/Makefile
drivers/pinctrl/spear/Kconfig [new file with mode: 0644]
drivers/pinctrl/spear/Makefile [new file with mode: 0644]
drivers/pinctrl/spear/pinctrl-spear.c [new file with mode: 0644]
drivers/pinctrl/spear/pinctrl-spear.h [new file with mode: 0644]
drivers/pinctrl/spear/pinctrl-spear300.c [new file with mode: 0644]
drivers/pinctrl/spear/pinctrl-spear310.c [new file with mode: 0644]
drivers/pinctrl/spear/pinctrl-spear320.c [new file with mode: 0644]
drivers/pinctrl/spear/pinctrl-spear3xx.c [new file with mode: 0644]
drivers/pinctrl/spear/pinctrl-spear3xx.h [new file with mode: 0644]
drivers/s390/block/dasd_eckd.c
drivers/s390/char/vmur.c
drivers/tty/amiserial.c
drivers/tty/serial/clps711x.c
drivers/tty/serial/pch_uart.c
drivers/usb/core/hub.c
drivers/usb/core/message.c
drivers/usb/dwc3/core.c
drivers/usb/dwc3/ep0.c
drivers/usb/gadget/at91_udc.c
drivers/usb/gadget/f_fs.c
drivers/usb/gadget/f_rndis.c
drivers/usb/gadget/fsl_udc_core.c
drivers/usb/gadget/g_ffs.c
drivers/usb/gadget/s3c-hsotg.c
drivers/usb/gadget/udc-core.c
drivers/usb/gadget/uvc_queue.c
drivers/usb/host/ehci-fsl.c
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-omap.c
drivers/usb/host/ehci-tegra.c
drivers/usb/host/ohci-at91.c
drivers/usb/misc/usbtest.c
drivers/usb/misc/yurex.c
drivers/usb/musb/musb_core.c
drivers/usb/musb/musb_host.c
drivers/usb/musb/omap2430.c
drivers/usb/serial/cp210x.c
drivers/usb/serial/sierra.c
drivers/uwb/hwa-rc.c
drivers/uwb/neh.c
drivers/vhost/test.c
drivers/virtio/virtio_balloon.c
drivers/xen/gntdev.c
drivers/xen/grant-table.c
drivers/xen/manage.c
drivers/xen/xenbus/xenbus_probe_frontend.c
fs/aio.c
fs/binfmt_aout.c
fs/binfmt_elf.c
fs/binfmt_elf_fdpic.c
fs/binfmt_flat.c
fs/binfmt_som.c
fs/btrfs/ctree.h
fs/cifs/connect.c
fs/ext4/ext4.h
fs/ext4/extents.c
fs/ext4/super.c
fs/fuse/dir.c
fs/fuse/file.c
fs/fuse/inode.c
fs/lockd/clnt4xdr.c
fs/lockd/clntxdr.c
fs/nfsd/nfs3xdr.c
fs/nfsd/nfs4proc.c
fs/nfsd/nfs4state.c
fs/nfsd/nfs4xdr.c
fs/nfsd/vfs.c
fs/ocfs2/alloc.c
fs/ocfs2/refcounttree.c
fs/ocfs2/suballoc.c
include/linux/fuse.h
include/linux/i2c/twl.h
include/linux/kvm_host.h
include/linux/mfd/db5500-prcmu.h
include/linux/mfd/rc5t583.h
include/linux/mfd/twl6040.h
include/linux/mm.h
include/linux/mmc/card.h
include/linux/nfsd/Kbuild
include/linux/usb/otg.h
lib/mpi/mpi-bit.c
mm/memblock.c
mm/memcontrol.c
mm/mmap.c
mm/nommu.c
scripts/checkpatch.pl
scripts/xz_wrap.sh
security/commoncap.c
security/smack/smack_lsm.c
security/smack/smackfs.c
sound/core/vmaster.c
sound/last.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
sound/soc/codecs/Kconfig
sound/soc/codecs/twl6040.c
sound/soc/omap/Kconfig
tools/perf/.gitignore
tools/perf/Makefile
tools/perf/perf-archive.sh
tools/perf/util/session.c
virt/kvm/iommu.c
virt/kvm/kvm_main.c

index 3fd3ce5df270563a7e9e1bfc26fa968498e9b1f4..5274c24d11e0a94ce55a05d166580f5cda50196f 100644 (file)
@@ -1,6 +1,6 @@
     <refentry id="V4L2-PIX-FMT-NV12M">
       <refmeta>
-       <refentrytitle>V4L2_PIX_FMT_NV12M ('NV12M')</refentrytitle>
+       <refentrytitle>V4L2_PIX_FMT_NV12M ('NM12')</refentrytitle>
        &manvol;
       </refmeta>
       <refnamediv>
index 9957863daf18d4a4627a74b52fbfe3bd1141b87e..60308f1eefdfea59a33d83f30d32747c8f5c1aa4 100644 (file)
@@ -1,6 +1,6 @@
     <refentry id="V4L2-PIX-FMT-YUV420M">
       <refmeta>
-       <refentrytitle>V4L2_PIX_FMT_YUV420M ('YU12M')</refentrytitle>
+       <refentrytitle>V4L2_PIX_FMT_YUV420M ('YM12')</refentrytitle>
        &manvol;
       </refmeta>
       <refnamediv>
index 253a35c6f782708868949c3251b776d901f78958..28a9af953b9dfdccb5e2c95bb21917e490d08b9a 100644 (file)
@@ -17,14 +17,14 @@ Introduction
   SPEAr (Platform)
        - SPEAr3XX (3XX SOC series, based on ARM9)
                - SPEAr300 (SOC)
-                       - SPEAr300_EVB (Evaluation Board)
+                       - SPEAr300 Evaluation Board
                - SPEAr310 (SOC)
-                       - SPEAr310_EVB (Evaluation Board)
+                       - SPEAr310 Evaluation Board
                - SPEAr320 (SOC)
-                       - SPEAr320_EVB (Evaluation Board)
+                       - SPEAr320 Evaluation Board
        - SPEAr6XX (6XX SOC series, based on ARM9)
                - SPEAr600 (SOC)
-                       - SPEAr600_EVB (Evaluation Board)
+                       - SPEAr600 Evaluation Board
        - SPEAr13XX (13XX SOC series, based on ARM CORTEXA9)
                - SPEAr1300 (SOC)
 
@@ -51,10 +51,11 @@ Introduction
   Common file for machines of spear3xx family is mach-spear3xx/spear3xx.c and for
   spear6xx is mach-spear6xx/spear6xx.c. mach-spear* also contain soc/machine
   specific files, like spear300.c, spear310.c, spear320.c and spear600.c.
-  mach-spear* also contains board specific files for each machine type.
+  mach-spear* doesn't contains board specific files as they fully support
+  Flattened Device Tree.
 
 
   Document Author
   ---------------
 
-  Viresh Kumar, (c) 2010 ST Microelectronics
+  Viresh Kumar <viresh.kumar@st.com>, (c) 2010-2012 ST Microelectronics
index f8e54f092328a92ba6b9f121ef83781ba2c88fee..aa5f355cc94726e4b497d5dea6792f9fd464d5af 100644 (file)
@@ -6,3 +6,21 @@ Boards with the ST SPEAr600 SoC shall have the following properties:
 Required root node property:
 
 compatible = "st,spear600";
+
+Boards with the ST SPEAr300 SoC shall have the following properties:
+
+Required root node property:
+
+compatible = "st,spear300";
+
+Boards with the ST SPEAr310 SoC shall have the following properties:
+
+Required root node property:
+
+compatible = "st,spear310";
+
+Boards with the ST SPEAr320 SoC shall have the following properties:
+
+Required root node property:
+
+compatible = "st,spear320";
diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl_spear.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl_spear.txt
new file mode 100644 (file)
index 0000000..3664d37
--- /dev/null
@@ -0,0 +1,108 @@
+ST Microelectronics, SPEAr pinmux controller
+
+Required properties:
+- compatible   : "st,spear300-pinmux"
+               : "st,spear310-pinmux"
+               : "st,spear320-pinmux"
+- reg          : Address range of the pinctrl registers
+- st,pinmux-mode: Mandatory for SPEAr300 and SPEAr320 and invalid for others.
+       - Its values for SPEAr300:
+               - NAND_MODE             : <0>
+               - NOR_MODE              : <1>
+               - PHOTO_FRAME_MODE      : <2>
+               - LEND_IP_PHONE_MODE    : <3>
+               - HEND_IP_PHONE_MODE    : <4>
+               - LEND_WIFI_PHONE_MODE  : <5>
+               - HEND_WIFI_PHONE_MODE  : <6>
+               - ATA_PABX_WI2S_MODE    : <7>
+               - ATA_PABX_I2S_MODE     : <8>
+               - CAML_LCDW_MODE        : <9>
+               - CAMU_LCD_MODE         : <10>
+               - CAMU_WLCD_MODE        : <11>
+               - CAML_LCD_MODE         : <12>
+       - Its values for SPEAr320:
+               - AUTO_NET_SMII_MODE    : <0>
+               - AUTO_NET_MII_MODE     : <1>
+               - AUTO_EXP_MODE         : <2>
+               - SMALL_PRINTERS_MODE   : <3>
+               - EXTENDED_MODE         : <4>
+
+Please refer to pinctrl-bindings.txt in this directory for details of the common
+pinctrl bindings used by client devices.
+
+SPEAr's pinmux nodes act as a container for an abitrary number of subnodes. Each
+of these subnodes represents muxing for a pin, a group, or a list of pins or
+groups.
+
+The name of each subnode is not important; all subnodes should be enumerated
+and processed purely based on their content.
+
+Required subnode-properties:
+- st,pins : An array of strings. Each string contains the name of a pin or
+  group.
+- st,function: A string containing the name of the function to mux to the pin or
+  group. See the SPEAr's TRM to determine which are valid for each pin or group.
+
+  Valid values for group and function names can be found from looking at the
+  group and function arrays in driver files:
+  drivers/pinctrl/spear/pinctrl-spear3*0.c
+
+Valid values for group names are:
+For All SPEAr3xx machines:
+       "firda_grp", "i2c0_grp", "ssp_cs_grp", "ssp0_grp", "mii0_grp",
+       "gpio0_pin0_grp", "gpio0_pin1_grp", "gpio0_pin2_grp", "gpio0_pin3_grp",
+       "gpio0_pin4_grp", "gpio0_pin5_grp", "uart0_ext_grp", "uart0_grp",
+       "timer_0_1_grp", timer_0_1_pins, "timer_2_3_grp"
+
+For SPEAr300 machines:
+       "fsmc_2chips_grp", "fsmc_4chips_grp", "clcd_lcdmode_grp",
+       "clcd_pfmode_grp", "tdm_grp", "i2c_clk_grp_grp", "caml_grp", "camu_grp",
+       "dac_grp", "i2s_grp", "sdhci_4bit_grp", "sdhci_8bit_grp",
+       "gpio1_0_to_3_grp", "gpio1_4_to_7_grp"
+
+For SPEAr310 machines:
+       "emi_cs_0_to_5_grp", "uart1_grp", "uart2_grp", "uart3_grp", "uart4_grp",
+       "uart5_grp", "fsmc_grp", "rs485_0_grp", "rs485_1_grp", "tdm_grp"
+
+For SPEAr320 machines:
+       "clcd_grp", "emi_grp", "fsmc_8bit_grp", "fsmc_16bit_grp", "spp_grp",
+       "sdhci_led_grp", "sdhci_cd_12_grp", "sdhci_cd_51_grp", "i2s_grp",
+       "uart1_grp", "uart1_modem_2_to_7_grp", "uart1_modem_31_to_36_grp",
+       "uart1_modem_34_to_45_grp", "uart1_modem_80_to_85_grp", "uart2_grp",
+       "uart3_8_9_grp", "uart3_15_16_grp", "uart3_41_42_grp",
+       "uart3_52_53_grp", "uart3_73_74_grp", "uart3_94_95_grp",
+       "uart3_98_99_grp", "uart4_6_7_grp", "uart4_13_14_grp",
+       "uart4_39_40_grp", "uart4_71_72_grp", "uart4_92_93_grp",
+       "uart4_100_101_grp", "uart5_4_5_grp", "uart5_37_38_grp",
+       "uart5_69_70_grp", "uart5_90_91_grp", "uart6_2_3_grp",
+       "uart6_88_89_grp", "rs485_grp", "touchscreen_grp", "can0_grp",
+       "can1_grp", "pwm0_1_pin_8_9_grp", "pwm0_1_pin_14_15_grp",
+       "pwm0_1_pin_30_31_grp", "pwm0_1_pin_37_38_grp", "pwm0_1_pin_42_43_grp",
+       "pwm0_1_pin_59_60_grp", "pwm0_1_pin_88_89_grp", "pwm2_pin_7_grp",
+       "pwm2_pin_13_grp", "pwm2_pin_29_grp", "pwm2_pin_34_grp",
+       "pwm2_pin_41_grp", "pwm2_pin_58_grp", "pwm2_pin_87_grp",
+       "pwm3_pin_6_grp", "pwm3_pin_12_grp", "pwm3_pin_28_grp",
+       "pwm3_pin_40_grp", "pwm3_pin_57_grp", "pwm3_pin_86_grp",
+       "ssp1_17_20_grp", "ssp1_36_39_grp", "ssp1_48_51_grp", "ssp1_65_68_grp",
+       "ssp1_94_97_grp", "ssp2_13_16_grp", "ssp2_32_35_grp", "ssp2_44_47_grp",
+       "ssp2_61_64_grp", "ssp2_90_93_grp", "mii2_grp", "smii0_1_grp",
+       "rmii0_1_grp", "i2c1_8_9_grp", "i2c1_98_99_grp", "i2c2_0_1_grp",
+       "i2c2_2_3_grp", "i2c2_19_20_grp", "i2c2_75_76_grp", "i2c2_96_97_grp"
+
+Valid values for function names are:
+For All SPEAr3xx machines:
+       "firda", "i2c0", "ssp_cs", "ssp0", "mii0", "gpio0", "uart0_ext",
+       "uart0", "timer_0_1", "timer_2_3"
+
+For SPEAr300 machines:
+       "fsmc", "clcd", "tdm", "i2c1", "cam", "dac", "i2s", "sdhci", "gpio1"
+
+For SPEAr310 machines:
+       "emi", "uart1", "uart2", "uart3", "uart4", "uart5", "fsmc", "rs485_0",
+       "rs485_1", "tdm"
+
+For SPEAr320 machines:
+       "clcd", "emi", "fsmc", "spp", "sdhci", "i2s", "uart1", "uart1_modem",
+       "uart2", "uart3", "uart4", "uart5", "uart6", "rs485", "touchscreen",
+       "can0", "can1", "pwm0_1", "pwm2", "pwm3", "ssp1", "ssp2", "mii2",
+       "mii0_1", "i2c1", "i2c2"
index b0f1073c40b0d8dc226b5d0efaa44167d801262b..99e1ba8bd054acd1478be888e13b0d6ac70e7e85 100644 (file)
@@ -2321,9 +2321,9 @@ S:        Supported
 F:     drivers/acpi/dock.c
 
 DOCUMENTATION
-M:     Randy Dunlap <rdunlap@xenotime.net>
+M:     Rob Landley <rob@landley.net>
 L:     linux-doc@vger.kernel.org
-T:     quilt http://xenotime.net/kernel-doc-patches/current/
+T:     TBD
 S:     Maintained
 F:     Documentation/
 
@@ -5234,6 +5234,14 @@ M:       Linus Walleij <linus.walleij@linaro.org>
 S:     Maintained
 F:     drivers/pinctrl/
 
+PIN CONTROLLER - ST SPEAR
+M:     Viresh Kumar <viresh.kumar@st.com>
+L:     spear-devel@list.st.com
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+W:     http://www.st.com/spear
+S:     Maintained
+F:     driver/pinctrl/spear/
+
 PKTCDVD DRIVER
 M:     Peter Osterlund <petero2@telia.com>
 S:     Maintained
@@ -6330,21 +6338,6 @@ F:       arch/arm/mach-spear*/clock.c
 F:     arch/arm/plat-spear/clock.c
 F:     arch/arm/plat-spear/include/plat/clock.h
 
-SPEAR PAD MULTIPLEXING SUPPORT
-M:     Viresh Kumar <viresh.kumar@st.com>
-L:     spear-devel@list.st.com
-L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-W:     http://www.st.com/spear
-S:     Maintained
-F:     arch/arm/plat-spear/include/plat/padmux.h
-F:     arch/arm/plat-spear/padmux.c
-F:     arch/arm/mach-spear*/spear*xx.c
-F:     arch/arm/mach-spear*/include/mach/generic.h
-F:     arch/arm/mach-spear3xx/spear3*0.c
-F:     arch/arm/mach-spear3xx/spear3*0_evb.c
-F:     arch/arm/mach-spear6xx/spear600.c
-F:     arch/arm/mach-spear6xx/spear600_evb.c
-
 SPI SUBSYSTEM
 M:     Grant Likely <grant.likely@secretlab.ca>
 L:     spi-devel-general@lists.sourceforge.net
index f6578f47e21e663402bfb2e401fbf8394024750a..afc868e6c75dd26dbbf28c3511cbcf29c0471573 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 3
 PATCHLEVEL = 4
 SUBLEVEL = 0
-EXTRAVERSION = -rc3
+EXTRAVERSION = -rc4
 NAME = Saber-toothed Squirrel
 
 # *DOCUMENTATION*
diff --git a/arch/arm/boot/dts/spear300-evb.dts b/arch/arm/boot/dts/spear300-evb.dts
new file mode 100644 (file)
index 0000000..402ca0d
--- /dev/null
@@ -0,0 +1,221 @@
+/*
+ * DTS file for SPEAr300 Evaluation Baord
+ *
+ * Copyright 2012 Viresh Kumar <viresh.kumar@st.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "spear300.dtsi"
+
+/ {
+       model = "ST SPEAr300 Evaluation Board";
+       compatible = "st,spear300-evb", "st,spear300";
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       memory {
+               reg = <0 0x40000000>;
+       };
+
+       ahb {
+               pinmux@99000000 {
+                       st,pinmux-mode = <2>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&state_default>;
+
+                       state_default: pinmux {
+                               i2c0 {
+                                       st,pins = "i2c0_grp";
+                                       st,function = "i2c0";
+                               };
+                               ssp0 {
+                                       st,pins = "ssp0_grp";
+                                       st,function = "ssp0";
+                               };
+                               mii0 {
+                                       st,pins = "mii0_grp";
+                                       st,function = "mii0";
+                               };
+                               uart0 {
+                                       st,pins = "uart0_grp";
+                                       st,function = "uart0";
+                               };
+                               clcd {
+                                       st,pins = "clcd_pfmode_grp";
+                                       st,function = "clcd";
+                               };
+                               sdhci {
+                                       st,pins = "sdhci_4bit_grp";
+                                       st,function = "sdhci";
+                               };
+                               gpio1 {
+                                       st,pins = "gpio1_4_to_7_grp",
+                                               "gpio1_0_to_3_grp";
+                                       st,function = "gpio1";
+                               };
+                       };
+               };
+
+               clcd@60000000 {
+                       status = "okay";
+               };
+
+               dma@fc400000 {
+                       status = "okay";
+               };
+
+               fsmc: flash@94000000 {
+                       status = "okay";
+               };
+
+               gmac: eth@e0800000 {
+                       status = "okay";
+               };
+
+               sdhci@70000000 {
+                       int-gpio = <&gpio1 0 0>;
+                       power-gpio = <&gpio1 2 1>;
+                       status = "okay";
+               };
+
+               smi: flash@fc000000 {
+                       status = "okay";
+               };
+
+               spi0: spi@d0100000 {
+                       status = "okay";
+               };
+
+               ehci@e1800000 {
+                       status = "okay";
+               };
+
+               ohci@e1900000 {
+                       status = "okay";
+               };
+
+               ohci@e2100000 {
+                       status = "okay";
+               };
+
+               apb {
+                       gpio0: gpio@fc980000 {
+                              status = "okay";
+                       };
+
+                       gpio1: gpio@a9000000 {
+                              status = "okay";
+                       };
+
+                       i2c0: i2c@d0180000 {
+                              status = "okay";
+                       };
+
+                       kbd@a0000000 {
+                               linux,keymap = < 0x00010000
+                                                0x00020100
+                                                0x00030200
+                                                0x00040300
+                                                0x00050400
+                                                0x00060500
+                                                0x00070600
+                                                0x00080700
+                                                0x00090800
+                                                0x000a0001
+                                                0x000c0101
+                                                0x000d0201
+                                                0x000e0301
+                                                0x000f0401
+                                                0x00100501
+                                                0x00110601
+                                                0x00120701
+                                                0x00130801
+                                                0x00140002
+                                                0x00150102
+                                                0x00160202
+                                                0x00170302
+                                                0x00180402
+                                                0x00190502
+                                                0x001a0602
+                                                0x001b0702
+                                                0x001c0802
+                                                0x001d0003
+                                                0x001e0103
+                                                0x001f0203
+                                                0x00200303
+                                                0x00210403
+                                                0x00220503
+                                                0x00230603
+                                                0x00240703
+                                                0x00250803
+                                                0x00260004
+                                                0x00270104
+                                                0x00280204
+                                                0x00290304
+                                                0x002a0404
+                                                0x002b0504
+                                                0x002c0604
+                                                0x002d0704
+                                                0x002e0804
+                                                0x002f0005
+                                                0x00300105
+                                                0x00310205
+                                                0x00320305
+                                                0x00330405
+                                                0x00340505
+                                                0x00350605
+                                                0x00360705
+                                                0x00370805
+                                                0x00380006
+                                                0x00390106
+                                                0x003a0206
+                                                0x003b0306
+                                                0x003c0406
+                                                0x003d0506
+                                                0x003e0606
+                                                0x003f0706
+                                                0x00400806
+                                                0x00410007
+                                                0x00420107
+                                                0x00430207
+                                                0x00440307
+                                                0x00450407
+                                                0x00460507
+                                                0x00470607
+                                                0x00480707
+                                                0x00490807
+                                                0x004a0008
+                                                0x004b0108
+                                                0x004c0208
+                                                0x004d0308
+                                                0x004e0408
+                                                0x004f0508
+                                                0x00500608
+                                                0x00510708
+                                                0x00520808 >;
+                              autorepeat;
+                              st,mode = <0>;
+                              status = "okay";
+                       };
+
+                       rtc@fc900000 {
+                              status = "okay";
+                       };
+
+                       serial@d0000000 {
+                              status = "okay";
+                       };
+
+                       wdt@fc880000 {
+                              status = "okay";
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/spear300.dtsi b/arch/arm/boot/dts/spear300.dtsi
new file mode 100644 (file)
index 0000000..01c5e35
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * DTS file for SPEAr300 SoC
+ *
+ * Copyright 2012 Viresh Kumar <viresh.kumar@st.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/include/ "spear3xx.dtsi"
+
+/ {
+       ahb {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "simple-bus";
+               ranges = <0x60000000 0x60000000 0x50000000
+                         0xd0000000 0xd0000000 0x30000000>;
+
+               pinmux@99000000 {
+                       compatible = "st,spear300-pinmux";
+                       reg = <0x99000000 0x1000>;
+               };
+
+               clcd@60000000 {
+                       compatible = "arm,clcd-pl110", "arm,primecell";
+                       reg = <0x60000000 0x1000>;
+                       interrupts = <30>;
+                       status = "disabled";
+               };
+
+               fsmc: flash@94000000 {
+                       compatible = "st,spear600-fsmc-nand";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x94000000 0x1000        /* FSMC Register */
+                              0x80000000 0x0010>;      /* NAND Base */
+                       reg-names = "fsmc_regs", "nand_data";
+                       st,ale-off = <0x20000>;
+                       st,cle-off = <0x10000>;
+                       status = "disabled";
+               };
+
+               sdhci@70000000 {
+                       compatible = "st,sdhci-spear";
+                       reg = <0x70000000 0x100>;
+                       interrupts = <1>;
+                       status = "disabled";
+               };
+
+               apb {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "simple-bus";
+                       ranges = <0xa0000000 0xa0000000 0x10000000
+                                 0xd0000000 0xd0000000 0x30000000>;
+
+                       gpio1: gpio@a9000000 {
+                               #gpio-cells = <2>;
+                               compatible = "arm,pl061", "arm,primecell";
+                               gpio-controller;
+                               reg = <0xa9000000 0x1000>;
+                               status = "disabled";
+                       };
+
+                       kbd@a0000000 {
+                               compatible = "st,spear300-kbd";
+                               reg = <0xa0000000 0x1000>;
+                               status = "disabled";
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/spear310-evb.dts b/arch/arm/boot/dts/spear310-evb.dts
new file mode 100644 (file)
index 0000000..6d95317
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * DTS file for SPEAr310 Evaluation Baord
+ *
+ * Copyright 2012 Viresh Kumar <viresh.kumar@st.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "spear310.dtsi"
+
+/ {
+       model = "ST SPEAr310 Evaluation Board";
+       compatible = "st,spear310-evb", "st,spear310";
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       memory {
+               reg = <0 0x40000000>;
+       };
+
+       ahb {
+               pinmux@b4000000 {
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&state_default>;
+
+                       state_default: pinmux {
+                               gpio0 {
+                                       st,pins = "gpio0_pin0_grp",
+                                               "gpio0_pin1_grp",
+                                               "gpio0_pin2_grp",
+                                               "gpio0_pin3_grp",
+                                               "gpio0_pin4_grp",
+                                               "gpio0_pin5_grp";
+                                       st,function = "gpio0";
+                               };
+                               i2c0 {
+                                       st,pins = "i2c0_grp";
+                                       st,function = "i2c0";
+                               };
+                               mii0 {
+                                       st,pins = "mii0_grp";
+                                       st,function = "mii0";
+                               };
+                               ssp0 {
+                                       st,pins = "ssp0_grp";
+                                       st,function = "ssp0";
+                               };
+                               uart0 {
+                                       st,pins = "uart0_grp";
+                                       st,function = "uart0";
+                               };
+                               emi {
+                                       st,pins = "emi_cs_0_to_5_grp";
+                                       st,function = "emi";
+                               };
+                               fsmc {
+                                       st,pins = "fsmc_grp";
+                                       st,function = "fsmc";
+                               };
+                               uart1 {
+                                       st,pins = "uart1_grp";
+                                       st,function = "uart1";
+                               };
+                               uart2 {
+                                       st,pins = "uart2_grp";
+                                       st,function = "uart2";
+                               };
+                               uart3 {
+                                       st,pins = "uart3_grp";
+                                       st,function = "uart3";
+                               };
+                               uart4 {
+                                       st,pins = "uart4_grp";
+                                       st,function = "uart4";
+                               };
+                               uart5 {
+                                       st,pins = "uart5_grp";
+                                       st,function = "uart5";
+                               };
+                       };
+               };
+
+               dma@fc400000 {
+                       status = "okay";
+               };
+
+               fsmc: flash@44000000 {
+                       status = "okay";
+               };
+
+               gmac: eth@e0800000 {
+                       status = "okay";
+               };
+
+               smi: flash@fc000000 {
+                       status = "okay";
+                       clock-rate=<50000000>;
+
+                       flash@f8000000 {
+                               label = "m25p64";
+                               reg = <0xf8000000 0x800000>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               st,smi-fast-mode;
+                       };
+               };
+
+               spi0: spi@d0100000 {
+                       status = "okay";
+               };
+
+               ehci@e1800000 {
+                       status = "okay";
+               };
+
+               ohci@e1900000 {
+                       status = "okay";
+               };
+
+               ohci@e2100000 {
+                       status = "okay";
+               };
+
+               apb {
+                       gpio0: gpio@fc980000 {
+                              status = "okay";
+                       };
+
+                       i2c0: i2c@d0180000 {
+                              status = "okay";
+                       };
+
+                       rtc@fc900000 {
+                              status = "okay";
+                       };
+
+                       serial@d0000000 {
+                              status = "okay";
+                       };
+
+                       serial@b2000000 {
+                              status = "okay";
+                       };
+
+                       serial@b2080000 {
+                              status = "okay";
+                       };
+
+                       serial@b2100000 {
+                              status = "okay";
+                       };
+
+                       serial@b2180000 {
+                              status = "okay";
+                       };
+
+                       serial@b2200000 {
+                              status = "okay";
+                       };
+
+                       wdt@fc880000 {
+                              status = "okay";
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/spear310.dtsi b/arch/arm/boot/dts/spear310.dtsi
new file mode 100644 (file)
index 0000000..e47081c
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * DTS file for SPEAr310 SoC
+ *
+ * Copyright 2012 Viresh Kumar <viresh.kumar@st.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/include/ "spear3xx.dtsi"
+
+/ {
+       ahb {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "simple-bus";
+               ranges = <0x40000000 0x40000000 0x10000000
+                         0xb0000000 0xb0000000 0x10000000
+                         0xd0000000 0xd0000000 0x30000000>;
+
+               pinmux@b4000000 {
+                       compatible = "st,spear310-pinmux";
+                       reg = <0xb4000000 0x1000>;
+               };
+
+               fsmc: flash@44000000 {
+                       compatible = "st,spear600-fsmc-nand";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x44000000 0x1000        /* FSMC Register */
+                              0x40000000 0x0010>;      /* NAND Base */
+                       reg-names = "fsmc_regs", "nand_data";
+                       st,ale-off = <0x10000>;
+                       st,cle-off = <0x20000>;
+                       status = "disabled";
+               };
+
+               apb {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "simple-bus";
+                       ranges = <0xb0000000 0xb0000000 0x10000000
+                                 0xd0000000 0xd0000000 0x30000000>;
+
+                       serial@b2000000 {
+                               compatible = "arm,pl011", "arm,primecell";
+                               reg = <0xb2000000 0x1000>;
+                               status = "disabled";
+                       };
+
+                       serial@b2080000 {
+                               compatible = "arm,pl011", "arm,primecell";
+                               reg = <0xb2080000 0x1000>;
+                               status = "disabled";
+                       };
+
+                       serial@b2100000 {
+                               compatible = "arm,pl011", "arm,primecell";
+                               reg = <0xb2100000 0x1000>;
+                               status = "disabled";
+                       };
+
+                       serial@b2180000 {
+                               compatible = "arm,pl011", "arm,primecell";
+                               reg = <0xb2180000 0x1000>;
+                               status = "disabled";
+                       };
+
+                       serial@b2200000 {
+                               compatible = "arm,pl011", "arm,primecell";
+                               reg = <0xb2200000 0x1000>;
+                               status = "disabled";
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/spear320-evb.dts b/arch/arm/boot/dts/spear320-evb.dts
new file mode 100644 (file)
index 0000000..0c6463b
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ * DTS file for SPEAr320 Evaluation Baord
+ *
+ * Copyright 2012 Viresh Kumar <viresh.kumar@st.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "spear320.dtsi"
+
+/ {
+       model = "ST SPEAr300 Evaluation Board";
+       compatible = "st,spear300-evb", "st,spear300";
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       memory {
+               reg = <0 0x40000000>;
+       };
+
+       ahb {
+               pinmux@b3000000 {
+                       st,pinmux-mode = <3>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&state_default>;
+
+                       state_default: pinmux {
+                               i2c0 {
+                                       st,pins = "i2c0_grp";
+                                       st,function = "i2c0";
+                               };
+                               mii0 {
+                                       st,pins = "mii0_grp";
+                                       st,function = "mii0";
+                               };
+                               ssp0 {
+                                       st,pins = "ssp0_grp";
+                                       st,function = "ssp0";
+                               };
+                               uart0 {
+                                       st,pins = "uart0_grp";
+                                       st,function = "uart0";
+                               };
+                               sdhci {
+                                       st,pins = "sdhci_cd_51_grp";
+                                       st,function = "sdhci";
+                               };
+                               i2s {
+                                       st,pins = "i2s_grp";
+                                       st,function = "i2s";
+                               };
+                               uart1 {
+                                       st,pins = "uart1_grp";
+                                       st,function = "uart1";
+                               };
+                               uart2 {
+                                       st,pins = "uart2_grp";
+                                       st,function = "uart2";
+                               };
+                               can0 {
+                                       st,pins = "can0_grp";
+                                       st,function = "can0";
+                               };
+                               can1 {
+                                       st,pins = "can1_grp";
+                                       st,function = "can1";
+                               };
+                               mii2 {
+                                       st,pins = "mii2_grp";
+                                       st,function = "mii2";
+                               };
+                               pwm0_1 {
+                                       st,pins = "pwm0_1_pin_14_15_grp";
+                                       st,function = "pwm0_1";
+                               };
+                               pwm2 {
+                                       st,pins = "pwm2_pin_13_grp";
+                                       st,function = "pwm2";
+                               };
+                       };
+               };
+
+               clcd@90000000 {
+                       status = "okay";
+               };
+
+               dma@fc400000 {
+                       status = "okay";
+               };
+
+               fsmc: flash@4c000000 {
+                       status = "okay";
+               };
+
+               gmac: eth@e0800000 {
+                       status = "okay";
+               };
+
+               sdhci@70000000 {
+                       power-gpio = <&gpio0 2 1>;
+                       power_always_enb;
+                       status = "okay";
+               };
+
+               smi: flash@fc000000 {
+                       status = "okay";
+               };
+
+               spi0: spi@d0100000 {
+                       status = "okay";
+               };
+
+               spi1: spi@a5000000 {
+                       status = "okay";
+               };
+
+               spi2: spi@a6000000 {
+                       status = "okay";
+               };
+
+               ehci@e1800000 {
+                       status = "okay";
+               };
+
+               ohci@e1900000 {
+                       status = "okay";
+               };
+
+               ohci@e2100000 {
+                       status = "okay";
+               };
+
+               apb {
+                       gpio0: gpio@fc980000 {
+                              status = "okay";
+                       };
+
+                       i2c0: i2c@d0180000 {
+                              status = "okay";
+                       };
+
+                       i2c1: i2c@a7000000 {
+                              status = "okay";
+                       };
+
+                       rtc@fc900000 {
+                              status = "okay";
+                       };
+
+                       serial@d0000000 {
+                              status = "okay";
+                       };
+
+                       serial@a3000000 {
+                              status = "okay";
+                       };
+
+                       serial@a4000000 {
+                              status = "okay";
+                       };
+
+                       wdt@fc880000 {
+                              status = "okay";
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/spear320.dtsi b/arch/arm/boot/dts/spear320.dtsi
new file mode 100644 (file)
index 0000000..5372ca3
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * DTS file for SPEAr320 SoC
+ *
+ * Copyright 2012 Viresh Kumar <viresh.kumar@st.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/include/ "spear3xx.dtsi"
+
+/ {
+       ahb {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "simple-bus";
+               ranges = <0x40000000 0x40000000 0x80000000
+                         0xd0000000 0xd0000000 0x30000000>;
+
+               pinmux@b3000000 {
+                       compatible = "st,spear320-pinmux";
+                       reg = <0xb3000000 0x1000>;
+               };
+
+               clcd@90000000 {
+                       compatible = "arm,clcd-pl110", "arm,primecell";
+                       reg = <0x90000000 0x1000>;
+                       interrupts = <33>;
+                       status = "disabled";
+               };
+
+               fsmc: flash@4c000000 {
+                       compatible = "st,spear600-fsmc-nand";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x4c000000 0x1000        /* FSMC Register */
+                              0x50000000 0x0010>;      /* NAND Base */
+                       reg-names = "fsmc_regs", "nand_data";
+                       st,ale-off = <0x20000>;
+                       st,cle-off = <0x10000>;
+                       status = "disabled";
+               };
+
+               sdhci@70000000 {
+                       compatible = "st,sdhci-spear";
+                       reg = <0x70000000 0x100>;
+                       interrupts = <29>;
+                       status = "disabled";
+               };
+
+               spi1: spi@a5000000 {
+                       compatible = "arm,pl022", "arm,primecell";
+                       reg = <0xa5000000 0x1000>;
+                       status = "disabled";
+               };
+
+               spi2: spi@a6000000 {
+                       compatible = "arm,pl022", "arm,primecell";
+                       reg = <0xa6000000 0x1000>;
+                       status = "disabled";
+               };
+
+               apb {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "simple-bus";
+                       ranges = <0xa0000000 0xa0000000 0x10000000
+                                 0xd0000000 0xd0000000 0x30000000>;
+
+                       i2c1: i2c@a7000000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "snps,designware-i2c";
+                               reg = <0xa7000000 0x1000>;
+                               status = "disabled";
+                       };
+
+                       serial@a3000000 {
+                               compatible = "arm,pl011", "arm,primecell";
+                               reg = <0xa3000000 0x1000>;
+                               status = "disabled";
+                       };
+
+                       serial@a4000000 {
+                               compatible = "arm,pl011", "arm,primecell";
+                               reg = <0xa4000000 0x1000>;
+                               status = "disabled";
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/spear3xx.dtsi b/arch/arm/boot/dts/spear3xx.dtsi
new file mode 100644 (file)
index 0000000..0ae7c8e
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * DTS file for all SPEAr3xx SoCs
+ *
+ * Copyright 2012 Viresh Kumar <viresh.kumar@st.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+       interrupt-parent = <&vic>;
+
+       cpus {
+               cpu@0 {
+                       compatible = "arm,arm926ejs";
+               };
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0 0x40000000>;
+       };
+
+       ahb {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "simple-bus";
+               ranges = <0xd0000000 0xd0000000 0x30000000>;
+
+               vic: interrupt-controller@f1100000 {
+                       compatible = "arm,pl190-vic";
+                       interrupt-controller;
+                       reg = <0xf1100000 0x1000>;
+                       #interrupt-cells = <1>;
+               };
+
+               dma@fc400000 {
+                       compatible = "arm,pl080", "arm,primecell";
+                       reg = <0xfc400000 0x1000>;
+                       interrupt-parent = <&vic>;
+                       interrupts = <8>;
+                       status = "disabled";
+               };
+
+               gmac: eth@e0800000 {
+                       compatible = "st,spear600-gmac";
+                       reg = <0xe0800000 0x8000>;
+                       interrupts = <23 22>;
+                       interrupt-names = "macirq", "eth_wake_irq";
+                       status = "disabled";
+               };
+
+               smi: flash@fc000000 {
+                       compatible = "st,spear600-smi";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0xfc000000 0x1000>;
+                       interrupts = <9>;
+                       status = "disabled";
+               };
+
+               spi0: spi@d0100000 {
+                       compatible = "arm,pl022", "arm,primecell";
+                       reg = <0xd0100000 0x1000>;
+                       interrupts = <20>;
+                       status = "disabled";
+               };
+
+               ehci@e1800000 {
+                       compatible = "st,spear600-ehci", "usb-ehci";
+                       reg = <0xe1800000 0x1000>;
+                       interrupts = <26>;
+                       status = "disabled";
+               };
+
+               ohci@e1900000 {
+                       compatible = "st,spear600-ohci", "usb-ohci";
+                       reg = <0xe1900000 0x1000>;
+                       interrupts = <25>;
+                       status = "disabled";
+               };
+
+               ohci@e2100000 {
+                       compatible = "st,spear600-ohci", "usb-ohci";
+                       reg = <0xe2100000 0x1000>;
+                       interrupts = <27>;
+                       status = "disabled";
+               };
+
+               apb {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "simple-bus";
+                       ranges = <0xd0000000 0xd0000000 0x30000000>;
+
+                       gpio0: gpio@fc980000 {
+                               compatible = "arm,pl061", "arm,primecell";
+                               reg = <0xfc980000 0x1000>;
+                               interrupts = <11>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                               status = "disabled";
+                       };
+
+                       i2c0: i2c@d0180000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "snps,designware-i2c";
+                               reg = <0xd0180000 0x1000>;
+                               interrupts = <21>;
+                               status = "disabled";
+                       };
+
+                       rtc@fc900000 {
+                               compatible = "st,spear-rtc";
+                               reg = <0xfc900000 0x1000>;
+                               interrupts = <10>;
+                               status = "disabled";
+                       };
+
+                       serial@d0000000 {
+                               compatible = "arm,pl011", "arm,primecell";
+                               reg = <0xd0000000 0x1000>;
+                               interrupts = <19>;
+                               status = "disabled";
+                       };
+
+                       wdt@fc880000 {
+                               compatible = "arm,sp805", "arm,primecell";
+                               reg = <0xfc880000 0x1000>;
+                               interrupts = <12>;
+                               status = "disabled";
+                       };
+               };
+       };
+};
index 636292e18c90c253c2b6022115dafc3a4ec475d2..790a7a8a5ccd05f2e622d2256090bb3956718e7d 100644 (file)
        };
 
        ahb {
+               dma@fc400000 {
+                       status = "okay";
+               };
+
                gmac: ethernet@e0800000 {
                        phy-mode = "gmii";
                        status = "okay";
index ebe0885a2b98635635517017f2d90705f69977dc..d777e3a6f178dee9bfba070d1850e47f4da2c507 100644 (file)
                        #interrupt-cells = <1>;
                };
 
+               dma@fc400000 {
+                       compatible = "arm,pl080", "arm,primecell";
+                       reg = <0xfc400000 0x1000>;
+                       interrupt-parent = <&vic1>;
+                       interrupts = <10>;
+                       status = "disabled";
+               };
+
                gmac: ethernet@e0800000 {
                        compatible = "st,spear600-gmac";
                        reg = <0xe0800000 0x8000>;
index b5ac644e12af9121985b0eadeecfdefaaf85c33b..6b31cb60daabd516579d55f1cb2b5a7198cb3776 100644 (file)
@@ -112,6 +112,7 @@ CONFIG_WATCHDOG=y
 CONFIG_IMX2_WDT=y
 CONFIG_MFD_MC13XXX=y
 CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_MC13783=y
 CONFIG_REGULATOR_MC13892=y
 CONFIG_FB=y
index fea7e1f026a367e88a70a2350deff4e83e4f517e..7ed42912d69ae5f764dbf41a2da875bb18d656d9 100644 (file)
@@ -2,33 +2,67 @@ CONFIG_EXPERIMENTAL=y
 CONFIG_SYSVIPC=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_KALLSYMS_EXTRA_PASS=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODVERSIONS=y
+CONFIG_PARTITION_ADVANCED=y
 CONFIG_PLAT_SPEAR=y
-CONFIG_BOARD_SPEAR300_EVB=y
-CONFIG_BOARD_SPEAR310_EVB=y
-CONFIG_BOARD_SPEAR320_EVB=y
+CONFIG_MACH_SPEAR300=y
+CONFIG_MACH_SPEAR310=y
+CONFIG_MACH_SPEAR320=y
 CONFIG_BINFMT_MISC=y
+CONFIG_NET=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_FSMC=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+CONFIG_STMMAC_ETH=y
+# CONFIG_WLAN is not set
 CONFIG_INPUT_FF_MEMLESS=y
 # CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_SPEAR=y
 # CONFIG_INPUT_MOUSE is not set
+# CONFIG_LEGACY_PTYS is not set
 CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
 # CONFIG_HW_RANDOM is not set
 CONFIG_RAW_DRIVER=y
 CONFIG_MAX_RAW_DEVS=8192
+CONFIG_I2C=y
+CONFIG_I2C_DESIGNWARE_PLATFORM=y
+CONFIG_SPI=y
+CONFIG_SPI_PL022=y
 CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_PL061=y
 # CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_ARM_SP805_WATCHDOG=y
+CONFIG_FB=y
+CONFIG_FB_ARMCLCD=y
 # CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
+CONFIG_USB=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_SPEAR=y
+CONFIG_RTC_CLASS=y
+CONFIG_DMADEVICES=y
+CONFIG_AMBA_PL08X=y
+CONFIG_DMATEST=m
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_SECURITY=y
@@ -39,8 +73,6 @@ CONFIG_MSDOS_FS=m
 CONFIG_VFAT_FS=m
 CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
 CONFIG_TMPFS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="utf8"
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ASCII=m
@@ -48,6 +80,4 @@ CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
 CONFIG_DEBUG_INFO=y
-# CONFIG_CRC32 is not set
index cef2e836afd25cb2bf048b7d5d0c135ff09568fd..cf94bc73a0e09318bed41dc0f13bed63c60fdc5e 100644 (file)
@@ -2,29 +2,58 @@ CONFIG_EXPERIMENTAL=y
 CONFIG_SYSVIPC=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_KALLSYMS_EXTRA_PASS=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODVERSIONS=y
+CONFIG_PARTITION_ADVANCED=y
 CONFIG_PLAT_SPEAR=y
 CONFIG_ARCH_SPEAR6XX=y
-CONFIG_BOARD_SPEAR600_EVB=y
+CONFIG_BOARD_SPEAR600_DT=y
 CONFIG_BINFMT_MISC=y
+CONFIG_NET=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_FSMC=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+CONFIG_STMMAC_ETH=y
+# CONFIG_WLAN is not set
 CONFIG_INPUT_FF_MEMLESS=y
 # CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_LEGACY_PTYS is not set
 CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
 CONFIG_RAW_DRIVER=y
 CONFIG_MAX_RAW_DEVS=8192
+CONFIG_I2C=y
+CONFIG_I2C_DESIGNWARE_PLATFORM=y
+CONFIG_SPI=y
+CONFIG_SPI_PL022=y
 CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_PL061=y
 # CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_ARM_SP805_WATCHDOG=y
 # CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_RTC_CLASS=y
+CONFIG_DMADEVICES=y
+CONFIG_AMBA_PL08X=y
+CONFIG_DMATEST=m
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_SECURITY=y
@@ -35,8 +64,6 @@ CONFIG_MSDOS_FS=m
 CONFIG_VFAT_FS=m
 CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
 CONFIG_TMPFS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="utf8"
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ASCII=m
@@ -44,6 +71,4 @@ CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
 CONFIG_DEBUG_INFO=y
-# CONFIG_CRC32 is not set
index 889d73ac1ae11e6870a7a345fb402b8e54ce8070..7e84f453e8a6f07e76c182badb2ee055eda1bde6 100644 (file)
@@ -8,8 +8,6 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_LBDAF is not set
 # CONFIG_BLK_DEV_BSG is not set
 CONFIG_ARCH_U8500=y
-CONFIG_UX500_SOC_DB5500=y
-CONFIG_UX500_SOC_DB8500=y
 CONFIG_MACH_HREFV60=y
 CONFIG_MACH_SNOWBALL=y
 CONFIG_MACH_U5500=y
@@ -39,7 +37,6 @@ CONFIG_CAIF=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=65536
-CONFIG_MISC_DEVICES=y
 CONFIG_AB8500_PWM=y
 CONFIG_SENSORS_BH1780=y
 CONFIG_NETDEVICES=y
@@ -65,16 +62,18 @@ CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
 CONFIG_HW_RANDOM=y
 CONFIG_HW_RANDOM_NOMADIK=y
-CONFIG_I2C=y
-CONFIG_I2C_NOMADIK=y
 CONFIG_SPI=y
 CONFIG_SPI_PL022=y
 CONFIG_GPIO_STMPE=y
 CONFIG_GPIO_TC3589X=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_AB8500_BM=y
+CONFIG_AB8500_BATTERY_THERM_ON_BATCTRL=y
 CONFIG_MFD_STMPE=y
 CONFIG_MFD_TC3589X=y
 CONFIG_AB5500_CORE=y
 CONFIG_AB8500_CORE=y
+CONFIG_REGULATOR=y
 CONFIG_REGULATOR_AB8500=y
 # CONFIG_HID_SUPPORT is not set
 CONFIG_USB_GADGET=y
index 99ce5c955e39d94d24f50005b875459739ef6ce5..05774e5b1cbaf32488a142b4060a1adc452c8177 100644 (file)
@@ -1173,7 +1173,6 @@ void __init at91_add_device_serial(void)
                printk(KERN_INFO "AT91: No default serial console defined.\n");
 }
 #else
-void __init __deprecated at91_init_serial(struct at91_uart_config *config) {}
 void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
 void __init at91_set_serial_console(unsigned portnr) {}
 void __init at91_add_device_serial(void) {}
index dd7f782b0b91731202c3d8e10f02597b7d89518c..104ca40d8d18908cb463e7ae1cd56790c926d971 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/clockchips.h>
+#include <linux/export.h>
 
 #include <asm/mach/time.h>
 
@@ -176,6 +177,7 @@ static struct clock_event_device clkevt = {
 };
 
 void __iomem *at91_st_base;
+EXPORT_SYMBOL_GPL(at91_st_base);
 
 void __init at91rm9200_ioremap_st(u32 addr)
 {
index 11cbaa8946fe0e269877104aac08da9fe03818e9..b2e4fe21f346cf6217dfb78b5e8b3f6553e76fe6 100644 (file)
@@ -117,7 +117,7 @@ static struct i2c_board_info __initdata ek_i2c_devices[] = {
 };
 
 #define EK_FLASH_BASE  AT91_CHIPSELECT_0
-#define EK_FLASH_SIZE  SZ_2M
+#define EK_FLASH_SIZE  SZ_8M
 
 static struct physmap_flash_data ek_flash_data = {
        .width          = 2,
index c3f9944628642050c34c0a5f31388854511921e4..065fed342424902bbe15aa67101fd524397eaa7b 100644 (file)
@@ -85,8 +85,6 @@ static struct resource dm9000_resource[] = {
                .flags  = IORESOURCE_MEM
        },
        [2] = {
-               .start  = AT91_PIN_PC11,
-               .end    = AT91_PIN_PC11,
                .flags  = IORESOURCE_IRQ
                        | IORESOURCE_IRQ_LOWEDGE | IORESOURCE_IRQ_HIGHEDGE,
        }
@@ -130,6 +128,8 @@ static struct sam9_smc_config __initdata dm9000_smc_config = {
 
 static void __init ek_add_device_dm9000(void)
 {
+       struct resource *r = &dm9000_resource[2];
+
        /* Configure chip-select 2 (DM9000) */
        sam9_smc_configure(0, 2, &dm9000_smc_config);
 
@@ -139,6 +139,7 @@ static void __init ek_add_device_dm9000(void)
        /* Configure Interrupt pin as input, no pull-up */
        at91_set_gpio_input(AT91_PIN_PC11, 0);
 
+       r->start = r->end = gpio_to_irq(AT91_PIN_PC11);
        platform_device_register(&dm9000_device);
 }
 #else
index a0f4d7424cdcf4cfbebbc0c81185fb615862e9b5..6b692824c9885555fffe031ead3bafcdf71d141d 100644 (file)
@@ -35,6 +35,7 @@
 #include "generic.h"
 
 void __iomem *at91_pmc_base;
+EXPORT_SYMBOL_GPL(at91_pmc_base);
 
 /*
  * There's a lot more which can be done with clocks, including cpufreq
index 36604782a78f0e52d4bed0d6af21c787dacf418f..ea2c57a86ca6ebf389aaa406bffeb5441e65a067 100644 (file)
@@ -25,7 +25,7 @@ extern void __iomem *at91_pmc_base;
 #define at91_pmc_write(field, value) \
        __raw_writel(value, at91_pmc_base + field)
 #else
-.extern at91_aic_base
+.extern at91_pmc_base
 #endif
 
 #define        AT91_PMC_SCER           0x00                    /* System Clock Enable Register */
index 97cc04dc807302d635e9fe56176d34e0d9210c4f..f44a2e7272e33f8e8568c4bc597db0bc0b38f5b5 100644 (file)
@@ -54,6 +54,7 @@ void __init at91_init_interrupts(unsigned int *priority)
 }
 
 void __iomem *at91_ramc_base[2];
+EXPORT_SYMBOL_GPL(at91_ramc_base);
 
 void __init at91_ioremap_ramc(int id, u32 addr, u32 size)
 {
@@ -292,6 +293,7 @@ void __init at91_ioremap_rstc(u32 base_addr)
 }
 
 void __iomem *at91_matrix_base;
+EXPORT_SYMBOL_GPL(at91_matrix_base);
 
 void __init at91_ioremap_matrix(u32 base_addr)
 {
index 22e4e0a28ad1eae0e549f43e47e548b9a36945dd..adbfb1994582ee1352a511501279f5b58c378bfc 100644 (file)
@@ -52,8 +52,8 @@
 #include <mach/csp/chipcHw_inline.h>
 #include <mach/csp/tmrHw_reg.h>
 
-static AMBA_APB_DEVICE(uartA, "uarta", MM_ADDR_IO_UARTA, { IRQ_UARTA }, NULL);
-static AMBA_APB_DEVICE(uartB, "uartb", MM_ADDR_IO_UARTB, { IRQ_UARTB }, NULL);
+static AMBA_APB_DEVICE(uartA, "uartA", 0, MM_ADDR_IO_UARTA, {IRQ_UARTA}, NULL);
+static AMBA_APB_DEVICE(uartB, "uartB", 0, MM_ADDR_IO_UARTB, {IRQ_UARTB}, NULL);
 
 static struct clk pll1_clk = {
        .name = "PLL1",
index 861ceb8232d60ca468cb361a749e34574bdb7961..ed38d03c61f22296acb782e7e4cc9c8dfde20344 100644 (file)
@@ -35,7 +35,7 @@ static const struct of_dev_auxdata imx27_auxdata_lookup[] __initconst = {
 static int __init imx27_avic_add_irq_domain(struct device_node *np,
                                struct device_node *interrupt_parent)
 {
-       irq_domain_add_simple(np, 0);
+       irq_domain_add_legacy(np, 64, 0, 0, &irq_domain_simple_ops, NULL);
        return 0;
 }
 
@@ -44,7 +44,9 @@ static int __init imx27_gpio_add_irq_domain(struct device_node *np,
 {
        static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS;
 
-       irq_domain_add_simple(np, gpio_irq_base);
+       gpio_irq_base -= 32;
+       irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops,
+                               NULL);
 
        return 0;
 }
index 05250aed61fbbc7f73f9e7b1c5b4bca00000f6fd..e10f3914fcfe6b1d2c59f9296d373805b4740901 100644 (file)
@@ -35,7 +35,7 @@ static void imx5_idle(void)
        }
        clk_enable(gpc_dvfs_clk);
        mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
-       if (tzic_enable_wake() != 0)
+       if (!tzic_enable_wake())
                cpu_do_idle();
        clk_disable(gpc_dvfs_clk);
 }
index 087dba0df47e305fd059b97885c68f696d4c8ea5..e9cc52d4cb2869964b933b8a4a74ee844bb003d8 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/io.h>
 #include <linux/spinlock.h>
 
+#include <mach/hardware.h>
 
 #include <plat/mux.h>
 
index 6e90665a7c47f6d4ed929b57dd6a79d9c7ed4f2a..fb202af01d0dc2fbb1f9622d220b90335e939de8 100644 (file)
@@ -47,9 +47,9 @@ static int omap1_dm_timer_set_src(struct platform_device *pdev,
        int n = (pdev->id - 1) << 1;
        u32 l;
 
-       l = __raw_readl(MOD_CONF_CTRL_1) & ~(0x03 << n);
+       l = omap_readl(MOD_CONF_CTRL_1) & ~(0x03 << n);
        l |= source << n;
-       __raw_writel(l, MOD_CONF_CTRL_1);
+       omap_writel(l, MOD_CONF_CTRL_1);
 
        return 0;
 }
index a39fc4bbd2b8ffb9cb8bb06c1c91f1c40e120333..130ab00c09a2b00751f7c3e90dfa2ffb8eac7882 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/usb/otg.h>
 #include <linux/spi/spi.h>
 #include <linux/i2c/twl.h>
+#include <linux/mfd/twl6040.h>
 #include <linux/gpio_keys.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/fixed.h>
@@ -560,7 +561,7 @@ static struct regulator_init_data sdp4430_vusim = {
        },
 };
 
-static struct twl4030_codec_data twl6040_codec = {
+static struct twl6040_codec_data twl6040_codec = {
        /* single-step ramp for headset and handsfree */
        .hs_left_step   = 0x0f,
        .hs_right_step  = 0x0f,
@@ -568,7 +569,7 @@ static struct twl4030_codec_data twl6040_codec = {
        .hf_right_step  = 0x1d,
 };
 
-static struct twl4030_vibra_data twl6040_vibra = {
+static struct twl6040_vibra_data twl6040_vibra = {
        .vibldrv_res = 8,
        .vibrdrv_res = 3,
        .viblmotor_res = 10,
@@ -577,16 +578,14 @@ static struct twl4030_vibra_data twl6040_vibra = {
        .vddvibr_uV = 0,        /* fixed volt supply - VBAT */
 };
 
-static struct twl4030_audio_data twl6040_audio = {
+static struct twl6040_platform_data twl6040_data = {
        .codec          = &twl6040_codec,
        .vibra          = &twl6040_vibra,
        .audpwron_gpio  = 127,
-       .naudint_irq    = OMAP44XX_IRQ_SYS_2N,
        .irq_base       = TWL6040_CODEC_IRQ_BASE,
 };
 
 static struct twl4030_platform_data sdp4430_twldata = {
-       .audio          = &twl6040_audio,
        /* Regulators */
        .vusim          = &sdp4430_vusim,
        .vaux1          = &sdp4430_vaux1,
@@ -617,7 +616,8 @@ static int __init omap4_i2c_init(void)
                        TWL_COMMON_REGULATOR_VCXIO |
                        TWL_COMMON_REGULATOR_VUSB |
                        TWL_COMMON_REGULATOR_CLK32KG);
-       omap4_pmic_init("twl6030", &sdp4430_twldata);
+       omap4_pmic_init("twl6030", &sdp4430_twldata,
+                       &twl6040_data, OMAP44XX_IRQ_SYS_2N);
        omap_register_i2c_bus(2, 400, NULL, 0);
        omap_register_i2c_bus(3, 400, sdp4430_i2c_3_boardinfo,
                                ARRAY_SIZE(sdp4430_i2c_3_boardinfo));
index 74e1687b51706317672694d80ac79aa92f0c416f..098d183a008655c6dd66895346033d76da74ecbe 100644 (file)
@@ -137,7 +137,7 @@ static struct twl4030_platform_data sdp4430_twldata = {
 
 static void __init omap4_i2c_init(void)
 {
-       omap4_pmic_init("twl6030", &sdp4430_twldata);
+       omap4_pmic_init("twl6030", &sdp4430_twldata, NULL, 0);
 }
 
 static void __init omap4_init(void)
index d8c0e89f0126a2b4a7ba2a87d49641d1cf05c57c..1b782ba534336f6f3d3236e10316733f0f1b2abc 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/gpio.h>
 #include <linux/usb/otg.h>
 #include <linux/i2c/twl.h>
+#include <linux/mfd/twl6040.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/fixed.h>
 #include <linux/wl12xx.h>
@@ -284,7 +285,7 @@ static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)
        return 0;
 }
 
-static struct twl4030_codec_data twl6040_codec = {
+static struct twl6040_codec_data twl6040_codec = {
        /* single-step ramp for headset and handsfree */
        .hs_left_step   = 0x0f,
        .hs_right_step  = 0x0f,
@@ -292,17 +293,14 @@ static struct twl4030_codec_data twl6040_codec = {
        .hf_right_step  = 0x1d,
 };
 
-static struct twl4030_audio_data twl6040_audio = {
+static struct twl6040_platform_data twl6040_data = {
        .codec          = &twl6040_codec,
        .audpwron_gpio  = 127,
-       .naudint_irq    = OMAP44XX_IRQ_SYS_2N,
        .irq_base       = TWL6040_CODEC_IRQ_BASE,
 };
 
 /* Panda board uses the common PMIC configuration */
-static struct twl4030_platform_data omap4_panda_twldata = {
-       .audio          = &twl6040_audio,
-};
+static struct twl4030_platform_data omap4_panda_twldata;
 
 /*
  * Display monitor features are burnt in their EEPROM as EDID data. The EEPROM
@@ -326,7 +324,8 @@ static int __init omap4_panda_i2c_init(void)
                        TWL_COMMON_REGULATOR_VCXIO |
                        TWL_COMMON_REGULATOR_VUSB |
                        TWL_COMMON_REGULATOR_CLK32KG);
-       omap4_pmic_init("twl6030", &omap4_panda_twldata);
+       omap4_pmic_init("twl6030", &omap4_panda_twldata,
+                       &twl6040_data, OMAP44XX_IRQ_SYS_2N);
        omap_register_i2c_bus(2, 400, NULL, 0);
        /*
         * Bus 3 is attached to the DVI port where devices like the pico DLP
index 2c27fdb61e6665f1037956307f718e224c1301d0..7144ae651d3defcb6e74f9f59ce7f38207691bf4 100644 (file)
@@ -1422,6 +1422,9 @@ static int _ocp_softreset(struct omap_hwmod *oh)
                goto dis_opt_clks;
        _write_sysconfig(v, oh);
 
+       if (oh->class->sysc->srst_udelay)
+               udelay(oh->class->sysc->srst_udelay);
+
        if (oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS)
                omap_test_timeout((omap_hwmod_read(oh,
                                                    oh->class->sysc->syss_offs)
@@ -1903,10 +1906,20 @@ void omap_hwmod_write(u32 v, struct omap_hwmod *oh, u16 reg_offs)
  */
 int omap_hwmod_softreset(struct omap_hwmod *oh)
 {
-       if (!oh)
+       u32 v;
+       int ret;
+
+       if (!oh || !(oh->_sysc_cache))
                return -EINVAL;
 
-       return _ocp_softreset(oh);
+       v = oh->_sysc_cache;
+       ret = _set_softreset(oh, &v);
+       if (ret)
+               goto error;
+       _write_sysconfig(v, oh);
+
+error:
+       return ret;
 }
 
 /**
index a5409ce3f3233eaac531ed070fc1f9cf74e8398f..a6bde34e443a7719fcefcbf447779ea16c9202b0 100644 (file)
@@ -1000,7 +1000,6 @@ static struct omap_hwmod_ocp_if omap2420_l4_core__dss_venc = {
                        .flags  = OMAP_FIREWALL_L4,
                }
        },
-       .flags          = OCPIF_SWSUP_IDLE,
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
index c4f56cb60d7d676ddda36e232c8b385a58fef6ba..04a3885f4475f6e6ff865c4624a19d58b061a7f4 100644 (file)
@@ -1049,7 +1049,6 @@ static struct omap_hwmod_ocp_if omap2430_l4_core__dss_venc = {
        .slave          = &omap2430_dss_venc_hwmod,
        .clk            = "dss_ick",
        .addr           = omap2_dss_venc_addrs,
-       .flags          = OCPIF_SWSUP_IDLE,
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
index 34b9766d1d231845356b2c71626fa234a731bee6..db86ce90c69fbc769fd1c63005a5ad188e43f33b 100644 (file)
@@ -1676,7 +1676,6 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_venc = {
                        .flags  = OMAP_FIREWALL_L4,
                }
        },
-       .flags          = OCPIF_SWSUP_IDLE,
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
index cc9bd106a854beca49128200825748833201fe61..6abc75753e42b2048ab7e7a4e4d158064efcce8b 100644 (file)
@@ -2594,6 +2594,15 @@ static struct omap_hwmod omap44xx_ipu_hwmod = {
 static struct omap_hwmod_class_sysconfig omap44xx_iss_sysc = {
        .rev_offs       = 0x0000,
        .sysc_offs      = 0x0010,
+       /*
+        * ISS needs 100 OCP clk cycles delay after a softreset before
+        * accessing sysconfig again.
+        * The lowest frequency at the moment for L3 bus is 100 MHz, so
+        * 1usec delay is needed. Add an x2 margin to be safe (2 usecs).
+        *
+        * TODO: Indicate errata when available.
+        */
+       .srst_udelay    = 2,
        .sysc_flags     = (SYSC_HAS_MIDLEMODE | SYSC_HAS_RESET_STATUS |
                           SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
        .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
index 0cdd359a128ee855e357daee257ec38231a05658..9fc2f44188cbb5fa0657f45ee5b5f3e14662569b 100644 (file)
@@ -108,8 +108,14 @@ static void omap_uart_set_noidle(struct platform_device *pdev)
 static void omap_uart_set_smartidle(struct platform_device *pdev)
 {
        struct omap_device *od = to_omap_device(pdev);
+       u8 idlemode;
 
-       omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_SMART);
+       if (od->hwmods[0]->class->sysc->idlemodes & SIDLE_SMART_WKUP)
+               idlemode = HWMOD_IDLEMODE_SMART_WKUP;
+       else
+               idlemode = HWMOD_IDLEMODE_SMART;
+
+       omap_hwmod_set_slave_idlemode(od->hwmods[0], idlemode);
 }
 
 #else
@@ -120,124 +126,8 @@ static void omap_uart_set_smartidle(struct platform_device *pdev) {}
 #endif /* CONFIG_PM */
 
 #ifdef CONFIG_OMAP_MUX
-static struct omap_device_pad default_uart1_pads[] __initdata = {
-       {
-               .name   = "uart1_cts.uart1_cts",
-               .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
-       },
-       {
-               .name   = "uart1_rts.uart1_rts",
-               .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
-       },
-       {
-               .name   = "uart1_tx.uart1_tx",
-               .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
-       },
-       {
-               .name   = "uart1_rx.uart1_rx",
-               .flags  = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
-               .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
-               .idle   = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
-       },
-};
-
-static struct omap_device_pad default_uart2_pads[] __initdata = {
-       {
-               .name   = "uart2_cts.uart2_cts",
-               .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
-       },
-       {
-               .name   = "uart2_rts.uart2_rts",
-               .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
-       },
-       {
-               .name   = "uart2_tx.uart2_tx",
-               .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
-       },
-       {
-               .name   = "uart2_rx.uart2_rx",
-               .flags  = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
-               .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
-               .idle   = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
-       },
-};
-
-static struct omap_device_pad default_uart3_pads[] __initdata = {
-       {
-               .name   = "uart3_cts_rctx.uart3_cts_rctx",
-               .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
-       },
-       {
-               .name   = "uart3_rts_sd.uart3_rts_sd",
-               .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
-       },
-       {
-               .name   = "uart3_tx_irtx.uart3_tx_irtx",
-               .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
-       },
-       {
-               .name   = "uart3_rx_irrx.uart3_rx_irrx",
-               .flags  = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
-               .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE0,
-               .idle   = OMAP_PIN_INPUT | OMAP_MUX_MODE0,
-       },
-};
-
-static struct omap_device_pad default_omap36xx_uart4_pads[] __initdata = {
-       {
-               .name   = "gpmc_wait2.uart4_tx",
-               .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
-       },
-       {
-               .name   = "gpmc_wait3.uart4_rx",
-               .flags  = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
-               .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE2,
-               .idle   = OMAP_PIN_INPUT | OMAP_MUX_MODE2,
-       },
-};
-
-static struct omap_device_pad default_omap4_uart4_pads[] __initdata = {
-       {
-               .name   = "uart4_tx.uart4_tx",
-               .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
-       },
-       {
-               .name   = "uart4_rx.uart4_rx",
-               .flags  = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
-               .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE0,
-               .idle   = OMAP_PIN_INPUT | OMAP_MUX_MODE0,
-       },
-};
-
 static void omap_serial_fill_default_pads(struct omap_board_data *bdata)
 {
-       switch (bdata->id) {
-       case 0:
-               bdata->pads = default_uart1_pads;
-               bdata->pads_cnt = ARRAY_SIZE(default_uart1_pads);
-               break;
-       case 1:
-               bdata->pads = default_uart2_pads;
-               bdata->pads_cnt = ARRAY_SIZE(default_uart2_pads);
-               break;
-       case 2:
-               bdata->pads = default_uart3_pads;
-               bdata->pads_cnt = ARRAY_SIZE(default_uart3_pads);
-               break;
-       case 3:
-               if (cpu_is_omap44xx()) {
-                       bdata->pads = default_omap4_uart4_pads;
-                       bdata->pads_cnt =
-                               ARRAY_SIZE(default_omap4_uart4_pads);
-               } else if (cpu_is_omap3630()) {
-                       bdata->pads = default_omap36xx_uart4_pads;
-                       bdata->pads_cnt =
-                               ARRAY_SIZE(default_omap36xx_uart4_pads);
-               }
-               break;
-       default:
-               break;
-       }
 }
 #else
 static void omap_serial_fill_default_pads(struct omap_board_data *bdata) {}
index 4b57757bf9d1200cf4e47e099734ec424cad47d2..7a7b89304c48eeb2e1af9f9b87f77d9d5dd5a6f1 100644 (file)
@@ -37,6 +37,16 @@ static struct i2c_board_info __initdata pmic_i2c_board_info = {
        .flags          = I2C_CLIENT_WAKE,
 };
 
+static struct i2c_board_info __initdata omap4_i2c1_board_info[] = {
+       {
+               .addr           = 0x48,
+               .flags          = I2C_CLIENT_WAKE,
+       },
+       {
+               I2C_BOARD_INFO("twl6040", 0x4b),
+       },
+};
+
 void __init omap_pmic_init(int bus, u32 clkrate,
                           const char *pmic_type, int pmic_irq,
                           struct twl4030_platform_data *pmic_data)
@@ -49,14 +59,31 @@ void __init omap_pmic_init(int bus, u32 clkrate,
        omap_register_i2c_bus(bus, clkrate, &pmic_i2c_board_info, 1);
 }
 
+void __init omap4_pmic_init(const char *pmic_type,
+                   struct twl4030_platform_data *pmic_data,
+                   struct twl6040_platform_data *twl6040_data, int twl6040_irq)
+{
+       /* PMIC part*/
+       strncpy(omap4_i2c1_board_info[0].type, pmic_type,
+               sizeof(omap4_i2c1_board_info[0].type));
+       omap4_i2c1_board_info[0].irq = OMAP44XX_IRQ_SYS_1N;
+       omap4_i2c1_board_info[0].platform_data = pmic_data;
+
+       /* TWL6040 audio IC part */
+       omap4_i2c1_board_info[1].irq = twl6040_irq;
+       omap4_i2c1_board_info[1].platform_data = twl6040_data;
+
+       omap_register_i2c_bus(1, 400, omap4_i2c1_board_info, 2);
+
+}
+
 void __init omap_pmic_late_init(void)
 {
        /* Init the OMAP TWL parameters (if PMIC has been registerd) */
-       if (!pmic_i2c_board_info.irq)
-               return;
-
-       omap3_twl_init();
-       omap4_twl_init();
+       if (pmic_i2c_board_info.irq)
+               omap3_twl_init();
+       if (omap4_i2c1_board_info[0].irq)
+               omap4_twl_init();
 }
 
 #if defined(CONFIG_ARCH_OMAP3)
index 275dde8cb27aa789ce4d9bfa89c8ed92fb122711..09627483a57f917a3a1c74c39b232b951de1594f 100644 (file)
@@ -29,6 +29,7 @@
 
 
 struct twl4030_platform_data;
+struct twl6040_platform_data;
 
 void omap_pmic_init(int bus, u32 clkrate, const char *pmic_type, int pmic_irq,
                    struct twl4030_platform_data *pmic_data);
@@ -46,12 +47,9 @@ static inline void omap3_pmic_init(const char *pmic_type,
        omap_pmic_init(1, 2600, pmic_type, INT_34XX_SYS_NIRQ, pmic_data);
 }
 
-static inline void omap4_pmic_init(const char *pmic_type,
-                                  struct twl4030_platform_data *pmic_data)
-{
-       /* Phoenix Audio IC needs I2C1 to start with 400 KHz or less */
-       omap_pmic_init(1, 400, pmic_type, OMAP44XX_IRQ_SYS_1N, pmic_data);
-}
+void omap4_pmic_init(const char *pmic_type,
+                   struct twl4030_platform_data *pmic_data,
+                   struct twl6040_platform_data *audio_data, int twl6040_irq);
 
 void omap3_pmic_get_config(struct twl4030_platform_data *pmic_data,
                           u32 pdata_flags, u32 regulators_flags);
index 2cee6b0de3712db9b10d99ad5066209834d5227a..8bd37291fa4f00ff652a9232b011962b6ae273c0 100644 (file)
@@ -5,39 +5,22 @@
 if ARCH_SPEAR3XX
 
 menu "SPEAr3xx Implementations"
-config BOARD_SPEAR300_EVB
-       bool "SPEAr300 Evaluation Board"
-       select MACH_SPEAR300
-       help
-         Supports ST SPEAr300 Evaluation Board
-
-config BOARD_SPEAR310_EVB
-       bool "SPEAr310 Evaluation Board"
-       select MACH_SPEAR310
-       help
-         Supports ST SPEAr310 Evaluation Board
-
-config BOARD_SPEAR320_EVB
-       bool "SPEAr320 Evaluation Board"
-       select MACH_SPEAR320
-       help
-         Supports ST SPEAr320 Evaluation Board
-
-endmenu
-
 config MACH_SPEAR300
-       bool "SPEAr300"
+       bool "SPEAr300 Machine support with Device Tree"
+       select PINCTRL_SPEAR300
        help
-         Supports ST SPEAr300 Machine
+         Supports ST SPEAr300 machine configured via the device-tree
 
 config MACH_SPEAR310
-       bool "SPEAr310"
+       bool "SPEAr310 Machine support with Device Tree"
+       select PINCTRL_SPEAR310
        help
-         Supports ST SPEAr310 Machine
+         Supports ST SPEAr310 machine configured via the device-tree
 
 config MACH_SPEAR320
-       bool "SPEAr320"
+       bool "SPEAr320 Machine support with Device Tree"
+       select PINCTRL_SPEAR320
        help
-         Supports ST SPEAr320 Machine
-
+         Supports ST SPEAr320 machine configured via the device-tree
+endmenu
 endif #ARCH_SPEAR3XX
index b248624897043449734aef1d06c31efaacea10a9..17b5d83cf2d5459457c80841fef4b5d3838d2964 100644 (file)
@@ -3,24 +3,13 @@
 #
 
 # common files
-obj-y  += spear3xx.o clock.o
+obj-$(CONFIG_ARCH_SPEAR3XX)    += spear3xx.o clock.o
 
 # spear300 specific files
 obj-$(CONFIG_MACH_SPEAR300) += spear300.o
 
-# spear300 boards files
-obj-$(CONFIG_BOARD_SPEAR300_EVB) += spear300_evb.o
-
-
 # spear310 specific files
 obj-$(CONFIG_MACH_SPEAR310) += spear310.o
 
-# spear310 boards files
-obj-$(CONFIG_BOARD_SPEAR310_EVB) += spear310_evb.o
-
-
 # spear320 specific files
 obj-$(CONFIG_MACH_SPEAR320) += spear320.o
-
-# spear320 boards files
-obj-$(CONFIG_BOARD_SPEAR320_EVB) += spear320_evb.o
index 4674a4c221dbcf58f9bc1b43a9fa97a0977d9489..d93e2177e6ec909882013ecdb0ec4a5a85005ca6 100644 (file)
@@ -1,3 +1,7 @@
 zreladdr-y     += 0x00008000
 params_phys-y  := 0x00000100
 initrd_phys-y  := 0x00800000
+
+dtb-$(CONFIG_MACH_SPEAR300)    += spear300-evb.dtb
+dtb-$(CONFIG_MACH_SPEAR310)    += spear310-evb.dtb
+dtb-$(CONFIG_MACH_SPEAR320)    += spear320-evb.dtb
index 6c4841f5522345cb9cdf5c1e5d83cd332adfc644..eeafe38eab25ea0117790ac1b461740bd4d8775b 100644 (file)
  * warranty of any kind, whether express or implied.
  */
 
+#include <linux/clkdev.h>
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
+#include <linux/of_platform.h>
 #include <asm/mach-types.h>
 #include <plat/clock.h>
 #include <mach/misc_regs.h>
@@ -411,6 +413,21 @@ static struct clk usbd_clk = {
        .recalc = &follow_parent,
 };
 
+/* clock derived from usbh clk */
+/* usbh0 clock */
+static struct clk usbh0_clk = {
+       .flags = ALWAYS_ENABLED,
+       .pclk = &usbh_clk,
+       .recalc = &follow_parent,
+};
+
+/* usbh1 clock */
+static struct clk usbh1_clk = {
+       .flags = ALWAYS_ENABLED,
+       .pclk = &usbh_clk,
+       .recalc = &follow_parent,
+};
+
 /* clock derived from ahb clk */
 /* apb masks structure */
 static struct bus_clk_masks apb_masks = {
@@ -652,109 +669,126 @@ static struct clk pwm_clk = {
 
 /* array of all spear 3xx clock lookups */
 static struct clk_lookup spear_clk_lookups[] = {
-       { .con_id = "apb_pclk",         .clk = &dummy_apb_pclk},
+       CLKDEV_INIT(NULL, "apb_pclk", &dummy_apb_pclk),
        /* root clks */
-       { .con_id = "osc_32k_clk",      .clk = &osc_32k_clk},
-       { .con_id = "osc_24m_clk",      .clk = &osc_24m_clk},
+       CLKDEV_INIT(NULL, "osc_32k_clk", &osc_32k_clk),
+       CLKDEV_INIT(NULL, "osc_24m_clk", &osc_24m_clk),
        /* clock derived from 32 KHz osc clk */
-       { .dev_id = "rtc-spear",        .clk = &rtc_clk},
+       CLKDEV_INIT("fc900000.rtc", NULL, &rtc_clk),
        /* clock derived from 24 MHz osc clk */
-       { .con_id = "pll1_clk",         .clk = &pll1_clk},
-       { .con_id = "pll3_48m_clk",     .clk = &pll3_48m_clk},
-       { .dev_id = "wdt",              .clk = &wdt_clk},
+       CLKDEV_INIT(NULL, "pll1_clk", &pll1_clk),
+       CLKDEV_INIT(NULL, "pll3_48m_clk", &pll3_48m_clk),
+       CLKDEV_INIT("fc880000.wdt", NULL, &wdt_clk),
        /* clock derived from pll1 clk */
-       { .con_id = "cpu_clk",          .clk = &cpu_clk},
-       { .con_id = "ahb_clk",          .clk = &ahb_clk},
-       { .con_id = "uart_synth_clk",   .clk = &uart_synth_clk},
-       { .con_id = "firda_synth_clk",  .clk = &firda_synth_clk},
-       { .con_id = "gpt0_synth_clk",   .clk = &gpt0_synth_clk},
-       { .con_id = "gpt1_synth_clk",   .clk = &gpt1_synth_clk},
-       { .con_id = "gpt2_synth_clk",   .clk = &gpt2_synth_clk},
-       { .dev_id = "uart",             .clk = &uart_clk},
-       { .dev_id = "firda",            .clk = &firda_clk},
-       { .dev_id = "gpt0",             .clk = &gpt0_clk},
-       { .dev_id = "gpt1",             .clk = &gpt1_clk},
-       { .dev_id = "gpt2",             .clk = &gpt2_clk},
+       CLKDEV_INIT(NULL, "cpu_clk", &cpu_clk),
+       CLKDEV_INIT(NULL, "ahb_clk", &ahb_clk),
+       CLKDEV_INIT(NULL, "uart_synth_clk", &uart_synth_clk),
+       CLKDEV_INIT(NULL, "firda_synth_clk", &firda_synth_clk),
+       CLKDEV_INIT(NULL, "gpt0_synth_clk", &gpt0_synth_clk),
+       CLKDEV_INIT(NULL, "gpt1_synth_clk", &gpt1_synth_clk),
+       CLKDEV_INIT(NULL, "gpt2_synth_clk", &gpt2_synth_clk),
+       CLKDEV_INIT("d0000000.serial", NULL, &uart_clk),
+       CLKDEV_INIT("firda", NULL, &firda_clk),
+       CLKDEV_INIT("gpt0", NULL, &gpt0_clk),
+       CLKDEV_INIT("gpt1", NULL, &gpt1_clk),
+       CLKDEV_INIT("gpt2", NULL, &gpt2_clk),
        /* clock derived from pll3 clk */
-       { .dev_id = "designware_udc",   .clk = &usbd_clk},
-       { .con_id = "usbh_clk",         .clk = &usbh_clk},
+       CLKDEV_INIT("designware_udc", NULL, &usbd_clk),
+       CLKDEV_INIT(NULL, "usbh_clk", &usbh_clk),
+       /* clock derived from usbh clk */
+       CLKDEV_INIT(NULL, "usbh.0_clk", &usbh0_clk),
+       CLKDEV_INIT(NULL, "usbh.1_clk", &usbh1_clk),
        /* clock derived from ahb clk */
-       { .con_id = "apb_clk",          .clk = &apb_clk},
-       { .dev_id = "i2c_designware.0", .clk = &i2c_clk},
-       { .dev_id = "dma",              .clk = &dma_clk},
-       { .dev_id = "jpeg",             .clk = &jpeg_clk},
-       { .dev_id = "gmac",             .clk = &gmac_clk},
-       { .dev_id = "smi",              .clk = &smi_clk},
-       { .dev_id = "c3",               .clk = &c3_clk},
+       CLKDEV_INIT(NULL, "apb_clk", &apb_clk),
+       CLKDEV_INIT("d0180000.i2c", NULL, &i2c_clk),
+       CLKDEV_INIT("fc400000.dma", NULL, &dma_clk),
+       CLKDEV_INIT("jpeg", NULL, &jpeg_clk),
+       CLKDEV_INIT("e0800000.eth", NULL, &gmac_clk),
+       CLKDEV_INIT("fc000000.flash", NULL, &smi_clk),
+       CLKDEV_INIT("c3", NULL, &c3_clk),
        /* clock derived from apb clk */
-       { .dev_id = "adc",              .clk = &adc_clk},
-       { .dev_id = "ssp-pl022.0",      .clk = &ssp0_clk},
-       { .dev_id = "gpio",             .clk = &gpio_clk},
+       CLKDEV_INIT("adc", NULL, &adc_clk),
+       CLKDEV_INIT("d0100000.spi", NULL, &ssp0_clk),
+       CLKDEV_INIT("fc980000.gpio", NULL, &gpio_clk),
 };
 
 /* array of all spear 300 clock lookups */
 #ifdef CONFIG_MACH_SPEAR300
 static struct clk_lookup spear300_clk_lookups[] = {
-       { .dev_id = "clcd",             .clk = &clcd_clk},
-       { .con_id = "fsmc",             .clk = &fsmc_clk},
-       { .dev_id = "gpio1",            .clk = &gpio1_clk},
-       { .dev_id = "keyboard",         .clk = &kbd_clk},
-       { .dev_id = "sdhci",            .clk = &sdhci_clk},
+       CLKDEV_INIT("60000000.clcd", NULL, &clcd_clk),
+       CLKDEV_INIT("94000000.flash", NULL, &fsmc_clk),
+       CLKDEV_INIT("a9000000.gpio", NULL, &gpio1_clk),
+       CLKDEV_INIT("a0000000.kbd", NULL, &kbd_clk),
+       CLKDEV_INIT("70000000.sdhci", NULL, &sdhci_clk),
 };
+
+void __init spear300_clk_init(void)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(spear_clk_lookups); i++)
+               clk_register(&spear_clk_lookups[i]);
+
+       for (i = 0; i < ARRAY_SIZE(spear300_clk_lookups); i++)
+               clk_register(&spear300_clk_lookups[i]);
+
+       clk_init();
+}
 #endif
 
 /* array of all spear 310 clock lookups */
 #ifdef CONFIG_MACH_SPEAR310
 static struct clk_lookup spear310_clk_lookups[] = {
-       { .con_id = "fsmc",             .clk = &fsmc_clk},
-       { .con_id = "emi",              .clk = &emi_clk},
-       { .dev_id = "uart1",            .clk = &uart1_clk},
-       { .dev_id = "uart2",            .clk = &uart2_clk},
-       { .dev_id = "uart3",            .clk = &uart3_clk},
-       { .dev_id = "uart4",            .clk = &uart4_clk},
-       { .dev_id = "uart5",            .clk = &uart5_clk},
+       CLKDEV_INIT("44000000.flash", NULL, &fsmc_clk),
+       CLKDEV_INIT(NULL, "emi", &emi_clk),
+       CLKDEV_INIT("b2000000.serial", NULL, &uart1_clk),
+       CLKDEV_INIT("b2080000.serial", NULL, &uart2_clk),
+       CLKDEV_INIT("b2100000.serial", NULL, &uart3_clk),
+       CLKDEV_INIT("b2180000.serial", NULL, &uart4_clk),
+       CLKDEV_INIT("b2200000.serial", NULL, &uart5_clk),
 };
+
+void __init spear310_clk_init(void)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(spear_clk_lookups); i++)
+               clk_register(&spear_clk_lookups[i]);
+
+       for (i = 0; i < ARRAY_SIZE(spear310_clk_lookups); i++)
+               clk_register(&spear310_clk_lookups[i]);
+
+       clk_init();
+}
 #endif
 
 /* array of all spear 320 clock lookups */
 #ifdef CONFIG_MACH_SPEAR320
 static struct clk_lookup spear320_clk_lookups[] = {
-       { .dev_id = "clcd",             .clk = &clcd_clk},
-       { .con_id = "fsmc",             .clk = &fsmc_clk},
-       { .dev_id = "i2c_designware.1", .clk = &i2c1_clk},
-       { .con_id = "emi",              .clk = &emi_clk},
-       { .dev_id = "pwm",              .clk = &pwm_clk},
-       { .dev_id = "sdhci",            .clk = &sdhci_clk},
-       { .dev_id = "c_can_platform.0", .clk = &can0_clk},
-       { .dev_id = "c_can_platform.1", .clk = &can1_clk},
-       { .dev_id = "ssp-pl022.1",      .clk = &ssp1_clk},
-       { .dev_id = "ssp-pl022.2",      .clk = &ssp2_clk},
-       { .dev_id = "uart1",            .clk = &uart1_clk},
-       { .dev_id = "uart2",            .clk = &uart2_clk},
-};
-#endif
-
-void __init spear3xx_clk_init(void)
+       CLKDEV_INIT("90000000.clcd", NULL, &clcd_clk),
+       CLKDEV_INIT("4c000000.flash", NULL, &fsmc_clk),
+       CLKDEV_INIT("a7000000.i2c", NULL, &i2c1_clk),
+       CLKDEV_INIT(NULL, "emi", &emi_clk),
+       CLKDEV_INIT("pwm", NULL, &pwm_clk),
+       CLKDEV_INIT("70000000.sdhci", NULL, &sdhci_clk),
+       CLKDEV_INIT("c_can_platform.0", NULL, &can0_clk),
+       CLKDEV_INIT("c_can_platform.1", NULL, &can1_clk),
+       CLKDEV_INIT("a5000000.spi", NULL, &ssp1_clk),
+       CLKDEV_INIT("a6000000.spi", NULL, &ssp2_clk),
+       CLKDEV_INIT("a3000000.serial", NULL, &uart1_clk),
+       CLKDEV_INIT("a4000000.serial", NULL, &uart2_clk),
+};
+
+void __init spear320_clk_init(void)
 {
-       int i, cnt;
-       struct clk_lookup *lookups;
-
-       if (machine_is_spear300()) {
-               cnt = ARRAY_SIZE(spear300_clk_lookups);
-               lookups = spear300_clk_lookups;
-       } else if (machine_is_spear310()) {
-               cnt = ARRAY_SIZE(spear310_clk_lookups);
-               lookups = spear310_clk_lookups;
-       } else {
-               cnt = ARRAY_SIZE(spear320_clk_lookups);
-               lookups = spear320_clk_lookups;
-       }
+       int i;
 
        for (i = 0; i < ARRAY_SIZE(spear_clk_lookups); i++)
                clk_register(&spear_clk_lookups[i]);
 
-       for (i = 0; i < cnt; i++)
-               clk_register(&lookups[i]);
+       for (i = 0; i < ARRAY_SIZE(spear320_clk_lookups); i++)
+               clk_register(&spear320_clk_lookups[i]);
 
        clk_init();
 }
+#endif
index 14276e5a98d2e2081d5ba227ceac6d5f11b6d985..9603bf4d5119d391e12e11c3d56d40a086ce8934 100644 (file)
 #ifndef __MACH_GENERIC_H
 #define __MACH_GENERIC_H
 
+#include <linux/amba/pl08x.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/amba/bus.h>
 #include <asm/mach/time.h>
 #include <asm/mach/map.h>
-#include <plat/padmux.h>
 
 /* spear3xx declarations */
 /*
 #define SPEAR_GPT0_CHAN1_IRQ   SPEAR3XX_IRQ_CPU_GPT1_2
 
 /* Add spear3xx family device structure declarations here */
-extern struct amba_device spear3xx_gpio_device;
-extern struct amba_device spear3xx_uart_device;
 extern struct sys_timer spear3xx_timer;
+extern struct pl022_ssp_controller pl022_plat_data;
+extern struct pl08x_platform_data pl080_plat_data;
 
 /* Add spear3xx family function declarations here */
-void __init spear3xx_clk_init(void);
 void __init spear_setup_timer(void);
 void __init spear3xx_map_io(void);
-void __init spear3xx_init_irq(void);
-void __init spear3xx_init(void);
+void __init spear3xx_dt_init_irq(void);
 
 void spear_restart(char, const char *);
 
-/* pad mux declarations */
-#define PMX_FIRDA_MASK         (1 << 14)
-#define PMX_I2C_MASK           (1 << 13)
-#define PMX_SSP_CS_MASK                (1 << 12)
-#define PMX_SSP_MASK           (1 << 11)
-#define PMX_MII_MASK           (1 << 10)
-#define PMX_GPIO_PIN0_MASK     (1 << 9)
-#define PMX_GPIO_PIN1_MASK     (1 << 8)
-#define PMX_GPIO_PIN2_MASK     (1 << 7)
-#define PMX_GPIO_PIN3_MASK     (1 << 6)
-#define PMX_GPIO_PIN4_MASK     (1 << 5)
-#define PMX_GPIO_PIN5_MASK     (1 << 4)
-#define PMX_UART0_MODEM_MASK   (1 << 3)
-#define PMX_UART0_MASK         (1 << 2)
-#define PMX_TIMER_3_4_MASK     (1 << 1)
-#define PMX_TIMER_1_2_MASK     (1 << 0)
-
-/* pad mux devices */
-extern struct pmx_dev spear3xx_pmx_firda;
-extern struct pmx_dev spear3xx_pmx_i2c;
-extern struct pmx_dev spear3xx_pmx_ssp_cs;
-extern struct pmx_dev spear3xx_pmx_ssp;
-extern struct pmx_dev spear3xx_pmx_mii;
-extern struct pmx_dev spear3xx_pmx_gpio_pin0;
-extern struct pmx_dev spear3xx_pmx_gpio_pin1;
-extern struct pmx_dev spear3xx_pmx_gpio_pin2;
-extern struct pmx_dev spear3xx_pmx_gpio_pin3;
-extern struct pmx_dev spear3xx_pmx_gpio_pin4;
-extern struct pmx_dev spear3xx_pmx_gpio_pin5;
-extern struct pmx_dev spear3xx_pmx_uart0_modem;
-extern struct pmx_dev spear3xx_pmx_uart0;
-extern struct pmx_dev spear3xx_pmx_timer_3_4;
-extern struct pmx_dev spear3xx_pmx_timer_1_2;
-
-#if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
-/* padmux plgpio devices */
-extern struct pmx_dev spear3xx_pmx_plgpio_0_1;
-extern struct pmx_dev spear3xx_pmx_plgpio_2_3;
-extern struct pmx_dev spear3xx_pmx_plgpio_4_5;
-extern struct pmx_dev spear3xx_pmx_plgpio_6_9;
-extern struct pmx_dev spear3xx_pmx_plgpio_10_27;
-extern struct pmx_dev spear3xx_pmx_plgpio_28;
-extern struct pmx_dev spear3xx_pmx_plgpio_29;
-extern struct pmx_dev spear3xx_pmx_plgpio_30;
-extern struct pmx_dev spear3xx_pmx_plgpio_31;
-extern struct pmx_dev spear3xx_pmx_plgpio_32;
-extern struct pmx_dev spear3xx_pmx_plgpio_33;
-extern struct pmx_dev spear3xx_pmx_plgpio_34_36;
-extern struct pmx_dev spear3xx_pmx_plgpio_37_42;
-extern struct pmx_dev spear3xx_pmx_plgpio_43_44_47_48;
-extern struct pmx_dev spear3xx_pmx_plgpio_45_46_49_50;
-#endif
-
 /* spear300 declarations */
 #ifdef CONFIG_MACH_SPEAR300
-/* Add spear300 machine device structure declarations here */
-extern struct amba_device spear300_gpio1_device;
-
-/* pad mux modes */
-extern struct pmx_mode spear300_nand_mode;
-extern struct pmx_mode spear300_nor_mode;
-extern struct pmx_mode spear300_photo_frame_mode;
-extern struct pmx_mode spear300_lend_ip_phone_mode;
-extern struct pmx_mode spear300_hend_ip_phone_mode;
-extern struct pmx_mode spear300_lend_wifi_phone_mode;
-extern struct pmx_mode spear300_hend_wifi_phone_mode;
-extern struct pmx_mode spear300_ata_pabx_wi2s_mode;
-extern struct pmx_mode spear300_ata_pabx_i2s_mode;
-extern struct pmx_mode spear300_caml_lcdw_mode;
-extern struct pmx_mode spear300_camu_lcd_mode;
-extern struct pmx_mode spear300_camu_wlcd_mode;
-extern struct pmx_mode spear300_caml_lcd_mode;
-
-/* pad mux devices */
-extern struct pmx_dev spear300_pmx_fsmc_2_chips;
-extern struct pmx_dev spear300_pmx_fsmc_4_chips;
-extern struct pmx_dev spear300_pmx_keyboard;
-extern struct pmx_dev spear300_pmx_clcd;
-extern struct pmx_dev spear300_pmx_telecom_gpio;
-extern struct pmx_dev spear300_pmx_telecom_tdm;
-extern struct pmx_dev spear300_pmx_telecom_spi_cs_i2c_clk;
-extern struct pmx_dev spear300_pmx_telecom_camera;
-extern struct pmx_dev spear300_pmx_telecom_dac;
-extern struct pmx_dev spear300_pmx_telecom_i2s;
-extern struct pmx_dev spear300_pmx_telecom_boot_pins;
-extern struct pmx_dev spear300_pmx_telecom_sdhci_4bit;
-extern struct pmx_dev spear300_pmx_telecom_sdhci_8bit;
-extern struct pmx_dev spear300_pmx_gpio1;
-
-/* Add spear300 machine function declarations here */
-void __init spear300_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
-               u8 pmx_dev_count);
+void __init spear300_clk_init(void);
 
 #endif /* CONFIG_MACH_SPEAR300 */
 
 /* spear310 declarations */
 #ifdef CONFIG_MACH_SPEAR310
-/* Add spear310 machine device structure declarations here */
-
-/* pad mux devices */
-extern struct pmx_dev spear310_pmx_emi_cs_0_1_4_5;
-extern struct pmx_dev spear310_pmx_emi_cs_2_3;
-extern struct pmx_dev spear310_pmx_uart1;
-extern struct pmx_dev spear310_pmx_uart2;
-extern struct pmx_dev spear310_pmx_uart3_4_5;
-extern struct pmx_dev spear310_pmx_fsmc;
-extern struct pmx_dev spear310_pmx_rs485_0_1;
-extern struct pmx_dev spear310_pmx_tdm0;
-
-/* Add spear310 machine function declarations here */
-void __init spear310_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
-               u8 pmx_dev_count);
+void __init spear310_clk_init(void);
 
 #endif /* CONFIG_MACH_SPEAR310 */
 
 /* spear320 declarations */
 #ifdef CONFIG_MACH_SPEAR320
-/* Add spear320 machine device structure declarations here */
-
-/* pad mux modes */
-extern struct pmx_mode spear320_auto_net_smii_mode;
-extern struct pmx_mode spear320_auto_net_mii_mode;
-extern struct pmx_mode spear320_auto_exp_mode;
-extern struct pmx_mode spear320_small_printers_mode;
-
-/* pad mux devices */
-extern struct pmx_dev spear320_pmx_clcd;
-extern struct pmx_dev spear320_pmx_emi;
-extern struct pmx_dev spear320_pmx_fsmc;
-extern struct pmx_dev spear320_pmx_spp;
-extern struct pmx_dev spear320_pmx_sdhci;
-extern struct pmx_dev spear320_pmx_i2s;
-extern struct pmx_dev spear320_pmx_uart1;
-extern struct pmx_dev spear320_pmx_uart1_modem;
-extern struct pmx_dev spear320_pmx_uart2;
-extern struct pmx_dev spear320_pmx_touchscreen;
-extern struct pmx_dev spear320_pmx_can;
-extern struct pmx_dev spear320_pmx_sdhci_led;
-extern struct pmx_dev spear320_pmx_pwm0;
-extern struct pmx_dev spear320_pmx_pwm1;
-extern struct pmx_dev spear320_pmx_pwm2;
-extern struct pmx_dev spear320_pmx_pwm3;
-extern struct pmx_dev spear320_pmx_ssp1;
-extern struct pmx_dev spear320_pmx_ssp2;
-extern struct pmx_dev spear320_pmx_mii1;
-extern struct pmx_dev spear320_pmx_smii0;
-extern struct pmx_dev spear320_pmx_smii1;
-extern struct pmx_dev spear320_pmx_i2c1;
-
-/* Add spear320 machine function declarations here */
-void __init spear320_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
-               u8 pmx_dev_count);
+void __init spear320_clk_init(void);
 
 #endif /* CONFIG_MACH_SPEAR320 */
 
index 4660c0d8ec0db16baf592055f18bf9fe45f7089a..defa374f5bee79b199d4da67c91ba28eac157824 100644 (file)
@@ -17,7 +17,4 @@
 #include <plat/hardware.h>
 #include <mach/spear.h>
 
-/* Vitual to physical translation of statically mapped space */
-#define IO_ADDRESS(x)          (x | 0xF0000000)
-
 #endif /* __MACH_HARDWARE_H */
index 63fd98356919d557133f28cc497c628adc33ed78..8e3900aa0d451f18bedeb763d68f1f587a6c454f 100644 (file)
@@ -25,8 +25,9 @@
 
 /* ICM1 - Low speed connection */
 #define SPEAR3XX_ICM1_2_BASE           UL(0xD0000000)
+#define VA_SPEAR3XX_ICM1_2_BASE                UL(0xFD000000)
 #define SPEAR3XX_ICM1_UART_BASE                UL(0xD0000000)
-#define VA_SPEAR3XX_ICM1_UART_BASE     IO_ADDRESS(SPEAR3XX_ICM1_UART_BASE)
+#define VA_SPEAR3XX_ICM1_UART_BASE     (VA_SPEAR3XX_ICM1_2_BASE | SPEAR3XX_ICM1_UART_BASE)
 #define SPEAR3XX_ICM1_ADC_BASE         UL(0xD0080000)
 #define SPEAR3XX_ICM1_SSP_BASE         UL(0xD0100000)
 #define SPEAR3XX_ICM1_I2C_BASE         UL(0xD0180000)
 #define SPEAR3XX_ICM3_ML1_2_BASE       UL(0xF0000000)
 #define SPEAR3XX_ML1_TMR_BASE          UL(0xF0000000)
 #define SPEAR3XX_ML1_VIC_BASE          UL(0xF1100000)
-#define VA_SPEAR3XX_ML1_VIC_BASE       IO_ADDRESS(SPEAR3XX_ML1_VIC_BASE)
 
 /* ICM3 - Basic Subsystem */
 #define SPEAR3XX_ICM3_SMEM_BASE                UL(0xF8000000)
 #define SPEAR3XX_ICM3_SMI_CTRL_BASE    UL(0xFC000000)
+#define VA_SPEAR3XX_ICM3_SMI_CTRL_BASE UL(0xFC000000)
 #define SPEAR3XX_ICM3_DMA_BASE         UL(0xFC400000)
 #define SPEAR3XX_ICM3_SDRAM_CTRL_BASE  UL(0xFC600000)
 #define SPEAR3XX_ICM3_TMR0_BASE                UL(0xFC800000)
@@ -65,9 +66,9 @@
 #define SPEAR3XX_ICM3_RTC_BASE         UL(0xFC900000)
 #define SPEAR3XX_ICM3_GPIO_BASE                UL(0xFC980000)
 #define SPEAR3XX_ICM3_SYS_CTRL_BASE    UL(0xFCA00000)
-#define VA_SPEAR3XX_ICM3_SYS_CTRL_BASE IO_ADDRESS(SPEAR3XX_ICM3_SYS_CTRL_BASE)
+#define VA_SPEAR3XX_ICM3_SYS_CTRL_BASE (VA_SPEAR3XX_ICM3_SMI_CTRL_BASE | SPEAR3XX_ICM3_SYS_CTRL_BASE)
 #define SPEAR3XX_ICM3_MISC_REG_BASE    UL(0xFCA80000)
-#define VA_SPEAR3XX_ICM3_MISC_REG_BASE IO_ADDRESS(SPEAR3XX_ICM3_MISC_REG_BASE)
+#define VA_SPEAR3XX_ICM3_MISC_REG_BASE (VA_SPEAR3XX_ICM3_SMI_CTRL_BASE | SPEAR3XX_ICM3_MISC_REG_BASE)
 #define SPEAR3XX_ICM3_TMR1_BASE                UL(0xFCB00000)
 
 /* Debug uart for linux, will be used for debug and uncompress messages */
index f7db66812abbbfff904a5776828d18c0b2991606..2db0bd14e48181dbb9f84600f5733501650496fc 100644 (file)
  *
  * SPEAr300 machine source file
  *
- * Copyright (C) 2009 ST Microelectronics
- * Viresh Kumar<viresh.kumar@st.com>
+ * Copyright (C) 2009-2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.com>
  *
  * This file is licensed under the terms of the GNU General Public
  * License version 2. This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
 
-#include <linux/types.h>
-#include <linux/amba/pl061.h>
-#include <linux/ptrace.h>
-#include <asm/irq.h>
+#define pr_fmt(fmt) "SPEAr300: " fmt
+
+#include <linux/amba/pl08x.h>
+#include <linux/of_platform.h>
+#include <asm/hardware/vic.h>
+#include <asm/mach/arch.h>
 #include <plat/shirq.h>
 #include <mach/generic.h>
 #include <mach/hardware.h>
 
-/* pad multiplexing support */
-/* muxing registers */
-#define PAD_MUX_CONFIG_REG     0x00
-#define MODE_CONFIG_REG                0x04
-
-/* modes */
-#define NAND_MODE                      (1 << 0)
-#define NOR_MODE                       (1 << 1)
-#define PHOTO_FRAME_MODE               (1 << 2)
-#define LEND_IP_PHONE_MODE             (1 << 3)
-#define HEND_IP_PHONE_MODE             (1 << 4)
-#define LEND_WIFI_PHONE_MODE           (1 << 5)
-#define HEND_WIFI_PHONE_MODE           (1 << 6)
-#define ATA_PABX_WI2S_MODE             (1 << 7)
-#define ATA_PABX_I2S_MODE              (1 << 8)
-#define CAML_LCDW_MODE                 (1 << 9)
-#define CAMU_LCD_MODE                  (1 << 10)
-#define CAMU_WLCD_MODE                 (1 << 11)
-#define CAML_LCD_MODE                  (1 << 12)
-#define ALL_MODES                      0x1FFF
-
-struct pmx_mode spear300_nand_mode = {
-       .id = NAND_MODE,
-       .name = "nand mode",
-       .mask = 0x00,
-};
-
-struct pmx_mode spear300_nor_mode = {
-       .id = NOR_MODE,
-       .name = "nor mode",
-       .mask = 0x01,
-};
-
-struct pmx_mode spear300_photo_frame_mode = {
-       .id = PHOTO_FRAME_MODE,
-       .name = "photo frame mode",
-       .mask = 0x02,
-};
-
-struct pmx_mode spear300_lend_ip_phone_mode = {
-       .id = LEND_IP_PHONE_MODE,
-       .name = "lend ip phone mode",
-       .mask = 0x03,
-};
-
-struct pmx_mode spear300_hend_ip_phone_mode = {
-       .id = HEND_IP_PHONE_MODE,
-       .name = "hend ip phone mode",
-       .mask = 0x04,
-};
-
-struct pmx_mode spear300_lend_wifi_phone_mode = {
-       .id = LEND_WIFI_PHONE_MODE,
-       .name = "lend wifi phone mode",
-       .mask = 0x05,
-};
-
-struct pmx_mode spear300_hend_wifi_phone_mode = {
-       .id = HEND_WIFI_PHONE_MODE,
-       .name = "hend wifi phone mode",
-       .mask = 0x06,
-};
-
-struct pmx_mode spear300_ata_pabx_wi2s_mode = {
-       .id = ATA_PABX_WI2S_MODE,
-       .name = "ata pabx wi2s mode",
-       .mask = 0x07,
-};
-
-struct pmx_mode spear300_ata_pabx_i2s_mode = {
-       .id = ATA_PABX_I2S_MODE,
-       .name = "ata pabx i2s mode",
-       .mask = 0x08,
-};
-
-struct pmx_mode spear300_caml_lcdw_mode = {
-       .id = CAML_LCDW_MODE,
-       .name = "caml lcdw mode",
-       .mask = 0x0C,
-};
-
-struct pmx_mode spear300_camu_lcd_mode = {
-       .id = CAMU_LCD_MODE,
-       .name = "camu lcd mode",
-       .mask = 0x0D,
-};
-
-struct pmx_mode spear300_camu_wlcd_mode = {
-       .id = CAMU_WLCD_MODE,
-       .name = "camu wlcd mode",
-       .mask = 0x0E,
-};
-
-struct pmx_mode spear300_caml_lcd_mode = {
-       .id = CAML_LCD_MODE,
-       .name = "caml lcd mode",
-       .mask = 0x0F,
-};
-
-/* devices */
-static struct pmx_dev_mode pmx_fsmc_2_chips_modes[] = {
-       {
-               .ids = NAND_MODE | NOR_MODE | PHOTO_FRAME_MODE |
-                       ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE,
-               .mask = PMX_FIRDA_MASK,
-       },
-};
-
-struct pmx_dev spear300_pmx_fsmc_2_chips = {
-       .name = "fsmc_2_chips",
-       .modes = pmx_fsmc_2_chips_modes,
-       .mode_count = ARRAY_SIZE(pmx_fsmc_2_chips_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_fsmc_4_chips_modes[] = {
-       {
-               .ids = NAND_MODE | NOR_MODE | PHOTO_FRAME_MODE |
-                       ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE,
-               .mask = PMX_FIRDA_MASK | PMX_UART0_MASK,
-       },
-};
-
-struct pmx_dev spear300_pmx_fsmc_4_chips = {
-       .name = "fsmc_4_chips",
-       .modes = pmx_fsmc_4_chips_modes,
-       .mode_count = ARRAY_SIZE(pmx_fsmc_4_chips_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_keyboard_modes[] = {
-       {
-               .ids = LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE |
-                       LEND_WIFI_PHONE_MODE | HEND_WIFI_PHONE_MODE |
-                       CAML_LCDW_MODE | CAMU_LCD_MODE | CAMU_WLCD_MODE |
-                       CAML_LCD_MODE,
-               .mask = 0x0,
-       },
-};
-
-struct pmx_dev spear300_pmx_keyboard = {
-       .name = "keyboard",
-       .modes = pmx_keyboard_modes,
-       .mode_count = ARRAY_SIZE(pmx_keyboard_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_clcd_modes[] = {
-       {
-               .ids = PHOTO_FRAME_MODE,
-               .mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK ,
-       }, {
-               .ids = HEND_IP_PHONE_MODE | HEND_WIFI_PHONE_MODE |
-                       CAMU_LCD_MODE | CAML_LCD_MODE,
-               .mask = PMX_TIMER_3_4_MASK,
-       },
-};
-
-struct pmx_dev spear300_pmx_clcd = {
-       .name = "clcd",
-       .modes = pmx_clcd_modes,
-       .mode_count = ARRAY_SIZE(pmx_clcd_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_telecom_gpio_modes[] = {
-       {
-               .ids = PHOTO_FRAME_MODE | CAMU_LCD_MODE | CAML_LCD_MODE,
-               .mask = PMX_MII_MASK,
-       }, {
-               .ids = LEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE,
-               .mask = PMX_MII_MASK | PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK,
-       }, {
-               .ids = ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_WLCD_MODE,
-               .mask = PMX_MII_MASK | PMX_TIMER_3_4_MASK,
-       }, {
-               .ids = HEND_IP_PHONE_MODE | HEND_WIFI_PHONE_MODE,
-               .mask = PMX_MII_MASK | PMX_TIMER_1_2_MASK,
-       }, {
-               .ids = ATA_PABX_WI2S_MODE,
-               .mask = PMX_MII_MASK | PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK
-                       | PMX_UART0_MODEM_MASK,
-       },
-};
-
-struct pmx_dev spear300_pmx_telecom_gpio = {
-       .name = "telecom_gpio",
-       .modes = pmx_telecom_gpio_modes,
-       .mode_count = ARRAY_SIZE(pmx_telecom_gpio_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_telecom_tdm_modes[] = {
-       {
-               .ids = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE |
-                       HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE
-                       | HEND_WIFI_PHONE_MODE | ATA_PABX_WI2S_MODE
-                       | ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE
-                       | CAMU_WLCD_MODE | CAML_LCD_MODE,
-               .mask = PMX_UART0_MODEM_MASK | PMX_SSP_CS_MASK,
-       },
-};
-
-struct pmx_dev spear300_pmx_telecom_tdm = {
-       .name = "telecom_tdm",
-       .modes = pmx_telecom_tdm_modes,
-       .mode_count = ARRAY_SIZE(pmx_telecom_tdm_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_telecom_spi_cs_i2c_clk_modes[] = {
-       {
-               .ids = LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE |
-                       LEND_WIFI_PHONE_MODE | HEND_WIFI_PHONE_MODE
-                       | ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE |
-                       CAML_LCDW_MODE | CAML_LCD_MODE,
-               .mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK,
-       },
-};
-
-struct pmx_dev spear300_pmx_telecom_spi_cs_i2c_clk = {
-       .name = "telecom_spi_cs_i2c_clk",
-       .modes = pmx_telecom_spi_cs_i2c_clk_modes,
-       .mode_count = ARRAY_SIZE(pmx_telecom_spi_cs_i2c_clk_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_telecom_camera_modes[] = {
-       {
-               .ids = CAML_LCDW_MODE | CAML_LCD_MODE,
-               .mask = PMX_MII_MASK,
-       }, {
-               .ids = CAMU_LCD_MODE | CAMU_WLCD_MODE,
-               .mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK | PMX_MII_MASK,
-       },
-};
-
-struct pmx_dev spear300_pmx_telecom_camera = {
-       .name = "telecom_camera",
-       .modes = pmx_telecom_camera_modes,
-       .mode_count = ARRAY_SIZE(pmx_telecom_camera_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_telecom_dac_modes[] = {
-       {
-               .ids = ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE
-                       | CAMU_WLCD_MODE | CAML_LCD_MODE,
-               .mask = PMX_TIMER_1_2_MASK,
-       },
-};
-
-struct pmx_dev spear300_pmx_telecom_dac = {
-       .name = "telecom_dac",
-       .modes = pmx_telecom_dac_modes,
-       .mode_count = ARRAY_SIZE(pmx_telecom_dac_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_telecom_i2s_modes[] = {
-       {
-               .ids = LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE
-                       | LEND_WIFI_PHONE_MODE | HEND_WIFI_PHONE_MODE |
-                       ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE
-                       | CAMU_WLCD_MODE | CAML_LCD_MODE,
-               .mask = PMX_UART0_MODEM_MASK,
-       },
-};
-
-struct pmx_dev spear300_pmx_telecom_i2s = {
-       .name = "telecom_i2s",
-       .modes = pmx_telecom_i2s_modes,
-       .mode_count = ARRAY_SIZE(pmx_telecom_i2s_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_telecom_boot_pins_modes[] = {
-       {
-               .ids = NAND_MODE | NOR_MODE,
-               .mask = PMX_UART0_MODEM_MASK | PMX_TIMER_1_2_MASK |
-                       PMX_TIMER_3_4_MASK,
-       },
-};
-
-struct pmx_dev spear300_pmx_telecom_boot_pins = {
-       .name = "telecom_boot_pins",
-       .modes = pmx_telecom_boot_pins_modes,
-       .mode_count = ARRAY_SIZE(pmx_telecom_boot_pins_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_telecom_sdhci_4bit_modes[] = {
-       {
-               .ids = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE |
-                       HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE |
-                       HEND_WIFI_PHONE_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE |
-                       CAMU_WLCD_MODE | CAML_LCD_MODE | ATA_PABX_WI2S_MODE |
-                       ATA_PABX_I2S_MODE,
-               .mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK |
-                       PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK |
-                       PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK,
-       },
-};
-
-struct pmx_dev spear300_pmx_telecom_sdhci_4bit = {
-       .name = "telecom_sdhci_4bit",
-       .modes = pmx_telecom_sdhci_4bit_modes,
-       .mode_count = ARRAY_SIZE(pmx_telecom_sdhci_4bit_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_telecom_sdhci_8bit_modes[] = {
-       {
-               .ids = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE |
-                       HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE |
-                       HEND_WIFI_PHONE_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE |
-                       CAMU_WLCD_MODE | CAML_LCD_MODE,
-               .mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK |
-                       PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK |
-                       PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK | PMX_MII_MASK,
-       },
-};
-
-struct pmx_dev spear300_pmx_telecom_sdhci_8bit = {
-       .name = "telecom_sdhci_8bit",
-       .modes = pmx_telecom_sdhci_8bit_modes,
-       .mode_count = ARRAY_SIZE(pmx_telecom_sdhci_8bit_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_gpio1_modes[] = {
-       {
-               .ids = PHOTO_FRAME_MODE,
-               .mask = PMX_UART0_MODEM_MASK | PMX_TIMER_1_2_MASK |
-                       PMX_TIMER_3_4_MASK,
-       },
-};
-
-struct pmx_dev spear300_pmx_gpio1 = {
-       .name = "arm gpio1",
-       .modes = pmx_gpio1_modes,
-       .mode_count = ARRAY_SIZE(pmx_gpio1_modes),
-       .enb_on_reset = 1,
-};
-
-/* pmx driver structure */
-static struct pmx_driver pmx_driver = {
-       .mode_reg = {.offset = MODE_CONFIG_REG, .mask = 0x0000000f},
-       .mux_reg = {.offset = PAD_MUX_CONFIG_REG, .mask = 0x00007fff},
-};
-
 /* spear3xx shared irq */
 static struct shirq_dev_config shirq_ras1_config[] = {
        {
@@ -423,45 +74,239 @@ static struct spear_shirq shirq_ras1 = {
        },
 };
 
-/* Add spear300 specific devices here */
-/* arm gpio1 device registration */
-static struct pl061_platform_data gpio1_plat_data = {
-       .gpio_base      = 8,
-       .irq_base       = SPEAR300_GPIO1_INT_BASE,
+/* DMAC platform data's slave info */
+struct pl08x_channel_data spear300_dma_info[] = {
+       {
+               .bus_id = "uart0_rx",
+               .min_signal = 2,
+               .max_signal = 2,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "uart0_tx",
+               .min_signal = 3,
+               .max_signal = 3,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ssp0_rx",
+               .min_signal = 8,
+               .max_signal = 8,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ssp0_tx",
+               .min_signal = 9,
+               .max_signal = 9,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "i2c_rx",
+               .min_signal = 10,
+               .max_signal = 10,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "i2c_tx",
+               .min_signal = 11,
+               .max_signal = 11,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "irda",
+               .min_signal = 12,
+               .max_signal = 12,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "adc",
+               .min_signal = 13,
+               .max_signal = 13,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "to_jpeg",
+               .min_signal = 14,
+               .max_signal = 14,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "from_jpeg",
+               .min_signal = 15,
+               .max_signal = 15,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras0_rx",
+               .min_signal = 0,
+               .max_signal = 0,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras0_tx",
+               .min_signal = 1,
+               .max_signal = 1,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras1_rx",
+               .min_signal = 2,
+               .max_signal = 2,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras1_tx",
+               .min_signal = 3,
+               .max_signal = 3,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras2_rx",
+               .min_signal = 4,
+               .max_signal = 4,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras2_tx",
+               .min_signal = 5,
+               .max_signal = 5,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras3_rx",
+               .min_signal = 6,
+               .max_signal = 6,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras3_tx",
+               .min_signal = 7,
+               .max_signal = 7,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras4_rx",
+               .min_signal = 8,
+               .max_signal = 8,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras4_tx",
+               .min_signal = 9,
+               .max_signal = 9,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras5_rx",
+               .min_signal = 10,
+               .max_signal = 10,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras5_tx",
+               .min_signal = 11,
+               .max_signal = 11,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras6_rx",
+               .min_signal = 12,
+               .max_signal = 12,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras6_tx",
+               .min_signal = 13,
+               .max_signal = 13,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras7_rx",
+               .min_signal = 14,
+               .max_signal = 14,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras7_tx",
+               .min_signal = 15,
+               .max_signal = 15,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       },
 };
 
-AMBA_APB_DEVICE(spear300_gpio1, "gpio1", 0, SPEAR300_GPIO_BASE,
-       {SPEAR300_VIRQ_GPIO1}, &gpio1_plat_data);
+/* Add SPEAr300 auxdata to pass platform data */
+static struct of_dev_auxdata spear300_auxdata_lookup[] __initdata = {
+       OF_DEV_AUXDATA("arm,pl022", SPEAR3XX_ICM1_SSP_BASE, NULL,
+                       &pl022_plat_data),
+       OF_DEV_AUXDATA("arm,pl080", SPEAR3XX_ICM3_DMA_BASE, NULL,
+                       &pl080_plat_data),
+       {}
+};
 
-/* spear300 routines */
-void __init spear300_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
-               u8 pmx_dev_count)
+static void __init spear300_dt_init(void)
 {
-       int ret = 0;
+       int ret;
+
+       pl080_plat_data.slave_channels = spear300_dma_info;
+       pl080_plat_data.num_slave_channels = ARRAY_SIZE(spear300_dma_info);
 
-       /* call spear3xx family common init function */
-       spear3xx_init();
+       of_platform_populate(NULL, of_default_bus_match_table,
+                       spear300_auxdata_lookup, NULL);
 
        /* shared irq registration */
        shirq_ras1.regs.base = ioremap(SPEAR300_TELECOM_BASE, SZ_4K);
        if (shirq_ras1.regs.base) {
                ret = spear_shirq_register(&shirq_ras1);
                if (ret)
-                       printk(KERN_ERR "Error registering Shared IRQ\n");
+                       pr_err("Error registering Shared IRQ\n");
        }
+}
 
-       /* pmx initialization */
-       pmx_driver.mode = pmx_mode;
-       pmx_driver.devs = pmx_devs;
-       pmx_driver.devs_count = pmx_dev_count;
+static const char * const spear300_dt_board_compat[] = {
+       "st,spear300",
+       "st,spear300-evb",
+       NULL,
+};
 
-       pmx_driver.base = ioremap(SPEAR300_SOC_CONFIG_BASE, SZ_4K);
-       if (pmx_driver.base) {
-               ret = pmx_register(&pmx_driver);
-               if (ret)
-                       printk(KERN_ERR "padmux: registration failed. err no"
-                                       ": %d\n", ret);
-               /* Free Mapping, device selection already done */
-               iounmap(pmx_driver.base);
-       }
+static void __init spear300_map_io(void)
+{
+       spear3xx_map_io();
+       spear300_clk_init();
 }
+
+DT_MACHINE_START(SPEAR300_DT, "ST SPEAr300 SoC with Flattened Device Tree")
+       .map_io         =       spear300_map_io,
+       .init_irq       =       spear3xx_dt_init_irq,
+       .handle_irq     =       vic_handle_irq,
+       .timer          =       &spear3xx_timer,
+       .init_machine   =       spear300_dt_init,
+       .restart        =       spear_restart,
+       .dt_compat      =       spear300_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-spear3xx/spear300_evb.c b/arch/arm/mach-spear3xx/spear300_evb.c
deleted file mode 100644 (file)
index 3462ab9..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * arch/arm/mach-spear3xx/spear300_evb.c
- *
- * SPEAr300 evaluation board source file
- *
- * Copyright (C) 2009 ST Microelectronics
- * Viresh Kumar<viresh.kumar@st.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <asm/hardware/vic.h>
-#include <asm/mach/arch.h>
-#include <asm/mach-types.h>
-#include <mach/generic.h>
-#include <mach/hardware.h>
-
-/* padmux devices to enable */
-static struct pmx_dev *pmx_devs[] = {
-       /* spear3xx specific devices */
-       &spear3xx_pmx_i2c,
-       &spear3xx_pmx_ssp_cs,
-       &spear3xx_pmx_ssp,
-       &spear3xx_pmx_mii,
-       &spear3xx_pmx_uart0,
-
-       /* spear300 specific devices */
-       &spear300_pmx_fsmc_2_chips,
-       &spear300_pmx_clcd,
-       &spear300_pmx_telecom_sdhci_4bit,
-       &spear300_pmx_gpio1,
-};
-
-static struct amba_device *amba_devs[] __initdata = {
-       /* spear3xx specific devices */
-       &spear3xx_gpio_device,
-       &spear3xx_uart_device,
-
-       /* spear300 specific devices */
-       &spear300_gpio1_device,
-};
-
-static struct platform_device *plat_devs[] __initdata = {
-       /* spear3xx specific devices */
-
-       /* spear300 specific devices */
-};
-
-static void __init spear300_evb_init(void)
-{
-       unsigned int i;
-
-       /* call spear300 machine init function */
-       spear300_init(&spear300_photo_frame_mode, pmx_devs,
-                       ARRAY_SIZE(pmx_devs));
-
-       /* Add Platform Devices */
-       platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
-
-       /* Add Amba Devices */
-       for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
-               amba_device_register(amba_devs[i], &iomem_resource);
-}
-
-MACHINE_START(SPEAR300, "ST-SPEAR300-EVB")
-       .atag_offset    =       0x100,
-       .map_io         =       spear3xx_map_io,
-       .init_irq       =       spear3xx_init_irq,
-       .handle_irq     =       vic_handle_irq,
-       .timer          =       &spear3xx_timer,
-       .init_machine   =       spear300_evb_init,
-       .restart        =       spear_restart,
-MACHINE_END
index febaa6fcfb6a0ee7d39da9a25ad0286fdd0eeed1..aec07c951205323967cca53c0321f02e4c0ccc2a 100644 (file)
  *
  * SPEAr310 machine source file
  *
- * Copyright (C) 2009 ST Microelectronics
- * Viresh Kumar<viresh.kumar@st.com>
+ * Copyright (C) 2009-2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.com>
  *
  * This file is licensed under the terms of the GNU General Public
  * License version 2. This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
 
-#include <linux/ptrace.h>
-#include <asm/irq.h>
+#define pr_fmt(fmt) "SPEAr310: " fmt
+
+#include <linux/amba/pl08x.h>
+#include <linux/amba/serial.h>
+#include <linux/of_platform.h>
+#include <asm/hardware/vic.h>
+#include <asm/mach/arch.h>
 #include <plat/shirq.h>
 #include <mach/generic.h>
 #include <mach/hardware.h>
 
-/* pad multiplexing support */
-/* muxing registers */
-#define PAD_MUX_CONFIG_REG     0x08
-
-/* devices */
-static struct pmx_dev_mode pmx_emi_cs_0_1_4_5_modes[] = {
-       {
-               .ids = 0x00,
-               .mask = PMX_TIMER_3_4_MASK,
-       },
-};
-
-struct pmx_dev spear310_pmx_emi_cs_0_1_4_5 = {
-       .name = "emi_cs_0_1_4_5",
-       .modes = pmx_emi_cs_0_1_4_5_modes,
-       .mode_count = ARRAY_SIZE(pmx_emi_cs_0_1_4_5_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_emi_cs_2_3_modes[] = {
-       {
-               .ids = 0x00,
-               .mask = PMX_TIMER_1_2_MASK,
-       },
-};
-
-struct pmx_dev spear310_pmx_emi_cs_2_3 = {
-       .name = "emi_cs_2_3",
-       .modes = pmx_emi_cs_2_3_modes,
-       .mode_count = ARRAY_SIZE(pmx_emi_cs_2_3_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_uart1_modes[] = {
-       {
-               .ids = 0x00,
-               .mask = PMX_FIRDA_MASK,
-       },
-};
-
-struct pmx_dev spear310_pmx_uart1 = {
-       .name = "uart1",
-       .modes = pmx_uart1_modes,
-       .mode_count = ARRAY_SIZE(pmx_uart1_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_uart2_modes[] = {
-       {
-               .ids = 0x00,
-               .mask = PMX_TIMER_1_2_MASK,
-       },
-};
-
-struct pmx_dev spear310_pmx_uart2 = {
-       .name = "uart2",
-       .modes = pmx_uart2_modes,
-       .mode_count = ARRAY_SIZE(pmx_uart2_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_uart3_4_5_modes[] = {
-       {
-               .ids = 0x00,
-               .mask = PMX_UART0_MODEM_MASK,
-       },
-};
-
-struct pmx_dev spear310_pmx_uart3_4_5 = {
-       .name = "uart3_4_5",
-       .modes = pmx_uart3_4_5_modes,
-       .mode_count = ARRAY_SIZE(pmx_uart3_4_5_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_fsmc_modes[] = {
-       {
-               .ids = 0x00,
-               .mask = PMX_SSP_CS_MASK,
-       },
-};
-
-struct pmx_dev spear310_pmx_fsmc = {
-       .name = "fsmc",
-       .modes = pmx_fsmc_modes,
-       .mode_count = ARRAY_SIZE(pmx_fsmc_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_rs485_0_1_modes[] = {
-       {
-               .ids = 0x00,
-               .mask = PMX_MII_MASK,
-       },
-};
-
-struct pmx_dev spear310_pmx_rs485_0_1 = {
-       .name = "rs485_0_1",
-       .modes = pmx_rs485_0_1_modes,
-       .mode_count = ARRAY_SIZE(pmx_rs485_0_1_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_tdm0_modes[] = {
-       {
-               .ids = 0x00,
-               .mask = PMX_MII_MASK,
-       },
-};
-
-struct pmx_dev spear310_pmx_tdm0 = {
-       .name = "tdm0",
-       .modes = pmx_tdm0_modes,
-       .mode_count = ARRAY_SIZE(pmx_tdm0_modes),
-       .enb_on_reset = 1,
-};
-
-/* pmx driver structure */
-static struct pmx_driver pmx_driver = {
-       .mux_reg = {.offset = PAD_MUX_CONFIG_REG, .mask = 0x00007fff},
-};
-
 /* spear3xx shared irq */
 static struct shirq_dev_config shirq_ras1_config[] = {
        {
@@ -255,17 +138,247 @@ static struct spear_shirq shirq_intrcomm_ras = {
        },
 };
 
-/* Add spear310 specific devices here */
+/* DMAC platform data's slave info */
+struct pl08x_channel_data spear310_dma_info[] = {
+       {
+               .bus_id = "uart0_rx",
+               .min_signal = 2,
+               .max_signal = 2,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "uart0_tx",
+               .min_signal = 3,
+               .max_signal = 3,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ssp0_rx",
+               .min_signal = 8,
+               .max_signal = 8,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ssp0_tx",
+               .min_signal = 9,
+               .max_signal = 9,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "i2c_rx",
+               .min_signal = 10,
+               .max_signal = 10,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "i2c_tx",
+               .min_signal = 11,
+               .max_signal = 11,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "irda",
+               .min_signal = 12,
+               .max_signal = 12,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "adc",
+               .min_signal = 13,
+               .max_signal = 13,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "to_jpeg",
+               .min_signal = 14,
+               .max_signal = 14,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "from_jpeg",
+               .min_signal = 15,
+               .max_signal = 15,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "uart1_rx",
+               .min_signal = 0,
+               .max_signal = 0,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "uart1_tx",
+               .min_signal = 1,
+               .max_signal = 1,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "uart2_rx",
+               .min_signal = 2,
+               .max_signal = 2,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "uart2_tx",
+               .min_signal = 3,
+               .max_signal = 3,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "uart3_rx",
+               .min_signal = 4,
+               .max_signal = 4,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "uart3_tx",
+               .min_signal = 5,
+               .max_signal = 5,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "uart4_rx",
+               .min_signal = 6,
+               .max_signal = 6,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "uart4_tx",
+               .min_signal = 7,
+               .max_signal = 7,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "uart5_rx",
+               .min_signal = 8,
+               .max_signal = 8,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "uart5_tx",
+               .min_signal = 9,
+               .max_signal = 9,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras5_rx",
+               .min_signal = 10,
+               .max_signal = 10,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras5_tx",
+               .min_signal = 11,
+               .max_signal = 11,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras6_rx",
+               .min_signal = 12,
+               .max_signal = 12,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras6_tx",
+               .min_signal = 13,
+               .max_signal = 13,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras7_rx",
+               .min_signal = 14,
+               .max_signal = 14,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras7_tx",
+               .min_signal = 15,
+               .max_signal = 15,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       },
+};
 
-/* spear310 routines */
-void __init spear310_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
-               u8 pmx_dev_count)
+/* uart devices plat data */
+static struct amba_pl011_data spear310_uart_data[] = {
+       {
+               .dma_filter = pl08x_filter_id,
+               .dma_tx_param = "uart1_tx",
+               .dma_rx_param = "uart1_rx",
+       }, {
+               .dma_filter = pl08x_filter_id,
+               .dma_tx_param = "uart2_tx",
+               .dma_rx_param = "uart2_rx",
+       }, {
+               .dma_filter = pl08x_filter_id,
+               .dma_tx_param = "uart3_tx",
+               .dma_rx_param = "uart3_rx",
+       }, {
+               .dma_filter = pl08x_filter_id,
+               .dma_tx_param = "uart4_tx",
+               .dma_rx_param = "uart4_rx",
+       }, {
+               .dma_filter = pl08x_filter_id,
+               .dma_tx_param = "uart5_tx",
+               .dma_rx_param = "uart5_rx",
+       },
+};
+
+/* Add SPEAr310 auxdata to pass platform data */
+static struct of_dev_auxdata spear310_auxdata_lookup[] __initdata = {
+       OF_DEV_AUXDATA("arm,pl022", SPEAR3XX_ICM1_SSP_BASE, NULL,
+                       &pl022_plat_data),
+       OF_DEV_AUXDATA("arm,pl080", SPEAR3XX_ICM3_DMA_BASE, NULL,
+                       &pl080_plat_data),
+       OF_DEV_AUXDATA("arm,pl011", SPEAR310_UART1_BASE, NULL,
+                       &spear310_uart_data[0]),
+       OF_DEV_AUXDATA("arm,pl011", SPEAR310_UART2_BASE, NULL,
+                       &spear310_uart_data[1]),
+       OF_DEV_AUXDATA("arm,pl011", SPEAR310_UART3_BASE, NULL,
+                       &spear310_uart_data[2]),
+       OF_DEV_AUXDATA("arm,pl011", SPEAR310_UART4_BASE, NULL,
+                       &spear310_uart_data[3]),
+       OF_DEV_AUXDATA("arm,pl011", SPEAR310_UART5_BASE, NULL,
+                       &spear310_uart_data[4]),
+       {}
+};
+
+static void __init spear310_dt_init(void)
 {
        void __iomem *base;
-       int ret = 0;
+       int ret;
 
-       /* call spear3xx family common init function */
-       spear3xx_init();
+       pl080_plat_data.slave_channels = spear310_dma_info;
+       pl080_plat_data.num_slave_channels = ARRAY_SIZE(spear310_dma_info);
+
+       of_platform_populate(NULL, of_default_bus_match_table,
+                       spear310_auxdata_lookup, NULL);
 
        /* shared irq registration */
        base = ioremap(SPEAR310_SOC_CONFIG_BASE, SZ_4K);
@@ -274,35 +387,46 @@ void __init spear310_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
                shirq_ras1.regs.base = base;
                ret = spear_shirq_register(&shirq_ras1);
                if (ret)
-                       printk(KERN_ERR "Error registering Shared IRQ 1\n");
+                       pr_err("Error registering Shared IRQ 1\n");
 
                /* shirq 2 */
                shirq_ras2.regs.base = base;
                ret = spear_shirq_register(&shirq_ras2);
                if (ret)
-                       printk(KERN_ERR "Error registering Shared IRQ 2\n");
+                       pr_err("Error registering Shared IRQ 2\n");
 
                /* shirq 3 */
                shirq_ras3.regs.base = base;
                ret = spear_shirq_register(&shirq_ras3);
                if (ret)
-                       printk(KERN_ERR "Error registering Shared IRQ 3\n");
+                       pr_err("Error registering Shared IRQ 3\n");
 
                /* shirq 4 */
                shirq_intrcomm_ras.regs.base = base;
                ret = spear_shirq_register(&shirq_intrcomm_ras);
                if (ret)
-                       printk(KERN_ERR "Error registering Shared IRQ 4\n");
+                       pr_err("Error registering Shared IRQ 4\n");
        }
+}
 
-       /* pmx initialization */
-       pmx_driver.base = base;
-       pmx_driver.mode = pmx_mode;
-       pmx_driver.devs = pmx_devs;
-       pmx_driver.devs_count = pmx_dev_count;
+static const char * const spear310_dt_board_compat[] = {
+       "st,spear310",
+       "st,spear310-evb",
+       NULL,
+};
 
-       ret = pmx_register(&pmx_driver);
-       if (ret)
-               printk(KERN_ERR "padmux: registration failed. err no: %d\n",
-                               ret);
+static void __init spear310_map_io(void)
+{
+       spear3xx_map_io();
+       spear310_clk_init();
 }
+
+DT_MACHINE_START(SPEAR310_DT, "ST SPEAr310 SoC with Flattened Device Tree")
+       .map_io         =       spear310_map_io,
+       .init_irq       =       spear3xx_dt_init_irq,
+       .handle_irq     =       vic_handle_irq,
+       .timer          =       &spear3xx_timer,
+       .init_machine   =       spear310_dt_init,
+       .restart        =       spear_restart,
+       .dt_compat      =       spear310_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-spear3xx/spear310_evb.c b/arch/arm/mach-spear3xx/spear310_evb.c
deleted file mode 100644 (file)
index f92c499..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * arch/arm/mach-spear3xx/spear310_evb.c
- *
- * SPEAr310 evaluation board source file
- *
- * Copyright (C) 2009 ST Microelectronics
- * Viresh Kumar<viresh.kumar@st.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <asm/hardware/vic.h>
-#include <asm/mach/arch.h>
-#include <asm/mach-types.h>
-#include <mach/generic.h>
-#include <mach/hardware.h>
-
-/* padmux devices to enable */
-static struct pmx_dev *pmx_devs[] = {
-       /* spear3xx specific devices */
-       &spear3xx_pmx_i2c,
-       &spear3xx_pmx_ssp,
-       &spear3xx_pmx_gpio_pin0,
-       &spear3xx_pmx_gpio_pin1,
-       &spear3xx_pmx_gpio_pin2,
-       &spear3xx_pmx_gpio_pin3,
-       &spear3xx_pmx_gpio_pin4,
-       &spear3xx_pmx_gpio_pin5,
-       &spear3xx_pmx_uart0,
-
-       /* spear310 specific devices */
-       &spear310_pmx_emi_cs_0_1_4_5,
-       &spear310_pmx_emi_cs_2_3,
-       &spear310_pmx_uart1,
-       &spear310_pmx_uart2,
-       &spear310_pmx_uart3_4_5,
-       &spear310_pmx_fsmc,
-       &spear310_pmx_rs485_0_1,
-       &spear310_pmx_tdm0,
-};
-
-static struct amba_device *amba_devs[] __initdata = {
-       /* spear3xx specific devices */
-       &spear3xx_gpio_device,
-       &spear3xx_uart_device,
-
-       /* spear310 specific devices */
-};
-
-static struct platform_device *plat_devs[] __initdata = {
-       /* spear3xx specific devices */
-
-       /* spear310 specific devices */
-};
-
-static void __init spear310_evb_init(void)
-{
-       unsigned int i;
-
-       /* call spear310 machine init function */
-       spear310_init(NULL, pmx_devs, ARRAY_SIZE(pmx_devs));
-
-       /* Add Platform Devices */
-       platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
-
-       /* Add Amba Devices */
-       for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
-               amba_device_register(amba_devs[i], &iomem_resource);
-}
-
-MACHINE_START(SPEAR310, "ST-SPEAR310-EVB")
-       .atag_offset    =       0x100,
-       .map_io         =       spear3xx_map_io,
-       .init_irq       =       spear3xx_init_irq,
-       .handle_irq     =       vic_handle_irq,
-       .timer          =       &spear3xx_timer,
-       .init_machine   =       spear310_evb_init,
-       .restart        =       spear_restart,
-MACHINE_END
index deaaf199612c87efd9d29e27448b92fdc07dddca..4812c692ca351640456e8bb2a352f93de1498334 100644 (file)
  *
  * SPEAr320 machine source file
  *
- * Copyright (C) 2009 ST Microelectronics
- * Viresh Kumar<viresh.kumar@st.com>
+ * Copyright (C) 2009-2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.com>
  *
  * This file is licensed under the terms of the GNU General Public
  * License version 2. This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
 
-#include <linux/ptrace.h>
-#include <asm/irq.h>
+#define pr_fmt(fmt) "SPEAr320: " fmt
+
+#include <linux/amba/pl022.h>
+#include <linux/amba/pl08x.h>
+#include <linux/amba/serial.h>
+#include <linux/of_platform.h>
+#include <asm/hardware/vic.h>
+#include <asm/mach/arch.h>
 #include <plat/shirq.h>
 #include <mach/generic.h>
 #include <mach/hardware.h>
 
-/* pad multiplexing support */
-/* muxing registers */
-#define PAD_MUX_CONFIG_REG     0x0C
-#define MODE_CONFIG_REG                0x10
-
-/* modes */
-#define AUTO_NET_SMII_MODE     (1 << 0)
-#define AUTO_NET_MII_MODE      (1 << 1)
-#define AUTO_EXP_MODE          (1 << 2)
-#define SMALL_PRINTERS_MODE    (1 << 3)
-#define ALL_MODES              0xF
-
-struct pmx_mode spear320_auto_net_smii_mode = {
-       .id = AUTO_NET_SMII_MODE,
-       .name = "Automation Networking SMII Mode",
-       .mask = 0x00,
-};
-
-struct pmx_mode spear320_auto_net_mii_mode = {
-       .id = AUTO_NET_MII_MODE,
-       .name = "Automation Networking MII Mode",
-       .mask = 0x01,
-};
-
-struct pmx_mode spear320_auto_exp_mode = {
-       .id = AUTO_EXP_MODE,
-       .name = "Automation Expanded Mode",
-       .mask = 0x02,
-};
-
-struct pmx_mode spear320_small_printers_mode = {
-       .id = SMALL_PRINTERS_MODE,
-       .name = "Small Printers Mode",
-       .mask = 0x03,
-};
-
-/* devices */
-static struct pmx_dev_mode pmx_clcd_modes[] = {
-       {
-               .ids = AUTO_NET_SMII_MODE,
-               .mask = 0x0,
-       },
-};
-
-struct pmx_dev spear320_pmx_clcd = {
-       .name = "clcd",
-       .modes = pmx_clcd_modes,
-       .mode_count = ARRAY_SIZE(pmx_clcd_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_emi_modes[] = {
-       {
-               .ids = AUTO_EXP_MODE,
-               .mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK,
-       },
-};
-
-struct pmx_dev spear320_pmx_emi = {
-       .name = "emi",
-       .modes = pmx_emi_modes,
-       .mode_count = ARRAY_SIZE(pmx_emi_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_fsmc_modes[] = {
-       {
-               .ids = ALL_MODES,
-               .mask = 0x0,
-       },
-};
-
-struct pmx_dev spear320_pmx_fsmc = {
-       .name = "fsmc",
-       .modes = pmx_fsmc_modes,
-       .mode_count = ARRAY_SIZE(pmx_fsmc_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_spp_modes[] = {
-       {
-               .ids = SMALL_PRINTERS_MODE,
-               .mask = 0x0,
-       },
-};
-
-struct pmx_dev spear320_pmx_spp = {
-       .name = "spp",
-       .modes = pmx_spp_modes,
-       .mode_count = ARRAY_SIZE(pmx_spp_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_sdhci_modes[] = {
-       {
-               .ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE |
-                       SMALL_PRINTERS_MODE,
-               .mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK,
-       },
-};
-
-struct pmx_dev spear320_pmx_sdhci = {
-       .name = "sdhci",
-       .modes = pmx_sdhci_modes,
-       .mode_count = ARRAY_SIZE(pmx_sdhci_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_i2s_modes[] = {
-       {
-               .ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
-               .mask = PMX_UART0_MODEM_MASK,
-       },
-};
-
-struct pmx_dev spear320_pmx_i2s = {
-       .name = "i2s",
-       .modes = pmx_i2s_modes,
-       .mode_count = ARRAY_SIZE(pmx_i2s_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_uart1_modes[] = {
-       {
-               .ids = ALL_MODES,
-               .mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK,
-       },
-};
-
-struct pmx_dev spear320_pmx_uart1 = {
-       .name = "uart1",
-       .modes = pmx_uart1_modes,
-       .mode_count = ARRAY_SIZE(pmx_uart1_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_uart1_modem_modes[] = {
-       {
-               .ids = AUTO_EXP_MODE,
-               .mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK |
-                       PMX_SSP_CS_MASK,
-       }, {
-               .ids = SMALL_PRINTERS_MODE,
-               .mask = PMX_GPIO_PIN3_MASK | PMX_GPIO_PIN4_MASK |
-                       PMX_GPIO_PIN5_MASK | PMX_SSP_CS_MASK,
-       },
-};
-
-struct pmx_dev spear320_pmx_uart1_modem = {
-       .name = "uart1_modem",
-       .modes = pmx_uart1_modem_modes,
-       .mode_count = ARRAY_SIZE(pmx_uart1_modem_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_uart2_modes[] = {
-       {
-               .ids = ALL_MODES,
-               .mask = PMX_FIRDA_MASK,
-       },
-};
-
-struct pmx_dev spear320_pmx_uart2 = {
-       .name = "uart2",
-       .modes = pmx_uart2_modes,
-       .mode_count = ARRAY_SIZE(pmx_uart2_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_touchscreen_modes[] = {
-       {
-               .ids = AUTO_NET_SMII_MODE,
-               .mask = PMX_SSP_CS_MASK,
-       },
-};
-
-struct pmx_dev spear320_pmx_touchscreen = {
-       .name = "touchscreen",
-       .modes = pmx_touchscreen_modes,
-       .mode_count = ARRAY_SIZE(pmx_touchscreen_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_can_modes[] = {
-       {
-               .ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE | AUTO_EXP_MODE,
-               .mask = PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK |
-                       PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK,
-       },
-};
-
-struct pmx_dev spear320_pmx_can = {
-       .name = "can",
-       .modes = pmx_can_modes,
-       .mode_count = ARRAY_SIZE(pmx_can_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_sdhci_led_modes[] = {
-       {
-               .ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
-               .mask = PMX_SSP_CS_MASK,
-       },
-};
-
-struct pmx_dev spear320_pmx_sdhci_led = {
-       .name = "sdhci_led",
-       .modes = pmx_sdhci_led_modes,
-       .mode_count = ARRAY_SIZE(pmx_sdhci_led_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_pwm0_modes[] = {
-       {
-               .ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
-               .mask = PMX_UART0_MODEM_MASK,
-       }, {
-               .ids = AUTO_EXP_MODE | SMALL_PRINTERS_MODE,
-               .mask = PMX_MII_MASK,
-       },
-};
-
-struct pmx_dev spear320_pmx_pwm0 = {
-       .name = "pwm0",
-       .modes = pmx_pwm0_modes,
-       .mode_count = ARRAY_SIZE(pmx_pwm0_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_pwm1_modes[] = {
-       {
-               .ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
-               .mask = PMX_UART0_MODEM_MASK,
-       }, {
-               .ids = AUTO_EXP_MODE | SMALL_PRINTERS_MODE,
-               .mask = PMX_MII_MASK,
-       },
-};
-
-struct pmx_dev spear320_pmx_pwm1 = {
-       .name = "pwm1",
-       .modes = pmx_pwm1_modes,
-       .mode_count = ARRAY_SIZE(pmx_pwm1_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_pwm2_modes[] = {
-       {
-               .ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
-               .mask = PMX_SSP_CS_MASK,
-       }, {
-               .ids = AUTO_EXP_MODE | SMALL_PRINTERS_MODE,
-               .mask = PMX_MII_MASK,
-       },
-};
-
-struct pmx_dev spear320_pmx_pwm2 = {
-       .name = "pwm2",
-       .modes = pmx_pwm2_modes,
-       .mode_count = ARRAY_SIZE(pmx_pwm2_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_pwm3_modes[] = {
-       {
-               .ids = AUTO_EXP_MODE | SMALL_PRINTERS_MODE | AUTO_NET_SMII_MODE,
-               .mask = PMX_MII_MASK,
-       },
-};
-
-struct pmx_dev spear320_pmx_pwm3 = {
-       .name = "pwm3",
-       .modes = pmx_pwm3_modes,
-       .mode_count = ARRAY_SIZE(pmx_pwm3_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_ssp1_modes[] = {
-       {
-               .ids = SMALL_PRINTERS_MODE | AUTO_NET_SMII_MODE,
-               .mask = PMX_MII_MASK,
-       },
-};
-
-struct pmx_dev spear320_pmx_ssp1 = {
-       .name = "ssp1",
-       .modes = pmx_ssp1_modes,
-       .mode_count = ARRAY_SIZE(pmx_ssp1_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_ssp2_modes[] = {
-       {
-               .ids = AUTO_NET_SMII_MODE,
-               .mask = PMX_MII_MASK,
-       },
-};
-
-struct pmx_dev spear320_pmx_ssp2 = {
-       .name = "ssp2",
-       .modes = pmx_ssp2_modes,
-       .mode_count = ARRAY_SIZE(pmx_ssp2_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_mii1_modes[] = {
-       {
-               .ids = AUTO_NET_MII_MODE,
-               .mask = 0x0,
-       },
-};
-
-struct pmx_dev spear320_pmx_mii1 = {
-       .name = "mii1",
-       .modes = pmx_mii1_modes,
-       .mode_count = ARRAY_SIZE(pmx_mii1_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_smii0_modes[] = {
-       {
-               .ids = AUTO_NET_SMII_MODE | AUTO_EXP_MODE | SMALL_PRINTERS_MODE,
-               .mask = PMX_MII_MASK,
-       },
-};
-
-struct pmx_dev spear320_pmx_smii0 = {
-       .name = "smii0",
-       .modes = pmx_smii0_modes,
-       .mode_count = ARRAY_SIZE(pmx_smii0_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_smii1_modes[] = {
-       {
-               .ids = AUTO_NET_SMII_MODE | SMALL_PRINTERS_MODE,
-               .mask = PMX_MII_MASK,
-       },
-};
-
-struct pmx_dev spear320_pmx_smii1 = {
-       .name = "smii1",
-       .modes = pmx_smii1_modes,
-       .mode_count = ARRAY_SIZE(pmx_smii1_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_i2c1_modes[] = {
-       {
-               .ids = AUTO_EXP_MODE,
-               .mask = 0x0,
-       },
-};
-
-struct pmx_dev spear320_pmx_i2c1 = {
-       .name = "i2c1",
-       .modes = pmx_i2c1_modes,
-       .mode_count = ARRAY_SIZE(pmx_i2c1_modes),
-       .enb_on_reset = 1,
-};
-
-/* pmx driver structure */
-static struct pmx_driver pmx_driver = {
-       .mode_reg = {.offset = MODE_CONFIG_REG, .mask = 0x00000007},
-       .mux_reg = {.offset = PAD_MUX_CONFIG_REG, .mask = 0x00007fff},
-};
-
 /* spear3xx shared irq */
 static struct shirq_dev_config shirq_ras1_config[] = {
        {
@@ -508,17 +147,250 @@ static struct spear_shirq shirq_intrcomm_ras = {
        },
 };
 
-/* Add spear320 specific devices here */
+/* DMAC platform data's slave info */
+struct pl08x_channel_data spear320_dma_info[] = {
+       {
+               .bus_id = "uart0_rx",
+               .min_signal = 2,
+               .max_signal = 2,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "uart0_tx",
+               .min_signal = 3,
+               .max_signal = 3,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ssp0_rx",
+               .min_signal = 8,
+               .max_signal = 8,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ssp0_tx",
+               .min_signal = 9,
+               .max_signal = 9,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "i2c0_rx",
+               .min_signal = 10,
+               .max_signal = 10,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "i2c0_tx",
+               .min_signal = 11,
+               .max_signal = 11,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "irda",
+               .min_signal = 12,
+               .max_signal = 12,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "adc",
+               .min_signal = 13,
+               .max_signal = 13,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "to_jpeg",
+               .min_signal = 14,
+               .max_signal = 14,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "from_jpeg",
+               .min_signal = 15,
+               .max_signal = 15,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ssp1_rx",
+               .min_signal = 0,
+               .max_signal = 0,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB2,
+       }, {
+               .bus_id = "ssp1_tx",
+               .min_signal = 1,
+               .max_signal = 1,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB2,
+       }, {
+               .bus_id = "ssp2_rx",
+               .min_signal = 2,
+               .max_signal = 2,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB2,
+       }, {
+               .bus_id = "ssp2_tx",
+               .min_signal = 3,
+               .max_signal = 3,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB2,
+       }, {
+               .bus_id = "uart1_rx",
+               .min_signal = 4,
+               .max_signal = 4,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB2,
+       }, {
+               .bus_id = "uart1_tx",
+               .min_signal = 5,
+               .max_signal = 5,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB2,
+       }, {
+               .bus_id = "uart2_rx",
+               .min_signal = 6,
+               .max_signal = 6,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB2,
+       }, {
+               .bus_id = "uart2_tx",
+               .min_signal = 7,
+               .max_signal = 7,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB2,
+       }, {
+               .bus_id = "i2c1_rx",
+               .min_signal = 8,
+               .max_signal = 8,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB2,
+       }, {
+               .bus_id = "i2c1_tx",
+               .min_signal = 9,
+               .max_signal = 9,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB2,
+       }, {
+               .bus_id = "i2c2_rx",
+               .min_signal = 10,
+               .max_signal = 10,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB2,
+       }, {
+               .bus_id = "i2c2_tx",
+               .min_signal = 11,
+               .max_signal = 11,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB2,
+       }, {
+               .bus_id = "i2s_rx",
+               .min_signal = 12,
+               .max_signal = 12,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB2,
+       }, {
+               .bus_id = "i2s_tx",
+               .min_signal = 13,
+               .max_signal = 13,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB2,
+       }, {
+               .bus_id = "rs485_rx",
+               .min_signal = 14,
+               .max_signal = 14,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB2,
+       }, {
+               .bus_id = "rs485_tx",
+               .min_signal = 15,
+               .max_signal = 15,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB2,
+       },
+};
+
+static struct pl022_ssp_controller spear320_ssp_data[] = {
+       {
+               .bus_id = 1,
+               .enable_dma = 1,
+               .dma_filter = pl08x_filter_id,
+               .dma_tx_param = "ssp1_tx",
+               .dma_rx_param = "ssp1_rx",
+               .num_chipselect = 2,
+       }, {
+               .bus_id = 2,
+               .enable_dma = 1,
+               .dma_filter = pl08x_filter_id,
+               .dma_tx_param = "ssp2_tx",
+               .dma_rx_param = "ssp2_rx",
+               .num_chipselect = 2,
+       }
+};
+
+static struct amba_pl011_data spear320_uart_data[] = {
+       {
+               .dma_filter = pl08x_filter_id,
+               .dma_tx_param = "uart1_tx",
+               .dma_rx_param = "uart1_rx",
+       }, {
+               .dma_filter = pl08x_filter_id,
+               .dma_tx_param = "uart2_tx",
+               .dma_rx_param = "uart2_rx",
+       },
+};
 
-/* spear320 routines */
-void __init spear320_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
-               u8 pmx_dev_count)
+/* Add SPEAr310 auxdata to pass platform data */
+static struct of_dev_auxdata spear320_auxdata_lookup[] __initdata = {
+       OF_DEV_AUXDATA("arm,pl022", SPEAR3XX_ICM1_SSP_BASE, NULL,
+                       &pl022_plat_data),
+       OF_DEV_AUXDATA("arm,pl080", SPEAR3XX_ICM3_DMA_BASE, NULL,
+                       &pl080_plat_data),
+       OF_DEV_AUXDATA("arm,pl022", SPEAR320_SSP0_BASE, NULL,
+                       &spear320_ssp_data[0]),
+       OF_DEV_AUXDATA("arm,pl022", SPEAR320_SSP1_BASE, NULL,
+                       &spear320_ssp_data[1]),
+       OF_DEV_AUXDATA("arm,pl011", SPEAR320_UART1_BASE, NULL,
+                       &spear320_uart_data[0]),
+       OF_DEV_AUXDATA("arm,pl011", SPEAR320_UART2_BASE, NULL,
+                       &spear320_uart_data[1]),
+       {}
+};
+
+static void __init spear320_dt_init(void)
 {
        void __iomem *base;
-       int ret = 0;
+       int ret;
+
+       pl080_plat_data.slave_channels = spear320_dma_info;
+       pl080_plat_data.num_slave_channels = ARRAY_SIZE(spear320_dma_info);
 
-       /* call spear3xx family common init function */
-       spear3xx_init();
+       of_platform_populate(NULL, of_default_bus_match_table,
+                       spear320_auxdata_lookup, NULL);
 
        /* shared irq registration */
        base = ioremap(SPEAR320_SOC_CONFIG_BASE, SZ_4K);
@@ -527,29 +399,40 @@ void __init spear320_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
                shirq_ras1.regs.base = base;
                ret = spear_shirq_register(&shirq_ras1);
                if (ret)
-                       printk(KERN_ERR "Error registering Shared IRQ 1\n");
+                       pr_err("Error registering Shared IRQ 1\n");
 
                /* shirq 3 */
                shirq_ras3.regs.base = base;
                ret = spear_shirq_register(&shirq_ras3);
                if (ret)
-                       printk(KERN_ERR "Error registering Shared IRQ 3\n");
+                       pr_err("Error registering Shared IRQ 3\n");
 
                /* shirq 4 */
                shirq_intrcomm_ras.regs.base = base;
                ret = spear_shirq_register(&shirq_intrcomm_ras);
                if (ret)
-                       printk(KERN_ERR "Error registering Shared IRQ 4\n");
+                       pr_err("Error registering Shared IRQ 4\n");
        }
+}
 
-       /* pmx initialization */
-       pmx_driver.base = base;
-       pmx_driver.mode = pmx_mode;
-       pmx_driver.devs = pmx_devs;
-       pmx_driver.devs_count = pmx_dev_count;
+static const char * const spear320_dt_board_compat[] = {
+       "st,spear320",
+       "st,spear320-evb",
+       NULL,
+};
 
-       ret = pmx_register(&pmx_driver);
-       if (ret)
-               printk(KERN_ERR "padmux: registration failed. err no: %d\n",
-                               ret);
+static void __init spear320_map_io(void)
+{
+       spear3xx_map_io();
+       spear320_clk_init();
 }
+
+DT_MACHINE_START(SPEAR320_DT, "ST SPEAr320 SoC with Flattened Device Tree")
+       .map_io         =       spear320_map_io,
+       .init_irq       =       spear3xx_dt_init_irq,
+       .handle_irq     =       vic_handle_irq,
+       .timer          =       &spear3xx_timer,
+       .init_machine   =       spear320_dt_init,
+       .restart        =       spear_restart,
+       .dt_compat      =       spear320_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c
deleted file mode 100644 (file)
index 105334a..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * arch/arm/mach-spear3xx/spear320_evb.c
- *
- * SPEAr320 evaluation board source file
- *
- * Copyright (C) 2009 ST Microelectronics
- * Viresh Kumar<viresh.kumar@st.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <asm/hardware/vic.h>
-#include <asm/mach/arch.h>
-#include <asm/mach-types.h>
-#include <mach/generic.h>
-#include <mach/hardware.h>
-
-/* padmux devices to enable */
-static struct pmx_dev *pmx_devs[] = {
-       /* spear3xx specific devices */
-       &spear3xx_pmx_i2c,
-       &spear3xx_pmx_ssp,
-       &spear3xx_pmx_mii,
-       &spear3xx_pmx_uart0,
-
-       /* spear320 specific devices */
-       &spear320_pmx_fsmc,
-       &spear320_pmx_sdhci,
-       &spear320_pmx_i2s,
-       &spear320_pmx_uart1,
-       &spear320_pmx_uart2,
-       &spear320_pmx_can,
-       &spear320_pmx_pwm0,
-       &spear320_pmx_pwm1,
-       &spear320_pmx_pwm2,
-       &spear320_pmx_mii1,
-};
-
-static struct amba_device *amba_devs[] __initdata = {
-       /* spear3xx specific devices */
-       &spear3xx_gpio_device,
-       &spear3xx_uart_device,
-
-       /* spear320 specific devices */
-};
-
-static struct platform_device *plat_devs[] __initdata = {
-       /* spear3xx specific devices */
-
-       /* spear320 specific devices */
-};
-
-static void __init spear320_evb_init(void)
-{
-       unsigned int i;
-
-       /* call spear320 machine init function */
-       spear320_init(&spear320_auto_net_mii_mode, pmx_devs,
-                       ARRAY_SIZE(pmx_devs));
-
-       /* Add Platform Devices */
-       platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
-
-       /* Add Amba Devices */
-       for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
-               amba_device_register(amba_devs[i], &iomem_resource);
-}
-
-MACHINE_START(SPEAR320, "ST-SPEAR320-EVB")
-       .atag_offset    =       0x100,
-       .map_io         =       spear3xx_map_io,
-       .init_irq       =       spear3xx_init_irq,
-       .handle_irq     =       vic_handle_irq,
-       .timer          =       &spear3xx_timer,
-       .init_machine   =       spear320_evb_init,
-       .restart        =       spear_restart,
-MACHINE_END
index b1733c37f209d2f1d96f482d8aa2b9a2e5c3c397..12bf879a9ef146ff00f2c76ee03410f3339d36d8 100644 (file)
@@ -3,71 +3,78 @@
  *
  * SPEAr3XX machines common source file
  *
- * Copyright (C) 2009 ST Microelectronics
- * Viresh Kumar<viresh.kumar@st.com>
+ * Copyright (C) 2009-2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.com>
  *
  * This file is licensed under the terms of the GNU General Public
  * License version 2. This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
 
-#include <linux/types.h>
-#include <linux/amba/pl061.h>
-#include <linux/ptrace.h>
+#define pr_fmt(fmt) "SPEAr3xx: " fmt
+
+#include <linux/amba/pl022.h>
+#include <linux/amba/pl08x.h>
+#include <linux/of_irq.h>
 #include <linux/io.h>
+#include <asm/hardware/pl080.h>
 #include <asm/hardware/vic.h>
-#include <asm/irq.h>
-#include <asm/mach/arch.h>
+#include <plat/pl080.h>
 #include <mach/generic.h>
 #include <mach/hardware.h>
 
-/* Add spear3xx machines common devices here */
-/* gpio device registration */
-static struct pl061_platform_data gpio_plat_data = {
-       .gpio_base      = 0,
-       .irq_base       = SPEAR3XX_GPIO_INT_BASE,
+/* ssp device registration */
+struct pl022_ssp_controller pl022_plat_data = {
+       .bus_id = 0,
+       .enable_dma = 1,
+       .dma_filter = pl08x_filter_id,
+       .dma_tx_param = "ssp0_tx",
+       .dma_rx_param = "ssp0_rx",
+       /*
+        * This is number of spi devices that can be connected to spi. There are
+        * two type of chipselects on which slave devices can work. One is chip
+        * select provided by spi masters other is controlled through external
+        * gpio's. We can't use chipselect provided from spi master (because as
+        * soon as FIFO becomes empty, CS is disabled and transfer ends). So
+        * this number now depends on number of gpios available for spi. each
+        * slave on each master requires a separate gpio pin.
+        */
+       .num_chipselect = 2,
+};
+
+/* dmac device registration */
+struct pl08x_platform_data pl080_plat_data = {
+       .memcpy_channel = {
+               .bus_id = "memcpy",
+               .cctl = (PL080_BSIZE_16 << PL080_CONTROL_SB_SIZE_SHIFT | \
+                       PL080_BSIZE_16 << PL080_CONTROL_DB_SIZE_SHIFT | \
+                       PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT | \
+                       PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT | \
+                       PL080_CONTROL_PROT_BUFF | PL080_CONTROL_PROT_CACHE | \
+                       PL080_CONTROL_PROT_SYS),
+       },
+       .lli_buses = PL08X_AHB1,
+       .mem_buses = PL08X_AHB1,
+       .get_signal = pl080_get_signal,
+       .put_signal = pl080_put_signal,
 };
 
-AMBA_APB_DEVICE(spear3xx_gpio, "gpio", 0, SPEAR3XX_ICM3_GPIO_BASE,
-       {SPEAR3XX_IRQ_BASIC_GPIO}, &gpio_plat_data);
-
-/* uart device registration */
-AMBA_APB_DEVICE(spear3xx_uart, "uart", 0, SPEAR3XX_ICM1_UART_BASE,
-       {SPEAR3XX_IRQ_UART}, NULL);
-
-/* Do spear3xx familiy common initialization part here */
-void __init spear3xx_init(void)
-{
-       /* nothing to do for now */
-}
-
-/* This will initialize vic */
-void __init spear3xx_init_irq(void)
-{
-       vic_init((void __iomem *)VA_SPEAR3XX_ML1_VIC_BASE, 0, ~0, 0);
-}
-
-/* Following will create static virtual/physical mappings */
+/*
+ * Following will create 16MB static virtual/physical mappings
+ * PHYSICAL            VIRTUAL
+ * 0xD0000000          0xFD000000
+ * 0xFC000000          0xFC000000
+ */
 struct map_desc spear3xx_io_desc[] __initdata = {
        {
-               .virtual        = VA_SPEAR3XX_ICM1_UART_BASE,
-               .pfn            = __phys_to_pfn(SPEAR3XX_ICM1_UART_BASE),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE
-       }, {
-               .virtual        = VA_SPEAR3XX_ML1_VIC_BASE,
-               .pfn            = __phys_to_pfn(SPEAR3XX_ML1_VIC_BASE),
-               .length         = SZ_4K,
+               .virtual        = VA_SPEAR3XX_ICM1_2_BASE,
+               .pfn            = __phys_to_pfn(SPEAR3XX_ICM1_2_BASE),
+               .length         = SZ_16M,
                .type           = MT_DEVICE
        }, {
-               .virtual        = VA_SPEAR3XX_ICM3_SYS_CTRL_BASE,
-               .pfn            = __phys_to_pfn(SPEAR3XX_ICM3_SYS_CTRL_BASE),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE
-       }, {
-               .virtual        = VA_SPEAR3XX_ICM3_MISC_REG_BASE,
-               .pfn            = __phys_to_pfn(SPEAR3XX_ICM3_MISC_REG_BASE),
-               .length         = SZ_4K,
+               .virtual        = VA_SPEAR3XX_ICM3_SMI_CTRL_BASE,
+               .pfn            = __phys_to_pfn(SPEAR3XX_ICM3_SMI_CTRL_BASE),
+               .length         = SZ_16M,
                .type           = MT_DEVICE
        },
 };
@@ -76,436 +83,8 @@ struct map_desc spear3xx_io_desc[] __initdata = {
 void __init spear3xx_map_io(void)
 {
        iotable_init(spear3xx_io_desc, ARRAY_SIZE(spear3xx_io_desc));
-
-       /* This will initialize clock framework */
-       spear3xx_clk_init();
 }
 
-/* pad multiplexing support */
-/* devices */
-static struct pmx_dev_mode pmx_firda_modes[] = {
-       {
-               .ids = 0xffffffff,
-               .mask = PMX_FIRDA_MASK,
-       },
-};
-
-struct pmx_dev spear3xx_pmx_firda = {
-       .name = "firda",
-       .modes = pmx_firda_modes,
-       .mode_count = ARRAY_SIZE(pmx_firda_modes),
-       .enb_on_reset = 0,
-};
-
-static struct pmx_dev_mode pmx_i2c_modes[] = {
-       {
-               .ids = 0xffffffff,
-               .mask = PMX_I2C_MASK,
-       },
-};
-
-struct pmx_dev spear3xx_pmx_i2c = {
-       .name = "i2c",
-       .modes = pmx_i2c_modes,
-       .mode_count = ARRAY_SIZE(pmx_i2c_modes),
-       .enb_on_reset = 0,
-};
-
-static struct pmx_dev_mode pmx_ssp_cs_modes[] = {
-       {
-               .ids = 0xffffffff,
-               .mask = PMX_SSP_CS_MASK,
-       },
-};
-
-struct pmx_dev spear3xx_pmx_ssp_cs = {
-       .name = "ssp_chip_selects",
-       .modes = pmx_ssp_cs_modes,
-       .mode_count = ARRAY_SIZE(pmx_ssp_cs_modes),
-       .enb_on_reset = 0,
-};
-
-static struct pmx_dev_mode pmx_ssp_modes[] = {
-       {
-               .ids = 0xffffffff,
-               .mask = PMX_SSP_MASK,
-       },
-};
-
-struct pmx_dev spear3xx_pmx_ssp = {
-       .name = "ssp",
-       .modes = pmx_ssp_modes,
-       .mode_count = ARRAY_SIZE(pmx_ssp_modes),
-       .enb_on_reset = 0,
-};
-
-static struct pmx_dev_mode pmx_mii_modes[] = {
-       {
-               .ids = 0xffffffff,
-               .mask = PMX_MII_MASK,
-       },
-};
-
-struct pmx_dev spear3xx_pmx_mii = {
-       .name = "mii",
-       .modes = pmx_mii_modes,
-       .mode_count = ARRAY_SIZE(pmx_mii_modes),
-       .enb_on_reset = 0,
-};
-
-static struct pmx_dev_mode pmx_gpio_pin0_modes[] = {
-       {
-               .ids = 0xffffffff,
-               .mask = PMX_GPIO_PIN0_MASK,
-       },
-};
-
-struct pmx_dev spear3xx_pmx_gpio_pin0 = {
-       .name = "gpio_pin0",
-       .modes = pmx_gpio_pin0_modes,
-       .mode_count = ARRAY_SIZE(pmx_gpio_pin0_modes),
-       .enb_on_reset = 0,
-};
-
-static struct pmx_dev_mode pmx_gpio_pin1_modes[] = {
-       {
-               .ids = 0xffffffff,
-               .mask = PMX_GPIO_PIN1_MASK,
-       },
-};
-
-struct pmx_dev spear3xx_pmx_gpio_pin1 = {
-       .name = "gpio_pin1",
-       .modes = pmx_gpio_pin1_modes,
-       .mode_count = ARRAY_SIZE(pmx_gpio_pin1_modes),
-       .enb_on_reset = 0,
-};
-
-static struct pmx_dev_mode pmx_gpio_pin2_modes[] = {
-       {
-               .ids = 0xffffffff,
-               .mask = PMX_GPIO_PIN2_MASK,
-       },
-};
-
-struct pmx_dev spear3xx_pmx_gpio_pin2 = {
-       .name = "gpio_pin2",
-       .modes = pmx_gpio_pin2_modes,
-       .mode_count = ARRAY_SIZE(pmx_gpio_pin2_modes),
-       .enb_on_reset = 0,
-};
-
-static struct pmx_dev_mode pmx_gpio_pin3_modes[] = {
-       {
-               .ids = 0xffffffff,
-               .mask = PMX_GPIO_PIN3_MASK,
-       },
-};
-
-struct pmx_dev spear3xx_pmx_gpio_pin3 = {
-       .name = "gpio_pin3",
-       .modes = pmx_gpio_pin3_modes,
-       .mode_count = ARRAY_SIZE(pmx_gpio_pin3_modes),
-       .enb_on_reset = 0,
-};
-
-static struct pmx_dev_mode pmx_gpio_pin4_modes[] = {
-       {
-               .ids = 0xffffffff,
-               .mask = PMX_GPIO_PIN4_MASK,
-       },
-};
-
-struct pmx_dev spear3xx_pmx_gpio_pin4 = {
-       .name = "gpio_pin4",
-       .modes = pmx_gpio_pin4_modes,
-       .mode_count = ARRAY_SIZE(pmx_gpio_pin4_modes),
-       .enb_on_reset = 0,
-};
-
-static struct pmx_dev_mode pmx_gpio_pin5_modes[] = {
-       {
-               .ids = 0xffffffff,
-               .mask = PMX_GPIO_PIN5_MASK,
-       },
-};
-
-struct pmx_dev spear3xx_pmx_gpio_pin5 = {
-       .name = "gpio_pin5",
-       .modes = pmx_gpio_pin5_modes,
-       .mode_count = ARRAY_SIZE(pmx_gpio_pin5_modes),
-       .enb_on_reset = 0,
-};
-
-static struct pmx_dev_mode pmx_uart0_modem_modes[] = {
-       {
-               .ids = 0xffffffff,
-               .mask = PMX_UART0_MODEM_MASK,
-       },
-};
-
-struct pmx_dev spear3xx_pmx_uart0_modem = {
-       .name = "uart0_modem",
-       .modes = pmx_uart0_modem_modes,
-       .mode_count = ARRAY_SIZE(pmx_uart0_modem_modes),
-       .enb_on_reset = 0,
-};
-
-static struct pmx_dev_mode pmx_uart0_modes[] = {
-       {
-               .ids = 0xffffffff,
-               .mask = PMX_UART0_MASK,
-       },
-};
-
-struct pmx_dev spear3xx_pmx_uart0 = {
-       .name = "uart0",
-       .modes = pmx_uart0_modes,
-       .mode_count = ARRAY_SIZE(pmx_uart0_modes),
-       .enb_on_reset = 0,
-};
-
-static struct pmx_dev_mode pmx_timer_3_4_modes[] = {
-       {
-               .ids = 0xffffffff,
-               .mask = PMX_TIMER_3_4_MASK,
-       },
-};
-
-struct pmx_dev spear3xx_pmx_timer_3_4 = {
-       .name = "timer_3_4",
-       .modes = pmx_timer_3_4_modes,
-       .mode_count = ARRAY_SIZE(pmx_timer_3_4_modes),
-       .enb_on_reset = 0,
-};
-
-static struct pmx_dev_mode pmx_timer_1_2_modes[] = {
-       {
-               .ids = 0xffffffff,
-               .mask = PMX_TIMER_1_2_MASK,
-       },
-};
-
-struct pmx_dev spear3xx_pmx_timer_1_2 = {
-       .name = "timer_1_2",
-       .modes = pmx_timer_1_2_modes,
-       .mode_count = ARRAY_SIZE(pmx_timer_1_2_modes),
-       .enb_on_reset = 0,
-};
-
-#if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
-/* plgpios devices */
-static struct pmx_dev_mode pmx_plgpio_0_1_modes[] = {
-       {
-               .ids = 0x00,
-               .mask = PMX_FIRDA_MASK,
-       },
-};
-
-struct pmx_dev spear3xx_pmx_plgpio_0_1 = {
-       .name = "plgpio 0 and 1",
-       .modes = pmx_plgpio_0_1_modes,
-       .mode_count = ARRAY_SIZE(pmx_plgpio_0_1_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_plgpio_2_3_modes[] = {
-       {
-               .ids = 0x00,
-               .mask = PMX_UART0_MASK,
-       },
-};
-
-struct pmx_dev spear3xx_pmx_plgpio_2_3 = {
-       .name = "plgpio 2 and 3",
-       .modes = pmx_plgpio_2_3_modes,
-       .mode_count = ARRAY_SIZE(pmx_plgpio_2_3_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_plgpio_4_5_modes[] = {
-       {
-               .ids = 0x00,
-               .mask = PMX_I2C_MASK,
-       },
-};
-
-struct pmx_dev spear3xx_pmx_plgpio_4_5 = {
-       .name = "plgpio 4 and 5",
-       .modes = pmx_plgpio_4_5_modes,
-       .mode_count = ARRAY_SIZE(pmx_plgpio_4_5_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_plgpio_6_9_modes[] = {
-       {
-               .ids = 0x00,
-               .mask = PMX_SSP_MASK,
-       },
-};
-
-struct pmx_dev spear3xx_pmx_plgpio_6_9 = {
-       .name = "plgpio 6 to 9",
-       .modes = pmx_plgpio_6_9_modes,
-       .mode_count = ARRAY_SIZE(pmx_plgpio_6_9_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_plgpio_10_27_modes[] = {
-       {
-               .ids = 0x00,
-               .mask = PMX_MII_MASK,
-       },
-};
-
-struct pmx_dev spear3xx_pmx_plgpio_10_27 = {
-       .name = "plgpio 10 to 27",
-       .modes = pmx_plgpio_10_27_modes,
-       .mode_count = ARRAY_SIZE(pmx_plgpio_10_27_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_plgpio_28_modes[] = {
-       {
-               .ids = 0x00,
-               .mask = PMX_GPIO_PIN0_MASK,
-       },
-};
-
-struct pmx_dev spear3xx_pmx_plgpio_28 = {
-       .name = "plgpio 28",
-       .modes = pmx_plgpio_28_modes,
-       .mode_count = ARRAY_SIZE(pmx_plgpio_28_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_plgpio_29_modes[] = {
-       {
-               .ids = 0x00,
-               .mask = PMX_GPIO_PIN1_MASK,
-       },
-};
-
-struct pmx_dev spear3xx_pmx_plgpio_29 = {
-       .name = "plgpio 29",
-       .modes = pmx_plgpio_29_modes,
-       .mode_count = ARRAY_SIZE(pmx_plgpio_29_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_plgpio_30_modes[] = {
-       {
-               .ids = 0x00,
-               .mask = PMX_GPIO_PIN2_MASK,
-       },
-};
-
-struct pmx_dev spear3xx_pmx_plgpio_30 = {
-       .name = "plgpio 30",
-       .modes = pmx_plgpio_30_modes,
-       .mode_count = ARRAY_SIZE(pmx_plgpio_30_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_plgpio_31_modes[] = {
-       {
-               .ids = 0x00,
-               .mask = PMX_GPIO_PIN3_MASK,
-       },
-};
-
-struct pmx_dev spear3xx_pmx_plgpio_31 = {
-       .name = "plgpio 31",
-       .modes = pmx_plgpio_31_modes,
-       .mode_count = ARRAY_SIZE(pmx_plgpio_31_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_plgpio_32_modes[] = {
-       {
-               .ids = 0x00,
-               .mask = PMX_GPIO_PIN4_MASK,
-       },
-};
-
-struct pmx_dev spear3xx_pmx_plgpio_32 = {
-       .name = "plgpio 32",
-       .modes = pmx_plgpio_32_modes,
-       .mode_count = ARRAY_SIZE(pmx_plgpio_32_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_plgpio_33_modes[] = {
-       {
-               .ids = 0x00,
-               .mask = PMX_GPIO_PIN5_MASK,
-       },
-};
-
-struct pmx_dev spear3xx_pmx_plgpio_33 = {
-       .name = "plgpio 33",
-       .modes = pmx_plgpio_33_modes,
-       .mode_count = ARRAY_SIZE(pmx_plgpio_33_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_plgpio_34_36_modes[] = {
-       {
-               .ids = 0x00,
-               .mask = PMX_SSP_CS_MASK,
-       },
-};
-
-struct pmx_dev spear3xx_pmx_plgpio_34_36 = {
-       .name = "plgpio 34 to 36",
-       .modes = pmx_plgpio_34_36_modes,
-       .mode_count = ARRAY_SIZE(pmx_plgpio_34_36_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_plgpio_37_42_modes[] = {
-       {
-               .ids = 0x00,
-               .mask = PMX_UART0_MODEM_MASK,
-       },
-};
-
-struct pmx_dev spear3xx_pmx_plgpio_37_42 = {
-       .name = "plgpio 37 to 42",
-       .modes = pmx_plgpio_37_42_modes,
-       .mode_count = ARRAY_SIZE(pmx_plgpio_37_42_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_plgpio_43_44_47_48_modes[] = {
-       {
-               .ids = 0x00,
-               .mask = PMX_TIMER_1_2_MASK,
-       },
-};
-
-struct pmx_dev spear3xx_pmx_plgpio_43_44_47_48 = {
-       .name = "plgpio 43, 44, 47 and 48",
-       .modes = pmx_plgpio_43_44_47_48_modes,
-       .mode_count = ARRAY_SIZE(pmx_plgpio_43_44_47_48_modes),
-       .enb_on_reset = 1,
-};
-
-static struct pmx_dev_mode pmx_plgpio_45_46_49_50_modes[] = {
-       {
-               .ids = 0x00,
-               .mask = PMX_TIMER_3_4_MASK,
-       },
-};
-
-struct pmx_dev spear3xx_pmx_plgpio_45_46_49_50 = {
-       .name = "plgpio 45, 46, 49 and 50",
-       .modes = pmx_plgpio_45_46_49_50_modes,
-       .mode_count = ARRAY_SIZE(pmx_plgpio_45_46_49_50_modes),
-       .enb_on_reset = 1,
-};
-#endif /* CONFIG_MACH_SPEAR310 || CONFIG_MACH_SPEAR320 */
-
 static void __init spear3xx_timer_init(void)
 {
        char pclk_name[] = "pll3_48m_clk";
@@ -536,3 +115,13 @@ static void __init spear3xx_timer_init(void)
 struct sys_timer spear3xx_timer = {
        .init = spear3xx_timer_init,
 };
+
+static const struct of_device_id vic_of_match[] __initconst = {
+       { .compatible = "arm,pl190-vic", .data = vic_of_init, },
+       { /* Sentinel */ }
+};
+
+void __init spear3xx_dt_init_irq(void)
+{
+       of_irq_init(vic_of_match);
+}
index 4674a4c221dbcf58f9bc1b43a9fa97a0977d9489..af493da37ab6f111643359320fd792bdfeb85876 100644 (file)
@@ -1,3 +1,5 @@
 zreladdr-y     += 0x00008000
 params_phys-y  := 0x00000100
 initrd_phys-y  := 0x00800000
+
+dtb-$(CONFIG_BOARD_SPEAR600_DT)        += spear600-evb.dtb
index a86499a8a15f706f702671a93b3fb67f8a3bb25d..adadef2b27b4fbbd18b77bd8e785b960a95395f1 100644 (file)
@@ -623,53 +623,53 @@ static struct clk dummy_apb_pclk;
 
 /* array of all spear 6xx clock lookups */
 static struct clk_lookup spear_clk_lookups[] = {
-       { .con_id = "apb_pclk",         .clk = &dummy_apb_pclk},
+       CLKDEV_INIT(NULL, "apb_pclk", &dummy_apb_pclk),
        /* root clks */
-       { .con_id = "osc_32k_clk",      .clk = &osc_32k_clk},
-       { .con_id = "osc_30m_clk",      .clk = &osc_30m_clk},
+       CLKDEV_INIT(NULL, "osc_32k_clk", &osc_32k_clk),
+       CLKDEV_INIT(NULL, "osc_30m_clk", &osc_30m_clk),
        /* clock derived from 32 KHz os          clk */
-       { .dev_id = "rtc-spear",        .clk = &rtc_clk},
+       CLKDEV_INIT("rtc-spear", NULL, &rtc_clk),
        /* clock derived from 30 MHz os          clk */
-       { .con_id = "pll1_clk",         .clk = &pll1_clk},
-       { .con_id = "pll3_48m_clk",     .clk = &pll3_48m_clk},
-       { .dev_id = "wdt",              .clk = &wdt_clk},
+       CLKDEV_INIT(NULL, "pll1_clk", &pll1_clk),
+       CLKDEV_INIT(NULL, "pll3_48m_clk", &pll3_48m_clk),
+       CLKDEV_INIT("wdt", NULL, &wdt_clk),
        /* clock derived from pll1 clk */
-       { .con_id = "cpu_clk",          .clk = &cpu_clk},
-       { .con_id = "ahb_clk",          .clk = &ahb_clk},
-       { .con_id = "uart_synth_clk",   .clk = &uart_synth_clk},
-       { .con_id = "firda_synth_clk",  .clk = &firda_synth_clk},
-       { .con_id = "clcd_synth_clk",   .clk = &clcd_synth_clk},
-       { .con_id = "gpt0_synth_clk",   .clk = &gpt0_synth_clk},
-       { .con_id = "gpt2_synth_clk",   .clk = &gpt2_synth_clk},
-       { .con_id = "gpt3_synth_clk",   .clk = &gpt3_synth_clk},
-       { .dev_id = "d0000000.serial",  .clk = &uart0_clk},
-       { .dev_id = "d0080000.serial",  .clk = &uart1_clk},
-       { .dev_id = "firda",            .clk = &firda_clk},
-       { .dev_id = "clcd",             .clk = &clcd_clk},
-       { .dev_id = "gpt0",             .clk = &gpt0_clk},
-       { .dev_id = "gpt1",             .clk = &gpt1_clk},
-       { .dev_id = "gpt2",             .clk = &gpt2_clk},
-       { .dev_id = "gpt3",             .clk = &gpt3_clk},
+       CLKDEV_INIT(NULL, "cpu_clk", &cpu_clk),
+       CLKDEV_INIT(NULL, "ahb_clk", &ahb_clk),
+       CLKDEV_INIT(NULL, "uart_synth_clk", &uart_synth_clk),
+       CLKDEV_INIT(NULL, "firda_synth_clk", &firda_synth_clk),
+       CLKDEV_INIT(NULL, "clcd_synth_clk", &clcd_synth_clk),
+       CLKDEV_INIT(NULL, "gpt0_synth_clk", &gpt0_synth_clk),
+       CLKDEV_INIT(NULL, "gpt2_synth_clk", &gpt2_synth_clk),
+       CLKDEV_INIT(NULL, "gpt3_synth_clk", &gpt3_synth_clk),
+       CLKDEV_INIT("d0000000.serial", NULL, &uart0_clk),
+       CLKDEV_INIT("d0080000.serial", NULL, &uart1_clk),
+       CLKDEV_INIT("firda", NULL, &firda_clk),
+       CLKDEV_INIT("clcd", NULL, &clcd_clk),
+       CLKDEV_INIT("gpt0", NULL, &gpt0_clk),
+       CLKDEV_INIT("gpt1", NULL, &gpt1_clk),
+       CLKDEV_INIT("gpt2", NULL, &gpt2_clk),
+       CLKDEV_INIT("gpt3", NULL, &gpt3_clk),
        /* clock derived from pll3 clk */
-       { .dev_id = "designware_udc",   .clk = &usbd_clk},
-       { .con_id = "usbh.0_clk",       .clk = &usbh0_clk},
-       { .con_id = "usbh.1_clk",       .clk = &usbh1_clk},
+       CLKDEV_INIT("designware_udc", NULL, &usbd_clk),
+       CLKDEV_INIT(NULL, "usbh.0_clk", &usbh0_clk),
+       CLKDEV_INIT(NULL, "usbh.1_clk", &usbh1_clk),
        /* clock derived from ahb clk */
-       { .con_id = "apb_clk",          .clk = &apb_clk},
-       { .dev_id = "d0200000.i2c",     .clk = &i2c_clk},
-       { .dev_id = "dma",              .clk = &dma_clk},
-       { .dev_id = "jpeg",             .clk = &jpeg_clk},
-       { .dev_id = "gmac",             .clk = &gmac_clk},
-       { .dev_id = "smi",              .clk = &smi_clk},
-       { .dev_id = "fsmc-nand",        .clk = &fsmc_clk},
+       CLKDEV_INIT(NULL, "apb_clk", &apb_clk),
+       CLKDEV_INIT("d0200000.i2c", NULL, &i2c_clk),
+       CLKDEV_INIT("fc400000.dma", NULL, &dma_clk),
+       CLKDEV_INIT("jpeg", NULL, &jpeg_clk),
+       CLKDEV_INIT("gmac", NULL, &gmac_clk),
+       CLKDEV_INIT("fc000000.flash", NULL, &smi_clk),
+       CLKDEV_INIT("d1800000.flash", NULL, &fsmc_clk),
        /* clock derived from apb clk */
-       { .dev_id = "adc",              .clk = &adc_clk},
-       { .dev_id = "ssp-pl022.0",      .clk = &ssp0_clk},
-       { .dev_id = "ssp-pl022.1",      .clk = &ssp1_clk},
-       { .dev_id = "ssp-pl022.2",      .clk = &ssp2_clk},
-       { .dev_id = "f0100000.gpio",    .clk = &gpio0_clk},
-       { .dev_id = "fc980000.gpio",    .clk = &gpio1_clk},
-       { .dev_id = "d8100000.gpio",    .clk = &gpio2_clk},
+       CLKDEV_INIT("adc", NULL, &adc_clk),
+       CLKDEV_INIT("ssp-pl022.0", NULL, &ssp0_clk),
+       CLKDEV_INIT("ssp-pl022.1", NULL, &ssp1_clk),
+       CLKDEV_INIT("ssp-pl022.2", NULL, &ssp2_clk),
+       CLKDEV_INIT("f0100000.gpio", NULL, &gpio0_clk),
+       CLKDEV_INIT("fc980000.gpio", NULL, &gpio1_clk),
+       CLKDEV_INIT("d8100000.gpio", NULL, &gpio2_clk),
 };
 
 void __init spear6xx_clk_init(void)
index 2ed8b14c82c8a34d04b8e73eb7cdc1dc1ce6f5ec..5b9e30f54cdb8b0e514533dbf3518829960bb408 100644 (file)
  * warranty of any kind, whether express or implied.
  */
 
+#include <linux/amba/pl08x.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
+#include <asm/hardware/pl080.h>
 #include <asm/hardware/vic.h>
 #include <asm/mach/arch.h>
+#include <plat/pl080.h>
 #include <mach/generic.h>
 #include <mach/hardware.h>
 
+/* dmac device registration */
+static struct pl08x_channel_data spear600_dma_info[] = {
+       {
+               .bus_id = "ssp1_rx",
+               .min_signal = 0,
+               .max_signal = 0,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ssp1_tx",
+               .min_signal = 1,
+               .max_signal = 1,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "uart0_rx",
+               .min_signal = 2,
+               .max_signal = 2,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "uart0_tx",
+               .min_signal = 3,
+               .max_signal = 3,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "uart1_rx",
+               .min_signal = 4,
+               .max_signal = 4,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "uart1_tx",
+               .min_signal = 5,
+               .max_signal = 5,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ssp2_rx",
+               .min_signal = 6,
+               .max_signal = 6,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB2,
+       }, {
+               .bus_id = "ssp2_tx",
+               .min_signal = 7,
+               .max_signal = 7,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB2,
+       }, {
+               .bus_id = "ssp0_rx",
+               .min_signal = 8,
+               .max_signal = 8,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ssp0_tx",
+               .min_signal = 9,
+               .max_signal = 9,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "i2c_rx",
+               .min_signal = 10,
+               .max_signal = 10,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "i2c_tx",
+               .min_signal = 11,
+               .max_signal = 11,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "irda",
+               .min_signal = 12,
+               .max_signal = 12,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "adc",
+               .min_signal = 13,
+               .max_signal = 13,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB2,
+       }, {
+               .bus_id = "to_jpeg",
+               .min_signal = 14,
+               .max_signal = 14,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "from_jpeg",
+               .min_signal = 15,
+               .max_signal = 15,
+               .muxval = 0,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras0_rx",
+               .min_signal = 0,
+               .max_signal = 0,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras0_tx",
+               .min_signal = 1,
+               .max_signal = 1,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras1_rx",
+               .min_signal = 2,
+               .max_signal = 2,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras1_tx",
+               .min_signal = 3,
+               .max_signal = 3,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras2_rx",
+               .min_signal = 4,
+               .max_signal = 4,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras2_tx",
+               .min_signal = 5,
+               .max_signal = 5,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras3_rx",
+               .min_signal = 6,
+               .max_signal = 6,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras3_tx",
+               .min_signal = 7,
+               .max_signal = 7,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras4_rx",
+               .min_signal = 8,
+               .max_signal = 8,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras4_tx",
+               .min_signal = 9,
+               .max_signal = 9,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras5_rx",
+               .min_signal = 10,
+               .max_signal = 10,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras5_tx",
+               .min_signal = 11,
+               .max_signal = 11,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras6_rx",
+               .min_signal = 12,
+               .max_signal = 12,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras6_tx",
+               .min_signal = 13,
+               .max_signal = 13,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras7_rx",
+               .min_signal = 14,
+               .max_signal = 14,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ras7_tx",
+               .min_signal = 15,
+               .max_signal = 15,
+               .muxval = 1,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB1,
+       }, {
+               .bus_id = "ext0_rx",
+               .min_signal = 0,
+               .max_signal = 0,
+               .muxval = 2,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB2,
+       }, {
+               .bus_id = "ext0_tx",
+               .min_signal = 1,
+               .max_signal = 1,
+               .muxval = 2,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB2,
+       }, {
+               .bus_id = "ext1_rx",
+               .min_signal = 2,
+               .max_signal = 2,
+               .muxval = 2,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB2,
+       }, {
+               .bus_id = "ext1_tx",
+               .min_signal = 3,
+               .max_signal = 3,
+               .muxval = 2,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB2,
+       }, {
+               .bus_id = "ext2_rx",
+               .min_signal = 4,
+               .max_signal = 4,
+               .muxval = 2,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB2,
+       }, {
+               .bus_id = "ext2_tx",
+               .min_signal = 5,
+               .max_signal = 5,
+               .muxval = 2,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB2,
+       }, {
+               .bus_id = "ext3_rx",
+               .min_signal = 6,
+               .max_signal = 6,
+               .muxval = 2,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB2,
+       }, {
+               .bus_id = "ext3_tx",
+               .min_signal = 7,
+               .max_signal = 7,
+               .muxval = 2,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB2,
+       }, {
+               .bus_id = "ext4_rx",
+               .min_signal = 8,
+               .max_signal = 8,
+               .muxval = 2,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB2,
+       }, {
+               .bus_id = "ext4_tx",
+               .min_signal = 9,
+               .max_signal = 9,
+               .muxval = 2,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB2,
+       }, {
+               .bus_id = "ext5_rx",
+               .min_signal = 10,
+               .max_signal = 10,
+               .muxval = 2,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB2,
+       }, {
+               .bus_id = "ext5_tx",
+               .min_signal = 11,
+               .max_signal = 11,
+               .muxval = 2,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB2,
+       }, {
+               .bus_id = "ext6_rx",
+               .min_signal = 12,
+               .max_signal = 12,
+               .muxval = 2,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB2,
+       }, {
+               .bus_id = "ext6_tx",
+               .min_signal = 13,
+               .max_signal = 13,
+               .muxval = 2,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB2,
+       }, {
+               .bus_id = "ext7_rx",
+               .min_signal = 14,
+               .max_signal = 14,
+               .muxval = 2,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB2,
+       }, {
+               .bus_id = "ext7_tx",
+               .min_signal = 15,
+               .max_signal = 15,
+               .muxval = 2,
+               .cctl = 0,
+               .periph_buses = PL08X_AHB2,
+       },
+};
+
+struct pl08x_platform_data pl080_plat_data = {
+       .memcpy_channel = {
+               .bus_id = "memcpy",
+               .cctl = (PL080_BSIZE_16 << PL080_CONTROL_SB_SIZE_SHIFT | \
+                       PL080_BSIZE_16 << PL080_CONTROL_DB_SIZE_SHIFT | \
+                       PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT | \
+                       PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT | \
+                       PL080_CONTROL_PROT_BUFF | PL080_CONTROL_PROT_CACHE | \
+                       PL080_CONTROL_PROT_SYS),
+       },
+       .lli_buses = PL08X_AHB1,
+       .mem_buses = PL08X_AHB1,
+       .get_signal = pl080_get_signal,
+       .put_signal = pl080_put_signal,
+       .slave_channels = spear600_dma_info,
+       .num_slave_channels = ARRAY_SIZE(spear600_dma_info),
+};
+
 /* Following will create static virtual/physical mappings */
 static struct map_desc spear6xx_io_desc[] __initdata = {
        {
@@ -92,9 +454,17 @@ struct sys_timer spear6xx_timer = {
        .init = spear6xx_timer_init,
 };
 
+/* Add auxdata to pass platform data */
+struct of_dev_auxdata spear6xx_auxdata_lookup[] __initdata = {
+       OF_DEV_AUXDATA("arm,pl080", SPEAR6XX_ICM3_DMA_BASE, NULL,
+                       &pl080_plat_data),
+       {}
+};
+
 static void __init spear600_dt_init(void)
 {
-       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+       of_platform_populate(NULL, of_default_bus_match_table,
+                       spear6xx_auxdata_lookup, NULL);
 }
 
 static const char *spear600_dt_board_compat[] = {
index 880d02ec89d4e598afb2ef6014ab7f03e9b0a56f..ef7099eea0f29a6a593106c482154b37a2d1a4e5 100644 (file)
@@ -17,6 +17,7 @@ config UX500_SOC_DB5500
 config UX500_SOC_DB8500
        bool
        select MFD_DB8500_PRCMU
+       select REGULATOR
        select REGULATOR_DB8500_PRCMU
        select CPU_FREQ_TABLE if CPU_FREQ
 
index 465b9ec9510a298c336d3aa4c974f16df191310b..015932c6bf08e1c99ca45e41d113cbf4c91820c0 100644 (file)
@@ -3,7 +3,7 @@
 #
 
 obj-y                          := clock.o cpu.o devices.o devices-common.o \
-                                  id.o usb.o timer.o
+                                  id.o pins.o usb.o timer.o
 obj-$(CONFIG_CACHE_L2X0)       += cache-l2x0.o
 obj-$(CONFIG_UX500_SOC_DB5500) += cpu-db5500.o dma-db5500.o
 obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o
@@ -11,7 +11,8 @@ obj-$(CONFIG_MACH_MOP500)     += board-mop500.o board-mop500-sdi.o \
                                board-mop500-regulators.o \
                                board-mop500-uib.o board-mop500-stuib.o \
                                board-mop500-u8500uib.o \
-                               board-mop500-pins.o
+                               board-mop500-pins.o \
+                               board-mop500-msp.o
 obj-$(CONFIG_MACH_U5500)       += board-u5500.o board-u5500-sdi.o
 obj-$(CONFIG_SMP)              += platsmp.o headsmp.o
 obj-$(CONFIG_HOTPLUG_CPU)      += hotplug.o
diff --git a/arch/arm/mach-ux500/board-mop500-msp.c b/arch/arm/mach-ux500/board-mop500-msp.c
new file mode 100644 (file)
index 0000000..c8f6300
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <plat/gpio-nomadik.h>
+
+#include <plat/pincfg.h>
+#include <plat/ste_dma40.h>
+
+#include <mach/devices.h>
+#include <ste-dma40-db8500.h>
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <mach/msp.h>
+
+#include "board-mop500.h"
+#include "devices-db8500.h"
+#include "pins-db8500.h"
+
+/* MSP1/3 Tx/Rx usage protection */
+static DEFINE_SPINLOCK(msp_rxtx_lock);
+
+/* Reference Count */
+static int msp_rxtx_ref;
+
+static pin_cfg_t mop500_msp1_pins_init[] = {
+               GPIO33_MSP1_TXD | PIN_OUTPUT_LOW   | PIN_SLPM_WAKEUP_DISABLE,
+               GPIO34_MSP1_TFS | PIN_INPUT_NOPULL | PIN_SLPM_WAKEUP_DISABLE,
+               GPIO35_MSP1_TCK | PIN_INPUT_NOPULL | PIN_SLPM_WAKEUP_DISABLE,
+               GPIO36_MSP1_RXD | PIN_INPUT_NOPULL | PIN_SLPM_WAKEUP_DISABLE,
+};
+
+static pin_cfg_t mop500_msp1_pins_exit[] = {
+               GPIO33_MSP1_TXD | PIN_OUTPUT_LOW   | PIN_SLPM_WAKEUP_ENABLE,
+               GPIO34_MSP1_TFS | PIN_INPUT_NOPULL | PIN_SLPM_WAKEUP_ENABLE,
+               GPIO35_MSP1_TCK | PIN_INPUT_NOPULL | PIN_SLPM_WAKEUP_ENABLE,
+               GPIO36_MSP1_RXD | PIN_INPUT_NOPULL | PIN_SLPM_WAKEUP_ENABLE,
+};
+
+int msp13_i2s_init(void)
+{
+       int retval = 0;
+       unsigned long flags;
+
+       spin_lock_irqsave(&msp_rxtx_lock, flags);
+       if (msp_rxtx_ref == 0)
+               retval = nmk_config_pins(
+                               ARRAY_AND_SIZE(mop500_msp1_pins_init));
+       if (!retval)
+               msp_rxtx_ref++;
+       spin_unlock_irqrestore(&msp_rxtx_lock, flags);
+
+       return retval;
+}
+
+int msp13_i2s_exit(void)
+{
+       int retval = 0;
+       unsigned long flags;
+
+       spin_lock_irqsave(&msp_rxtx_lock, flags);
+       WARN_ON(!msp_rxtx_ref);
+       msp_rxtx_ref--;
+       if (msp_rxtx_ref == 0)
+               retval = nmk_config_pins_sleep(
+                               ARRAY_AND_SIZE(mop500_msp1_pins_exit));
+       spin_unlock_irqrestore(&msp_rxtx_lock, flags);
+
+       return retval;
+}
+
+static struct stedma40_chan_cfg msp0_dma_rx = {
+       .high_priority = true,
+       .dir = STEDMA40_PERIPH_TO_MEM,
+
+       .src_dev_type = DB8500_DMA_DEV31_MSP0_RX_SLIM0_CH0_RX,
+       .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
+
+       .src_info.psize = STEDMA40_PSIZE_LOG_4,
+       .dst_info.psize = STEDMA40_PSIZE_LOG_4,
+
+       /* data_width is set during configuration */
+};
+
+static struct stedma40_chan_cfg msp0_dma_tx = {
+       .high_priority = true,
+       .dir = STEDMA40_MEM_TO_PERIPH,
+
+       .src_dev_type = STEDMA40_DEV_DST_MEMORY,
+       .dst_dev_type = DB8500_DMA_DEV31_MSP0_TX_SLIM0_CH0_TX,
+
+       .src_info.psize = STEDMA40_PSIZE_LOG_4,
+       .dst_info.psize = STEDMA40_PSIZE_LOG_4,
+
+       /* data_width is set during configuration */
+};
+
+static struct msp_i2s_platform_data msp0_platform_data = {
+       .id = MSP_I2S_0,
+       .msp_i2s_dma_rx = &msp0_dma_rx,
+       .msp_i2s_dma_tx = &msp0_dma_tx,
+};
+
+static struct stedma40_chan_cfg msp1_dma_rx = {
+       .high_priority = true,
+       .dir = STEDMA40_PERIPH_TO_MEM,
+
+       .src_dev_type = DB8500_DMA_DEV30_MSP3_RX,
+       .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
+
+       .src_info.psize = STEDMA40_PSIZE_LOG_4,
+       .dst_info.psize = STEDMA40_PSIZE_LOG_4,
+
+       /* data_width is set during configuration */
+};
+
+static struct stedma40_chan_cfg msp1_dma_tx = {
+       .high_priority = true,
+       .dir = STEDMA40_MEM_TO_PERIPH,
+
+       .src_dev_type = STEDMA40_DEV_DST_MEMORY,
+       .dst_dev_type = DB8500_DMA_DEV30_MSP1_TX,
+
+       .src_info.psize = STEDMA40_PSIZE_LOG_4,
+       .dst_info.psize = STEDMA40_PSIZE_LOG_4,
+
+       /* data_width is set during configuration */
+};
+
+static struct msp_i2s_platform_data msp1_platform_data = {
+       .id = MSP_I2S_1,
+       .msp_i2s_dma_rx = NULL,
+       .msp_i2s_dma_tx = &msp1_dma_tx,
+       .msp_i2s_init = msp13_i2s_init,
+       .msp_i2s_exit = msp13_i2s_exit,
+};
+
+static struct stedma40_chan_cfg msp2_dma_rx = {
+       .high_priority = true,
+       .dir = STEDMA40_PERIPH_TO_MEM,
+
+       .src_dev_type = DB8500_DMA_DEV14_MSP2_RX,
+       .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
+
+       /* MSP2 DMA doesn't work with PSIZE == 4 on DB8500v2 */
+       .src_info.psize = STEDMA40_PSIZE_LOG_1,
+       .dst_info.psize = STEDMA40_PSIZE_LOG_1,
+
+       /* data_width is set during configuration */
+};
+
+static struct stedma40_chan_cfg msp2_dma_tx = {
+       .high_priority = true,
+       .dir = STEDMA40_MEM_TO_PERIPH,
+
+       .src_dev_type = STEDMA40_DEV_DST_MEMORY,
+       .dst_dev_type = DB8500_DMA_DEV14_MSP2_TX,
+
+       .src_info.psize = STEDMA40_PSIZE_LOG_4,
+       .dst_info.psize = STEDMA40_PSIZE_LOG_4,
+
+       .use_fixed_channel = true,
+       .phy_channel = 1,
+
+       /* data_width is set during configuration */
+};
+
+static int db8500_add_msp_i2s(struct device *parent, int id,
+                       resource_size_t base, int irq,
+                       struct msp_i2s_platform_data *pdata)
+{
+       struct platform_device *pdev;
+       struct resource res[] = {
+               DEFINE_RES_MEM(base, SZ_4K),
+               DEFINE_RES_IRQ(irq),
+       };
+
+       pr_info("Register platform-device 'ux500-msp-i2s', id %d, irq %d\n",
+               id, irq);
+       pdev = platform_device_register_resndata(parent, "ux500-msp-i2s", id,
+                                               res, ARRAY_SIZE(res),
+                                               pdata, sizeof(*pdata));
+       if (!pdev) {
+               pr_err("Failed to register platform-device 'ux500-msp-i2s.%d'!\n",
+                       id);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+/* Platform device for ASoC U8500 machine */
+static struct platform_device snd_soc_u8500 = {
+               .name = "snd-soc-u8500",
+               .id = 0,
+               .dev = {
+                       .platform_data = NULL,
+               },
+};
+
+/* Platform device for Ux500-PCM */
+static struct platform_device ux500_pcm = {
+               .name = "ux500-pcm",
+               .id = 0,
+               .dev = {
+                       .platform_data = NULL,
+               },
+};
+
+static struct msp_i2s_platform_data msp2_platform_data = {
+       .id = MSP_I2S_2,
+       .msp_i2s_dma_rx = &msp2_dma_rx,
+       .msp_i2s_dma_tx = &msp2_dma_tx,
+};
+
+static struct msp_i2s_platform_data msp3_platform_data = {
+       .id             = MSP_I2S_3,
+       .msp_i2s_dma_rx = &msp1_dma_rx,
+       .msp_i2s_dma_tx = NULL,
+       .msp_i2s_init = msp13_i2s_init,
+       .msp_i2s_exit = msp13_i2s_exit,
+};
+
+int mop500_msp_init(struct device *parent)
+{
+       int ret;
+
+       pr_info("%s: Register platform-device 'snd-soc-u8500'.\n", __func__);
+       platform_device_register(&snd_soc_u8500);
+
+       pr_info("Initialize MSP I2S-devices.\n");
+       ret = db8500_add_msp_i2s(parent, 0, U8500_MSP0_BASE, IRQ_DB8500_MSP0,
+                               &msp0_platform_data);
+       ret |= db8500_add_msp_i2s(parent, 1, U8500_MSP1_BASE, IRQ_DB8500_MSP1,
+                               &msp1_platform_data);
+       ret |= db8500_add_msp_i2s(parent, 2, U8500_MSP2_BASE, IRQ_DB8500_MSP2,
+                               &msp2_platform_data);
+       ret |= db8500_add_msp_i2s(parent, 3, U8500_MSP3_BASE, IRQ_DB8500_MSP1,
+                               &msp3_platform_data);
+
+       pr_info("%s: Register platform-device 'ux500-pcm'\n", __func__);
+       platform_device_register(&ux500_pcm);
+
+       return ret;
+}
diff --git a/arch/arm/mach-ux500/board-mop500-msp.h b/arch/arm/mach-ux500/board-mop500-msp.h
new file mode 100644 (file)
index 0000000..6fcfb5e
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2012
+ *
+ * Author: Ola Lilja <ola.o.lilja@stericsson.com>,
+ *         for ST-Ericsson.
+ *
+ * License terms:
+ *
+ * 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.
+ */
+
+void mop500_msp_init(struct device *parent);
index f5413dca532cf61e1d183420ab587020811f344d..df5b190d331c8444f90769bdd850a34bfc0e99d8 100644 (file)
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/bug.h>
+#include <linux/string.h>
 
 #include <asm/mach-types.h>
 #include <plat/pincfg.h>
 #include <plat/gpio-nomadik.h>
+
 #include <mach/hardware.h>
 
 #include "pins-db8500.h"
+#include "pins.h"
+#include "board-mop500.h"
+
+enum custom_pin_cfg_t {
+       PINS_FOR_DEFAULT,
+       PINS_FOR_U9500,
+};
+
+static enum custom_pin_cfg_t pinsfor;
 
 static pin_cfg_t mop500_pins_common[] = {
-       /* I2C */
-       GPIO147_I2C0_SCL,
-       GPIO148_I2C0_SDA,
-       GPIO16_I2C1_SCL,
-       GPIO17_I2C1_SDA,
-       GPIO10_I2C2_SDA,
-       GPIO11_I2C2_SCL,
-       GPIO229_I2C3_SDA,
-       GPIO230_I2C3_SCL,
-
-       /* MSP0 */
+       /* uMSP0 */
        GPIO12_MSP0_TXD,
        GPIO13_MSP0_TFS,
        GPIO14_MSP0_TCK,
        GPIO15_MSP0_RXD,
 
        /* MSP2: HDMI */
-       GPIO193_MSP2_TXD,
-       GPIO194_MSP2_TCK,
-       GPIO195_MSP2_TFS,
+       GPIO193_MSP2_TXD | PIN_INPUT_PULLDOWN,
+       GPIO194_MSP2_TCK | PIN_INPUT_PULLDOWN,
+       GPIO195_MSP2_TFS | PIN_INPUT_PULLDOWN,
        GPIO196_MSP2_RXD | PIN_OUTPUT_LOW,
 
+       /* LCD TE0 */
+       GPIO68_LCD_VSI0 | PIN_INPUT_PULLUP,
+
        /* Touch screen INTERFACE */
        GPIO84_GPIO     | PIN_INPUT_PULLUP, /* TOUCH_INT1 */
 
        /* STMPE1601/tc35893 keypad  IRQ */
        GPIO218_GPIO    | PIN_INPUT_PULLUP,
 
-       /* MMC0 (MicroSD card) */
-       GPIO18_MC0_CMDDIR       | PIN_OUTPUT_HIGH,
-       GPIO19_MC0_DAT0DIR      | PIN_OUTPUT_HIGH,
-       GPIO20_MC0_DAT2DIR      | PIN_OUTPUT_HIGH,
-
-       GPIO22_MC0_FBCLK        | PIN_INPUT_NOPULL,
-       GPIO23_MC0_CLK          | PIN_OUTPUT_LOW,
-       GPIO24_MC0_CMD          | PIN_INPUT_PULLUP,
-       GPIO25_MC0_DAT0         | PIN_INPUT_PULLUP,
-       GPIO26_MC0_DAT1         | PIN_INPUT_PULLUP,
-       GPIO27_MC0_DAT2         | PIN_INPUT_PULLUP,
-       GPIO28_MC0_DAT3         | PIN_INPUT_PULLUP,
-
-       /* SDI1 (SDIO) */
-       GPIO208_MC1_CLK         | PIN_OUTPUT_LOW,
-       GPIO209_MC1_FBCLK       | PIN_INPUT_NOPULL,
-       GPIO210_MC1_CMD         | PIN_INPUT_PULLUP,
-       GPIO211_MC1_DAT0        | PIN_INPUT_PULLUP,
-       GPIO212_MC1_DAT1        | PIN_INPUT_PULLUP,
-       GPIO213_MC1_DAT2        | PIN_INPUT_PULLUP,
-       GPIO214_MC1_DAT3        | PIN_INPUT_PULLUP,
-
-       /* MMC2 (On-board DATA INTERFACE eMMC) */
-       GPIO128_MC2_CLK         | PIN_OUTPUT_LOW,
-       GPIO129_MC2_CMD         | PIN_INPUT_PULLUP,
-       GPIO130_MC2_FBCLK       | PIN_INPUT_NOPULL,
-       GPIO131_MC2_DAT0        | PIN_INPUT_PULLUP,
-       GPIO132_MC2_DAT1        | PIN_INPUT_PULLUP,
-       GPIO133_MC2_DAT2        | PIN_INPUT_PULLUP,
-       GPIO134_MC2_DAT3        | PIN_INPUT_PULLUP,
-       GPIO135_MC2_DAT4        | PIN_INPUT_PULLUP,
-       GPIO136_MC2_DAT5        | PIN_INPUT_PULLUP,
-       GPIO137_MC2_DAT6        | PIN_INPUT_PULLUP,
-       GPIO138_MC2_DAT7        | PIN_INPUT_PULLUP,
-
-       /* MMC4 (On-board STORAGE INTERFACE eMMC) */
-       GPIO197_MC4_DAT3        | PIN_INPUT_PULLUP,
-       GPIO198_MC4_DAT2        | PIN_INPUT_PULLUP,
-       GPIO199_MC4_DAT1        | PIN_INPUT_PULLUP,
-       GPIO200_MC4_DAT0        | PIN_INPUT_PULLUP,
-       GPIO201_MC4_CMD         | PIN_INPUT_PULLUP,
-       GPIO202_MC4_FBCLK       | PIN_INPUT_NOPULL,
-       GPIO203_MC4_CLK         | PIN_OUTPUT_LOW,
-       GPIO204_MC4_DAT7        | PIN_INPUT_PULLUP,
-       GPIO205_MC4_DAT6        | PIN_INPUT_PULLUP,
-       GPIO206_MC4_DAT5        | PIN_INPUT_PULLUP,
-       GPIO207_MC4_DAT4        | PIN_INPUT_PULLUP,
-
-       /* SKE keypad */
-       GPIO153_KP_I7,
-       GPIO154_KP_I6,
-       GPIO155_KP_I5,
-       GPIO156_KP_I4,
-       GPIO157_KP_O7,
-       GPIO158_KP_O6,
-       GPIO159_KP_O5,
-       GPIO160_KP_O4,
-       GPIO161_KP_I3,
-       GPIO162_KP_I2,
-       GPIO163_KP_I1,
-       GPIO164_KP_I0,
-       GPIO165_KP_O3,
-       GPIO166_KP_O2,
-       GPIO167_KP_O1,
-       GPIO168_KP_O0,
-
        /* UART */
        /* uart-0 pins gpio configuration should be
         * kept intact to prevent glitch in tx line
@@ -128,10 +66,6 @@ static pin_cfg_t mop500_pins_common[] = {
        GPIO30_U2_TXD   | PIN_OUTPUT_HIGH,
        GPIO31_U2_CTSn  | PIN_INPUT_PULLUP,
        GPIO32_U2_RTSn  | PIN_OUTPUT_HIGH,
-
-       /* Display & HDMI HW sync */
-       GPIO68_LCD_VSI0 | PIN_INPUT_PULLUP,
-       GPIO69_LCD_VSI1 | PIN_INPUT_PULLUP,
 };
 
 static pin_cfg_t mop500_pins_default[] = {
@@ -141,10 +75,13 @@ static pin_cfg_t mop500_pins_default[] = {
        GPIO145_SSP0_RXD | PIN_PULL_DOWN,
        GPIO146_SSP0_TXD,
 
+       /* XENON Flashgun INTERFACE */
+       GPIO6_IP_GPIO0  | PIN_INPUT_PULLUP,/* XENON_FLASH_ID */
+       GPIO7_IP_GPIO1  | PIN_INPUT_PULLUP,/* XENON_READY */
 
        GPIO217_GPIO    | PIN_INPUT_PULLUP, /* TC35892 IRQ */
 
-       /* SDI0 (MicroSD card) */
+       /* sdi0 (removable MMC/SD/SDIO cards) not handled by pm_runtime */
        GPIO21_MC0_DAT31DIR     | PIN_OUTPUT_HIGH,
 
        /* UART */
@@ -156,13 +93,11 @@ static pin_cfg_t mop500_pins_default[] = {
 
 static pin_cfg_t hrefv60_pins[] = {
        /* WLAN */
-       GPIO4_GPIO              | PIN_INPUT_PULLUP,/* WLAN_IRQ */
        GPIO85_GPIO             | PIN_OUTPUT_LOW,/* WLAN_ENA */
 
        /* XENON Flashgun INTERFACE */
        GPIO6_IP_GPIO0  | PIN_INPUT_PULLUP,/* XENON_FLASH_ID */
        GPIO7_IP_GPIO1  | PIN_INPUT_PULLUP,/* XENON_READY */
-       GPIO170_GPIO    | PIN_OUTPUT_LOW, /* XENON_CHARGE */
 
        /* Assistant LED INTERFACE */
        GPIO21_GPIO | PIN_OUTPUT_LOW,  /* XENON_EN1 */
@@ -173,7 +108,7 @@ static pin_cfg_t hrefv60_pins[] = {
        GPIO32_GPIO | PIN_INPUT_PULLDOWN, /* Magnetometer DRDY */
 
        /* Display Interface */
-       GPIO65_GPIO             | PIN_OUTPUT_LOW, /* DISP1 RST */
+       GPIO65_GPIO             | PIN_OUTPUT_HIGH, /* DISP1 NO RST */
        GPIO66_GPIO             | PIN_OUTPUT_LOW, /* DISP2 RST */
 
        /* Touch screen INTERFACE */
@@ -215,11 +150,8 @@ static pin_cfg_t hrefv60_pins[] = {
        /* DiPro Sensor Interface */
        GPIO139_GPIO    | PIN_INPUT_PULLUP, /* DIPRO_INT */
 
-       /* HAL SWITCH INTERFACE */
-       GPIO145_GPIO    | PIN_INPUT_PULLDOWN,/* HAL_SW */
-
        /* Audio Amplifier Interface */
-       GPIO149_GPIO    | PIN_OUTPUT_LOW, /* VAUDIO_HF_EN */
+       GPIO149_GPIO    | PIN_OUTPUT_HIGH, /* VAUDIO_HF_EN, enable MAX8968 */
 
        /* GBF INTERFACE */
        GPIO171_GPIO    | PIN_OUTPUT_LOW, /* GBF_ENA_RESET */
@@ -231,10 +163,29 @@ static pin_cfg_t hrefv60_pins[] = {
        GPIO82_GPIO             | PIN_INPUT_PULLUP, /* ACC_INT1 */
        GPIO83_GPIO             | PIN_INPUT_PULLUP, /* ACC_INT2 */
 
-       /* Proximity Sensor */
-       GPIO217_GPIO            | PIN_INPUT_PULLUP,
+       /* SD card detect */
+       GPIO95_GPIO     | PIN_INPUT_PULLUP,
+};
 
+static pin_cfg_t u9500_pins[] = {
+       GPIO4_U1_RXD    | PIN_INPUT_PULLUP,
+       GPIO5_U1_TXD    | PIN_OUTPUT_HIGH,
+       GPIO144_GPIO    | PIN_INPUT_PULLUP,/* WLAN_IRQ */
+
+       /* HSI */
+       GPIO219_HSIR_FLA0 | PIN_INPUT_PULLDOWN,
+       GPIO220_HSIR_DAT0 | PIN_INPUT_PULLDOWN,
+       GPIO221_HSIR_RDY0 | PIN_OUTPUT_LOW,
+       GPIO222_HSIT_FLA0 | PIN_OUTPUT_LOW,
+       GPIO223_HSIT_DAT0 | PIN_OUTPUT_LOW,
+       GPIO224_HSIT_RDY0 | PIN_INPUT_PULLDOWN,
+       GPIO225_HSIT_CAWAKE0 | PIN_INPUT_PULLDOWN, /* CA_WAKE0 */
+       GPIO226_GPIO    | PIN_OUTPUT_HIGH, /* AC_WAKE0 */
+};
 
+static pin_cfg_t u8500_pins[] = {
+       GPIO226_GPIO    | PIN_OUTPUT_LOW, /* WLAN_PMU_EN */
+       GPIO4_GPIO              | PIN_INPUT_PULLUP,/* WLAN_IRQ */
 };
 
 static pin_cfg_t snowball_pins[] = {
@@ -275,13 +226,245 @@ static pin_cfg_t snowball_pins[] = {
 
        /* RSTn_LAN */
        GPIO141_GPIO            | PIN_OUTPUT_HIGH,
+
+       /*  Accelerometer/Magnetometer */
+       GPIO163_GPIO            | PIN_INPUT_PULLUP, /* ACCEL_IRQ1 */
+       GPIO164_GPIO            | PIN_INPUT_PULLUP, /* ACCEL_IRQ2 */
+       GPIO165_GPIO            | PIN_INPUT_PULLUP, /* MAG_DRDY */
+
+       /* WLAN/GBF */
+       GPIO161_GPIO            | PIN_OUTPUT_LOW, /* WLAN_PMU_EN */
+       GPIO171_GPIO            | PIN_OUTPUT_HIGH,/* GBF_ENA */
+       GPIO215_GPIO            | PIN_OUTPUT_LOW,/* WLAN_ENA */
+       GPIO216_GPIO            | PIN_INPUT_PULLUP,/* WLAN_IRQ */
+};
+
+/*
+ * I2C
+ */
+
+static UX500_PINS(mop500_pins_i2c0,
+       GPIO147_I2C0_SCL |
+               PIN_SLPM_GPIO | PIN_SLPM_INPUT_NOPULL,
+       GPIO148_I2C0_SDA |
+               PIN_SLPM_GPIO | PIN_SLPM_INPUT_NOPULL,
+);
+
+static UX500_PINS(mop500_pins_i2c1,
+       GPIO16_I2C1_SCL |
+               PIN_SLPM_GPIO | PIN_SLPM_INPUT_NOPULL,
+       GPIO17_I2C1_SDA |
+               PIN_SLPM_GPIO | PIN_SLPM_INPUT_NOPULL,
+);
+
+static UX500_PINS(mop500_pins_i2c2,
+       GPIO10_I2C2_SDA |
+               PIN_SLPM_GPIO | PIN_SLPM_INPUT_NOPULL,
+       GPIO11_I2C2_SCL |
+               PIN_SLPM_GPIO | PIN_SLPM_INPUT_NOPULL,
+);
+
+static UX500_PINS(mop500_pins_i2c3,
+       GPIO229_I2C3_SDA |
+               PIN_SLPM_GPIO | PIN_SLPM_INPUT_NOPULL,
+       GPIO230_I2C3_SCL |
+               PIN_SLPM_GPIO | PIN_SLPM_INPUT_NOPULL,
+);
+
+static UX500_PINS(mop500_pins_mcde_tvout,
+       GPIO78_LCD_D8,
+       GPIO79_LCD_D9,
+       GPIO80_LCD_D10,
+       GPIO81_LCD_D11,
+       GPIO150_LCDA_CLK,
+);
+
+static UX500_PINS(mop500_pins_mcde_hdmi,
+       GPIO69_LCD_VSI1 | PIN_INPUT_PULLUP,
+);
+
+static UX500_PINS(mop500_pins_ske,
+       GPIO153_KP_I7 | PIN_INPUT_PULLDOWN | PIN_SLPM_INPUT_PULLUP,
+       GPIO154_KP_I6 | PIN_INPUT_PULLDOWN | PIN_SLPM_INPUT_PULLUP,
+       GPIO155_KP_I5 | PIN_INPUT_PULLDOWN | PIN_SLPM_INPUT_PULLUP,
+       GPIO156_KP_I4 | PIN_INPUT_PULLDOWN | PIN_SLPM_INPUT_PULLUP,
+       GPIO161_KP_I3 | PIN_INPUT_PULLDOWN | PIN_SLPM_INPUT_PULLUP,
+       GPIO162_KP_I2 | PIN_INPUT_PULLDOWN | PIN_SLPM_INPUT_PULLUP,
+       GPIO163_KP_I1 | PIN_INPUT_PULLDOWN | PIN_SLPM_INPUT_PULLUP,
+       GPIO164_KP_I0 | PIN_INPUT_PULLDOWN | PIN_SLPM_INPUT_PULLUP,
+       GPIO157_KP_O7 | PIN_INPUT_PULLUP | PIN_SLPM_OUTPUT_LOW,
+       GPIO158_KP_O6 | PIN_INPUT_PULLUP | PIN_SLPM_OUTPUT_LOW,
+       GPIO159_KP_O5 | PIN_INPUT_PULLUP | PIN_SLPM_OUTPUT_LOW,
+       GPIO160_KP_O4 | PIN_INPUT_PULLUP | PIN_SLPM_OUTPUT_LOW,
+       GPIO165_KP_O3 | PIN_INPUT_PULLUP | PIN_SLPM_OUTPUT_LOW,
+       GPIO166_KP_O2 | PIN_INPUT_PULLUP | PIN_SLPM_OUTPUT_LOW,
+       GPIO167_KP_O1 | PIN_INPUT_PULLUP | PIN_SLPM_OUTPUT_LOW,
+       GPIO168_KP_O0 | PIN_INPUT_PULLUP | PIN_SLPM_OUTPUT_LOW,
+);
+
+/* sdi0 (removable MMC/SD/SDIO cards) */
+static UX500_PINS(mop500_pins_sdi0,
+       GPIO18_MC0_CMDDIR       | PIN_OUTPUT_HIGH,
+       GPIO19_MC0_DAT0DIR      | PIN_OUTPUT_HIGH,
+       GPIO20_MC0_DAT2DIR      | PIN_OUTPUT_HIGH,
+
+       GPIO22_MC0_FBCLK        | PIN_INPUT_NOPULL,
+       GPIO23_MC0_CLK          | PIN_OUTPUT_LOW,
+       GPIO24_MC0_CMD          | PIN_INPUT_PULLUP,
+       GPIO25_MC0_DAT0         | PIN_INPUT_PULLUP,
+       GPIO26_MC0_DAT1         | PIN_INPUT_PULLUP,
+       GPIO27_MC0_DAT2         | PIN_INPUT_PULLUP,
+       GPIO28_MC0_DAT3         | PIN_INPUT_PULLUP,
+);
+
+/* sdi1 (WLAN CW1200) */
+static UX500_PINS(mop500_pins_sdi1,
+       GPIO208_MC1_CLK         | PIN_OUTPUT_LOW,
+       GPIO209_MC1_FBCLK       | PIN_INPUT_NOPULL,
+       GPIO210_MC1_CMD         | PIN_INPUT_PULLUP,
+       GPIO211_MC1_DAT0        | PIN_INPUT_PULLUP,
+       GPIO212_MC1_DAT1        | PIN_INPUT_PULLUP,
+       GPIO213_MC1_DAT2        | PIN_INPUT_PULLUP,
+       GPIO214_MC1_DAT3        | PIN_INPUT_PULLUP,
+);
+
+/* sdi2 (POP eMMC) */
+static UX500_PINS(mop500_pins_sdi2,
+       GPIO128_MC2_CLK         | PIN_OUTPUT_LOW,
+       GPIO129_MC2_CMD         | PIN_INPUT_PULLUP,
+       GPIO130_MC2_FBCLK       | PIN_INPUT_NOPULL,
+       GPIO131_MC2_DAT0        | PIN_INPUT_PULLUP,
+       GPIO132_MC2_DAT1        | PIN_INPUT_PULLUP,
+       GPIO133_MC2_DAT2        | PIN_INPUT_PULLUP,
+       GPIO134_MC2_DAT3        | PIN_INPUT_PULLUP,
+       GPIO135_MC2_DAT4        | PIN_INPUT_PULLUP,
+       GPIO136_MC2_DAT5        | PIN_INPUT_PULLUP,
+       GPIO137_MC2_DAT6        | PIN_INPUT_PULLUP,
+       GPIO138_MC2_DAT7        | PIN_INPUT_PULLUP,
+);
+
+/* sdi4 (PCB eMMC) */
+static UX500_PINS(mop500_pins_sdi4,
+       GPIO197_MC4_DAT3        | PIN_INPUT_PULLUP,
+       GPIO198_MC4_DAT2        | PIN_INPUT_PULLUP,
+       GPIO199_MC4_DAT1        | PIN_INPUT_PULLUP,
+       GPIO200_MC4_DAT0        | PIN_INPUT_PULLUP,
+       GPIO201_MC4_CMD         | PIN_INPUT_PULLUP,
+       GPIO202_MC4_FBCLK       | PIN_INPUT_NOPULL,
+       GPIO203_MC4_CLK         | PIN_OUTPUT_LOW,
+       GPIO204_MC4_DAT7        | PIN_INPUT_PULLUP,
+       GPIO205_MC4_DAT6        | PIN_INPUT_PULLUP,
+       GPIO206_MC4_DAT5        | PIN_INPUT_PULLUP,
+       GPIO207_MC4_DAT4        | PIN_INPUT_PULLUP,
+);
+
+/* USB */
+static UX500_PINS(mop500_pins_usb,
+       GPIO256_USB_NXT,
+       GPIO257_USB_STP         | PIN_OUTPUT_HIGH,
+       GPIO258_USB_XCLK,
+       GPIO259_USB_DIR,
+       GPIO260_USB_DAT7,
+       GPIO261_USB_DAT6,
+       GPIO262_USB_DAT5,
+       GPIO263_USB_DAT4,
+       GPIO264_USB_DAT3,
+       GPIO265_USB_DAT2,
+       GPIO266_USB_DAT1,
+       GPIO267_USB_DAT0,
+);
+
+/* SPI2 */
+static UX500_PINS(mop500_pins_spi2,
+       GPIO216_GPIO    | PIN_OUTPUT_HIGH,
+       GPIO218_SPI2_RXD        | PIN_INPUT_PULLDOWN,
+       GPIO215_SPI2_TXD        | PIN_OUTPUT_LOW,
+       GPIO217_SPI2_CLK        | PIN_OUTPUT_LOW,
+);
+
+static UX500_PINS(mop500_pins_sensors1p_v60,
+       GPIO217_GPIO| PIN_INPUT_PULLUP |
+                 PIN_SLPM_GPIO | PIN_SLPM_INPUT_NOPULL,
+       GPIO145_GPIO | PIN_INPUT_PULLDOWN |
+                 PIN_SLPM_GPIO | PIN_SLPM_INPUT_NOPULL,
+       GPIO139_GPIO | PIN_INPUT_PULLUP |
+                 PIN_SLPM_GPIO | PIN_SLPM_INPUT_NOPULL,
+);
+
+static UX500_PINS(mop500_pins_sensors1p,
+       PIN_CFG_INPUT(GPIO_PROX_SENSOR, GPIO, NOPULL),
+       PIN_CFG_INPUT(GPIO_HAL_SENSOR, GPIO, NOPULL),
+);
+
+static struct ux500_pin_lookup mop500_runtime_pins[] = {
+       PIN_LOOKUP("mcde-tvout", &mop500_pins_mcde_tvout),
+       PIN_LOOKUP("av8100-hdmi", &mop500_pins_mcde_hdmi),
+       PIN_LOOKUP("nmk-i2c.0", &mop500_pins_i2c0),
+       PIN_LOOKUP("nmk-i2c.1", &mop500_pins_i2c1),
+       PIN_LOOKUP("nmk-i2c.2", &mop500_pins_i2c2),
+       PIN_LOOKUP("nmk-i2c.3", &mop500_pins_i2c3),
+       PIN_LOOKUP("sdi0", &mop500_pins_sdi0),
+       PIN_LOOKUP("sdi1", &mop500_pins_sdi1),
+       PIN_LOOKUP("sdi2", &mop500_pins_sdi2),
+       PIN_LOOKUP("sdi4", &mop500_pins_sdi4),
+       PIN_LOOKUP("musb-ux500.0", &mop500_pins_usb),
+       PIN_LOOKUP("spi2", &mop500_pins_spi2),
 };
 
+static struct ux500_pin_lookup mop500_runtime_pins_v60[] = {
+       PIN_LOOKUP("ske", &mop500_pins_ske),
+       PIN_LOOKUP("gpio-keys.0", &mop500_pins_sensors1p_v60),
+};
+
+static struct ux500_pin_lookup mop500_runtime_pins_pre_v60[] = {
+       PIN_LOOKUP("ske", &mop500_pins_ske),
+       PIN_LOOKUP("gpio-keys.0", &mop500_pins_sensors1p),
+};
+
+/*
+ * passing "pinsfor=" in kernel cmdline allows for custom
+ * configuration of GPIOs on u8500 derived boards.
+ */
+static int __init early_pinsfor(char *p)
+{
+       pinsfor = PINS_FOR_DEFAULT;
+
+       if (strcmp(p, "u9500-21") == 0)
+               pinsfor = PINS_FOR_U9500;
+
+       return 0;
+}
+early_param("pinsfor", early_pinsfor);
+
+int pins_for_u9500(void)
+{
+       if (pinsfor == PINS_FOR_U9500)
+               return 1;
+
+       return 0;
+}
+
 void __init mop500_pins_init(void)
 {
        nmk_config_pins(mop500_pins_common,
                        ARRAY_SIZE(mop500_pins_common));
 
+       ux500_pins_add(mop500_runtime_pins, ARRAY_SIZE(mop500_runtime_pins));
+
+       ux500_pins_add(mop500_runtime_pins_pre_v60,
+                      ARRAY_SIZE(mop500_runtime_pins_pre_v60));
+
+       switch (pinsfor) {
+       case PINS_FOR_U9500:
+               nmk_config_pins(u9500_pins, ARRAY_SIZE(u9500_pins));
+               break;
+
+       case PINS_FOR_DEFAULT:
+               nmk_config_pins(u8500_pins, ARRAY_SIZE(u8500_pins));
+       default:
+               break;
+       }
+
        nmk_config_pins(mop500_pins_default,
                        ARRAY_SIZE(mop500_pins_default));
 }
@@ -291,8 +474,11 @@ void __init snowball_pins_init(void)
        nmk_config_pins(mop500_pins_common,
                        ARRAY_SIZE(mop500_pins_common));
 
-       nmk_config_pins(snowball_pins,
-                       ARRAY_SIZE(snowball_pins));
+       ux500_pins_add(mop500_runtime_pins, ARRAY_SIZE(mop500_runtime_pins));
+
+       nmk_config_pins(u8500_pins, ARRAY_SIZE(u8500_pins));
+
+       nmk_config_pins(snowball_pins, ARRAY_SIZE(snowball_pins));
 }
 
 void __init hrefv60_pins_init(void)
@@ -300,6 +486,22 @@ void __init hrefv60_pins_init(void)
        nmk_config_pins(mop500_pins_common,
                        ARRAY_SIZE(mop500_pins_common));
 
+       ux500_pins_add(mop500_runtime_pins, ARRAY_SIZE(mop500_runtime_pins));
+
+       ux500_pins_add(mop500_runtime_pins_v60,
+                      ARRAY_SIZE(mop500_runtime_pins_v60));
+
        nmk_config_pins(hrefv60_pins,
                        ARRAY_SIZE(hrefv60_pins));
+
+       switch (pinsfor) {
+       case PINS_FOR_U9500:
+               nmk_config_pins(u9500_pins, ARRAY_SIZE(u9500_pins));
+               break;
+
+       case PINS_FOR_DEFAULT:
+               nmk_config_pins(u8500_pins, ARRAY_SIZE(u8500_pins));
+       default:
+               break;
+       }
 }
index 77d03c1fbd04551982dd97dcf055ef520ca664ea..ca0d62599f70deec172cd66c8c55bfd246561fce 100644 (file)
@@ -53,6 +53,7 @@
 #include "devices-db8500.h"
 #include "board-mop500.h"
 #include "board-mop500-regulators.h"
+#include "board-mop500-msp.h"
 
 static struct gpio_led snowball_led_array[] = {
        {
@@ -631,6 +632,7 @@ static void __init mop500_init_machine(void)
        mop500_i2c_init(parent);
        mop500_sdi_init(parent);
        mop500_spi_init(parent);
+       mop500_msp_init(parent);
        mop500_uart_init(parent);
 
        i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices);
@@ -662,6 +664,7 @@ static void __init snowball_init_machine(void)
        mop500_i2c_init(parent);
        snowball_sdi_init(parent);
        mop500_spi_init(parent);
+       mop500_msp_init(parent);
        mop500_uart_init(parent);
 
        i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices);
@@ -699,6 +702,7 @@ static void __init hrefv60_init_machine(void)
        mop500_i2c_init(parent);
        hrefv60_sdi_init(parent);
        mop500_spi_init(parent);
+       mop500_msp_init(parent);
        mop500_uart_init(parent);
 
        i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices);
@@ -746,10 +750,22 @@ MACHINE_END
 #ifdef CONFIG_MACH_UX500_DT
 
 struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = {
+       /* Requires DMA and call-back bindings. */
        OF_DEV_AUXDATA("arm,pl011", 0x80120000, "uart0", &uart0_plat),
        OF_DEV_AUXDATA("arm,pl011", 0x80121000, "uart1", &uart1_plat),
        OF_DEV_AUXDATA("arm,pl011", 0x80007000, "uart2", &uart2_plat),
+       /* Requires DMA bindings. */
        OF_DEV_AUXDATA("arm,pl022", 0x80002000, "ssp0",  &ssp0_plat),
+       /* Requires clock name bindings. */
+       OF_DEV_AUXDATA("st,nomadik-gpio", 0x8012e000, "gpio.0", NULL),
+       OF_DEV_AUXDATA("st,nomadik-gpio", 0x8012e080, "gpio.1", NULL),
+       OF_DEV_AUXDATA("st,nomadik-gpio", 0x8000e000, "gpio.2", NULL),
+       OF_DEV_AUXDATA("st,nomadik-gpio", 0x8000e080, "gpio.3", NULL),
+       OF_DEV_AUXDATA("st,nomadik-gpio", 0x8000e100, "gpio.4", NULL),
+       OF_DEV_AUXDATA("st,nomadik-gpio", 0x8000e180, "gpio.5", NULL),
+       OF_DEV_AUXDATA("st,nomadik-gpio", 0x8011e000, "gpio.6", NULL),
+       OF_DEV_AUXDATA("st,nomadik-gpio", 0x8011e080, "gpio.7", NULL),
+       OF_DEV_AUXDATA("st,nomadik-gpio", 0xa03fe000, "gpio.8", NULL),
        {},
 };
 
index fdcfa8721bb4358e84c2b5d361f30b3ef5503f0e..91dc63fe101b80c16badbe64bfd422b20d03c83f 100644 (file)
@@ -7,6 +7,9 @@
 #ifndef __BOARD_MOP500_H
 #define __BOARD_MOP500_H
 
+/* For NOMADIK_NR_GPIO */
+#include <mach/irqs.h>
+
 /* Snowball specific GPIO assignments, this board has no GPIO expander */
 #define SNOWBALL_ACCEL_INT1_GPIO       163
 #define SNOWBALL_ACCEL_INT2_GPIO       164
@@ -73,6 +76,7 @@
 #define SNOWBALL_PME_ETH_GPIO          MOP500_AB8500_PIN_GPIO(24)      /* SYSCLKREQ7/GPIO24 */
 #define SNOWBALL_EN_3V3_ETH_GPIO       MOP500_AB8500_PIN_GPIO(26)      /* GPIO26 */
 
+struct device;
 struct i2c_board_info;
 
 extern void mop500_sdi_init(struct device *parent);
index ec35f0aa5665a99d23f11c73ec552ab6e83f3aca..700042cb66816990eabdef74d64e3d5b95b6f39c 100644 (file)
@@ -336,6 +336,7 @@ static DEFINE_PRCMU_CLK(uiccclk,    0x4, 1, UICCCLK); /* v1 */
  */
 
 /* Peripheral Cluster #1 */
+static DEFINE_PRCC_CLK(1, msp3,                11, 10, &clk_msp1clk);
 static DEFINE_PRCC_CLK(1, i2c4,                10, 9, &clk_i2cclk);
 static DEFINE_PRCC_CLK(1, gpio0,       9, -1, NULL);
 static DEFINE_PRCC_CLK(1, slimbus0,    8,  8, &clk_slimclk);
@@ -405,7 +406,7 @@ static struct clk_lookup u8500_clks[] = {
        CLK(slimbus0,   "slimbus0",     NULL),
        CLK(i2c2,       "nmk-i2c.2",    NULL),
        CLK(sdi0,       "sdi0",         NULL),
-       CLK(msp0,       "msp0",         NULL),
+       CLK(msp0,       "ux500-msp-i2s.0",      NULL),
        CLK(i2c1,       "nmk-i2c.1",    NULL),
        CLK(uart1,      "uart1",        NULL),
        CLK(uart0,      "uart0",        NULL),
@@ -455,7 +456,8 @@ static struct clk_lookup u8500_clks[] = {
        /* Peripheral Cluster #1 */
        CLK(i2c4,       "nmk-i2c.4",    NULL),
        CLK(spi3,       "spi3",         NULL),
-       CLK(msp1,       "msp1",         NULL),
+       CLK(msp1,       "ux500-msp-i2s.1",      NULL),
+       CLK(msp3,       "ux500-msp-i2s.3",      NULL),
 
        /* Peripheral Cluster #2 */
        CLK(gpio1,      "gpio.6",       NULL),
@@ -465,7 +467,7 @@ static struct clk_lookup u8500_clks[] = {
        CLK(spi0,       "spi0",         NULL),
        CLK(sdi3,       "sdi3",         NULL),
        CLK(sdi1,       "sdi1",         NULL),
-       CLK(msp2,       "msp2",         NULL),
+       CLK(msp2,       "ux500-msp-i2s.2",      NULL),
        CLK(sdi4,       "sdi4",         NULL),
        CLK(pwl,        "pwl",          NULL),
        CLK(spi1,       "spi1",         NULL),
index d11f3892a27dffe6a596a5c279ecdd355b44f280..f6522f9f129c93611460b17103a8c9d1229c23d9 100644 (file)
 
 void __iomem *_PRCMU_BASE;
 
+/*
+ * FIXME: Should we set up the GPIO domain here?
+ *
+ * The problem is that we cannot put the interrupt resources into the platform
+ * device until the irqdomain has been added. Right now, we set the GIC interrupt
+ * domain from init_irq(), then load the gpio driver from
+ * core_initcall(nmk_gpio_init) and add the platform devices from
+ * arch_initcall(customize_machine).
+ *
+ * This feels fragile because it depends on the gpio device getting probed
+ * _before_ any device uses the gpio interrupts.
+*/
 static const struct of_device_id ux500_dt_irq_match[] = {
        { .compatible = "arm,cortex-a9-gic", .data = gic_of_init, },
        {},
index 9fd93e9da529084146a8b1590f1dab8023c9c7d8..e22b78626068d412d31577adf1db254bcd1b915e 100644 (file)
@@ -34,7 +34,6 @@ db8500_add_ssp(struct device *parent, const char *name, resource_size_t base,
        return dbx500_add_amba_device(parent, name, base, irq, pdata, 0);
 }
 
-
 #define db8500_add_i2c0(parent, pdata) \
        dbx500_add_i2c(parent, 0, U8500_I2C0_BASE, IRQ_DB8500_I2C0, pdata)
 #define db8500_add_i2c1(parent, pdata) \
@@ -46,15 +45,6 @@ db8500_add_ssp(struct device *parent, const char *name, resource_size_t base,
 #define db8500_add_i2c4(parent, pdata) \
        dbx500_add_i2c(parent, 4, U8500_I2C4_BASE, IRQ_DB8500_I2C4, pdata)
 
-#define db8500_add_msp0_i2s(parent, pdata) \
-       dbx500_add_msp_i2s(parent, 0, U8500_MSP0_BASE, IRQ_DB8500_MSP0, pdata)
-#define db8500_add_msp1_i2s(parent, pdata) \
-       dbx500_add_msp_i2s(parent, 1, U8500_MSP1_BASE, IRQ_DB8500_MSP1, pdata)
-#define db8500_add_msp2_i2s(parent, pdata) \
-       dbx500_add_msp_i2s(parent, 2, U8500_MSP2_BASE, IRQ_DB8500_MSP2, pdata)
-#define db8500_add_msp3_i2s(parent, pdata) \
-       dbx500_add_msp_i2s(parent, 3, U8500_MSP3_BASE, IRQ_DB8500_MSP1, pdata)
-
 #define db8500_add_msp0_spi(parent, pdata) \
        dbx500_add_msp_spi(parent, "msp0", U8500_MSP0_BASE, \
                           IRQ_DB8500_MSP0, pdata)
diff --git a/arch/arm/mach-ux500/include/mach/msp.h b/arch/arm/mach-ux500/include/mach/msp.h
new file mode 100644 (file)
index 0000000..798be19
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL), version 2.
+ */
+
+#ifndef __MSP_H
+#define __MSP_H
+
+#include <plat/ste_dma40.h>
+
+enum msp_i2s_id {
+       MSP_I2S_0 = 0,
+       MSP_I2S_1,
+       MSP_I2S_2,
+       MSP_I2S_3,
+};
+
+/* Platform data structure for a MSP I2S-device */
+struct msp_i2s_platform_data {
+       enum msp_i2s_id id;
+       struct stedma40_chan_cfg *msp_i2s_dma_rx;
+       struct stedma40_chan_cfg *msp_i2s_dma_tx;
+       int (*msp_i2s_init) (void);
+       int (*msp_i2s_exit) (void);
+};
+
+#endif
index 8b1d1a7a679ec6ce643627cb34078b611dd0f2be..062c7acf4576643e5abb682175e847bc3b604bdd 100644 (file)
 
 #define GPIO4_GPIO             PIN_CFG(4, GPIO)
 #define GPIO4_U1_RXD           PIN_CFG(4, ALT_A)
-#define GPIO4_I2C4_SCL         PIN_CFG_INPUT(4, ALT_B, PULLUP)
+#define GPIO4_I2C4_SCL         PIN_CFG(4, ALT_B)
 #define GPIO4_IP_TRSTn         PIN_CFG(4, ALT_C)
 
 #define GPIO5_GPIO             PIN_CFG(5, GPIO)
 #define GPIO5_U1_TXD           PIN_CFG(5, ALT_A)
-#define GPIO5_I2C4_SDA         PIN_CFG_INPUT(5, ALT_B, PULLUP)
+#define GPIO5_I2C4_SDA         PIN_CFG(5, ALT_B)
 #define GPIO5_IP_GPIO6         PIN_CFG(5, ALT_C)
 
 #define GPIO6_GPIO             PIN_CFG(6, GPIO)
 #define GPIO6_U1_CTSn          PIN_CFG(6, ALT_A)
-#define GPIO6_I2C1_SCL         PIN_CFG_INPUT(6, ALT_B, PULLUP)
+#define GPIO6_I2C1_SCL         PIN_CFG(6, ALT_B)
 #define GPIO6_IP_GPIO0         PIN_CFG(6, ALT_C)
 
 #define GPIO7_GPIO             PIN_CFG(7, GPIO)
 #define GPIO7_U1_RTSn          PIN_CFG(7, ALT_A)
-#define GPIO7_I2C1_SDA         PIN_CFG_INPUT(7, ALT_B, PULLUP)
+#define GPIO7_I2C1_SDA         PIN_CFG(7, ALT_B)
 #define GPIO7_IP_GPIO1         PIN_CFG(7, ALT_C)
 
 #define GPIO8_GPIO             PIN_CFG(8, GPIO)
-#define GPIO8_IPI2C_SDA                PIN_CFG_INPUT(8, ALT_A, PULLUP)
-#define GPIO8_I2C2_SDA         PIN_CFG_INPUT(8, ALT_B, PULLUP)
+#define GPIO8_IPI2C_SDA                PIN_CFG(8, ALT_A)
+#define GPIO8_I2C2_SDA         PIN_CFG(8, ALT_B)
 
 #define GPIO9_GPIO             PIN_CFG(9, GPIO)
-#define GPIO9_IPI2C_SCL                PIN_CFG_INPUT(9, ALT_A, PULLUP)
-#define GPIO9_I2C2_SCL         PIN_CFG_INPUT(9, ALT_B, PULLUP)
+#define GPIO9_IPI2C_SCL                PIN_CFG(9, ALT_A)
+#define GPIO9_I2C2_SCL         PIN_CFG(9, ALT_B)
 
 #define GPIO10_GPIO            PIN_CFG(10, GPIO)
-#define GPIO10_IPI2C_SDA       PIN_CFG_INPUT(10, ALT_A, PULLUP)
-#define GPIO10_I2C2_SDA                PIN_CFG_INPUT(10, ALT_B, PULLUP)
+#define GPIO10_IPI2C_SDA       PIN_CFG(10, ALT_A)
+#define GPIO10_I2C2_SDA                PIN_CFG(10, ALT_B)
 #define GPIO10_IP_GPIO3                PIN_CFG(10, ALT_C)
 
 #define GPIO11_GPIO            PIN_CFG(11, GPIO)
-#define GPIO11_IPI2C_SCL       PIN_CFG_INPUT(11, ALT_A, PULLUP)
-#define GPIO11_I2C2_SCL                PIN_CFG_INPUT(11, ALT_B, PULLUP)
+#define GPIO11_IPI2C_SCL       PIN_CFG(11, ALT_A)
+#define GPIO11_I2C2_SCL                PIN_CFG(11, ALT_B)
 #define GPIO11_IP_GPIO2                PIN_CFG(11, ALT_C)
 
 #define GPIO12_GPIO            PIN_CFG(12, GPIO)
 
 #define GPIO16_GPIO            PIN_CFG(16, GPIO)
 #define GPIO16_MSP0_RFS                PIN_CFG(16, ALT_A)
-#define GPIO16_I2C1_SCL                PIN_CFG_INPUT(16, ALT_B, PULLUP)
+#define GPIO16_I2C1_SCL                PIN_CFG(16, ALT_B)
 #define GPIO16_SLIM0_DAT       PIN_CFG(16, ALT_C)
 
 #define GPIO17_GPIO            PIN_CFG(17, GPIO)
 #define GPIO17_MSP0_RCK                PIN_CFG(17, ALT_A)
-#define GPIO17_I2C1_SDA                PIN_CFG_INPUT(17, ALT_B, PULLUP)
+#define GPIO17_I2C1_SDA                PIN_CFG(17, ALT_B)
 #define GPIO17_SLIM0_CLK       PIN_CFG(17, ALT_C)
 
 #define GPIO18_GPIO            PIN_CFG(18, GPIO)
 #define GPIO146_SSP0_TXD       PIN_CFG(146, ALT_A)
 
 #define GPIO147_GPIO           PIN_CFG(147, GPIO)
-#define GPIO147_I2C0_SCL       PIN_CFG_INPUT(147, ALT_A, PULLUP)
+#define GPIO147_I2C0_SCL       PIN_CFG(147, ALT_A)
 
 #define GPIO148_GPIO           PIN_CFG(148, GPIO)
-#define GPIO148_I2C0_SDA       PIN_CFG_INPUT(148, ALT_A, PULLUP)
+#define GPIO148_I2C0_SDA       PIN_CFG(148, ALT_A)
 
 #define GPIO149_GPIO           PIN_CFG(149, GPIO)
 #define GPIO149_IP_GPIO0       PIN_CFG(149, ALT_A)
 #define GPIO152_KP_O9          PIN_CFG(152, ALT_C)
 
 #define GPIO153_GPIO           PIN_CFG(153, GPIO)
-#define GPIO153_KP_I7          PIN_CFG_INPUT(153, ALT_A, PULLDOWN)
+#define GPIO153_KP_I7          PIN_CFG(153, ALT_A)
 #define GPIO153_LCD_D24                PIN_CFG(153, ALT_B)
 #define GPIO153_U2_RXD         PIN_CFG(153, ALT_C)
 
 #define GPIO154_GPIO           PIN_CFG(154, GPIO)
-#define GPIO154_KP_I6          PIN_CFG_INPUT(154, ALT_A, PULLDOWN)
+#define GPIO154_KP_I6          PIN_CFG(154, ALT_A)
 #define GPIO154_LCD_D25                PIN_CFG(154, ALT_B)
 #define GPIO154_U2_TXD         PIN_CFG(154, ALT_C)
 
 #define GPIO155_GPIO           PIN_CFG(155, GPIO)
-#define GPIO155_KP_I5          PIN_CFG_INPUT(155, ALT_A, PULLDOWN)
+#define GPIO155_KP_I5          PIN_CFG(155, ALT_A)
 #define GPIO155_LCD_D26                PIN_CFG(155, ALT_B)
 #define GPIO155_STMAPE_CLK     PIN_CFG(155, ALT_C)
 
 #define GPIO156_GPIO           PIN_CFG(156, GPIO)
-#define GPIO156_KP_I4          PIN_CFG_INPUT(156, ALT_A, PULLDOWN)
+#define GPIO156_KP_I4          PIN_CFG(156, ALT_A)
 #define GPIO156_LCD_D27                PIN_CFG(156, ALT_B)
 #define GPIO156_STMAPE_DAT3    PIN_CFG(156, ALT_C)
 
 #define GPIO157_GPIO           PIN_CFG(157, GPIO)
-#define GPIO157_KP_O7          PIN_CFG_INPUT(157, ALT_A, PULLUP)
+#define GPIO157_KP_O7          PIN_CFG(157, ALT_A)
 #define GPIO157_LCD_D28                PIN_CFG(157, ALT_B)
 #define GPIO157_STMAPE_DAT2    PIN_CFG(157, ALT_C)
 
 #define GPIO158_GPIO           PIN_CFG(158, GPIO)
-#define GPIO158_KP_O6          PIN_CFG_INPUT(158, ALT_A, PULLUP)
+#define GPIO158_KP_O6          PIN_CFG(158, ALT_A)
 #define GPIO158_LCD_D29                PIN_CFG(158, ALT_B)
 #define GPIO158_STMAPE_DAT1    PIN_CFG(158, ALT_C)
 
 #define GPIO159_GPIO           PIN_CFG(159, GPIO)
-#define GPIO159_KP_O5          PIN_CFG_INPUT(159, ALT_A, PULLUP)
+#define GPIO159_KP_O5          PIN_CFG(159, ALT_A)
 #define GPIO159_LCD_D30                PIN_CFG(159, ALT_B)
 #define GPIO159_STMAPE_DAT0    PIN_CFG(159, ALT_C)
 
 #define GPIO160_GPIO           PIN_CFG(160, GPIO)
-#define GPIO160_KP_O4          PIN_CFG_INPUT(160, ALT_A, PULLUP)
+#define GPIO160_KP_O4          PIN_CFG(160, ALT_A)
 #define GPIO160_LCD_D31                PIN_CFG(160, ALT_B)
 #define GPIO160_NONE           PIN_CFG(160, ALT_C)
 
 #define GPIO161_GPIO           PIN_CFG(161, GPIO)
-#define GPIO161_KP_I3          PIN_CFG_INPUT(161, ALT_A, PULLDOWN)
+#define GPIO161_KP_I3          PIN_CFG(161, ALT_A)
 #define GPIO161_LCD_D32                PIN_CFG(161, ALT_B)
 #define GPIO161_UARTMOD_RXD    PIN_CFG(161, ALT_C)
 
 #define GPIO162_GPIO           PIN_CFG(162, GPIO)
-#define GPIO162_KP_I2          PIN_CFG_INPUT(162, ALT_A, PULLDOWN)
+#define GPIO162_KP_I2          PIN_CFG(162, ALT_A)
 #define GPIO162_LCD_D33                PIN_CFG(162, ALT_B)
 #define GPIO162_UARTMOD_TXD    PIN_CFG(162, ALT_C)
 
 #define GPIO163_GPIO           PIN_CFG(163, GPIO)
-#define GPIO163_KP_I1          PIN_CFG_INPUT(163, ALT_A, PULLDOWN)
+#define GPIO163_KP_I1          PIN_CFG(163, ALT_A)
 #define GPIO163_LCD_D34                PIN_CFG(163, ALT_B)
 #define GPIO163_STMMOD_CLK     PIN_CFG(163, ALT_C)
 
 #define GPIO164_GPIO           PIN_CFG(164, GPIO)
-#define GPIO164_KP_I0          PIN_CFG_INPUT(164, ALT_A, PULLUP)
+#define GPIO164_KP_I0          PIN_CFG(164, ALT_A)
 #define GPIO164_LCD_D35                PIN_CFG(164, ALT_B)
 #define GPIO164_STMMOD_DAT3    PIN_CFG(164, ALT_C)
 
 #define GPIO165_GPIO           PIN_CFG(165, GPIO)
-#define GPIO165_KP_O3          PIN_CFG_INPUT(165, ALT_A, PULLUP)
+#define GPIO165_KP_O3          PIN_CFG(165, ALT_A)
 #define GPIO165_LCD_D36                PIN_CFG(165, ALT_B)
 #define GPIO165_STMMOD_DAT2    PIN_CFG(165, ALT_C)
 
 #define GPIO166_GPIO           PIN_CFG(166, GPIO)
-#define GPIO166_KP_O2          PIN_CFG_INPUT(166, ALT_A, PULLUP)
+#define GPIO166_KP_O2          PIN_CFG(166, ALT_A)
 #define GPIO166_LCD_D37                PIN_CFG(166, ALT_B)
 #define GPIO166_STMMOD_DAT1    PIN_CFG(166, ALT_C)
 
 #define GPIO167_GPIO           PIN_CFG(167, GPIO)
-#define GPIO167_KP_O1          PIN_CFG_INPUT(167, ALT_A, PULLUP)
+#define GPIO167_KP_O1          PIN_CFG(167, ALT_A)
 #define GPIO167_LCD_D38                PIN_CFG(167, ALT_B)
 #define GPIO167_STMMOD_DAT0    PIN_CFG(167, ALT_C)
 
 #define GPIO168_GPIO           PIN_CFG(168, GPIO)
-#define GPIO168_KP_O0          PIN_CFG_INPUT(168, ALT_A, PULLUP)
+#define GPIO168_KP_O0          PIN_CFG(168, ALT_A)
 #define GPIO168_LCD_D39                PIN_CFG(168, ALT_B)
 #define GPIO168_NONE           PIN_CFG(168, ALT_C)
 
 #define GPIO216_GPIO           PIN_CFG(216, GPIO)
 #define GPIO216_MC1_DAT2DIR    PIN_CFG(216, ALT_A)
 #define GPIO216_MC3_CMDDIR     PIN_CFG(216, ALT_B)
-#define GPIO216_I2C3_SDA       PIN_CFG_INPUT(216, ALT_C, PULLUP)
+#define GPIO216_I2C3_SDA       PIN_CFG(216, ALT_C)
 #define GPIO216_SPI2_FRM       PIN_CFG(216, ALT_C)
 
 #define GPIO217_GPIO           PIN_CFG(217, GPIO)
 #define GPIO218_GPIO           PIN_CFG(218, GPIO)
 #define GPIO218_MC1_DAT31DIR   PIN_CFG(218, ALT_A)
 #define GPIO218_MC3_DAT0DIR    PIN_CFG(218, ALT_B)
-#define GPIO218_I2C3_SCL       PIN_CFG_INPUT(218, ALT_C, PULLUP)
+#define GPIO218_I2C3_SCL       PIN_CFG(218, ALT_C)
 #define GPIO218_SPI2_RXD       PIN_CFG(218, ALT_C)
 
 #define GPIO219_GPIO           PIN_CFG(219, GPIO)
 #define GPIO229_GPIO           PIN_CFG(229, GPIO)
 #define GPIO229_CLKOUT1                PIN_CFG(229, ALT_A)
 #define GPIO229_PWL            PIN_CFG(229, ALT_B)
-#define GPIO229_I2C3_SDA       PIN_CFG_INPUT(229, ALT_C, PULLUP)
+#define GPIO229_I2C3_SDA       PIN_CFG(229, ALT_C)
 
 #define GPIO230_GPIO           PIN_CFG(230, GPIO)
 #define GPIO230_CLKOUT2                PIN_CFG(230, ALT_A)
 #define GPIO230_PWL            PIN_CFG(230, ALT_B)
-#define GPIO230_I2C3_SCL       PIN_CFG_INPUT(230, ALT_C, PULLUP)
+#define GPIO230_I2C3_SCL       PIN_CFG(230, ALT_C)
 
 #define GPIO256_GPIO           PIN_CFG(256, GPIO)
 #define GPIO256_USB_NXT                PIN_CFG(256, ALT_A)
diff --git a/arch/arm/mach-ux500/pins.c b/arch/arm/mach-ux500/pins.c
new file mode 100644 (file)
index 0000000..38c1d47
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/device.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+#include <linux/err.h>
+#include <plat/pincfg.h>
+
+#include "pins.h"
+
+static LIST_HEAD(pin_lookups);
+static DEFINE_MUTEX(pin_lookups_mutex);
+static DEFINE_SPINLOCK(pins_lock);
+
+void __init ux500_pins_add(struct ux500_pin_lookup *pl, size_t num)
+{
+       mutex_lock(&pin_lookups_mutex);
+
+       while (num--) {
+               list_add_tail(&pl->node, &pin_lookups);
+               pl++;
+       }
+
+       mutex_unlock(&pin_lookups_mutex);
+}
+
+struct ux500_pins *ux500_pins_get(const char *name)
+{
+       struct ux500_pins *pins = NULL;
+       struct ux500_pin_lookup *pl;
+
+       mutex_lock(&pin_lookups_mutex);
+
+       list_for_each_entry(pl, &pin_lookups, node) {
+               if (!strcmp(pl->name, name)) {
+                       pins = pl->pins;
+                       goto out;
+               }
+       }
+
+out:
+       mutex_unlock(&pin_lookups_mutex);
+       return pins;
+}
+
+int ux500_pins_enable(struct ux500_pins *pins)
+{
+       unsigned long flags;
+       int ret = 0;
+
+       spin_lock_irqsave(&pins_lock, flags);
+
+       if (pins->usage++ == 0)
+               ret = nmk_config_pins(pins->cfg, pins->num);
+
+       spin_unlock_irqrestore(&pins_lock, flags);
+       return ret;
+}
+
+int ux500_pins_disable(struct ux500_pins *pins)
+{
+       unsigned long flags;
+       int ret = 0;
+
+       spin_lock_irqsave(&pins_lock, flags);
+
+       if (WARN_ON(pins->usage == 0))
+               goto out;
+
+       if (--pins->usage == 0)
+               ret = nmk_config_pins_sleep(pins->cfg, pins->num);
+
+out:
+       spin_unlock_irqrestore(&pins_lock, flags);
+       return ret;
+}
+
+void ux500_pins_put(struct ux500_pins *pins)
+{
+       WARN_ON(!pins);
+}
diff --git a/arch/arm/mach-ux500/pins.h b/arch/arm/mach-ux500/pins.h
new file mode 100644 (file)
index 0000000..0d36af2
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#ifndef __MACH_UX500_PINS_H
+#define __MACH_UX500_PINS_H
+
+#include <linux/list.h>
+#include <plat/pincfg.h>
+
+#define PIN_LOOKUP(_name, _pins)       \
+{                                      \
+       .name   = _name,                \
+       .pins   = _pins,                \
+}
+
+#define UX500_PINS(name, pins...)                      \
+struct ux500_pins name = {                             \
+       .cfg = (pin_cfg_t[]) {pins},                    \
+       .num = ARRAY_SIZE(((pin_cfg_t[]) {pins})),      \
+}
+
+struct ux500_pins {
+       int usage;
+       int num;
+       pin_cfg_t *cfg;
+};
+
+struct ux500_pin_lookup {
+       struct list_head        node;
+       const char              *name;
+       struct ux500_pins       *pins;
+};
+
+void __init ux500_pins_add(struct ux500_pin_lookup *pl, size_t num);
+void __init ux500_offchip_gpio_init(struct ux500_pins *pins);
+struct ux500_pins *ux500_pins_get(const char *name);
+int ux500_pins_enable(struct ux500_pins *pins);
+int ux500_pins_disable(struct ux500_pins *pins);
+void ux500_pins_put(struct ux500_pins *pins);
+int pins_for_u9500(void);
+
+#endif
index d2058ef8345fd4518874d2ab409ae3daa376d5df..eff5842f6232a8f7d0af9e29a87477508ce9f455 100644 (file)
@@ -99,7 +99,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
         */
        write_pen_release(cpu_logical_map(cpu));
 
-       gic_raise_softirq(cpumask_of(cpu), 1);
+       smp_send_reschedule(cpu);
 
        timeout = jiffies + (1 * HZ);
        while (time_before(jiffies, timeout)) {
index 9605bf227df9e9ebca2ccda718f8e4aa7a81c9f8..3e8b7f16fb7819716f62a6442a99b7ad7752ab03 100644 (file)
@@ -29,6 +29,7 @@
 #define NMK_GPIO_SLPC  0x1c
 #define NMK_GPIO_AFSLA 0x20
 #define NMK_GPIO_AFSLB 0x24
+#define NMK_GPIO_LOWEMI        0x28
 
 #define NMK_GPIO_RIMSC 0x40
 #define NMK_GPIO_FIMSC 0x44
index 22cb97d2d8adc0bc225458f43f7561e32f540734..c015133a7ad3f940986b32ad3ff0f803111a18f9 100644 (file)
@@ -24,6 +24,7 @@
  *     bit 16..18 - SLPM pull up/down state
  *     bit 19..20 - SLPM direction
  *     bit 21..22 - SLPM Value (if output)
+ *     bit 23..25 - PDIS value (if input)
  *
  * to facilitate the definition, the following macros are provided
  *
@@ -67,6 +68,10 @@ typedef unsigned long pin_cfg_t;
 /* These two replace the above in DB8500v2+ */
 #define PIN_SLPM_WAKEUP_ENABLE (NMK_GPIO_SLPM_WAKEUP_ENABLE << PIN_SLPM_SHIFT)
 #define PIN_SLPM_WAKEUP_DISABLE        (NMK_GPIO_SLPM_WAKEUP_DISABLE << PIN_SLPM_SHIFT)
+#define PIN_SLPM_USE_MUX_SETTINGS_IN_SLEEP PIN_SLPM_WAKEUP_DISABLE
+
+#define PIN_SLPM_GPIO  PIN_SLPM_WAKEUP_ENABLE /* In SLPM, pin is a gpio */
+#define PIN_SLPM_ALTFUNC PIN_SLPM_WAKEUP_DISABLE /* In SLPM, pin is altfunc */
 
 #define PIN_DIR_SHIFT          14
 #define PIN_DIR_MASK           (0x1 << PIN_DIR_SHIFT)
@@ -105,6 +110,20 @@ typedef unsigned long pin_cfg_t;
 #define PIN_SLPM_VAL_LOW       ((1 + 0) << PIN_SLPM_VAL_SHIFT)
 #define PIN_SLPM_VAL_HIGH      ((1 + 1) << PIN_SLPM_VAL_SHIFT)
 
+#define PIN_SLPM_PDIS_SHIFT            23
+#define PIN_SLPM_PDIS_MASK             (0x3 << PIN_SLPM_PDIS_SHIFT)
+#define PIN_SLPM_PDIS(x)       \
+       (((x) & PIN_SLPM_PDIS_MASK) >> PIN_SLPM_PDIS_SHIFT)
+#define PIN_SLPM_PDIS_NO_CHANGE                (0 << PIN_SLPM_PDIS_SHIFT)
+#define PIN_SLPM_PDIS_DISABLED         (1 << PIN_SLPM_PDIS_SHIFT)
+#define PIN_SLPM_PDIS_ENABLED          (2 << PIN_SLPM_PDIS_SHIFT)
+
+#define PIN_LOWEMI_SHIFT       25
+#define PIN_LOWEMI_MASK                (0x1 << PIN_LOWEMI_SHIFT)
+#define PIN_LOWEMI(x)          (((x) & PIN_LOWEMI_MASK) >> PIN_LOWEMI_SHIFT)
+#define PIN_LOWEMI_DISABLED    (0 << PIN_LOWEMI_SHIFT)
+#define PIN_LOWEMI_ENABLED     (1 << PIN_LOWEMI_SHIFT)
+
 /* Shortcuts.  Use these instead of separate DIR, PULL, and VAL.  */
 #define PIN_INPUT_PULLDOWN     (PIN_DIR_INPUT | PIN_PULL_DOWN)
 #define PIN_INPUT_PULLUP       (PIN_DIR_INPUT | PIN_PULL_UP)
index 8070145ccb9802b951b6b2c124e5f4d562807db3..3f26db4ee8e671531bb4239acc60852cb0448295 100644 (file)
@@ -305,6 +305,7 @@ struct omap_hwmod_sysc_fields {
  * @rev_offs: IP block revision register offset (from module base addr)
  * @sysc_offs: OCP_SYSCONFIG register offset (from module base addr)
  * @syss_offs: OCP_SYSSTATUS register offset (from module base addr)
+ * @srst_udelay: Delay needed after doing a softreset in usecs
  * @idlemodes: One or more of {SIDLE,MSTANDBY}_{OFF,FORCE,SMART}
  * @sysc_flags: SYS{C,S}_HAS* flags indicating SYSCONFIG bits supported
  * @clockact: the default value of the module CLOCKACTIVITY bits
@@ -330,9 +331,10 @@ struct omap_hwmod_class_sysconfig {
        u16 sysc_offs;
        u16 syss_offs;
        u16 sysc_flags;
+       struct omap_hwmod_sysc_fields *sysc_fields;
+       u8 srst_udelay;
        u8 idlemodes;
        u8 clockact;
-       struct omap_hwmod_sysc_fields *sysc_fields;
 };
 
 /**
index eec98afa0f8328b2023f855879fa8a2ff34890ac..f9a8c5341ee93e41138f2adb5a6a6f4ce09d48d5 100644 (file)
@@ -348,7 +348,6 @@ u32 omap3_configure_core_dpll(u32 m2, u32 unlock_dll, u32 f, u32 inc,
                        sdrc_actim_ctrl_b_1, sdrc_mr_1);
 }
 
-#ifdef CONFIG_PM
 void omap3_sram_restore_context(void)
 {
        omap_sram_ceil = omap_sram_base + omap_sram_size;
@@ -358,17 +357,18 @@ void omap3_sram_restore_context(void)
                               omap3_sram_configure_core_dpll_sz);
        omap_push_sram_idle();
 }
-#endif /* CONFIG_PM */
-
-#endif /* CONFIG_ARCH_OMAP3 */
 
 static inline int omap34xx_sram_init(void)
 {
-#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
        omap3_sram_restore_context();
-#endif
        return 0;
 }
+#else
+static inline int omap34xx_sram_init(void)
+{
+       return 0;
+}
+#endif /* CONFIG_ARCH_OMAP3 */
 
 static inline int am33xx_sram_init(void)
 {
index 1bb3dbce88101fed9b09b0ef18f6fcd51ead7031..387655b5ce0593025e4a5b73194fa2033dc3965c 100644 (file)
@@ -9,9 +9,11 @@ choice
        default ARCH_SPEAR3XX
 
 config ARCH_SPEAR3XX
-       bool "SPEAr3XX"
+       bool "ST SPEAr3xx with Device Tree"
        select ARM_VIC
        select CPU_ARM926T
+       select USE_OF
+       select PINCTRL
        help
          Supports for ARM's SPEAR3XX family
 
index e0f2e5b9530c8390c264f5eba165aa6571e7120f..7744802c83e733d8c564b2ae63a3013126afb6ef 100644 (file)
@@ -3,6 +3,6 @@
 #
 
 # Common support
-obj-y  := clock.o restart.o time.o
+obj-y  := clock.o restart.o time.o pl080.o
 
-obj-$(CONFIG_ARCH_SPEAR3XX)    += shirq.o padmux.o
+obj-$(CONFIG_ARCH_SPEAR3XX)    += shirq.o
diff --git a/arch/arm/plat-spear/include/plat/padmux.h b/arch/arm/plat-spear/include/plat/padmux.h
deleted file mode 100644 (file)
index 877f3ad..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * arch/arm/plat-spear/include/plat/padmux.h
- *
- * SPEAr platform specific gpio pads muxing file
- *
- * Copyright (C) 2009 ST Microelectronics
- * Viresh Kumar<viresh.kumar@st.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#ifndef __PLAT_PADMUX_H
-#define __PLAT_PADMUX_H
-
-#include <linux/types.h>
-
-/*
- * struct pmx_reg: configuration structure for mode reg and mux reg
- *
- * offset: offset of mode reg
- * mask: mask of mode reg
- */
-struct pmx_reg {
-       u32 offset;
-       u32 mask;
-};
-
-/*
- * struct pmx_dev_mode: configuration structure every group of modes of a device
- *
- * ids: all modes for this configuration
- * mask: mask for supported mode
- */
-struct pmx_dev_mode {
-       u32 ids;
-       u32 mask;
-};
-
-/*
- * struct pmx_mode: mode definition structure
- *
- * name: mode name
- * mask: mode mask
- */
-struct pmx_mode {
-       char *name;
-       u32 id;
-       u32 mask;
-};
-
-/*
- * struct pmx_dev: device definition structure
- *
- * name: device name
- * modes: device configuration array for different modes supported
- * mode_count: size of modes array
- * is_active: is peripheral active/enabled
- * enb_on_reset: if 1, mask bits to be cleared in reg otherwise to be set in reg
- */
-struct pmx_dev {
-       char *name;
-       struct pmx_dev_mode *modes;
-       u8 mode_count;
-       bool is_active;
-       bool enb_on_reset;
-};
-
-/*
- * struct pmx_driver: driver definition structure
- *
- * mode: mode to be set
- * devs: array of pointer to pmx devices
- * devs_count: ARRAY_SIZE of devs
- * base: base address of soc config registers
- * mode_reg: structure of mode config register
- * mux_reg: structure of device mux config register
- */
-struct pmx_driver {
-       struct pmx_mode *mode;
-       struct pmx_dev **devs;
-       u8 devs_count;
-       u32 *base;
-       struct pmx_reg mode_reg;
-       struct pmx_reg mux_reg;
-};
-
-/* pmx functions */
-int pmx_register(struct pmx_driver *driver);
-
-#endif /* __PLAT_PADMUX_H */
diff --git a/arch/arm/plat-spear/include/plat/pl080.h b/arch/arm/plat-spear/include/plat/pl080.h
new file mode 100644 (file)
index 0000000..e14a3e4
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/plat-spear/include/plat/pl080.h
+ *
+ * DMAC pl080 definitions for SPEAr platform
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_PL080_H
+#define __PLAT_PL080_H
+
+struct pl08x_dma_chan;
+int pl080_get_signal(struct pl08x_dma_chan *ch);
+void pl080_put_signal(struct pl08x_dma_chan *ch);
+
+#endif /* __PLAT_PL080_H */
diff --git a/arch/arm/plat-spear/padmux.c b/arch/arm/plat-spear/padmux.c
deleted file mode 100644 (file)
index 555eec6..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * arch/arm/plat-spear/include/plat/padmux.c
- *
- * SPEAr platform specific gpio pads muxing source file
- *
- * Copyright (C) 2009 ST Microelectronics
- * Viresh Kumar<viresh.kumar@st.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <plat/padmux.h>
-
-/*
- * struct pmx: pmx definition structure
- *
- * base: base address of configuration registers
- * mode_reg: mode configurations
- * mux_reg: muxing configurations
- * active_mode: pointer to current active mode
- */
-struct pmx {
-       u32 base;
-       struct pmx_reg mode_reg;
-       struct pmx_reg mux_reg;
-       struct pmx_mode *active_mode;
-};
-
-static struct pmx *pmx;
-
-/**
- * pmx_mode_set - Enables an multiplexing mode
- * @mode - pointer to pmx mode
- *
- * It will set mode of operation in hardware.
- * Returns -ve on Err otherwise 0
- */
-static int pmx_mode_set(struct pmx_mode *mode)
-{
-       u32 val;
-
-       if (!mode->name)
-               return -EFAULT;
-
-       pmx->active_mode = mode;
-
-       val = readl(pmx->base + pmx->mode_reg.offset);
-       val &= ~pmx->mode_reg.mask;
-       val |= mode->mask & pmx->mode_reg.mask;
-       writel(val, pmx->base + pmx->mode_reg.offset);
-
-       return 0;
-}
-
-/**
- * pmx_devs_enable - Enables list of devices
- * @devs - pointer to pmx device array
- * @count - number of devices to enable
- *
- * It will enable pads for all required peripherals once and only once.
- * If peripheral is not supported by current mode then request is rejected.
- * Conflicts between peripherals are not handled and peripherals will be
- * enabled in the order they are present in pmx_dev array.
- * In case of conflicts last peripheral enabled will be present.
- * Returns -ve on Err otherwise 0
- */
-static int pmx_devs_enable(struct pmx_dev **devs, u8 count)
-{
-       u32 val, i, mask;
-
-       if (!count)
-               return -EINVAL;
-
-       val = readl(pmx->base + pmx->mux_reg.offset);
-       for (i = 0; i < count; i++) {
-               u8 j = 0;
-
-               if (!devs[i]->name || !devs[i]->modes) {
-                       printk(KERN_ERR "padmux: dev name or modes is null\n");
-                       continue;
-               }
-               /* check if peripheral exists in active mode */
-               if (pmx->active_mode) {
-                       bool found = false;
-                       for (j = 0; j < devs[i]->mode_count; j++) {
-                               if (devs[i]->modes[j].ids &
-                                               pmx->active_mode->id) {
-                                       found = true;
-                                       break;
-                               }
-                       }
-                       if (found == false) {
-                               printk(KERN_ERR "%s device not available in %s"\
-                                               "mode\n", devs[i]->name,
-                                               pmx->active_mode->name);
-                               continue;
-                       }
-               }
-
-               /* enable peripheral */
-               mask = devs[i]->modes[j].mask & pmx->mux_reg.mask;
-               if (devs[i]->enb_on_reset)
-                       val &= ~mask;
-               else
-                       val |= mask;
-
-               devs[i]->is_active = true;
-       }
-       writel(val, pmx->base + pmx->mux_reg.offset);
-       kfree(pmx);
-
-       /* this will ensure that multiplexing can't be changed now */
-       pmx = (struct pmx *)-1;
-
-       return 0;
-}
-
-/**
- * pmx_register - registers a platform requesting pad mux feature
- * @driver - pointer to driver structure containing driver specific parameters
- *
- * Also this must be called only once. This will allocate memory for pmx
- * structure, will call pmx_mode_set, will call pmx_devs_enable.
- * Returns -ve on Err otherwise 0
- */
-int pmx_register(struct pmx_driver *driver)
-{
-       int ret = 0;
-
-       if (pmx)
-               return -EPERM;
-       if (!driver->base || !driver->devs)
-               return -EFAULT;
-
-       pmx = kzalloc(sizeof(*pmx), GFP_KERNEL);
-       if (!pmx)
-               return -ENOMEM;
-
-       pmx->base = (u32)driver->base;
-       pmx->mode_reg.offset = driver->mode_reg.offset;
-       pmx->mode_reg.mask = driver->mode_reg.mask;
-       pmx->mux_reg.offset = driver->mux_reg.offset;
-       pmx->mux_reg.mask = driver->mux_reg.mask;
-
-       /* choose mode to enable */
-       if (driver->mode) {
-               ret = pmx_mode_set(driver->mode);
-               if (ret)
-                       goto pmx_fail;
-       }
-       ret = pmx_devs_enable(driver->devs, driver->devs_count);
-       if (ret)
-               goto pmx_fail;
-
-       return 0;
-
-pmx_fail:
-       return ret;
-}
diff --git a/arch/arm/plat-spear/pl080.c b/arch/arm/plat-spear/pl080.c
new file mode 100644 (file)
index 0000000..d53d75e
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * arch/arm/plat-spear/pl080.c
+ *
+ * DMAC pl080 definitions for SPEAr platform
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/amba/pl08x.h>
+#include <linux/amba/bus.h>
+#include <linux/bug.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/spinlock_types.h>
+#include <mach/misc_regs.h>
+
+static spinlock_t lock = __SPIN_LOCK_UNLOCKED(x);
+
+struct {
+       unsigned char busy;
+       unsigned char val;
+} signals[16] = {{0, 0}, };
+
+int pl080_get_signal(struct pl08x_dma_chan *ch)
+{
+       const struct pl08x_channel_data *cd = ch->cd;
+       unsigned int signal = cd->min_signal, val;
+       unsigned long flags;
+
+       spin_lock_irqsave(&lock, flags);
+
+       /* Return if signal is already acquired by somebody else */
+       if (signals[signal].busy &&
+                       (signals[signal].val != cd->muxval)) {
+               spin_unlock_irqrestore(&lock, flags);
+               return -EBUSY;
+       }
+
+       /* If acquiring for the first time, configure it */
+       if (!signals[signal].busy) {
+               val = readl(DMA_CHN_CFG);
+
+               /*
+                * Each request line has two bits in DMA_CHN_CFG register. To
+                * goto the bits of current request line, do left shift of
+                * value by 2 * signal number.
+                */
+               val &= ~(0x3 << (signal * 2));
+               val |= cd->muxval << (signal * 2);
+               writel(val, DMA_CHN_CFG);
+       }
+
+       signals[signal].busy++;
+       signals[signal].val = cd->muxval;
+       spin_unlock_irqrestore(&lock, flags);
+
+       return signal;
+}
+
+void pl080_put_signal(struct pl08x_dma_chan *ch)
+{
+       const struct pl08x_channel_data *cd = ch->cd;
+       unsigned long flags;
+
+       spin_lock_irqsave(&lock, flags);
+
+       /* if signal is not used */
+       if (!signals[cd->min_signal].busy)
+               BUG();
+
+       signals[cd->min_signal].busy--;
+
+       spin_unlock_irqrestore(&lock, flags);
+}
index 0ab82cc2dc8fe990f79d7db76f166b94e75b11d9..d2bf1fd5e44f5970caf455acdddc671fc0dee192 100644 (file)
@@ -106,15 +106,16 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
                return -EFAULT;
 
        {
-               register unsigned long r8 __asm ("r8") = 0;
+               register unsigned long r8 __asm ("r8");
                unsigned long prev;
                __asm__ __volatile__(
                        "       mf;;                                    \n"
-                       "       mov ar.ccv=%3;;                         \n"
-                       "[1:]   cmpxchg4.acq %0=[%1],%2,ar.ccv          \n"
+                       "       mov %0=r0                               \n"
+                       "       mov ar.ccv=%4;;                         \n"
+                       "[1:]   cmpxchg4.acq %1=[%2],%3,ar.ccv          \n"
                        "       .xdata4 \"__ex_table\", 1b-., 2f-.      \n"
                        "[2:]"
-                       : "=r" (prev)
+                       : "=r" (r8), "=r" (prev)
                        : "r" (uaddr), "r" (newval),
                          "rO" ((long) (unsigned) oldval)
                        : "memory");
index 9d0fd7d5bb82c03d65820a01b1af673c7b0c7c7e..f00ba025375d5696d0070bfe640b6f26f554eebd 100644 (file)
@@ -604,12 +604,6 @@ pfm_unprotect_ctx_ctxsw(pfm_context_t *x, unsigned long f)
        spin_unlock(&(x)->ctx_lock);
 }
 
-static inline unsigned int
-pfm_do_munmap(struct mm_struct *mm, unsigned long addr, size_t len, int acct)
-{
-       return do_munmap(mm, addr, len);
-}
-
 static inline unsigned long 
 pfm_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags, unsigned long exec)
 {
@@ -1458,8 +1452,9 @@ pfm_unreserve_session(pfm_context_t *ctx, int is_syswide, unsigned int cpu)
  * a PROTECT_CTX() section.
  */
 static int
-pfm_remove_smpl_mapping(struct task_struct *task, void *vaddr, unsigned long size)
+pfm_remove_smpl_mapping(void *vaddr, unsigned long size)
 {
+       struct task_struct *task = current;
        int r;
 
        /* sanity checks */
@@ -1473,13 +1468,8 @@ pfm_remove_smpl_mapping(struct task_struct *task, void *vaddr, unsigned long siz
        /*
         * does the actual unmapping
         */
-       down_write(&task->mm->mmap_sem);
+       r = vm_munmap((unsigned long)vaddr, size);
 
-       DPRINT(("down_write done smpl_vaddr=%p size=%lu\n", vaddr, size));
-
-       r = pfm_do_munmap(task->mm, (unsigned long)vaddr, size, 0);
-
-       up_write(&task->mm->mmap_sem);
        if (r !=0) {
                printk(KERN_ERR "perfmon: [%d] unable to unmap sampling buffer @%p size=%lu\n", task_pid_nr(task), vaddr, size);
        }
@@ -1945,7 +1935,7 @@ pfm_flush(struct file *filp, fl_owner_t id)
         * because some VM function reenables interrupts.
         *
         */
-       if (smpl_buf_vaddr) pfm_remove_smpl_mapping(current, smpl_buf_vaddr, smpl_buf_size);
+       if (smpl_buf_vaddr) pfm_remove_smpl_mapping(smpl_buf_vaddr, smpl_buf_size);
 
        return 0;
 }
index 33c32aeca12beb418955260a4f83a127ef900960..a1230e82bb1e5226c3d61968b1c625bbf40c6a17 100644 (file)
@@ -49,7 +49,6 @@ CONFIG_BLK_DEV_RAM=y
 CONFIG_NETDEVICES=y
 CONFIG_NET_ETHERNET=y
 CONFIG_FEC=y
-CONFIG_FEC2=y
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 CONFIG_PPP=y
index 7ed848c3b848784cf4d0067e35889ce4c857a0fd..f91a53294c357eebe80364a9a696a5993ab782f7 100644 (file)
@@ -74,9 +74,7 @@ static void __init m527x_fec_init(void)
        writew(par | 0xf00, MCF_IPSBAR + 0x100082);
        v = readb(MCF_IPSBAR + 0x100078);
        writeb(v | 0xc0, MCF_IPSBAR + 0x100078);
-#endif
 
-#ifdef CONFIG_FEC2
        /* Set multi-function pins to ethernet mode for fec1 */
        par = readw(MCF_IPSBAR + 0x100082);
        writew(par | 0xa0, MCF_IPSBAR + 0x100082);
index ee97735a242c5575c208c8391559b2e2fab98dce..b44d799b111500d9e4406227fd50ff85ac812830 100644 (file)
@@ -3,9 +3,3 @@
 #
 
 obj-y := config.o
-
-extra-y := bootlogo.rh
-
-$(obj)/bootlogo.rh: $(src)/bootlogo.h
-       perl $(src)/../68328/bootlogo.pl < $(src)/bootlogo.h \
-               > $(obj)/bootlogo.rh
index 447ffa0fd7c7a15759e06403a4c7eafe9fabbfb6..a49d75e654899a1adb229fb275290943ad0b3b94 100644 (file)
@@ -3,14 +3,9 @@
 #
 
 obj-y          := config.o
-logo-$(UCDIMM) := bootlogo.rh
-logo-$(DRAGEN2)        := screen.h
-extra-y                := $(logo-y)
-
-$(obj)/bootlogo.rh: $(src)/../68EZ328/bootlogo.h
-       perl $(src)/bootlogo.pl < $(src)/../68328/bootlogo.h > $(obj)/bootlogo.rh
+extra-$(DRAGEN2):= screen.h
 
 $(obj)/screen.h: $(src)/screen.xbm $(src)/xbm2lcd.pl
        perl $(src)/xbm2lcd.pl < $(src)/screen.xbm > $(obj)/screen.h
 
-clean-files := $(obj)/screen.h $(obj)/bootlogo.rh
+clean-files := $(obj)/screen.h
similarity index 99%
rename from arch/m68k/platform/68EZ328/bootlogo.h
rename to arch/m68k/platform/68VZ328/bootlogo.h
index e842bdae583935abdf4110875b60a97cdb552f96..b38e2b255142ef1cf6132f7293d7bb393a566864 100644 (file)
@@ -1,6 +1,6 @@
 #define splash_width 640
 #define splash_height 480
-static unsigned char splash_bits[] = {
+unsigned char __attribute__ ((aligned(16))) bootlogo_bits[] = {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
index fa50c48292ffafc7597afb073079dd79c3b6bb98..7af97362b95c3bb067ee939f35d50bcd0991ac4f 100644 (file)
@@ -114,7 +114,7 @@ static struct resource mcf_fec1_resources[] = {
 
 static struct platform_device mcf_fec1 = {
        .name                   = "fec",
-       .id                     = 0,
+       .id                     = 1,
        .num_resources          = ARRAY_SIZE(mcf_fec1_resources),
        .resource               = mcf_fec1_resources,
 };
index 2b7c0fbe578e3341a8d52e98f9cfced0a82023df..9015060919a0430cd5b8233081f2e12f4c3e2547 100644 (file)
@@ -90,7 +90,6 @@ config S390
        select HAVE_KERNEL_XZ
        select HAVE_ARCH_MUTEX_CPU_RELAX
        select HAVE_ARCH_JUMP_LABEL if !MARCH_G5
-       select HAVE_RCU_TABLE_FREE if SMP
        select ARCH_SAVE_PAGE_KEYS if HIBERNATION
        select HAVE_MEMBLOCK
        select HAVE_MEMBLOCK_NODE_MAP
index 6cf8e26b313780a4addc668018f3a658880be257..1957a9dd256d655400deca01f69e7530de33869d 100644 (file)
@@ -1,8 +1,12 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_FHANDLE=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
 CONFIG_AUDIT=y
-CONFIG_RCU_TRACE=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_CGROUPS=y
@@ -14,16 +18,22 @@ CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y
 CONFIG_CGROUP_SCHED=y
 CONFIG_RT_GROUP_SCHED=y
 CONFIG_BLK_CGROUP=y
+CONFIG_NAMESPACES=y
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_XZ=y
+CONFIG_RD_LZO=y
+CONFIG_EXPERT=y
 # CONFIG_COMPAT_BRK is not set
-CONFIG_SLAB=y
 CONFIG_PROFILING=y
 CONFIG_OPROFILE=y
 CONFIG_KPROBES=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODVERSIONS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_IBM_PARTITION=y
 CONFIG_DEFAULT_DEADLINE=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
@@ -34,18 +44,15 @@ CONFIG_KSM=y
 CONFIG_BINFMT_MISC=m
 CONFIG_CMM=m
 CONFIG_HZ_100=y
-CONFIG_KEXEC=y
-CONFIG_PM=y
+CONFIG_CRASH_DUMP=y
 CONFIG_HIBERNATION=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
 CONFIG_NET_KEY=y
-CONFIG_AFIUCV=m
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_INET_LRO is not set
 CONFIG_IPV6=y
-CONFIG_NET_SCTPPROBE=m
 CONFIG_L2TP=m
 CONFIG_L2TP_DEBUGFS=m
 CONFIG_VLAN_8021Q=y
@@ -84,15 +91,14 @@ CONFIG_SCSI_CONSTANTS=y
 CONFIG_SCSI_LOGGING=y
 CONFIG_SCSI_SCAN_ASYNC=y
 CONFIG_ZFCP=y
-CONFIG_ZFCP_DIF=y
 CONFIG_NETDEVICES=y
-CONFIG_DUMMY=m
 CONFIG_BONDING=m
+CONFIG_DUMMY=m
 CONFIG_EQUALIZER=m
 CONFIG_TUN=m
-CONFIG_NET_ETHERNET=y
 CONFIG_VIRTIO_NET=y
 CONFIG_RAW_DRIVER=m
+CONFIG_VIRTIO_BALLOON=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
@@ -103,27 +109,21 @@ CONFIG_PROC_KCORE=y
 CONFIG_TMPFS=y
 CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_NETWORK_FILESYSTEMS is not set
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_IBM_PARTITION=y
-CONFIG_DLM=m
 CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
 CONFIG_TIMER_STATS=y
 CONFIG_PROVE_LOCKING=y
 CONFIG_PROVE_RCU=y
 CONFIG_LOCK_STAT=y
 CONFIG_DEBUG_LOCKDEP=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
 CONFIG_DEBUG_LIST=y
 CONFIG_DEBUG_NOTIFIERS=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_RCU_TRACE=y
 CONFIG_KPROBES_SANITY_TEST=y
 CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
 CONFIG_CPU_NOTIFIER_ERROR_INJECT=m
 CONFIG_LATENCYTOP=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_DEBUG_PAGEALLOC=y
-# CONFIG_FTRACE is not set
+CONFIG_BLK_DEV_IO_TRACE=y
 # CONFIG_STRICT_DEVMEM is not set
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_CRYPTD=m
@@ -173,4 +173,3 @@ CONFIG_CRYPTO_SHA512_S390=m
 CONFIG_CRYPTO_DES_S390=m
 CONFIG_CRYPTO_AES_S390=m
 CONFIG_CRC7=m
-CONFIG_VIRTIO_BALLOON=y
index 1e5b27edc0c92e72e656485539391b579db8086a..2ee66a65f2d4740572791c46b9cf42a9c4e65d51 100644 (file)
@@ -38,12 +38,11 @@ static inline void stfle(u64 *stfle_fac_list, int size)
        unsigned long nr;
 
        preempt_disable();
-       S390_lowcore.stfl_fac_list = 0;
        asm volatile(
                "       .insn s,0xb2b10000,0(0)\n" /* stfl */
                "0:\n"
                EX_TABLE(0b, 0b)
-               : "=m" (S390_lowcore.stfl_fac_list));
+               : "+m" (S390_lowcore.stfl_fac_list));
        nr = 4; /* bytes stored by stfl */
        memcpy(stfle_fac_list, &S390_lowcore.stfl_fac_list, 4);
        if (S390_lowcore.stfl_fac_list & 0x01000000) {
index 8eef9b5b3cf440c35744ed5338240e39f777067a..78e3041919dedd11556ed359c40c1b2d875a197c 100644 (file)
@@ -22,10 +22,7 @@ void crst_table_free(struct mm_struct *, unsigned long *);
 
 unsigned long *page_table_alloc(struct mm_struct *, unsigned long);
 void page_table_free(struct mm_struct *, unsigned long *);
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
 void page_table_free_rcu(struct mmu_gather *, unsigned long *);
-void __tlb_remove_table(void *_table);
-#endif
 
 static inline void clear_table(unsigned long *s, unsigned long val, size_t n)
 {
index 6bdee21c077e0755ab0e0bc2084e118bdcb5e83f..a3e4ebb32090dc10ab0692f320c3ae3137f0f7dc 100644 (file)
@@ -77,7 +77,7 @@ static inline __u16 __arch_swab16p(const __u16 *x)
        
        asm volatile(
 #ifndef __s390x__
-               "       icm     %0,2,%O+1(%R1)\n"
+               "       icm     %0,2,%O1+1(%R1)\n"
                "       ic      %0,%1\n"
                : "=&d" (result) : "Q" (*x) : "cc");
 #else /* __s390x__ */
index c687a2c834626adb1f01cc24ae4f62713d83adaa..775a5eea8f9eb9896e9d38e809dc74d51823d99f 100644 (file)
 
 struct mmu_gather {
        struct mm_struct *mm;
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
        struct mmu_table_batch *batch;
-#endif
        unsigned int fullmm;
-       unsigned int need_flush;
 };
 
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
 struct mmu_table_batch {
        struct rcu_head         rcu;
        unsigned int            nr;
@@ -49,7 +45,6 @@ struct mmu_table_batch {
 
 extern void tlb_table_flush(struct mmu_gather *tlb);
 extern void tlb_remove_table(struct mmu_gather *tlb, void *table);
-#endif
 
 static inline void tlb_gather_mmu(struct mmu_gather *tlb,
                                  struct mm_struct *mm,
@@ -57,29 +52,20 @@ static inline void tlb_gather_mmu(struct mmu_gather *tlb,
 {
        tlb->mm = mm;
        tlb->fullmm = full_mm_flush;
-       tlb->need_flush = 0;
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
        tlb->batch = NULL;
-#endif
        if (tlb->fullmm)
                __tlb_flush_mm(mm);
 }
 
 static inline void tlb_flush_mmu(struct mmu_gather *tlb)
 {
-       if (!tlb->need_flush)
-               return;
-       tlb->need_flush = 0;
-       __tlb_flush_mm(tlb->mm);
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
        tlb_table_flush(tlb);
-#endif
 }
 
 static inline void tlb_finish_mmu(struct mmu_gather *tlb,
                                  unsigned long start, unsigned long end)
 {
-       tlb_flush_mmu(tlb);
+       tlb_table_flush(tlb);
 }
 
 /*
@@ -105,10 +91,8 @@ static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page)
 static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
                                unsigned long address)
 {
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
        if (!tlb->fullmm)
                return page_table_free_rcu(tlb, (unsigned long *) pte);
-#endif
        page_table_free(tlb->mm, (unsigned long *) pte);
 }
 
@@ -125,10 +109,8 @@ static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd,
 #ifdef __s390x__
        if (tlb->mm->context.asce_limit <= (1UL << 31))
                return;
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
        if (!tlb->fullmm)
                return tlb_remove_table(tlb, pmd);
-#endif
        crst_table_free(tlb->mm, (unsigned long *) pmd);
 #endif
 }
@@ -146,10 +128,8 @@ static inline void pud_free_tlb(struct mmu_gather *tlb, pud_t *pud,
 #ifdef __s390x__
        if (tlb->mm->context.asce_limit <= (1UL << 42))
                return;
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
        if (!tlb->fullmm)
                return tlb_remove_table(tlb, pud);
-#endif
        crst_table_free(tlb->mm, (unsigned long *) pud);
 #endif
 }
index c27a0727f9304cecf518aa310c70c33260fc3245..adccd908ebc773d51c8850897098c04af91b601d 100644 (file)
@@ -474,9 +474,9 @@ ENTRY(startup_kdump)
        stck    __LC_LAST_UPDATE_CLOCK
        spt     5f-.LPG0(%r13)
        mvc     __LC_LAST_UPDATE_TIMER(8),5f-.LPG0(%r13)
+       xc      __LC_STFL_FAC_LIST(8),__LC_STFL_FAC_LIST
 #ifndef CONFIG_MARCH_G5
        # check capabilities against MARCH_{G5,Z900,Z990,Z9_109,Z10}
-       xc      __LC_STFL_FAC_LIST(8),__LC_STFL_FAC_LIST
        .insn   s,0xb2b10000,__LC_STFL_FAC_LIST # store facility list
        tm      __LC_STFL_FAC_LIST,0x01 # stfle available ?
        jz      0f
index 1c2cdd59ccd0504469a1d31a45ba2aaf6442368b..8a22c27219dd0748f380a0aef0d63128b01ec21a 100644 (file)
@@ -118,9 +118,10 @@ asmlinkage void do_softirq(void)
                                         "a" (__do_softirq)
                                     : "0", "1", "2", "3", "4", "5", "14",
                                       "cc", "memory" );
-               } else
+               } else {
                        /* We are already on the async stack. */
                        __do_softirq();
+               }
        }
 
        local_irq_restore(flags);
@@ -192,11 +193,12 @@ int unregister_external_interrupt(u16 code, ext_int_handler_t handler)
        int index = ext_hash(code);
 
        spin_lock_irqsave(&ext_int_hash_lock, flags);
-       list_for_each_entry_rcu(p, &ext_int_hash[index], entry)
+       list_for_each_entry_rcu(p, &ext_int_hash[index], entry) {
                if (p->code == code && p->handler == handler) {
                        list_del_rcu(&p->entry);
                        kfree_rcu(p, rcu);
                }
+       }
        spin_unlock_irqrestore(&ext_int_hash_lock, flags);
        return 0;
 }
@@ -211,9 +213,10 @@ void __irq_entry do_extint(struct pt_regs *regs, struct ext_code ext_code,
 
        old_regs = set_irq_regs(regs);
        irq_enter();
-       if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator)
+       if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator) {
                /* Serve timer interrupts first. */
                clock_comparator_work();
+       }
        kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++;
        if (ext_code.code != 0x1004)
                __get_cpu_var(s390_idle).nohz_delay = 1;
index 46405086479c246f6439151c879ab7430d59e5f2..cb019f429e88ba22745a14bf38c714743c2383ad 100644 (file)
@@ -178,7 +178,7 @@ static void cpumf_pmu_enable(struct pmu *pmu)
        err = lcctl(cpuhw->state);
        if (err) {
                pr_err("Enabling the performance measuring unit "
-                      "failed with rc=%lx\n", err);
+                      "failed with rc=%x\n", err);
                return;
        }
 
@@ -203,7 +203,7 @@ static void cpumf_pmu_disable(struct pmu *pmu)
        err = lcctl(inactive);
        if (err) {
                pr_err("Disabling the performance measuring unit "
-                      "failed with rc=%lx\n", err);
+                      "failed with rc=%x\n", err);
                return;
        }
 
index 7bb15fcca75ea572362d02a6b2626836868be9ed..e1335dc2b1b76fffea016ef83e7d1b229086bf20 100644 (file)
@@ -61,21 +61,14 @@ long probe_kernel_write(void *dst, const void *src, size_t size)
        return copied < 0 ? -EFAULT : 0;
 }
 
-/*
- * Copy memory in real mode (kernel to kernel)
- */
-int memcpy_real(void *dest, void *src, size_t count)
+static int __memcpy_real(void *dest, void *src, size_t count)
 {
        register unsigned long _dest asm("2") = (unsigned long) dest;
        register unsigned long _len1 asm("3") = (unsigned long) count;
        register unsigned long _src  asm("4") = (unsigned long) src;
        register unsigned long _len2 asm("5") = (unsigned long) count;
-       unsigned long flags;
        int rc = -EFAULT;
 
-       if (!count)
-               return 0;
-       flags = __arch_local_irq_stnsm(0xf8UL);
        asm volatile (
                "0:     mvcle   %1,%2,0x0\n"
                "1:     jo      0b\n"
@@ -86,7 +79,23 @@ int memcpy_real(void *dest, void *src, size_t count)
                  "+d" (_len2), "=m" (*((long *) dest))
                : "m" (*((long *) src))
                : "cc", "memory");
-       arch_local_irq_restore(flags);
+       return rc;
+}
+
+/*
+ * Copy memory in real mode (kernel to kernel)
+ */
+int memcpy_real(void *dest, void *src, size_t count)
+{
+       unsigned long flags;
+       int rc;
+
+       if (!count)
+               return 0;
+       local_irq_save(flags);
+       __arch_local_irq_stnsm(0xfbUL);
+       rc = __memcpy_real(dest, src, count);
+       local_irq_restore(flags);
        return rc;
 }
 
index 373adf69b01c48ceebfa2808131326ba5c7188dc..6e765bf00670c2d062632baa317c2b8ef0ea7235 100644 (file)
@@ -678,8 +678,6 @@ void page_table_free(struct mm_struct *mm, unsigned long *table)
        }
 }
 
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
-
 static void __page_table_free_rcu(void *table, unsigned bit)
 {
        struct page *page;
@@ -733,7 +731,66 @@ void __tlb_remove_table(void *_table)
                free_pages((unsigned long) table, ALLOC_ORDER);
 }
 
-#endif
+static void tlb_remove_table_smp_sync(void *arg)
+{
+       /* Simply deliver the interrupt */
+}
+
+static void tlb_remove_table_one(void *table)
+{
+       /*
+        * This isn't an RCU grace period and hence the page-tables cannot be
+        * assumed to be actually RCU-freed.
+        *
+        * It is however sufficient for software page-table walkers that rely
+        * on IRQ disabling. See the comment near struct mmu_table_batch.
+        */
+       smp_call_function(tlb_remove_table_smp_sync, NULL, 1);
+       __tlb_remove_table(table);
+}
+
+static void tlb_remove_table_rcu(struct rcu_head *head)
+{
+       struct mmu_table_batch *batch;
+       int i;
+
+       batch = container_of(head, struct mmu_table_batch, rcu);
+
+       for (i = 0; i < batch->nr; i++)
+               __tlb_remove_table(batch->tables[i]);
+
+       free_page((unsigned long)batch);
+}
+
+void tlb_table_flush(struct mmu_gather *tlb)
+{
+       struct mmu_table_batch **batch = &tlb->batch;
+
+       if (*batch) {
+               __tlb_flush_mm(tlb->mm);
+               call_rcu_sched(&(*batch)->rcu, tlb_remove_table_rcu);
+               *batch = NULL;
+       }
+}
+
+void tlb_remove_table(struct mmu_gather *tlb, void *table)
+{
+       struct mmu_table_batch **batch = &tlb->batch;
+
+       if (*batch == NULL) {
+               *batch = (struct mmu_table_batch *)
+                       __get_free_page(GFP_NOWAIT | __GFP_NOWARN);
+               if (*batch == NULL) {
+                       __tlb_flush_mm(tlb->mm);
+                       tlb_remove_table_one(table);
+                       return;
+               }
+               (*batch)->nr = 0;
+       }
+       (*batch)->tables[(*batch)->nr++] = table;
+       if ((*batch)->nr == MAX_TABLE_BATCH)
+               tlb_table_flush(tlb);
+}
 
 /*
  * switch on pgstes for its userspace process (for kvm)
index 1210fde187406c2a5c149151ab46205c00c3358d..160cac9c403654043269e0a63123ecf3ee3bd0a6 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/pm.h>
 #include <linux/delay.h>
 #include <linux/gfp.h>
+#include <linux/cpu.h>
 
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
@@ -78,6 +79,8 @@ void __cpuinit leon_callin(void)
        local_flush_tlb_all();
        leon_configure_cache_smp();
 
+       notify_cpu_starting(cpuid);
+
        /* Get our local ticker going. */
        smp_setup_percpu_timer();
 
index 232df9949530f3d95c3c95385a62d45402c6d042..3ee51f189a55297b0babeb1f54d0b40af97de6f8 100644 (file)
@@ -566,15 +566,10 @@ out:
 
 SYSCALL_DEFINE2(64_munmap, unsigned long, addr, size_t, len)
 {
-       long ret;
-
        if (invalid_64bit_range(addr, len))
                return -EINVAL;
 
-       down_write(&current->mm->mmap_sem);
-       ret = do_munmap(current->mm, addr, len);
-       up_write(&current->mm->mmap_sem);
-       return ret;
+       return vm_munmap(addr, len);
 }
 
 extern unsigned long do_mremap(unsigned long addr,
index 9efbc1391b3ce841f8e676492d1e74e6b0a3f733..89529c9f060535013bfd0505cfa3a13cfd728cd6 100644 (file)
@@ -346,12 +346,10 @@ void single_step_once(struct pt_regs *regs)
                }
 
                /* allocate a cache line of writable, executable memory */
-               down_write(&current->mm->mmap_sem);
-               buffer = (void __user *) do_mmap(NULL, 0, 64,
+               buffer = (void __user *) vm_mmap(NULL, 0, 64,
                                          PROT_EXEC | PROT_READ | PROT_WRITE,
                                          MAP_PRIVATE | MAP_ANONYMOUS,
                                          0);
-               up_write(&current->mm->mmap_sem);
 
                if (IS_ERR((void __force *)buffer)) {
                        kfree(state);
index d511d951a0527103e05abca9c1cf73b4b024b7c1..4824fb45560f7b6afe7bef4bf260f9f39f95a117 100644 (file)
@@ -119,9 +119,7 @@ static void set_brk(unsigned long start, unsigned long end)
        end = PAGE_ALIGN(end);
        if (end <= start)
                return;
-       down_write(&current->mm->mmap_sem);
-       do_brk(start, end - start);
-       up_write(&current->mm->mmap_sem);
+       vm_brk(start, end - start);
 }
 
 #ifdef CORE_DUMP
@@ -332,9 +330,7 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs)
                pos = 32;
                map_size = ex.a_text+ex.a_data;
 
-               down_write(&current->mm->mmap_sem);
-               error = do_brk(text_addr & PAGE_MASK, map_size);
-               up_write(&current->mm->mmap_sem);
+               error = vm_brk(text_addr & PAGE_MASK, map_size);
 
                if (error != (text_addr & PAGE_MASK)) {
                        send_sig(SIGKILL, current, 0);
@@ -373,9 +369,7 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs)
                if (!bprm->file->f_op->mmap || (fd_offset & ~PAGE_MASK) != 0) {
                        loff_t pos = fd_offset;
 
-                       down_write(&current->mm->mmap_sem);
-                       do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
-                       up_write(&current->mm->mmap_sem);
+                       vm_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
                        bprm->file->f_op->read(bprm->file,
                                        (char __user *)N_TXTADDR(ex),
                                        ex.a_text+ex.a_data, &pos);
@@ -385,26 +379,22 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs)
                        goto beyond_if;
                }
 
-               down_write(&current->mm->mmap_sem);
-               error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text,
+               error = vm_mmap(bprm->file, N_TXTADDR(ex), ex.a_text,
                                PROT_READ | PROT_EXEC,
                                MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE |
                                MAP_EXECUTABLE | MAP_32BIT,
                                fd_offset);
-               up_write(&current->mm->mmap_sem);
 
                if (error != N_TXTADDR(ex)) {
                        send_sig(SIGKILL, current, 0);
                        return error;
                }
 
-               down_write(&current->mm->mmap_sem);
-               error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
+               error = vm_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
                                PROT_READ | PROT_WRITE | PROT_EXEC,
                                MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE |
                                MAP_EXECUTABLE | MAP_32BIT,
                                fd_offset + ex.a_text);
-               up_write(&current->mm->mmap_sem);
                if (error != N_DATADDR(ex)) {
                        send_sig(SIGKILL, current, 0);
                        return error;
@@ -476,9 +466,7 @@ static int load_aout_library(struct file *file)
                        error_time = jiffies;
                }
 #endif
-               down_write(&current->mm->mmap_sem);
-               do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
-               up_write(&current->mm->mmap_sem);
+               vm_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
 
                file->f_op->read(file, (char __user *)start_addr,
                        ex.a_text + ex.a_data, &pos);
@@ -490,12 +478,10 @@ static int load_aout_library(struct file *file)
                goto out;
        }
        /* Now use mmap to map the library into memory. */
-       down_write(&current->mm->mmap_sem);
-       error = do_mmap(file, start_addr, ex.a_text + ex.a_data,
+       error = vm_mmap(file, start_addr, ex.a_text + ex.a_data,
                        PROT_READ | PROT_WRITE | PROT_EXEC,
                        MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_32BIT,
                        N_TXTOFF(ex));
-       up_write(&current->mm->mmap_sem);
        retval = error;
        if (error != start_addr)
                goto out;
@@ -503,9 +489,7 @@ static int load_aout_library(struct file *file)
        len = PAGE_ALIGN(ex.a_text + ex.a_data);
        bss = ex.a_text + ex.a_data + ex.a_bss;
        if (bss > len) {
-               down_write(&current->mm->mmap_sem);
-               error = do_brk(start_addr + len, bss - len);
-               up_write(&current->mm->mmap_sem);
+               error = vm_brk(start_addr + len, bss - len);
                retval = error;
                if (error != start_addr + len)
                        goto out;
index 173df38dbda5b5fba0e86658692cd40faa8e8145..2e88438ffd83186c0d7a6b136cc97ae5c943ae4a 100644 (file)
@@ -459,17 +459,17 @@ void kvm_pmu_cpuid_update(struct kvm_vcpu *vcpu)
        pmu->available_event_types = ~entry->ebx & ((1ull << bitmap_len) - 1);
 
        if (pmu->version == 1) {
-               pmu->global_ctrl = (1 << pmu->nr_arch_gp_counters) - 1;
-               return;
+               pmu->nr_arch_fixed_counters = 0;
+       } else {
+               pmu->nr_arch_fixed_counters = min((int)(entry->edx & 0x1f),
+                               X86_PMC_MAX_FIXED);
+               pmu->counter_bitmask[KVM_PMC_FIXED] =
+                       ((u64)1 << ((entry->edx >> 5) & 0xff)) - 1;
        }
 
-       pmu->nr_arch_fixed_counters = min((int)(entry->edx & 0x1f),
-                       X86_PMC_MAX_FIXED);
-       pmu->counter_bitmask[KVM_PMC_FIXED] =
-               ((u64)1 << ((entry->edx >> 5) & 0xff)) - 1;
-       pmu->global_ctrl_mask = ~(((1 << pmu->nr_arch_gp_counters) - 1)
-                       | (((1ull << pmu->nr_arch_fixed_counters) - 1)
-                               << X86_PMC_IDX_FIXED));
+       pmu->global_ctrl = ((1 << pmu->nr_arch_gp_counters) - 1) |
+               (((1ull << pmu->nr_arch_fixed_counters) - 1) << X86_PMC_IDX_FIXED);
+       pmu->global_ctrl_mask = ~pmu->global_ctrl;
 }
 
 void kvm_pmu_init(struct kvm_vcpu *vcpu)
index ad85adfef843c07262b959924cf24fd234c8c9e2..4ff0ab9bc3c86fd26889fa4b88b23c48c84523db 100644 (file)
@@ -2210,9 +2210,12 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
                msr = find_msr_entry(vmx, msr_index);
                if (msr) {
                        msr->data = data;
-                       if (msr - vmx->guest_msrs < vmx->save_nmsrs)
+                       if (msr - vmx->guest_msrs < vmx->save_nmsrs) {
+                               preempt_disable();
                                kvm_set_shared_msr(msr->index, msr->data,
                                                   msr->mask);
+                               preempt_enable();
+                       }
                        break;
                }
                ret = kvm_set_msr_common(vcpu, msr_index, data);
index 4044ce0bf7c1e7741620b8fcda9a78c9cb1bc775..91a5e989abcfe86f60df7bcb2a2919e25f87df6a 100644 (file)
@@ -6336,13 +6336,11 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
                if (npages && !old.rmap) {
                        unsigned long userspace_addr;
 
-                       down_write(&current->mm->mmap_sem);
-                       userspace_addr = do_mmap(NULL, 0,
+                       userspace_addr = vm_mmap(NULL, 0,
                                                 npages * PAGE_SIZE,
                                                 PROT_READ | PROT_WRITE,
                                                 map_flags,
                                                 0);
-                       up_write(&current->mm->mmap_sem);
 
                        if (IS_ERR((void *)userspace_addr))
                                return PTR_ERR((void *)userspace_addr);
@@ -6366,10 +6364,8 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
        if (!user_alloc && !old.user_alloc && old.rmap && !npages) {
                int ret;
 
-               down_write(&current->mm->mmap_sem);
-               ret = do_munmap(current->mm, old.userspace_addr,
+               ret = vm_munmap(old.userspace_addr,
                                old.npages * PAGE_SIZE);
-               up_write(&current->mm->mmap_sem);
                if (ret < 0)
                        printk(KERN_WARNING
                               "kvm_vm_ioctl_set_memory_region: "
index 25feb1ae71c5758273346057d8809232bdb1c769..b1e6c4b2e8eb228834edcbad9d9ff8ffbb9d99f9 100644 (file)
@@ -379,8 +379,8 @@ err_out:
        return;
 }
 
-/* Decode moffset16/32/64 */
-static void __get_moffset(struct insn *insn)
+/* Decode moffset16/32/64. Return 0 if failed */
+static int __get_moffset(struct insn *insn)
 {
        switch (insn->addr_bytes) {
        case 2:
@@ -397,15 +397,19 @@ static void __get_moffset(struct insn *insn)
                insn->moffset2.value = get_next(int, insn);
                insn->moffset2.nbytes = 4;
                break;
+       default:        /* opnd_bytes must be modified manually */
+               goto err_out;
        }
        insn->moffset1.got = insn->moffset2.got = 1;
 
+       return 1;
+
 err_out:
-       return;
+       return 0;
 }
 
-/* Decode imm v32(Iz) */
-static void __get_immv32(struct insn *insn)
+/* Decode imm v32(Iz). Return 0 if failed */
+static int __get_immv32(struct insn *insn)
 {
        switch (insn->opnd_bytes) {
        case 2:
@@ -417,14 +421,18 @@ static void __get_immv32(struct insn *insn)
                insn->immediate.value = get_next(int, insn);
                insn->immediate.nbytes = 4;
                break;
+       default:        /* opnd_bytes must be modified manually */
+               goto err_out;
        }
 
+       return 1;
+
 err_out:
-       return;
+       return 0;
 }
 
-/* Decode imm v64(Iv/Ov) */
-static void __get_immv(struct insn *insn)
+/* Decode imm v64(Iv/Ov), Return 0 if failed */
+static int __get_immv(struct insn *insn)
 {
        switch (insn->opnd_bytes) {
        case 2:
@@ -441,15 +449,18 @@ static void __get_immv(struct insn *insn)
                insn->immediate2.value = get_next(int, insn);
                insn->immediate2.nbytes = 4;
                break;
+       default:        /* opnd_bytes must be modified manually */
+               goto err_out;
        }
        insn->immediate1.got = insn->immediate2.got = 1;
 
+       return 1;
 err_out:
-       return;
+       return 0;
 }
 
 /* Decode ptr16:16/32(Ap) */
-static void __get_immptr(struct insn *insn)
+static int __get_immptr(struct insn *insn)
 {
        switch (insn->opnd_bytes) {
        case 2:
@@ -462,14 +473,17 @@ static void __get_immptr(struct insn *insn)
                break;
        case 8:
                /* ptr16:64 is not exist (no segment) */
-               return;
+               return 0;
+       default:        /* opnd_bytes must be modified manually */
+               goto err_out;
        }
        insn->immediate2.value = get_next(unsigned short, insn);
        insn->immediate2.nbytes = 2;
        insn->immediate1.got = insn->immediate2.got = 1;
 
+       return 1;
 err_out:
-       return;
+       return 0;
 }
 
 /**
@@ -489,7 +503,8 @@ void insn_get_immediate(struct insn *insn)
                insn_get_displacement(insn);
 
        if (inat_has_moffset(insn->attr)) {
-               __get_moffset(insn);
+               if (!__get_moffset(insn))
+                       goto err_out;
                goto done;
        }
 
@@ -517,16 +532,20 @@ void insn_get_immediate(struct insn *insn)
                insn->immediate2.nbytes = 4;
                break;
        case INAT_IMM_PTR:
-               __get_immptr(insn);
+               if (!__get_immptr(insn))
+                       goto err_out;
                break;
        case INAT_IMM_VWORD32:
-               __get_immv32(insn);
+               if (!__get_immv32(insn))
+                       goto err_out;
                break;
        case INAT_IMM_VWORD:
-               __get_immv(insn);
+               if (!__get_immv(insn))
+                       goto err_out;
                break;
        default:
-               break;
+               /* Here, insn must have an immediate, but failed */
+               goto err_out;
        }
        if (inat_has_second_immediate(insn->attr)) {
                insn->immediate2.value = get_next(char, insn);
index 107f6f7be5e139129a1666f1f20aa3a6967c1ef0..dd30f40af9f505152bbc620211fa37d109eae1d7 100644 (file)
@@ -174,7 +174,7 @@ sha512_update(struct shash_desc *desc, const u8 *data, unsigned int len)
        index = sctx->count[0] & 0x7f;
 
        /* Update number of bytes */
-       if (!(sctx->count[0] += len))
+       if ((sctx->count[0] += len) < len)
                sctx->count[1]++;
 
         part_len = 128 - index;
index ab513a972c95b2376703ebee11cad903c7721ba6..a716fede4f25781d8e4e0633c21626ab03c83719 100644 (file)
@@ -74,7 +74,8 @@ acpi_status acpi_reset(void)
 
        /* Check if the reset register is supported */
 
-       if (!reset_reg->address) {
+       if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) ||
+           !reset_reg->address) {
                return_ACPI_STATUS(AE_NOT_EXIST);
        }
 
index ba14fb93c92946097bafc866e316c79234ab02f3..c3881b2eb8b2c5a0ac9b353aa7d7bdd699001ba0 100644 (file)
@@ -607,8 +607,7 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler,
 
        acpi_irq_handler = handler;
        acpi_irq_context = context;
-       if (request_threaded_irq(irq, NULL, acpi_irq, IRQF_SHARED, "acpi",
-                                acpi_irq)) {
+       if (request_irq(irq, acpi_irq, IRQF_SHARED, "acpi", acpi_irq)) {
                printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq);
                acpi_irq_handler = NULL;
                return AE_NOT_ACQUIRED;
index c1d612435939a5d62abb832d1f620faeeac7dc20..a6c77e8b37bde54c266cae17d620c441a896e3b9 100644 (file)
@@ -23,7 +23,8 @@ void acpi_reboot(void)
        /* Is the reset register supported? The spec says we should be
         * checking the bit width and bit offset, but Windows ignores
         * these fields */
-       /* Ignore also acpi_gbl_FADT.flags.ACPI_FADT_RESET_REGISTER */
+       if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER))
+               return;
 
        reset_value = acpi_gbl_FADT.reset_value;
 
index 68013f96729ffc624aad80342ec92af6768b89fa..7857e8fd0a3e56e007004492482b3e306d8ba089 100644 (file)
@@ -329,6 +329,8 @@ static const struct pci_device_id piix_pci_tbl[] = {
        { 0x8086, 0x8c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
        /* SATA Controller IDE (Lynx Point) */
        { 0x8086, 0x8c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
+       /* SATA Controller IDE (DH89xxCC) */
+       { 0x8086, 0x2326, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
        { }     /* terminate list */
 };
 
index e0bda9ff89cda7a6d0271980bbd83fb1c89a9a42..28db50b57b918df812e5bb9f262243421dd97bea 100644 (file)
@@ -95,7 +95,7 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev);
 static void ata_dev_xfermask(struct ata_device *dev);
 static unsigned long ata_dev_blacklisted(const struct ata_device *dev);
 
-unsigned int ata_print_id = 1;
+atomic_t ata_print_id = ATOMIC_INIT(1);
 
 struct ata_force_param {
        const char      *name;
@@ -6029,7 +6029,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
 
        /* give ports names and add SCSI hosts */
        for (i = 0; i < host->n_ports; i++)
-               host->ports[i]->print_id = ata_print_id++;
+               host->ports[i]->print_id = atomic_inc_return(&ata_print_id);
 
 
        /* Create associated sysfs transport objects  */
index 1ee00c8b5b0495674c30237f2be672dee81ee928..93dabdcd2cbe3712191f4ae05c0720a1bf42549d 100644 (file)
@@ -3843,7 +3843,7 @@ int ata_sas_async_port_init(struct ata_port *ap)
        int rc = ap->ops->port_start(ap);
 
        if (!rc) {
-               ap->print_id = ata_print_id++;
+               ap->print_id = atomic_inc_return(&ata_print_id);
                __ata_port_probe(ap);
        }
 
@@ -3867,7 +3867,7 @@ int ata_sas_port_init(struct ata_port *ap)
        int rc = ap->ops->port_start(ap);
 
        if (!rc) {
-               ap->print_id = ata_print_id++;
+               ap->print_id = atomic_inc_return(&ata_print_id);
                rc = ata_port_probe(ap);
        }
 
index 74aaee30e264ce1959c3807cb6a9e4c8bad27c95..c341904853770f7dad45e5cc4e1180f76111e322 100644 (file)
@@ -294,6 +294,7 @@ int ata_tport_add(struct device *parent,
        device_enable_async_suspend(dev);
        pm_runtime_set_active(dev);
        pm_runtime_enable(dev);
+       pm_runtime_forbid(dev);
 
        transport_add_device(dev);
        transport_configure_device(dev);
index 2e26fcaf635b211192238dcfea0d7eebdad5b25b..9d0fd0b7185224239030e51d42dbe83f27ebbafb 100644 (file)
@@ -53,7 +53,7 @@ enum {
        ATA_DNXFER_QUIET        = (1 << 31),
 };
 
-extern unsigned int ata_print_id;
+extern atomic_t ata_print_id;
 extern int atapi_passthru16;
 extern int libata_fua;
 extern int libata_noacpi;
index 38950ea8398a9ebb05425a62b448578acfe172a1..7336d4a7ab317c091b7b991a1355a712f58023ab 100644 (file)
@@ -4025,7 +4025,8 @@ static int mv_platform_probe(struct platform_device *pdev)
        struct ata_host *host;
        struct mv_host_priv *hpriv;
        struct resource *res;
-       int n_ports, rc;
+       int n_ports = 0;
+       int rc;
 
        ata_print_version_once(&pdev->dev, DRV_VERSION);
 
index 0e4ef3de9d5deb6fab10c5ef0fb5678ec610a3be..0d39f2f4294a3c2587e5c019e39904b3f8440fc2 100644 (file)
@@ -375,6 +375,34 @@ static int init_vq(struct virtio_blk *vblk)
        return err;
 }
 
+/*
+ * Legacy naming scheme used for virtio devices.  We are stuck with it for
+ * virtio blk but don't ever use it for any new driver.
+ */
+static int virtblk_name_format(char *prefix, int index, char *buf, int buflen)
+{
+       const int base = 'z' - 'a' + 1;
+       char *begin = buf + strlen(prefix);
+       char *end = buf + buflen;
+       char *p;
+       int unit;
+
+       p = end - 1;
+       *p = '\0';
+       unit = base;
+       do {
+               if (p == begin)
+                       return -EINVAL;
+               *--p = 'a' + (index % unit);
+               index = (index / unit) - 1;
+       } while (index >= 0);
+
+       memmove(begin, p, end - p);
+       memcpy(buf, prefix, strlen(prefix));
+
+       return 0;
+}
+
 static int __devinit virtblk_probe(struct virtio_device *vdev)
 {
        struct virtio_blk *vblk;
@@ -443,18 +471,7 @@ static int __devinit virtblk_probe(struct virtio_device *vdev)
 
        q->queuedata = vblk;
 
-       if (index < 26) {
-               sprintf(vblk->disk->disk_name, "vd%c", 'a' + index % 26);
-       } else if (index < (26 + 1) * 26) {
-               sprintf(vblk->disk->disk_name, "vd%c%c",
-                       'a' + index / 26 - 1, 'a' + index % 26);
-       } else {
-               const unsigned int m1 = (index / 26 - 1) / 26 - 1;
-               const unsigned int m2 = (index / 26 - 1) % 26;
-               const unsigned int m3 =  index % 26;
-               sprintf(vblk->disk->disk_name, "vd%c%c%c",
-                       'a' + m1, 'a' + m2, 'a' + m3);
-       }
+       virtblk_name_format("vd", index, vblk->disk->disk_name, DISK_NAME_LEN);
 
        vblk->disk->major = major;
        vblk->disk->first_minor = index_to_minor(index);
index 89860f34a7ece7c890f3f45925e8dd8cd613d912..4f66171c668354b490f1284aec48278b8676bd84 100644 (file)
@@ -416,7 +416,7 @@ static void xen_blkbk_discard(struct xenbus_transaction xbt, struct backend_info
                                    "discard-secure", "%d",
                                    blkif->vbd.discard_secure);
                if (err) {
-                       dev_warn(dev-dev, "writing discard-secure (%d)", err);
+                       dev_warn(&dev->dev, "writing discard-secure (%d)", err);
                        return;
                }
        }
index 0053d7ebb5cae0a479eacf0d22c69606509644ea..8f3f74ce8c7fd7ac95e241c2c4504f06a52da38c 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
 #include <linux/gfp.h>
+#include <linux/module.h>
 
 #include <crypto/ctr.h>
 #include <crypto/des.h>
index dc641c79652650dbe7bc02ce5d3b0e889427e376..921039e56f87f9360156074233c9e38828bc1612 100644 (file)
@@ -124,6 +124,9 @@ struct talitos_private {
        void __iomem *reg;
        int irq[2];
 
+       /* SEC global registers lock  */
+       spinlock_t reg_lock ____cacheline_aligned;
+
        /* SEC version geometry (from device tree node) */
        unsigned int num_channels;
        unsigned int chfifo_len;
@@ -412,6 +415,7 @@ static void talitos_done_##name(unsigned long data)                 \
 {                                                                      \
        struct device *dev = (struct device *)data;                     \
        struct talitos_private *priv = dev_get_drvdata(dev);            \
+       unsigned long flags;                                            \
                                                                        \
        if (ch_done_mask & 1)                                           \
                flush_channel(dev, 0, 0, 0);                            \
@@ -427,8 +431,10 @@ static void talitos_done_##name(unsigned long data)                        \
 out:                                                                   \
        /* At this point, all completed channels have been processed */ \
        /* Unmask done interrupts for channels completed later on. */   \
+       spin_lock_irqsave(&priv->reg_lock, flags);                      \
        setbits32(priv->reg + TALITOS_IMR, ch_done_mask);               \
        setbits32(priv->reg + TALITOS_IMR_LO, TALITOS_IMR_LO_INIT);     \
+       spin_unlock_irqrestore(&priv->reg_lock, flags);                 \
 }
 DEF_TALITOS_DONE(4ch, TALITOS_ISR_4CHDONE)
 DEF_TALITOS_DONE(ch0_2, TALITOS_ISR_CH_0_2_DONE)
@@ -619,22 +625,28 @@ static irqreturn_t talitos_interrupt_##name(int irq, void *data)         \
        struct device *dev = data;                                             \
        struct talitos_private *priv = dev_get_drvdata(dev);                   \
        u32 isr, isr_lo;                                                       \
+       unsigned long flags;                                                   \
                                                                               \
+       spin_lock_irqsave(&priv->reg_lock, flags);                             \
        isr = in_be32(priv->reg + TALITOS_ISR);                                \
        isr_lo = in_be32(priv->reg + TALITOS_ISR_LO);                          \
        /* Acknowledge interrupt */                                            \
        out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \
        out_be32(priv->reg + TALITOS_ICR_LO, isr_lo);                          \
                                                                               \
-       if (unlikely((isr & ~TALITOS_ISR_4CHDONE) & ch_err_mask || isr_lo))    \
-               talitos_error(dev, isr, isr_lo);                               \
-       else                                                                   \
+       if (unlikely(isr & ch_err_mask || isr_lo)) {                           \
+               spin_unlock_irqrestore(&priv->reg_lock, flags);                \
+               talitos_error(dev, isr & ch_err_mask, isr_lo);                 \
+       }                                                                      \
+       else {                                                                 \
                if (likely(isr & ch_done_mask)) {                              \
                        /* mask further done interrupts. */                    \
                        clrbits32(priv->reg + TALITOS_IMR, ch_done_mask);      \
                        /* done_task will unmask done interrupts at exit */    \
                        tasklet_schedule(&priv->done_task[tlet]);              \
                }                                                              \
+               spin_unlock_irqrestore(&priv->reg_lock, flags);                \
+       }                                                                      \
                                                                               \
        return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED :  \
                                                                IRQ_NONE;      \
@@ -2719,6 +2731,8 @@ static int talitos_probe(struct platform_device *ofdev)
 
        priv->ofdev = ofdev;
 
+       spin_lock_init(&priv->reg_lock);
+
        err = talitos_probe_irq(ofdev);
        if (err)
                goto err_out;
index cf9da362d64f9a233512ce7a228bccad25906197..ef378b5b17e49079075f1fdf3f5834cca90f05a7 100644 (file)
@@ -91,11 +91,10 @@ config DW_DMAC
 
 config AT_HDMAC
        tristate "Atmel AHB DMA support"
-       depends on ARCH_AT91SAM9RL || ARCH_AT91SAM9G45
+       depends on ARCH_AT91
        select DMA_ENGINE
        help
-         Support the Atmel AHB DMA controller.  This can be integrated in
-         chips such as the Atmel AT91SAM9RL.
+         Support the Atmel AHB DMA controller.
 
 config FSL_DMA
        tristate "Freescale Elo and Elo Plus DMA support"
index 839624f9fe6aa6dca29aba693dad33671abed888..9b126b6d79ccc0c29c8aec9748d36bc9136ee695 100644 (file)
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/irqdomain.h>
 #include <linux/slab.h>
 
 #include <asm/mach/irq.h>
 
 #include <plat/pincfg.h>
 #include <plat/gpio-nomadik.h>
-#include <mach/hardware.h>
-#include <asm/gpio.h>
 
 /*
  * The GPIO module in the Nomadik family of Systems-on-Chip is an
@@ -43,6 +42,7 @@
 
 struct nmk_gpio_chip {
        struct gpio_chip chip;
+       struct irq_domain *domain;
        void __iomem *addr;
        struct clk *clk;
        unsigned int bank;
@@ -58,8 +58,10 @@ struct nmk_gpio_chip {
        u32 real_wake;
        u32 rwimsc;
        u32 fwimsc;
-       u32 slpm;
+       u32 rimsc;
+       u32 fimsc;
        u32 pull_up;
+       u32 lowemi;
 };
 
 static struct nmk_gpio_chip *
@@ -124,6 +126,24 @@ static void __nmk_gpio_set_pull(struct nmk_gpio_chip *nmk_chip,
        }
 }
 
+static void __nmk_gpio_set_lowemi(struct nmk_gpio_chip *nmk_chip,
+                                 unsigned offset, bool lowemi)
+{
+       u32 bit = BIT(offset);
+       bool enabled = nmk_chip->lowemi & bit;
+
+       if (lowemi == enabled)
+               return;
+
+       if (lowemi)
+               nmk_chip->lowemi |= bit;
+       else
+               nmk_chip->lowemi &= ~bit;
+
+       writel_relaxed(nmk_chip->lowemi,
+                      nmk_chip->addr + NMK_GPIO_LOWEMI);
+}
+
 static void __nmk_gpio_make_input(struct nmk_gpio_chip *nmk_chip,
                                  unsigned offset)
 {
@@ -150,8 +170,8 @@ static void __nmk_gpio_set_mode_safe(struct nmk_gpio_chip *nmk_chip,
                                     unsigned offset, int gpio_mode,
                                     bool glitch)
 {
-       u32 rwimsc = readl(nmk_chip->addr + NMK_GPIO_RWIMSC);
-       u32 fwimsc = readl(nmk_chip->addr + NMK_GPIO_FWIMSC);
+       u32 rwimsc = nmk_chip->rwimsc;
+       u32 fwimsc = nmk_chip->fwimsc;
 
        if (glitch && nmk_chip->set_ioforce) {
                u32 bit = BIT(offset);
@@ -173,6 +193,36 @@ static void __nmk_gpio_set_mode_safe(struct nmk_gpio_chip *nmk_chip,
        }
 }
 
+static void
+nmk_gpio_disable_lazy_irq(struct nmk_gpio_chip *nmk_chip, unsigned offset)
+{
+       u32 falling = nmk_chip->fimsc & BIT(offset);
+       u32 rising = nmk_chip->rimsc & BIT(offset);
+       int gpio = nmk_chip->chip.base + offset;
+       int irq = NOMADIK_GPIO_TO_IRQ(gpio);
+       struct irq_data *d = irq_get_irq_data(irq);
+
+       if (!rising && !falling)
+               return;
+
+       if (!d || !irqd_irq_disabled(d))
+               return;
+
+       if (rising) {
+               nmk_chip->rimsc &= ~BIT(offset);
+               writel_relaxed(nmk_chip->rimsc,
+                              nmk_chip->addr + NMK_GPIO_RIMSC);
+       }
+
+       if (falling) {
+               nmk_chip->fimsc &= ~BIT(offset);
+               writel_relaxed(nmk_chip->fimsc,
+                              nmk_chip->addr + NMK_GPIO_FIMSC);
+       }
+
+       dev_dbg(nmk_chip->chip.dev, "%d: clearing interrupt mask\n", gpio);
+}
+
 static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset,
                             pin_cfg_t cfg, bool sleep, unsigned int *slpmregs)
 {
@@ -238,6 +288,17 @@ static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset,
                __nmk_gpio_set_pull(nmk_chip, offset, pull);
        }
 
+       __nmk_gpio_set_lowemi(nmk_chip, offset, PIN_LOWEMI(cfg));
+
+       /*
+        * If the pin is switching to altfunc, and there was an interrupt
+        * installed on it which has been lazy disabled, actually mask the
+        * interrupt to prevent spurious interrupts that would occur while the
+        * pin is under control of the peripheral.  Only SKE does this.
+        */
+       if (af != NMK_GPIO_ALT_GPIO)
+               nmk_gpio_disable_lazy_irq(nmk_chip, offset);
+
        /*
         * If we've backed up the SLPM registers (glitch workaround), modify
         * the backups since they will be restored.
@@ -334,7 +395,7 @@ static int __nmk_config_pins(pin_cfg_t *cfgs, int num, bool sleep)
                struct nmk_gpio_chip *nmk_chip;
                int pin = PIN_NUM(cfgs[i]);
 
-               nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(pin));
+               nmk_chip = nmk_gpio_chips[pin / NMK_GPIO_PER_CHIP];
                if (!nmk_chip) {
                        ret = -EINVAL;
                        break;
@@ -342,7 +403,7 @@ static int __nmk_config_pins(pin_cfg_t *cfgs, int num, bool sleep)
 
                clk_enable(nmk_chip->clk);
                spin_lock(&nmk_chip->lock);
-               __nmk_config_pin(nmk_chip, pin - nmk_chip->chip.base,
+               __nmk_config_pin(nmk_chip, pin % NMK_GPIO_PER_CHIP,
                                 cfgs[i], sleep, glitch ? slpm : NULL);
                spin_unlock(&nmk_chip->lock);
                clk_disable(nmk_chip->clk);
@@ -426,7 +487,7 @@ int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode)
        struct nmk_gpio_chip *nmk_chip;
        unsigned long flags;
 
-       nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
+       nmk_chip = nmk_gpio_chips[gpio / NMK_GPIO_PER_CHIP];
        if (!nmk_chip)
                return -EINVAL;
 
@@ -434,7 +495,7 @@ int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode)
        spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
        spin_lock(&nmk_chip->lock);
 
-       __nmk_gpio_set_slpm(nmk_chip, gpio - nmk_chip->chip.base, mode);
+       __nmk_gpio_set_slpm(nmk_chip, gpio % NMK_GPIO_PER_CHIP, mode);
 
        spin_unlock(&nmk_chip->lock);
        spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
@@ -461,13 +522,13 @@ int nmk_gpio_set_pull(int gpio, enum nmk_gpio_pull pull)
        struct nmk_gpio_chip *nmk_chip;
        unsigned long flags;
 
-       nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
+       nmk_chip = nmk_gpio_chips[gpio / NMK_GPIO_PER_CHIP];
        if (!nmk_chip)
                return -EINVAL;
 
        clk_enable(nmk_chip->clk);
        spin_lock_irqsave(&nmk_chip->lock, flags);
-       __nmk_gpio_set_pull(nmk_chip, gpio - nmk_chip->chip.base, pull);
+       __nmk_gpio_set_pull(nmk_chip, gpio % NMK_GPIO_PER_CHIP, pull);
        spin_unlock_irqrestore(&nmk_chip->lock, flags);
        clk_disable(nmk_chip->clk);
 
@@ -489,13 +550,13 @@ int nmk_gpio_set_mode(int gpio, int gpio_mode)
        struct nmk_gpio_chip *nmk_chip;
        unsigned long flags;
 
-       nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
+       nmk_chip = nmk_gpio_chips[gpio / NMK_GPIO_PER_CHIP];
        if (!nmk_chip)
                return -EINVAL;
 
        clk_enable(nmk_chip->clk);
        spin_lock_irqsave(&nmk_chip->lock, flags);
-       __nmk_gpio_set_mode(nmk_chip, gpio - nmk_chip->chip.base, gpio_mode);
+       __nmk_gpio_set_mode(nmk_chip, gpio % NMK_GPIO_PER_CHIP, gpio_mode);
        spin_unlock_irqrestore(&nmk_chip->lock, flags);
        clk_disable(nmk_chip->clk);
 
@@ -508,11 +569,11 @@ int nmk_gpio_get_mode(int gpio)
        struct nmk_gpio_chip *nmk_chip;
        u32 afunc, bfunc, bit;
 
-       nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
+       nmk_chip = nmk_gpio_chips[gpio / NMK_GPIO_PER_CHIP];
        if (!nmk_chip)
                return -EINVAL;
 
-       bit = 1 << (gpio - nmk_chip->chip.base);
+       bit = 1 << (gpio % NMK_GPIO_PER_CHIP);
 
        clk_enable(nmk_chip->clk);
 
@@ -529,21 +590,19 @@ EXPORT_SYMBOL(nmk_gpio_get_mode);
 /* IRQ functions */
 static inline int nmk_gpio_get_bitmask(int gpio)
 {
-       return 1 << (gpio % 32);
+       return 1 << (gpio % NMK_GPIO_PER_CHIP);
 }
 
 static void nmk_gpio_irq_ack(struct irq_data *d)
 {
-       int gpio;
        struct nmk_gpio_chip *nmk_chip;
 
-       gpio = NOMADIK_IRQ_TO_GPIO(d->irq);
        nmk_chip = irq_data_get_irq_chip_data(d);
        if (!nmk_chip)
                return;
 
        clk_enable(nmk_chip->clk);
-       writel(nmk_gpio_get_bitmask(gpio), nmk_chip->addr + NMK_GPIO_IC);
+       writel(nmk_gpio_get_bitmask(d->hwirq), nmk_chip->addr + NMK_GPIO_IC);
        clk_disable(nmk_chip->clk);
 }
 
@@ -556,37 +615,52 @@ static void __nmk_gpio_irq_modify(struct nmk_gpio_chip *nmk_chip,
                                  int gpio, enum nmk_gpio_irq_type which,
                                  bool enable)
 {
-       u32 rimsc = which == WAKE ? NMK_GPIO_RWIMSC : NMK_GPIO_RIMSC;
-       u32 fimsc = which == WAKE ? NMK_GPIO_FWIMSC : NMK_GPIO_FIMSC;
        u32 bitmask = nmk_gpio_get_bitmask(gpio);
-       u32 reg;
+       u32 *rimscval;
+       u32 *fimscval;
+       u32 rimscreg;
+       u32 fimscreg;
+
+       if (which == NORMAL) {
+               rimscreg = NMK_GPIO_RIMSC;
+               fimscreg = NMK_GPIO_FIMSC;
+               rimscval = &nmk_chip->rimsc;
+               fimscval = &nmk_chip->fimsc;
+       } else  {
+               rimscreg = NMK_GPIO_RWIMSC;
+               fimscreg = NMK_GPIO_FWIMSC;
+               rimscval = &nmk_chip->rwimsc;
+               fimscval = &nmk_chip->fwimsc;
+       }
 
        /* we must individually set/clear the two edges */
        if (nmk_chip->edge_rising & bitmask) {
-               reg = readl(nmk_chip->addr + rimsc);
                if (enable)
-                       reg |= bitmask;
+                       *rimscval |= bitmask;
                else
-                       reg &= ~bitmask;
-               writel(reg, nmk_chip->addr + rimsc);
+                       *rimscval &= ~bitmask;
+               writel(*rimscval, nmk_chip->addr + rimscreg);
        }
        if (nmk_chip->edge_falling & bitmask) {
-               reg = readl(nmk_chip->addr + fimsc);
                if (enable)
-                       reg |= bitmask;
+                       *fimscval |= bitmask;
                else
-                       reg &= ~bitmask;
-               writel(reg, nmk_chip->addr + fimsc);
+                       *fimscval &= ~bitmask;
+               writel(*fimscval, nmk_chip->addr + fimscreg);
        }
 }
 
 static void __nmk_gpio_set_wake(struct nmk_gpio_chip *nmk_chip,
                                int gpio, bool on)
 {
-       if (nmk_chip->sleepmode) {
-               __nmk_gpio_set_slpm(nmk_chip, gpio - nmk_chip->chip.base,
-                                   on ? NMK_GPIO_SLPM_WAKEUP_ENABLE
-                                   : NMK_GPIO_SLPM_WAKEUP_DISABLE);
+       /*
+        * Ensure WAKEUP_ENABLE is on.  No need to disable it if wakeup is
+        * disabled, since setting SLPM to 1 increases power consumption, and
+        * wakeup is anyhow controlled by the RIMSC and FIMSC registers.
+        */
+       if (nmk_chip->sleepmode && on) {
+               __nmk_gpio_set_slpm(nmk_chip, gpio % nmk_chip->chip.base,
+                                   NMK_GPIO_SLPM_WAKEUP_ENABLE);
        }
 
        __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, on);
@@ -594,14 +668,12 @@ static void __nmk_gpio_set_wake(struct nmk_gpio_chip *nmk_chip,
 
 static int nmk_gpio_irq_maskunmask(struct irq_data *d, bool enable)
 {
-       int gpio;
        struct nmk_gpio_chip *nmk_chip;
        unsigned long flags;
        u32 bitmask;
 
-       gpio = NOMADIK_IRQ_TO_GPIO(d->irq);
        nmk_chip = irq_data_get_irq_chip_data(d);
-       bitmask = nmk_gpio_get_bitmask(gpio);
+       bitmask = nmk_gpio_get_bitmask(d->hwirq);
        if (!nmk_chip)
                return -EINVAL;
 
@@ -609,10 +681,10 @@ static int nmk_gpio_irq_maskunmask(struct irq_data *d, bool enable)
        spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
        spin_lock(&nmk_chip->lock);
 
-       __nmk_gpio_irq_modify(nmk_chip, gpio, NORMAL, enable);
+       __nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, enable);
 
        if (!(nmk_chip->real_wake & bitmask))
-               __nmk_gpio_set_wake(nmk_chip, gpio, enable);
+               __nmk_gpio_set_wake(nmk_chip, d->hwirq, enable);
 
        spin_unlock(&nmk_chip->lock);
        spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
@@ -636,20 +708,18 @@ static int nmk_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
        struct nmk_gpio_chip *nmk_chip;
        unsigned long flags;
        u32 bitmask;
-       int gpio;
 
-       gpio = NOMADIK_IRQ_TO_GPIO(d->irq);
        nmk_chip = irq_data_get_irq_chip_data(d);
        if (!nmk_chip)
                return -EINVAL;
-       bitmask = nmk_gpio_get_bitmask(gpio);
+       bitmask = nmk_gpio_get_bitmask(d->hwirq);
 
        clk_enable(nmk_chip->clk);
        spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
        spin_lock(&nmk_chip->lock);
 
        if (irqd_irq_disabled(d))
-               __nmk_gpio_set_wake(nmk_chip, gpio, on);
+               __nmk_gpio_set_wake(nmk_chip, d->hwirq, on);
 
        if (on)
                nmk_chip->real_wake |= bitmask;
@@ -667,17 +737,14 @@ static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type)
 {
        bool enabled = !irqd_irq_disabled(d);
        bool wake = irqd_is_wakeup_set(d);
-       int gpio;
        struct nmk_gpio_chip *nmk_chip;
        unsigned long flags;
        u32 bitmask;
 
-       gpio = NOMADIK_IRQ_TO_GPIO(d->irq);
        nmk_chip = irq_data_get_irq_chip_data(d);
-       bitmask = nmk_gpio_get_bitmask(gpio);
+       bitmask = nmk_gpio_get_bitmask(d->hwirq);
        if (!nmk_chip)
                return -EINVAL;
-
        if (type & IRQ_TYPE_LEVEL_HIGH)
                return -EINVAL;
        if (type & IRQ_TYPE_LEVEL_LOW)
@@ -687,10 +754,10 @@ static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type)
        spin_lock_irqsave(&nmk_chip->lock, flags);
 
        if (enabled)
-               __nmk_gpio_irq_modify(nmk_chip, gpio, NORMAL, false);
+               __nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, false);
 
        if (enabled || wake)
-               __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, false);
+               __nmk_gpio_irq_modify(nmk_chip, d->hwirq, WAKE, false);
 
        nmk_chip->edge_rising &= ~bitmask;
        if (type & IRQ_TYPE_EDGE_RISING)
@@ -701,10 +768,10 @@ static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type)
                nmk_chip->edge_falling |= bitmask;
 
        if (enabled)
-               __nmk_gpio_irq_modify(nmk_chip, gpio, NORMAL, true);
+               __nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, true);
 
        if (enabled || wake)
-               __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, true);
+               __nmk_gpio_irq_modify(nmk_chip, d->hwirq, WAKE, true);
 
        spin_unlock_irqrestore(&nmk_chip->lock, flags);
        clk_disable(nmk_chip->clk);
@@ -750,7 +817,7 @@ static void __nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc,
        chained_irq_enter(host_chip, desc);
 
        nmk_chip = irq_get_handler_data(irq);
-       first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base);
+       first_irq = nmk_chip->domain->revmap_data.legacy.first_irq;
        while (status) {
                int bit = __ffs(status);
 
@@ -784,18 +851,6 @@ static void nmk_gpio_secondary_irq_handler(unsigned int irq,
 
 static int nmk_gpio_init_irq(struct nmk_gpio_chip *nmk_chip)
 {
-       unsigned int first_irq;
-       int i;
-
-       first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base);
-       for (i = first_irq; i < first_irq + nmk_chip->chip.ngpio; i++) {
-               irq_set_chip_and_handler(i, &nmk_gpio_irq_chip,
-                                        handle_edge_irq);
-               set_irq_flags(i, IRQF_VALID);
-               irq_set_chip_data(i, nmk_chip);
-               irq_set_irq_type(i, IRQ_TYPE_EDGE_FALLING);
-       }
-
        irq_set_chained_handler(nmk_chip->parent_irq, nmk_gpio_irq_handler);
        irq_set_handler_data(nmk_chip->parent_irq, nmk_chip);
 
@@ -872,7 +927,7 @@ static int nmk_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
        struct nmk_gpio_chip *nmk_chip =
                container_of(chip, struct nmk_gpio_chip, chip);
 
-       return NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base) + offset;
+       return irq_find_mapping(nmk_chip->domain, offset);
 }
 
 #ifdef CONFIG_DEBUG_FS
@@ -1008,21 +1063,11 @@ void nmk_gpio_wakeups_suspend(void)
 
                clk_enable(chip->clk);
 
-               chip->rwimsc = readl(chip->addr + NMK_GPIO_RWIMSC);
-               chip->fwimsc = readl(chip->addr + NMK_GPIO_FWIMSC);
-
                writel(chip->rwimsc & chip->real_wake,
                       chip->addr + NMK_GPIO_RWIMSC);
                writel(chip->fwimsc & chip->real_wake,
                       chip->addr + NMK_GPIO_FWIMSC);
 
-               if (chip->sleepmode) {
-                       chip->slpm = readl(chip->addr + NMK_GPIO_SLPC);
-
-                       /* 0 -> wakeup enable */
-                       writel(~chip->real_wake, chip->addr + NMK_GPIO_SLPC);
-               }
-
                clk_disable(chip->clk);
        }
 }
@@ -1042,9 +1087,6 @@ void nmk_gpio_wakeups_resume(void)
                writel(chip->rwimsc, chip->addr + NMK_GPIO_RWIMSC);
                writel(chip->fwimsc, chip->addr + NMK_GPIO_FWIMSC);
 
-               if (chip->sleepmode)
-                       writel(chip->slpm, chip->addr + NMK_GPIO_SLPC);
-
                clk_disable(chip->clk);
        }
 }
@@ -1068,19 +1110,62 @@ void nmk_gpio_read_pull(int gpio_bank, u32 *pull_up)
        }
 }
 
+int nmk_gpio_irq_map(struct irq_domain *d, unsigned int irq,
+                         irq_hw_number_t hwirq)
+{
+       struct nmk_gpio_chip *nmk_chip = d->host_data;
+
+       if (!nmk_chip)
+               return -EINVAL;
+
+       irq_set_chip_and_handler(irq, &nmk_gpio_irq_chip, handle_edge_irq);
+       set_irq_flags(irq, IRQF_VALID);
+       irq_set_chip_data(irq, nmk_chip);
+       irq_set_irq_type(irq, IRQ_TYPE_EDGE_FALLING);
+
+       return 0;
+}
+
+const struct irq_domain_ops nmk_gpio_irq_simple_ops = {
+       .map = nmk_gpio_irq_map,
+       .xlate = irq_domain_xlate_twocell,
+};
+
 static int __devinit nmk_gpio_probe(struct platform_device *dev)
 {
        struct nmk_gpio_platform_data *pdata = dev->dev.platform_data;
+       struct device_node *np = dev->dev.of_node;
        struct nmk_gpio_chip *nmk_chip;
        struct gpio_chip *chip;
        struct resource *res;
        struct clk *clk;
        int secondary_irq;
+       void __iomem *base;
        int irq;
        int ret;
 
-       if (!pdata)
+       if (!pdata && !np) {
+               dev_err(&dev->dev, "No platform data or device tree found\n");
                return -ENODEV;
+       }
+
+       if (np) {
+               pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+               if (!pdata)
+                       return -ENOMEM;
+
+               if (of_get_property(np, "supports-sleepmode", NULL))
+                       pdata->supports_sleepmode = true;
+
+               if (of_property_read_u32(np, "gpio-bank", &dev->id)) {
+                       dev_err(&dev->dev, "gpio-bank property not found\n");
+                       ret = -EINVAL;
+                       goto out;
+               }
+
+               pdata->first_gpio = dev->id * NMK_GPIO_PER_CHIP;
+               pdata->num_gpio   = NMK_GPIO_PER_CHIP;
+       }
 
        res = platform_get_resource(dev, IORESOURCE_MEM, 0);
        if (!res) {
@@ -1106,10 +1191,16 @@ static int __devinit nmk_gpio_probe(struct platform_device *dev)
                goto out;
        }
 
+       base = ioremap(res->start, resource_size(res));
+       if (!base) {
+               ret = -ENOMEM;
+               goto out_release;
+       }
+
        clk = clk_get(&dev->dev, NULL);
        if (IS_ERR(clk)) {
                ret = PTR_ERR(clk);
-               goto out_release;
+               goto out_unmap;
        }
 
        nmk_chip = kzalloc(sizeof(*nmk_chip), GFP_KERNEL);
@@ -1117,13 +1208,14 @@ static int __devinit nmk_gpio_probe(struct platform_device *dev)
                ret = -ENOMEM;
                goto out_clk;
        }
+
        /*
         * The virt address in nmk_chip->addr is in the nomadik register space,
         * so we can simply convert the resource address, without remapping
         */
        nmk_chip->bank = dev->id;
        nmk_chip->clk = clk;
-       nmk_chip->addr = io_p2v(res->start);
+       nmk_chip->addr = base;
        nmk_chip->chip = nmk_gpio_template;
        nmk_chip->parent_irq = irq;
        nmk_chip->secondary_parent_irq = secondary_irq;
@@ -1139,6 +1231,12 @@ static int __devinit nmk_gpio_probe(struct platform_device *dev)
        chip->dev = &dev->dev;
        chip->owner = THIS_MODULE;
 
+       clk_enable(nmk_chip->clk);
+       nmk_chip->lowemi = readl_relaxed(nmk_chip->addr + NMK_GPIO_LOWEMI);
+       clk_disable(nmk_chip->clk);
+
+       chip->of_node = np;
+
        ret = gpiochip_add(&nmk_chip->chip);
        if (ret)
                goto out_free;
@@ -1146,12 +1244,22 @@ static int __devinit nmk_gpio_probe(struct platform_device *dev)
        BUG_ON(nmk_chip->bank >= ARRAY_SIZE(nmk_gpio_chips));
 
        nmk_gpio_chips[nmk_chip->bank] = nmk_chip;
+
        platform_set_drvdata(dev, nmk_chip);
 
+       nmk_chip->domain = irq_domain_add_legacy(np, NMK_GPIO_PER_CHIP,
+                                               NOMADIK_GPIO_TO_IRQ(pdata->first_gpio),
+                                               0, &nmk_gpio_irq_simple_ops, nmk_chip);
+       if (!nmk_chip->domain) {
+               pr_err("%s: Failed to create irqdomain\n", np->full_name);
+               ret = -ENOSYS;
+               goto out_free;
+       }
+
        nmk_gpio_init_irq(nmk_chip);
 
-       dev_info(&dev->dev, "at address %p\n",
-                nmk_chip->addr);
+       dev_info(&dev->dev, "at address %p\n", nmk_chip->addr);
+
        return 0;
 
 out_free:
@@ -1159,18 +1267,29 @@ out_free:
 out_clk:
        clk_disable(clk);
        clk_put(clk);
+out_unmap:
+       iounmap(base);
 out_release:
        release_mem_region(res->start, resource_size(res));
 out:
        dev_err(&dev->dev, "Failure %i for GPIO %i-%i\n", ret,
                  pdata->first_gpio, pdata->first_gpio+31);
+       if (np)
+               kfree(pdata);
+
        return ret;
 }
 
+static const struct of_device_id nmk_gpio_match[] = {
+       { .compatible = "st,nomadik-gpio", },
+       {}
+};
+
 static struct platform_driver nmk_gpio_driver = {
        .driver = {
                .owner = THIS_MODULE,
                .name = "gpio",
+               .of_match_table = nmk_gpio_match,
        },
        .probe = nmk_gpio_probe,
 };
index 30372f7b2d457a8803e819d9050ccd3c525e7825..348b367debebdcf1823ac4f781915097e3fb027a 100644 (file)
@@ -1510,8 +1510,8 @@ int drm_freebufs(struct drm_device *dev, void *data,
  * \param arg pointer to a drm_buf_map structure.
  * \return zero on success or a negative number on failure.
  *
- * Maps the AGP, SG or PCI buffer region with do_mmap(), and copies information
- * about each buffer into user space. For PCI buffers, it calls do_mmap() with
+ * Maps the AGP, SG or PCI buffer region with vm_mmap(), and copies information
+ * about each buffer into user space. For PCI buffers, it calls vm_mmap() with
  * offset equal to 0, which drm_mmap() interpretes as PCI buffers and calls
  * drm_mmap_dma().
  */
@@ -1553,18 +1553,14 @@ int drm_mapbufs(struct drm_device *dev, void *data,
                                retcode = -EINVAL;
                                goto done;
                        }
-                       down_write(&current->mm->mmap_sem);
-                       virtual = do_mmap(file_priv->filp, 0, map->size,
+                       virtual = vm_mmap(file_priv->filp, 0, map->size,
                                          PROT_READ | PROT_WRITE,
                                          MAP_SHARED,
                                          token);
-                       up_write(&current->mm->mmap_sem);
                } else {
-                       down_write(&current->mm->mmap_sem);
-                       virtual = do_mmap(file_priv->filp, 0, dma->byte_count,
+                       virtual = vm_mmap(file_priv->filp, 0, dma->byte_count,
                                          PROT_READ | PROT_WRITE,
                                          MAP_SHARED, 0);
-                       up_write(&current->mm->mmap_sem);
                }
                if (virtual > -1024UL) {
                        /* Real error */
index d3aaeb6ae2362167f360d3a8d1aa846028714fdd..c79870a75c2ffa426125d17bba4fc736ec3233e9 100644 (file)
@@ -3335,10 +3335,12 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
 
        ret = crtc->funcs->page_flip(crtc, fb, e);
        if (ret) {
-               spin_lock_irqsave(&dev->event_lock, flags);
-               file_priv->event_space += sizeof e->event;
-               spin_unlock_irqrestore(&dev->event_lock, flags);
-               kfree(e);
+               if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) {
+                       spin_lock_irqsave(&dev->event_lock, flags);
+                       file_priv->event_space += sizeof e->event;
+                       spin_unlock_irqrestore(&dev->event_lock, flags);
+                       kfree(e);
+               }
        }
 
 out:
index cdfbf27b2b3ccf6bbda4d7e8c0ebef8b2c8e5381..123de28f94ef0613441b6656e9be9f309577c387 100644 (file)
@@ -507,12 +507,12 @@ int drm_release(struct inode *inode, struct file *filp)
 
        drm_events_release(file_priv);
 
-       if (dev->driver->driver_features & DRIVER_GEM)
-               drm_gem_release(dev, file_priv);
-
        if (dev->driver->driver_features & DRIVER_MODESET)
                drm_fb_release(file_priv);
 
+       if (dev->driver->driver_features & DRIVER_GEM)
+               drm_gem_release(dev, file_priv);
+
        mutex_lock(&dev->ctxlist_mutex);
        if (!list_empty(&dev->ctxlist)) {
                struct drm_ctx_list *pos, *n;
index c8c83dad2ce1443d67782ef94fd3ae70b0505983..37c9a523dd1c6f0c8391766023e43421b36ec57b 100644 (file)
@@ -1,6 +1,6 @@
 #include "drmP.h"
 #include <linux/usb.h>
-#include <linux/export.h>
+#include <linux/module.h>
 
 int drm_get_usb_dev(struct usb_interface *interface,
                    const struct usb_device_id *id,
@@ -114,3 +114,7 @@ void drm_usb_exit(struct drm_driver *driver,
        usb_deregister(udriver);
 }
 EXPORT_SYMBOL(drm_usb_exit);
+
+MODULE_AUTHOR("David Airlie");
+MODULE_DESCRIPTION("USB DRM support");
+MODULE_LICENSE("GPL and additional rights");
index 26d51979116b456bb269cff95bc003d6a55394b1..392ce71ed6a18103db1562ee9024f70f51e6d46e 100644 (file)
@@ -581,10 +581,8 @@ int exynos_drm_gem_mmap_ioctl(struct drm_device *dev, void *data,
        obj->filp->f_op = &exynos_drm_gem_fops;
        obj->filp->private_data = obj;
 
-       down_write(&current->mm->mmap_sem);
-       addr = do_mmap(obj->filp, 0, args->size,
+       addr = vm_mmap(obj->filp, 0, args->size,
                        PROT_READ | PROT_WRITE, MAP_SHARED, 0);
-       up_write(&current->mm->mmap_sem);
 
        drm_gem_object_unreference_unlocked(obj);
 
index 21071cef92a4c60a7791969cd63771855fac4540..36eb0744841c7c2f4071da62b11ba45006d7b466 100644 (file)
@@ -29,7 +29,6 @@
 #define __MDFLD_DSI_OUTPUT_H__
 
 #include <linux/backlight.h>
-#include <linux/version.h>
 #include <drm/drmP.h>
 #include <drm/drm.h>
 #include <drm/drm_crtc.h>
index 2c8a60c3b98eacdbeac6673e75f763dff8e065da..f920fb5e42b63846e3d8b7b782b492e547e18eef 100644 (file)
@@ -129,6 +129,7 @@ static int i810_map_buffer(struct drm_buf *buf, struct drm_file *file_priv)
        if (buf_priv->currently_mapped == I810_BUF_MAPPED)
                return -EINVAL;
 
+       /* This is all entirely broken */
        down_write(&current->mm->mmap_sem);
        old_fops = file_priv->filp->f_op;
        file_priv->filp->f_op = &i810_buffer_fops;
@@ -157,11 +158,8 @@ static int i810_unmap_buffer(struct drm_buf *buf)
        if (buf_priv->currently_mapped != I810_BUF_MAPPED)
                return -EINVAL;
 
-       down_write(&current->mm->mmap_sem);
-       retcode = do_munmap(current->mm,
-                           (unsigned long)buf_priv->virtual,
+       retcode = vm_munmap((unsigned long)buf_priv->virtual,
                            (size_t) buf->total);
-       up_write(&current->mm->mmap_sem);
 
        buf_priv->currently_mapped = I810_BUF_UNMAPPED;
        buf_priv->virtual = NULL;
index 0e3c6acde955d47e95576261acee362d36f12e8e..0d1e4b7b4b99c9bb76460c2fca3ca3c5a6216b11 100644 (file)
@@ -1087,11 +1087,9 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
        if (obj == NULL)
                return -ENOENT;
 
-       down_write(&current->mm->mmap_sem);
-       addr = do_mmap(obj->filp, 0, args->size,
+       addr = vm_mmap(obj->filp, 0, args->size,
                       PROT_READ | PROT_WRITE, MAP_SHARED,
                       args->offset);
-       up_write(&current->mm->mmap_sem);
        drm_gem_object_unreference_unlocked(obj);
        if (IS_ERR((void *)addr))
                return addr;
index bae38acf44dc4396ce7bb7af53162d435af9ec46..5908cd563400f486f7ae5a302f6a12f4c62da8af 100644 (file)
@@ -3478,8 +3478,11 @@ static bool intel_crtc_mode_fixup(struct drm_crtc *crtc,
                        return false;
        }
 
-       /* All interlaced capable intel hw wants timings in frames. */
-       drm_mode_set_crtcinfo(adjusted_mode, 0);
+       /* All interlaced capable intel hw wants timings in frames. Note though
+        * that intel_lvds_mode_fixup does some funny tricks with the crtc
+        * timings, so we need to be careful not to clobber these.*/
+       if (!(adjusted_mode->private_flags & INTEL_MODE_CRTC_TIMINGS_SET))
+               drm_mode_set_crtcinfo(adjusted_mode, 0);
 
        return true;
 }
@@ -7465,7 +7468,13 @@ static int intel_gen6_queue_flip(struct drm_device *dev,
        OUT_RING(fb->pitches[0] | obj->tiling_mode);
        OUT_RING(obj->gtt_offset);
 
-       pf = I915_READ(PF_CTL(intel_crtc->pipe)) & PF_ENABLE;
+       /* Contrary to the suggestions in the documentation,
+        * "Enable Panel Fitter" does not seem to be required when page
+        * flipping with a non-native mode, and worse causes a normal
+        * modeset to fail.
+        * pf = I915_READ(PF_CTL(intel_crtc->pipe)) & PF_ENABLE;
+        */
+       pf = 0;
        pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff;
        OUT_RING(pf | pipesrc);
        ADVANCE_LP_RING();
index 5a14149b3794237ad26ee24bce00b5938e157b93..715afa15302528ac7523f883aee5bd7e3c428906 100644 (file)
 #define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0)
 #define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT)
 #define INTEL_MODE_DP_FORCE_6BPC (0x10)
+/* This flag must be set by the encoder's mode_fixup if it changes the crtc
+ * timings in the mode to prevent the crtc fixup from overwriting them.
+ * Currently only lvds needs that. */
+#define INTEL_MODE_CRTC_TIMINGS_SET (0x20)
 
 static inline void
 intel_mode_set_pixel_multiplier(struct drm_display_mode *mode,
index 19ecd78b8a2ce572c98b1407122e1d97d94c4781..6e9ee33fd4122110a4df115c7d74bb18c20fc386 100644 (file)
@@ -279,6 +279,8 @@ void intel_fb_restore_mode(struct drm_device *dev)
        struct drm_mode_config *config = &dev->mode_config;
        struct drm_plane *plane;
 
+       mutex_lock(&dev->mode_config.mutex);
+
        ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper);
        if (ret)
                DRM_DEBUG("failed to restore crtc mode\n");
@@ -286,4 +288,6 @@ void intel_fb_restore_mode(struct drm_device *dev)
        /* Be sure to shut off any planes that may be active */
        list_for_each_entry(plane, &config->plane_list, head)
                plane->funcs->disable_plane(plane);
+
+       mutex_unlock(&dev->mode_config.mutex);
 }
index 95db2e988227a8c6fe7cbac5d0984a879181f492..30e2c82101de0d8cb0c841d97f77db6acfc501aa 100644 (file)
@@ -187,6 +187,8 @@ centre_horizontally(struct drm_display_mode *mode,
 
        mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos;
        mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width;
+
+       mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET;
 }
 
 static void
@@ -208,6 +210,8 @@ centre_vertically(struct drm_display_mode *mode,
 
        mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos;
        mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width;
+
+       mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET;
 }
 
 static inline u32 panel_fitter_scaling(u32 source, u32 target)
@@ -283,6 +287,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
        for_each_pipe(pipe)
                I915_WRITE(BCLRPAT(pipe), 0);
 
+       drm_mode_set_crtcinfo(adjusted_mode, 0);
+
        switch (intel_lvds->fitting_mode) {
        case DRM_MODE_SCALE_CENTER:
                /*
index 230a141dbea34da3feff3e4fc043d780a6975fdd..48177ec4720ed14bae9bc4cb2bdbc0a2d06e4985 100644 (file)
@@ -47,8 +47,6 @@ intel_fixed_panel_mode(struct drm_display_mode *fixed_mode,
        adjusted_mode->vtotal = fixed_mode->vtotal;
 
        adjusted_mode->clock = fixed_mode->clock;
-
-       drm_mode_set_crtcinfo(adjusted_mode, 0);
 }
 
 /* adjusted_mode has been preset to be the panel's fixed mode */
index 34d591b7d4efe91d1221d0ae11131157efcdcca9..da3e7c3abab7090a3770413c02bd0cbbaa6134a3 100644 (file)
@@ -235,6 +235,7 @@ nouveau_pm_profile_set(struct drm_device *dev, const char *profile)
                return -EPERM;
 
        strncpy(string, profile, sizeof(string));
+       string[sizeof(string) - 1] = 0;
        if ((ptr = strchr(string, '\n')))
                *ptr = '\0';
 
index a7844ab6a50cd5603b351eb026a62e763cb6a554..27464021247583a87fd5dfc1c6c79441da9e703c 100644 (file)
@@ -42,7 +42,7 @@ nv50_sor_dp_lane_map(struct drm_device *dev, struct dcb_entry *dcb, u8 lane)
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        static const u8 nvaf[] = { 24, 16, 8, 0 }; /* thanks, apple.. */
        static const u8 nv50[] = { 16, 8, 0, 24 };
-       if (dev_priv->card_type == 0xaf)
+       if (dev_priv->chipset == 0xaf)
                return nvaf[lane];
        return nv50[lane];
 }
index de71243b591ff037dc9555bd83d7b85cc8657eda..c8187c4b6ae8838f65fdd0445be43974cc040f1b 100644 (file)
@@ -1135,7 +1135,7 @@ static void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc
        }
        if (rdev->flags & RADEON_IS_AGP) {
                size_bf = mc->gtt_start;
-               size_af = 0xFFFFFFFF - mc->gtt_end + 1;
+               size_af = 0xFFFFFFFF - mc->gtt_end;
                if (size_bf > size_af) {
                        if (mc->mc_vram_size > size_bf) {
                                dev_warn(rdev->dev, "limiting VRAM\n");
@@ -1149,7 +1149,7 @@ static void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc
                                mc->real_vram_size = size_af;
                                mc->mc_vram_size = size_af;
                        }
-                       mc->vram_start = mc->gtt_end;
+                       mc->vram_start = mc->gtt_end + 1;
                }
                mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;
                dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n",
index bd05156edbdb07fc30188215fcba9d0bbef3c31f..3c2e7a000a2ad91cefff66c5aa3dde40f3d9649d 100644 (file)
@@ -970,7 +970,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
 
                        encoder = obj_to_encoder(obj);
 
-                       if (encoder->encoder_type != DRM_MODE_ENCODER_DAC ||
+                       if (encoder->encoder_type != DRM_MODE_ENCODER_DAC &&
                            encoder->encoder_type != DRM_MODE_ENCODER_TVDAC)
                                continue;
 
@@ -1000,6 +1000,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
         * cases the DVI port is actually a virtual KVM port connected to the service
         * processor.
         */
+out:
        if ((!rdev->is_atom_bios) &&
            (ret == connector_status_disconnected) &&
            rdev->mode_info.bios_hardcoded_edid_size) {
@@ -1007,7 +1008,6 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
                ret = connector_status_connected;
        }
 
-out:
        /* updated in get modes as well since we need to know if it's analog or digital */
        radeon_connector_update_scratch_regs(connector, ret);
        return ret;
index 66d5fe1c81747cfa73da445d1f2099d36e9e4261..65060b77c8058efea3c7f35aac4df40b777aac4c 100644 (file)
@@ -147,6 +147,12 @@ static bool radeon_msi_ok(struct radeon_device *rdev)
            (rdev->pdev->subsystem_device == 0x01fd))
                return true;
 
+       /* RV515 seems to have MSI issues where it loses
+        * MSI rearms occasionally. This leads to lockups and freezes.
+        * disable it by default.
+        */
+       if (rdev->family == CHIP_RV515)
+               return false;
        if (rdev->flags & RADEON_IS_IGP) {
                /* APUs work fine with MSIs */
                if (rdev->family >= CHIP_PALM)
index c62ae4be3845f02df5934304d3b90e7b8582588c..cdab1aeaed6e443fe4d8d62b75cf2e6d03516ad5 100644 (file)
@@ -969,7 +969,7 @@ void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
        }
        if (rdev->flags & RADEON_IS_AGP) {
                size_bf = mc->gtt_start;
-               size_af = 0xFFFFFFFF - mc->gtt_end + 1;
+               size_af = 0xFFFFFFFF - mc->gtt_end;
                if (size_bf > size_af) {
                        if (mc->mc_vram_size > size_bf) {
                                dev_warn(rdev->dev, "limiting VRAM\n");
@@ -983,7 +983,7 @@ void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
                                mc->real_vram_size = size_af;
                                mc->mc_vram_size = size_af;
                        }
-                       mc->vram_start = mc->gtt_end;
+                       mc->vram_start = mc->gtt_end + 1;
                }
                mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;
                dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n",
index ac7a199ffece9cd3df519187561aa2b6a5617f59..27bda986fc2bd8a6ad948d19e819bb1e8ec415df 100644 (file)
@@ -2999,8 +2999,8 @@ int si_rlc_init(struct radeon_device *rdev)
        }
        r = radeon_bo_pin(rdev->rlc.save_restore_obj, RADEON_GEM_DOMAIN_VRAM,
                          &rdev->rlc.save_restore_gpu_addr);
+       radeon_bo_unreserve(rdev->rlc.save_restore_obj);
        if (r) {
-               radeon_bo_unreserve(rdev->rlc.save_restore_obj);
                dev_warn(rdev->dev, "(%d) pin RLC sr bo failed\n", r);
                si_rlc_fini(rdev);
                return r;
@@ -3023,9 +3023,8 @@ int si_rlc_init(struct radeon_device *rdev)
        }
        r = radeon_bo_pin(rdev->rlc.clear_state_obj, RADEON_GEM_DOMAIN_VRAM,
                          &rdev->rlc.clear_state_gpu_addr);
+       radeon_bo_unreserve(rdev->rlc.clear_state_obj);
        if (r) {
-
-               radeon_bo_unreserve(rdev->rlc.clear_state_obj);
                dev_warn(rdev->dev, "(%d) pin RLC c bo failed\n", r);
                si_rlc_fini(rdev);
                return r;
index a3d033252995aeb388fbcabc1dab8a286e38cb51..ffddcba32af62b637baa09fd9487f515451fca4f 100644 (file)
@@ -34,7 +34,7 @@ config HID
 config HID_BATTERY_STRENGTH
        bool
        depends on HID && POWER_SUPPLY && HID = POWER_SUPPLY
-       default y
+       default n
 
 config HIDRAW
        bool "/dev/hidraw raw HID device support"
index de47039c708c5546232bc1c05606d2a3e89b99d2..9f85f827607fd6fca72b03152ca7a51b061ec82c 100644 (file)
@@ -62,7 +62,7 @@ static int tivo_input_mapping(struct hid_device *hdev, struct hid_input *hi,
 
 static const struct hid_device_id tivo_devices[] = {
        /* TiVo Slide Bluetooth remote, pairs with a Broadcom dongle */
-       { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_BT) },
+       { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_BT) },
        { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE) },
        { }
 };
index 7765e4f74ec56177ad8cc39476320d6d2436f719..1958f03efd7aaa43f72416f809eb42fe569b413f 100644 (file)
@@ -59,14 +59,11 @@ struct ads1015_data {
        struct ads1015_channel_data channel_data[ADS1015_CHANNELS];
 };
 
-static int ads1015_read_value(struct i2c_client *client, unsigned int channel,
-                             int *value)
+static int ads1015_read_adc(struct i2c_client *client, unsigned int channel)
 {
        u16 config;
-       s16 conversion;
        struct ads1015_data *data = i2c_get_clientdata(client);
        unsigned int pga = data->channel_data[channel].pga;
-       int fullscale;
        unsigned int data_rate = data->channel_data[channel].data_rate;
        unsigned int conversion_time_ms;
        int res;
@@ -78,7 +75,6 @@ static int ads1015_read_value(struct i2c_client *client, unsigned int channel,
        if (res < 0)
                goto err_unlock;
        config = res;
-       fullscale = fullscale_table[pga];
        conversion_time_ms = DIV_ROUND_UP(1000, data_rate_table[data_rate]);
 
        /* setup and start single conversion */
@@ -105,33 +101,36 @@ static int ads1015_read_value(struct i2c_client *client, unsigned int channel,
        }
 
        res = i2c_smbus_read_word_swapped(client, ADS1015_CONVERSION);
-       if (res < 0)
-               goto err_unlock;
-       conversion = res;
-
-       mutex_unlock(&data->update_lock);
-
-       *value = DIV_ROUND_CLOSEST(conversion * fullscale, 0x7ff0);
-
-       return 0;
 
 err_unlock:
        mutex_unlock(&data->update_lock);
        return res;
 }
 
+static int ads1015_reg_to_mv(struct i2c_client *client, unsigned int channel,
+                            s16 reg)
+{
+       struct ads1015_data *data = i2c_get_clientdata(client);
+       unsigned int pga = data->channel_data[channel].pga;
+       int fullscale = fullscale_table[pga];
+
+       return DIV_ROUND_CLOSEST(reg * fullscale, 0x7ff0);
+}
+
 /* sysfs callback function */
 static ssize_t show_in(struct device *dev, struct device_attribute *da,
        char *buf)
 {
        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
        struct i2c_client *client = to_i2c_client(dev);
-       int in;
        int res;
+       int index = attr->index;
 
-       res = ads1015_read_value(client, attr->index, &in);
+       res = ads1015_read_adc(client, index);
+       if (res < 0)
+               return res;
 
-       return (res < 0) ? res : sprintf(buf, "%d\n", in);
+       return sprintf(buf, "%d\n", ads1015_reg_to_mv(client, index, res));
 }
 
 static const struct sensor_device_attribute ads1015_in[] = {
index b7494af1e4a9ba8cb6952c83d96b845f19f9e7fd..37a8fc92b44acf50a16d086c9983a9794c03b838 100644 (file)
@@ -122,6 +122,38 @@ static bool __devinit fam15h_power_is_internal_node0(struct pci_dev *f4)
        return true;
 }
 
+/*
+ * Newer BKDG versions have an updated recommendation on how to properly
+ * initialize the running average range (was: 0xE, now: 0x9). This avoids
+ * counter saturations resulting in bogus power readings.
+ * We correct this value ourselves to cope with older BIOSes.
+ */
+static void __devinit tweak_runavg_range(struct pci_dev *pdev)
+{
+       u32 val;
+       const struct pci_device_id affected_device = {
+               PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) };
+
+       /*
+        * let this quirk apply only to the current version of the
+        * northbridge, since future versions may change the behavior
+        */
+       if (!pci_match_id(&affected_device, pdev))
+               return;
+
+       pci_bus_read_config_dword(pdev->bus,
+               PCI_DEVFN(PCI_SLOT(pdev->devfn), 5),
+               REG_TDP_RUNNING_AVERAGE, &val);
+       if ((val & 0xf) != 0xe)
+               return;
+
+       val &= ~0xf;
+       val |=  0x9;
+       pci_bus_write_config_dword(pdev->bus,
+               PCI_DEVFN(PCI_SLOT(pdev->devfn), 5),
+               REG_TDP_RUNNING_AVERAGE, val);
+}
+
 static void __devinit fam15h_power_init_data(struct pci_dev *f4,
                                             struct fam15h_power_data *data)
 {
@@ -155,6 +187,13 @@ static int __devinit fam15h_power_probe(struct pci_dev *pdev,
        struct device *dev;
        int err;
 
+       /*
+        * though we ignore every other northbridge, we still have to
+        * do the tweaking on _each_ node in MCM processors as the counters
+        * are working hand-in-hand
+        */
+       tweak_runavg_range(pdev);
+
        if (!fam15h_power_is_internal_node0(pdev)) {
                err = -ENODEV;
                goto exit;
index 2d787796bf50a186d87652edbaad100217f85084..7faf4a7fcaa9219d278b67b75a77a6c10081f678 100644 (file)
@@ -380,8 +380,7 @@ config INPUT_TWL4030_VIBRA
 
 config INPUT_TWL6040_VIBRA
        tristate "Support for TWL6040 Vibrator"
-       depends on TWL4030_CORE
-       select TWL6040_CORE
+       depends on TWL6040_CORE
        select INPUT_FF_MEMLESS
        help
          This option enables support for TWL6040 Vibrator Driver.
index 45874fed523ab771e94f8b3d9dccf415b8cfa6af..14e94f56cb7d4dab69581335b2b82e9b822895f9 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/workqueue.h>
-#include <linux/i2c/twl.h>
+#include <linux/input.h>
 #include <linux/mfd/twl6040.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
@@ -257,7 +257,7 @@ static SIMPLE_DEV_PM_OPS(twl6040_vibra_pm_ops, twl6040_vibra_suspend, NULL);
 
 static int __devinit twl6040_vibra_probe(struct platform_device *pdev)
 {
-       struct twl4030_vibra_data *pdata = pdev->dev.platform_data;
+       struct twl6040_vibra_data *pdata = pdev->dev.platform_data;
        struct vibra_info *info;
        int ret;
 
index 800243b6037ed9edc5b945b74d226a17be05f712..64ad702a2ecc64eff2505fd0f4217126fd10bdf9 100644 (file)
@@ -35,7 +35,7 @@ static void pwmled_brightness(struct led_classdev *cdev, enum led_brightness b)
  * NOTE:  we reuse the platform_data structure of GPIO leds,
  * but repurpose its "gpio" number as a PWM channel number.
  */
-static int __init pwmled_probe(struct platform_device *pdev)
+static int __devinit pwmled_probe(struct platform_device *pdev)
 {
        const struct gpio_led_platform_data     *pdata;
        struct pwmled                           *leds;
index 7f98984e4fad0526fbe98335a29b166cf6bba428..eab2ea42420090c7847cd5d4eaa889659bf351b4 100644 (file)
@@ -54,6 +54,7 @@ struct xc5000_priv {
        struct list_head hybrid_tuner_instance_list;
 
        u32 if_khz;
+       u32 xtal_khz;
        u32 freq_hz;
        u32 bandwidth;
        u8  video_standard;
@@ -214,9 +215,9 @@ static const struct xc5000_fw_cfg xc5000a_1_6_114 = {
        .size = 12401,
 };
 
-static const struct xc5000_fw_cfg xc5000c_41_024_5_31875 = {
-       .name = "dvb-fe-xc5000c-41.024.5-31875.fw",
-       .size = 16503,
+static const struct xc5000_fw_cfg xc5000c_41_024_5 = {
+       .name = "dvb-fe-xc5000c-41.024.5.fw",
+       .size = 16497,
 };
 
 static inline const struct xc5000_fw_cfg *xc5000_assign_firmware(int chip_id)
@@ -226,7 +227,7 @@ static inline const struct xc5000_fw_cfg *xc5000_assign_firmware(int chip_id)
        case XC5000A:
                return &xc5000a_1_6_114;
        case XC5000C:
-               return &xc5000c_41_024_5_31875;
+               return &xc5000c_41_024_5;
        }
 }
 
@@ -572,6 +573,31 @@ static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz, int mode)
        return found;
 }
 
+static int xc_set_xtal(struct dvb_frontend *fe)
+{
+       struct xc5000_priv *priv = fe->tuner_priv;
+       int ret = XC_RESULT_SUCCESS;
+
+       switch (priv->chip_id) {
+       default:
+       case XC5000A:
+               /* 32.000 MHz xtal is default */
+               break;
+       case XC5000C:
+               switch (priv->xtal_khz) {
+               default:
+               case 32000:
+                       /* 32.000 MHz xtal is default */
+                       break;
+               case 31875:
+                       /* 31.875 MHz xtal configuration */
+                       ret = xc_write_reg(priv, 0x000f, 0x8081);
+                       break;
+               }
+               break;
+       }
+       return ret;
+}
 
 static int xc5000_fwupload(struct dvb_frontend *fe)
 {
@@ -603,6 +629,8 @@ static int xc5000_fwupload(struct dvb_frontend *fe)
        } else {
                printk(KERN_INFO "xc5000: firmware uploading...\n");
                ret = xc_load_i2c_sequence(fe,  fw->data);
+               if (XC_RESULT_SUCCESS == ret)
+                       ret = xc_set_xtal(fe);
                printk(KERN_INFO "xc5000: firmware upload complete...\n");
        }
 
@@ -1164,6 +1192,9 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
                priv->if_khz = cfg->if_khz;
        }
 
+       if (priv->xtal_khz == 0)
+               priv->xtal_khz = cfg->xtal_khz;
+
        if (priv->radio_input == 0)
                priv->radio_input = cfg->radio_input;
 
index 3396f8e02b40c2fb1363bedb891c76badbbf9da8..39a73bf01406c8e3d2df4a3f6cc53ac7f065467c 100644 (file)
@@ -34,6 +34,7 @@ struct xc5000_config {
        u8   i2c_address;
        u32  if_khz;
        u8   radio_input;
+       u32  xtal_khz;
 
        int chip_id;
 };
index 39696c6a4ed750d91b44c3291ed2eda0f9b0b4d0..0f64d71826572d298d4cbf19050e8be254fce887 100644 (file)
@@ -1446,6 +1446,28 @@ static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system)
                                __func__);
                        return -EINVAL;
                }
+               /*
+                * Get a delivery system that is compatible with DVBv3
+                * NOTE: in order for this to work with softwares like Kaffeine that
+                *      uses a DVBv5 call for DVB-S2 and a DVBv3 call to go back to
+                *      DVB-S, drivers that support both should put the SYS_DVBS entry
+                *      before the SYS_DVBS2, otherwise it won't switch back to DVB-S.
+                *      The real fix is that userspace applications should not use DVBv3
+                *      and not trust on calling FE_SET_FRONTEND to switch the delivery
+                *      system.
+                */
+               ncaps = 0;
+               while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) {
+                       if (fe->ops.delsys[ncaps] == desired_system) {
+                               delsys = desired_system;
+                               break;
+                       }
+                       ncaps++;
+               }
+               if (delsys == SYS_UNDEFINED) {
+                       dprintk("%s() Couldn't find a delivery system that matches %d\n",
+                               __func__, desired_system);
+               }
        } else {
                /*
                 * This is a DVBv5 call. So, it likely knows the supported
@@ -1494,9 +1516,10 @@ static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system)
                                __func__);
                        return -EINVAL;
                }
-               c->delivery_system = delsys;
        }
 
+       c->delivery_system = delsys;
+
        /*
         * The DVBv3 or DVBv5 call is requesting a different system. So,
         * emulation is needed.
index 36d11756492f5f62471ba412786d8183e271aecc..a414b1f2b6a5a0f2cd1c4dcfef210ea45189f912 100644 (file)
@@ -1520,8 +1520,10 @@ static int scu_command(struct drxk_state *state,
        dprintk(1, "\n");
 
        if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) ||
-           ((resultLen > 0) && (result == NULL)))
-               goto error;
+           ((resultLen > 0) && (result == NULL))) {
+               printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+               return status;
+       }
 
        mutex_lock(&state->mutex);
 
index b09c5fae489bd020ea4748cd9c33d67dc12568b0..af526586fa263f63ccf6d2088f10a779724fb3a8 100644 (file)
@@ -1046,6 +1046,7 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)
                goto exit_unregister_led;
        }
 
+       data->dev->driver_type = RC_DRIVER_IR_RAW;
        data->dev->driver_name = WBCIR_NAME;
        data->dev->input_name = WBCIR_NAME;
        data->dev->input_phys = "wbcir/cir0";
index f2479c5c0eb23071d6f3d29c6cd598b7f777e55b..ce1e7ba940f6c75ac2818b799010deee37553c48 100644 (file)
@@ -492,7 +492,7 @@ config VIDEO_VS6624
 
 config VIDEO_MT9M032
        tristate "MT9M032 camera sensor support"
-       depends on I2C && VIDEO_V4L2
+       depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
        select VIDEO_APTINA_PLL
        ---help---
          This driver supports MT9M032 camera sensors from Aptina, monochrome
index 7636672c3548a45fc1b76dc502d099b34c472533..645973c5feb01d7a9413310a106a35af59dd4c0d 100644 (file)
@@ -392,10 +392,11 @@ static int mt9m032_set_pad_format(struct v4l2_subdev *subdev,
        }
 
        /* Scaling is not supported, the format is thus fixed. */
-       ret = mt9m032_get_pad_format(subdev, fh, fmt);
+       fmt->format = *__mt9m032_get_pad_format(sensor, fh, fmt->which);
+       ret = 0;
 
 done:
-       mutex_lock(&sensor->lock);
+       mutex_unlock(&sensor->lock);
        return ret;
 }
 
index 29f463cc09cbc5dc56ec215a225548be8a65b900..11e44386fa9bba2287c3fda66b422b3f88c57963 100644 (file)
@@ -268,10 +268,17 @@ config TWL6030_PWM
          This is used to control charging LED brightness.
 
 config TWL6040_CORE
-       bool
-       depends on TWL4030_CORE && GENERIC_HARDIRQS
+       bool "Support for TWL6040 audio codec"
+       depends on I2C=y && GENERIC_HARDIRQS
        select MFD_CORE
+       select REGMAP_I2C
        default n
+       help
+         Say yes here if you want support for Texas Instruments TWL6040 audio
+         codec.
+         This driver provides common support for accessing the device,
+         additional drivers must be enabled in order to use the
+         functionality of the device (audio, vibra).
 
 config MFD_STMPE
        bool "Support STMicroelectronics STMPE"
index 1895cf9fab8c1b1c491cbc611335775f014760e0..1582c3d952579e66306e1ad8ce2713f3b0d03f9c 100644 (file)
@@ -527,7 +527,9 @@ static void asic3_gpio_set(struct gpio_chip *chip,
 
 static int asic3_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
 {
-       return (offset < ASIC3_NUM_GPIOS) ? IRQ_BOARD_START + offset : -ENXIO;
+       struct asic3 *asic = container_of(chip, struct asic3, gpio);
+
+       return (offset < ASIC3_NUM_GPIOS) ? asic->irq_base + offset : -ENXIO;
 }
 
 static __init int asic3_gpio_probe(struct platform_device *pdev,
index 95a2e546a48962c18cfaa151aa7dc539e4c94035..c8aae6640e64cc00bdc4079f3326ac8ef512df34 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/clk.h>
 #include <linux/dma-mapping.h>
 #include <linux/spinlock.h>
-#include <linux/gpio.h>
 #include <plat/usb.h>
 #include <linux/pm_runtime.h>
 
@@ -502,19 +501,6 @@ static void omap_usbhs_init(struct device *dev)
        pm_runtime_get_sync(dev);
        spin_lock_irqsave(&omap->lock, flags);
 
-       if (pdata->ehci_data->phy_reset) {
-               if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
-                       gpio_request_one(pdata->ehci_data->reset_gpio_port[0],
-                                        GPIOF_OUT_INIT_LOW, "USB1 PHY reset");
-
-               if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
-                       gpio_request_one(pdata->ehci_data->reset_gpio_port[1],
-                                        GPIOF_OUT_INIT_LOW, "USB2 PHY reset");
-
-               /* Hold the PHY in RESET for enough time till DIR is high */
-               udelay(10);
-       }
-
        omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION);
        dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev);
 
@@ -593,39 +579,10 @@ static void omap_usbhs_init(struct device *dev)
                        usbhs_omap_tll_init(dev, OMAP_TLL_CHANNEL_COUNT);
        }
 
-       if (pdata->ehci_data->phy_reset) {
-               /* Hold the PHY in RESET for enough time till
-                * PHY is settled and ready
-                */
-               udelay(10);
-
-               if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
-                       gpio_set_value
-                               (pdata->ehci_data->reset_gpio_port[0], 1);
-
-               if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
-                       gpio_set_value
-                               (pdata->ehci_data->reset_gpio_port[1], 1);
-       }
-
        spin_unlock_irqrestore(&omap->lock, flags);
        pm_runtime_put_sync(dev);
 }
 
-static void omap_usbhs_deinit(struct device *dev)
-{
-       struct usbhs_hcd_omap           *omap = dev_get_drvdata(dev);
-       struct usbhs_omap_platform_data *pdata = &omap->platdata;
-
-       if (pdata->ehci_data->phy_reset) {
-               if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
-                       gpio_free(pdata->ehci_data->reset_gpio_port[0]);
-
-               if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
-                       gpio_free(pdata->ehci_data->reset_gpio_port[1]);
-       }
-}
-
 
 /**
  * usbhs_omap_probe - initialize TI-based HCDs
@@ -860,7 +817,6 @@ static int __devexit usbhs_omap_remove(struct platform_device *pdev)
 {
        struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev);
 
-       omap_usbhs_deinit(&pdev->dev);
        iounmap(omap->tll_base);
        iounmap(omap->uhh_base);
        clk_put(omap->init_60m_fclk);
index 99ef944c621df5e00f1f440c05fe5e8938938415..44afae0a69ce75a5fada79d48acae246db1dfdb0 100644 (file)
@@ -80,44 +80,6 @@ static struct mfd_cell rc5t583_subdevs[] = {
        {.name = "rc5t583-key",      }
 };
 
-int rc5t583_write(struct device *dev, uint8_t reg, uint8_t val)
-{
-       struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
-       return regmap_write(rc5t583->regmap, reg, val);
-}
-
-int rc5t583_read(struct device *dev, uint8_t reg, uint8_t *val)
-{
-       struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
-       unsigned int ival;
-       int ret;
-       ret = regmap_read(rc5t583->regmap, reg, &ival);
-       if (!ret)
-               *val = (uint8_t)ival;
-       return ret;
-}
-
-int rc5t583_set_bits(struct device *dev, unsigned int reg,
-                       unsigned int bit_mask)
-{
-       struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
-       return regmap_update_bits(rc5t583->regmap, reg, bit_mask, bit_mask);
-}
-
-int rc5t583_clear_bits(struct device *dev, unsigned int reg,
-                       unsigned int bit_mask)
-{
-       struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
-       return regmap_update_bits(rc5t583->regmap, reg, bit_mask, 0);
-}
-
-int rc5t583_update(struct device *dev, unsigned int reg,
-               unsigned int val, unsigned int mask)
-{
-       struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
-       return regmap_update_bits(rc5t583->regmap, reg, mask, val);
-}
-
 static int __rc5t583_set_ext_pwrreq1_control(struct device *dev,
        int id, int ext_pwr, int slots)
 {
@@ -197,6 +159,7 @@ int rc5t583_ext_power_req_config(struct device *dev, int ds_id,
                        ds_id, ext_pwr_req);
        return 0;
 }
+EXPORT_SYMBOL(rc5t583_ext_power_req_config);
 
 static int rc5t583_clear_ext_power_req(struct rc5t583 *rc5t583,
        struct rc5t583_platform_data *pdata)
index b2d8e512d3cb002b6f3e809e47a12f01f96de588..2d6bedadca096d68eec4ce61332b57d6f08140a8 100644 (file)
@@ -30,7 +30,9 @@
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
 #include <linux/delay.h>
-#include <linux/i2c/twl.h>
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+#include <linux/err.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/twl6040.h>
 
@@ -39,7 +41,7 @@
 int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg)
 {
        int ret;
-       u8 val = 0;
+       unsigned int val;
 
        mutex_lock(&twl6040->io_mutex);
        /* Vibra control registers from cache */
@@ -47,7 +49,7 @@ int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg)
                     reg == TWL6040_REG_VIBCTLR)) {
                val = twl6040->vibra_ctrl_cache[VIBRACTRL_MEMBER(reg)];
        } else {
-               ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg);
+               ret = regmap_read(twl6040->regmap, reg, &val);
                if (ret < 0) {
                        mutex_unlock(&twl6040->io_mutex);
                        return ret;
@@ -64,7 +66,7 @@ int twl6040_reg_write(struct twl6040 *twl6040, unsigned int reg, u8 val)
        int ret;
 
        mutex_lock(&twl6040->io_mutex);
-       ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg);
+       ret = regmap_write(twl6040->regmap, reg, val);
        /* Cache the vibra control registers */
        if (reg == TWL6040_REG_VIBCTLL || reg == TWL6040_REG_VIBCTLR)
                twl6040->vibra_ctrl_cache[VIBRACTRL_MEMBER(reg)] = val;
@@ -77,16 +79,9 @@ EXPORT_SYMBOL(twl6040_reg_write);
 int twl6040_set_bits(struct twl6040 *twl6040, unsigned int reg, u8 mask)
 {
        int ret;
-       u8 val;
 
        mutex_lock(&twl6040->io_mutex);
-       ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg);
-       if (ret)
-               goto out;
-
-       val |= mask;
-       ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg);
-out:
+       ret = regmap_update_bits(twl6040->regmap, reg, mask, mask);
        mutex_unlock(&twl6040->io_mutex);
        return ret;
 }
@@ -95,16 +90,9 @@ EXPORT_SYMBOL(twl6040_set_bits);
 int twl6040_clear_bits(struct twl6040 *twl6040, unsigned int reg, u8 mask)
 {
        int ret;
-       u8 val;
 
        mutex_lock(&twl6040->io_mutex);
-       ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg);
-       if (ret)
-               goto out;
-
-       val &= ~mask;
-       ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg);
-out:
+       ret = regmap_update_bits(twl6040->regmap, reg, mask, 0);
        mutex_unlock(&twl6040->io_mutex);
        return ret;
 }
@@ -494,32 +482,58 @@ static struct resource twl6040_codec_rsrc[] = {
        },
 };
 
-static int __devinit twl6040_probe(struct platform_device *pdev)
+static bool twl6040_readable_reg(struct device *dev, unsigned int reg)
 {
-       struct twl4030_audio_data *pdata = pdev->dev.platform_data;
+       /* Register 0 is not readable */
+       if (!reg)
+               return false;
+       return true;
+}
+
+static struct regmap_config twl6040_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+       .max_register = TWL6040_REG_STATUS, /* 0x2e */
+
+       .readable_reg = twl6040_readable_reg,
+};
+
+static int __devinit twl6040_probe(struct i2c_client *client,
+                                    const struct i2c_device_id *id)
+{
+       struct twl6040_platform_data *pdata = client->dev.platform_data;
        struct twl6040 *twl6040;
        struct mfd_cell *cell = NULL;
        int ret, children = 0;
 
        if (!pdata) {
-               dev_err(&pdev->dev, "Platform data is missing\n");
+               dev_err(&client->dev, "Platform data is missing\n");
                return -EINVAL;
        }
 
        /* In order to operate correctly we need valid interrupt config */
-       if (!pdata->naudint_irq || !pdata->irq_base) {
-               dev_err(&pdev->dev, "Invalid IRQ configuration\n");
+       if (!client->irq || !pdata->irq_base) {
+               dev_err(&client->dev, "Invalid IRQ configuration\n");
                return -EINVAL;
        }
 
-       twl6040 = kzalloc(sizeof(struct twl6040), GFP_KERNEL);
-       if (!twl6040)
-               return -ENOMEM;
+       twl6040 = devm_kzalloc(&client->dev, sizeof(struct twl6040),
+                              GFP_KERNEL);
+       if (!twl6040) {
+               ret = -ENOMEM;
+               goto err;
+       }
+
+       twl6040->regmap = regmap_init_i2c(client, &twl6040_regmap_config);
+       if (IS_ERR(twl6040->regmap)) {
+               ret = PTR_ERR(twl6040->regmap);
+               goto err;
+       }
 
-       platform_set_drvdata(pdev, twl6040);
+       i2c_set_clientdata(client, twl6040);
 
-       twl6040->dev = &pdev->dev;
-       twl6040->irq = pdata->naudint_irq;
+       twl6040->dev = &client->dev;
+       twl6040->irq = client->irq;
        twl6040->irq_base = pdata->irq_base;
 
        mutex_init(&twl6040->mutex);
@@ -588,12 +602,12 @@ static int __devinit twl6040_probe(struct platform_device *pdev)
        }
 
        if (children) {
-               ret = mfd_add_devices(&pdev->dev, pdev->id, twl6040->cells,
+               ret = mfd_add_devices(&client->dev, -1, twl6040->cells,
                                      children, NULL, 0);
                if (ret)
                        goto mfd_err;
        } else {
-               dev_err(&pdev->dev, "No platform data found for children\n");
+               dev_err(&client->dev, "No platform data found for children\n");
                ret = -ENODEV;
                goto mfd_err;
        }
@@ -608,14 +622,15 @@ gpio2_err:
        if (gpio_is_valid(twl6040->audpwron))
                gpio_free(twl6040->audpwron);
 gpio1_err:
-       platform_set_drvdata(pdev, NULL);
-       kfree(twl6040);
+       i2c_set_clientdata(client, NULL);
+       regmap_exit(twl6040->regmap);
+err:
        return ret;
 }
 
-static int __devexit twl6040_remove(struct platform_device *pdev)
+static int __devexit twl6040_remove(struct i2c_client *client)
 {
-       struct twl6040 *twl6040 = platform_get_drvdata(pdev);
+       struct twl6040 *twl6040 = i2c_get_clientdata(client);
 
        if (twl6040->power_count)
                twl6040_power(twl6040, 0);
@@ -626,23 +641,30 @@ static int __devexit twl6040_remove(struct platform_device *pdev)
        free_irq(twl6040->irq_base + TWL6040_IRQ_READY, twl6040);
        twl6040_irq_exit(twl6040);
 
-       mfd_remove_devices(&pdev->dev);
-       platform_set_drvdata(pdev, NULL);
-       kfree(twl6040);
+       mfd_remove_devices(&client->dev);
+       i2c_set_clientdata(client, NULL);
+       regmap_exit(twl6040->regmap);
 
        return 0;
 }
 
-static struct platform_driver twl6040_driver = {
+static const struct i2c_device_id twl6040_i2c_id[] = {
+       { "twl6040", 0, },
+       { },
+};
+MODULE_DEVICE_TABLE(i2c, twl6040_i2c_id);
+
+static struct i2c_driver twl6040_driver = {
+       .driver = {
+               .name = "twl6040",
+               .owner = THIS_MODULE,
+       },
        .probe          = twl6040_probe,
        .remove         = __devexit_p(twl6040_remove),
-       .driver         = {
-               .owner  = THIS_MODULE,
-               .name   = "twl6040",
-       },
+       .id_table       = twl6040_i2c_id,
 };
 
-module_platform_driver(twl6040_driver);
+module_i2c_driver(twl6040_driver);
 
 MODULE_DESCRIPTION("TWL6040 MFD");
 MODULE_AUTHOR("Misael Lopez Cruz <misael.lopez@ti.com>");
index b1809650b7aaebfb000dab7047e1172570f66b4a..dabec556ebb87421f04372ecf1452b645629ab17 100644 (file)
@@ -873,7 +873,7 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq,
 {
        struct mmc_blk_data *md = mq->data;
        struct mmc_card *card = md->queue.card;
-       unsigned int from, nr, arg;
+       unsigned int from, nr, arg, trim_arg, erase_arg;
        int err = 0, type = MMC_BLK_SECDISCARD;
 
        if (!(mmc_can_secure_erase_trim(card) || mmc_can_sanitize(card))) {
@@ -881,20 +881,26 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq,
                goto out;
        }
 
+       from = blk_rq_pos(req);
+       nr = blk_rq_sectors(req);
+
        /* The sanitize operation is supported at v4.5 only */
        if (mmc_can_sanitize(card)) {
-               err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-                               EXT_CSD_SANITIZE_START, 1, 0);
-               goto out;
+               erase_arg = MMC_ERASE_ARG;
+               trim_arg = MMC_TRIM_ARG;
+       } else {
+               erase_arg = MMC_SECURE_ERASE_ARG;
+               trim_arg = MMC_SECURE_TRIM1_ARG;
        }
 
-       from = blk_rq_pos(req);
-       nr = blk_rq_sectors(req);
-
-       if (mmc_can_trim(card) && !mmc_erase_group_aligned(card, from, nr))
-               arg = MMC_SECURE_TRIM1_ARG;
-       else
-               arg = MMC_SECURE_ERASE_ARG;
+       if (mmc_erase_group_aligned(card, from, nr))
+               arg = erase_arg;
+       else if (mmc_can_trim(card))
+               arg = trim_arg;
+       else {
+               err = -EINVAL;
+               goto out;
+       }
 retry:
        if (card->quirks & MMC_QUIRK_INAND_CMD38) {
                err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
@@ -904,25 +910,41 @@ retry:
                                 INAND_CMD38_ARG_SECERASE,
                                 0);
                if (err)
-                       goto out;
+                       goto out_retry;
        }
+
        err = mmc_erase(card, from, nr, arg);
-       if (!err && arg == MMC_SECURE_TRIM1_ARG) {
+       if (err == -EIO)
+               goto out_retry;
+       if (err)
+               goto out;
+
+       if (arg == MMC_SECURE_TRIM1_ARG) {
                if (card->quirks & MMC_QUIRK_INAND_CMD38) {
                        err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
                                         INAND_CMD38_ARG_EXT_CSD,
                                         INAND_CMD38_ARG_SECTRIM2,
                                         0);
                        if (err)
-                               goto out;
+                               goto out_retry;
                }
+
                err = mmc_erase(card, from, nr, MMC_SECURE_TRIM2_ARG);
+               if (err == -EIO)
+                       goto out_retry;
+               if (err)
+                       goto out;
        }
-out:
-       if (err == -EIO && !mmc_blk_reset(md, card->host, type))
+
+       if (mmc_can_sanitize(card))
+               err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+                                EXT_CSD_SANITIZE_START, 1, 0);
+out_retry:
+       if (err && !mmc_blk_reset(md, card->host, type))
                goto retry;
        if (!err)
                mmc_blk_reset_success(md, type);
+out:
        spin_lock_irq(&md->lock);
        __blk_end_request(req, err, blk_rq_bytes(req));
        spin_unlock_irq(&md->lock);
@@ -1802,7 +1824,7 @@ static void mmc_blk_remove(struct mmc_card *card)
 }
 
 #ifdef CONFIG_PM
-static int mmc_blk_suspend(struct mmc_card *card, pm_message_t state)
+static int mmc_blk_suspend(struct mmc_card *card)
 {
        struct mmc_blk_data *part_md;
        struct mmc_blk_data *md = mmc_get_drvdata(card);
index 2517547b4366a9bbdc6eea69ce1f1dc35ef09f08..996f8e36e23d8aa8bbf7c333fd6d6d56b8ec79ad 100644 (file)
@@ -139,7 +139,7 @@ static void mmc_queue_setup_discard(struct request_queue *q,
 
        queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q);
        q->limits.max_discard_sectors = max_discard;
-       if (card->erased_byte == 0)
+       if (card->erased_byte == 0 && !mmc_can_discard(card))
                q->limits.discard_zeroes_data = 1;
        q->limits.discard_granularity = card->pref_erase << 9;
        /* granularity must not be greater than max. discard */
index 3f606068d552ee738afe82516fff71bca47fc79d..c60cee92a2b2fe9bfd4a9b863dbc95d0e76e2eae 100644 (file)
@@ -122,14 +122,14 @@ static int mmc_bus_remove(struct device *dev)
        return 0;
 }
 
-static int mmc_bus_suspend(struct device *dev, pm_message_t state)
+static int mmc_bus_suspend(struct device *dev)
 {
        struct mmc_driver *drv = to_mmc_driver(dev->driver);
        struct mmc_card *card = mmc_dev_to_card(dev);
        int ret = 0;
 
        if (dev->driver && drv->suspend)
-               ret = drv->suspend(card, state);
+               ret = drv->suspend(card);
        return ret;
 }
 
@@ -165,20 +165,14 @@ static int mmc_runtime_idle(struct device *dev)
        return pm_runtime_suspend(dev);
 }
 
+#endif /* !CONFIG_PM_RUNTIME */
+
 static const struct dev_pm_ops mmc_bus_pm_ops = {
-       .runtime_suspend        = mmc_runtime_suspend,
-       .runtime_resume         = mmc_runtime_resume,
-       .runtime_idle           = mmc_runtime_idle,
+       SET_RUNTIME_PM_OPS(mmc_runtime_suspend, mmc_runtime_resume,
+                       mmc_runtime_idle)
+       SET_SYSTEM_SLEEP_PM_OPS(mmc_bus_suspend, mmc_bus_resume)
 };
 
-#define MMC_PM_OPS_PTR (&mmc_bus_pm_ops)
-
-#else /* !CONFIG_PM_RUNTIME */
-
-#define MMC_PM_OPS_PTR NULL
-
-#endif /* !CONFIG_PM_RUNTIME */
-
 static struct bus_type mmc_bus_type = {
        .name           = "mmc",
        .dev_attrs      = mmc_dev_attrs,
@@ -186,9 +180,7 @@ static struct bus_type mmc_bus_type = {
        .uevent         = mmc_bus_uevent,
        .probe          = mmc_bus_probe,
        .remove         = mmc_bus_remove,
-       .suspend        = mmc_bus_suspend,
-       .resume         = mmc_bus_resume,
-       .pm             = MMC_PM_OPS_PTR,
+       .pm             = &mmc_bus_pm_ops,
 };
 
 int mmc_register_bus(void)
index 29de31e260dda56da18d0345f15a3886c6c1063a..2c14be73254c385d9a481c89db978c7c82c1b6e9 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/gpio.h>
 #include <linux/interrupt.h>
 #include <linux/jiffies.h>
+#include <linux/mmc/cd-gpio.h>
 #include <linux/mmc/host.h>
 #include <linux/module.h>
 #include <linux/slab.h>
index 7474c47b9c084f3047c65930bb1517a2813a5298..ba821fe70bca03dd3fbf17661e150ff737af242c 100644 (file)
@@ -1409,7 +1409,10 @@ static unsigned int mmc_mmc_erase_timeout(struct mmc_card *card,
 {
        unsigned int erase_timeout;
 
-       if (card->ext_csd.erase_group_def & 1) {
+       if (arg == MMC_DISCARD_ARG ||
+           (arg == MMC_TRIM_ARG && card->ext_csd.rev >= 6)) {
+               erase_timeout = card->ext_csd.trim_timeout;
+       } else if (card->ext_csd.erase_group_def & 1) {
                /* High Capacity Erase Group Size uses HC timeouts */
                if (arg == MMC_TRIM_ARG)
                        erase_timeout = card->ext_csd.trim_timeout;
@@ -1681,8 +1684,6 @@ int mmc_can_trim(struct mmc_card *card)
 {
        if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN)
                return 1;
-       if (mmc_can_discard(card))
-               return 1;
        return 0;
 }
 EXPORT_SYMBOL(mmc_can_trim);
@@ -1701,6 +1702,8 @@ EXPORT_SYMBOL(mmc_can_discard);
 
 int mmc_can_sanitize(struct mmc_card *card)
 {
+       if (!mmc_can_trim(card) && !mmc_can_erase(card))
+               return 0;
        if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_SANITIZE)
                return 1;
        return 0;
@@ -2235,6 +2238,7 @@ int mmc_cache_ctrl(struct mmc_host *host, u8 enable)
                        mmc_card_is_removable(host))
                return err;
 
+       mmc_claim_host(host);
        if (card && mmc_card_mmc(card) &&
                        (card->ext_csd.cache_size > 0)) {
                enable = !!enable;
@@ -2252,6 +2256,7 @@ int mmc_cache_ctrl(struct mmc_host *host, u8 enable)
                                card->ext_csd.cache_ctrl = enable;
                }
        }
+       mmc_release_host(host);
 
        return err;
 }
@@ -2269,49 +2274,32 @@ int mmc_suspend_host(struct mmc_host *host)
 
        cancel_delayed_work(&host->detect);
        mmc_flush_scheduled_work();
-       if (mmc_try_claim_host(host)) {
-               err = mmc_cache_ctrl(host, 0);
-               mmc_release_host(host);
-       } else {
-               err = -EBUSY;
-       }
 
+       err = mmc_cache_ctrl(host, 0);
        if (err)
                goto out;
 
        mmc_bus_get(host);
        if (host->bus_ops && !host->bus_dead) {
 
-               /*
-                * A long response time is not acceptable for device drivers
-                * when doing suspend. Prevent mmc_claim_host in the suspend
-                * sequence, to potentially wait "forever" by trying to
-                * pre-claim the host.
-                */
-               if (mmc_try_claim_host(host)) {
-                       if (host->bus_ops->suspend) {
-                               err = host->bus_ops->suspend(host);
-                       }
-                       mmc_release_host(host);
+               if (host->bus_ops->suspend)
+                       err = host->bus_ops->suspend(host);
 
-                       if (err == -ENOSYS || !host->bus_ops->resume) {
-                               /*
-                                * We simply "remove" the card in this case.
-                                * It will be redetected on resume.  (Calling
-                                * bus_ops->remove() with a claimed host can
-                                * deadlock.)
-                                */
-                               if (host->bus_ops->remove)
-                                       host->bus_ops->remove(host);
-                               mmc_claim_host(host);
-                               mmc_detach_bus(host);
-                               mmc_power_off(host);
-                               mmc_release_host(host);
-                               host->pm_flags = 0;
-                               err = 0;
-                       }
-               } else {
-                       err = -EBUSY;
+               if (err == -ENOSYS || !host->bus_ops->resume) {
+                       /*
+                        * We simply "remove" the card in this case.
+                        * It will be redetected on resume.  (Calling
+                        * bus_ops->remove() with a claimed host can
+                        * deadlock.)
+                        */
+                       if (host->bus_ops->remove)
+                               host->bus_ops->remove(host);
+                       mmc_claim_host(host);
+                       mmc_detach_bus(host);
+                       mmc_power_off(host);
+                       mmc_release_host(host);
+                       host->pm_flags = 0;
+                       err = 0;
                }
        }
        mmc_bus_put(host);
index bf3c9b456aaf1080d6db5163eacefb3e7805787a..ab3fc46171079d4c8d07da35d5d00792032854d0 100644 (file)
@@ -526,8 +526,10 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data)
                return -ENODEV;
 
        sg_len = dw_mci_pre_dma_transfer(host, data, 0);
-       if (sg_len < 0)
+       if (sg_len < 0) {
+               host->dma_ops->stop(host);
                return sg_len;
+       }
 
        host->using_dma = 1;
 
@@ -1879,7 +1881,8 @@ static void dw_mci_init_dma(struct dw_mci *host)
        if (!host->dma_ops)
                goto no_dma;
 
-       if (host->dma_ops->init) {
+       if (host->dma_ops->init && host->dma_ops->start &&
+           host->dma_ops->stop && host->dma_ops->cleanup) {
                if (host->dma_ops->init(host)) {
                        dev_err(&host->dev, "%s: Unable to initialize "
                                "DMA Controller.\n", __func__);
index 5c2b1c10af9ce837c679180162db96ce345eb011..56d4499d43889e42a971fcfffb9bd0c334645294 100644 (file)
@@ -249,7 +249,7 @@ static int omap_hsmmc_set_power(struct device *dev, int slot, int power_on,
         * the pbias cell programming support is still missing when
         * booting with Device tree
         */
-       if (of_have_populated_dt() && !vdd)
+       if (dev->of_node && !vdd)
                return 0;
 
        if (mmc_slot(host).before_set_reg)
@@ -1549,7 +1549,7 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
                         * can't be allowed when booting with device
                         * tree.
                         */
-                       (!of_have_populated_dt())) {
+                       !host->dev->of_node) {
                                /*
                                 * The mmc_select_voltage fn of the core does
                                 * not seem to set the power_mode to
@@ -1741,7 +1741,7 @@ static const struct of_device_id omap_mmc_of_match[] = {
                .data = &omap4_reg_offset,
        },
        {},
-}
+};
 MODULE_DEVICE_TABLE(of, omap_mmc_of_match);
 
 static struct omap_mmc_platform_data *of_get_hsmmc_pdata(struct device *dev)
index 6193a0d7bde52b8cc29e52837179d90eed50faeb..8abdaf6697a8db6e0bf0949e9c54900cb2ac0889 100644 (file)
@@ -467,8 +467,7 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
        clk_prepare_enable(clk);
        pltfm_host->clk = clk;
 
-       if (!is_imx25_esdhc(imx_data))
-               host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
+       host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
 
        if (is_imx25_esdhc(imx_data) || is_imx35_esdhc(imx_data))
                /* Fix errata ENGcm07207 present on i.MX25 and i.MX35 */
index 9aa77f3f04a86ede55b30f93b3becbdc1498048e..ccefdebeff1458a6041f269c7494fc26cac0d8a3 100644 (file)
@@ -147,7 +147,7 @@ static void sdhci_set_card_detection(struct sdhci_host *host, bool enable)
        u32 present, irqs;
 
        if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) ||
-           !mmc_card_is_removable(host->mmc))
+           (host->mmc->caps & MMC_CAP_NONREMOVABLE))
                return;
 
        present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
index d20f1334792b06423c27e17c6fbda9833459e82e..111569ccab434dda8262e1ddeb3a9aab04043171 100644 (file)
@@ -991,8 +991,8 @@ static void pci_restore_config_dword(struct pci_dev *pdev, int offset,
        }
 }
 
-static void pci_restore_config_space(struct pci_dev *pdev, int start, int end,
-                                    int retry)
+static void pci_restore_config_space_range(struct pci_dev *pdev,
+                                          int start, int end, int retry)
 {
        int index;
 
@@ -1002,6 +1002,18 @@ static void pci_restore_config_space(struct pci_dev *pdev, int start, int end,
                                         retry);
 }
 
+static void pci_restore_config_space(struct pci_dev *pdev)
+{
+       if (pdev->hdr_type == PCI_HEADER_TYPE_NORMAL) {
+               pci_restore_config_space_range(pdev, 10, 15, 0);
+               /* Restore BARs before the command register. */
+               pci_restore_config_space_range(pdev, 4, 9, 10);
+               pci_restore_config_space_range(pdev, 0, 3, 0);
+       } else {
+               pci_restore_config_space_range(pdev, 0, 15, 0);
+       }
+}
+
 /** 
  * pci_restore_state - Restore the saved state of a PCI device
  * @dev: - PCI device that we're dealing with
@@ -1015,13 +1027,7 @@ void pci_restore_state(struct pci_dev *dev)
        pci_restore_pcie_state(dev);
        pci_restore_ats_state(dev);
 
-       pci_restore_config_space(dev, 10, 15, 0);
-       /*
-        * The Base Address register should be programmed before the command
-        * register(s)
-        */
-       pci_restore_config_space(dev, 4, 9, 10);
-       pci_restore_config_space(dev, 0, 3, 0);
+       pci_restore_config_space(dev);
 
        pci_restore_pcix_state(dev);
        pci_restore_msi_state(dev);
index f73a5ea89754cec60583a714eea9188342656465..de6e6845960564fa4afa4fc5a1b6dde50b068a03 100644 (file)
@@ -83,6 +83,8 @@ config PINCTRL_COH901
          COH 901 335 and COH 901 571/3. They contain 3, 5 or 7
          ports of 8 GPIO pins each.
 
+source "drivers/pinctrl/spear/Kconfig"
+
 endmenu
 
 endif
index 8e3c95a02fbd041281edc5ef11045e97dfed317f..03c97e2052bbeffcaf2d66d22795eb9276901170 100644 (file)
@@ -19,3 +19,5 @@ obj-$(CONFIG_PINCTRL_TEGRA20) += pinctrl-tegra20.o
 obj-$(CONFIG_PINCTRL_TEGRA30)  += pinctrl-tegra30.o
 obj-$(CONFIG_PINCTRL_U300)     += pinctrl-u300.o
 obj-$(CONFIG_PINCTRL_COH901)   += pinctrl-coh901.o
+
+obj-$(CONFIG_PLAT_SPEAR)       += spear/
diff --git a/drivers/pinctrl/spear/Kconfig b/drivers/pinctrl/spear/Kconfig
new file mode 100644 (file)
index 0000000..6a2596b
--- /dev/null
@@ -0,0 +1,34 @@
+#
+# ST Microelectronics SPEAr PINCTRL drivers
+#
+
+if PLAT_SPEAR
+
+config PINCTRL_SPEAR
+       bool
+       depends on OF
+       select PINMUX
+       help
+         This enables pin control drivers for SPEAr Platform
+
+config PINCTRL_SPEAR3XX
+       bool
+       depends on ARCH_SPEAR3XX
+       select PINCTRL_SPEAR
+
+config PINCTRL_SPEAR300
+       bool "ST Microelectronics SPEAr300 SoC pin controller driver"
+       depends on MACH_SPEAR300
+       select PINCTRL_SPEAR3XX
+
+config PINCTRL_SPEAR310
+       bool "ST Microelectronics SPEAr310 SoC pin controller driver"
+       depends on MACH_SPEAR310
+       select PINCTRL_SPEAR3XX
+
+config PINCTRL_SPEAR320
+       bool "ST Microelectronics SPEAr320 SoC pin controller driver"
+       depends on MACH_SPEAR320
+       select PINCTRL_SPEAR3XX
+
+endif
diff --git a/drivers/pinctrl/spear/Makefile b/drivers/pinctrl/spear/Makefile
new file mode 100644 (file)
index 0000000..15dcb85
--- /dev/null
@@ -0,0 +1,7 @@
+# SPEAr pinmux support
+
+obj-$(CONFIG_PINCTRL_SPEAR)    += pinctrl-spear.o
+obj-$(CONFIG_PINCTRL_SPEAR3XX) += pinctrl-spear3xx.o
+obj-$(CONFIG_PINCTRL_SPEAR300) += pinctrl-spear300.o
+obj-$(CONFIG_PINCTRL_SPEAR310) += pinctrl-spear310.o
+obj-$(CONFIG_PINCTRL_SPEAR320) += pinctrl-spear320.o
diff --git a/drivers/pinctrl/spear/pinctrl-spear.c b/drivers/pinctrl/spear/pinctrl-spear.c
new file mode 100644 (file)
index 0000000..5ae50aa
--- /dev/null
@@ -0,0 +1,354 @@
+/*
+ * Driver for the ST Microelectronics SPEAr pinmux
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.com>
+ *
+ * Inspired from:
+ * - U300 Pinctl drivers
+ * - Tegra Pinctl drivers
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/pinctrl/machine.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "pinctrl-spear.h"
+
+#define DRIVER_NAME "spear-pinmux"
+
+static inline u32 pmx_readl(struct spear_pmx *pmx, u32 reg)
+{
+       return readl_relaxed(pmx->vbase + reg);
+}
+
+static inline void pmx_writel(struct spear_pmx *pmx, u32 val, u32 reg)
+{
+       writel_relaxed(val, pmx->vbase + reg);
+}
+
+static int set_mode(struct spear_pmx *pmx, int mode)
+{
+       struct spear_pmx_mode *pmx_mode = NULL;
+       int i;
+       u32 val;
+
+       if (!pmx->machdata->pmx_modes || !pmx->machdata->npmx_modes)
+               return -EINVAL;
+
+       for (i = 0; i < pmx->machdata->npmx_modes; i++) {
+               if (pmx->machdata->pmx_modes[i]->mode == (1 << mode)) {
+                       pmx_mode = pmx->machdata->pmx_modes[i];
+                       break;
+               }
+       }
+
+       if (!pmx_mode)
+               return -EINVAL;
+
+       val = pmx_readl(pmx, pmx_mode->reg);
+       val &= ~pmx_mode->mask;
+       val |= pmx_mode->val;
+       pmx_writel(pmx, val, pmx_mode->reg);
+
+       pmx->machdata->mode = pmx_mode->mode;
+       dev_info(pmx->dev, "Configured Mode: %s with id: %x\n\n",
+                       pmx_mode->name ? pmx_mode->name : "no_name",
+                       pmx_mode->reg);
+
+       return 0;
+}
+
+void __devinit pmx_init_addr(struct spear_pinctrl_machdata *machdata, u16 reg)
+{
+       struct spear_pingroup *pgroup;
+       struct spear_modemux *modemux;
+       int i, j, group;
+
+       for (group = 0; group < machdata->ngroups; group++) {
+               pgroup = machdata->groups[group];
+
+               for (i = 0; i < pgroup->nmodemuxs; i++) {
+                       modemux = &pgroup->modemuxs[i];
+
+                       for (j = 0; j < modemux->nmuxregs; j++)
+                               if (modemux->muxregs[j].reg == 0xFFFF)
+                                       modemux->muxregs[j].reg = reg;
+               }
+       }
+}
+
+static int spear_pinctrl_get_groups_cnt(struct pinctrl_dev *pctldev)
+{
+       struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+       return pmx->machdata->ngroups;
+}
+
+static const char *spear_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
+               unsigned group)
+{
+       struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+       return pmx->machdata->groups[group]->name;
+}
+
+static int spear_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
+               unsigned group, const unsigned **pins, unsigned *num_pins)
+{
+       struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+       *pins = pmx->machdata->groups[group]->pins;
+       *num_pins = pmx->machdata->groups[group]->npins;
+
+       return 0;
+}
+
+static void spear_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
+               struct seq_file *s, unsigned offset)
+{
+       seq_printf(s, " " DRIVER_NAME);
+}
+
+int spear_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
+                                struct device_node *np_config,
+                                struct pinctrl_map **map, unsigned *num_maps)
+{
+       struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+       struct device_node *np;
+       struct property *prop;
+       const char *function, *group;
+       int ret, index = 0, count = 0;
+
+       /* calculate number of maps required */
+       for_each_child_of_node(np_config, np) {
+               ret = of_property_read_string(np, "st,function", &function);
+               if (ret < 0)
+                       return ret;
+
+               ret = of_property_count_strings(np, "st,pins");
+               if (ret < 0)
+                       return ret;
+
+               count += ret;
+       }
+
+       if (!count) {
+               dev_err(pmx->dev, "No child nodes passed via DT\n");
+               return -ENODEV;
+       }
+
+       *map = kzalloc(sizeof(**map) * count, GFP_KERNEL);
+       if (!*map)
+               return -ENOMEM;
+
+       for_each_child_of_node(np_config, np) {
+               of_property_read_string(np, "st,function", &function);
+               of_property_for_each_string(np, "st,pins", prop, group) {
+                       (*map)[index].type = PIN_MAP_TYPE_MUX_GROUP;
+                       (*map)[index].data.mux.group = group;
+                       (*map)[index].data.mux.function = function;
+                       index++;
+               }
+       }
+
+       *num_maps = count;
+
+       return 0;
+}
+
+void spear_pinctrl_dt_free_map(struct pinctrl_dev *pctldev,
+               struct pinctrl_map *map, unsigned num_maps)
+{
+       kfree(map);
+}
+
+static struct pinctrl_ops spear_pinctrl_ops = {
+       .get_groups_count = spear_pinctrl_get_groups_cnt,
+       .get_group_name = spear_pinctrl_get_group_name,
+       .get_group_pins = spear_pinctrl_get_group_pins,
+       .pin_dbg_show = spear_pinctrl_pin_dbg_show,
+       .dt_node_to_map = spear_pinctrl_dt_node_to_map,
+       .dt_free_map = spear_pinctrl_dt_free_map,
+};
+
+static int spear_pinctrl_get_funcs_count(struct pinctrl_dev *pctldev)
+{
+       struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+       return pmx->machdata->nfunctions;
+}
+
+static const char *spear_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
+               unsigned function)
+{
+       struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+       return pmx->machdata->functions[function]->name;
+}
+
+static int spear_pinctrl_get_func_groups(struct pinctrl_dev *pctldev,
+               unsigned function, const char *const **groups,
+               unsigned * const ngroups)
+{
+       struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+       *groups = pmx->machdata->functions[function]->groups;
+       *ngroups = pmx->machdata->functions[function]->ngroups;
+
+       return 0;
+}
+
+static int spear_pinctrl_endisable(struct pinctrl_dev *pctldev,
+               unsigned function, unsigned group, bool enable)
+{
+       struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+       const struct spear_pingroup *pgroup;
+       const struct spear_modemux *modemux;
+       struct spear_muxreg *muxreg;
+       u32 val, temp;
+       int i, j;
+       bool found = false;
+
+       pgroup = pmx->machdata->groups[group];
+
+       for (i = 0; i < pgroup->nmodemuxs; i++) {
+               modemux = &pgroup->modemuxs[i];
+
+               /* SoC have any modes */
+               if (pmx->machdata->modes_supported) {
+                       if (!(pmx->machdata->mode & modemux->modes))
+                               continue;
+               }
+
+               found = true;
+               for (j = 0; j < modemux->nmuxregs; j++) {
+                       muxreg = &modemux->muxregs[j];
+
+                       val = pmx_readl(pmx, muxreg->reg);
+                       val &= ~muxreg->mask;
+
+                       if (enable)
+                               temp = muxreg->val;
+                       else
+                               temp = ~muxreg->val;
+
+                       val |= temp;
+                       pmx_writel(pmx, val, muxreg->reg);
+               }
+       }
+
+       if (!found) {
+               dev_err(pmx->dev, "pinmux group: %s not supported\n",
+                               pgroup->name);
+               return -ENODEV;
+       }
+
+       return 0;
+}
+
+static int spear_pinctrl_enable(struct pinctrl_dev *pctldev, unsigned function,
+               unsigned group)
+{
+       return spear_pinctrl_endisable(pctldev, function, group, true);
+}
+
+static void spear_pinctrl_disable(struct pinctrl_dev *pctldev,
+               unsigned function, unsigned group)
+{
+       spear_pinctrl_endisable(pctldev, function, group, false);
+}
+
+static struct pinmux_ops spear_pinmux_ops = {
+       .get_functions_count = spear_pinctrl_get_funcs_count,
+       .get_function_name = spear_pinctrl_get_func_name,
+       .get_function_groups = spear_pinctrl_get_func_groups,
+       .enable = spear_pinctrl_enable,
+       .disable = spear_pinctrl_disable,
+};
+
+static struct pinctrl_desc spear_pinctrl_desc = {
+       .name = DRIVER_NAME,
+       .pctlops = &spear_pinctrl_ops,
+       .pmxops = &spear_pinmux_ops,
+       .owner = THIS_MODULE,
+};
+
+int __devinit spear_pinctrl_probe(struct platform_device *pdev,
+               struct spear_pinctrl_machdata *machdata)
+{
+       struct device_node *np = pdev->dev.of_node;
+       struct resource *res;
+       struct spear_pmx *pmx;
+
+       if (!machdata)
+               return -ENODEV;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res)
+               return -EINVAL;
+
+       pmx = devm_kzalloc(&pdev->dev, sizeof(*pmx), GFP_KERNEL);
+       if (!pmx) {
+               dev_err(&pdev->dev, "Can't alloc spear_pmx\n");
+               return -ENOMEM;
+       }
+
+       pmx->vbase = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+       if (!pmx->vbase) {
+               dev_err(&pdev->dev, "Couldn't ioremap at index 0\n");
+               return -ENODEV;
+       }
+
+       pmx->dev = &pdev->dev;
+       pmx->machdata = machdata;
+
+       /* configure mode, if supported by SoC */
+       if (machdata->modes_supported) {
+               int mode = 0;
+
+               if (of_property_read_u32(np, "st,pinmux-mode", &mode)) {
+                       dev_err(&pdev->dev, "OF: pinmux mode not passed\n");
+                       return -EINVAL;
+               }
+
+               if (set_mode(pmx, mode)) {
+                       dev_err(&pdev->dev, "OF: Couldn't configure mode: %x\n",
+                                       mode);
+                       return -EINVAL;
+               }
+       }
+
+       platform_set_drvdata(pdev, pmx);
+
+       spear_pinctrl_desc.pins = machdata->pins;
+       spear_pinctrl_desc.npins = machdata->npins;
+
+       pmx->pctl = pinctrl_register(&spear_pinctrl_desc, &pdev->dev, pmx);
+       if (IS_ERR(pmx->pctl)) {
+               dev_err(&pdev->dev, "Couldn't register pinctrl driver\n");
+               return PTR_ERR(pmx->pctl);
+       }
+
+       return 0;
+}
+
+int __devexit spear_pinctrl_remove(struct platform_device *pdev)
+{
+       struct spear_pmx *pmx = platform_get_drvdata(pdev);
+
+       pinctrl_unregister(pmx->pctl);
+
+       return 0;
+}
diff --git a/drivers/pinctrl/spear/pinctrl-spear.h b/drivers/pinctrl/spear/pinctrl-spear.h
new file mode 100644 (file)
index 0000000..47a6b5b
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * Driver header file for the ST Microelectronics SPEAr pinmux
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PINMUX_SPEAR_H__
+#define __PINMUX_SPEAR_H__
+
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/types.h>
+
+struct platform_device;
+struct device;
+
+/**
+ * struct spear_pmx_mode - SPEAr pmx mode
+ * @name: name of pmx mode
+ * @mode: mode id
+ * @reg: register for configuring this mode
+ * @mask: mask of this mode in reg
+ * @val: val to be configured at reg after doing (val & mask)
+ */
+struct spear_pmx_mode {
+       const char *const name;
+       u16 mode;
+       u16 reg;
+       u16 mask;
+       u32 val;
+};
+
+/**
+ * struct spear_muxreg - SPEAr mux reg configuration
+ * @reg: register offset
+ * @mask: mask bits
+ * @val: val to be written on mask bits
+ */
+struct spear_muxreg {
+       u16 reg;
+       u32 mask;
+       u32 val;
+};
+
+/**
+ * struct spear_modemux - SPEAr mode mux configuration
+ * @modes: mode ids supported by this group of muxregs
+ * @nmuxregs: number of muxreg configurations to be done for modes
+ * @muxregs: array of muxreg configurations to be done for modes
+ */
+struct spear_modemux {
+       u16 modes;
+       u8 nmuxregs;
+       struct spear_muxreg *muxregs;
+};
+
+/**
+ * struct spear_pingroup - SPEAr pin group configurations
+ * @name: name of pin group
+ * @pins: array containing pin numbers
+ * @npins: size of pins array
+ * @modemuxs: array of modemux configurations for this pin group
+ * @nmodemuxs: size of array modemuxs
+ *
+ * A representation of a group of pins in the SPEAr pin controller. Each group
+ * allows some parameter or parameters to be configured.
+ */
+struct spear_pingroup {
+       const char *name;
+       const unsigned *pins;
+       unsigned npins;
+       struct spear_modemux *modemuxs;
+       unsigned nmodemuxs;
+};
+
+/**
+ * struct spear_function - SPEAr pinctrl mux function
+ * @name: The name of the function, exported to pinctrl core.
+ * @groups: An array of pin groups that may select this function.
+ * @ngroups: The number of entries in @groups.
+ */
+struct spear_function {
+       const char *name;
+       const char *const *groups;
+       unsigned ngroups;
+};
+
+/**
+ * struct spear_pinctrl_machdata - SPEAr pin controller machine driver
+ *     configuration
+ * @pins: An array describing all pins the pin controller affects.
+ *     All pins which are also GPIOs must be listed first within the *array,
+ *     and be numbered identically to the GPIO controller's *numbering.
+ * @npins: The numbmer of entries in @pins.
+ * @functions: An array describing all mux functions the SoC supports.
+ * @nfunctions: The numbmer of entries in @functions.
+ * @groups: An array describing all pin groups the pin SoC supports.
+ * @ngroups: The numbmer of entries in @groups.
+ *
+ * @modes_supported: Does SoC support modes
+ * @mode: mode configured from probe
+ * @pmx_modes: array of modes supported by SoC
+ * @npmx_modes: number of entries in pmx_modes.
+ */
+struct spear_pinctrl_machdata {
+       const struct pinctrl_pin_desc *pins;
+       unsigned npins;
+       struct spear_function **functions;
+       unsigned nfunctions;
+       struct spear_pingroup **groups;
+       unsigned ngroups;
+
+       bool modes_supported;
+       u16 mode;
+       struct spear_pmx_mode **pmx_modes;
+       unsigned npmx_modes;
+};
+
+/**
+ * struct spear_pmx - SPEAr pinctrl mux
+ * @dev: pointer to struct dev of platform_device registered
+ * @pctl: pointer to struct pinctrl_dev
+ * @machdata: pointer to SoC or machine specific structure
+ * @vbase: virtual base address of pinmux controller
+ */
+struct spear_pmx {
+       struct device *dev;
+       struct pinctrl_dev *pctl;
+       struct spear_pinctrl_machdata *machdata;
+       void __iomem *vbase;
+};
+
+/* exported routines */
+void __devinit pmx_init_addr(struct spear_pinctrl_machdata *machdata, u16 reg);
+int __devinit spear_pinctrl_probe(struct platform_device *pdev,
+               struct spear_pinctrl_machdata *machdata);
+int __devexit spear_pinctrl_remove(struct platform_device *pdev);
+#endif /* __PINMUX_SPEAR_H__ */
diff --git a/drivers/pinctrl/spear/pinctrl-spear300.c b/drivers/pinctrl/spear/pinctrl-spear300.c
new file mode 100644 (file)
index 0000000..9c82a35
--- /dev/null
@@ -0,0 +1,708 @@
+/*
+ * Driver for the ST Microelectronics SPEAr300 pinmux
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include "pinctrl-spear3xx.h"
+
+#define DRIVER_NAME "spear300-pinmux"
+
+/* addresses */
+#define PMX_CONFIG_REG                 0x00
+#define MODE_CONFIG_REG                        0x04
+
+/* modes */
+#define NAND_MODE                      (1 << 0)
+#define NOR_MODE                       (1 << 1)
+#define PHOTO_FRAME_MODE               (1 << 2)
+#define LEND_IP_PHONE_MODE             (1 << 3)
+#define HEND_IP_PHONE_MODE             (1 << 4)
+#define LEND_WIFI_PHONE_MODE           (1 << 5)
+#define HEND_WIFI_PHONE_MODE           (1 << 6)
+#define ATA_PABX_WI2S_MODE             (1 << 7)
+#define ATA_PABX_I2S_MODE              (1 << 8)
+#define CAML_LCDW_MODE                 (1 << 9)
+#define CAMU_LCD_MODE                  (1 << 10)
+#define CAMU_WLCD_MODE                 (1 << 11)
+#define CAML_LCD_MODE                  (1 << 12)
+
+static struct spear_pmx_mode pmx_mode_nand = {
+       .name = "nand",
+       .mode = NAND_MODE,
+       .reg = MODE_CONFIG_REG,
+       .mask = 0x0000000F,
+       .val = 0x00,
+};
+
+static struct spear_pmx_mode pmx_mode_nor = {
+       .name = "nor",
+       .mode = NOR_MODE,
+       .reg = MODE_CONFIG_REG,
+       .mask = 0x0000000F,
+       .val = 0x01,
+};
+
+static struct spear_pmx_mode pmx_mode_photo_frame = {
+       .name = "photo frame mode",
+       .mode = PHOTO_FRAME_MODE,
+       .reg = MODE_CONFIG_REG,
+       .mask = 0x0000000F,
+       .val = 0x02,
+};
+
+static struct spear_pmx_mode pmx_mode_lend_ip_phone = {
+       .name = "lend ip phone mode",
+       .mode = LEND_IP_PHONE_MODE,
+       .reg = MODE_CONFIG_REG,
+       .mask = 0x0000000F,
+       .val = 0x03,
+};
+
+static struct spear_pmx_mode pmx_mode_hend_ip_phone = {
+       .name = "hend ip phone mode",
+       .mode = HEND_IP_PHONE_MODE,
+       .reg = MODE_CONFIG_REG,
+       .mask = 0x0000000F,
+       .val = 0x04,
+};
+
+static struct spear_pmx_mode pmx_mode_lend_wifi_phone = {
+       .name = "lend wifi phone mode",
+       .mode = LEND_WIFI_PHONE_MODE,
+       .reg = MODE_CONFIG_REG,
+       .mask = 0x0000000F,
+       .val = 0x05,
+};
+
+static struct spear_pmx_mode pmx_mode_hend_wifi_phone = {
+       .name = "hend wifi phone mode",
+       .mode = HEND_WIFI_PHONE_MODE,
+       .reg = MODE_CONFIG_REG,
+       .mask = 0x0000000F,
+       .val = 0x06,
+};
+
+static struct spear_pmx_mode pmx_mode_ata_pabx_wi2s = {
+       .name = "ata pabx wi2s mode",
+       .mode = ATA_PABX_WI2S_MODE,
+       .reg = MODE_CONFIG_REG,
+       .mask = 0x0000000F,
+       .val = 0x07,
+};
+
+static struct spear_pmx_mode pmx_mode_ata_pabx_i2s = {
+       .name = "ata pabx i2s mode",
+       .mode = ATA_PABX_I2S_MODE,
+       .reg = MODE_CONFIG_REG,
+       .mask = 0x0000000F,
+       .val = 0x08,
+};
+
+static struct spear_pmx_mode pmx_mode_caml_lcdw = {
+       .name = "caml lcdw mode",
+       .mode = CAML_LCDW_MODE,
+       .reg = MODE_CONFIG_REG,
+       .mask = 0x0000000F,
+       .val = 0x0C,
+};
+
+static struct spear_pmx_mode pmx_mode_camu_lcd = {
+       .name = "camu lcd mode",
+       .mode = CAMU_LCD_MODE,
+       .reg = MODE_CONFIG_REG,
+       .mask = 0x0000000F,
+       .val = 0x0D,
+};
+
+static struct spear_pmx_mode pmx_mode_camu_wlcd = {
+       .name = "camu wlcd mode",
+       .mode = CAMU_WLCD_MODE,
+       .reg = MODE_CONFIG_REG,
+       .mask = 0x0000000F,
+       .val = 0xE,
+};
+
+static struct spear_pmx_mode pmx_mode_caml_lcd = {
+       .name = "caml lcd mode",
+       .mode = CAML_LCD_MODE,
+       .reg = MODE_CONFIG_REG,
+       .mask = 0x0000000F,
+       .val = 0x0F,
+};
+
+static struct spear_pmx_mode *spear300_pmx_modes[] = {
+       &pmx_mode_nand,
+       &pmx_mode_nor,
+       &pmx_mode_photo_frame,
+       &pmx_mode_lend_ip_phone,
+       &pmx_mode_hend_ip_phone,
+       &pmx_mode_lend_wifi_phone,
+       &pmx_mode_hend_wifi_phone,
+       &pmx_mode_ata_pabx_wi2s,
+       &pmx_mode_ata_pabx_i2s,
+       &pmx_mode_caml_lcdw,
+       &pmx_mode_camu_lcd,
+       &pmx_mode_camu_wlcd,
+       &pmx_mode_caml_lcd,
+};
+
+/* fsmc_2chips_pins */
+static const unsigned fsmc_2chips_pins[] = { 1, 97 };
+static struct spear_muxreg fsmc_2chips_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_FIRDA_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_modemux fsmc_2chips_modemux[] = {
+       {
+               .modes = NAND_MODE | NOR_MODE | PHOTO_FRAME_MODE |
+                       ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE,
+               .muxregs = fsmc_2chips_muxreg,
+               .nmuxregs = ARRAY_SIZE(fsmc_2chips_muxreg),
+       },
+};
+
+static struct spear_pingroup fsmc_2chips_pingroup = {
+       .name = "fsmc_2chips_grp",
+       .pins = fsmc_2chips_pins,
+       .npins = ARRAY_SIZE(fsmc_2chips_pins),
+       .modemuxs = fsmc_2chips_modemux,
+       .nmodemuxs = ARRAY_SIZE(fsmc_2chips_modemux),
+};
+
+/* fsmc_4chips_pins */
+static const unsigned fsmc_4chips_pins[] = { 1, 2, 3, 97 };
+static struct spear_muxreg fsmc_4chips_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_FIRDA_MASK | PMX_UART0_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_modemux fsmc_4chips_modemux[] = {
+       {
+               .modes = NAND_MODE | NOR_MODE | PHOTO_FRAME_MODE |
+                       ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE,
+               .muxregs = fsmc_4chips_muxreg,
+               .nmuxregs = ARRAY_SIZE(fsmc_4chips_muxreg),
+       },
+};
+
+static struct spear_pingroup fsmc_4chips_pingroup = {
+       .name = "fsmc_4chips_grp",
+       .pins = fsmc_4chips_pins,
+       .npins = ARRAY_SIZE(fsmc_4chips_pins),
+       .modemuxs = fsmc_4chips_modemux,
+       .nmodemuxs = ARRAY_SIZE(fsmc_4chips_modemux),
+};
+
+static const char *const fsmc_grps[] = { "fsmc_2chips_grp", "fsmc_4chips_grp"
+};
+static struct spear_function fsmc_function = {
+       .name = "fsmc",
+       .groups = fsmc_grps,
+       .ngroups = ARRAY_SIZE(fsmc_grps),
+};
+
+/* clcd_lcdmode_pins */
+static const unsigned clcd_lcdmode_pins[] = { 49, 50 };
+static struct spear_muxreg clcd_lcdmode_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_modemux clcd_lcdmode_modemux[] = {
+       {
+               .modes = HEND_IP_PHONE_MODE | HEND_WIFI_PHONE_MODE |
+                       CAMU_LCD_MODE | CAML_LCD_MODE,
+               .muxregs = clcd_lcdmode_muxreg,
+               .nmuxregs = ARRAY_SIZE(clcd_lcdmode_muxreg),
+       },
+};
+
+static struct spear_pingroup clcd_lcdmode_pingroup = {
+       .name = "clcd_lcdmode_grp",
+       .pins = clcd_lcdmode_pins,
+       .npins = ARRAY_SIZE(clcd_lcdmode_pins),
+       .modemuxs = clcd_lcdmode_modemux,
+       .nmodemuxs = ARRAY_SIZE(clcd_lcdmode_modemux),
+};
+
+/* clcd_pfmode_pins */
+static const unsigned clcd_pfmode_pins[] = { 47, 48, 49, 50 };
+static struct spear_muxreg clcd_pfmode_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_TIMER_2_3_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_modemux clcd_pfmode_modemux[] = {
+       {
+               .modes = PHOTO_FRAME_MODE,
+               .muxregs = clcd_pfmode_muxreg,
+               .nmuxregs = ARRAY_SIZE(clcd_pfmode_muxreg),
+       },
+};
+
+static struct spear_pingroup clcd_pfmode_pingroup = {
+       .name = "clcd_pfmode_grp",
+       .pins = clcd_pfmode_pins,
+       .npins = ARRAY_SIZE(clcd_pfmode_pins),
+       .modemuxs = clcd_pfmode_modemux,
+       .nmodemuxs = ARRAY_SIZE(clcd_pfmode_modemux),
+};
+
+static const char *const clcd_grps[] = { "clcd_lcdmode_grp", "clcd_pfmode_grp"
+};
+static struct spear_function clcd_function = {
+       .name = "clcd",
+       .groups = clcd_grps,
+       .ngroups = ARRAY_SIZE(clcd_grps),
+};
+
+/* tdm_pins */
+static const unsigned tdm_pins[] = { 34, 35, 36, 37, 38 };
+static struct spear_muxreg tdm_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_UART0_MODEM_MASK | PMX_SSP_CS_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_modemux tdm_modemux[] = {
+       {
+               .modes = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE |
+                       HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE
+                       | HEND_WIFI_PHONE_MODE | ATA_PABX_WI2S_MODE
+                       | ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE
+                       | CAMU_WLCD_MODE | CAML_LCD_MODE,
+               .muxregs = tdm_muxreg,
+               .nmuxregs = ARRAY_SIZE(tdm_muxreg),
+       },
+};
+
+static struct spear_pingroup tdm_pingroup = {
+       .name = "tdm_grp",
+       .pins = tdm_pins,
+       .npins = ARRAY_SIZE(tdm_pins),
+       .modemuxs = tdm_modemux,
+       .nmodemuxs = ARRAY_SIZE(tdm_modemux),
+};
+
+static const char *const tdm_grps[] = { "tdm_grp" };
+static struct spear_function tdm_function = {
+       .name = "tdm",
+       .groups = tdm_grps,
+       .ngroups = ARRAY_SIZE(tdm_grps),
+};
+
+/* i2c_clk_pins */
+static const unsigned i2c_clk_pins[] = { 45, 46, 47, 48 };
+static struct spear_muxreg i2c_clk_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_modemux i2c_clk_modemux[] = {
+       {
+               .modes = LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE |
+                       LEND_WIFI_PHONE_MODE | HEND_WIFI_PHONE_MODE |
+                       ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE | CAML_LCDW_MODE
+                       | CAML_LCD_MODE,
+               .muxregs = i2c_clk_muxreg,
+               .nmuxregs = ARRAY_SIZE(i2c_clk_muxreg),
+       },
+};
+
+static struct spear_pingroup i2c_clk_pingroup = {
+       .name = "i2c_clk_grp_grp",
+       .pins = i2c_clk_pins,
+       .npins = ARRAY_SIZE(i2c_clk_pins),
+       .modemuxs = i2c_clk_modemux,
+       .nmodemuxs = ARRAY_SIZE(i2c_clk_modemux),
+};
+
+static const char *const i2c_grps[] = { "i2c_clk_grp" };
+static struct spear_function i2c_function = {
+       .name = "i2c1",
+       .groups = i2c_grps,
+       .ngroups = ARRAY_SIZE(i2c_grps),
+};
+
+/* caml_pins */
+static const unsigned caml_pins[] = { 12, 13, 14, 15, 16, 17, 18, 19, 20, 21 };
+static struct spear_muxreg caml_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_MII_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_modemux caml_modemux[] = {
+       {
+               .modes = CAML_LCDW_MODE | CAML_LCD_MODE,
+               .muxregs = caml_muxreg,
+               .nmuxregs = ARRAY_SIZE(caml_muxreg),
+       },
+};
+
+static struct spear_pingroup caml_pingroup = {
+       .name = "caml_grp",
+       .pins = caml_pins,
+       .npins = ARRAY_SIZE(caml_pins),
+       .modemuxs = caml_modemux,
+       .nmodemuxs = ARRAY_SIZE(caml_modemux),
+};
+
+/* camu_pins */
+static const unsigned camu_pins[] = { 16, 17, 18, 19, 20, 21, 45, 46, 47, 48 };
+static struct spear_muxreg camu_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK | PMX_MII_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_modemux camu_modemux[] = {
+       {
+               .modes = CAMU_LCD_MODE | CAMU_WLCD_MODE,
+               .muxregs = camu_muxreg,
+               .nmuxregs = ARRAY_SIZE(camu_muxreg),
+       },
+};
+
+static struct spear_pingroup camu_pingroup = {
+       .name = "camu_grp",
+       .pins = camu_pins,
+       .npins = ARRAY_SIZE(camu_pins),
+       .modemuxs = camu_modemux,
+       .nmodemuxs = ARRAY_SIZE(camu_modemux),
+};
+
+static const char *const cam_grps[] = { "caml_grp", "camu_grp" };
+static struct spear_function cam_function = {
+       .name = "cam",
+       .groups = cam_grps,
+       .ngroups = ARRAY_SIZE(cam_grps),
+};
+
+/* dac_pins */
+static const unsigned dac_pins[] = { 43, 44 };
+static struct spear_muxreg dac_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_TIMER_0_1_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_modemux dac_modemux[] = {
+       {
+               .modes = ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE
+                       | CAMU_WLCD_MODE | CAML_LCD_MODE,
+               .muxregs = dac_muxreg,
+               .nmuxregs = ARRAY_SIZE(dac_muxreg),
+       },
+};
+
+static struct spear_pingroup dac_pingroup = {
+       .name = "dac_grp",
+       .pins = dac_pins,
+       .npins = ARRAY_SIZE(dac_pins),
+       .modemuxs = dac_modemux,
+       .nmodemuxs = ARRAY_SIZE(dac_modemux),
+};
+
+static const char *const dac_grps[] = { "dac_grp" };
+static struct spear_function dac_function = {
+       .name = "dac",
+       .groups = dac_grps,
+       .ngroups = ARRAY_SIZE(dac_grps),
+};
+
+/* i2s_pins */
+static const unsigned i2s_pins[] = { 39, 40, 41, 42 };
+static struct spear_muxreg i2s_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_UART0_MODEM_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_modemux i2s_modemux[] = {
+       {
+               .modes = LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE
+                       | LEND_WIFI_PHONE_MODE | HEND_WIFI_PHONE_MODE |
+                       ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE
+                       | CAMU_WLCD_MODE | CAML_LCD_MODE,
+               .muxregs = i2s_muxreg,
+               .nmuxregs = ARRAY_SIZE(i2s_muxreg),
+       },
+};
+
+static struct spear_pingroup i2s_pingroup = {
+       .name = "i2s_grp",
+       .pins = i2s_pins,
+       .npins = ARRAY_SIZE(i2s_pins),
+       .modemuxs = i2s_modemux,
+       .nmodemuxs = ARRAY_SIZE(i2s_modemux),
+};
+
+static const char *const i2s_grps[] = { "i2s_grp" };
+static struct spear_function i2s_function = {
+       .name = "i2s",
+       .groups = i2s_grps,
+       .ngroups = ARRAY_SIZE(i2s_grps),
+};
+
+/* sdhci_4bit_pins */
+static const unsigned sdhci_4bit_pins[] = { 28, 29, 30, 31, 32, 33 };
+static struct spear_muxreg sdhci_4bit_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK |
+                       PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK |
+                       PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_modemux sdhci_4bit_modemux[] = {
+       {
+               .modes = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE |
+                       HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE |
+                       HEND_WIFI_PHONE_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE |
+                       CAMU_WLCD_MODE | CAML_LCD_MODE | ATA_PABX_WI2S_MODE,
+               .muxregs = sdhci_4bit_muxreg,
+               .nmuxregs = ARRAY_SIZE(sdhci_4bit_muxreg),
+       },
+};
+
+static struct spear_pingroup sdhci_4bit_pingroup = {
+       .name = "sdhci_4bit_grp",
+       .pins = sdhci_4bit_pins,
+       .npins = ARRAY_SIZE(sdhci_4bit_pins),
+       .modemuxs = sdhci_4bit_modemux,
+       .nmodemuxs = ARRAY_SIZE(sdhci_4bit_modemux),
+};
+
+/* sdhci_8bit_pins */
+static const unsigned sdhci_8bit_pins[] = { 24, 25, 26, 27, 28, 29, 30, 31, 32,
+       33 };
+static struct spear_muxreg sdhci_8bit_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK |
+                       PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK |
+                       PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK | PMX_MII_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_modemux sdhci_8bit_modemux[] = {
+       {
+               .modes = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE |
+                       HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE |
+                       HEND_WIFI_PHONE_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE |
+                       CAMU_WLCD_MODE | CAML_LCD_MODE,
+               .muxregs = sdhci_8bit_muxreg,
+               .nmuxregs = ARRAY_SIZE(sdhci_8bit_muxreg),
+       },
+};
+
+static struct spear_pingroup sdhci_8bit_pingroup = {
+       .name = "sdhci_8bit_grp",
+       .pins = sdhci_8bit_pins,
+       .npins = ARRAY_SIZE(sdhci_8bit_pins),
+       .modemuxs = sdhci_8bit_modemux,
+       .nmodemuxs = ARRAY_SIZE(sdhci_8bit_modemux),
+};
+
+static const char *const sdhci_grps[] = { "sdhci_4bit_grp", "sdhci_8bit_grp" };
+static struct spear_function sdhci_function = {
+       .name = "sdhci",
+       .groups = sdhci_grps,
+       .ngroups = ARRAY_SIZE(sdhci_grps),
+};
+
+/* gpio1_0_to_3_pins */
+static const unsigned gpio1_0_to_3_pins[] = { 39, 40, 41, 42 };
+static struct spear_muxreg gpio1_0_to_3_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_UART0_MODEM_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_modemux gpio1_0_to_3_modemux[] = {
+       {
+               .modes = PHOTO_FRAME_MODE,
+               .muxregs = gpio1_0_to_3_muxreg,
+               .nmuxregs = ARRAY_SIZE(gpio1_0_to_3_muxreg),
+       },
+};
+
+static struct spear_pingroup gpio1_0_to_3_pingroup = {
+       .name = "gpio1_0_to_3_grp",
+       .pins = gpio1_0_to_3_pins,
+       .npins = ARRAY_SIZE(gpio1_0_to_3_pins),
+       .modemuxs = gpio1_0_to_3_modemux,
+       .nmodemuxs = ARRAY_SIZE(gpio1_0_to_3_modemux),
+};
+
+/* gpio1_4_to_7_pins */
+static const unsigned gpio1_4_to_7_pins[] = { 43, 44, 45, 46 };
+
+static struct spear_muxreg gpio1_4_to_7_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_modemux gpio1_4_to_7_modemux[] = {
+       {
+               .modes = PHOTO_FRAME_MODE,
+               .muxregs = gpio1_4_to_7_muxreg,
+               .nmuxregs = ARRAY_SIZE(gpio1_4_to_7_muxreg),
+       },
+};
+
+static struct spear_pingroup gpio1_4_to_7_pingroup = {
+       .name = "gpio1_4_to_7_grp",
+       .pins = gpio1_4_to_7_pins,
+       .npins = ARRAY_SIZE(gpio1_4_to_7_pins),
+       .modemuxs = gpio1_4_to_7_modemux,
+       .nmodemuxs = ARRAY_SIZE(gpio1_4_to_7_modemux),
+};
+
+static const char *const gpio1_grps[] = { "gpio1_0_to_3_grp", "gpio1_4_to_7_grp"
+};
+static struct spear_function gpio1_function = {
+       .name = "gpio1",
+       .groups = gpio1_grps,
+       .ngroups = ARRAY_SIZE(gpio1_grps),
+};
+
+/* pingroups */
+static struct spear_pingroup *spear300_pingroups[] = {
+       SPEAR3XX_COMMON_PINGROUPS,
+       &fsmc_2chips_pingroup,
+       &fsmc_4chips_pingroup,
+       &clcd_lcdmode_pingroup,
+       &clcd_pfmode_pingroup,
+       &tdm_pingroup,
+       &i2c_clk_pingroup,
+       &caml_pingroup,
+       &camu_pingroup,
+       &dac_pingroup,
+       &i2s_pingroup,
+       &sdhci_4bit_pingroup,
+       &sdhci_8bit_pingroup,
+       &gpio1_0_to_3_pingroup,
+       &gpio1_4_to_7_pingroup,
+};
+
+/* functions */
+static struct spear_function *spear300_functions[] = {
+       SPEAR3XX_COMMON_FUNCTIONS,
+       &fsmc_function,
+       &clcd_function,
+       &tdm_function,
+       &i2c_function,
+       &cam_function,
+       &dac_function,
+       &i2s_function,
+       &sdhci_function,
+       &gpio1_function,
+};
+
+static struct of_device_id spear300_pinctrl_of_match[] __devinitdata = {
+       {
+               .compatible = "st,spear300-pinmux",
+       },
+       {},
+};
+
+static int __devinit spear300_pinctrl_probe(struct platform_device *pdev)
+{
+       int ret;
+
+       spear3xx_machdata.groups = spear300_pingroups;
+       spear3xx_machdata.ngroups = ARRAY_SIZE(spear300_pingroups);
+       spear3xx_machdata.functions = spear300_functions;
+       spear3xx_machdata.nfunctions = ARRAY_SIZE(spear300_functions);
+
+       spear3xx_machdata.modes_supported = true;
+       spear3xx_machdata.pmx_modes = spear300_pmx_modes;
+       spear3xx_machdata.npmx_modes = ARRAY_SIZE(spear300_pmx_modes);
+
+       pmx_init_addr(&spear3xx_machdata, PMX_CONFIG_REG);
+
+       ret = spear_pinctrl_probe(pdev, &spear3xx_machdata);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static int __devexit spear300_pinctrl_remove(struct platform_device *pdev)
+{
+       return spear_pinctrl_remove(pdev);
+}
+
+static struct platform_driver spear300_pinctrl_driver = {
+       .driver = {
+               .name = DRIVER_NAME,
+               .owner = THIS_MODULE,
+               .of_match_table = spear300_pinctrl_of_match,
+       },
+       .probe = spear300_pinctrl_probe,
+       .remove = __devexit_p(spear300_pinctrl_remove),
+};
+
+static int __init spear300_pinctrl_init(void)
+{
+       return platform_driver_register(&spear300_pinctrl_driver);
+}
+arch_initcall(spear300_pinctrl_init);
+
+static void __exit spear300_pinctrl_exit(void)
+{
+       platform_driver_unregister(&spear300_pinctrl_driver);
+}
+module_exit(spear300_pinctrl_exit);
+
+MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>");
+MODULE_DESCRIPTION("ST Microelectronics SPEAr300 pinctrl driver");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, spear300_pinctrl_of_match);
diff --git a/drivers/pinctrl/spear/pinctrl-spear310.c b/drivers/pinctrl/spear/pinctrl-spear310.c
new file mode 100644 (file)
index 0000000..1a97076
--- /dev/null
@@ -0,0 +1,431 @@
+/*
+ * Driver for the ST Microelectronics SPEAr310 pinmux
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include "pinctrl-spear3xx.h"
+
+#define DRIVER_NAME "spear310-pinmux"
+
+/* addresses */
+#define PMX_CONFIG_REG                 0x08
+
+/* emi_cs_0_to_5_pins */
+static const unsigned emi_cs_0_to_5_pins[] = { 45, 46, 47, 48, 49, 50 };
+static struct spear_muxreg emi_cs_0_to_5_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_modemux emi_cs_0_to_5_modemux[] = {
+       {
+               .muxregs = emi_cs_0_to_5_muxreg,
+               .nmuxregs = ARRAY_SIZE(emi_cs_0_to_5_muxreg),
+       },
+};
+
+static struct spear_pingroup emi_cs_0_to_5_pingroup = {
+       .name = "emi_cs_0_to_5_grp",
+       .pins = emi_cs_0_to_5_pins,
+       .npins = ARRAY_SIZE(emi_cs_0_to_5_pins),
+       .modemuxs = emi_cs_0_to_5_modemux,
+       .nmodemuxs = ARRAY_SIZE(emi_cs_0_to_5_modemux),
+};
+
+static const char *const emi_cs_0_to_5_grps[] = { "emi_cs_0_to_5_grp" };
+static struct spear_function emi_cs_0_to_5_function = {
+       .name = "emi",
+       .groups = emi_cs_0_to_5_grps,
+       .ngroups = ARRAY_SIZE(emi_cs_0_to_5_grps),
+};
+
+/* uart1_pins */
+static const unsigned uart1_pins[] = { 0, 1 };
+static struct spear_muxreg uart1_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_FIRDA_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_modemux uart1_modemux[] = {
+       {
+               .muxregs = uart1_muxreg,
+               .nmuxregs = ARRAY_SIZE(uart1_muxreg),
+       },
+};
+
+static struct spear_pingroup uart1_pingroup = {
+       .name = "uart1_grp",
+       .pins = uart1_pins,
+       .npins = ARRAY_SIZE(uart1_pins),
+       .modemuxs = uart1_modemux,
+       .nmodemuxs = ARRAY_SIZE(uart1_modemux),
+};
+
+static const char *const uart1_grps[] = { "uart1_grp" };
+static struct spear_function uart1_function = {
+       .name = "uart1",
+       .groups = uart1_grps,
+       .ngroups = ARRAY_SIZE(uart1_grps),
+};
+
+/* uart2_pins */
+static const unsigned uart2_pins[] = { 43, 44 };
+static struct spear_muxreg uart2_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_TIMER_0_1_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_modemux uart2_modemux[] = {
+       {
+               .muxregs = uart2_muxreg,
+               .nmuxregs = ARRAY_SIZE(uart2_muxreg),
+       },
+};
+
+static struct spear_pingroup uart2_pingroup = {
+       .name = "uart2_grp",
+       .pins = uart2_pins,
+       .npins = ARRAY_SIZE(uart2_pins),
+       .modemuxs = uart2_modemux,
+       .nmodemuxs = ARRAY_SIZE(uart2_modemux),
+};
+
+static const char *const uart2_grps[] = { "uart2_grp" };
+static struct spear_function uart2_function = {
+       .name = "uart2",
+       .groups = uart2_grps,
+       .ngroups = ARRAY_SIZE(uart2_grps),
+};
+
+/* uart3_pins */
+static const unsigned uart3_pins[] = { 37, 38 };
+static struct spear_muxreg uart3_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_UART0_MODEM_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_modemux uart3_modemux[] = {
+       {
+               .muxregs = uart3_muxreg,
+               .nmuxregs = ARRAY_SIZE(uart3_muxreg),
+       },
+};
+
+static struct spear_pingroup uart3_pingroup = {
+       .name = "uart3_grp",
+       .pins = uart3_pins,
+       .npins = ARRAY_SIZE(uart3_pins),
+       .modemuxs = uart3_modemux,
+       .nmodemuxs = ARRAY_SIZE(uart3_modemux),
+};
+
+static const char *const uart3_grps[] = { "uart3_grp" };
+static struct spear_function uart3_function = {
+       .name = "uart3",
+       .groups = uart3_grps,
+       .ngroups = ARRAY_SIZE(uart3_grps),
+};
+
+/* uart4_pins */
+static const unsigned uart4_pins[] = { 39, 40 };
+static struct spear_muxreg uart4_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_UART0_MODEM_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_modemux uart4_modemux[] = {
+       {
+               .muxregs = uart4_muxreg,
+               .nmuxregs = ARRAY_SIZE(uart4_muxreg),
+       },
+};
+
+static struct spear_pingroup uart4_pingroup = {
+       .name = "uart4_grp",
+       .pins = uart4_pins,
+       .npins = ARRAY_SIZE(uart4_pins),
+       .modemuxs = uart4_modemux,
+       .nmodemuxs = ARRAY_SIZE(uart4_modemux),
+};
+
+static const char *const uart4_grps[] = { "uart4_grp" };
+static struct spear_function uart4_function = {
+       .name = "uart4",
+       .groups = uart4_grps,
+       .ngroups = ARRAY_SIZE(uart4_grps),
+};
+
+/* uart5_pins */
+static const unsigned uart5_pins[] = { 41, 42 };
+static struct spear_muxreg uart5_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_UART0_MODEM_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_modemux uart5_modemux[] = {
+       {
+               .muxregs = uart5_muxreg,
+               .nmuxregs = ARRAY_SIZE(uart5_muxreg),
+       },
+};
+
+static struct spear_pingroup uart5_pingroup = {
+       .name = "uart5_grp",
+       .pins = uart5_pins,
+       .npins = ARRAY_SIZE(uart5_pins),
+       .modemuxs = uart5_modemux,
+       .nmodemuxs = ARRAY_SIZE(uart5_modemux),
+};
+
+static const char *const uart5_grps[] = { "uart5_grp" };
+static struct spear_function uart5_function = {
+       .name = "uart5",
+       .groups = uart5_grps,
+       .ngroups = ARRAY_SIZE(uart5_grps),
+};
+
+/* fsmc_pins */
+static const unsigned fsmc_pins[] = { 34, 35, 36 };
+static struct spear_muxreg fsmc_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_SSP_CS_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_modemux fsmc_modemux[] = {
+       {
+               .muxregs = fsmc_muxreg,
+               .nmuxregs = ARRAY_SIZE(fsmc_muxreg),
+       },
+};
+
+static struct spear_pingroup fsmc_pingroup = {
+       .name = "fsmc_grp",
+       .pins = fsmc_pins,
+       .npins = ARRAY_SIZE(fsmc_pins),
+       .modemuxs = fsmc_modemux,
+       .nmodemuxs = ARRAY_SIZE(fsmc_modemux),
+};
+
+static const char *const fsmc_grps[] = { "fsmc_grp" };
+static struct spear_function fsmc_function = {
+       .name = "fsmc",
+       .groups = fsmc_grps,
+       .ngroups = ARRAY_SIZE(fsmc_grps),
+};
+
+/* rs485_0_pins */
+static const unsigned rs485_0_pins[] = { 19, 20, 21, 22, 23 };
+static struct spear_muxreg rs485_0_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_MII_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_modemux rs485_0_modemux[] = {
+       {
+               .muxregs = rs485_0_muxreg,
+               .nmuxregs = ARRAY_SIZE(rs485_0_muxreg),
+       },
+};
+
+static struct spear_pingroup rs485_0_pingroup = {
+       .name = "rs485_0_grp",
+       .pins = rs485_0_pins,
+       .npins = ARRAY_SIZE(rs485_0_pins),
+       .modemuxs = rs485_0_modemux,
+       .nmodemuxs = ARRAY_SIZE(rs485_0_modemux),
+};
+
+static const char *const rs485_0_grps[] = { "rs485_0" };
+static struct spear_function rs485_0_function = {
+       .name = "rs485_0",
+       .groups = rs485_0_grps,
+       .ngroups = ARRAY_SIZE(rs485_0_grps),
+};
+
+/* rs485_1_pins */
+static const unsigned rs485_1_pins[] = { 14, 15, 16, 17, 18 };
+static struct spear_muxreg rs485_1_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_MII_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_modemux rs485_1_modemux[] = {
+       {
+               .muxregs = rs485_1_muxreg,
+               .nmuxregs = ARRAY_SIZE(rs485_1_muxreg),
+       },
+};
+
+static struct spear_pingroup rs485_1_pingroup = {
+       .name = "rs485_1_grp",
+       .pins = rs485_1_pins,
+       .npins = ARRAY_SIZE(rs485_1_pins),
+       .modemuxs = rs485_1_modemux,
+       .nmodemuxs = ARRAY_SIZE(rs485_1_modemux),
+};
+
+static const char *const rs485_1_grps[] = { "rs485_1" };
+static struct spear_function rs485_1_function = {
+       .name = "rs485_1",
+       .groups = rs485_1_grps,
+       .ngroups = ARRAY_SIZE(rs485_1_grps),
+};
+
+/* tdm_pins */
+static const unsigned tdm_pins[] = { 10, 11, 12, 13 };
+static struct spear_muxreg tdm_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_MII_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_modemux tdm_modemux[] = {
+       {
+               .muxregs = tdm_muxreg,
+               .nmuxregs = ARRAY_SIZE(tdm_muxreg),
+       },
+};
+
+static struct spear_pingroup tdm_pingroup = {
+       .name = "tdm_grp",
+       .pins = tdm_pins,
+       .npins = ARRAY_SIZE(tdm_pins),
+       .modemuxs = tdm_modemux,
+       .nmodemuxs = ARRAY_SIZE(tdm_modemux),
+};
+
+static const char *const tdm_grps[] = { "tdm_grp" };
+static struct spear_function tdm_function = {
+       .name = "tdm",
+       .groups = tdm_grps,
+       .ngroups = ARRAY_SIZE(tdm_grps),
+};
+
+/* pingroups */
+static struct spear_pingroup *spear310_pingroups[] = {
+       SPEAR3XX_COMMON_PINGROUPS,
+       &emi_cs_0_to_5_pingroup,
+       &uart1_pingroup,
+       &uart2_pingroup,
+       &uart3_pingroup,
+       &uart4_pingroup,
+       &uart5_pingroup,
+       &fsmc_pingroup,
+       &rs485_0_pingroup,
+       &rs485_1_pingroup,
+       &tdm_pingroup,
+};
+
+/* functions */
+static struct spear_function *spear310_functions[] = {
+       SPEAR3XX_COMMON_FUNCTIONS,
+       &emi_cs_0_to_5_function,
+       &uart1_function,
+       &uart2_function,
+       &uart3_function,
+       &uart4_function,
+       &uart5_function,
+       &fsmc_function,
+       &rs485_0_function,
+       &rs485_1_function,
+       &tdm_function,
+};
+
+static struct of_device_id spear310_pinctrl_of_match[] __devinitdata = {
+       {
+               .compatible = "st,spear310-pinmux",
+       },
+       {},
+};
+
+static int __devinit spear310_pinctrl_probe(struct platform_device *pdev)
+{
+       int ret;
+
+       spear3xx_machdata.groups = spear310_pingroups;
+       spear3xx_machdata.ngroups = ARRAY_SIZE(spear310_pingroups);
+       spear3xx_machdata.functions = spear310_functions;
+       spear3xx_machdata.nfunctions = ARRAY_SIZE(spear310_functions);
+
+       pmx_init_addr(&spear3xx_machdata, PMX_CONFIG_REG);
+
+       spear3xx_machdata.modes_supported = false;
+
+       ret = spear_pinctrl_probe(pdev, &spear3xx_machdata);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static int __devexit spear310_pinctrl_remove(struct platform_device *pdev)
+{
+       return spear_pinctrl_remove(pdev);
+}
+
+static struct platform_driver spear310_pinctrl_driver = {
+       .driver = {
+               .name = DRIVER_NAME,
+               .owner = THIS_MODULE,
+               .of_match_table = spear310_pinctrl_of_match,
+       },
+       .probe = spear310_pinctrl_probe,
+       .remove = __devexit_p(spear310_pinctrl_remove),
+};
+
+static int __init spear310_pinctrl_init(void)
+{
+       return platform_driver_register(&spear310_pinctrl_driver);
+}
+arch_initcall(spear310_pinctrl_init);
+
+static void __exit spear310_pinctrl_exit(void)
+{
+       platform_driver_unregister(&spear310_pinctrl_driver);
+}
+module_exit(spear310_pinctrl_exit);
+
+MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>");
+MODULE_DESCRIPTION("ST Microelectronics SPEAr310 pinctrl driver");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, SPEAr310_pinctrl_of_match);
diff --git a/drivers/pinctrl/spear/pinctrl-spear320.c b/drivers/pinctrl/spear/pinctrl-spear320.c
new file mode 100644 (file)
index 0000000..de726e6
--- /dev/null
@@ -0,0 +1,3468 @@
+/*
+ * Driver for the ST Microelectronics SPEAr320 pinmux
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include "pinctrl-spear3xx.h"
+
+#define DRIVER_NAME "spear320-pinmux"
+
+/* addresses */
+#define PMX_CONFIG_REG                 0x0C
+#define MODE_CONFIG_REG                        0x10
+#define MODE_EXT_CONFIG_REG            0x18
+
+/* modes */
+#define AUTO_NET_SMII_MODE     (1 << 0)
+#define AUTO_NET_MII_MODE      (1 << 1)
+#define AUTO_EXP_MODE          (1 << 2)
+#define SMALL_PRINTERS_MODE    (1 << 3)
+#define EXTENDED_MODE          (1 << 4)
+
+static struct spear_pmx_mode pmx_mode_auto_net_smii = {
+       .name = "Automation Networking SMII mode",
+       .mode = AUTO_NET_SMII_MODE,
+       .reg = MODE_CONFIG_REG,
+       .mask = 0x00000007,
+       .val = 0x0,
+};
+
+static struct spear_pmx_mode pmx_mode_auto_net_mii = {
+       .name = "Automation Networking MII mode",
+       .mode = AUTO_NET_MII_MODE,
+       .reg = MODE_CONFIG_REG,
+       .mask = 0x00000007,
+       .val = 0x1,
+};
+
+static struct spear_pmx_mode pmx_mode_auto_exp = {
+       .name = "Automation Expanded mode",
+       .mode = AUTO_EXP_MODE,
+       .reg = MODE_CONFIG_REG,
+       .mask = 0x00000007,
+       .val = 0x2,
+};
+
+static struct spear_pmx_mode pmx_mode_small_printers = {
+       .name = "Small Printers mode",
+       .mode = SMALL_PRINTERS_MODE,
+       .reg = MODE_CONFIG_REG,
+       .mask = 0x00000007,
+       .val = 0x3,
+};
+
+static struct spear_pmx_mode pmx_mode_extended = {
+       .name = "extended mode",
+       .mode = EXTENDED_MODE,
+       .reg = MODE_EXT_CONFIG_REG,
+       .mask = 0x00000001,
+       .val = 0x1,
+};
+
+static struct spear_pmx_mode *spear320_pmx_modes[] = {
+       &pmx_mode_auto_net_smii,
+       &pmx_mode_auto_net_mii,
+       &pmx_mode_auto_exp,
+       &pmx_mode_small_printers,
+       &pmx_mode_extended,
+};
+
+/* Extended mode registers and their offsets */
+#define EXT_CTRL_REG                           0x0018
+       #define MII_MDIO_MASK                   (1 << 4)
+       #define MII_MDIO_10_11_VAL              0
+       #define MII_MDIO_81_VAL                 (1 << 4)
+       #define EMI_FSMC_DYNAMIC_MUX_MASK       (1 << 5)
+       #define MAC_MODE_MII                    0
+       #define MAC_MODE_RMII                   1
+       #define MAC_MODE_SMII                   2
+       #define MAC_MODE_SS_SMII                3
+       #define MAC_MODE_MASK                   0x3
+       #define MAC1_MODE_SHIFT                 16
+       #define MAC2_MODE_SHIFT                 18
+
+#define IP_SEL_PAD_0_9_REG                     0x00A4
+       #define PMX_PL_0_1_MASK                 (0x3F << 0)
+       #define PMX_UART2_PL_0_1_VAL            0x0
+       #define PMX_I2C2_PL_0_1_VAL             (0x4 | (0x4 << 3))
+
+       #define PMX_PL_2_3_MASK                 (0x3F << 6)
+       #define PMX_I2C2_PL_2_3_VAL             0x0
+       #define PMX_UART6_PL_2_3_VAL            ((0x1 << 6) | (0x1 << 9))
+       #define PMX_UART1_ENH_PL_2_3_VAL        ((0x4 << 6) | (0x4 << 9))
+
+       #define PMX_PL_4_5_MASK                 (0x3F << 12)
+       #define PMX_UART5_PL_4_5_VAL            ((0x1 << 12) | (0x1 << 15))
+       #define PMX_UART1_ENH_PL_4_5_VAL        ((0x4 << 12) | (0x4 << 15))
+       #define PMX_PL_5_MASK                   (0x7 << 15)
+       #define PMX_TOUCH_Y_PL_5_VAL            0x0
+
+       #define PMX_PL_6_7_MASK                 (0x3F << 18)
+       #define PMX_PL_6_MASK                   (0x7 << 18)
+       #define PMX_PL_7_MASK                   (0x7 << 21)
+       #define PMX_UART4_PL_6_7_VAL            ((0x1 << 18) | (0x1 << 21))
+       #define PMX_PWM_3_PL_6_VAL              (0x2 << 18)
+       #define PMX_PWM_2_PL_7_VAL              (0x2 << 21)
+       #define PMX_UART1_ENH_PL_6_7_VAL        ((0x4 << 18) | (0x4 << 21))
+
+       #define PMX_PL_8_9_MASK                 (0x3F << 24)
+       #define PMX_UART3_PL_8_9_VAL            ((0x1 << 24) | (0x1 << 27))
+       #define PMX_PWM_0_1_PL_8_9_VAL          ((0x2 << 24) | (0x2 << 27))
+       #define PMX_I2C1_PL_8_9_VAL             ((0x4 << 24) | (0x4 << 27))
+
+#define IP_SEL_PAD_10_19_REG                   0x00A8
+       #define PMX_PL_10_11_MASK               (0x3F << 0)
+       #define PMX_SMII_PL_10_11_VAL           0
+       #define PMX_RMII_PL_10_11_VAL           ((0x4 << 0) | (0x4 << 3))
+
+       #define PMX_PL_12_MASK                  (0x7 << 6)
+       #define PMX_PWM3_PL_12_VAL              0
+       #define PMX_SDHCI_CD_PL_12_VAL          (0x4 << 6)
+
+       #define PMX_PL_13_14_MASK               (0x3F << 9)
+       #define PMX_PL_13_MASK                  (0x7 << 9)
+       #define PMX_PL_14_MASK                  (0x7 << 12)
+       #define PMX_SSP2_PL_13_14_15_16_VAL     0
+       #define PMX_UART4_PL_13_14_VAL          ((0x1 << 9) | (0x1 << 12))
+       #define PMX_RMII_PL_13_14_VAL           ((0x4 << 9) | (0x4 << 12))
+       #define PMX_PWM2_PL_13_VAL              (0x2 << 9)
+       #define PMX_PWM1_PL_14_VAL              (0x2 << 12)
+
+       #define PMX_PL_15_MASK                  (0x7 << 15)
+       #define PMX_PWM0_PL_15_VAL              (0x2 << 15)
+       #define PMX_PL_15_16_MASK               (0x3F << 15)
+       #define PMX_UART3_PL_15_16_VAL          ((0x1 << 15) | (0x1 << 18))
+       #define PMX_RMII_PL_15_16_VAL           ((0x4 << 15) | (0x4 << 18))
+
+       #define PMX_PL_17_18_MASK               (0x3F << 21)
+       #define PMX_SSP1_PL_17_18_19_20_VAL     0
+       #define PMX_RMII_PL_17_18_VAL           ((0x4 << 21) | (0x4 << 24))
+
+       #define PMX_PL_19_MASK                  (0x7 << 27)
+       #define PMX_I2C2_PL_19_VAL              (0x1 << 27)
+       #define PMX_RMII_PL_19_VAL              (0x4 << 27)
+
+#define IP_SEL_PAD_20_29_REG                   0x00AC
+       #define PMX_PL_20_MASK                  (0x7 << 0)
+       #define PMX_I2C2_PL_20_VAL              (0x1 << 0)
+       #define PMX_RMII_PL_20_VAL              (0x4 << 0)
+
+       #define PMX_PL_21_TO_27_MASK            (0x1FFFFF << 3)
+       #define PMX_SMII_PL_21_TO_27_VAL        0
+       #define PMX_RMII_PL_21_TO_27_VAL        ((0x4 << 3) | (0x4 << 6) | (0x4 << 9) | (0x4 << 12) | (0x4 << 15) | (0x4 << 18) | (0x4 << 21))
+
+       #define PMX_PL_28_29_MASK               (0x3F << 24)
+       #define PMX_PL_28_MASK                  (0x7 << 24)
+       #define PMX_PL_29_MASK                  (0x7 << 27)
+       #define PMX_UART1_PL_28_29_VAL          0
+       #define PMX_PWM_3_PL_28_VAL             (0x4 << 24)
+       #define PMX_PWM_2_PL_29_VAL             (0x4 << 27)
+
+#define IP_SEL_PAD_30_39_REG                   0x00B0
+       #define PMX_PL_30_31_MASK               (0x3F << 0)
+       #define PMX_CAN1_PL_30_31_VAL           (0)
+       #define PMX_PL_30_MASK                  (0x7 << 0)
+       #define PMX_PL_31_MASK                  (0x7 << 3)
+       #define PMX_PWM1_EXT_PL_30_VAL          (0x4 << 0)
+       #define PMX_PWM0_EXT_PL_31_VAL          (0x4 << 3)
+       #define PMX_UART1_ENH_PL_31_VAL         (0x3 << 3)
+
+       #define PMX_PL_32_33_MASK               (0x3F << 6)
+       #define PMX_CAN0_PL_32_33_VAL           0
+       #define PMX_UART1_ENH_PL_32_33_VAL      ((0x3 << 6) | (0x3 << 9))
+       #define PMX_SSP2_PL_32_33_VAL           ((0x4 << 6) | (0x4 << 9))
+
+       #define PMX_PL_34_MASK                  (0x7 << 12)
+       #define PMX_PWM2_PL_34_VAL              0
+       #define PMX_UART1_ENH_PL_34_VAL         (0x2 << 12)
+       #define PMX_SSP2_PL_34_VAL              (0x4 << 12)
+
+       #define PMX_PL_35_MASK                  (0x7 << 15)
+       #define PMX_I2S_REF_CLK_PL_35_VAL       0
+       #define PMX_UART1_ENH_PL_35_VAL         (0x2 << 15)
+       #define PMX_SSP2_PL_35_VAL              (0x4 << 15)
+
+       #define PMX_PL_36_MASK                  (0x7 << 18)
+       #define PMX_TOUCH_X_PL_36_VAL           0
+       #define PMX_UART1_ENH_PL_36_VAL         (0x2 << 18)
+       #define PMX_SSP1_PL_36_VAL              (0x4 << 18)
+
+       #define PMX_PL_37_38_MASK               (0x3F << 21)
+       #define PMX_PWM0_1_PL_37_38_VAL         0
+       #define PMX_UART5_PL_37_38_VAL          ((0x2 << 21) | (0x2 << 24))
+       #define PMX_SSP1_PL_37_38_VAL           ((0x4 << 21) | (0x4 << 24))
+
+       #define PMX_PL_39_MASK                  (0x7 << 27)
+       #define PMX_I2S_PL_39_VAL               0
+       #define PMX_UART4_PL_39_VAL             (0x2 << 27)
+       #define PMX_SSP1_PL_39_VAL              (0x4 << 27)
+
+#define IP_SEL_PAD_40_49_REG                   0x00B4
+       #define PMX_PL_40_MASK                  (0x7 << 0)
+       #define PMX_I2S_PL_40_VAL               0
+       #define PMX_UART4_PL_40_VAL             (0x2 << 0)
+       #define PMX_PWM3_PL_40_VAL              (0x4 << 0)
+
+       #define PMX_PL_41_42_MASK               (0x3F << 3)
+       #define PMX_PL_41_MASK                  (0x7 << 3)
+       #define PMX_PL_42_MASK                  (0x7 << 6)
+       #define PMX_I2S_PL_41_42_VAL            0
+       #define PMX_UART3_PL_41_42_VAL          ((0x2 << 3) | (0x2 << 6))
+       #define PMX_PWM2_PL_41_VAL              (0x4 << 3)
+       #define PMX_PWM1_PL_42_VAL              (0x4 << 6)
+
+       #define PMX_PL_43_MASK                  (0x7 << 9)
+       #define PMX_SDHCI_PL_43_VAL             0
+       #define PMX_UART1_ENH_PL_43_VAL         (0x2 << 9)
+       #define PMX_PWM0_PL_43_VAL              (0x4 << 9)
+
+       #define PMX_PL_44_45_MASK               (0x3F << 12)
+       #define PMX_SDHCI_PL_44_45_VAL  0
+       #define PMX_UART1_ENH_PL_44_45_VAL      ((0x2 << 12) | (0x2 << 15))
+       #define PMX_SSP2_PL_44_45_VAL           ((0x4 << 12) | (0x4 << 15))
+
+       #define PMX_PL_46_47_MASK               (0x3F << 18)
+       #define PMX_SDHCI_PL_46_47_VAL  0
+       #define PMX_FSMC_EMI_PL_46_47_VAL       ((0x2 << 18) | (0x2 << 21))
+       #define PMX_SSP2_PL_46_47_VAL           ((0x4 << 18) | (0x4 << 21))
+
+       #define PMX_PL_48_49_MASK               (0x3F << 24)
+       #define PMX_SDHCI_PL_48_49_VAL  0
+       #define PMX_FSMC_EMI_PL_48_49_VAL       ((0x2 << 24) | (0x2 << 27))
+       #define PMX_SSP1_PL_48_49_VAL           ((0x4 << 24) | (0x4 << 27))
+
+#define IP_SEL_PAD_50_59_REG                   0x00B8
+       #define PMX_PL_50_51_MASK               (0x3F << 0)
+       #define PMX_EMI_PL_50_51_VAL            ((0x2 << 0) | (0x2 << 3))
+       #define PMX_SSP1_PL_50_51_VAL           ((0x4 << 0) | (0x4 << 3))
+       #define PMX_PL_50_MASK                  (0x7 << 0)
+       #define PMX_PL_51_MASK                  (0x7 << 3)
+       #define PMX_SDHCI_PL_50_VAL             0
+       #define PMX_SDHCI_CD_PL_51_VAL          0
+
+       #define PMX_PL_52_53_MASK               (0x3F << 6)
+       #define PMX_FSMC_PL_52_53_VAL           0
+       #define PMX_EMI_PL_52_53_VAL            ((0x2 << 6) | (0x2 << 9))
+       #define PMX_UART3_PL_52_53_VAL          ((0x4 << 6) | (0x4 << 9))
+
+       #define PMX_PL_54_55_56_MASK            (0x1FF << 12)
+       #define PMX_FSMC_EMI_PL_54_55_56_VAL    ((0x2 << 12) | (0x2 << 15) | (0x2 << 18))
+
+       #define PMX_PL_57_MASK                  (0x7 << 21)
+       #define PMX_FSMC_PL_57_VAL              0
+       #define PMX_PWM3_PL_57_VAL              (0x4 << 21)
+
+       #define PMX_PL_58_59_MASK               (0x3F << 24)
+       #define PMX_PL_58_MASK                  (0x7 << 24)
+       #define PMX_PL_59_MASK                  (0x7 << 27)
+       #define PMX_FSMC_EMI_PL_58_59_VAL       ((0x2 << 24) | (0x2 << 27))
+       #define PMX_PWM2_PL_58_VAL              (0x4 << 24)
+       #define PMX_PWM1_PL_59_VAL              (0x4 << 27)
+
+#define IP_SEL_PAD_60_69_REG                   0x00BC
+       #define PMX_PL_60_MASK                  (0x7 << 0)
+       #define PMX_FSMC_PL_60_VAL              0
+       #define PMX_PWM0_PL_60_VAL              (0x4 << 0)
+
+       #define PMX_PL_61_TO_64_MASK            (0xFFF << 3)
+       #define PMX_FSMC_PL_61_TO_64_VAL        ((0x2 << 3) | (0x2 << 6) | (0x2 << 9) | (0x2 << 12))
+       #define PMX_SSP2_PL_61_TO_64_VAL        ((0x4 << 3) | (0x4 << 6) | (0x4 << 9) | (0x4 << 12))
+
+       #define PMX_PL_65_TO_68_MASK            (0xFFF << 15)
+       #define PMX_FSMC_PL_65_TO_68_VAL        ((0x2 << 15) | (0x2 << 18) | (0x2 << 21) | (0x2 << 24))
+       #define PMX_SSP1_PL_65_TO_68_VAL        ((0x4 << 15) | (0x4 << 18) | (0x4 << 21) | (0x4 << 24))
+
+       #define PMX_PL_69_MASK                  (0x7 << 27)
+       #define PMX_CLCD_PL_69_VAL              (0)
+       #define PMX_EMI_PL_69_VAL               (0x2 << 27)
+       #define PMX_SPP_PL_69_VAL               (0x3 << 27)
+       #define PMX_UART5_PL_69_VAL             (0x4 << 27)
+
+#define IP_SEL_PAD_70_79_REG                   0x00C0
+       #define PMX_PL_70_MASK                  (0x7 << 0)
+       #define PMX_CLCD_PL_70_VAL              (0)
+       #define PMX_FSMC_EMI_PL_70_VAL          (0x2 << 0)
+       #define PMX_SPP_PL_70_VAL               (0x3 << 0)
+       #define PMX_UART5_PL_70_VAL             (0x4 << 0)
+
+       #define PMX_PL_71_72_MASK               (0x3F << 3)
+       #define PMX_CLCD_PL_71_72_VAL           (0)
+       #define PMX_FSMC_EMI_PL_71_72_VAL       ((0x2 << 3) | (0x2 << 6))
+       #define PMX_SPP_PL_71_72_VAL            ((0x3 << 3) | (0x3 << 6))
+       #define PMX_UART4_PL_71_72_VAL          ((0x4 << 3) | (0x4 << 6))
+
+       #define PMX_PL_73_MASK                  (0x7 << 9)
+       #define PMX_CLCD_PL_73_VAL              (0)
+       #define PMX_FSMC_EMI_PL_73_VAL          (0x2 << 9)
+       #define PMX_SPP_PL_73_VAL               (0x3 << 9)
+       #define PMX_UART3_PL_73_VAL             (0x4 << 9)
+
+       #define PMX_PL_74_MASK                  (0x7 << 12)
+       #define PMX_CLCD_PL_74_VAL              (0)
+       #define PMX_EMI_PL_74_VAL               (0x2 << 12)
+       #define PMX_SPP_PL_74_VAL               (0x3 << 12)
+       #define PMX_UART3_PL_74_VAL             (0x4 << 12)
+
+       #define PMX_PL_75_76_MASK               (0x3F << 15)
+       #define PMX_CLCD_PL_75_76_VAL           (0)
+       #define PMX_EMI_PL_75_76_VAL            ((0x2 << 15) | (0x2 << 18))
+       #define PMX_SPP_PL_75_76_VAL            ((0x3 << 15) | (0x3 << 18))
+       #define PMX_I2C2_PL_75_76_VAL           ((0x4 << 15) | (0x4 << 18))
+
+       #define PMX_PL_77_78_79_MASK            (0x1FF << 21)
+       #define PMX_CLCD_PL_77_78_79_VAL        (0)
+       #define PMX_EMI_PL_77_78_79_VAL         ((0x2 << 21) | (0x2 << 24) | (0x2 << 27))
+       #define PMX_SPP_PL_77_78_79_VAL         ((0x3 << 21) | (0x3 << 24) | (0x3 << 27))
+       #define PMX_RS485_PL_77_78_79_VAL       ((0x4 << 21) | (0x4 << 24) | (0x4 << 27))
+
+#define IP_SEL_PAD_80_89_REG                   0x00C4
+       #define PMX_PL_80_TO_85_MASK            (0x3FFFF << 0)
+       #define PMX_CLCD_PL_80_TO_85_VAL        0
+       #define PMX_MII2_PL_80_TO_85_VAL        ((0x1 << 0) | (0x1 << 3) | (0x1 << 6) | (0x1 << 9) | (0x1 << 12) | (0x1 << 15))
+       #define PMX_EMI_PL_80_TO_85_VAL         ((0x2 << 0) | (0x2 << 3) | (0x2 << 6) | (0x2 << 9) | (0x2 << 12) | (0x2 << 15))
+       #define PMX_SPP_PL_80_TO_85_VAL         ((0x3 << 0) | (0x3 << 3) | (0x3 << 6) | (0x3 << 9) | (0x3 << 12) | (0x3 << 15))
+       #define PMX_UART1_ENH_PL_80_TO_85_VAL   ((0x4 << 0) | (0x4 << 3) | (0x4 << 6) | (0x4 << 9) | (0x4 << 12) | (0x4 << 15))
+
+       #define PMX_PL_86_87_MASK               (0x3F << 18)
+       #define PMX_PL_86_MASK                  (0x7 << 18)
+       #define PMX_PL_87_MASK                  (0x7 << 21)
+       #define PMX_CLCD_PL_86_87_VAL           0
+       #define PMX_MII2_PL_86_87_VAL           ((0x1 << 18) | (0x1 << 21))
+       #define PMX_EMI_PL_86_87_VAL            ((0x2 << 18) | (0x2 << 21))
+       #define PMX_PWM3_PL_86_VAL              (0x4 << 18)
+       #define PMX_PWM2_PL_87_VAL              (0x4 << 21)
+
+       #define PMX_PL_88_89_MASK               (0x3F << 24)
+       #define PMX_CLCD_PL_88_89_VAL           0
+       #define PMX_MII2_PL_88_89_VAL           ((0x1 << 24) | (0x1 << 27))
+       #define PMX_EMI_PL_88_89_VAL            ((0x2 << 24) | (0x2 << 27))
+       #define PMX_UART6_PL_88_89_VAL          ((0x3 << 24) | (0x3 << 27))
+       #define PMX_PWM0_1_PL_88_89_VAL         ((0x4 << 24) | (0x4 << 27))
+
+#define IP_SEL_PAD_90_99_REG                   0x00C8
+       #define PMX_PL_90_91_MASK               (0x3F << 0)
+       #define PMX_CLCD_PL_90_91_VAL           0
+       #define PMX_MII2_PL_90_91_VAL           ((0x1 << 0) | (0x1 << 3))
+       #define PMX_EMI1_PL_90_91_VAL           ((0x2 << 0) | (0x2 << 3))
+       #define PMX_UART5_PL_90_91_VAL          ((0x3 << 0) | (0x3 << 3))
+       #define PMX_SSP2_PL_90_91_VAL           ((0x4 << 0) | (0x4 << 3))
+
+       #define PMX_PL_92_93_MASK               (0x3F << 6)
+       #define PMX_CLCD_PL_92_93_VAL           0
+       #define PMX_MII2_PL_92_93_VAL           ((0x1 << 6) | (0x1 << 9))
+       #define PMX_EMI1_PL_92_93_VAL           ((0x2 << 6) | (0x2 << 9))
+       #define PMX_UART4_PL_92_93_VAL          ((0x3 << 6) | (0x3 << 9))
+       #define PMX_SSP2_PL_92_93_VAL           ((0x4 << 6) | (0x4 << 9))
+
+       #define PMX_PL_94_95_MASK               (0x3F << 12)
+       #define PMX_CLCD_PL_94_95_VAL           0
+       #define PMX_MII2_PL_94_95_VAL           ((0x1 << 12) | (0x1 << 15))
+       #define PMX_EMI1_PL_94_95_VAL           ((0x2 << 12) | (0x2 << 15))
+       #define PMX_UART3_PL_94_95_VAL          ((0x3 << 12) | (0x3 << 15))
+       #define PMX_SSP1_PL_94_95_VAL           ((0x4 << 12) | (0x4 << 15))
+
+       #define PMX_PL_96_97_MASK               (0x3F << 18)
+       #define PMX_CLCD_PL_96_97_VAL           0
+       #define PMX_MII2_PL_96_97_VAL           ((0x1 << 18) | (0x1 << 21))
+       #define PMX_EMI1_PL_96_97_VAL           ((0x2 << 18) | (0x2 << 21))
+       #define PMX_I2C2_PL_96_97_VAL           ((0x3 << 18) | (0x3 << 21))
+       #define PMX_SSP1_PL_96_97_VAL           ((0x4 << 18) | (0x4 << 21))
+
+       #define PMX_PL_98_MASK                  (0x7 << 24)
+       #define PMX_CLCD_PL_98_VAL              0
+       #define PMX_I2C1_PL_98_VAL              (0x2 << 24)
+       #define PMX_UART3_PL_98_VAL             (0x4 << 24)
+
+       #define PMX_PL_99_MASK                  (0x7 << 27)
+       #define PMX_SDHCI_PL_99_VAL             0
+       #define PMX_I2C1_PL_99_VAL              (0x2 << 27)
+       #define PMX_UART3_PL_99_VAL             (0x4 << 27)
+
+#define IP_SEL_MIX_PAD_REG                     0x00CC
+       #define PMX_PL_100_101_MASK             (0x3F << 0)
+       #define PMX_SDHCI_PL_100_101_VAL        0
+       #define PMX_UART4_PL_100_101_VAL        ((0x4 << 0) | (0x4 << 3))
+
+       #define PMX_SSP1_PORT_SEL_MASK          (0x7 << 8)
+       #define PMX_SSP1_PORT_94_TO_97_VAL      0
+       #define PMX_SSP1_PORT_65_TO_68_VAL      (0x1 << 8)
+       #define PMX_SSP1_PORT_48_TO_51_VAL      (0x2 << 8)
+       #define PMX_SSP1_PORT_36_TO_39_VAL      (0x3 << 8)
+       #define PMX_SSP1_PORT_17_TO_20_VAL      (0x4 << 8)
+
+       #define PMX_SSP2_PORT_SEL_MASK          (0x7 << 11)
+       #define PMX_SSP2_PORT_90_TO_93_VAL      0
+       #define PMX_SSP2_PORT_61_TO_64_VAL      (0x1 << 11)
+       #define PMX_SSP2_PORT_44_TO_47_VAL      (0x2 << 11)
+       #define PMX_SSP2_PORT_32_TO_35_VAL      (0x3 << 11)
+       #define PMX_SSP2_PORT_13_TO_16_VAL      (0x4 << 11)
+
+       #define PMX_UART1_ENH_PORT_SEL_MASK             (0x3 << 14)
+       #define PMX_UART1_ENH_PORT_81_TO_85_VAL         0
+       #define PMX_UART1_ENH_PORT_44_45_34_36_VAL      (0x1 << 14)
+       #define PMX_UART1_ENH_PORT_32_TO_34_36_VAL      (0x2 << 14)
+       #define PMX_UART1_ENH_PORT_3_TO_5_7_VAL         (0x3 << 14)
+
+       #define PMX_UART3_PORT_SEL_MASK         (0x7 << 16)
+       #define PMX_UART3_PORT_94_VAL           0
+       #define PMX_UART3_PORT_73_VAL           (0x1 << 16)
+       #define PMX_UART3_PORT_52_VAL           (0x2 << 16)
+       #define PMX_UART3_PORT_41_VAL           (0x3 << 16)
+       #define PMX_UART3_PORT_15_VAL           (0x4 << 16)
+       #define PMX_UART3_PORT_8_VAL            (0x5 << 16)
+       #define PMX_UART3_PORT_99_VAL           (0x6 << 16)
+
+       #define PMX_UART4_PORT_SEL_MASK         (0x7 << 19)
+       #define PMX_UART4_PORT_92_VAL           0
+       #define PMX_UART4_PORT_71_VAL           (0x1 << 19)
+       #define PMX_UART4_PORT_39_VAL           (0x2 << 19)
+       #define PMX_UART4_PORT_13_VAL           (0x3 << 19)
+       #define PMX_UART4_PORT_6_VAL            (0x4 << 19)
+       #define PMX_UART4_PORT_101_VAL          (0x5 << 19)
+
+       #define PMX_UART5_PORT_SEL_MASK         (0x3 << 22)
+       #define PMX_UART5_PORT_90_VAL           0
+       #define PMX_UART5_PORT_69_VAL           (0x1 << 22)
+       #define PMX_UART5_PORT_37_VAL           (0x2 << 22)
+       #define PMX_UART5_PORT_4_VAL            (0x3 << 22)
+
+       #define PMX_UART6_PORT_SEL_MASK         (0x1 << 24)
+       #define PMX_UART6_PORT_88_VAL           0
+       #define PMX_UART6_PORT_2_VAL            (0x1 << 24)
+
+       #define PMX_I2C1_PORT_SEL_MASK          (0x1 << 25)
+       #define PMX_I2C1_PORT_8_9_VAL           0
+       #define PMX_I2C1_PORT_98_99_VAL         (0x1 << 25)
+
+       #define PMX_I2C2_PORT_SEL_MASK          (0x3 << 26)
+       #define PMX_I2C2_PORT_96_97_VAL         0
+       #define PMX_I2C2_PORT_75_76_VAL         (0x1 << 26)
+       #define PMX_I2C2_PORT_19_20_VAL         (0x2 << 26)
+       #define PMX_I2C2_PORT_2_3_VAL           (0x3 << 26)
+       #define PMX_I2C2_PORT_0_1_VAL           (0x4 << 26)
+
+       #define PMX_SDHCI_CD_PORT_SEL_MASK      (0x1 << 29)
+       #define PMX_SDHCI_CD_PORT_12_VAL        0
+       #define PMX_SDHCI_CD_PORT_51_VAL        (0x1 << 29)
+
+/* Pad multiplexing for CLCD device */
+static const unsigned clcd_pins[] = { 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+       79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
+       97 };
+static struct spear_muxreg clcd_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_60_69_REG,
+               .mask = PMX_PL_69_MASK,
+               .val = PMX_CLCD_PL_69_VAL,
+       }, {
+               .reg = IP_SEL_PAD_70_79_REG,
+               .mask = PMX_PL_70_MASK | PMX_PL_71_72_MASK | PMX_PL_73_MASK |
+                       PMX_PL_74_MASK | PMX_PL_75_76_MASK |
+                       PMX_PL_77_78_79_MASK,
+               .val = PMX_CLCD_PL_70_VAL | PMX_CLCD_PL_71_72_VAL |
+                       PMX_CLCD_PL_73_VAL | PMX_CLCD_PL_74_VAL |
+                       PMX_CLCD_PL_75_76_VAL | PMX_CLCD_PL_77_78_79_VAL,
+       }, {
+               .reg = IP_SEL_PAD_80_89_REG,
+               .mask = PMX_PL_80_TO_85_MASK | PMX_PL_86_87_MASK |
+                       PMX_PL_88_89_MASK,
+               .val = PMX_CLCD_PL_80_TO_85_VAL | PMX_CLCD_PL_86_87_VAL |
+                       PMX_CLCD_PL_88_89_VAL,
+       }, {
+               .reg = IP_SEL_PAD_90_99_REG,
+               .mask = PMX_PL_90_91_MASK | PMX_PL_92_93_MASK |
+                       PMX_PL_94_95_MASK | PMX_PL_96_97_MASK | PMX_PL_98_MASK,
+               .val = PMX_CLCD_PL_90_91_VAL | PMX_CLCD_PL_92_93_VAL |
+                       PMX_CLCD_PL_94_95_VAL | PMX_CLCD_PL_96_97_VAL |
+                       PMX_CLCD_PL_98_VAL,
+       },
+};
+
+static struct spear_modemux clcd_modemux[] = {
+       {
+               .modes = EXTENDED_MODE,
+               .muxregs = clcd_muxreg,
+               .nmuxregs = ARRAY_SIZE(clcd_muxreg),
+       },
+};
+
+static struct spear_pingroup clcd_pingroup = {
+       .name = "clcd_grp",
+       .pins = clcd_pins,
+       .npins = ARRAY_SIZE(clcd_pins),
+       .modemuxs = clcd_modemux,
+       .nmodemuxs = ARRAY_SIZE(clcd_modemux),
+};
+
+static const char *const clcd_grps[] = { "clcd_grp" };
+static struct spear_function clcd_function = {
+       .name = "clcd",
+       .groups = clcd_grps,
+       .ngroups = ARRAY_SIZE(clcd_grps),
+};
+
+/* Pad multiplexing for EMI (Parallel NOR flash) device */
+static const unsigned emi_pins[] = { 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
+       57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+       75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
+       93, 94, 95, 96, 97 };
+static struct spear_muxreg emi_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_muxreg emi_ext_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_40_49_REG,
+               .mask = PMX_PL_46_47_MASK | PMX_PL_48_49_MASK,
+               .val = PMX_FSMC_EMI_PL_46_47_VAL | PMX_FSMC_EMI_PL_48_49_VAL,
+       }, {
+               .reg = IP_SEL_PAD_50_59_REG,
+               .mask = PMX_PL_50_51_MASK | PMX_PL_52_53_MASK |
+                       PMX_PL_54_55_56_MASK | PMX_PL_58_59_MASK,
+               .val = PMX_EMI_PL_50_51_VAL | PMX_EMI_PL_52_53_VAL |
+                       PMX_FSMC_EMI_PL_54_55_56_VAL |
+                       PMX_FSMC_EMI_PL_58_59_VAL,
+       }, {
+               .reg = IP_SEL_PAD_60_69_REG,
+               .mask = PMX_PL_69_MASK,
+               .val = PMX_EMI_PL_69_VAL,
+       }, {
+               .reg = IP_SEL_PAD_70_79_REG,
+               .mask = PMX_PL_70_MASK | PMX_PL_71_72_MASK | PMX_PL_73_MASK |
+                       PMX_PL_74_MASK | PMX_PL_75_76_MASK |
+                       PMX_PL_77_78_79_MASK,
+               .val = PMX_FSMC_EMI_PL_70_VAL | PMX_FSMC_EMI_PL_71_72_VAL |
+                       PMX_FSMC_EMI_PL_73_VAL | PMX_EMI_PL_74_VAL |
+                       PMX_EMI_PL_75_76_VAL | PMX_EMI_PL_77_78_79_VAL,
+       }, {
+               .reg = IP_SEL_PAD_80_89_REG,
+               .mask = PMX_PL_80_TO_85_MASK | PMX_PL_86_87_MASK |
+                       PMX_PL_88_89_MASK,
+               .val = PMX_EMI_PL_80_TO_85_VAL | PMX_EMI_PL_86_87_VAL |
+                       PMX_EMI_PL_88_89_VAL,
+       }, {
+               .reg = IP_SEL_PAD_90_99_REG,
+               .mask = PMX_PL_90_91_MASK | PMX_PL_92_93_MASK |
+                       PMX_PL_94_95_MASK | PMX_PL_96_97_MASK,
+               .val = PMX_EMI1_PL_90_91_VAL | PMX_EMI1_PL_92_93_VAL |
+                       PMX_EMI1_PL_94_95_VAL | PMX_EMI1_PL_96_97_VAL,
+       }, {
+               .reg = EXT_CTRL_REG,
+               .mask = EMI_FSMC_DYNAMIC_MUX_MASK,
+               .val = EMI_FSMC_DYNAMIC_MUX_MASK,
+       },
+};
+
+static struct spear_modemux emi_modemux[] = {
+       {
+               .modes = AUTO_EXP_MODE | EXTENDED_MODE,
+               .muxregs = emi_muxreg,
+               .nmuxregs = ARRAY_SIZE(emi_muxreg),
+       }, {
+               .modes = EXTENDED_MODE,
+               .muxregs = emi_ext_muxreg,
+               .nmuxregs = ARRAY_SIZE(emi_ext_muxreg),
+       },
+};
+
+static struct spear_pingroup emi_pingroup = {
+       .name = "emi_grp",
+       .pins = emi_pins,
+       .npins = ARRAY_SIZE(emi_pins),
+       .modemuxs = emi_modemux,
+       .nmodemuxs = ARRAY_SIZE(emi_modemux),
+};
+
+static const char *const emi_grps[] = { "emi_grp" };
+static struct spear_function emi_function = {
+       .name = "emi",
+       .groups = emi_grps,
+       .ngroups = ARRAY_SIZE(emi_grps),
+};
+
+/* Pad multiplexing for FSMC (NAND flash) device */
+static const unsigned fsmc_8bit_pins[] = { 52, 53, 54, 55, 56, 57, 58, 59, 60,
+       61, 62, 63, 64, 65, 66, 67, 68 };
+static struct spear_muxreg fsmc_8bit_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_50_59_REG,
+               .mask = PMX_PL_52_53_MASK | PMX_PL_54_55_56_MASK |
+                       PMX_PL_57_MASK | PMX_PL_58_59_MASK,
+               .val = PMX_FSMC_PL_52_53_VAL | PMX_FSMC_EMI_PL_54_55_56_VAL |
+                       PMX_FSMC_PL_57_VAL | PMX_FSMC_EMI_PL_58_59_VAL,
+       }, {
+               .reg = IP_SEL_PAD_60_69_REG,
+               .mask = PMX_PL_60_MASK | PMX_PL_61_TO_64_MASK |
+                       PMX_PL_65_TO_68_MASK,
+               .val = PMX_FSMC_PL_60_VAL | PMX_FSMC_PL_61_TO_64_VAL |
+                       PMX_FSMC_PL_65_TO_68_VAL,
+       }, {
+               .reg = EXT_CTRL_REG,
+               .mask = EMI_FSMC_DYNAMIC_MUX_MASK,
+               .val = EMI_FSMC_DYNAMIC_MUX_MASK,
+       },
+};
+
+static struct spear_modemux fsmc_8bit_modemux[] = {
+       {
+               .modes = EXTENDED_MODE,
+               .muxregs = fsmc_8bit_muxreg,
+               .nmuxregs = ARRAY_SIZE(fsmc_8bit_muxreg),
+       },
+};
+
+static struct spear_pingroup fsmc_8bit_pingroup = {
+       .name = "fsmc_8bit_grp",
+       .pins = fsmc_8bit_pins,
+       .npins = ARRAY_SIZE(fsmc_8bit_pins),
+       .modemuxs = fsmc_8bit_modemux,
+       .nmodemuxs = ARRAY_SIZE(fsmc_8bit_modemux),
+};
+
+static const unsigned fsmc_16bit_pins[] = { 46, 47, 48, 49, 52, 53, 54, 55, 56,
+       57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 70, 71, 72, 73 };
+static struct spear_muxreg fsmc_16bit_autoexp_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_muxreg fsmc_16bit_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_40_49_REG,
+               .mask = PMX_PL_46_47_MASK | PMX_PL_48_49_MASK,
+               .val = PMX_FSMC_EMI_PL_46_47_VAL | PMX_FSMC_EMI_PL_48_49_VAL,
+       }, {
+               .reg = IP_SEL_PAD_70_79_REG,
+               .mask = PMX_PL_70_MASK | PMX_PL_71_72_MASK | PMX_PL_73_MASK,
+               .val = PMX_FSMC_EMI_PL_70_VAL | PMX_FSMC_EMI_PL_71_72_VAL |
+                       PMX_FSMC_EMI_PL_73_VAL,
+       }
+};
+
+static struct spear_modemux fsmc_16bit_modemux[] = {
+       {
+               .modes = EXTENDED_MODE,
+               .muxregs = fsmc_8bit_muxreg,
+               .nmuxregs = ARRAY_SIZE(fsmc_8bit_muxreg),
+       }, {
+               .modes = AUTO_EXP_MODE | EXTENDED_MODE,
+               .muxregs = fsmc_16bit_autoexp_muxreg,
+               .nmuxregs = ARRAY_SIZE(fsmc_16bit_autoexp_muxreg),
+       }, {
+               .modes = EXTENDED_MODE,
+               .muxregs = fsmc_16bit_muxreg,
+               .nmuxregs = ARRAY_SIZE(fsmc_16bit_muxreg),
+       },
+};
+
+static struct spear_pingroup fsmc_16bit_pingroup = {
+       .name = "fsmc_16bit_grp",
+       .pins = fsmc_16bit_pins,
+       .npins = ARRAY_SIZE(fsmc_16bit_pins),
+       .modemuxs = fsmc_16bit_modemux,
+       .nmodemuxs = ARRAY_SIZE(fsmc_16bit_modemux),
+};
+
+static const char *const fsmc_grps[] = { "fsmc_8bit_grp", "fsmc_16bit_grp" };
+static struct spear_function fsmc_function = {
+       .name = "fsmc",
+       .groups = fsmc_grps,
+       .ngroups = ARRAY_SIZE(fsmc_grps),
+};
+
+/* Pad multiplexing for SPP device */
+static const unsigned spp_pins[] = { 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+       80, 81, 82, 83, 84, 85 };
+static struct spear_muxreg spp_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_60_69_REG,
+               .mask = PMX_PL_69_MASK,
+               .val = PMX_SPP_PL_69_VAL,
+       }, {
+               .reg = IP_SEL_PAD_70_79_REG,
+               .mask = PMX_PL_70_MASK | PMX_PL_71_72_MASK | PMX_PL_73_MASK |
+                       PMX_PL_74_MASK | PMX_PL_75_76_MASK |
+                       PMX_PL_77_78_79_MASK,
+               .val = PMX_SPP_PL_70_VAL | PMX_SPP_PL_71_72_VAL |
+                       PMX_SPP_PL_73_VAL | PMX_SPP_PL_74_VAL |
+                       PMX_SPP_PL_75_76_VAL | PMX_SPP_PL_77_78_79_VAL,
+       }, {
+               .reg = IP_SEL_PAD_80_89_REG,
+               .mask = PMX_PL_80_TO_85_MASK,
+               .val = PMX_SPP_PL_80_TO_85_VAL,
+       },
+};
+
+static struct spear_modemux spp_modemux[] = {
+       {
+               .modes = EXTENDED_MODE,
+               .muxregs = spp_muxreg,
+               .nmuxregs = ARRAY_SIZE(spp_muxreg),
+       },
+};
+
+static struct spear_pingroup spp_pingroup = {
+       .name = "spp_grp",
+       .pins = spp_pins,
+       .npins = ARRAY_SIZE(spp_pins),
+       .modemuxs = spp_modemux,
+       .nmodemuxs = ARRAY_SIZE(spp_modemux),
+};
+
+static const char *const spp_grps[] = { "spp_grp" };
+static struct spear_function spp_function = {
+       .name = "spp",
+       .groups = spp_grps,
+       .ngroups = ARRAY_SIZE(spp_grps),
+};
+
+/* Pad multiplexing for SDHCI device */
+static const unsigned sdhci_led_pins[] = { 34 };
+static struct spear_muxreg sdhci_led_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_SSP_CS_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_muxreg sdhci_led_ext_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_30_39_REG,
+               .mask = PMX_PL_34_MASK,
+               .val = PMX_PWM2_PL_34_VAL,
+       },
+};
+
+static struct spear_modemux sdhci_led_modemux[] = {
+       {
+               .modes = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE | EXTENDED_MODE,
+               .muxregs = sdhci_led_muxreg,
+               .nmuxregs = ARRAY_SIZE(sdhci_led_muxreg),
+       }, {
+               .modes = EXTENDED_MODE,
+               .muxregs = sdhci_led_ext_muxreg,
+               .nmuxregs = ARRAY_SIZE(sdhci_led_ext_muxreg),
+       },
+};
+
+static struct spear_pingroup sdhci_led_pingroup = {
+       .name = "sdhci_led_grp",
+       .pins = sdhci_led_pins,
+       .npins = ARRAY_SIZE(sdhci_led_pins),
+       .modemuxs = sdhci_led_modemux,
+       .nmodemuxs = ARRAY_SIZE(sdhci_led_modemux),
+};
+
+static const unsigned sdhci_cd_12_pins[] = { 12, 43, 44, 45, 46, 47, 48, 49,
+       50};
+static const unsigned sdhci_cd_51_pins[] = { 43, 44, 45, 46, 47, 48, 49, 50, 51
+};
+static struct spear_muxreg sdhci_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_muxreg sdhci_ext_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_40_49_REG,
+               .mask = PMX_PL_43_MASK | PMX_PL_44_45_MASK | PMX_PL_46_47_MASK |
+                       PMX_PL_48_49_MASK,
+               .val = PMX_SDHCI_PL_43_VAL | PMX_SDHCI_PL_44_45_VAL |
+                       PMX_SDHCI_PL_46_47_VAL | PMX_SDHCI_PL_48_49_VAL,
+       }, {
+               .reg = IP_SEL_PAD_50_59_REG,
+               .mask = PMX_PL_50_MASK,
+               .val = PMX_SDHCI_PL_50_VAL,
+       }, {
+               .reg = IP_SEL_PAD_90_99_REG,
+               .mask = PMX_PL_99_MASK,
+               .val = PMX_SDHCI_PL_99_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_PL_100_101_MASK,
+               .val = PMX_SDHCI_PL_100_101_VAL,
+       },
+};
+
+static struct spear_muxreg sdhci_cd_12_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_MII_MASK,
+               .val = 0,
+       }, {
+               .reg = IP_SEL_PAD_10_19_REG,
+               .mask = PMX_PL_12_MASK,
+               .val = PMX_SDHCI_CD_PL_12_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_SDHCI_CD_PORT_SEL_MASK,
+               .val = PMX_SDHCI_CD_PORT_12_VAL,
+       },
+};
+
+static struct spear_muxreg sdhci_cd_51_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_50_59_REG,
+               .mask = PMX_PL_51_MASK,
+               .val = PMX_SDHCI_CD_PL_51_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_SDHCI_CD_PORT_SEL_MASK,
+               .val = PMX_SDHCI_CD_PORT_51_VAL,
+       },
+};
+
+#define pmx_sdhci_common_modemux                                       \
+       {                                                               \
+               .modes = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE |       \
+                       SMALL_PRINTERS_MODE | EXTENDED_MODE,            \
+               .muxregs = sdhci_muxreg,                                \
+               .nmuxregs = ARRAY_SIZE(sdhci_muxreg),                   \
+       }, {                                                            \
+               .modes = EXTENDED_MODE,                                 \
+               .muxregs = sdhci_ext_muxreg,                            \
+               .nmuxregs = ARRAY_SIZE(sdhci_ext_muxreg),               \
+       }
+
+static struct spear_modemux sdhci_modemux[][3] = {
+       {
+               /* select pin 12 for cd */
+               pmx_sdhci_common_modemux,
+               {
+                       .modes = EXTENDED_MODE,
+                       .muxregs = sdhci_cd_12_muxreg,
+                       .nmuxregs = ARRAY_SIZE(sdhci_cd_12_muxreg),
+               },
+       }, {
+               /* select pin 51 for cd */
+               pmx_sdhci_common_modemux,
+               {
+                       .modes = EXTENDED_MODE,
+                       .muxregs = sdhci_cd_51_muxreg,
+                       .nmuxregs = ARRAY_SIZE(sdhci_cd_51_muxreg),
+               },
+       }
+};
+
+static struct spear_pingroup sdhci_pingroup[] = {
+       {
+               .name = "sdhci_cd_12_grp",
+               .pins = sdhci_cd_12_pins,
+               .npins = ARRAY_SIZE(sdhci_cd_12_pins),
+               .modemuxs = sdhci_modemux[0],
+               .nmodemuxs = ARRAY_SIZE(sdhci_modemux[0]),
+       }, {
+               .name = "sdhci_cd_51_grp",
+               .pins = sdhci_cd_51_pins,
+               .npins = ARRAY_SIZE(sdhci_cd_51_pins),
+               .modemuxs = sdhci_modemux[1],
+               .nmodemuxs = ARRAY_SIZE(sdhci_modemux[1]),
+       },
+};
+
+static const char *const sdhci_grps[] = { "sdhci_cd_12_grp", "sdhci_cd_51_grp",
+       "sdhci_led_grp" };
+
+static struct spear_function sdhci_function = {
+       .name = "sdhci",
+       .groups = sdhci_grps,
+       .ngroups = ARRAY_SIZE(sdhci_grps),
+};
+
+/* Pad multiplexing for I2S device */
+static const unsigned i2s_pins[] = { 35, 39, 40, 41, 42 };
+static struct spear_muxreg i2s_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_SSP_CS_MASK,
+               .val = 0,
+       }, {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_UART0_MODEM_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_muxreg i2s_ext_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_30_39_REG,
+               .mask = PMX_PL_35_MASK | PMX_PL_39_MASK,
+               .val = PMX_I2S_REF_CLK_PL_35_VAL | PMX_I2S_PL_39_VAL,
+       }, {
+               .reg = IP_SEL_PAD_40_49_REG,
+               .mask = PMX_PL_40_MASK | PMX_PL_41_42_MASK,
+               .val = PMX_I2S_PL_40_VAL | PMX_I2S_PL_41_42_VAL,
+       },
+};
+
+static struct spear_modemux i2s_modemux[] = {
+       {
+               .modes = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE | EXTENDED_MODE,
+               .muxregs = i2s_muxreg,
+               .nmuxregs = ARRAY_SIZE(i2s_muxreg),
+       }, {
+               .modes = EXTENDED_MODE,
+               .muxregs = i2s_ext_muxreg,
+               .nmuxregs = ARRAY_SIZE(i2s_ext_muxreg),
+       },
+};
+
+static struct spear_pingroup i2s_pingroup = {
+       .name = "i2s_grp",
+       .pins = i2s_pins,
+       .npins = ARRAY_SIZE(i2s_pins),
+       .modemuxs = i2s_modemux,
+       .nmodemuxs = ARRAY_SIZE(i2s_modemux),
+};
+
+static const char *const i2s_grps[] = { "i2s_grp" };
+static struct spear_function i2s_function = {
+       .name = "i2s",
+       .groups = i2s_grps,
+       .ngroups = ARRAY_SIZE(i2s_grps),
+};
+
+/* Pad multiplexing for UART1 device */
+static const unsigned uart1_pins[] = { 28, 29 };
+static struct spear_muxreg uart1_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_muxreg uart1_ext_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_20_29_REG,
+               .mask = PMX_PL_28_29_MASK,
+               .val = PMX_UART1_PL_28_29_VAL,
+       },
+};
+
+static struct spear_modemux uart1_modemux[] = {
+       {
+               .modes = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE | AUTO_EXP_MODE
+                       | SMALL_PRINTERS_MODE | EXTENDED_MODE,
+               .muxregs = uart1_muxreg,
+               .nmuxregs = ARRAY_SIZE(uart1_muxreg),
+       }, {
+               .modes = EXTENDED_MODE,
+               .muxregs = uart1_ext_muxreg,
+               .nmuxregs = ARRAY_SIZE(uart1_ext_muxreg),
+       },
+};
+
+static struct spear_pingroup uart1_pingroup = {
+       .name = "uart1_grp",
+       .pins = uart1_pins,
+       .npins = ARRAY_SIZE(uart1_pins),
+       .modemuxs = uart1_modemux,
+       .nmodemuxs = ARRAY_SIZE(uart1_modemux),
+};
+
+static const char *const uart1_grps[] = { "uart1_grp" };
+static struct spear_function uart1_function = {
+       .name = "uart1",
+       .groups = uart1_grps,
+       .ngroups = ARRAY_SIZE(uart1_grps),
+};
+
+/* Pad multiplexing for UART1 Modem device */
+static const unsigned uart1_modem_2_to_7_pins[] = { 2, 3, 4, 5, 6, 7 };
+static const unsigned uart1_modem_31_to_36_pins[] = { 31, 32, 33, 34, 35, 36 };
+static const unsigned uart1_modem_34_to_45_pins[] = { 34, 35, 36, 43, 44, 45 };
+static const unsigned uart1_modem_80_to_85_pins[] = { 80, 81, 82, 83, 84, 85 };
+
+static struct spear_muxreg uart1_modem_ext_2_to_7_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_UART0_MASK | PMX_I2C_MASK | PMX_SSP_MASK,
+               .val = 0,
+       }, {
+               .reg = IP_SEL_PAD_0_9_REG,
+               .mask = PMX_PL_2_3_MASK | PMX_PL_6_7_MASK,
+               .val = PMX_UART1_ENH_PL_2_3_VAL | PMX_UART1_ENH_PL_4_5_VAL |
+                       PMX_UART1_ENH_PL_6_7_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_UART1_ENH_PORT_SEL_MASK,
+               .val = PMX_UART1_ENH_PORT_3_TO_5_7_VAL,
+       },
+};
+
+static struct spear_muxreg uart1_modem_31_to_36_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_GPIO_PIN3_MASK | PMX_GPIO_PIN4_MASK |
+                       PMX_GPIO_PIN5_MASK | PMX_SSP_CS_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_muxreg uart1_modem_ext_31_to_36_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_30_39_REG,
+               .mask = PMX_PL_31_MASK | PMX_PL_32_33_MASK | PMX_PL_34_MASK |
+                       PMX_PL_35_MASK | PMX_PL_36_MASK,
+               .val = PMX_UART1_ENH_PL_31_VAL | PMX_UART1_ENH_PL_32_33_VAL |
+                       PMX_UART1_ENH_PL_34_VAL | PMX_UART1_ENH_PL_35_VAL |
+                       PMX_UART1_ENH_PL_36_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_UART1_ENH_PORT_SEL_MASK,
+               .val = PMX_UART1_ENH_PORT_32_TO_34_36_VAL,
+       },
+};
+
+static struct spear_muxreg uart1_modem_34_to_45_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK |
+                       PMX_SSP_CS_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_muxreg uart1_modem_ext_34_to_45_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_30_39_REG,
+               .mask = PMX_PL_34_MASK | PMX_PL_35_MASK | PMX_PL_36_MASK,
+               .val = PMX_UART1_ENH_PL_34_VAL | PMX_UART1_ENH_PL_35_VAL |
+                       PMX_UART1_ENH_PL_36_VAL,
+       }, {
+               .reg = IP_SEL_PAD_40_49_REG,
+               .mask = PMX_PL_43_MASK | PMX_PL_44_45_MASK,
+               .val = PMX_UART1_ENH_PL_43_VAL | PMX_UART1_ENH_PL_44_45_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_UART1_ENH_PORT_SEL_MASK,
+               .val = PMX_UART1_ENH_PORT_44_45_34_36_VAL,
+       },
+};
+
+static struct spear_muxreg uart1_modem_ext_80_to_85_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_80_89_REG,
+               .mask = PMX_PL_80_TO_85_MASK,
+               .val = PMX_UART1_ENH_PL_80_TO_85_VAL,
+       }, {
+               .reg = IP_SEL_PAD_40_49_REG,
+               .mask = PMX_PL_43_MASK | PMX_PL_44_45_MASK,
+               .val = PMX_UART1_ENH_PL_43_VAL | PMX_UART1_ENH_PL_44_45_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_UART1_ENH_PORT_SEL_MASK,
+               .val = PMX_UART1_ENH_PORT_81_TO_85_VAL,
+       },
+};
+
+static struct spear_modemux uart1_modem_2_to_7_modemux[] = {
+       {
+               .modes = EXTENDED_MODE,
+               .muxregs = uart1_modem_ext_2_to_7_muxreg,
+               .nmuxregs = ARRAY_SIZE(uart1_modem_ext_2_to_7_muxreg),
+       },
+};
+
+static struct spear_modemux uart1_modem_31_to_36_modemux[] = {
+       {
+               .modes = SMALL_PRINTERS_MODE | EXTENDED_MODE,
+               .muxregs = uart1_modem_31_to_36_muxreg,
+               .nmuxregs = ARRAY_SIZE(uart1_modem_31_to_36_muxreg),
+       }, {
+               .modes = EXTENDED_MODE,
+               .muxregs = uart1_modem_ext_31_to_36_muxreg,
+               .nmuxregs = ARRAY_SIZE(uart1_modem_ext_31_to_36_muxreg),
+       },
+};
+
+static struct spear_modemux uart1_modem_34_to_45_modemux[] = {
+       {
+               .modes = AUTO_EXP_MODE | EXTENDED_MODE,
+               .muxregs = uart1_modem_34_to_45_muxreg,
+               .nmuxregs = ARRAY_SIZE(uart1_modem_34_to_45_muxreg),
+       }, {
+               .modes = EXTENDED_MODE,
+               .muxregs = uart1_modem_ext_34_to_45_muxreg,
+               .nmuxregs = ARRAY_SIZE(uart1_modem_ext_34_to_45_muxreg),
+       },
+};
+
+static struct spear_modemux uart1_modem_80_to_85_modemux[] = {
+       {
+               .modes = EXTENDED_MODE,
+               .muxregs = uart1_modem_ext_80_to_85_muxreg,
+               .nmuxregs = ARRAY_SIZE(uart1_modem_ext_80_to_85_muxreg),
+       },
+};
+
+static struct spear_pingroup uart1_modem_pingroup[] = {
+       {
+               .name = "uart1_modem_2_to_7_grp",
+               .pins = uart1_modem_2_to_7_pins,
+               .npins = ARRAY_SIZE(uart1_modem_2_to_7_pins),
+               .modemuxs = uart1_modem_2_to_7_modemux,
+               .nmodemuxs = ARRAY_SIZE(uart1_modem_2_to_7_modemux),
+       }, {
+               .name = "uart1_modem_31_to_36_grp",
+               .pins = uart1_modem_31_to_36_pins,
+               .npins = ARRAY_SIZE(uart1_modem_31_to_36_pins),
+               .modemuxs = uart1_modem_31_to_36_modemux,
+               .nmodemuxs = ARRAY_SIZE(uart1_modem_31_to_36_modemux),
+       }, {
+               .name = "uart1_modem_34_to_45_grp",
+               .pins = uart1_modem_34_to_45_pins,
+               .npins = ARRAY_SIZE(uart1_modem_34_to_45_pins),
+               .modemuxs = uart1_modem_34_to_45_modemux,
+               .nmodemuxs = ARRAY_SIZE(uart1_modem_34_to_45_modemux),
+       }, {
+               .name = "uart1_modem_80_to_85_grp",
+               .pins = uart1_modem_80_to_85_pins,
+               .npins = ARRAY_SIZE(uart1_modem_80_to_85_pins),
+               .modemuxs = uart1_modem_80_to_85_modemux,
+               .nmodemuxs = ARRAY_SIZE(uart1_modem_80_to_85_modemux),
+       },
+};
+
+static const char *const uart1_modem_grps[] = { "uart1_modem_2_to_7_grp",
+       "uart1_modem_31_to_36_grp", "uart1_modem_34_to_45_grp",
+       "uart1_modem_80_to_85_grp" };
+static struct spear_function uart1_modem_function = {
+       .name = "uart1_modem",
+       .groups = uart1_modem_grps,
+       .ngroups = ARRAY_SIZE(uart1_modem_grps),
+};
+
+/* Pad multiplexing for UART2 device */
+static const unsigned uart2_pins[] = { 0, 1 };
+static struct spear_muxreg uart2_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_FIRDA_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_muxreg uart2_ext_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_0_9_REG,
+               .mask = PMX_PL_0_1_MASK,
+               .val = PMX_UART2_PL_0_1_VAL,
+       },
+};
+
+static struct spear_modemux uart2_modemux[] = {
+       {
+               .modes = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE | AUTO_EXP_MODE
+                       | SMALL_PRINTERS_MODE | EXTENDED_MODE,
+               .muxregs = uart2_muxreg,
+               .nmuxregs = ARRAY_SIZE(uart2_muxreg),
+       }, {
+               .modes = EXTENDED_MODE,
+               .muxregs = uart2_ext_muxreg,
+               .nmuxregs = ARRAY_SIZE(uart2_ext_muxreg),
+       },
+};
+
+static struct spear_pingroup uart2_pingroup = {
+       .name = "uart2_grp",
+       .pins = uart2_pins,
+       .npins = ARRAY_SIZE(uart2_pins),
+       .modemuxs = uart2_modemux,
+       .nmodemuxs = ARRAY_SIZE(uart2_modemux),
+};
+
+static const char *const uart2_grps[] = { "uart2_grp" };
+static struct spear_function uart2_function = {
+       .name = "uart2",
+       .groups = uart2_grps,
+       .ngroups = ARRAY_SIZE(uart2_grps),
+};
+
+/* Pad multiplexing for uart3 device */
+static const unsigned uart3_pins[][2] = { { 8, 9 }, { 15, 16 }, { 41, 42 },
+       { 52, 53 }, { 73, 74 }, { 94, 95 }, { 98, 99 } };
+
+static struct spear_muxreg uart3_ext_8_9_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_SSP_MASK,
+               .val = 0,
+       }, {
+               .reg = IP_SEL_PAD_0_9_REG,
+               .mask = PMX_PL_8_9_MASK,
+               .val = PMX_UART3_PL_8_9_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_UART3_PORT_SEL_MASK,
+               .val = PMX_UART3_PORT_8_VAL,
+       },
+};
+
+static struct spear_muxreg uart3_ext_15_16_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_MII_MASK,
+               .val = 0,
+       }, {
+               .reg = IP_SEL_PAD_10_19_REG,
+               .mask = PMX_PL_15_16_MASK,
+               .val = PMX_UART3_PL_15_16_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_UART3_PORT_SEL_MASK,
+               .val = PMX_UART3_PORT_15_VAL,
+       },
+};
+
+static struct spear_muxreg uart3_ext_41_42_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_UART0_MODEM_MASK,
+               .val = 0,
+       }, {
+               .reg = IP_SEL_PAD_40_49_REG,
+               .mask = PMX_PL_41_42_MASK,
+               .val = PMX_UART3_PL_41_42_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_UART3_PORT_SEL_MASK,
+               .val = PMX_UART3_PORT_41_VAL,
+       },
+};
+
+static struct spear_muxreg uart3_ext_52_53_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_50_59_REG,
+               .mask = PMX_PL_52_53_MASK,
+               .val = PMX_UART3_PL_52_53_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_UART3_PORT_SEL_MASK,
+               .val = PMX_UART3_PORT_52_VAL,
+       },
+};
+
+static struct spear_muxreg uart3_ext_73_74_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_70_79_REG,
+               .mask = PMX_PL_73_MASK | PMX_PL_74_MASK,
+               .val = PMX_UART3_PL_73_VAL | PMX_UART3_PL_74_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_UART3_PORT_SEL_MASK,
+               .val = PMX_UART3_PORT_73_VAL,
+       },
+};
+
+static struct spear_muxreg uart3_ext_94_95_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_90_99_REG,
+               .mask = PMX_PL_94_95_MASK,
+               .val = PMX_UART3_PL_94_95_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_UART3_PORT_SEL_MASK,
+               .val = PMX_UART3_PORT_94_VAL,
+       },
+};
+
+static struct spear_muxreg uart3_ext_98_99_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_90_99_REG,
+               .mask = PMX_PL_98_MASK | PMX_PL_99_MASK,
+               .val = PMX_UART3_PL_98_VAL | PMX_UART3_PL_99_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_UART3_PORT_SEL_MASK,
+               .val = PMX_UART3_PORT_99_VAL,
+       },
+};
+
+static struct spear_modemux uart3_modemux[][1] = {
+       {
+               /* Select signals on pins 8_9 */
+               {
+                       .modes = EXTENDED_MODE,
+                       .muxregs = uart3_ext_8_9_muxreg,
+                       .nmuxregs = ARRAY_SIZE(uart3_ext_8_9_muxreg),
+               },
+       }, {
+               /* Select signals on pins 15_16 */
+               {
+                       .modes = EXTENDED_MODE,
+                       .muxregs = uart3_ext_15_16_muxreg,
+                       .nmuxregs = ARRAY_SIZE(uart3_ext_15_16_muxreg),
+               },
+       }, {
+               /* Select signals on pins 41_42 */
+               {
+                       .modes = EXTENDED_MODE,
+                       .muxregs = uart3_ext_41_42_muxreg,
+                       .nmuxregs = ARRAY_SIZE(uart3_ext_41_42_muxreg),
+               },
+       }, {
+               /* Select signals on pins 52_53 */
+               {
+                       .modes = EXTENDED_MODE,
+                       .muxregs = uart3_ext_52_53_muxreg,
+                       .nmuxregs = ARRAY_SIZE(uart3_ext_52_53_muxreg),
+               },
+       }, {
+               /* Select signals on pins 73_74 */
+               {
+                       .modes = EXTENDED_MODE,
+                       .muxregs = uart3_ext_73_74_muxreg,
+                       .nmuxregs = ARRAY_SIZE(uart3_ext_73_74_muxreg),
+               },
+       }, {
+               /* Select signals on pins 94_95 */
+               {
+                       .modes = EXTENDED_MODE,
+                       .muxregs = uart3_ext_94_95_muxreg,
+                       .nmuxregs = ARRAY_SIZE(uart3_ext_94_95_muxreg),
+               },
+       }, {
+               /* Select signals on pins 98_99 */
+               {
+                       .modes = EXTENDED_MODE,
+                       .muxregs = uart3_ext_98_99_muxreg,
+                       .nmuxregs = ARRAY_SIZE(uart3_ext_98_99_muxreg),
+               },
+       },
+};
+
+static struct spear_pingroup uart3_pingroup[] = {
+       {
+               .name = "uart3_8_9_grp",
+               .pins = uart3_pins[0],
+               .npins = ARRAY_SIZE(uart3_pins[0]),
+               .modemuxs = uart3_modemux[0],
+               .nmodemuxs = ARRAY_SIZE(uart3_modemux[0]),
+       }, {
+               .name = "uart3_15_16_grp",
+               .pins = uart3_pins[1],
+               .npins = ARRAY_SIZE(uart3_pins[1]),
+               .modemuxs = uart3_modemux[1],
+               .nmodemuxs = ARRAY_SIZE(uart3_modemux[1]),
+       }, {
+               .name = "uart3_41_42_grp",
+               .pins = uart3_pins[2],
+               .npins = ARRAY_SIZE(uart3_pins[2]),
+               .modemuxs = uart3_modemux[2],
+               .nmodemuxs = ARRAY_SIZE(uart3_modemux[2]),
+       }, {
+               .name = "uart3_52_53_grp",
+               .pins = uart3_pins[3],
+               .npins = ARRAY_SIZE(uart3_pins[3]),
+               .modemuxs = uart3_modemux[3],
+               .nmodemuxs = ARRAY_SIZE(uart3_modemux[3]),
+       }, {
+               .name = "uart3_73_74_grp",
+               .pins = uart3_pins[4],
+               .npins = ARRAY_SIZE(uart3_pins[4]),
+               .modemuxs = uart3_modemux[4],
+               .nmodemuxs = ARRAY_SIZE(uart3_modemux[4]),
+       }, {
+               .name = "uart3_94_95_grp",
+               .pins = uart3_pins[5],
+               .npins = ARRAY_SIZE(uart3_pins[5]),
+               .modemuxs = uart3_modemux[5],
+               .nmodemuxs = ARRAY_SIZE(uart3_modemux[5]),
+       }, {
+               .name = "uart3_98_99_grp",
+               .pins = uart3_pins[6],
+               .npins = ARRAY_SIZE(uart3_pins[6]),
+               .modemuxs = uart3_modemux[6],
+               .nmodemuxs = ARRAY_SIZE(uart3_modemux[6]),
+       },
+};
+
+static const char *const uart3_grps[] = { "uart3_8_9_grp", "uart3_15_16_grp",
+       "uart3_41_42_grp", "uart3_52_53_grp", "uart3_73_74_grp",
+       "uart3_94_95_grp", "uart3_98_99_grp" };
+
+static struct spear_function uart3_function = {
+       .name = "uart3",
+       .groups = uart3_grps,
+       .ngroups = ARRAY_SIZE(uart3_grps),
+};
+
+/* Pad multiplexing for uart4 device */
+static const unsigned uart4_pins[][2] = { { 6, 7 }, { 13, 14 }, { 39, 40 },
+       { 71, 72 }, { 92, 93 }, { 100, 101 } };
+
+static struct spear_muxreg uart4_ext_6_7_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_SSP_MASK,
+               .val = 0,
+       }, {
+               .reg = IP_SEL_PAD_0_9_REG,
+               .mask = PMX_PL_6_7_MASK,
+               .val = PMX_UART4_PL_6_7_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_UART4_PORT_SEL_MASK,
+               .val = PMX_UART4_PORT_6_VAL,
+       },
+};
+
+static struct spear_muxreg uart4_ext_13_14_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_MII_MASK,
+               .val = 0,
+       }, {
+               .reg = IP_SEL_PAD_10_19_REG,
+               .mask = PMX_PL_13_14_MASK,
+               .val = PMX_UART4_PL_13_14_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_UART4_PORT_SEL_MASK,
+               .val = PMX_UART4_PORT_13_VAL,
+       },
+};
+
+static struct spear_muxreg uart4_ext_39_40_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_UART0_MODEM_MASK,
+               .val = 0,
+       }, {
+               .reg = IP_SEL_PAD_30_39_REG,
+               .mask = PMX_PL_39_MASK,
+               .val = PMX_UART4_PL_39_VAL,
+       }, {
+               .reg = IP_SEL_PAD_40_49_REG,
+               .mask = PMX_PL_40_MASK,
+               .val = PMX_UART4_PL_40_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_UART4_PORT_SEL_MASK,
+               .val = PMX_UART4_PORT_39_VAL,
+       },
+};
+
+static struct spear_muxreg uart4_ext_71_72_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_70_79_REG,
+               .mask = PMX_PL_71_72_MASK,
+               .val = PMX_UART4_PL_71_72_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_UART4_PORT_SEL_MASK,
+               .val = PMX_UART4_PORT_71_VAL,
+       },
+};
+
+static struct spear_muxreg uart4_ext_92_93_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_90_99_REG,
+               .mask = PMX_PL_92_93_MASK,
+               .val = PMX_UART4_PL_92_93_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_UART4_PORT_SEL_MASK,
+               .val = PMX_UART4_PORT_92_VAL,
+       },
+};
+
+static struct spear_muxreg uart4_ext_100_101_muxreg[] = {
+       {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_PL_100_101_MASK |
+                       PMX_UART4_PORT_SEL_MASK,
+               .val = PMX_UART4_PL_100_101_VAL |
+                       PMX_UART4_PORT_101_VAL,
+       },
+};
+
+static struct spear_modemux uart4_modemux[][1] = {
+       {
+               /* Select signals on pins 6_7 */
+               {
+                       .modes = EXTENDED_MODE,
+                       .muxregs = uart4_ext_6_7_muxreg,
+                       .nmuxregs = ARRAY_SIZE(uart4_ext_6_7_muxreg),
+               },
+       }, {
+               /* Select signals on pins 13_14 */
+               {
+                       .modes = EXTENDED_MODE,
+                       .muxregs = uart4_ext_13_14_muxreg,
+                       .nmuxregs = ARRAY_SIZE(uart4_ext_13_14_muxreg),
+               },
+       }, {
+               /* Select signals on pins 39_40 */
+               {
+                       .modes = EXTENDED_MODE,
+                       .muxregs = uart4_ext_39_40_muxreg,
+                       .nmuxregs = ARRAY_SIZE(uart4_ext_39_40_muxreg),
+               },
+       }, {
+               /* Select signals on pins 71_72 */
+               {
+                       .modes = EXTENDED_MODE,
+                       .muxregs = uart4_ext_71_72_muxreg,
+                       .nmuxregs = ARRAY_SIZE(uart4_ext_71_72_muxreg),
+               },
+       }, {
+               /* Select signals on pins 92_93 */
+               {
+                       .modes = EXTENDED_MODE,
+                       .muxregs = uart4_ext_92_93_muxreg,
+                       .nmuxregs = ARRAY_SIZE(uart4_ext_92_93_muxreg),
+               },
+       }, {
+               /* Select signals on pins 100_101_ */
+               {
+                       .modes = EXTENDED_MODE,
+                       .muxregs = uart4_ext_100_101_muxreg,
+                       .nmuxregs = ARRAY_SIZE(uart4_ext_100_101_muxreg),
+               },
+       },
+};
+
+static struct spear_pingroup uart4_pingroup[] = {
+       {
+               .name = "uart4_6_7_grp",
+               .pins = uart4_pins[0],
+               .npins = ARRAY_SIZE(uart4_pins[0]),
+               .modemuxs = uart4_modemux[0],
+               .nmodemuxs = ARRAY_SIZE(uart4_modemux[0]),
+       }, {
+               .name = "uart4_13_14_grp",
+               .pins = uart4_pins[1],
+               .npins = ARRAY_SIZE(uart4_pins[1]),
+               .modemuxs = uart4_modemux[1],
+               .nmodemuxs = ARRAY_SIZE(uart4_modemux[1]),
+       }, {
+               .name = "uart4_39_40_grp",
+               .pins = uart4_pins[2],
+               .npins = ARRAY_SIZE(uart4_pins[2]),
+               .modemuxs = uart4_modemux[2],
+               .nmodemuxs = ARRAY_SIZE(uart4_modemux[2]),
+       }, {
+               .name = "uart4_71_72_grp",
+               .pins = uart4_pins[3],
+               .npins = ARRAY_SIZE(uart4_pins[3]),
+               .modemuxs = uart4_modemux[3],
+               .nmodemuxs = ARRAY_SIZE(uart4_modemux[3]),
+       }, {
+               .name = "uart4_92_93_grp",
+               .pins = uart4_pins[4],
+               .npins = ARRAY_SIZE(uart4_pins[4]),
+               .modemuxs = uart4_modemux[4],
+               .nmodemuxs = ARRAY_SIZE(uart4_modemux[4]),
+       }, {
+               .name = "uart4_100_101_grp",
+               .pins = uart4_pins[5],
+               .npins = ARRAY_SIZE(uart4_pins[5]),
+               .modemuxs = uart4_modemux[5],
+               .nmodemuxs = ARRAY_SIZE(uart4_modemux[5]),
+       },
+};
+
+static const char *const uart4_grps[] = { "uart4_6_7_grp", "uart4_13_14_grp",
+       "uart4_39_40_grp", "uart4_71_72_grp", "uart4_92_93_grp",
+       "uart4_100_101_grp" };
+
+static struct spear_function uart4_function = {
+       .name = "uart4",
+       .groups = uart4_grps,
+       .ngroups = ARRAY_SIZE(uart4_grps),
+};
+
+/* Pad multiplexing for uart5 device */
+static const unsigned uart5_pins[][2] = { { 4, 5 }, { 37, 38 }, { 69, 70 },
+       { 90, 91 } };
+
+static struct spear_muxreg uart5_ext_4_5_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_I2C_MASK,
+               .val = 0,
+       }, {
+               .reg = IP_SEL_PAD_0_9_REG,
+               .mask = PMX_PL_4_5_MASK,
+               .val = PMX_UART5_PL_4_5_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_UART5_PORT_SEL_MASK,
+               .val = PMX_UART5_PORT_4_VAL,
+       },
+};
+
+static struct spear_muxreg uart5_ext_37_38_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_UART0_MODEM_MASK,
+               .val = 0,
+       }, {
+               .reg = IP_SEL_PAD_30_39_REG,
+               .mask = PMX_PL_37_38_MASK,
+               .val = PMX_UART5_PL_37_38_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_UART5_PORT_SEL_MASK,
+               .val = PMX_UART5_PORT_37_VAL,
+       },
+};
+
+static struct spear_muxreg uart5_ext_69_70_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_60_69_REG,
+               .mask = PMX_PL_69_MASK,
+               .val = PMX_UART5_PL_69_VAL,
+       }, {
+               .reg = IP_SEL_PAD_70_79_REG,
+               .mask = PMX_PL_70_MASK,
+               .val = PMX_UART5_PL_70_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_UART5_PORT_SEL_MASK,
+               .val = PMX_UART5_PORT_69_VAL,
+       },
+};
+
+static struct spear_muxreg uart5_ext_90_91_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_90_99_REG,
+               .mask = PMX_PL_90_91_MASK,
+               .val = PMX_UART5_PL_90_91_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_UART5_PORT_SEL_MASK,
+               .val = PMX_UART5_PORT_90_VAL,
+       },
+};
+
+static struct spear_modemux uart5_modemux[][1] = {
+       {
+               /* Select signals on pins 4_5 */
+               {
+                       .modes = EXTENDED_MODE,
+                       .muxregs = uart5_ext_4_5_muxreg,
+                       .nmuxregs = ARRAY_SIZE(uart5_ext_4_5_muxreg),
+               },
+       }, {
+               /* Select signals on pins 37_38 */
+               {
+                       .modes = EXTENDED_MODE,
+                       .muxregs = uart5_ext_37_38_muxreg,
+                       .nmuxregs = ARRAY_SIZE(uart5_ext_37_38_muxreg),
+               },
+       }, {
+               /* Select signals on pins 69_70 */
+               {
+                       .modes = EXTENDED_MODE,
+                       .muxregs = uart5_ext_69_70_muxreg,
+                       .nmuxregs = ARRAY_SIZE(uart5_ext_69_70_muxreg),
+               },
+       }, {
+               /* Select signals on pins 90_91 */
+               {
+                       .modes = EXTENDED_MODE,
+                       .muxregs = uart5_ext_90_91_muxreg,
+                       .nmuxregs = ARRAY_SIZE(uart5_ext_90_91_muxreg),
+               },
+       },
+};
+
+static struct spear_pingroup uart5_pingroup[] = {
+       {
+               .name = "uart5_4_5_grp",
+               .pins = uart5_pins[0],
+               .npins = ARRAY_SIZE(uart5_pins[0]),
+               .modemuxs = uart5_modemux[0],
+               .nmodemuxs = ARRAY_SIZE(uart5_modemux[0]),
+       }, {
+               .name = "uart5_37_38_grp",
+               .pins = uart5_pins[1],
+               .npins = ARRAY_SIZE(uart5_pins[1]),
+               .modemuxs = uart5_modemux[1],
+               .nmodemuxs = ARRAY_SIZE(uart5_modemux[1]),
+       }, {
+               .name = "uart5_69_70_grp",
+               .pins = uart5_pins[2],
+               .npins = ARRAY_SIZE(uart5_pins[2]),
+               .modemuxs = uart5_modemux[2],
+               .nmodemuxs = ARRAY_SIZE(uart5_modemux[2]),
+       }, {
+               .name = "uart5_90_91_grp",
+               .pins = uart5_pins[3],
+               .npins = ARRAY_SIZE(uart5_pins[3]),
+               .modemuxs = uart5_modemux[3],
+               .nmodemuxs = ARRAY_SIZE(uart5_modemux[3]),
+       },
+};
+
+static const char *const uart5_grps[] = { "uart5_4_5_grp", "uart5_37_38_grp",
+       "uart5_69_70_grp", "uart5_90_91_grp" };
+static struct spear_function uart5_function = {
+       .name = "uart5",
+       .groups = uart5_grps,
+       .ngroups = ARRAY_SIZE(uart5_grps),
+};
+
+/* Pad multiplexing for uart6 device */
+static const unsigned uart6_pins[][2] = { { 2, 3 }, { 88, 89 } };
+static struct spear_muxreg uart6_ext_2_3_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_UART0_MASK,
+               .val = 0,
+       }, {
+               .reg = IP_SEL_PAD_0_9_REG,
+               .mask = PMX_PL_2_3_MASK,
+               .val = PMX_UART6_PL_2_3_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_UART6_PORT_SEL_MASK,
+               .val = PMX_UART6_PORT_2_VAL,
+       },
+};
+
+static struct spear_muxreg uart6_ext_88_89_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_80_89_REG,
+               .mask = PMX_PL_88_89_MASK,
+               .val = PMX_UART6_PL_88_89_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_UART6_PORT_SEL_MASK,
+               .val = PMX_UART6_PORT_88_VAL,
+       },
+};
+
+static struct spear_modemux uart6_modemux[][1] = {
+       {
+               /* Select signals on pins 2_3 */
+               {
+                       .modes = EXTENDED_MODE,
+                       .muxregs = uart6_ext_2_3_muxreg,
+                       .nmuxregs = ARRAY_SIZE(uart6_ext_2_3_muxreg),
+               },
+       }, {
+               /* Select signals on pins 88_89 */
+               {
+                       .modes = EXTENDED_MODE,
+                       .muxregs = uart6_ext_88_89_muxreg,
+                       .nmuxregs = ARRAY_SIZE(uart6_ext_88_89_muxreg),
+               },
+       },
+};
+
+static struct spear_pingroup uart6_pingroup[] = {
+       {
+               .name = "uart6_2_3_grp",
+               .pins = uart6_pins[0],
+               .npins = ARRAY_SIZE(uart6_pins[0]),
+               .modemuxs = uart6_modemux[0],
+               .nmodemuxs = ARRAY_SIZE(uart6_modemux[0]),
+       }, {
+               .name = "uart6_88_89_grp",
+               .pins = uart6_pins[1],
+               .npins = ARRAY_SIZE(uart6_pins[1]),
+               .modemuxs = uart6_modemux[1],
+               .nmodemuxs = ARRAY_SIZE(uart6_modemux[1]),
+       },
+};
+
+static const char *const uart6_grps[] = { "uart6_2_3_grp", "uart6_88_89_grp" };
+static struct spear_function uart6_function = {
+       .name = "uart6",
+       .groups = uart6_grps,
+       .ngroups = ARRAY_SIZE(uart6_grps),
+};
+
+/* UART - RS485 pmx */
+static const unsigned rs485_pins[] = { 77, 78, 79 };
+static struct spear_muxreg rs485_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_70_79_REG,
+               .mask = PMX_PL_77_78_79_MASK,
+               .val = PMX_RS485_PL_77_78_79_VAL,
+       },
+};
+
+static struct spear_modemux rs485_modemux[] = {
+       {
+               .modes = EXTENDED_MODE,
+               .muxregs = rs485_muxreg,
+               .nmuxregs = ARRAY_SIZE(rs485_muxreg),
+       },
+};
+
+static struct spear_pingroup rs485_pingroup = {
+       .name = "rs485_grp",
+       .pins = rs485_pins,
+       .npins = ARRAY_SIZE(rs485_pins),
+       .modemuxs = rs485_modemux,
+       .nmodemuxs = ARRAY_SIZE(rs485_modemux),
+};
+
+static const char *const rs485_grps[] = { "rs485_grp" };
+static struct spear_function rs485_function = {
+       .name = "rs485",
+       .groups = rs485_grps,
+       .ngroups = ARRAY_SIZE(rs485_grps),
+};
+
+/* Pad multiplexing for Touchscreen device */
+static const unsigned touchscreen_pins[] = { 5, 36 };
+static struct spear_muxreg touchscreen_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_I2C_MASK | PMX_SSP_CS_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_muxreg touchscreen_ext_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_0_9_REG,
+               .mask = PMX_PL_5_MASK,
+               .val = PMX_TOUCH_Y_PL_5_VAL,
+       }, {
+               .reg = IP_SEL_PAD_30_39_REG,
+               .mask = PMX_PL_36_MASK,
+               .val = PMX_TOUCH_X_PL_36_VAL,
+       },
+};
+
+static struct spear_modemux touchscreen_modemux[] = {
+       {
+               .modes = AUTO_NET_SMII_MODE | EXTENDED_MODE,
+               .muxregs = touchscreen_muxreg,
+               .nmuxregs = ARRAY_SIZE(touchscreen_muxreg),
+       }, {
+               .modes = EXTENDED_MODE,
+               .muxregs = touchscreen_ext_muxreg,
+               .nmuxregs = ARRAY_SIZE(touchscreen_ext_muxreg),
+       },
+};
+
+static struct spear_pingroup touchscreen_pingroup = {
+       .name = "touchscreen_grp",
+       .pins = touchscreen_pins,
+       .npins = ARRAY_SIZE(touchscreen_pins),
+       .modemuxs = touchscreen_modemux,
+       .nmodemuxs = ARRAY_SIZE(touchscreen_modemux),
+};
+
+static const char *const touchscreen_grps[] = { "touchscreen_grp" };
+static struct spear_function touchscreen_function = {
+       .name = "touchscreen",
+       .groups = touchscreen_grps,
+       .ngroups = ARRAY_SIZE(touchscreen_grps),
+};
+
+/* Pad multiplexing for CAN device */
+static const unsigned can0_pins[] = { 32, 33 };
+static struct spear_muxreg can0_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_muxreg can0_ext_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_30_39_REG,
+               .mask = PMX_PL_32_33_MASK,
+               .val = PMX_CAN0_PL_32_33_VAL,
+       },
+};
+
+static struct spear_modemux can0_modemux[] = {
+       {
+               .modes = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE | AUTO_EXP_MODE
+                       | EXTENDED_MODE,
+               .muxregs = can0_muxreg,
+               .nmuxregs = ARRAY_SIZE(can0_muxreg),
+       }, {
+               .modes = EXTENDED_MODE,
+               .muxregs = can0_ext_muxreg,
+               .nmuxregs = ARRAY_SIZE(can0_ext_muxreg),
+       },
+};
+
+static struct spear_pingroup can0_pingroup = {
+       .name = "can0_grp",
+       .pins = can0_pins,
+       .npins = ARRAY_SIZE(can0_pins),
+       .modemuxs = can0_modemux,
+       .nmodemuxs = ARRAY_SIZE(can0_modemux),
+};
+
+static const char *const can0_grps[] = { "can0_grp" };
+static struct spear_function can0_function = {
+       .name = "can0",
+       .groups = can0_grps,
+       .ngroups = ARRAY_SIZE(can0_grps),
+};
+
+static const unsigned can1_pins[] = { 30, 31 };
+static struct spear_muxreg can1_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_muxreg can1_ext_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_30_39_REG,
+               .mask = PMX_PL_30_31_MASK,
+               .val = PMX_CAN1_PL_30_31_VAL,
+       },
+};
+
+static struct spear_modemux can1_modemux[] = {
+       {
+               .modes = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE | AUTO_EXP_MODE
+                       | EXTENDED_MODE,
+               .muxregs = can1_muxreg,
+               .nmuxregs = ARRAY_SIZE(can1_muxreg),
+       }, {
+               .modes = EXTENDED_MODE,
+               .muxregs = can1_ext_muxreg,
+               .nmuxregs = ARRAY_SIZE(can1_ext_muxreg),
+       },
+};
+
+static struct spear_pingroup can1_pingroup = {
+       .name = "can1_grp",
+       .pins = can1_pins,
+       .npins = ARRAY_SIZE(can1_pins),
+       .modemuxs = can1_modemux,
+       .nmodemuxs = ARRAY_SIZE(can1_modemux),
+};
+
+static const char *const can1_grps[] = { "can1_grp" };
+static struct spear_function can1_function = {
+       .name = "can1",
+       .groups = can1_grps,
+       .ngroups = ARRAY_SIZE(can1_grps),
+};
+
+/* Pad multiplexing for PWM0_1 device */
+static const unsigned pwm0_1_pins[][2] = { { 37, 38 }, { 14, 15 }, { 8, 9 },
+       { 30, 31 }, { 42, 43 }, { 59, 60 }, { 88, 89 } };
+
+static struct spear_muxreg pwm0_1_pin_8_9_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_SSP_MASK,
+               .val = 0,
+       }, {
+               .reg = IP_SEL_PAD_0_9_REG,
+               .mask = PMX_PL_8_9_MASK,
+               .val = PMX_PWM_0_1_PL_8_9_VAL,
+       },
+};
+
+static struct spear_muxreg pwm0_1_autoexpsmallpri_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_MII_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_muxreg pwm0_1_pin_14_15_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_10_19_REG,
+               .mask = PMX_PL_14_MASK | PMX_PL_15_MASK,
+               .val = PMX_PWM1_PL_14_VAL | PMX_PWM0_PL_15_VAL,
+       },
+};
+
+static struct spear_muxreg pwm0_1_pin_30_31_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK,
+               .val = 0,
+       }, {
+               .reg = IP_SEL_PAD_30_39_REG,
+               .mask = PMX_PL_30_MASK | PMX_PL_31_MASK,
+               .val = PMX_PWM1_EXT_PL_30_VAL | PMX_PWM0_EXT_PL_31_VAL,
+       },
+};
+
+static struct spear_muxreg pwm0_1_net_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_UART0_MODEM_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_muxreg pwm0_1_pin_37_38_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_30_39_REG,
+               .mask = PMX_PL_37_38_MASK,
+               .val = PMX_PWM0_1_PL_37_38_VAL,
+       },
+};
+
+static struct spear_muxreg pwm0_1_pin_42_43_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_UART0_MODEM_MASK | PMX_TIMER_0_1_MASK ,
+               .val = 0,
+       }, {
+               .reg = IP_SEL_PAD_40_49_REG,
+               .mask = PMX_PL_42_MASK | PMX_PL_43_MASK,
+               .val = PMX_PWM1_PL_42_VAL |
+                       PMX_PWM0_PL_43_VAL,
+       },
+};
+
+static struct spear_muxreg pwm0_1_pin_59_60_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_50_59_REG,
+               .mask = PMX_PL_59_MASK,
+               .val = PMX_PWM1_PL_59_VAL,
+       }, {
+               .reg = IP_SEL_PAD_60_69_REG,
+               .mask = PMX_PL_60_MASK,
+               .val = PMX_PWM0_PL_60_VAL,
+       },
+};
+
+static struct spear_muxreg pwm0_1_pin_88_89_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_80_89_REG,
+               .mask = PMX_PL_88_89_MASK,
+               .val = PMX_PWM0_1_PL_88_89_VAL,
+       },
+};
+
+static struct spear_modemux pwm0_1_pin_8_9_modemux[] = {
+       {
+               .modes = EXTENDED_MODE,
+               .muxregs = pwm0_1_pin_8_9_muxreg,
+               .nmuxregs = ARRAY_SIZE(pwm0_1_pin_8_9_muxreg),
+       },
+};
+
+static struct spear_modemux pwm0_1_pin_14_15_modemux[] = {
+       {
+               .modes = AUTO_EXP_MODE | SMALL_PRINTERS_MODE | EXTENDED_MODE,
+               .muxregs = pwm0_1_autoexpsmallpri_muxreg,
+               .nmuxregs = ARRAY_SIZE(pwm0_1_autoexpsmallpri_muxreg),
+       }, {
+               .modes = EXTENDED_MODE,
+               .muxregs = pwm0_1_pin_14_15_muxreg,
+               .nmuxregs = ARRAY_SIZE(pwm0_1_pin_14_15_muxreg),
+       },
+};
+
+static struct spear_modemux pwm0_1_pin_30_31_modemux[] = {
+       {
+               .modes = EXTENDED_MODE,
+               .muxregs = pwm0_1_pin_30_31_muxreg,
+               .nmuxregs = ARRAY_SIZE(pwm0_1_pin_30_31_muxreg),
+       },
+};
+
+static struct spear_modemux pwm0_1_pin_37_38_modemux[] = {
+       {
+               .modes = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE | EXTENDED_MODE,
+               .muxregs = pwm0_1_net_muxreg,
+               .nmuxregs = ARRAY_SIZE(pwm0_1_net_muxreg),
+       }, {
+               .modes = EXTENDED_MODE,
+               .muxregs = pwm0_1_pin_37_38_muxreg,
+               .nmuxregs = ARRAY_SIZE(pwm0_1_pin_37_38_muxreg),
+       },
+};
+
+static struct spear_modemux pwm0_1_pin_42_43_modemux[] = {
+       {
+               .modes = EXTENDED_MODE,
+               .muxregs = pwm0_1_pin_42_43_muxreg,
+               .nmuxregs = ARRAY_SIZE(pwm0_1_pin_42_43_muxreg),
+       },
+};
+
+static struct spear_modemux pwm0_1_pin_59_60_modemux[] = {
+       {
+               .modes = EXTENDED_MODE,
+               .muxregs = pwm0_1_pin_59_60_muxreg,
+               .nmuxregs = ARRAY_SIZE(pwm0_1_pin_59_60_muxreg),
+       },
+};
+
+static struct spear_modemux pwm0_1_pin_88_89_modemux[] = {
+       {
+               .modes = EXTENDED_MODE,
+               .muxregs = pwm0_1_pin_88_89_muxreg,
+               .nmuxregs = ARRAY_SIZE(pwm0_1_pin_88_89_muxreg),
+       },
+};
+
+static struct spear_pingroup pwm0_1_pingroup[] = {
+       {
+               .name = "pwm0_1_pin_8_9_grp",
+               .pins = pwm0_1_pins[0],
+               .npins = ARRAY_SIZE(pwm0_1_pins[0]),
+               .modemuxs = pwm0_1_pin_8_9_modemux,
+               .nmodemuxs = ARRAY_SIZE(pwm0_1_pin_8_9_modemux),
+       }, {
+               .name = "pwm0_1_pin_14_15_grp",
+               .pins = pwm0_1_pins[1],
+               .npins = ARRAY_SIZE(pwm0_1_pins[1]),
+               .modemuxs = pwm0_1_pin_14_15_modemux,
+               .nmodemuxs = ARRAY_SIZE(pwm0_1_pin_14_15_modemux),
+       }, {
+               .name = "pwm0_1_pin_30_31_grp",
+               .pins = pwm0_1_pins[2],
+               .npins = ARRAY_SIZE(pwm0_1_pins[2]),
+               .modemuxs = pwm0_1_pin_30_31_modemux,
+               .nmodemuxs = ARRAY_SIZE(pwm0_1_pin_30_31_modemux),
+       }, {
+               .name = "pwm0_1_pin_37_38_grp",
+               .pins = pwm0_1_pins[3],
+               .npins = ARRAY_SIZE(pwm0_1_pins[3]),
+               .modemuxs = pwm0_1_pin_37_38_modemux,
+               .nmodemuxs = ARRAY_SIZE(pwm0_1_pin_37_38_modemux),
+       }, {
+               .name = "pwm0_1_pin_42_43_grp",
+               .pins = pwm0_1_pins[4],
+               .npins = ARRAY_SIZE(pwm0_1_pins[4]),
+               .modemuxs = pwm0_1_pin_42_43_modemux,
+               .nmodemuxs = ARRAY_SIZE(pwm0_1_pin_42_43_modemux),
+       }, {
+               .name = "pwm0_1_pin_59_60_grp",
+               .pins = pwm0_1_pins[5],
+               .npins = ARRAY_SIZE(pwm0_1_pins[5]),
+               .modemuxs = pwm0_1_pin_59_60_modemux,
+               .nmodemuxs = ARRAY_SIZE(pwm0_1_pin_59_60_modemux),
+       }, {
+               .name = "pwm0_1_pin_88_89_grp",
+               .pins = pwm0_1_pins[6],
+               .npins = ARRAY_SIZE(pwm0_1_pins[6]),
+               .modemuxs = pwm0_1_pin_88_89_modemux,
+               .nmodemuxs = ARRAY_SIZE(pwm0_1_pin_88_89_modemux),
+       },
+};
+
+static const char *const pwm0_1_grps[] = { "pwm0_1_pin_8_9_grp",
+       "pwm0_1_pin_14_15_grp", "pwm0_1_pin_30_31_grp", "pwm0_1_pin_37_38_grp",
+       "pwm0_1_pin_42_43_grp", "pwm0_1_pin_59_60_grp", "pwm0_1_pin_88_89_grp"
+};
+
+static struct spear_function pwm0_1_function = {
+       .name = "pwm0_1",
+       .groups = pwm0_1_grps,
+       .ngroups = ARRAY_SIZE(pwm0_1_grps),
+};
+
+/* Pad multiplexing for PWM2 device */
+static const unsigned pwm2_pins[][1] = { { 7 }, { 13 }, { 29 }, { 34 }, { 41 },
+       { 58 }, { 87 } };
+static struct spear_muxreg pwm2_net_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_SSP_CS_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_muxreg pwm2_pin_7_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_0_9_REG,
+               .mask = PMX_PL_7_MASK,
+               .val = PMX_PWM_2_PL_7_VAL,
+       },
+};
+
+static struct spear_muxreg pwm2_autoexpsmallpri_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_MII_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_muxreg pwm2_pin_13_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_10_19_REG,
+               .mask = PMX_PL_13_MASK,
+               .val = PMX_PWM2_PL_13_VAL,
+       },
+};
+
+static struct spear_muxreg pwm2_pin_29_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_GPIO_PIN1_MASK,
+               .val = 0,
+       }, {
+               .reg = IP_SEL_PAD_20_29_REG,
+               .mask = PMX_PL_29_MASK,
+               .val = PMX_PWM_2_PL_29_VAL,
+       },
+};
+
+static struct spear_muxreg pwm2_pin_34_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_SSP_CS_MASK,
+               .val = 0,
+       }, {
+               .reg = IP_SEL_PAD_30_39_REG,
+               .mask = PMX_PL_34_MASK,
+               .val = PMX_PWM2_PL_34_VAL,
+       },
+};
+
+static struct spear_muxreg pwm2_pin_41_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_UART0_MODEM_MASK,
+               .val = 0,
+       }, {
+               .reg = IP_SEL_PAD_40_49_REG,
+               .mask = PMX_PL_41_MASK,
+               .val = PMX_PWM2_PL_41_VAL,
+       },
+};
+
+static struct spear_muxreg pwm2_pin_58_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_50_59_REG,
+               .mask = PMX_PL_58_MASK,
+               .val = PMX_PWM2_PL_58_VAL,
+       },
+};
+
+static struct spear_muxreg pwm2_pin_87_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_80_89_REG,
+               .mask = PMX_PL_87_MASK,
+               .val = PMX_PWM2_PL_87_VAL,
+       },
+};
+
+static struct spear_modemux pwm2_pin_7_modemux[] = {
+       {
+               .modes = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE | EXTENDED_MODE,
+               .muxregs = pwm2_net_muxreg,
+               .nmuxregs = ARRAY_SIZE(pwm2_net_muxreg),
+       }, {
+               .modes = EXTENDED_MODE,
+               .muxregs = pwm2_pin_7_muxreg,
+               .nmuxregs = ARRAY_SIZE(pwm2_pin_7_muxreg),
+       },
+};
+static struct spear_modemux pwm2_pin_13_modemux[] = {
+       {
+               .modes = AUTO_EXP_MODE | SMALL_PRINTERS_MODE | EXTENDED_MODE,
+               .muxregs = pwm2_autoexpsmallpri_muxreg,
+               .nmuxregs = ARRAY_SIZE(pwm2_autoexpsmallpri_muxreg),
+       }, {
+               .modes = EXTENDED_MODE,
+               .muxregs = pwm2_pin_13_muxreg,
+               .nmuxregs = ARRAY_SIZE(pwm2_pin_13_muxreg),
+       },
+};
+static struct spear_modemux pwm2_pin_29_modemux[] = {
+       {
+               .modes = EXTENDED_MODE,
+               .muxregs = pwm2_pin_29_muxreg,
+               .nmuxregs = ARRAY_SIZE(pwm2_pin_29_muxreg),
+       },
+};
+static struct spear_modemux pwm2_pin_34_modemux[] = {
+       {
+               .modes = EXTENDED_MODE,
+               .muxregs = pwm2_pin_34_muxreg,
+               .nmuxregs = ARRAY_SIZE(pwm2_pin_34_muxreg),
+       },
+};
+
+static struct spear_modemux pwm2_pin_41_modemux[] = {
+       {
+               .modes = EXTENDED_MODE,
+               .muxregs = pwm2_pin_41_muxreg,
+               .nmuxregs = ARRAY_SIZE(pwm2_pin_41_muxreg),
+       },
+};
+
+static struct spear_modemux pwm2_pin_58_modemux[] = {
+       {
+               .modes = EXTENDED_MODE,
+               .muxregs = pwm2_pin_58_muxreg,
+               .nmuxregs = ARRAY_SIZE(pwm2_pin_58_muxreg),
+       },
+};
+
+static struct spear_modemux pwm2_pin_87_modemux[] = {
+       {
+               .modes = EXTENDED_MODE,
+               .muxregs = pwm2_pin_87_muxreg,
+               .nmuxregs = ARRAY_SIZE(pwm2_pin_87_muxreg),
+       },
+};
+
+static struct spear_pingroup pwm2_pingroup[] = {
+       {
+               .name = "pwm2_pin_7_grp",
+               .pins = pwm2_pins[0],
+               .npins = ARRAY_SIZE(pwm2_pins[0]),
+               .modemuxs = pwm2_pin_7_modemux,
+               .nmodemuxs = ARRAY_SIZE(pwm2_pin_7_modemux),
+       }, {
+               .name = "pwm2_pin_13_grp",
+               .pins = pwm2_pins[1],
+               .npins = ARRAY_SIZE(pwm2_pins[1]),
+               .modemuxs = pwm2_pin_13_modemux,
+               .nmodemuxs = ARRAY_SIZE(pwm2_pin_13_modemux),
+       }, {
+               .name = "pwm2_pin_29_grp",
+               .pins = pwm2_pins[2],
+               .npins = ARRAY_SIZE(pwm2_pins[2]),
+               .modemuxs = pwm2_pin_29_modemux,
+               .nmodemuxs = ARRAY_SIZE(pwm2_pin_29_modemux),
+       }, {
+               .name = "pwm2_pin_34_grp",
+               .pins = pwm2_pins[3],
+               .npins = ARRAY_SIZE(pwm2_pins[3]),
+               .modemuxs = pwm2_pin_34_modemux,
+               .nmodemuxs = ARRAY_SIZE(pwm2_pin_34_modemux),
+       }, {
+               .name = "pwm2_pin_41_grp",
+               .pins = pwm2_pins[4],
+               .npins = ARRAY_SIZE(pwm2_pins[4]),
+               .modemuxs = pwm2_pin_41_modemux,
+               .nmodemuxs = ARRAY_SIZE(pwm2_pin_41_modemux),
+       }, {
+               .name = "pwm2_pin_58_grp",
+               .pins = pwm2_pins[5],
+               .npins = ARRAY_SIZE(pwm2_pins[5]),
+               .modemuxs = pwm2_pin_58_modemux,
+               .nmodemuxs = ARRAY_SIZE(pwm2_pin_58_modemux),
+       }, {
+               .name = "pwm2_pin_87_grp",
+               .pins = pwm2_pins[6],
+               .npins = ARRAY_SIZE(pwm2_pins[6]),
+               .modemuxs = pwm2_pin_87_modemux,
+               .nmodemuxs = ARRAY_SIZE(pwm2_pin_87_modemux),
+       },
+};
+
+static const char *const pwm2_grps[] = { "pwm2_pin_7_grp", "pwm2_pin_13_grp",
+       "pwm2_pin_29_grp", "pwm2_pin_34_grp", "pwm2_pin_41_grp",
+       "pwm2_pin_58_grp", "pwm2_pin_87_grp" };
+static struct spear_function pwm2_function = {
+       .name = "pwm2",
+       .groups = pwm2_grps,
+       .ngroups = ARRAY_SIZE(pwm2_grps),
+};
+
+/* Pad multiplexing for PWM3 device */
+static const unsigned pwm3_pins[][1] = { { 6 }, { 12 }, { 28 }, { 40 }, { 57 },
+       { 86 } };
+static struct spear_muxreg pwm3_pin_6_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_SSP_MASK,
+               .val = 0,
+       }, {
+               .reg = IP_SEL_PAD_0_9_REG,
+               .mask = PMX_PL_6_MASK,
+               .val = PMX_PWM_3_PL_6_VAL,
+       },
+};
+
+static struct spear_muxreg pwm3_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_MII_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_muxreg pwm3_pin_12_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_10_19_REG,
+               .mask = PMX_PL_12_MASK,
+               .val = PMX_PWM3_PL_12_VAL,
+       },
+};
+
+static struct spear_muxreg pwm3_pin_28_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_GPIO_PIN0_MASK,
+               .val = 0,
+       }, {
+               .reg = IP_SEL_PAD_20_29_REG,
+               .mask = PMX_PL_28_MASK,
+               .val = PMX_PWM_3_PL_28_VAL,
+       },
+};
+
+static struct spear_muxreg pwm3_pin_40_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_UART0_MODEM_MASK,
+               .val = 0,
+       }, {
+               .reg = IP_SEL_PAD_40_49_REG,
+               .mask = PMX_PL_40_MASK,
+               .val = PMX_PWM3_PL_40_VAL,
+       },
+};
+
+static struct spear_muxreg pwm3_pin_57_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_50_59_REG,
+               .mask = PMX_PL_57_MASK,
+               .val = PMX_PWM3_PL_57_VAL,
+       },
+};
+
+static struct spear_muxreg pwm3_pin_86_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_80_89_REG,
+               .mask = PMX_PL_86_MASK,
+               .val = PMX_PWM3_PL_86_VAL,
+       },
+};
+
+static struct spear_modemux pwm3_pin_6_modemux[] = {
+       {
+               .modes = EXTENDED_MODE,
+               .muxregs = pwm3_pin_6_muxreg,
+               .nmuxregs = ARRAY_SIZE(pwm3_pin_6_muxreg),
+       },
+};
+
+static struct spear_modemux pwm3_pin_12_modemux[] = {
+       {
+               .modes = AUTO_EXP_MODE | SMALL_PRINTERS_MODE |
+                       AUTO_NET_SMII_MODE | EXTENDED_MODE,
+               .muxregs = pwm3_muxreg,
+               .nmuxregs = ARRAY_SIZE(pwm3_muxreg),
+       }, {
+               .modes = EXTENDED_MODE,
+               .muxregs = pwm3_pin_12_muxreg,
+               .nmuxregs = ARRAY_SIZE(pwm3_pin_12_muxreg),
+       },
+};
+
+static struct spear_modemux pwm3_pin_28_modemux[] = {
+       {
+               .modes = EXTENDED_MODE,
+               .muxregs = pwm3_pin_28_muxreg,
+               .nmuxregs = ARRAY_SIZE(pwm3_pin_28_muxreg),
+       },
+};
+
+static struct spear_modemux pwm3_pin_40_modemux[] = {
+       {
+               .modes = EXTENDED_MODE,
+               .muxregs = pwm3_pin_40_muxreg,
+               .nmuxregs = ARRAY_SIZE(pwm3_pin_40_muxreg),
+       },
+};
+
+static struct spear_modemux pwm3_pin_57_modemux[] = {
+       {
+               .modes = EXTENDED_MODE,
+               .muxregs = pwm3_pin_57_muxreg,
+               .nmuxregs = ARRAY_SIZE(pwm3_pin_57_muxreg),
+       },
+};
+
+static struct spear_modemux pwm3_pin_86_modemux[] = {
+       {
+               .modes = EXTENDED_MODE,
+               .muxregs = pwm3_pin_86_muxreg,
+               .nmuxregs = ARRAY_SIZE(pwm3_pin_86_muxreg),
+       },
+};
+
+static struct spear_pingroup pwm3_pingroup[] = {
+       {
+               .name = "pwm3_pin_6_grp",
+               .pins = pwm3_pins[0],
+               .npins = ARRAY_SIZE(pwm3_pins[0]),
+               .modemuxs = pwm3_pin_6_modemux,
+               .nmodemuxs = ARRAY_SIZE(pwm3_pin_6_modemux),
+       }, {
+               .name = "pwm3_pin_12_grp",
+               .pins = pwm3_pins[1],
+               .npins = ARRAY_SIZE(pwm3_pins[1]),
+               .modemuxs = pwm3_pin_12_modemux,
+               .nmodemuxs = ARRAY_SIZE(pwm3_pin_12_modemux),
+       }, {
+               .name = "pwm3_pin_28_grp",
+               .pins = pwm3_pins[2],
+               .npins = ARRAY_SIZE(pwm3_pins[2]),
+               .modemuxs = pwm3_pin_28_modemux,
+               .nmodemuxs = ARRAY_SIZE(pwm3_pin_28_modemux),
+       }, {
+               .name = "pwm3_pin_40_grp",
+               .pins = pwm3_pins[3],
+               .npins = ARRAY_SIZE(pwm3_pins[3]),
+               .modemuxs = pwm3_pin_40_modemux,
+               .nmodemuxs = ARRAY_SIZE(pwm3_pin_40_modemux),
+       }, {
+               .name = "pwm3_pin_57_grp",
+               .pins = pwm3_pins[4],
+               .npins = ARRAY_SIZE(pwm3_pins[4]),
+               .modemuxs = pwm3_pin_57_modemux,
+               .nmodemuxs = ARRAY_SIZE(pwm3_pin_57_modemux),
+       }, {
+               .name = "pwm3_pin_86_grp",
+               .pins = pwm3_pins[5],
+               .npins = ARRAY_SIZE(pwm3_pins[5]),
+               .modemuxs = pwm3_pin_86_modemux,
+               .nmodemuxs = ARRAY_SIZE(pwm3_pin_86_modemux),
+       },
+};
+
+static const char *const pwm3_grps[] = { "pwm3_pin_6_grp", "pwm3_pin_12_grp",
+       "pwm3_pin_28_grp", "pwm3_pin_40_grp", "pwm3_pin_57_grp",
+       "pwm3_pin_86_grp" };
+static struct spear_function pwm3_function = {
+       .name = "pwm3",
+       .groups = pwm3_grps,
+       .ngroups = ARRAY_SIZE(pwm3_grps),
+};
+
+/* Pad multiplexing for SSP1 device */
+static const unsigned ssp1_pins[][2] = { { 17, 20 }, { 36, 39 }, { 48, 51 },
+       { 65, 68 }, { 94, 97 } };
+static struct spear_muxreg ssp1_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_MII_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_muxreg ssp1_ext_17_20_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_10_19_REG,
+               .mask = PMX_PL_17_18_MASK | PMX_PL_19_MASK,
+               .val = PMX_SSP1_PL_17_18_19_20_VAL,
+       }, {
+               .reg = IP_SEL_PAD_20_29_REG,
+               .mask = PMX_PL_20_MASK,
+               .val = PMX_SSP1_PL_17_18_19_20_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_SSP1_PORT_SEL_MASK,
+               .val = PMX_SSP1_PORT_17_TO_20_VAL,
+       },
+};
+
+static struct spear_muxreg ssp1_ext_36_39_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_UART0_MODEM_MASK | PMX_SSP_CS_MASK,
+               .val = 0,
+       }, {
+               .reg = IP_SEL_PAD_30_39_REG,
+               .mask = PMX_PL_36_MASK | PMX_PL_37_38_MASK | PMX_PL_39_MASK,
+               .val = PMX_SSP1_PL_36_VAL | PMX_SSP1_PL_37_38_VAL |
+                       PMX_SSP1_PL_39_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_SSP1_PORT_SEL_MASK,
+               .val = PMX_SSP1_PORT_36_TO_39_VAL,
+       },
+};
+
+static struct spear_muxreg ssp1_ext_48_51_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK,
+               .val = 0,
+       }, {
+               .reg = IP_SEL_PAD_40_49_REG,
+               .mask = PMX_PL_48_49_MASK,
+               .val = PMX_SSP1_PL_48_49_VAL,
+       }, {
+               .reg = IP_SEL_PAD_50_59_REG,
+               .mask = PMX_PL_50_51_MASK,
+               .val = PMX_SSP1_PL_50_51_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_SSP1_PORT_SEL_MASK,
+               .val = PMX_SSP1_PORT_48_TO_51_VAL,
+       },
+};
+
+static struct spear_muxreg ssp1_ext_65_68_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_60_69_REG,
+               .mask = PMX_PL_65_TO_68_MASK,
+               .val = PMX_SSP1_PL_65_TO_68_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_SSP1_PORT_SEL_MASK,
+               .val = PMX_SSP1_PORT_65_TO_68_VAL,
+       },
+};
+
+static struct spear_muxreg ssp1_ext_94_97_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_90_99_REG,
+               .mask = PMX_PL_94_95_MASK | PMX_PL_96_97_MASK,
+               .val = PMX_SSP1_PL_94_95_VAL | PMX_SSP1_PL_96_97_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_SSP1_PORT_SEL_MASK,
+               .val = PMX_SSP1_PORT_94_TO_97_VAL,
+       },
+};
+
+static struct spear_modemux ssp1_17_20_modemux[] = {
+       {
+               .modes = SMALL_PRINTERS_MODE | AUTO_NET_SMII_MODE |
+                       EXTENDED_MODE,
+               .muxregs = ssp1_muxreg,
+               .nmuxregs = ARRAY_SIZE(ssp1_muxreg),
+       }, {
+               .modes = EXTENDED_MODE,
+               .muxregs = ssp1_ext_17_20_muxreg,
+               .nmuxregs = ARRAY_SIZE(ssp1_ext_17_20_muxreg),
+       },
+};
+
+static struct spear_modemux ssp1_36_39_modemux[] = {
+       {
+               .modes = EXTENDED_MODE,
+               .muxregs = ssp1_ext_36_39_muxreg,
+               .nmuxregs = ARRAY_SIZE(ssp1_ext_36_39_muxreg),
+       },
+};
+
+static struct spear_modemux ssp1_48_51_modemux[] = {
+       {
+               .modes = EXTENDED_MODE,
+               .muxregs = ssp1_ext_48_51_muxreg,
+               .nmuxregs = ARRAY_SIZE(ssp1_ext_48_51_muxreg),
+       },
+};
+static struct spear_modemux ssp1_65_68_modemux[] = {
+       {
+               .modes = EXTENDED_MODE,
+               .muxregs = ssp1_ext_65_68_muxreg,
+               .nmuxregs = ARRAY_SIZE(ssp1_ext_65_68_muxreg),
+       },
+};
+
+static struct spear_modemux ssp1_94_97_modemux[] = {
+       {
+               .modes = EXTENDED_MODE,
+               .muxregs = ssp1_ext_94_97_muxreg,
+               .nmuxregs = ARRAY_SIZE(ssp1_ext_94_97_muxreg),
+       },
+};
+
+static struct spear_pingroup ssp1_pingroup[] = {
+       {
+               .name = "ssp1_17_20_grp",
+               .pins = ssp1_pins[0],
+               .npins = ARRAY_SIZE(ssp1_pins[0]),
+               .modemuxs = ssp1_17_20_modemux,
+               .nmodemuxs = ARRAY_SIZE(ssp1_17_20_modemux),
+       }, {
+               .name = "ssp1_36_39_grp",
+               .pins = ssp1_pins[1],
+               .npins = ARRAY_SIZE(ssp1_pins[1]),
+               .modemuxs = ssp1_36_39_modemux,
+               .nmodemuxs = ARRAY_SIZE(ssp1_36_39_modemux),
+       }, {
+               .name = "ssp1_48_51_grp",
+               .pins = ssp1_pins[2],
+               .npins = ARRAY_SIZE(ssp1_pins[2]),
+               .modemuxs = ssp1_48_51_modemux,
+               .nmodemuxs = ARRAY_SIZE(ssp1_48_51_modemux),
+       }, {
+               .name = "ssp1_65_68_grp",
+               .pins = ssp1_pins[3],
+               .npins = ARRAY_SIZE(ssp1_pins[3]),
+               .modemuxs = ssp1_65_68_modemux,
+               .nmodemuxs = ARRAY_SIZE(ssp1_65_68_modemux),
+       }, {
+               .name = "ssp1_94_97_grp",
+               .pins = ssp1_pins[4],
+               .npins = ARRAY_SIZE(ssp1_pins[4]),
+               .modemuxs = ssp1_94_97_modemux,
+               .nmodemuxs = ARRAY_SIZE(ssp1_94_97_modemux),
+       },
+};
+
+static const char *const ssp1_grps[] = { "ssp1_17_20_grp", "ssp1_36_39_grp",
+       "ssp1_48_51_grp", "ssp1_65_68_grp", "ssp1_94_97_grp"
+};
+static struct spear_function ssp1_function = {
+       .name = "ssp1",
+       .groups = ssp1_grps,
+       .ngroups = ARRAY_SIZE(ssp1_grps),
+};
+
+/* Pad multiplexing for SSP2 device */
+static const unsigned ssp2_pins[][2] = { { 13, 16 }, { 32, 35 }, { 44, 47 },
+       { 61, 64 }, { 90, 93 } };
+static struct spear_muxreg ssp2_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_MII_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_muxreg ssp2_ext_13_16_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_10_19_REG,
+               .mask = PMX_PL_13_14_MASK | PMX_PL_15_16_MASK,
+               .val = PMX_SSP2_PL_13_14_15_16_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_SSP2_PORT_SEL_MASK,
+               .val = PMX_SSP2_PORT_13_TO_16_VAL,
+       },
+};
+
+static struct spear_muxreg ssp2_ext_32_35_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_SSP_CS_MASK | PMX_GPIO_PIN4_MASK |
+                       PMX_GPIO_PIN5_MASK,
+               .val = 0,
+       }, {
+               .reg = IP_SEL_PAD_30_39_REG,
+               .mask = PMX_PL_32_33_MASK | PMX_PL_34_MASK | PMX_PL_35_MASK,
+               .val = PMX_SSP2_PL_32_33_VAL | PMX_SSP2_PL_34_VAL |
+                       PMX_SSP2_PL_35_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_SSP2_PORT_SEL_MASK,
+               .val = PMX_SSP2_PORT_32_TO_35_VAL,
+       },
+};
+
+static struct spear_muxreg ssp2_ext_44_47_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK,
+               .val = 0,
+       }, {
+               .reg = IP_SEL_PAD_40_49_REG,
+               .mask = PMX_PL_44_45_MASK | PMX_PL_46_47_MASK,
+               .val = PMX_SSP2_PL_44_45_VAL | PMX_SSP2_PL_46_47_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_SSP2_PORT_SEL_MASK,
+               .val = PMX_SSP2_PORT_44_TO_47_VAL,
+       },
+};
+
+static struct spear_muxreg ssp2_ext_61_64_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_60_69_REG,
+               .mask = PMX_PL_61_TO_64_MASK,
+               .val = PMX_SSP2_PL_61_TO_64_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_SSP2_PORT_SEL_MASK,
+               .val = PMX_SSP2_PORT_61_TO_64_VAL,
+       },
+};
+
+static struct spear_muxreg ssp2_ext_90_93_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_90_99_REG,
+               .mask = PMX_PL_90_91_MASK | PMX_PL_92_93_MASK,
+               .val = PMX_SSP2_PL_90_91_VAL | PMX_SSP2_PL_92_93_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_SSP2_PORT_SEL_MASK,
+               .val = PMX_SSP2_PORT_90_TO_93_VAL,
+       },
+};
+
+static struct spear_modemux ssp2_13_16_modemux[] = {
+       {
+               .modes = AUTO_NET_SMII_MODE | EXTENDED_MODE,
+               .muxregs = ssp2_muxreg,
+               .nmuxregs = ARRAY_SIZE(ssp2_muxreg),
+       }, {
+               .modes = EXTENDED_MODE,
+               .muxregs = ssp2_ext_13_16_muxreg,
+               .nmuxregs = ARRAY_SIZE(ssp2_ext_13_16_muxreg),
+       },
+};
+
+static struct spear_modemux ssp2_32_35_modemux[] = {
+       {
+               .modes = EXTENDED_MODE,
+               .muxregs = ssp2_ext_32_35_muxreg,
+               .nmuxregs = ARRAY_SIZE(ssp2_ext_32_35_muxreg),
+       },
+};
+
+static struct spear_modemux ssp2_44_47_modemux[] = {
+       {
+               .modes = EXTENDED_MODE,
+               .muxregs = ssp2_ext_44_47_muxreg,
+               .nmuxregs = ARRAY_SIZE(ssp2_ext_44_47_muxreg),
+       },
+};
+
+static struct spear_modemux ssp2_61_64_modemux[] = {
+       {
+               .modes = EXTENDED_MODE,
+               .muxregs = ssp2_ext_61_64_muxreg,
+               .nmuxregs = ARRAY_SIZE(ssp2_ext_61_64_muxreg),
+       },
+};
+
+static struct spear_modemux ssp2_90_93_modemux[] = {
+       {
+               .modes = EXTENDED_MODE,
+               .muxregs = ssp2_ext_90_93_muxreg,
+               .nmuxregs = ARRAY_SIZE(ssp2_ext_90_93_muxreg),
+       },
+};
+
+static struct spear_pingroup ssp2_pingroup[] = {
+       {
+               .name = "ssp2_13_16_grp",
+               .pins = ssp2_pins[0],
+               .npins = ARRAY_SIZE(ssp2_pins[0]),
+               .modemuxs = ssp2_13_16_modemux,
+               .nmodemuxs = ARRAY_SIZE(ssp2_13_16_modemux),
+       }, {
+               .name = "ssp2_32_35_grp",
+               .pins = ssp2_pins[1],
+               .npins = ARRAY_SIZE(ssp2_pins[1]),
+               .modemuxs = ssp2_32_35_modemux,
+               .nmodemuxs = ARRAY_SIZE(ssp2_32_35_modemux),
+       }, {
+               .name = "ssp2_44_47_grp",
+               .pins = ssp2_pins[2],
+               .npins = ARRAY_SIZE(ssp2_pins[2]),
+               .modemuxs = ssp2_44_47_modemux,
+               .nmodemuxs = ARRAY_SIZE(ssp2_44_47_modemux),
+       }, {
+               .name = "ssp2_61_64_grp",
+               .pins = ssp2_pins[3],
+               .npins = ARRAY_SIZE(ssp2_pins[3]),
+               .modemuxs = ssp2_61_64_modemux,
+               .nmodemuxs = ARRAY_SIZE(ssp2_61_64_modemux),
+       }, {
+               .name = "ssp2_90_93_grp",
+               .pins = ssp2_pins[4],
+               .npins = ARRAY_SIZE(ssp2_pins[4]),
+               .modemuxs = ssp2_90_93_modemux,
+               .nmodemuxs = ARRAY_SIZE(ssp2_90_93_modemux),
+       },
+};
+
+static const char *const ssp2_grps[] = { "ssp2_13_16_grp", "ssp2_32_35_grp",
+       "ssp2_44_47_grp", "ssp2_61_64_grp", "ssp2_90_93_grp" };
+static struct spear_function ssp2_function = {
+       .name = "ssp2",
+       .groups = ssp2_grps,
+       .ngroups = ARRAY_SIZE(ssp2_grps),
+};
+
+/* Pad multiplexing for cadence mii2 as mii device */
+static const unsigned mii2_pins[] = { 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+       90, 91, 92, 93, 94, 95, 96, 97 };
+static struct spear_muxreg mii2_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_80_89_REG,
+               .mask = PMX_PL_80_TO_85_MASK | PMX_PL_86_87_MASK |
+                       PMX_PL_88_89_MASK,
+               .val = PMX_MII2_PL_80_TO_85_VAL | PMX_MII2_PL_86_87_VAL |
+                       PMX_MII2_PL_88_89_VAL,
+       }, {
+               .reg = IP_SEL_PAD_90_99_REG,
+               .mask = PMX_PL_90_91_MASK | PMX_PL_92_93_MASK |
+                       PMX_PL_94_95_MASK | PMX_PL_96_97_MASK,
+               .val = PMX_MII2_PL_90_91_VAL | PMX_MII2_PL_92_93_VAL |
+                       PMX_MII2_PL_94_95_VAL | PMX_MII2_PL_96_97_VAL,
+       }, {
+               .reg = EXT_CTRL_REG,
+               .mask = (MAC_MODE_MASK << MAC2_MODE_SHIFT) |
+                       (MAC_MODE_MASK << MAC1_MODE_SHIFT) |
+                       MII_MDIO_MASK,
+               .val = (MAC_MODE_MII << MAC2_MODE_SHIFT) |
+                       (MAC_MODE_MII << MAC1_MODE_SHIFT) |
+                       MII_MDIO_81_VAL,
+       },
+};
+
+static struct spear_modemux mii2_modemux[] = {
+       {
+               .modes = EXTENDED_MODE,
+               .muxregs = mii2_muxreg,
+               .nmuxregs = ARRAY_SIZE(mii2_muxreg),
+       },
+};
+
+static struct spear_pingroup mii2_pingroup = {
+       .name = "mii2_grp",
+       .pins = mii2_pins,
+       .npins = ARRAY_SIZE(mii2_pins),
+       .modemuxs = mii2_modemux,
+       .nmodemuxs = ARRAY_SIZE(mii2_modemux),
+};
+
+static const char *const mii2_grps[] = { "mii2_grp" };
+static struct spear_function mii2_function = {
+       .name = "mii2",
+       .groups = mii2_grps,
+       .ngroups = ARRAY_SIZE(mii2_grps),
+};
+
+/* Pad multiplexing for cadence mii 1_2 as smii or rmii device */
+static const unsigned smii0_1_pins[] = { 10, 11, 13, 14, 15, 16, 17, 18, 19, 20,
+       21, 22, 23, 24, 25, 26, 27 };
+static const unsigned rmii0_1_pins[] = { 10, 11, 21, 22, 23, 24, 25, 26, 27 };
+static struct spear_muxreg mii0_1_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_MII_MASK,
+               .val = 0,
+       },
+};
+
+static struct spear_muxreg smii0_1_ext_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_10_19_REG,
+               .mask = PMX_PL_10_11_MASK,
+               .val = PMX_SMII_PL_10_11_VAL,
+       }, {
+               .reg = IP_SEL_PAD_20_29_REG,
+               .mask = PMX_PL_21_TO_27_MASK,
+               .val = PMX_SMII_PL_21_TO_27_VAL,
+       }, {
+               .reg = EXT_CTRL_REG,
+               .mask = (MAC_MODE_MASK << MAC2_MODE_SHIFT) |
+                       (MAC_MODE_MASK << MAC1_MODE_SHIFT) |
+                       MII_MDIO_MASK,
+               .val = (MAC_MODE_SMII << MAC2_MODE_SHIFT)
+                       | (MAC_MODE_SMII << MAC1_MODE_SHIFT)
+                       | MII_MDIO_10_11_VAL,
+       },
+};
+
+static struct spear_muxreg rmii0_1_ext_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_10_19_REG,
+               .mask = PMX_PL_10_11_MASK | PMX_PL_13_14_MASK |
+                       PMX_PL_15_16_MASK | PMX_PL_17_18_MASK | PMX_PL_19_MASK,
+               .val = PMX_RMII_PL_10_11_VAL | PMX_RMII_PL_13_14_VAL |
+                       PMX_RMII_PL_15_16_VAL | PMX_RMII_PL_17_18_VAL |
+                       PMX_RMII_PL_19_VAL,
+       }, {
+               .reg = IP_SEL_PAD_20_29_REG,
+               .mask = PMX_PL_20_MASK | PMX_PL_21_TO_27_MASK,
+               .val = PMX_RMII_PL_20_VAL | PMX_RMII_PL_21_TO_27_VAL,
+       }, {
+               .reg = EXT_CTRL_REG,
+               .mask = (MAC_MODE_MASK << MAC2_MODE_SHIFT) |
+                       (MAC_MODE_MASK << MAC1_MODE_SHIFT) |
+                       MII_MDIO_MASK,
+               .val = (MAC_MODE_RMII << MAC2_MODE_SHIFT)
+                       | (MAC_MODE_RMII << MAC1_MODE_SHIFT)
+                       | MII_MDIO_10_11_VAL,
+       },
+};
+
+static struct spear_modemux mii0_1_modemux[][2] = {
+       {
+               /* configure as smii */
+               {
+                       .modes = AUTO_NET_SMII_MODE | AUTO_EXP_MODE |
+                               SMALL_PRINTERS_MODE | EXTENDED_MODE,
+                       .muxregs = mii0_1_muxreg,
+                       .nmuxregs = ARRAY_SIZE(mii0_1_muxreg),
+               }, {
+                       .modes = EXTENDED_MODE,
+                       .muxregs = smii0_1_ext_muxreg,
+                       .nmuxregs = ARRAY_SIZE(smii0_1_ext_muxreg),
+               },
+       }, {
+               /* configure as rmii */
+               {
+                       .modes = AUTO_NET_SMII_MODE | AUTO_EXP_MODE |
+                               SMALL_PRINTERS_MODE | EXTENDED_MODE,
+                       .muxregs = mii0_1_muxreg,
+                       .nmuxregs = ARRAY_SIZE(mii0_1_muxreg),
+               }, {
+                       .modes = EXTENDED_MODE,
+                       .muxregs = rmii0_1_ext_muxreg,
+                       .nmuxregs = ARRAY_SIZE(rmii0_1_ext_muxreg),
+               },
+       },
+};
+
+static struct spear_pingroup mii0_1_pingroup[] = {
+       {
+               .name = "smii0_1_grp",
+               .pins = smii0_1_pins,
+               .npins = ARRAY_SIZE(smii0_1_pins),
+               .modemuxs = mii0_1_modemux[0],
+               .nmodemuxs = ARRAY_SIZE(mii0_1_modemux[0]),
+       }, {
+               .name = "rmii0_1_grp",
+               .pins = rmii0_1_pins,
+               .npins = ARRAY_SIZE(rmii0_1_pins),
+               .modemuxs = mii0_1_modemux[1],
+               .nmodemuxs = ARRAY_SIZE(mii0_1_modemux[1]),
+       },
+};
+
+static const char *const mii0_1_grps[] = { "smii0_1_grp", "rmii0_1_grp" };
+static struct spear_function mii0_1_function = {
+       .name = "mii0_1",
+       .groups = mii0_1_grps,
+       .ngroups = ARRAY_SIZE(mii0_1_grps),
+};
+
+/* Pad multiplexing for i2c1 device */
+static const unsigned i2c1_pins[][2] = { { 8, 9 }, { 98, 99 } };
+static struct spear_muxreg i2c1_ext_8_9_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_SSP_CS_MASK,
+               .val = 0,
+       }, {
+               .reg = IP_SEL_PAD_0_9_REG,
+               .mask = PMX_PL_8_9_MASK,
+               .val = PMX_I2C1_PL_8_9_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_I2C1_PORT_SEL_MASK,
+               .val = PMX_I2C1_PORT_8_9_VAL,
+       },
+};
+
+static struct spear_muxreg i2c1_ext_98_99_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_90_99_REG,
+               .mask = PMX_PL_98_MASK | PMX_PL_99_MASK,
+               .val = PMX_I2C1_PL_98_VAL | PMX_I2C1_PL_99_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_I2C1_PORT_SEL_MASK,
+               .val = PMX_I2C1_PORT_98_99_VAL,
+       },
+};
+
+static struct spear_modemux i2c1_modemux[][1] = {
+       {
+               /* Select signals on pins 8-9 */
+               {
+                       .modes = EXTENDED_MODE,
+                       .muxregs = i2c1_ext_8_9_muxreg,
+                       .nmuxregs = ARRAY_SIZE(i2c1_ext_8_9_muxreg),
+               },
+       }, {
+               /* Select signals on pins 98-99 */
+               {
+                       .modes = EXTENDED_MODE,
+                       .muxregs = i2c1_ext_98_99_muxreg,
+                       .nmuxregs = ARRAY_SIZE(i2c1_ext_98_99_muxreg),
+               },
+       },
+};
+
+static struct spear_pingroup i2c1_pingroup[] = {
+       {
+               .name = "i2c1_8_9_grp",
+               .pins = i2c1_pins[0],
+               .npins = ARRAY_SIZE(i2c1_pins[0]),
+               .modemuxs = i2c1_modemux[0],
+               .nmodemuxs = ARRAY_SIZE(i2c1_modemux[0]),
+       }, {
+               .name = "i2c1_98_99_grp",
+               .pins = i2c1_pins[1],
+               .npins = ARRAY_SIZE(i2c1_pins[1]),
+               .modemuxs = i2c1_modemux[1],
+               .nmodemuxs = ARRAY_SIZE(i2c1_modemux[1]),
+       },
+};
+
+static const char *const i2c1_grps[] = { "i2c1_8_9_grp", "i2c1_98_99_grp" };
+static struct spear_function i2c1_function = {
+       .name = "i2c1",
+       .groups = i2c1_grps,
+       .ngroups = ARRAY_SIZE(i2c1_grps),
+};
+
+/* Pad multiplexing for i2c2 device */
+static const unsigned i2c2_pins[][2] = { { 0, 1 }, { 2, 3 }, { 19, 20 },
+       { 75, 76 }, { 96, 97 } };
+static struct spear_muxreg i2c2_ext_0_1_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_FIRDA_MASK,
+               .val = 0,
+       }, {
+               .reg = IP_SEL_PAD_0_9_REG,
+               .mask = PMX_PL_0_1_MASK,
+               .val = PMX_I2C2_PL_0_1_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_I2C2_PORT_SEL_MASK,
+               .val = PMX_I2C2_PORT_0_1_VAL,
+       },
+};
+
+static struct spear_muxreg i2c2_ext_2_3_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_UART0_MASK,
+               .val = 0,
+       }, {
+               .reg = IP_SEL_PAD_0_9_REG,
+               .mask = PMX_PL_2_3_MASK,
+               .val = PMX_I2C2_PL_2_3_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_I2C2_PORT_SEL_MASK,
+               .val = PMX_I2C2_PORT_2_3_VAL,
+       },
+};
+
+static struct spear_muxreg i2c2_ext_19_20_muxreg[] = {
+       {
+               .reg = PMX_CONFIG_REG,
+               .mask = PMX_MII_MASK,
+               .val = 0,
+       }, {
+               .reg = IP_SEL_PAD_10_19_REG,
+               .mask = PMX_PL_19_MASK,
+               .val = PMX_I2C2_PL_19_VAL,
+       }, {
+               .reg = IP_SEL_PAD_20_29_REG,
+               .mask = PMX_PL_20_MASK,
+               .val = PMX_I2C2_PL_20_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_I2C2_PORT_SEL_MASK,
+               .val = PMX_I2C2_PORT_19_20_VAL,
+       },
+};
+
+static struct spear_muxreg i2c2_ext_75_76_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_70_79_REG,
+               .mask = PMX_PL_75_76_MASK,
+               .val = PMX_I2C2_PL_75_76_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_I2C2_PORT_SEL_MASK,
+               .val = PMX_I2C2_PORT_75_76_VAL,
+       },
+};
+
+static struct spear_muxreg i2c2_ext_96_97_muxreg[] = {
+       {
+               .reg = IP_SEL_PAD_90_99_REG,
+               .mask = PMX_PL_96_97_MASK,
+               .val = PMX_I2C2_PL_96_97_VAL,
+       }, {
+               .reg = IP_SEL_MIX_PAD_REG,
+               .mask = PMX_I2C2_PORT_SEL_MASK,
+               .val = PMX_I2C2_PORT_96_97_VAL,
+       },
+};
+
+static struct spear_modemux i2c2_modemux[][1] = {
+       {
+               /* Select signals on pins 0_1 */
+               {
+                       .modes = EXTENDED_MODE,
+                       .muxregs = i2c2_ext_0_1_muxreg,
+                       .nmuxregs = ARRAY_SIZE(i2c2_ext_0_1_muxreg),
+               },
+       }, {
+               /* Select signals on pins 2_3 */
+               {
+                       .modes = EXTENDED_MODE,
+                       .muxregs = i2c2_ext_2_3_muxreg,
+                       .nmuxregs = ARRAY_SIZE(i2c2_ext_2_3_muxreg),
+               },
+       }, {
+               /* Select signals on pins 19_20 */
+               {
+                       .modes = EXTENDED_MODE,
+                       .muxregs = i2c2_ext_19_20_muxreg,
+                       .nmuxregs = ARRAY_SIZE(i2c2_ext_19_20_muxreg),
+               },
+       }, {
+               /* Select signals on pins 75_76 */
+               {
+                       .modes = EXTENDED_MODE,
+                       .muxregs = i2c2_ext_75_76_muxreg,
+                       .nmuxregs = ARRAY_SIZE(i2c2_ext_75_76_muxreg),
+               },
+       }, {
+               /* Select signals on pins 96_97 */
+               {
+                       .modes = EXTENDED_MODE,
+                       .muxregs = i2c2_ext_96_97_muxreg,
+                       .nmuxregs = ARRAY_SIZE(i2c2_ext_96_97_muxreg),
+               },
+       },
+};
+
+static struct spear_pingroup i2c2_pingroup[] = {
+       {
+               .name = "i2c2_0_1_grp",
+               .pins = i2c2_pins[0],
+               .npins = ARRAY_SIZE(i2c2_pins[0]),
+               .modemuxs = i2c2_modemux[0],
+               .nmodemuxs = ARRAY_SIZE(i2c2_modemux[0]),
+       }, {
+               .name = "i2c2_2_3_grp",
+               .pins = i2c2_pins[1],
+               .npins = ARRAY_SIZE(i2c2_pins[1]),
+               .modemuxs = i2c2_modemux[1],
+               .nmodemuxs = ARRAY_SIZE(i2c2_modemux[1]),
+       }, {
+               .name = "i2c2_19_20_grp",
+               .pins = i2c2_pins[2],
+               .npins = ARRAY_SIZE(i2c2_pins[2]),
+               .modemuxs = i2c2_modemux[2],
+               .nmodemuxs = ARRAY_SIZE(i2c2_modemux[2]),
+       }, {
+               .name = "i2c2_75_76_grp",
+               .pins = i2c2_pins[3],
+               .npins = ARRAY_SIZE(i2c2_pins[3]),
+               .modemuxs = i2c2_modemux[3],
+               .nmodemuxs = ARRAY_SIZE(i2c2_modemux[3]),
+       }, {
+               .name = "i2c2_96_97_grp",
+               .pins = i2c2_pins[4],
+               .npins = ARRAY_SIZE(i2c2_pins[4]),
+               .modemuxs = i2c2_modemux[4],
+               .nmodemuxs = ARRAY_SIZE(i2c2_modemux[4]),
+       },
+};
+
+static const char *const i2c2_grps[] = { "i2c2_0_1_grp", "i2c2_2_3_grp",
+       "i2c2_19_20_grp", "i2c2_75_76_grp", "i2c2_96_97_grp" };
+static struct spear_function i2c2_function = {
+       .name = "i2c2",
+       .groups = i2c2_grps,
+       .ngroups = ARRAY_SIZE(i2c2_grps),
+};
+
+/* pingroups */
+static struct spear_pingroup *spear320_pingroups[] = {
+       SPEAR3XX_COMMON_PINGROUPS,
+       &clcd_pingroup,
+       &emi_pingroup,
+       &fsmc_8bit_pingroup,
+       &fsmc_16bit_pingroup,
+       &spp_pingroup,
+       &sdhci_led_pingroup,
+       &sdhci_pingroup[0],
+       &sdhci_pingroup[1],
+       &i2s_pingroup,
+       &uart1_pingroup,
+       &uart1_modem_pingroup[0],
+       &uart1_modem_pingroup[1],
+       &uart1_modem_pingroup[2],
+       &uart1_modem_pingroup[3],
+       &uart2_pingroup,
+       &uart3_pingroup[0],
+       &uart3_pingroup[1],
+       &uart3_pingroup[2],
+       &uart3_pingroup[3],
+       &uart3_pingroup[4],
+       &uart3_pingroup[5],
+       &uart3_pingroup[6],
+       &uart4_pingroup[0],
+       &uart4_pingroup[1],
+       &uart4_pingroup[2],
+       &uart4_pingroup[3],
+       &uart4_pingroup[4],
+       &uart4_pingroup[5],
+       &uart5_pingroup[0],
+       &uart5_pingroup[1],
+       &uart5_pingroup[2],
+       &uart5_pingroup[3],
+       &uart6_pingroup[0],
+       &uart6_pingroup[1],
+       &rs485_pingroup,
+       &touchscreen_pingroup,
+       &can0_pingroup,
+       &can1_pingroup,
+       &pwm0_1_pingroup[0],
+       &pwm0_1_pingroup[1],
+       &pwm0_1_pingroup[2],
+       &pwm0_1_pingroup[3],
+       &pwm0_1_pingroup[4],
+       &pwm0_1_pingroup[5],
+       &pwm0_1_pingroup[6],
+       &pwm2_pingroup[0],
+       &pwm2_pingroup[1],
+       &pwm2_pingroup[2],
+       &pwm2_pingroup[3],
+       &pwm2_pingroup[4],
+       &pwm2_pingroup[5],
+       &pwm2_pingroup[6],
+       &pwm3_pingroup[0],
+       &pwm3_pingroup[1],
+       &pwm3_pingroup[2],
+       &pwm3_pingroup[3],
+       &pwm3_pingroup[4],
+       &pwm3_pingroup[5],
+       &ssp1_pingroup[0],
+       &ssp1_pingroup[1],
+       &ssp1_pingroup[2],
+       &ssp1_pingroup[3],
+       &ssp1_pingroup[4],
+       &ssp2_pingroup[0],
+       &ssp2_pingroup[1],
+       &ssp2_pingroup[2],
+       &ssp2_pingroup[3],
+       &ssp2_pingroup[4],
+       &mii2_pingroup,
+       &mii0_1_pingroup[0],
+       &mii0_1_pingroup[1],
+       &i2c1_pingroup[0],
+       &i2c1_pingroup[1],
+       &i2c2_pingroup[0],
+       &i2c2_pingroup[1],
+       &i2c2_pingroup[2],
+       &i2c2_pingroup[3],
+       &i2c2_pingroup[4],
+};
+
+/* functions */
+static struct spear_function *spear320_functions[] = {
+       SPEAR3XX_COMMON_FUNCTIONS,
+       &clcd_function,
+       &emi_function,
+       &fsmc_function,
+       &spp_function,
+       &sdhci_function,
+       &i2s_function,
+       &uart1_function,
+       &uart1_modem_function,
+       &uart2_function,
+       &uart3_function,
+       &uart4_function,
+       &uart5_function,
+       &uart6_function,
+       &rs485_function,
+       &touchscreen_function,
+       &can0_function,
+       &can1_function,
+       &pwm0_1_function,
+       &pwm2_function,
+       &pwm3_function,
+       &ssp1_function,
+       &ssp2_function,
+       &mii2_function,
+       &mii0_1_function,
+       &i2c1_function,
+       &i2c2_function,
+};
+
+static struct of_device_id spear320_pinctrl_of_match[] __devinitdata = {
+       {
+               .compatible = "st,spear320-pinmux",
+       },
+       {},
+};
+
+static int __devinit spear320_pinctrl_probe(struct platform_device *pdev)
+{
+       int ret;
+
+       spear3xx_machdata.groups = spear320_pingroups;
+       spear3xx_machdata.ngroups = ARRAY_SIZE(spear320_pingroups);
+       spear3xx_machdata.functions = spear320_functions;
+       spear3xx_machdata.nfunctions = ARRAY_SIZE(spear320_functions);
+
+       spear3xx_machdata.modes_supported = true;
+       spear3xx_machdata.pmx_modes = spear320_pmx_modes;
+       spear3xx_machdata.npmx_modes = ARRAY_SIZE(spear320_pmx_modes);
+
+       pmx_init_addr(&spear3xx_machdata, PMX_CONFIG_REG);
+
+       ret = spear_pinctrl_probe(pdev, &spear3xx_machdata);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static int __devexit spear320_pinctrl_remove(struct platform_device *pdev)
+{
+       return spear_pinctrl_remove(pdev);
+}
+
+static struct platform_driver spear320_pinctrl_driver = {
+       .driver = {
+               .name = DRIVER_NAME,
+               .owner = THIS_MODULE,
+               .of_match_table = spear320_pinctrl_of_match,
+       },
+       .probe = spear320_pinctrl_probe,
+       .remove = __devexit_p(spear320_pinctrl_remove),
+};
+
+static int __init spear320_pinctrl_init(void)
+{
+       return platform_driver_register(&spear320_pinctrl_driver);
+}
+arch_initcall(spear320_pinctrl_init);
+
+static void __exit spear320_pinctrl_exit(void)
+{
+       platform_driver_unregister(&spear320_pinctrl_driver);
+}
+module_exit(spear320_pinctrl_exit);
+
+MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>");
+MODULE_DESCRIPTION("ST Microelectronics SPEAr320 pinctrl driver");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, spear320_pinctrl_of_match);
diff --git a/drivers/pinctrl/spear/pinctrl-spear3xx.c b/drivers/pinctrl/spear/pinctrl-spear3xx.c
new file mode 100644 (file)
index 0000000..832049a
--- /dev/null
@@ -0,0 +1,588 @@
+/*
+ * Driver for the ST Microelectronics SPEAr3xx pinmux
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-spear3xx.h"
+
+/* pins */
+static const struct pinctrl_pin_desc spear3xx_pins[] = {
+       PINCTRL_PIN(0, "PLGPIO0"),
+       PINCTRL_PIN(1, "PLGPIO1"),
+       PINCTRL_PIN(2, "PLGPIO2"),
+       PINCTRL_PIN(3, "PLGPIO3"),
+       PINCTRL_PIN(4, "PLGPIO4"),
+       PINCTRL_PIN(5, "PLGPIO5"),
+       PINCTRL_PIN(6, "PLGPIO6"),
+       PINCTRL_PIN(7, "PLGPIO7"),
+       PINCTRL_PIN(8, "PLGPIO8"),
+       PINCTRL_PIN(9, "PLGPIO9"),
+       PINCTRL_PIN(10, "PLGPIO10"),
+       PINCTRL_PIN(11, "PLGPIO11"),
+       PINCTRL_PIN(12, "PLGPIO12"),
+       PINCTRL_PIN(13, "PLGPIO13"),
+       PINCTRL_PIN(14, "PLGPIO14"),
+       PINCTRL_PIN(15, "PLGPIO15"),
+       PINCTRL_PIN(16, "PLGPIO16"),
+       PINCTRL_PIN(17, "PLGPIO17"),
+       PINCTRL_PIN(18, "PLGPIO18"),
+       PINCTRL_PIN(19, "PLGPIO19"),
+       PINCTRL_PIN(20, "PLGPIO20"),
+       PINCTRL_PIN(21, "PLGPIO21"),
+       PINCTRL_PIN(22, "PLGPIO22"),
+       PINCTRL_PIN(23, "PLGPIO23"),
+       PINCTRL_PIN(24, "PLGPIO24"),
+       PINCTRL_PIN(25, "PLGPIO25"),
+       PINCTRL_PIN(26, "PLGPIO26"),
+       PINCTRL_PIN(27, "PLGPIO27"),
+       PINCTRL_PIN(28, "PLGPIO28"),
+       PINCTRL_PIN(29, "PLGPIO29"),
+       PINCTRL_PIN(30, "PLGPIO30"),
+       PINCTRL_PIN(31, "PLGPIO31"),
+       PINCTRL_PIN(32, "PLGPIO32"),
+       PINCTRL_PIN(33, "PLGPIO33"),
+       PINCTRL_PIN(34, "PLGPIO34"),
+       PINCTRL_PIN(35, "PLGPIO35"),
+       PINCTRL_PIN(36, "PLGPIO36"),
+       PINCTRL_PIN(37, "PLGPIO37"),
+       PINCTRL_PIN(38, "PLGPIO38"),
+       PINCTRL_PIN(39, "PLGPIO39"),
+       PINCTRL_PIN(40, "PLGPIO40"),
+       PINCTRL_PIN(41, "PLGPIO41"),
+       PINCTRL_PIN(42, "PLGPIO42"),
+       PINCTRL_PIN(43, "PLGPIO43"),
+       PINCTRL_PIN(44, "PLGPIO44"),
+       PINCTRL_PIN(45, "PLGPIO45"),
+       PINCTRL_PIN(46, "PLGPIO46"),
+       PINCTRL_PIN(47, "PLGPIO47"),
+       PINCTRL_PIN(48, "PLGPIO48"),
+       PINCTRL_PIN(49, "PLGPIO49"),
+       PINCTRL_PIN(50, "PLGPIO50"),
+       PINCTRL_PIN(51, "PLGPIO51"),
+       PINCTRL_PIN(52, "PLGPIO52"),
+       PINCTRL_PIN(53, "PLGPIO53"),
+       PINCTRL_PIN(54, "PLGPIO54"),
+       PINCTRL_PIN(55, "PLGPIO55"),
+       PINCTRL_PIN(56, "PLGPIO56"),
+       PINCTRL_PIN(57, "PLGPIO57"),
+       PINCTRL_PIN(58, "PLGPIO58"),
+       PINCTRL_PIN(59, "PLGPIO59"),
+       PINCTRL_PIN(60, "PLGPIO60"),
+       PINCTRL_PIN(61, "PLGPIO61"),
+       PINCTRL_PIN(62, "PLGPIO62"),
+       PINCTRL_PIN(63, "PLGPIO63"),
+       PINCTRL_PIN(64, "PLGPIO64"),
+       PINCTRL_PIN(65, "PLGPIO65"),
+       PINCTRL_PIN(66, "PLGPIO66"),
+       PINCTRL_PIN(67, "PLGPIO67"),
+       PINCTRL_PIN(68, "PLGPIO68"),
+       PINCTRL_PIN(69, "PLGPIO69"),
+       PINCTRL_PIN(70, "PLGPIO70"),
+       PINCTRL_PIN(71, "PLGPIO71"),
+       PINCTRL_PIN(72, "PLGPIO72"),
+       PINCTRL_PIN(73, "PLGPIO73"),
+       PINCTRL_PIN(74, "PLGPIO74"),
+       PINCTRL_PIN(75, "PLGPIO75"),
+       PINCTRL_PIN(76, "PLGPIO76"),
+       PINCTRL_PIN(77, "PLGPIO77"),
+       PINCTRL_PIN(78, "PLGPIO78"),
+       PINCTRL_PIN(79, "PLGPIO79"),
+       PINCTRL_PIN(80, "PLGPIO80"),
+       PINCTRL_PIN(81, "PLGPIO81"),
+       PINCTRL_PIN(82, "PLGPIO82"),
+       PINCTRL_PIN(83, "PLGPIO83"),
+       PINCTRL_PIN(84, "PLGPIO84"),
+       PINCTRL_PIN(85, "PLGPIO85"),
+       PINCTRL_PIN(86, "PLGPIO86"),
+       PINCTRL_PIN(87, "PLGPIO87"),
+       PINCTRL_PIN(88, "PLGPIO88"),
+       PINCTRL_PIN(89, "PLGPIO89"),
+       PINCTRL_PIN(90, "PLGPIO90"),
+       PINCTRL_PIN(91, "PLGPIO91"),
+       PINCTRL_PIN(92, "PLGPIO92"),
+       PINCTRL_PIN(93, "PLGPIO93"),
+       PINCTRL_PIN(94, "PLGPIO94"),
+       PINCTRL_PIN(95, "PLGPIO95"),
+       PINCTRL_PIN(96, "PLGPIO96"),
+       PINCTRL_PIN(97, "PLGPIO97"),
+       PINCTRL_PIN(98, "PLGPIO98"),
+       PINCTRL_PIN(99, "PLGPIO99"),
+       PINCTRL_PIN(100, "PLGPIO100"),
+       PINCTRL_PIN(101, "PLGPIO101"),
+};
+
+/* firda_pins */
+static const unsigned firda_pins[] = { 0, 1 };
+static struct spear_muxreg firda_muxreg[] = {
+       {
+               .reg = -1,
+               .mask = PMX_FIRDA_MASK,
+               .val = PMX_FIRDA_MASK,
+       },
+};
+
+static struct spear_modemux firda_modemux[] = {
+       {
+               .modes = ~0,
+               .muxregs = firda_muxreg,
+               .nmuxregs = ARRAY_SIZE(firda_muxreg),
+       },
+};
+
+struct spear_pingroup spear3xx_firda_pingroup = {
+       .name = "firda_grp",
+       .pins = firda_pins,
+       .npins = ARRAY_SIZE(firda_pins),
+       .modemuxs = firda_modemux,
+       .nmodemuxs = ARRAY_SIZE(firda_modemux),
+};
+
+static const char *const firda_grps[] = { "firda_grp" };
+struct spear_function spear3xx_firda_function = {
+       .name = "firda",
+       .groups = firda_grps,
+       .ngroups = ARRAY_SIZE(firda_grps),
+};
+
+/* i2c_pins */
+static const unsigned i2c_pins[] = { 4, 5 };
+static struct spear_muxreg i2c_muxreg[] = {
+       {
+               .reg = -1,
+               .mask = PMX_I2C_MASK,
+               .val = PMX_I2C_MASK,
+       },
+};
+
+static struct spear_modemux i2c_modemux[] = {
+       {
+               .modes = ~0,
+               .muxregs = i2c_muxreg,
+               .nmuxregs = ARRAY_SIZE(i2c_muxreg),
+       },
+};
+
+struct spear_pingroup spear3xx_i2c_pingroup = {
+       .name = "i2c0_grp",
+       .pins = i2c_pins,
+       .npins = ARRAY_SIZE(i2c_pins),
+       .modemuxs = i2c_modemux,
+       .nmodemuxs = ARRAY_SIZE(i2c_modemux),
+};
+
+static const char *const i2c_grps[] = { "i2c0_grp" };
+struct spear_function spear3xx_i2c_function = {
+       .name = "i2c0",
+       .groups = i2c_grps,
+       .ngroups = ARRAY_SIZE(i2c_grps),
+};
+
+/* ssp_cs_pins */
+static const unsigned ssp_cs_pins[] = { 34, 35, 36 };
+static struct spear_muxreg ssp_cs_muxreg[] = {
+       {
+               .reg = -1,
+               .mask = PMX_SSP_CS_MASK,
+               .val = PMX_SSP_CS_MASK,
+       },
+};
+
+static struct spear_modemux ssp_cs_modemux[] = {
+       {
+               .modes = ~0,
+               .muxregs = ssp_cs_muxreg,
+               .nmuxregs = ARRAY_SIZE(ssp_cs_muxreg),
+       },
+};
+
+struct spear_pingroup spear3xx_ssp_cs_pingroup = {
+       .name = "ssp_cs_grp",
+       .pins = ssp_cs_pins,
+       .npins = ARRAY_SIZE(ssp_cs_pins),
+       .modemuxs = ssp_cs_modemux,
+       .nmodemuxs = ARRAY_SIZE(ssp_cs_modemux),
+};
+
+static const char *const ssp_cs_grps[] = { "ssp_cs_grp" };
+struct spear_function spear3xx_ssp_cs_function = {
+       .name = "ssp_cs",
+       .groups = ssp_cs_grps,
+       .ngroups = ARRAY_SIZE(ssp_cs_grps),
+};
+
+/* ssp_pins */
+static const unsigned ssp_pins[] = { 6, 7, 8, 9 };
+static struct spear_muxreg ssp_muxreg[] = {
+       {
+               .reg = -1,
+               .mask = PMX_SSP_MASK,
+               .val = PMX_SSP_MASK,
+       },
+};
+
+static struct spear_modemux ssp_modemux[] = {
+       {
+               .modes = ~0,
+               .muxregs = ssp_muxreg,
+               .nmuxregs = ARRAY_SIZE(ssp_muxreg),
+       },
+};
+
+struct spear_pingroup spear3xx_ssp_pingroup = {
+       .name = "ssp0_grp",
+       .pins = ssp_pins,
+       .npins = ARRAY_SIZE(ssp_pins),
+       .modemuxs = ssp_modemux,
+       .nmodemuxs = ARRAY_SIZE(ssp_modemux),
+};
+
+static const char *const ssp_grps[] = { "ssp0_grp" };
+struct spear_function spear3xx_ssp_function = {
+       .name = "ssp0",
+       .groups = ssp_grps,
+       .ngroups = ARRAY_SIZE(ssp_grps),
+};
+
+/* mii_pins */
+static const unsigned mii_pins[] = { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+       21, 22, 23, 24, 25, 26, 27 };
+static struct spear_muxreg mii_muxreg[] = {
+       {
+               .reg = -1,
+               .mask = PMX_MII_MASK,
+               .val = PMX_MII_MASK,
+       },
+};
+
+static struct spear_modemux mii_modemux[] = {
+       {
+               .modes = ~0,
+               .muxregs = mii_muxreg,
+               .nmuxregs = ARRAY_SIZE(mii_muxreg),
+       },
+};
+
+struct spear_pingroup spear3xx_mii_pingroup = {
+       .name = "mii0_grp",
+       .pins = mii_pins,
+       .npins = ARRAY_SIZE(mii_pins),
+       .modemuxs = mii_modemux,
+       .nmodemuxs = ARRAY_SIZE(mii_modemux),
+};
+
+static const char *const mii_grps[] = { "mii0_grp" };
+struct spear_function spear3xx_mii_function = {
+       .name = "mii0",
+       .groups = mii_grps,
+       .ngroups = ARRAY_SIZE(mii_grps),
+};
+
+/* gpio0_pin0_pins */
+static const unsigned gpio0_pin0_pins[] = { 28 };
+static struct spear_muxreg gpio0_pin0_muxreg[] = {
+       {
+               .reg = -1,
+               .mask = PMX_GPIO_PIN0_MASK,
+               .val = PMX_GPIO_PIN0_MASK,
+       },
+};
+
+static struct spear_modemux gpio0_pin0_modemux[] = {
+       {
+               .modes = ~0,
+               .muxregs = gpio0_pin0_muxreg,
+               .nmuxregs = ARRAY_SIZE(gpio0_pin0_muxreg),
+       },
+};
+
+struct spear_pingroup spear3xx_gpio0_pin0_pingroup = {
+       .name = "gpio0_pin0_grp",
+       .pins = gpio0_pin0_pins,
+       .npins = ARRAY_SIZE(gpio0_pin0_pins),
+       .modemuxs = gpio0_pin0_modemux,
+       .nmodemuxs = ARRAY_SIZE(gpio0_pin0_modemux),
+};
+
+/* gpio0_pin1_pins */
+static const unsigned gpio0_pin1_pins[] = { 29 };
+static struct spear_muxreg gpio0_pin1_muxreg[] = {
+       {
+               .reg = -1,
+               .mask = PMX_GPIO_PIN1_MASK,
+               .val = PMX_GPIO_PIN1_MASK,
+       },
+};
+
+static struct spear_modemux gpio0_pin1_modemux[] = {
+       {
+               .modes = ~0,
+               .muxregs = gpio0_pin1_muxreg,
+               .nmuxregs = ARRAY_SIZE(gpio0_pin1_muxreg),
+       },
+};
+
+struct spear_pingroup spear3xx_gpio0_pin1_pingroup = {
+       .name = "gpio0_pin1_grp",
+       .pins = gpio0_pin1_pins,
+       .npins = ARRAY_SIZE(gpio0_pin1_pins),
+       .modemuxs = gpio0_pin1_modemux,
+       .nmodemuxs = ARRAY_SIZE(gpio0_pin1_modemux),
+};
+
+/* gpio0_pin2_pins */
+static const unsigned gpio0_pin2_pins[] = { 30 };
+static struct spear_muxreg gpio0_pin2_muxreg[] = {
+       {
+               .reg = -1,
+               .mask = PMX_GPIO_PIN2_MASK,
+               .val = PMX_GPIO_PIN2_MASK,
+       },
+};
+
+static struct spear_modemux gpio0_pin2_modemux[] = {
+       {
+               .modes = ~0,
+               .muxregs = gpio0_pin2_muxreg,
+               .nmuxregs = ARRAY_SIZE(gpio0_pin2_muxreg),
+       },
+};
+
+struct spear_pingroup spear3xx_gpio0_pin2_pingroup = {
+       .name = "gpio0_pin2_grp",
+       .pins = gpio0_pin2_pins,
+       .npins = ARRAY_SIZE(gpio0_pin2_pins),
+       .modemuxs = gpio0_pin2_modemux,
+       .nmodemuxs = ARRAY_SIZE(gpio0_pin2_modemux),
+};
+
+/* gpio0_pin3_pins */
+static const unsigned gpio0_pin3_pins[] = { 31 };
+static struct spear_muxreg gpio0_pin3_muxreg[] = {
+       {
+               .reg = -1,
+               .mask = PMX_GPIO_PIN3_MASK,
+               .val = PMX_GPIO_PIN3_MASK,
+       },
+};
+
+static struct spear_modemux gpio0_pin3_modemux[] = {
+       {
+               .modes = ~0,
+               .muxregs = gpio0_pin3_muxreg,
+               .nmuxregs = ARRAY_SIZE(gpio0_pin3_muxreg),
+       },
+};
+
+struct spear_pingroup spear3xx_gpio0_pin3_pingroup = {
+       .name = "gpio0_pin3_grp",
+       .pins = gpio0_pin3_pins,
+       .npins = ARRAY_SIZE(gpio0_pin3_pins),
+       .modemuxs = gpio0_pin3_modemux,
+       .nmodemuxs = ARRAY_SIZE(gpio0_pin3_modemux),
+};
+
+/* gpio0_pin4_pins */
+static const unsigned gpio0_pin4_pins[] = { 32 };
+static struct spear_muxreg gpio0_pin4_muxreg[] = {
+       {
+               .reg = -1,
+               .mask = PMX_GPIO_PIN4_MASK,
+               .val = PMX_GPIO_PIN4_MASK,
+       },
+};
+
+static struct spear_modemux gpio0_pin4_modemux[] = {
+       {
+               .modes = ~0,
+               .muxregs = gpio0_pin4_muxreg,
+               .nmuxregs = ARRAY_SIZE(gpio0_pin4_muxreg),
+       },
+};
+
+struct spear_pingroup spear3xx_gpio0_pin4_pingroup = {
+       .name = "gpio0_pin4_grp",
+       .pins = gpio0_pin4_pins,
+       .npins = ARRAY_SIZE(gpio0_pin4_pins),
+       .modemuxs = gpio0_pin4_modemux,
+       .nmodemuxs = ARRAY_SIZE(gpio0_pin4_modemux),
+};
+
+/* gpio0_pin5_pins */
+static const unsigned gpio0_pin5_pins[] = { 33 };
+static struct spear_muxreg gpio0_pin5_muxreg[] = {
+       {
+               .reg = -1,
+               .mask = PMX_GPIO_PIN5_MASK,
+               .val = PMX_GPIO_PIN5_MASK,
+       },
+};
+
+static struct spear_modemux gpio0_pin5_modemux[] = {
+       {
+               .modes = ~0,
+               .muxregs = gpio0_pin5_muxreg,
+               .nmuxregs = ARRAY_SIZE(gpio0_pin5_muxreg),
+       },
+};
+
+struct spear_pingroup spear3xx_gpio0_pin5_pingroup = {
+       .name = "gpio0_pin5_grp",
+       .pins = gpio0_pin5_pins,
+       .npins = ARRAY_SIZE(gpio0_pin5_pins),
+       .modemuxs = gpio0_pin5_modemux,
+       .nmodemuxs = ARRAY_SIZE(gpio0_pin5_modemux),
+};
+
+static const char *const gpio0_grps[] = { "gpio0_pin0_grp", "gpio0_pin1_grp",
+       "gpio0_pin2_grp", "gpio0_pin3_grp", "gpio0_pin4_grp", "gpio0_pin5_grp",
+};
+struct spear_function spear3xx_gpio0_function = {
+       .name = "gpio0",
+       .groups = gpio0_grps,
+       .ngroups = ARRAY_SIZE(gpio0_grps),
+};
+
+/* uart0_ext_pins */
+static const unsigned uart0_ext_pins[] = { 37, 38, 39, 40, 41, 42 };
+static struct spear_muxreg uart0_ext_muxreg[] = {
+       {
+               .reg = -1,
+               .mask = PMX_UART0_MODEM_MASK,
+               .val = PMX_UART0_MODEM_MASK,
+       },
+};
+
+static struct spear_modemux uart0_ext_modemux[] = {
+       {
+               .modes = ~0,
+               .muxregs = uart0_ext_muxreg,
+               .nmuxregs = ARRAY_SIZE(uart0_ext_muxreg),
+       },
+};
+
+struct spear_pingroup spear3xx_uart0_ext_pingroup = {
+       .name = "uart0_ext_grp",
+       .pins = uart0_ext_pins,
+       .npins = ARRAY_SIZE(uart0_ext_pins),
+       .modemuxs = uart0_ext_modemux,
+       .nmodemuxs = ARRAY_SIZE(uart0_ext_modemux),
+};
+
+static const char *const uart0_ext_grps[] = { "uart0_ext_grp" };
+struct spear_function spear3xx_uart0_ext_function = {
+       .name = "uart0_ext",
+       .groups = uart0_ext_grps,
+       .ngroups = ARRAY_SIZE(uart0_ext_grps),
+};
+
+/* uart0_pins */
+static const unsigned uart0_pins[] = { 2, 3 };
+static struct spear_muxreg uart0_muxreg[] = {
+       {
+               .reg = -1,
+               .mask = PMX_UART0_MASK,
+               .val = PMX_UART0_MASK,
+       },
+};
+
+static struct spear_modemux uart0_modemux[] = {
+       {
+               .modes = ~0,
+               .muxregs = uart0_muxreg,
+               .nmuxregs = ARRAY_SIZE(uart0_muxreg),
+       },
+};
+
+struct spear_pingroup spear3xx_uart0_pingroup = {
+       .name = "uart0_grp",
+       .pins = uart0_pins,
+       .npins = ARRAY_SIZE(uart0_pins),
+       .modemuxs = uart0_modemux,
+       .nmodemuxs = ARRAY_SIZE(uart0_modemux),
+};
+
+static const char *const uart0_grps[] = { "uart0_grp" };
+struct spear_function spear3xx_uart0_function = {
+       .name = "uart0",
+       .groups = uart0_grps,
+       .ngroups = ARRAY_SIZE(uart0_grps),
+};
+
+/* timer_0_1_pins */
+static const unsigned timer_0_1_pins[] = { 43, 44, 47, 48 };
+static struct spear_muxreg timer_0_1_muxreg[] = {
+       {
+               .reg = -1,
+               .mask = PMX_TIMER_0_1_MASK,
+               .val = PMX_TIMER_0_1_MASK,
+       },
+};
+
+static struct spear_modemux timer_0_1_modemux[] = {
+       {
+               .modes = ~0,
+               .muxregs = timer_0_1_muxreg,
+               .nmuxregs = ARRAY_SIZE(timer_0_1_muxreg),
+       },
+};
+
+struct spear_pingroup spear3xx_timer_0_1_pingroup = {
+       .name = "timer_0_1_grp",
+       .pins = timer_0_1_pins,
+       .npins = ARRAY_SIZE(timer_0_1_pins),
+       .modemuxs = timer_0_1_modemux,
+       .nmodemuxs = ARRAY_SIZE(timer_0_1_modemux),
+};
+
+static const char *const timer_0_1_grps[] = { "timer_0_1_grp" };
+struct spear_function spear3xx_timer_0_1_function = {
+       .name = "timer_0_1",
+       .groups = timer_0_1_grps,
+       .ngroups = ARRAY_SIZE(timer_0_1_grps),
+};
+
+/* timer_2_3_pins */
+static const unsigned timer_2_3_pins[] = { 45, 46, 49, 50 };
+static struct spear_muxreg timer_2_3_muxreg[] = {
+       {
+               .reg = -1,
+               .mask = PMX_TIMER_2_3_MASK,
+               .val = PMX_TIMER_2_3_MASK,
+       },
+};
+
+static struct spear_modemux timer_2_3_modemux[] = {
+       {
+               .modes = ~0,
+               .muxregs = timer_2_3_muxreg,
+               .nmuxregs = ARRAY_SIZE(timer_2_3_muxreg),
+       },
+};
+
+struct spear_pingroup spear3xx_timer_2_3_pingroup = {
+       .name = "timer_2_3_grp",
+       .pins = timer_2_3_pins,
+       .npins = ARRAY_SIZE(timer_2_3_pins),
+       .modemuxs = timer_2_3_modemux,
+       .nmodemuxs = ARRAY_SIZE(timer_2_3_modemux),
+};
+
+static const char *const timer_2_3_grps[] = { "timer_2_3_grp" };
+struct spear_function spear3xx_timer_2_3_function = {
+       .name = "timer_2_3",
+       .groups = timer_2_3_grps,
+       .ngroups = ARRAY_SIZE(timer_2_3_grps),
+};
+
+struct spear_pinctrl_machdata spear3xx_machdata = {
+       .pins = spear3xx_pins,
+       .npins = ARRAY_SIZE(spear3xx_pins),
+};
diff --git a/drivers/pinctrl/spear/pinctrl-spear3xx.h b/drivers/pinctrl/spear/pinctrl-spear3xx.h
new file mode 100644 (file)
index 0000000..5d5fdd8
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Header file for the ST Microelectronics SPEAr3xx pinmux
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PINMUX_SPEAR3XX_H__
+#define __PINMUX_SPEAR3XX_H__
+
+#include "pinctrl-spear.h"
+
+/* pad mux declarations */
+#define PMX_FIRDA_MASK         (1 << 14)
+#define PMX_I2C_MASK           (1 << 13)
+#define PMX_SSP_CS_MASK                (1 << 12)
+#define PMX_SSP_MASK           (1 << 11)
+#define PMX_MII_MASK           (1 << 10)
+#define PMX_GPIO_PIN0_MASK     (1 << 9)
+#define PMX_GPIO_PIN1_MASK     (1 << 8)
+#define PMX_GPIO_PIN2_MASK     (1 << 7)
+#define PMX_GPIO_PIN3_MASK     (1 << 6)
+#define PMX_GPIO_PIN4_MASK     (1 << 5)
+#define PMX_GPIO_PIN5_MASK     (1 << 4)
+#define PMX_UART0_MODEM_MASK   (1 << 3)
+#define PMX_UART0_MASK         (1 << 2)
+#define PMX_TIMER_2_3_MASK     (1 << 1)
+#define PMX_TIMER_0_1_MASK     (1 << 0)
+
+extern struct spear_pingroup spear3xx_firda_pingroup;
+extern struct spear_pingroup spear3xx_gpio0_pin0_pingroup;
+extern struct spear_pingroup spear3xx_gpio0_pin1_pingroup;
+extern struct spear_pingroup spear3xx_gpio0_pin2_pingroup;
+extern struct spear_pingroup spear3xx_gpio0_pin3_pingroup;
+extern struct spear_pingroup spear3xx_gpio0_pin4_pingroup;
+extern struct spear_pingroup spear3xx_gpio0_pin5_pingroup;
+extern struct spear_pingroup spear3xx_i2c_pingroup;
+extern struct spear_pingroup spear3xx_mii_pingroup;
+extern struct spear_pingroup spear3xx_ssp_cs_pingroup;
+extern struct spear_pingroup spear3xx_ssp_pingroup;
+extern struct spear_pingroup spear3xx_timer_0_1_pingroup;
+extern struct spear_pingroup spear3xx_timer_2_3_pingroup;
+extern struct spear_pingroup spear3xx_uart0_ext_pingroup;
+extern struct spear_pingroup spear3xx_uart0_pingroup;
+
+#define SPEAR3XX_COMMON_PINGROUPS              \
+       &spear3xx_firda_pingroup,               \
+       &spear3xx_gpio0_pin0_pingroup,          \
+       &spear3xx_gpio0_pin1_pingroup,          \
+       &spear3xx_gpio0_pin2_pingroup,          \
+       &spear3xx_gpio0_pin3_pingroup,          \
+       &spear3xx_gpio0_pin4_pingroup,          \
+       &spear3xx_gpio0_pin5_pingroup,          \
+       &spear3xx_i2c_pingroup,                 \
+       &spear3xx_mii_pingroup,                 \
+       &spear3xx_ssp_cs_pingroup,              \
+       &spear3xx_ssp_pingroup,                 \
+       &spear3xx_timer_0_1_pingroup,           \
+       &spear3xx_timer_2_3_pingroup,           \
+       &spear3xx_uart0_ext_pingroup,           \
+       &spear3xx_uart0_pingroup
+
+extern struct spear_function spear3xx_firda_function;
+extern struct spear_function spear3xx_gpio0_function;
+extern struct spear_function spear3xx_i2c_function;
+extern struct spear_function spear3xx_mii_function;
+extern struct spear_function spear3xx_ssp_cs_function;
+extern struct spear_function spear3xx_ssp_function;
+extern struct spear_function spear3xx_timer_0_1_function;
+extern struct spear_function spear3xx_timer_2_3_function;
+extern struct spear_function spear3xx_uart0_ext_function;
+extern struct spear_function spear3xx_uart0_function;
+
+#define SPEAR3XX_COMMON_FUNCTIONS              \
+       &spear3xx_firda_function,               \
+       &spear3xx_gpio0_function,               \
+       &spear3xx_i2c_function,                 \
+       &spear3xx_mii_function,                 \
+       &spear3xx_ssp_cs_function,              \
+       &spear3xx_ssp_function,                 \
+       &spear3xx_timer_0_1_function,           \
+       &spear3xx_timer_2_3_function,           \
+       &spear3xx_uart0_ext_function,           \
+       &spear3xx_uart0_function
+
+extern struct spear_pinctrl_machdata spear3xx_machdata;
+
+#endif /* __PINMUX_SPEAR3XX_H__ */
index c21871a4e73da92c06119fa3e0f3b7ad93298274..bc2e8a7c265b518e8049bdb1877e0cf57a1b19a2 100644 (file)
@@ -2844,6 +2844,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
        sector_t recid, trkid;
        unsigned int offs;
        unsigned int count, count_to_trk_end;
+       int ret;
 
        basedev = block->base;
        if (rq_data_dir(req) == READ) {
@@ -2884,8 +2885,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
 
        itcw = itcw_init(cqr->data, itcw_size, itcw_op, 0, ctidaw, 0);
        if (IS_ERR(itcw)) {
-               dasd_sfree_request(cqr, startdev);
-               return ERR_PTR(-EINVAL);
+               ret = -EINVAL;
+               goto out_error;
        }
        cqr->cpaddr = itcw_get_tcw(itcw);
        if (prepare_itcw(itcw, first_trk, last_trk,
@@ -2897,8 +2898,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
                /* Clock not in sync and XRC is enabled.
                 * Try again later.
                 */
-               dasd_sfree_request(cqr, startdev);
-               return ERR_PTR(-EAGAIN);
+               ret = -EAGAIN;
+               goto out_error;
        }
        len_to_track_end = 0;
        /*
@@ -2937,8 +2938,10 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
                                        tidaw_flags = 0;
                                last_tidaw = itcw_add_tidaw(itcw, tidaw_flags,
                                                            dst, part_len);
-                               if (IS_ERR(last_tidaw))
-                                       return ERR_PTR(-EINVAL);
+                               if (IS_ERR(last_tidaw)) {
+                                       ret = -EINVAL;
+                                       goto out_error;
+                               }
                                dst += part_len;
                        }
                }
@@ -2947,8 +2950,10 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
                        dst = page_address(bv->bv_page) + bv->bv_offset;
                        last_tidaw = itcw_add_tidaw(itcw, 0x00,
                                                    dst, bv->bv_len);
-                       if (IS_ERR(last_tidaw))
-                               return ERR_PTR(-EINVAL);
+                       if (IS_ERR(last_tidaw)) {
+                               ret = -EINVAL;
+                               goto out_error;
+                       }
                }
        }
        last_tidaw->flags |= TIDAW_FLAGS_LAST;
@@ -2968,6 +2973,9 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
        cqr->buildclk = get_clock();
        cqr->status = DASD_CQR_FILLED;
        return cqr;
+out_error:
+       dasd_sfree_request(cqr, startdev);
+       return ERR_PTR(ret);
 }
 
 static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
index 85f4a9a5d12e5d00a7e445bd1e1e0a784eaf7cd0..73bef0bd394cab2df006f64bf5e3c25ecce7bb3f 100644 (file)
@@ -903,7 +903,7 @@ static int ur_set_online(struct ccw_device *cdev)
                goto fail_urdev_put;
        }
 
-       cdev_init(urd->char_device, &ur_fops);
+       urd->char_device->ops = &ur_fops;
        urd->char_device->dev = MKDEV(major, minor);
        urd->char_device->owner = ur_fops.owner;
 
index 24145c30c9b069104564df2f9e14b19f8728740b..6cc4358f68c12ad2c779c7837207ce875968cf40 100644 (file)
@@ -1073,8 +1073,10 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state,
                    (new_serial.close_delay != port->close_delay) ||
                    (new_serial.xmit_fifo_size != state->xmit_fifo_size) ||
                    ((new_serial.flags & ~ASYNC_USR_MASK) !=
-                    (port->flags & ~ASYNC_USR_MASK)))
+                    (port->flags & ~ASYNC_USR_MASK))) {
+                       tty_unlock();
                        return -EPERM;
+               }
                port->flags = ((port->flags & ~ASYNC_USR_MASK) |
                               (new_serial.flags & ASYNC_USR_MASK));
                state->custom_divisor = new_serial.custom_divisor;
index e6c3dbd781d61fd21e9dcafd3d85c1a0799f1f66..836fe2731234bbeabe690ef41ee230588cedea1b 100644 (file)
@@ -154,10 +154,9 @@ static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id)
                port->x_char = 0;
                return IRQ_HANDLED;
        }
-       if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
-               clps711xuart_stop_tx(port);
-               return IRQ_HANDLED;
-       }
+
+       if (uart_circ_empty(xmit) || uart_tx_stopped(port))
+               goto disable_tx_irq;
 
        count = port->fifosize >> 1;
        do {
@@ -171,8 +170,11 @@ static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id)
        if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
                uart_write_wakeup(port);
 
-       if (uart_circ_empty(xmit))
-               clps711xuart_stop_tx(port);
+       if (uart_circ_empty(xmit)) {
+       disable_tx_irq:
+               disable_irq_nosync(TX_IRQ(port));
+               tx_enabled(port) = 0;
+       }
 
        return IRQ_HANDLED;
 }
index bbbec4a74cfb5c30b3f9ba6c5f5fdfbed122d1ed..c2816f4948070157f1c969898bfde97b58bd6841 100644 (file)
@@ -1447,9 +1447,11 @@ static int pch_uart_verify_port(struct uart_port *port,
                        __func__);
                return -EOPNOTSUPP;
 #endif
-               priv->use_dma = 1;
                priv->use_dma_flag = 1;
                dev_info(priv->port.dev, "PCH UART : Use DMA Mode\n");
+               if (!priv->use_dma)
+                       pch_request_dma(port);
+               priv->use_dma = 1;
        }
 
        return 0;
index a2aa9d652c672c42ca0c6ba68fc0fbfb4907e32f..ec6c97dadbe4dba5e3cf8a47980e23256a44bff5 100644 (file)
@@ -1667,7 +1667,6 @@ void usb_disconnect(struct usb_device **pdev)
 {
        struct usb_device       *udev = *pdev;
        int                     i;
-       struct usb_hcd          *hcd = bus_to_hcd(udev->bus);
 
        /* mark the device as inactive, so any further urb submissions for
         * this device (and any of its children) will fail immediately.
@@ -1690,9 +1689,7 @@ void usb_disconnect(struct usb_device **pdev)
         * so that the hardware is now fully quiesced.
         */
        dev_dbg (&udev->dev, "unregistering device\n");
-       mutex_lock(hcd->bandwidth_mutex);
        usb_disable_device(udev, 0);
-       mutex_unlock(hcd->bandwidth_mutex);
        usb_hcd_synchronize_unlinks(udev);
 
        usb_remove_ep_devs(&udev->ep0);
index aed3e07942d458b8f32b95defd766d30fd7d2ee9..ca717da3be95ddbab8d4b5211e78af699fcb1399 100644 (file)
@@ -1136,8 +1136,6 @@ void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf,
  * Deallocates hcd/hardware state for the endpoints (nuking all or most
  * pending urbs) and usbcore state for the interfaces, so that usbcore
  * must usb_set_configuration() before any interfaces could be used.
- *
- * Must be called with hcd->bandwidth_mutex held.
  */
 void usb_disable_device(struct usb_device *dev, int skip_ep0)
 {
@@ -1190,7 +1188,9 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
                        usb_disable_endpoint(dev, i + USB_DIR_IN, false);
                }
                /* Remove endpoints from the host controller internal state */
+               mutex_lock(hcd->bandwidth_mutex);
                usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL);
+               mutex_unlock(hcd->bandwidth_mutex);
                /* Second pass: remove endpoint pointers */
        }
        for (i = skip_ep0; i < 16; ++i) {
@@ -1750,7 +1750,6 @@ free_interfaces:
        /* if it's already configured, clear out old state first.
         * getting rid of old interfaces means unbinding their drivers.
         */
-       mutex_lock(hcd->bandwidth_mutex);
        if (dev->state != USB_STATE_ADDRESS)
                usb_disable_device(dev, 1);     /* Skip ep0 */
 
@@ -1763,6 +1762,7 @@ free_interfaces:
         * host controller will not allow submissions to dropped endpoints.  If
         * this call fails, the device state is unchanged.
         */
+       mutex_lock(hcd->bandwidth_mutex);
        ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL);
        if (ret < 0) {
                mutex_unlock(hcd->bandwidth_mutex);
index 7bd815a507e8c3c94f9faaf0545b465f7ed3a781..99b58d84553acd56263ad0ed1e774f9d9eb2afec 100644 (file)
@@ -206,11 +206,11 @@ static void dwc3_free_event_buffers(struct dwc3 *dwc)
 
        for (i = 0; i < dwc->num_event_buffers; i++) {
                evt = dwc->ev_buffs[i];
-               if (evt) {
+               if (evt)
                        dwc3_free_one_event_buffer(dwc, evt);
-                       dwc->ev_buffs[i] = NULL;
-               }
        }
+
+       kfree(dwc->ev_buffs);
 }
 
 /**
index 25910e251c04b4fb7ce0ef8bb9685573e859b9b9..3584a169886f3dfa23b8513c3850dd71f71e22e0 100644 (file)
@@ -353,6 +353,9 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
 
                        dwc->test_mode_nr = wIndex >> 8;
                        dwc->test_mode = true;
+                       break;
+               default:
+                       return -EINVAL;
                }
                break;
 
@@ -559,15 +562,20 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
        length = trb->size & DWC3_TRB_SIZE_MASK;
 
        if (dwc->ep0_bounced) {
+               unsigned transfer_size = ur->length;
+               unsigned maxp = ep0->endpoint.maxpacket;
+
+               transfer_size += (maxp - (transfer_size % maxp));
                transferred = min_t(u32, ur->length,
-                               ep0->endpoint.maxpacket - length);
+                               transfer_size - length);
                memcpy(ur->buf, dwc->ep0_bounce, transferred);
                dwc->ep0_bounced = false;
        } else {
                transferred = ur->length - length;
-               ur->actual += transferred;
        }
 
+       ur->actual += transferred;
+
        if ((epnum & 1) && ur->actual < ur->length) {
                /* for some reason we did not get everything out */
 
index 0c935d7c65bdf7379f466e5c3f1522fb88a7e266..9d7bcd910074d0715a282c35d0e439539cdd3367 100644 (file)
@@ -1863,8 +1863,8 @@ static int __devinit at91udc_probe(struct platform_device *pdev)
                        mod_timer(&udc->vbus_timer,
                                  jiffies + VBUS_POLL_TIMEOUT);
                } else {
-                       if (request_irq(udc->board.vbus_pin, at91_vbus_irq,
-                                       0, driver_name, udc)) {
+                       if (request_irq(gpio_to_irq(udc->board.vbus_pin),
+                                       at91_vbus_irq, 0, driver_name, udc)) {
                                DBG("request vbus irq %d failed\n",
                                    udc->board.vbus_pin);
                                retval = -EBUSY;
@@ -1886,7 +1886,7 @@ static int __devinit at91udc_probe(struct platform_device *pdev)
        return 0;
 fail4:
        if (gpio_is_valid(udc->board.vbus_pin) && !udc->board.vbus_polled)
-               free_irq(udc->board.vbus_pin, udc);
+               free_irq(gpio_to_irq(udc->board.vbus_pin), udc);
 fail3:
        if (gpio_is_valid(udc->board.vbus_pin))
                gpio_free(udc->board.vbus_pin);
@@ -1924,7 +1924,7 @@ static int __exit at91udc_remove(struct platform_device *pdev)
        device_init_wakeup(&pdev->dev, 0);
        remove_debug_file(udc);
        if (gpio_is_valid(udc->board.vbus_pin)) {
-               free_irq(udc->board.vbus_pin, udc);
+               free_irq(gpio_to_irq(udc->board.vbus_pin), udc);
                gpio_free(udc->board.vbus_pin);
        }
        free_irq(udc->udp_irq, udc);
index 1cbba70836bcd7c1516c21253b3a54dd24a5849a..f52cb1ae45d9a5ab27a46cb40b34cdb94e93a484 100644 (file)
@@ -712,7 +712,7 @@ static long ffs_ep0_ioctl(struct file *file, unsigned code, unsigned long value)
        if (code == FUNCTIONFS_INTERFACE_REVMAP) {
                struct ffs_function *func = ffs->func;
                ret = func ? ffs_func_revmap_intf(func, value) : -ENODEV;
-       } else if (gadget->ops->ioctl) {
+       } else if (gadget && gadget->ops->ioctl) {
                ret = gadget->ops->ioctl(gadget, code, value);
        } else {
                ret = -ENOTTY;
@@ -1382,6 +1382,7 @@ static void functionfs_unbind(struct ffs_data *ffs)
                ffs->ep0req = NULL;
                ffs->gadget = NULL;
                ffs_data_put(ffs);
+               clear_bit(FFS_FL_BOUND, &ffs->flags);
        }
 }
 
index 7b1cf18df5e3e4cd0706422d3e16d17bc1aad075..52343654f5df5218929e86bf7bdac64bf2577b9e 100644 (file)
@@ -500,6 +500,7 @@ rndis_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
                        if (buf) {
                                memcpy(req->buf, buf, n);
                                req->complete = rndis_response_complete;
+                               req->context = rndis;
                                rndis_free_response(rndis->config, buf);
                                value = n;
                        }
index 5f94e79cd6b9b3f8856dad2d97d1e74677f62bad..55abfb6bd612dc96da58c67fb59def9e0cc14ea0 100644 (file)
@@ -730,7 +730,7 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
                : (1 << (ep_index(ep)));
 
        /* check if the pipe is empty */
-       if (!(list_empty(&ep->queue))) {
+       if (!(list_empty(&ep->queue)) && !(ep_index(ep) == 0)) {
                /* Add td to the end */
                struct fsl_req *lastreq;
                lastreq = list_entry(ep->queue.prev, struct fsl_req, queue);
@@ -918,10 +918,6 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
                return -ENOMEM;
        }
 
-       /* Update ep0 state */
-       if ((ep_index(ep) == 0))
-               udc->ep0_state = DATA_STATE_XMIT;
-
        /* irq handler advances the queue */
        if (req != NULL)
                list_add_tail(&req->queue, &ep->queue);
@@ -1279,7 +1275,8 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction)
                udc->ep0_dir = USB_DIR_OUT;
 
        ep = &udc->eps[0];
-       udc->ep0_state = WAIT_FOR_OUT_STATUS;
+       if (udc->ep0_state != DATA_STATE_XMIT)
+               udc->ep0_state = WAIT_FOR_OUT_STATUS;
 
        req->ep = ep;
        req->req.length = 0;
@@ -1384,6 +1381,9 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value,
 
        list_add_tail(&req->queue, &ep->queue);
        udc->ep0_state = DATA_STATE_XMIT;
+       if (ep0_prime_status(udc, EP_DIR_OUT))
+               ep0stall(udc);
+
        return;
 stall:
        ep0stall(udc);
@@ -1492,6 +1492,14 @@ static void setup_received_irq(struct fsl_udc *udc,
                spin_lock(&udc->lock);
                udc->ep0_state = (setup->bRequestType & USB_DIR_IN)
                                ?  DATA_STATE_XMIT : DATA_STATE_RECV;
+               /*
+                * If the data stage is IN, send status prime immediately.
+                * See 2.0 Spec chapter 8.5.3.3 for detail.
+                */
+               if (udc->ep0_state == DATA_STATE_XMIT)
+                       if (ep0_prime_status(udc, EP_DIR_OUT))
+                               ep0stall(udc);
+
        } else {
                /* No data phase, IN status from gadget */
                udc->ep0_dir = USB_DIR_IN;
@@ -1520,9 +1528,8 @@ static void ep0_req_complete(struct fsl_udc *udc, struct fsl_ep *ep0,
 
        switch (udc->ep0_state) {
        case DATA_STATE_XMIT:
-               /* receive status phase */
-               if (ep0_prime_status(udc, EP_DIR_OUT))
-                       ep0stall(udc);
+               /* already primed at setup_received_irq */
+               udc->ep0_state = WAIT_FOR_OUT_STATUS;
                break;
        case DATA_STATE_RECV:
                /* send status phase */
index 331cd6729d3cf4d1ac8bccf9b4ca5746d4d79821..a85eaf40b948592f4df5746cd1dca2a87141cf8d 100644 (file)
@@ -161,7 +161,7 @@ static struct usb_composite_driver gfs_driver = {
 static struct ffs_data *gfs_ffs_data;
 static unsigned long gfs_registered;
 
-static int  gfs_init(void)
+static int __init gfs_init(void)
 {
        ENTER();
 
@@ -169,7 +169,7 @@ static int  gfs_init(void)
 }
 module_init(gfs_init);
 
-static void  gfs_exit(void)
+static void __exit gfs_exit(void)
 {
        ENTER();
 
index 69295ba9d99ae12f29738533fb15f5a7b4cce046..105b206cd8443dbe01bfd32b14555a51b22438b6 100644 (file)
@@ -340,7 +340,7 @@ static void s3c_hsotg_init_fifo(struct s3c_hsotg *hsotg)
        /* currently we allocate TX FIFOs for all possible endpoints,
         * and assume that they are all the same size. */
 
-       for (ep = 0; ep <= 15; ep++) {
+       for (ep = 1; ep <= 15; ep++) {
                val = addr;
                val |= size << S3C_DPTXFSIZn_DPTxFSize_SHIFT;
                addr += size;
@@ -741,7 +741,7 @@ static void s3c_hsotg_start_req(struct s3c_hsotg *hsotg,
        /* write size / packets */
        writel(epsize, hsotg->regs + epsize_reg);
 
-       if (using_dma(hsotg)) {
+       if (using_dma(hsotg) && !continuing) {
                unsigned int dma_reg;
 
                /* write DMA address to control register, buffer already
@@ -1696,10 +1696,12 @@ static void s3c_hsotg_set_ep_maxpacket(struct s3c_hsotg *hsotg,
        reg |= mpsval;
        writel(reg, regs + S3C_DIEPCTL(ep));
 
-       reg = readl(regs + S3C_DOEPCTL(ep));
-       reg &= ~S3C_DxEPCTL_MPS_MASK;
-       reg |= mpsval;
-       writel(reg, regs + S3C_DOEPCTL(ep));
+       if (ep) {
+               reg = readl(regs + S3C_DOEPCTL(ep));
+               reg &= ~S3C_DxEPCTL_MPS_MASK;
+               reg |= mpsval;
+               writel(reg, regs + S3C_DOEPCTL(ep));
+       }
 
        return;
 
@@ -1919,7 +1921,8 @@ static void s3c_hsotg_epint(struct s3c_hsotg *hsotg, unsigned int idx,
                    ints & S3C_DIEPMSK_TxFIFOEmpty) {
                        dev_dbg(hsotg->dev, "%s: ep%d: TxFIFOEmpty\n",
                                __func__, idx);
-                       s3c_hsotg_trytx(hsotg, hs_ep);
+                       if (!using_dma(hsotg))
+                               s3c_hsotg_trytx(hsotg, hs_ep);
                }
        }
 }
index 56da49f31d6c35a0f61611c1bb651b51e59732ab..2fa9865babedb0d76e28d6cfa2ac2ad6cf859628 100644 (file)
@@ -264,8 +264,8 @@ static void usb_gadget_remove_driver(struct usb_udc *udc)
        if (udc_is_newstyle(udc)) {
                udc->driver->disconnect(udc->gadget);
                udc->driver->unbind(udc->gadget);
-               usb_gadget_udc_stop(udc->gadget, udc->driver);
                usb_gadget_disconnect(udc->gadget);
+               usb_gadget_udc_stop(udc->gadget, udc->driver);
        } else {
                usb_gadget_stop(udc->gadget, udc->driver);
        }
@@ -411,8 +411,12 @@ static ssize_t usb_udc_softconn_store(struct device *dev,
        struct usb_udc          *udc = container_of(dev, struct usb_udc, dev);
 
        if (sysfs_streq(buf, "connect")) {
+               if (udc_is_newstyle(udc))
+                       usb_gadget_udc_start(udc->gadget, udc->driver);
                usb_gadget_connect(udc->gadget);
        } else if (sysfs_streq(buf, "disconnect")) {
+               if (udc_is_newstyle(udc))
+                       usb_gadget_udc_stop(udc->gadget, udc->driver);
                usb_gadget_disconnect(udc->gadget);
        } else {
                dev_err(dev, "unsupported command '%s'\n", buf);
index d776adb2da675c24f0d669d9a931f0a15abcf37f..0cdf89d32a15817d78ce0388a76f32909b29240c 100644 (file)
@@ -543,11 +543,11 @@ done:
        return ret;
 }
 
+/* called with queue->irqlock held.. */
 static struct uvc_buffer *
 uvc_queue_next_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf)
 {
        struct uvc_buffer *nextbuf;
-       unsigned long flags;
 
        if ((queue->flags & UVC_QUEUE_DROP_INCOMPLETE) &&
            buf->buf.length != buf->buf.bytesused) {
@@ -556,14 +556,12 @@ uvc_queue_next_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf)
                return buf;
        }
 
-       spin_lock_irqsave(&queue->irqlock, flags);
        list_del(&buf->queue);
        if (!list_empty(&queue->irqqueue))
                nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer,
                                           queue);
        else
                nextbuf = NULL;
-       spin_unlock_irqrestore(&queue->irqlock, flags);
 
        buf->buf.sequence = queue->sequence++;
        do_gettimeofday(&buf->buf.timestamp);
index 3e7345172e03a86b56b31f48f66dfc601955b899..d0a84bd3f3ebe5bca473e2c6c99711bf02069c3f 100644 (file)
@@ -218,6 +218,9 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci,
        u32 portsc;
        struct usb_hcd *hcd = ehci_to_hcd(ehci);
        void __iomem *non_ehci = hcd->regs;
+       struct fsl_usb2_platform_data *pdata;
+
+       pdata = hcd->self.controller->platform_data;
 
        portsc = ehci_readl(ehci, &ehci->regs->port_status[port_offset]);
        portsc &= ~(PORT_PTS_MSK | PORT_PTS_PTW);
@@ -234,7 +237,9 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci,
                /* fall through */
        case FSL_USB2_PHY_UTMI:
                /* enable UTMI PHY */
-               setbits32(non_ehci + FSL_SOC_USB_CTRL, CTRL_UTMI_PHY_EN);
+               if (pdata->have_sysif_regs)
+                       setbits32(non_ehci + FSL_SOC_USB_CTRL,
+                                 CTRL_UTMI_PHY_EN);
                portsc |= PORT_PTS_UTMI;
                break;
        case FSL_USB2_PHY_NONE:
index 806cc95317aa162b8cca938b6a87cd3a2915e972..4a3bc5b7a06f82d395c9a6dae0a025ba9660cf02 100644 (file)
@@ -858,8 +858,13 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
                goto dead;
        }
 
+       /*
+        * We don't use STS_FLR, but some controllers don't like it to
+        * remain on, so mask it out along with the other status bits.
+        */
+       masked_status = status & (INTR_MASK | STS_FLR);
+
        /* Shared IRQ? */
-       masked_status = status & INTR_MASK;
        if (!masked_status || unlikely(ehci->rh_state == EHCI_RH_HALTED)) {
                spin_unlock(&ehci->lock);
                return IRQ_NONE;
@@ -910,7 +915,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
                pcd_status = status;
 
                /* resume root hub? */
-               if (!(cmd & CMD_RUN))
+               if (ehci->rh_state == EHCI_RH_SUSPENDED)
                        usb_hcd_resume_root_hub(hcd);
 
                /* get per-port change detect bits */
index bba9850f32f09f78c668a04d2d024d99d3320857..5c78f9e71466ef7a81df23535ead8927dd73af24 100644 (file)
@@ -42,6 +42,7 @@
 #include <plat/usb.h>
 #include <linux/regulator/consumer.h>
 #include <linux/pm_runtime.h>
+#include <linux/gpio.h>
 
 /* EHCI Register Set */
 #define EHCI_INSNREG04                                 (0xA0)
@@ -191,6 +192,19 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
                }
        }
 
+       if (pdata->phy_reset) {
+               if (gpio_is_valid(pdata->reset_gpio_port[0]))
+                       gpio_request_one(pdata->reset_gpio_port[0],
+                                        GPIOF_OUT_INIT_LOW, "USB1 PHY reset");
+
+               if (gpio_is_valid(pdata->reset_gpio_port[1]))
+                       gpio_request_one(pdata->reset_gpio_port[1],
+                                        GPIOF_OUT_INIT_LOW, "USB2 PHY reset");
+
+               /* Hold the PHY in RESET for enough time till DIR is high */
+               udelay(10);
+       }
+
        pm_runtime_enable(dev);
        pm_runtime_get_sync(dev);
 
@@ -237,6 +251,19 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
        /* root ports should always stay powered */
        ehci_port_power(omap_ehci, 1);
 
+       if (pdata->phy_reset) {
+               /* Hold the PHY in RESET for enough time till
+                * PHY is settled and ready
+                */
+               udelay(10);
+
+               if (gpio_is_valid(pdata->reset_gpio_port[0]))
+                       gpio_set_value(pdata->reset_gpio_port[0], 1);
+
+               if (gpio_is_valid(pdata->reset_gpio_port[1]))
+                       gpio_set_value(pdata->reset_gpio_port[1], 1);
+       }
+
        return 0;
 
 err_add_hcd:
@@ -259,8 +286,9 @@ err_io:
  */
 static int ehci_hcd_omap_remove(struct platform_device *pdev)
 {
-       struct device *dev      = &pdev->dev;
-       struct usb_hcd *hcd     = dev_get_drvdata(dev);
+       struct device *dev                              = &pdev->dev;
+       struct usb_hcd *hcd                             = dev_get_drvdata(dev);
+       struct ehci_hcd_omap_platform_data *pdata       = dev->platform_data;
 
        usb_remove_hcd(hcd);
        disable_put_regulator(dev->platform_data);
@@ -269,6 +297,13 @@ static int ehci_hcd_omap_remove(struct platform_device *pdev)
        pm_runtime_put_sync(dev);
        pm_runtime_disable(dev);
 
+       if (pdata->phy_reset) {
+               if (gpio_is_valid(pdata->reset_gpio_port[0]))
+                       gpio_free(pdata->reset_gpio_port[0]);
+
+               if (gpio_is_valid(pdata->reset_gpio_port[1]))
+                       gpio_free(pdata->reset_gpio_port[1]);
+       }
        return 0;
 }
 
index 9692bef159f540a0b1973b7828cfcf2007b0985d..826c2fd8c4026346b0f84afe8e3f30c4d664eec9 100644 (file)
@@ -732,7 +732,6 @@ static int tegra_ehci_probe(struct platform_device *pdev)
                err = -ENODEV;
                goto fail;
        }
-       set_irq_flags(irq, IRQF_VALID);
 
 #ifdef CONFIG_USB_OTG_UTILS
        if (pdata->operating_mode == TEGRA_USB_OTG) {
index 09f597ad6e00ad739ab4e0924800a0c81e0abbfc..13ebeca8e73e3e5f78f52b6001ebc3464f40a432 100644 (file)
@@ -94,7 +94,7 @@ static void at91_stop_hc(struct platform_device *pdev)
 
 /*-------------------------------------------------------------------------*/
 
-static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
+static void __devexit usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
 
 /* configure so an HC device and id are always provided */
 /* always called with process context; sleeping is OK */
@@ -108,7 +108,7 @@ static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
  * then invokes the start() method for the HCD associated with it
  * through the hotplug entry's driver_data.
  */
-static int usb_hcd_at91_probe(const struct hc_driver *driver,
+static int __devinit usb_hcd_at91_probe(const struct hc_driver *driver,
                        struct platform_device *pdev)
 {
        int retval;
@@ -203,7 +203,7 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,
  * context, "rmmod" or something similar.
  *
  */
-static void usb_hcd_at91_remove(struct usb_hcd *hcd,
+static void __devexit usb_hcd_at91_remove(struct usb_hcd *hcd,
                                struct platform_device *pdev)
 {
        usb_remove_hcd(hcd);
@@ -545,7 +545,7 @@ static int __devinit ohci_at91_of_init(struct platform_device *pdev)
 
 /*-------------------------------------------------------------------------*/
 
-static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
+static int __devinit ohci_hcd_at91_drv_probe(struct platform_device *pdev)
 {
        struct at91_usbh_data   *pdata;
        int                     i;
@@ -620,7 +620,7 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
        return usb_hcd_at91_probe(&ohci_at91_hc_driver, pdev);
 }
 
-static int ohci_hcd_at91_drv_remove(struct platform_device *pdev)
+static int __devexit ohci_hcd_at91_drv_remove(struct platform_device *pdev)
 {
        struct at91_usbh_data   *pdata = pdev->dev.platform_data;
        int                     i;
@@ -696,7 +696,7 @@ MODULE_ALIAS("platform:at91_ohci");
 
 static struct platform_driver ohci_hcd_at91_driver = {
        .probe          = ohci_hcd_at91_drv_probe,
-       .remove         = ohci_hcd_at91_drv_remove,
+       .remove         = __devexit_p(ohci_hcd_at91_drv_remove),
        .shutdown       = usb_hcd_platform_shutdown,
        .suspend        = ohci_hcd_at91_drv_suspend,
        .resume         = ohci_hcd_at91_drv_resume,
index 959145baf3cf8dd87669be5ed292de99541b4ed3..9dcb68f04f03025265f3747e6f7bf072ab1b8958 100644 (file)
@@ -423,7 +423,7 @@ alloc_sglist(int nents, int max, int vary)
        unsigned                i;
        unsigned                size = max;
 
-       sg = kmalloc(nents * sizeof *sg, GFP_KERNEL);
+       sg = kmalloc_array(nents, sizeof *sg, GFP_KERNEL);
        if (!sg)
                return NULL;
        sg_init_table(sg, nents);
@@ -904,6 +904,9 @@ test_ctrl_queue(struct usbtest_dev *dev, struct usbtest_param *param)
        struct ctrl_ctx         context;
        int                     i;
 
+       if (param->sglen == 0 || param->iterations > UINT_MAX / param->sglen)
+               return -EOPNOTSUPP;
+
        spin_lock_init(&context.lock);
        context.dev = dev;
        init_completion(&context.complete);
@@ -1981,8 +1984,6 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)
 
        /* queued control messaging */
        case 10:
-               if (param->sglen == 0)
-                       break;
                retval = 0;
                dev_info(&intf->dev,
                                "TEST 10:  queue %d control calls, %d times\n",
@@ -2276,6 +2277,8 @@ usbtest_probe(struct usb_interface *intf, const struct usb_device_id *id)
                        if (status < 0) {
                                WARNING(dev, "couldn't get endpoints, %d\n",
                                                status);
+                               kfree(dev->buf);
+                               kfree(dev);
                                return status;
                        }
                        /* may find bulk or ISO pipes */
index 897edda422709c016b36d469b5930532a104a30c..70201462e19c0e57d8615432a7d3e5e5813aed85 100644 (file)
@@ -99,9 +99,7 @@ static void yurex_delete(struct kref *kref)
        usb_put_dev(dev->udev);
        if (dev->cntl_urb) {
                usb_kill_urb(dev->cntl_urb);
-               if (dev->cntl_req)
-                       usb_free_coherent(dev->udev, YUREX_BUF_SIZE,
-                               dev->cntl_req, dev->cntl_urb->setup_dma);
+               kfree(dev->cntl_req);
                if (dev->cntl_buffer)
                        usb_free_coherent(dev->udev, YUREX_BUF_SIZE,
                                dev->cntl_buffer, dev->cntl_urb->transfer_dma);
@@ -234,9 +232,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_
        }
 
        /* allocate buffer for control req */
-       dev->cntl_req = usb_alloc_coherent(dev->udev, YUREX_BUF_SIZE,
-                                          GFP_KERNEL,
-                                          &dev->cntl_urb->setup_dma);
+       dev->cntl_req = kmalloc(YUREX_BUF_SIZE, GFP_KERNEL);
        if (!dev->cntl_req) {
                err("Could not allocate cntl_req");
                goto error;
@@ -286,7 +282,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_
                         usb_rcvintpipe(dev->udev, dev->int_in_endpointAddr),
                         dev->int_buffer, YUREX_BUF_SIZE, yurex_interrupt,
                         dev, 1);
-       dev->cntl_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+       dev->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
        if (usb_submit_urb(dev->urb, GFP_KERNEL)) {
                retval = -EIO;
                err("Could not submitting URB");
index 0f8b82918a40f8038d5c75567b18e2b62d454829..66aaccf04490487f83c1aa926be58e2410d12eea 100644 (file)
@@ -137,6 +137,9 @@ static int musb_ulpi_read(struct usb_phy *phy, u32 offset)
        int     i = 0;
        u8      r;
        u8      power;
+       int     ret;
+
+       pm_runtime_get_sync(phy->io_dev);
 
        /* Make sure the transceiver is not in low power mode */
        power = musb_readb(addr, MUSB_POWER);
@@ -154,15 +157,22 @@ static int musb_ulpi_read(struct usb_phy *phy, u32 offset)
        while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL)
                                & MUSB_ULPI_REG_CMPLT)) {
                i++;
-               if (i == 10000)
-                       return -ETIMEDOUT;
+               if (i == 10000) {
+                       ret = -ETIMEDOUT;
+                       goto out;
+               }
 
        }
        r = musb_readb(addr, MUSB_ULPI_REG_CONTROL);
        r &= ~MUSB_ULPI_REG_CMPLT;
        musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r);
 
-       return musb_readb(addr, MUSB_ULPI_REG_DATA);
+       ret = musb_readb(addr, MUSB_ULPI_REG_DATA);
+
+out:
+       pm_runtime_put(phy->io_dev);
+
+       return ret;
 }
 
 static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data)
@@ -171,6 +181,9 @@ static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data)
        int     i = 0;
        u8      r = 0;
        u8      power;
+       int     ret = 0;
+
+       pm_runtime_get_sync(phy->io_dev);
 
        /* Make sure the transceiver is not in low power mode */
        power = musb_readb(addr, MUSB_POWER);
@@ -184,15 +197,20 @@ static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data)
        while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL)
                                & MUSB_ULPI_REG_CMPLT)) {
                i++;
-               if (i == 10000)
-                       return -ETIMEDOUT;
+               if (i == 10000) {
+                       ret = -ETIMEDOUT;
+                       goto out;
+               }
        }
 
        r = musb_readb(addr, MUSB_ULPI_REG_CONTROL);
        r &= ~MUSB_ULPI_REG_CMPLT;
        musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r);
 
-       return 0;
+out:
+       pm_runtime_put(phy->io_dev);
+
+       return ret;
 }
 #else
 #define musb_ulpi_read         NULL
@@ -1904,14 +1922,17 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
 
        if (!musb->isr) {
                status = -ENODEV;
-               goto fail3;
+               goto fail2;
        }
 
        if (!musb->xceiv->io_ops) {
+               musb->xceiv->io_dev = musb->controller;
                musb->xceiv->io_priv = musb->mregs;
                musb->xceiv->io_ops = &musb_ulpi_access;
        }
 
+       pm_runtime_get_sync(musb->controller);
+
 #ifndef CONFIG_MUSB_PIO_ONLY
        if (use_dma && dev->dma_mask) {
                struct dma_controller   *c;
@@ -2023,6 +2044,8 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
                goto fail5;
 #endif
 
+       pm_runtime_put(musb->controller);
+
        dev_info(dev, "USB %s mode controller at %p using %s, IRQ %d\n",
                        ({char *s;
                         switch (musb->board_mode) {
@@ -2047,6 +2070,9 @@ fail4:
                musb_gadget_cleanup(musb);
 
 fail3:
+       pm_runtime_put_sync(musb->controller);
+
+fail2:
        if (musb->irq_wake)
                device_init_wakeup(dev, 0);
        musb_platform_exit(musb);
index 79cb0af779fa07dac0702ee9b2b2d43e0a22b738..ef8d744800ac29c58dc24e089a645211fcd665ff 100644 (file)
@@ -2098,7 +2098,7 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh)
        }
 
        /* turn off DMA requests, discard state, stop polling ... */
-       if (is_in) {
+       if (ep->epnum && is_in) {
                /* giveback saves bulk toggle */
                csr = musb_h_flush_rxfifo(ep, 0);
 
index 2ae0bb3099940404044d84eb40740e7a82f52586..c7785e81254cdf96eef46f352ee134fc8ca759aa 100644 (file)
@@ -282,7 +282,8 @@ static void musb_otg_notifier_work(struct work_struct *data_notifier_work)
 
 static int omap2430_musb_init(struct musb *musb)
 {
-       u32 l, status = 0;
+       u32 l;
+       int status = 0;
        struct device *dev = musb->controller;
        struct musb_hdrc_platform_data *plat = dev->platform_data;
        struct omap_musb_board_data *data = plat->board_data;
@@ -301,7 +302,7 @@ static int omap2430_musb_init(struct musb *musb)
 
        status = pm_runtime_get_sync(dev);
        if (status < 0) {
-               dev_err(dev, "pm_runtime_get_sync FAILED");
+               dev_err(dev, "pm_runtime_get_sync FAILED %d\n", status);
                goto err1;
        }
 
@@ -333,6 +334,7 @@ static int omap2430_musb_init(struct musb *musb)
 
        setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb);
 
+       pm_runtime_put_noidle(musb->controller);
        return 0;
 
 err1:
@@ -452,14 +454,14 @@ static int __devinit omap2430_probe(struct platform_device *pdev)
                goto err2;
        }
 
+       pm_runtime_enable(&pdev->dev);
+
        ret = platform_device_add(musb);
        if (ret) {
                dev_err(&pdev->dev, "failed to register musb device\n");
                goto err2;
        }
 
-       pm_runtime_enable(&pdev->dev);
-
        return 0;
 
 err2:
@@ -478,7 +480,6 @@ static int __devexit omap2430_remove(struct platform_device *pdev)
 
        platform_device_del(glue->musb);
        platform_device_put(glue->musb);
-       pm_runtime_put(&pdev->dev);
        kfree(glue);
 
        return 0;
@@ -491,11 +492,13 @@ static int omap2430_runtime_suspend(struct device *dev)
        struct omap2430_glue            *glue = dev_get_drvdata(dev);
        struct musb                     *musb = glue_to_musb(glue);
 
-       musb->context.otg_interfsel = musb_readl(musb->mregs,
-                                               OTG_INTERFSEL);
+       if (musb) {
+               musb->context.otg_interfsel = musb_readl(musb->mregs,
+                               OTG_INTERFSEL);
 
-       omap2430_low_level_exit(musb);
-       usb_phy_set_suspend(musb->xceiv, 1);
+               omap2430_low_level_exit(musb);
+               usb_phy_set_suspend(musb->xceiv, 1);
+       }
 
        return 0;
 }
@@ -505,11 +508,13 @@ static int omap2430_runtime_resume(struct device *dev)
        struct omap2430_glue            *glue = dev_get_drvdata(dev);
        struct musb                     *musb = glue_to_musb(glue);
 
-       omap2430_low_level_init(musb);
-       musb_writel(musb->mregs, OTG_INTERFSEL,
-                                       musb->context.otg_interfsel);
+       if (musb) {
+               omap2430_low_level_init(musb);
+               musb_writel(musb->mregs, OTG_INTERFSEL,
+                               musb->context.otg_interfsel);
 
-       usb_phy_set_suspend(musb->xceiv, 0);
+               usb_phy_set_suspend(musb->xceiv, 0);
+       }
 
        return 0;
 }
index 0310e2df59f5b78029ed5832e61039c826ae082d..ec30f95ef399e3b8bc907084c00c50592734791d 100644 (file)
@@ -287,7 +287,8 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request,
        /* Issue the request, attempting to read 'size' bytes */
        result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
                                request, REQTYPE_DEVICE_TO_HOST, 0x0000,
-                               port_priv->bInterfaceNumber, buf, size, 300);
+                               port_priv->bInterfaceNumber, buf, size,
+                               USB_CTRL_GET_TIMEOUT);
 
        /* Convert data into an array of integers */
        for (i = 0; i < length; i++)
@@ -340,12 +341,14 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request,
                result = usb_control_msg(serial->dev,
                                usb_sndctrlpipe(serial->dev, 0),
                                request, REQTYPE_HOST_TO_DEVICE, 0x0000,
-                               port_priv->bInterfaceNumber, buf, size, 300);
+                               port_priv->bInterfaceNumber, buf, size,
+                               USB_CTRL_SET_TIMEOUT);
        } else {
                result = usb_control_msg(serial->dev,
                                usb_sndctrlpipe(serial->dev, 0),
                                request, REQTYPE_HOST_TO_DEVICE, data[0],
-                               port_priv->bInterfaceNumber, NULL, 0, 300);
+                               port_priv->bInterfaceNumber, NULL, 0,
+                               USB_CTRL_SET_TIMEOUT);
        }
 
        kfree(buf);
index fdd5aa2c8d82cc0b4be7130ccfed5a8953465591..8c8bf806f6faf9b779c8ed002a273c7aba5c96c0 100644 (file)
@@ -221,7 +221,7 @@ static const struct sierra_iface_info typeB_interface_list = {
 };
 
 /* 'blacklist' of interfaces not served by this driver */
-static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11 };
+static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11, 19, 20 };
 static const struct sierra_iface_info direct_ip_interface_blacklist = {
        .infolen = ARRAY_SIZE(direct_ip_non_serial_ifaces),
        .ifaceinfo = direct_ip_non_serial_ifaces,
@@ -289,7 +289,6 @@ static const struct usb_device_id id_table[] = {
        { USB_DEVICE(0x1199, 0x6856) }, /* Sierra Wireless AirCard 881 U */
        { USB_DEVICE(0x1199, 0x6859) }, /* Sierra Wireless AirCard 885 E */
        { USB_DEVICE(0x1199, 0x685A) }, /* Sierra Wireless AirCard 885 E */
-       { USB_DEVICE(0x1199, 0x68A2) }, /* Sierra Wireless MC7710 */
        /* Sierra Wireless C885 */
        { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6880, 0xFF, 0xFF, 0xFF)},
        /* Sierra Wireless C888, Air Card 501, USB 303, USB 304 */
@@ -299,6 +298,9 @@ static const struct usb_device_id id_table[] = {
        /* Sierra Wireless HSPA Non-Composite Device */
        { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)},
        { USB_DEVICE(0x1199, 0x6893) }, /* Sierra Wireless Device */
+       { USB_DEVICE(0x1199, 0x68A2),   /* Sierra Wireless MC77xx in QMI mode */
+         .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist
+       },
        { USB_DEVICE(0x1199, 0x68A3),   /* Sierra Wireless Direct IP modems */
          .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist
        },
index 66797e9c5010d35cd5c21563a99faec79cd8a175..810c90ae2c5584fc57113813f2a9251422724840 100644 (file)
@@ -645,7 +645,8 @@ void hwarc_neep_cb(struct urb *urb)
                dev_err(dev, "NEEP: URB error %d\n", urb->status);
        }
        result = usb_submit_urb(urb, GFP_ATOMIC);
-       if (result < 0) {
+       if (result < 0 && result != -ENODEV && result != -EPERM) {
+               /* ignoring unrecoverable errors */
                dev_err(dev, "NEEP: Can't resubmit URB (%d) resetting device\n",
                        result);
                goto error;
index a269937be1b8230898f991eb5f430e3f79ac9824..8cb71bb333c2ea830881ddc8bf19afd4096b3d60 100644 (file)
@@ -107,6 +107,7 @@ struct uwb_rc_neh {
        u8 evt_type;
        __le16 evt;
        u8 context;
+       u8 completed;
        uwb_rc_cmd_cb_f cb;
        void *arg;
 
@@ -409,6 +410,7 @@ static void uwb_rc_neh_grok_event(struct uwb_rc *rc, struct uwb_rceb *rceb, size
        struct device *dev = &rc->uwb_dev.dev;
        struct uwb_rc_neh *neh;
        struct uwb_rceb *notif;
+       unsigned long flags;
 
        if (rceb->bEventContext == 0) {
                notif = kmalloc(size, GFP_ATOMIC);
@@ -422,7 +424,11 @@ static void uwb_rc_neh_grok_event(struct uwb_rc *rc, struct uwb_rceb *rceb, size
        } else {
                neh = uwb_rc_neh_lookup(rc, rceb);
                if (neh) {
-                       del_timer_sync(&neh->timer);
+                       spin_lock_irqsave(&rc->neh_lock, flags);
+                       /* to guard against a timeout */
+                       neh->completed = 1;
+                       del_timer(&neh->timer);
+                       spin_unlock_irqrestore(&rc->neh_lock, flags);
                        uwb_rc_neh_cb(neh, rceb, size);
                } else
                        dev_warn(dev, "event 0x%02x/%04x/%02x (%zu bytes): nobody cared\n",
@@ -568,6 +574,10 @@ static void uwb_rc_neh_timer(unsigned long arg)
        unsigned long flags;
 
        spin_lock_irqsave(&rc->neh_lock, flags);
+       if (neh->completed) {
+               spin_unlock_irqrestore(&rc->neh_lock, flags);
+               return;
+       }
        if (neh->context)
                __uwb_rc_neh_rm(rc, neh);
        else
index fc9a1d75281f33d57be305b3c724195c578334de..3de00d9fae2e6b7f186ed1767bed6e6424f08c76 100644 (file)
@@ -155,7 +155,7 @@ static int vhost_test_release(struct inode *inode, struct file *f)
 
        vhost_test_stop(n, &private);
        vhost_test_flush(n);
-       vhost_dev_cleanup(&n->dev);
+       vhost_dev_cleanup(&n->dev, false);
        /* We do an extra flush before freeing memory,
         * since jobs can re-queue themselves. */
        vhost_test_flush(n);
index 05f0a80818a2b1c202e2d5104ced13b9802287d0..c2d05a8279fd25c3ca988d354b7335e4102780c0 100644 (file)
 #include <linux/slab.h>
 #include <linux/module.h>
 
+/*
+ * Balloon device works in 4K page units.  So each page is pointed to by
+ * multiple balloon pages.  All memory counters in this driver are in balloon
+ * page units.
+ */
+#define VIRTIO_BALLOON_PAGES_PER_PAGE (PAGE_SIZE >> VIRTIO_BALLOON_PFN_SHIFT)
+
 struct virtio_balloon
 {
        struct virtio_device *vdev;
@@ -42,8 +49,13 @@ struct virtio_balloon
        /* Waiting for host to ack the pages we released. */
        struct completion acked;
 
-       /* The pages we've told the Host we're not using. */
+       /* Number of balloon pages we've told the Host we're not using. */
        unsigned int num_pages;
+       /*
+        * The pages we've told the Host we're not using.
+        * Each page on this list adds VIRTIO_BALLOON_PAGES_PER_PAGE
+        * to num_pages above.
+        */
        struct list_head pages;
 
        /* The array of pfns we tell the Host about. */
@@ -66,7 +78,13 @@ static u32 page_to_balloon_pfn(struct page *page)
 
        BUILD_BUG_ON(PAGE_SHIFT < VIRTIO_BALLOON_PFN_SHIFT);
        /* Convert pfn from Linux page size to balloon page size. */
-       return pfn >> (PAGE_SHIFT - VIRTIO_BALLOON_PFN_SHIFT);
+       return pfn * VIRTIO_BALLOON_PAGES_PER_PAGE;
+}
+
+static struct page *balloon_pfn_to_page(u32 pfn)
+{
+       BUG_ON(pfn % VIRTIO_BALLOON_PAGES_PER_PAGE);
+       return pfn_to_page(pfn / VIRTIO_BALLOON_PAGES_PER_PAGE);
 }
 
 static void balloon_ack(struct virtqueue *vq)
@@ -96,12 +114,23 @@ static void tell_host(struct virtio_balloon *vb, struct virtqueue *vq)
        wait_for_completion(&vb->acked);
 }
 
+static void set_page_pfns(u32 pfns[], struct page *page)
+{
+       unsigned int i;
+
+       /* Set balloon pfns pointing at this page.
+        * Note that the first pfn points at start of the page. */
+       for (i = 0; i < VIRTIO_BALLOON_PAGES_PER_PAGE; i++)
+               pfns[i] = page_to_balloon_pfn(page) + i;
+}
+
 static void fill_balloon(struct virtio_balloon *vb, size_t num)
 {
        /* We can only do one array worth at a time. */
        num = min(num, ARRAY_SIZE(vb->pfns));
 
-       for (vb->num_pfns = 0; vb->num_pfns < num; vb->num_pfns++) {
+       for (vb->num_pfns = 0; vb->num_pfns < num;
+            vb->num_pfns += VIRTIO_BALLOON_PAGES_PER_PAGE) {
                struct page *page = alloc_page(GFP_HIGHUSER | __GFP_NORETRY |
                                        __GFP_NOMEMALLOC | __GFP_NOWARN);
                if (!page) {
@@ -113,9 +142,9 @@ static void fill_balloon(struct virtio_balloon *vb, size_t num)
                        msleep(200);
                        break;
                }
-               vb->pfns[vb->num_pfns] = page_to_balloon_pfn(page);
+               set_page_pfns(vb->pfns + vb->num_pfns, page);
+               vb->num_pages += VIRTIO_BALLOON_PAGES_PER_PAGE;
                totalram_pages--;
-               vb->num_pages++;
                list_add(&page->lru, &vb->pages);
        }
 
@@ -130,8 +159,9 @@ static void release_pages_by_pfn(const u32 pfns[], unsigned int num)
 {
        unsigned int i;
 
-       for (i = 0; i < num; i++) {
-               __free_page(pfn_to_page(pfns[i]));
+       /* Find pfns pointing at start of each page, get pages and free them. */
+       for (i = 0; i < num; i += VIRTIO_BALLOON_PAGES_PER_PAGE) {
+               __free_page(balloon_pfn_to_page(pfns[i]));
                totalram_pages++;
        }
 }
@@ -143,11 +173,12 @@ static void leak_balloon(struct virtio_balloon *vb, size_t num)
        /* We can only do one array worth at a time. */
        num = min(num, ARRAY_SIZE(vb->pfns));
 
-       for (vb->num_pfns = 0; vb->num_pfns < num; vb->num_pfns++) {
+       for (vb->num_pfns = 0; vb->num_pfns < num;
+            vb->num_pfns += VIRTIO_BALLOON_PAGES_PER_PAGE) {
                page = list_first_entry(&vb->pages, struct page, lru);
                list_del(&page->lru);
-               vb->pfns[vb->num_pfns] = page_to_balloon_pfn(page);
-               vb->num_pages--;
+               set_page_pfns(vb->pfns + vb->num_pfns, page);
+               vb->num_pages -= VIRTIO_BALLOON_PAGES_PER_PAGE;
        }
 
        /*
@@ -234,11 +265,14 @@ static void virtballoon_changed(struct virtio_device *vdev)
 
 static inline s64 towards_target(struct virtio_balloon *vb)
 {
-       u32 v;
+       __le32 v;
+       s64 target;
+
        vb->vdev->config->get(vb->vdev,
                              offsetof(struct virtio_balloon_config, num_pages),
                              &v, sizeof(v));
-       return (s64)v - vb->num_pages;
+       target = le32_to_cpu(v);
+       return target - vb->num_pages;
 }
 
 static void update_balloon_size(struct virtio_balloon *vb)
index 99d8151c824adbff0611a16f493dde6e6927de4c..1ffd03bf8e10dcb6b015e3e0b94a2a460f0d0dcd 100644 (file)
@@ -722,7 +722,7 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma)
        vma->vm_flags |= VM_RESERVED|VM_DONTEXPAND;
 
        if (use_ptemod)
-               vma->vm_flags |= VM_DONTCOPY|VM_PFNMAP;
+               vma->vm_flags |= VM_DONTCOPY;
 
        vma->vm_private_data = map;
 
index b4d4eac761db6241042e60db3b604caa9150e91e..f100ce20b16b428880863ab768bf952ed84c43a9 100644 (file)
@@ -1029,6 +1029,7 @@ int gnttab_init(void)
        int i;
        unsigned int max_nr_glist_frames, nr_glist_frames;
        unsigned int nr_init_grefs;
+       int ret;
 
        nr_grant_frames = 1;
        boot_max_nr_grant_frames = __max_nr_grant_frames();
@@ -1047,12 +1048,16 @@ int gnttab_init(void)
        nr_glist_frames = (nr_grant_frames * GREFS_PER_GRANT_FRAME + RPP - 1) / RPP;
        for (i = 0; i < nr_glist_frames; i++) {
                gnttab_list[i] = (grant_ref_t *)__get_free_page(GFP_KERNEL);
-               if (gnttab_list[i] == NULL)
+               if (gnttab_list[i] == NULL) {
+                       ret = -ENOMEM;
                        goto ini_nomem;
+               }
        }
 
-       if (gnttab_resume() < 0)
-               return -ENODEV;
+       if (gnttab_resume() < 0) {
+               ret = -ENODEV;
+               goto ini_nomem;
+       }
 
        nr_init_grefs = nr_grant_frames * GREFS_PER_GRANT_FRAME;
 
@@ -1070,7 +1075,7 @@ int gnttab_init(void)
        for (i--; i >= 0; i--)
                free_page((unsigned long)gnttab_list[i]);
        kfree(gnttab_list);
-       return -ENOMEM;
+       return ret;
 }
 EXPORT_SYMBOL_GPL(gnttab_init);
 
index 9e14ae6cd49c018bf45156d58c1ff4af7411fdc3..412b96cc5305746c20d554b1a6d2c7e55ab09686 100644 (file)
@@ -132,6 +132,7 @@ static void do_suspend(void)
        err = dpm_suspend_end(PMSG_FREEZE);
        if (err) {
                printk(KERN_ERR "dpm_suspend_end failed: %d\n", err);
+               si.cancelled = 0;
                goto out_resume;
        }
 
index f20c5f178b40e27f8d2e9a4fbdf6e2b05dbe9320..a31b54d488398675fc01eaa2878f0a21ec49fe46 100644 (file)
@@ -135,7 +135,7 @@ static int read_backend_details(struct xenbus_device *xendev)
        return xenbus_read_otherend_details(xendev, "backend-id", "backend");
 }
 
-static int is_device_connecting(struct device *dev, void *data)
+static int is_device_connecting(struct device *dev, void *data, bool ignore_nonessential)
 {
        struct xenbus_device *xendev = to_xenbus_device(dev);
        struct device_driver *drv = data;
@@ -152,16 +152,41 @@ static int is_device_connecting(struct device *dev, void *data)
        if (drv && (dev->driver != drv))
                return 0;
 
+       if (ignore_nonessential) {
+               /* With older QEMU, for PVonHVM guests the guest config files
+                * could contain: vfb = [ 'vnc=1, vnclisten=0.0.0.0']
+                * which is nonsensical as there is no PV FB (there can be
+                * a PVKB) running as HVM guest. */
+
+               if ((strncmp(xendev->nodename, "device/vkbd", 11) == 0))
+                       return 0;
+
+               if ((strncmp(xendev->nodename, "device/vfb", 10) == 0))
+                       return 0;
+       }
        xendrv = to_xenbus_driver(dev->driver);
        return (xendev->state < XenbusStateConnected ||
                (xendev->state == XenbusStateConnected &&
                 xendrv->is_ready && !xendrv->is_ready(xendev)));
 }
+static int essential_device_connecting(struct device *dev, void *data)
+{
+       return is_device_connecting(dev, data, true /* ignore PV[KBB+FB] */);
+}
+static int non_essential_device_connecting(struct device *dev, void *data)
+{
+       return is_device_connecting(dev, data, false);
+}
 
-static int exists_connecting_device(struct device_driver *drv)
+static int exists_essential_connecting_device(struct device_driver *drv)
 {
        return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv,
-                               is_device_connecting);
+                               essential_device_connecting);
+}
+static int exists_non_essential_connecting_device(struct device_driver *drv)
+{
+       return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv,
+                               non_essential_device_connecting);
 }
 
 static int print_device_status(struct device *dev, void *data)
@@ -192,6 +217,23 @@ static int print_device_status(struct device *dev, void *data)
 /* We only wait for device setup after most initcalls have run. */
 static int ready_to_wait_for_devices;
 
+static bool wait_loop(unsigned long start, unsigned int max_delay,
+                    unsigned int *seconds_waited)
+{
+       if (time_after(jiffies, start + (*seconds_waited+5)*HZ)) {
+               if (!*seconds_waited)
+                       printk(KERN_WARNING "XENBUS: Waiting for "
+                              "devices to initialise: ");
+               *seconds_waited += 5;
+               printk("%us...", max_delay - *seconds_waited);
+               if (*seconds_waited == max_delay)
+                       return true;
+       }
+
+       schedule_timeout_interruptible(HZ/10);
+
+       return false;
+}
 /*
  * On a 5-minute timeout, wait for all devices currently configured.  We need
  * to do this to guarantee that the filesystems and / or network devices
@@ -215,19 +257,14 @@ static void wait_for_devices(struct xenbus_driver *xendrv)
        if (!ready_to_wait_for_devices || !xen_domain())
                return;
 
-       while (exists_connecting_device(drv)) {
-               if (time_after(jiffies, start + (seconds_waited+5)*HZ)) {
-                       if (!seconds_waited)
-                               printk(KERN_WARNING "XENBUS: Waiting for "
-                                      "devices to initialise: ");
-                       seconds_waited += 5;
-                       printk("%us...", 300 - seconds_waited);
-                       if (seconds_waited == 300)
-                               break;
-               }
-
-               schedule_timeout_interruptible(HZ/10);
-       }
+       while (exists_non_essential_connecting_device(drv))
+               if (wait_loop(start, 30, &seconds_waited))
+                       break;
+
+       /* Skips PVKB and PVFB check.*/
+       while (exists_essential_connecting_device(drv))
+               if (wait_loop(start, 270, &seconds_waited))
+                       break;
 
        if (seconds_waited)
                printk("\n");
index da887604dfc51929cd4cc17b10a943645b4618ef..67a6db3e1b6f83677009d2323c54dccd38dea63d 100644 (file)
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -93,9 +93,8 @@ static void aio_free_ring(struct kioctx *ctx)
                put_page(info->ring_pages[i]);
 
        if (info->mmap_size) {
-               down_write(&ctx->mm->mmap_sem);
-               do_munmap(ctx->mm, info->mmap_base, info->mmap_size);
-               up_write(&ctx->mm->mmap_sem);
+               BUG_ON(ctx->mm != current->mm);
+               vm_munmap(info->mmap_base, info->mmap_size);
        }
 
        if (info->ring_pages && info->ring_pages != info->internal_pages)
@@ -389,6 +388,17 @@ void exit_aio(struct mm_struct *mm)
                                "exit_aio:ioctx still alive: %d %d %d\n",
                                atomic_read(&ctx->users), ctx->dead,
                                ctx->reqs_active);
+               /*
+                * We don't need to bother with munmap() here -
+                * exit_mmap(mm) is coming and it'll unmap everything.
+                * Since aio_free_ring() uses non-zero ->mmap_size
+                * as indicator that it needs to unmap the area,
+                * just set it to 0; aio_free_ring() is the only
+                * place that uses ->mmap_size, so it's safe.
+                * That way we get all munmap done to current->mm -
+                * all other callers have ctx->mm == current->mm.
+                */
+               ctx->ring_info.mmap_size = 0;
                put_ioctx(ctx);
        }
 }
index 2eb12f13593db771987c9c4e7cd30c16515fcf11..d146e181d10df8611050c16745195b9efca62c93 100644 (file)
@@ -50,9 +50,7 @@ static int set_brk(unsigned long start, unsigned long end)
        end = PAGE_ALIGN(end);
        if (end > start) {
                unsigned long addr;
-               down_write(&current->mm->mmap_sem);
-               addr = do_brk(start, end - start);
-               up_write(&current->mm->mmap_sem);
+               addr = vm_brk(start, end - start);
                if (BAD_ADDR(addr))
                        return addr;
        }
@@ -280,9 +278,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
                pos = 32;
                map_size = ex.a_text+ex.a_data;
 #endif
-               down_write(&current->mm->mmap_sem);
-               error = do_brk(text_addr & PAGE_MASK, map_size);
-               up_write(&current->mm->mmap_sem);
+               error = vm_brk(text_addr & PAGE_MASK, map_size);
                if (error != (text_addr & PAGE_MASK)) {
                        send_sig(SIGKILL, current, 0);
                        return error;
@@ -313,9 +309,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
 
                if (!bprm->file->f_op->mmap||((fd_offset & ~PAGE_MASK) != 0)) {
                        loff_t pos = fd_offset;
-                       down_write(&current->mm->mmap_sem);
-                       do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
-                       up_write(&current->mm->mmap_sem);
+                       vm_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
                        bprm->file->f_op->read(bprm->file,
                                        (char __user *)N_TXTADDR(ex),
                                        ex.a_text+ex.a_data, &pos);
@@ -325,24 +319,20 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
                        goto beyond_if;
                }
 
-               down_write(&current->mm->mmap_sem);
-               error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text,
+               error = vm_mmap(bprm->file, N_TXTADDR(ex), ex.a_text,
                        PROT_READ | PROT_EXEC,
                        MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
                        fd_offset);
-               up_write(&current->mm->mmap_sem);
 
                if (error != N_TXTADDR(ex)) {
                        send_sig(SIGKILL, current, 0);
                        return error;
                }
 
-               down_write(&current->mm->mmap_sem);
-               error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
+               error = vm_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
                                PROT_READ | PROT_WRITE | PROT_EXEC,
                                MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
                                fd_offset + ex.a_text);
-               up_write(&current->mm->mmap_sem);
                if (error != N_DATADDR(ex)) {
                        send_sig(SIGKILL, current, 0);
                        return error;
@@ -412,9 +402,7 @@ static int load_aout_library(struct file *file)
                               "N_TXTOFF is not page aligned. Please convert library: %s\n",
                               file->f_path.dentry->d_name.name);
                }
-               down_write(&current->mm->mmap_sem);
-               do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
-               up_write(&current->mm->mmap_sem);
+               vm_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
                
                file->f_op->read(file, (char __user *)start_addr,
                        ex.a_text + ex.a_data, &pos);
@@ -425,12 +413,10 @@ static int load_aout_library(struct file *file)
                goto out;
        }
        /* Now use mmap to map the library into memory. */
-       down_write(&current->mm->mmap_sem);
-       error = do_mmap(file, start_addr, ex.a_text + ex.a_data,
+       error = vm_mmap(file, start_addr, ex.a_text + ex.a_data,
                        PROT_READ | PROT_WRITE | PROT_EXEC,
                        MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
                        N_TXTOFF(ex));
-       up_write(&current->mm->mmap_sem);
        retval = error;
        if (error != start_addr)
                goto out;
@@ -438,9 +424,7 @@ static int load_aout_library(struct file *file)
        len = PAGE_ALIGN(ex.a_text + ex.a_data);
        bss = ex.a_text + ex.a_data + ex.a_bss;
        if (bss > len) {
-               down_write(&current->mm->mmap_sem);
-               error = do_brk(start_addr + len, bss - len);
-               up_write(&current->mm->mmap_sem);
+               error = vm_brk(start_addr + len, bss - len);
                retval = error;
                if (error != start_addr + len)
                        goto out;
index 48ffb3dc610a7c9d6ea4428dd441666b4605b2c4..16f7354170725e050e69bf971aeb63eb57598c3e 100644 (file)
@@ -82,9 +82,7 @@ static int set_brk(unsigned long start, unsigned long end)
        end = ELF_PAGEALIGN(end);
        if (end > start) {
                unsigned long addr;
-               down_write(&current->mm->mmap_sem);
-               addr = do_brk(start, end - start);
-               up_write(&current->mm->mmap_sem);
+               addr = vm_brk(start, end - start);
                if (BAD_ADDR(addr))
                        return addr;
        }
@@ -514,9 +512,7 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
                elf_bss = ELF_PAGESTART(elf_bss + ELF_MIN_ALIGN - 1);
 
                /* Map the last of the bss segment */
-               down_write(&current->mm->mmap_sem);
-               error = do_brk(elf_bss, last_bss - elf_bss);
-               up_write(&current->mm->mmap_sem);
+               error = vm_brk(elf_bss, last_bss - elf_bss);
                if (BAD_ADDR(error))
                        goto out_close;
        }
@@ -962,10 +958,8 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
                   and some applications "depend" upon this behavior.
                   Since we do not have the power to recompile these, we
                   emulate the SVr4 behavior. Sigh. */
-               down_write(&current->mm->mmap_sem);
-               error = do_mmap(NULL, 0, PAGE_SIZE, PROT_READ | PROT_EXEC,
+               error = vm_mmap(NULL, 0, PAGE_SIZE, PROT_READ | PROT_EXEC,
                                MAP_FIXED | MAP_PRIVATE, 0);
-               up_write(&current->mm->mmap_sem);
        }
 
 #ifdef ELF_PLAT_INIT
@@ -1050,8 +1044,7 @@ static int load_elf_library(struct file *file)
                eppnt++;
 
        /* Now use mmap to map the library into memory. */
-       down_write(&current->mm->mmap_sem);
-       error = do_mmap(file,
+       error = vm_mmap(file,
                        ELF_PAGESTART(eppnt->p_vaddr),
                        (eppnt->p_filesz +
                         ELF_PAGEOFFSET(eppnt->p_vaddr)),
@@ -1059,7 +1052,6 @@ static int load_elf_library(struct file *file)
                        MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
                        (eppnt->p_offset -
                         ELF_PAGEOFFSET(eppnt->p_vaddr)));
-       up_write(&current->mm->mmap_sem);
        if (error != ELF_PAGESTART(eppnt->p_vaddr))
                goto out_free_ph;
 
@@ -1072,11 +1064,8 @@ static int load_elf_library(struct file *file)
        len = ELF_PAGESTART(eppnt->p_filesz + eppnt->p_vaddr +
                            ELF_MIN_ALIGN - 1);
        bss = eppnt->p_memsz + eppnt->p_vaddr;
-       if (bss > len) {
-               down_write(&current->mm->mmap_sem);
-               do_brk(len, bss - len);
-               up_write(&current->mm->mmap_sem);
-       }
+       if (bss > len)
+               vm_brk(len, bss - len);
        error = 0;
 
 out_free_ph:
index 9bd5612a8224fc5c6374d4dcc27ff99a58ee76e5..d390a0fffc65e1794c1985a2a626a87ed16c124b 100644 (file)
@@ -390,21 +390,17 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm,
            (executable_stack == EXSTACK_DEFAULT && VM_STACK_FLAGS & VM_EXEC))
                stack_prot |= PROT_EXEC;
 
-       down_write(&current->mm->mmap_sem);
-       current->mm->start_brk = do_mmap(NULL, 0, stack_size, stack_prot,
+       current->mm->start_brk = vm_mmap(NULL, 0, stack_size, stack_prot,
                                         MAP_PRIVATE | MAP_ANONYMOUS |
                                         MAP_UNINITIALIZED | MAP_GROWSDOWN,
                                         0);
 
        if (IS_ERR_VALUE(current->mm->start_brk)) {
-               up_write(&current->mm->mmap_sem);
                retval = current->mm->start_brk;
                current->mm->start_brk = 0;
                goto error_kill;
        }
 
-       up_write(&current->mm->mmap_sem);
-
        current->mm->brk = current->mm->start_brk;
        current->mm->context.end_brk = current->mm->start_brk;
        current->mm->context.end_brk +=
@@ -955,10 +951,8 @@ static int elf_fdpic_map_file_constdisp_on_uclinux(
        if (params->flags & ELF_FDPIC_FLAG_EXECUTABLE)
                mflags |= MAP_EXECUTABLE;
 
-       down_write(&mm->mmap_sem);
-       maddr = do_mmap(NULL, load_addr, top - base,
+       maddr = vm_mmap(NULL, load_addr, top - base,
                        PROT_READ | PROT_WRITE | PROT_EXEC, mflags, 0);
-       up_write(&mm->mmap_sem);
        if (IS_ERR_VALUE(maddr))
                return (int) maddr;
 
@@ -1096,10 +1090,8 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
 
                /* create the mapping */
                disp = phdr->p_vaddr & ~PAGE_MASK;
-               down_write(&mm->mmap_sem);
-               maddr = do_mmap(file, maddr, phdr->p_memsz + disp, prot, flags,
+               maddr = vm_mmap(file, maddr, phdr->p_memsz + disp, prot, flags,
                                phdr->p_offset - disp);
-               up_write(&mm->mmap_sem);
 
                kdebug("mmap[%d] <file> sz=%lx pr=%x fl=%x of=%lx --> %08lx",
                       loop, phdr->p_memsz + disp, prot, flags,
@@ -1143,10 +1135,8 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
                        unsigned long xmaddr;
 
                        flags |= MAP_FIXED | MAP_ANONYMOUS;
-                       down_write(&mm->mmap_sem);
-                       xmaddr = do_mmap(NULL, xaddr, excess - excess1,
+                       xmaddr = vm_mmap(NULL, xaddr, excess - excess1,
                                         prot, flags, 0);
-                       up_write(&mm->mmap_sem);
 
                        kdebug("mmap[%d] <anon>"
                               " ad=%lx sz=%lx pr=%x fl=%x of=0 --> %08lx",
index 024d20ee3ca3a617e377045fa7cf6d0706a4ed43..6b2daf99fab8bcd91d314f0abd951b8472a092d2 100644 (file)
@@ -542,10 +542,8 @@ static int load_flat_file(struct linux_binprm * bprm,
                 */
                DBG_FLT("BINFMT_FLAT: ROM mapping of file (we hope)\n");
 
-               down_write(&current->mm->mmap_sem);
-               textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC,
+               textpos = vm_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC,
                                  MAP_PRIVATE|MAP_EXECUTABLE, 0);
-               up_write(&current->mm->mmap_sem);
                if (!textpos || IS_ERR_VALUE(textpos)) {
                        if (!textpos)
                                textpos = (unsigned long) -ENOMEM;
@@ -556,10 +554,8 @@ static int load_flat_file(struct linux_binprm * bprm,
 
                len = data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long);
                len = PAGE_ALIGN(len);
-               down_write(&current->mm->mmap_sem);
-               realdatastart = do_mmap(0, 0, len,
+               realdatastart = vm_mmap(0, 0, len,
                        PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0);
-               up_write(&current->mm->mmap_sem);
 
                if (realdatastart == 0 || IS_ERR_VALUE(realdatastart)) {
                        if (!realdatastart)
@@ -603,10 +599,8 @@ static int load_flat_file(struct linux_binprm * bprm,
 
                len = text_len + data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long);
                len = PAGE_ALIGN(len);
-               down_write(&current->mm->mmap_sem);
-               textpos = do_mmap(0, 0, len,
+               textpos = vm_mmap(0, 0, len,
                        PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0);
-               up_write(&current->mm->mmap_sem);
 
                if (!textpos || IS_ERR_VALUE(textpos)) {
                        if (!textpos)
index e4fc746629a70000dc2ace0aac62038717add3f1..4517aaff61b4b874df51113698524fc20d44578c 100644 (file)
@@ -147,10 +147,8 @@ static int map_som_binary(struct file *file,
        code_size = SOM_PAGEALIGN(hpuxhdr->exec_tsize);
        current->mm->start_code = code_start;
        current->mm->end_code = code_start + code_size;
-       down_write(&current->mm->mmap_sem);
-       retval = do_mmap(file, code_start, code_size, prot,
+       retval = vm_mmap(file, code_start, code_size, prot,
                        flags, SOM_PAGESTART(hpuxhdr->exec_tfile));
-       up_write(&current->mm->mmap_sem);
        if (retval < 0 && retval > -1024)
                goto out;
 
@@ -158,20 +156,16 @@ static int map_som_binary(struct file *file,
        data_size = SOM_PAGEALIGN(hpuxhdr->exec_dsize);
        current->mm->start_data = data_start;
        current->mm->end_data = bss_start = data_start + data_size;
-       down_write(&current->mm->mmap_sem);
-       retval = do_mmap(file, data_start, data_size,
+       retval = vm_mmap(file, data_start, data_size,
                        prot | PROT_WRITE, flags,
                        SOM_PAGESTART(hpuxhdr->exec_dfile));
-       up_write(&current->mm->mmap_sem);
        if (retval < 0 && retval > -1024)
                goto out;
 
        som_brk = bss_start + SOM_PAGEALIGN(hpuxhdr->exec_bsize);
        current->mm->start_brk = current->mm->brk = som_brk;
-       down_write(&current->mm->mmap_sem);
-       retval = do_mmap(NULL, bss_start, som_brk - bss_start,
+       retval = vm_mmap(NULL, bss_start, som_brk - bss_start,
                        prot | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, 0);
-       up_write(&current->mm->mmap_sem);
        if (retval > 0 || retval < -1024)
                retval = 0;
 out:
index 5b8ef8eb35218e0f595ee93069fc1ccab49c6b1e..3f65a812e282d00744e9de5b89acc09ead08acb8 100644 (file)
@@ -2166,7 +2166,7 @@ BTRFS_SETGET_STACK_FUNCS(root_last_snapshot, struct btrfs_root_item,
 
 static inline bool btrfs_root_readonly(struct btrfs_root *root)
 {
-       return root->root_item.flags & BTRFS_ROOT_SUBVOL_RDONLY;
+       return (root->root_item.flags & cpu_to_le64(BTRFS_ROOT_SUBVOL_RDONLY)) != 0;
 }
 
 /* struct btrfs_root_backup */
index d81e933a796b1a07aa41ad6987f6f8d328594746..f31dc9ac37b76f0014fe5584c88d35d836bb1659 100644 (file)
@@ -109,6 +109,8 @@ enum {
 
        /* Options which could be blank */
        Opt_blank_pass,
+       Opt_blank_user,
+       Opt_blank_ip,
 
        Opt_err
 };
@@ -183,11 +185,15 @@ static const match_table_t cifs_mount_option_tokens = {
        { Opt_wsize, "wsize=%s" },
        { Opt_actimeo, "actimeo=%s" },
 
+       { Opt_blank_user, "user=" },
+       { Opt_blank_user, "username=" },
        { Opt_user, "user=%s" },
        { Opt_user, "username=%s" },
        { Opt_blank_pass, "pass=" },
        { Opt_pass, "pass=%s" },
        { Opt_pass, "password=%s" },
+       { Opt_blank_ip, "ip=" },
+       { Opt_blank_ip, "addr=" },
        { Opt_ip, "ip=%s" },
        { Opt_ip, "addr=%s" },
        { Opt_unc, "unc=%s" },
@@ -1117,7 +1123,7 @@ static int get_option_ul(substring_t args[], unsigned long *option)
        string = match_strdup(args);
        if (string == NULL)
                return -ENOMEM;
-       rc = kstrtoul(string, 10, option);
+       rc = kstrtoul(string, 0, option);
        kfree(string);
 
        return rc;
@@ -1534,15 +1540,17 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
 
                /* String Arguments */
 
+               case Opt_blank_user:
+                       /* null user, ie. anonymous authentication */
+                       vol->nullauth = 1;
+                       vol->username = NULL;
+                       break;
                case Opt_user:
                        string = match_strdup(args);
                        if (string == NULL)
                                goto out_nomem;
 
-                       if (!*string) {
-                               /* null user, ie. anonymous authentication */
-                               vol->nullauth = 1;
-                       } else if (strnlen(string, MAX_USERNAME_SIZE) >
+                       if (strnlen(string, MAX_USERNAME_SIZE) >
                                                        MAX_USERNAME_SIZE) {
                                printk(KERN_WARNING "CIFS: username too long\n");
                                goto cifs_parse_mount_err;
@@ -1611,14 +1619,15 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                        }
                        vol->password[j] = '\0';
                        break;
+               case Opt_blank_ip:
+                       vol->UNCip = NULL;
+                       break;
                case Opt_ip:
                        string = match_strdup(args);
                        if (string == NULL)
                                goto out_nomem;
 
-                       if (!*string) {
-                               vol->UNCip = NULL;
-                       } else if (strnlen(string, INET6_ADDRSTRLEN) >
+                       if (strnlen(string, INET6_ADDRSTRLEN) >
                                                INET6_ADDRSTRLEN) {
                                printk(KERN_WARNING "CIFS: ip address "
                                                    "too long\n");
@@ -1636,12 +1645,6 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                        if (string == NULL)
                                goto out_nomem;
 
-                       if (!*string) {
-                               printk(KERN_WARNING "CIFS: invalid path to "
-                                                   "network resource\n");
-                               goto cifs_parse_mount_err;
-                       }
-
                        temp_len = strnlen(string, 300);
                        if (temp_len  == 300) {
                                printk(KERN_WARNING "CIFS: UNC name too long\n");
@@ -1670,11 +1673,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                        if (string == NULL)
                                goto out_nomem;
 
-                       if (!*string) {
-                               printk(KERN_WARNING "CIFS: invalid domain"
-                                                   " name\n");
-                               goto cifs_parse_mount_err;
-                       } else if (strnlen(string, 256) == 256) {
+                       if (strnlen(string, 256) == 256) {
                                printk(KERN_WARNING "CIFS: domain name too"
                                                    " long\n");
                                goto cifs_parse_mount_err;
@@ -1693,11 +1692,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                        if (string == NULL)
                                goto out_nomem;
 
-                       if (!*string) {
-                               printk(KERN_WARNING "CIFS: srcaddr value not"
-                                                   " specified\n");
-                               goto cifs_parse_mount_err;
-                       } else if (!cifs_convert_address(
+                       if (!cifs_convert_address(
                                        (struct sockaddr *)&vol->srcaddr,
                                        string, strlen(string))) {
                                printk(KERN_WARNING "CIFS:  Could not parse"
@@ -1710,11 +1705,6 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                        if (string == NULL)
                                goto out_nomem;
 
-                       if (!*string) {
-                               printk(KERN_WARNING "CIFS: Invalid path"
-                                                   " prefix\n");
-                               goto cifs_parse_mount_err;
-                       }
                        temp_len = strnlen(string, 1024);
                        if (string[0] != '/')
                                temp_len++; /* missing leading slash */
@@ -1742,11 +1732,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                        if (string == NULL)
                                goto out_nomem;
 
-                       if (!*string) {
-                               printk(KERN_WARNING "CIFS: Invalid iocharset"
-                                                   " specified\n");
-                               goto cifs_parse_mount_err;
-                       } else if (strnlen(string, 1024) >= 65) {
+                       if (strnlen(string, 1024) >= 65) {
                                printk(KERN_WARNING "CIFS: iocharset name "
                                                    "too long.\n");
                                goto cifs_parse_mount_err;
@@ -1771,11 +1757,6 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                        if (string == NULL)
                                goto out_nomem;
 
-                       if (!*string) {
-                               printk(KERN_WARNING "CIFS: No socket option"
-                                                   " specified\n");
-                               goto cifs_parse_mount_err;
-                       }
                        if (strnicmp(string, "TCP_NODELAY", 11) == 0)
                                vol->sockopt_tcp_nodelay = 1;
                        break;
@@ -1784,12 +1765,6 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                        if (string == NULL)
                                goto out_nomem;
 
-                       if (!*string) {
-                               printk(KERN_WARNING "CIFS: Invalid (empty)"
-                                                   " netbiosname\n");
-                               break;
-                       }
-
                        memset(vol->source_rfc1001_name, 0x20,
                                RFC1001_NAME_LEN);
                        /*
@@ -1817,11 +1792,6 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                        if (string == NULL)
                                goto out_nomem;
 
-                       if (!*string) {
-                               printk(KERN_WARNING "CIFS: Empty server"
-                                       " netbiosname specified\n");
-                               break;
-                       }
                        /* last byte, type, is 0x20 for servr type */
                        memset(vol->target_rfc1001_name, 0x20,
                                RFC1001_NAME_LEN_WITH_NULL);
@@ -1848,12 +1818,6 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                        if (string == NULL)
                                goto out_nomem;
 
-                       if (!*string) {
-                               cERROR(1, "no protocol version specified"
-                                         " after vers= mount option");
-                               goto cifs_parse_mount_err;
-                       }
-
                        if (strnicmp(string, "cifs", 4) == 0 ||
                            strnicmp(string, "1", 1) == 0) {
                                /* This is the default */
@@ -1868,12 +1832,6 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                        if (string == NULL)
                                goto out_nomem;
 
-                       if (!*string) {
-                               printk(KERN_WARNING "CIFS: no security flavor"
-                                                   " specified\n");
-                               break;
-                       }
-
                        if (cifs_parse_security_flavors(string, vol) != 0)
                                goto cifs_parse_mount_err;
                        break;
index ab2594a30f86f8a39a0fc918a0bdc69e1d7c9e0f..0e01e90add8bc42f1492a73a2e1e78331b8ae134 100644 (file)
@@ -1203,9 +1203,6 @@ struct ext4_sb_info {
        unsigned long s_ext_blocks;
        unsigned long s_ext_extents;
 #endif
-       /* ext4 extent cache stats */
-       unsigned long extent_cache_hits;
-       unsigned long extent_cache_misses;
 
        /* for buddy allocator */
        struct ext4_group_info ***s_group_info;
index 1421938e6792a4f5426cbd8f4d218eea4f2192f9..abcdeab67f5232b66d4aa5a6cbb88838094f6247 100644 (file)
@@ -2066,10 +2066,6 @@ static int ext4_ext_check_cache(struct inode *inode, ext4_lblk_t block,
                ret = 1;
        }
 errout:
-       if (!ret)
-               sbi->extent_cache_misses++;
-       else
-               sbi->extent_cache_hits++;
        trace_ext4_ext_in_cache(inode, block, ret);
        spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
        return ret;
@@ -2882,7 +2878,7 @@ static int ext4_split_extent_at(handle_t *handle,
                if (err)
                        goto fix_extent_len;
                /* update the extent length and mark as initialized */
-               ex->ee_len = cpu_to_le32(ee_len);
+               ex->ee_len = cpu_to_le16(ee_len);
                ext4_ext_try_to_merge(inode, path, ex);
                err = ext4_ext_dirty(handle, inode, path + depth);
                goto out;
index ceebaf853beb74c7e139e63f46bf44975696566b..6da193564e43b2dc6862dcca4c4aa52689479939 100644 (file)
@@ -1305,20 +1305,20 @@ static int set_qf_name(struct super_block *sb, int qtype, substring_t *args)
                ext4_msg(sb, KERN_ERR,
                        "Cannot change journaled "
                        "quota options when quota turned on");
-               return 0;
+               return -1;
        }
        qname = match_strdup(args);
        if (!qname) {
                ext4_msg(sb, KERN_ERR,
                        "Not enough memory for storing quotafile name");
-               return 0;
+               return -1;
        }
        if (sbi->s_qf_names[qtype] &&
                strcmp(sbi->s_qf_names[qtype], qname)) {
                ext4_msg(sb, KERN_ERR,
                        "%s quota file already specified", QTYPE2NAME(qtype));
                kfree(qname);
-               return 0;
+               return -1;
        }
        sbi->s_qf_names[qtype] = qname;
        if (strchr(sbi->s_qf_names[qtype], '/')) {
@@ -1326,7 +1326,7 @@ static int set_qf_name(struct super_block *sb, int qtype, substring_t *args)
                        "quotafile must be on filesystem root");
                kfree(sbi->s_qf_names[qtype]);
                sbi->s_qf_names[qtype] = NULL;
-               return 0;
+               return -1;
        }
        set_opt(sb, QUOTA);
        return 1;
@@ -1341,7 +1341,7 @@ static int clear_qf_name(struct super_block *sb, int qtype)
                sbi->s_qf_names[qtype]) {
                ext4_msg(sb, KERN_ERR, "Cannot change journaled quota options"
                        " when quota turned on");
-               return 0;
+               return -1;
        }
        /*
         * The space will be released later when all options are confirmed
@@ -1450,6 +1450,16 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token,
        const struct mount_opts *m;
        int arg = 0;
 
+#ifdef CONFIG_QUOTA
+       if (token == Opt_usrjquota)
+               return set_qf_name(sb, USRQUOTA, &args[0]);
+       else if (token == Opt_grpjquota)
+               return set_qf_name(sb, GRPQUOTA, &args[0]);
+       else if (token == Opt_offusrjquota)
+               return clear_qf_name(sb, USRQUOTA);
+       else if (token == Opt_offgrpjquota)
+               return clear_qf_name(sb, GRPQUOTA);
+#endif
        if (args->from && match_int(args, &arg))
                return -1;
        switch (token) {
@@ -1549,18 +1559,6 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token,
                                sbi->s_mount_opt |= m->mount_opt;
                        }
 #ifdef CONFIG_QUOTA
-               } else if (token == Opt_usrjquota) {
-                       if (!set_qf_name(sb, USRQUOTA, &args[0]))
-                               return -1;
-               } else if (token == Opt_grpjquota) {
-                       if (!set_qf_name(sb, GRPQUOTA, &args[0]))
-                               return -1;
-               } else if (token == Opt_offusrjquota) {
-                       if (!clear_qf_name(sb, USRQUOTA))
-                               return -1;
-               } else if (token == Opt_offgrpjquota) {
-                       if (!clear_qf_name(sb, GRPQUOTA))
-                               return -1;
                } else if (m->flags & MOPT_QFMT) {
                        if (sb_any_quota_loaded(sb) &&
                            sbi->s_jquota_fmt != m->mount_opt) {
@@ -2366,18 +2364,6 @@ static ssize_t lifetime_write_kbytes_show(struct ext4_attr *a,
                          EXT4_SB(sb)->s_sectors_written_start) >> 1)));
 }
 
-static ssize_t extent_cache_hits_show(struct ext4_attr *a,
-                                     struct ext4_sb_info *sbi, char *buf)
-{
-       return snprintf(buf, PAGE_SIZE, "%lu\n", sbi->extent_cache_hits);
-}
-
-static ssize_t extent_cache_misses_show(struct ext4_attr *a,
-                                       struct ext4_sb_info *sbi, char *buf)
-{
-       return snprintf(buf, PAGE_SIZE, "%lu\n", sbi->extent_cache_misses);
-}
-
 static ssize_t inode_readahead_blks_store(struct ext4_attr *a,
                                          struct ext4_sb_info *sbi,
                                          const char *buf, size_t count)
@@ -2435,8 +2421,6 @@ static struct ext4_attr ext4_attr_##name = __ATTR(name, mode, show, store)
 EXT4_RO_ATTR(delayed_allocation_blocks);
 EXT4_RO_ATTR(session_write_kbytes);
 EXT4_RO_ATTR(lifetime_write_kbytes);
-EXT4_RO_ATTR(extent_cache_hits);
-EXT4_RO_ATTR(extent_cache_misses);
 EXT4_ATTR_OFFSET(inode_readahead_blks, 0644, sbi_ui_show,
                 inode_readahead_blks_store, s_inode_readahead_blks);
 EXT4_RW_ATTR_SBI_UI(inode_goal, s_inode_goal);
@@ -2452,8 +2436,6 @@ static struct attribute *ext4_attrs[] = {
        ATTR_LIST(delayed_allocation_blocks),
        ATTR_LIST(session_write_kbytes),
        ATTR_LIST(lifetime_write_kbytes),
-       ATTR_LIST(extent_cache_hits),
-       ATTR_LIST(extent_cache_misses),
        ATTR_LIST(inode_readahead_blks),
        ATTR_LIST(inode_goal),
        ATTR_LIST(mb_stats),
index 206632887bb40ccf48bb80b96e497c2107c172d9..df5ac048dc74e6b33174a69dc36b3a5b6084fd74 100644 (file)
@@ -387,9 +387,6 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry,
        if (fc->no_create)
                return -ENOSYS;
 
-       if (flags & O_DIRECT)
-               return -EINVAL;
-
        forget = fuse_alloc_forget();
        if (!forget)
                return -ENOMEM;
@@ -644,13 +641,12 @@ static int fuse_unlink(struct inode *dir, struct dentry *entry)
        fuse_put_request(fc, req);
        if (!err) {
                struct inode *inode = entry->d_inode;
+               struct fuse_inode *fi = get_fuse_inode(inode);
 
-               /*
-                * Set nlink to zero so the inode can be cleared, if the inode
-                * does have more links this will be discovered at the next
-                * lookup/getattr.
-                */
-               clear_nlink(inode);
+               spin_lock(&fc->lock);
+               fi->attr_version = ++fc->attr_version;
+               drop_nlink(inode);
+               spin_unlock(&fc->lock);
                fuse_invalidate_attr(inode);
                fuse_invalidate_attr(dir);
                fuse_invalidate_entry_cache(entry);
@@ -762,8 +758,17 @@ static int fuse_link(struct dentry *entry, struct inode *newdir,
           will reflect changes in the backing inode (link count,
           etc.)
        */
-       if (!err || err == -EINTR)
+       if (!err) {
+               struct fuse_inode *fi = get_fuse_inode(inode);
+
+               spin_lock(&fc->lock);
+               fi->attr_version = ++fc->attr_version;
+               inc_nlink(inode);
+               spin_unlock(&fc->lock);
+               fuse_invalidate_attr(inode);
+       } else if (err == -EINTR) {
                fuse_invalidate_attr(inode);
+       }
        return err;
 }
 
index a841868bf9ce363cb9705f3a5ba978a39c682df7..504e61b7fd7515f8aafe7e3b9edd2c9fa42fd91d 100644 (file)
@@ -194,10 +194,6 @@ int fuse_open_common(struct inode *inode, struct file *file, bool isdir)
        struct fuse_conn *fc = get_fuse_conn(inode);
        int err;
 
-       /* VFS checks this, but only _after_ ->open() */
-       if (file->f_flags & O_DIRECT)
-               return -EINVAL;
-
        err = generic_file_open(inode, file);
        if (err)
                return err;
@@ -932,17 +928,23 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
        struct file *file = iocb->ki_filp;
        struct address_space *mapping = file->f_mapping;
        size_t count = 0;
+       size_t ocount = 0;
        ssize_t written = 0;
+       ssize_t written_buffered = 0;
        struct inode *inode = mapping->host;
        ssize_t err;
        struct iov_iter i;
+       loff_t endbyte = 0;
 
        WARN_ON(iocb->ki_pos != pos);
 
-       err = generic_segment_checks(iov, &nr_segs, &count, VERIFY_READ);
+       ocount = 0;
+       err = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ);
        if (err)
                return err;
 
+       count = ocount;
+
        mutex_lock(&inode->i_mutex);
        vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE);
 
@@ -962,11 +964,41 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
 
        file_update_time(file);
 
-       iov_iter_init(&i, iov, nr_segs, count, 0);
-       written = fuse_perform_write(file, mapping, &i, pos);
-       if (written >= 0)
-               iocb->ki_pos = pos + written;
+       if (file->f_flags & O_DIRECT) {
+               written = generic_file_direct_write(iocb, iov, &nr_segs,
+                                                   pos, &iocb->ki_pos,
+                                                   count, ocount);
+               if (written < 0 || written == count)
+                       goto out;
+
+               pos += written;
+               count -= written;
 
+               iov_iter_init(&i, iov, nr_segs, count, written);
+               written_buffered = fuse_perform_write(file, mapping, &i, pos);
+               if (written_buffered < 0) {
+                       err = written_buffered;
+                       goto out;
+               }
+               endbyte = pos + written_buffered - 1;
+
+               err = filemap_write_and_wait_range(file->f_mapping, pos,
+                                                  endbyte);
+               if (err)
+                       goto out;
+
+               invalidate_mapping_pages(file->f_mapping,
+                                        pos >> PAGE_CACHE_SHIFT,
+                                        endbyte >> PAGE_CACHE_SHIFT);
+
+               written += written_buffered;
+               iocb->ki_pos = pos + written_buffered;
+       } else {
+               iov_iter_init(&i, iov, nr_segs, count, 0);
+               written = fuse_perform_write(file, mapping, &i, pos);
+               if (written >= 0)
+                       iocb->ki_pos = pos + written;
+       }
 out:
        current->backing_dev_info = NULL;
        mutex_unlock(&inode->i_mutex);
@@ -1101,30 +1133,41 @@ static ssize_t fuse_direct_read(struct file *file, char __user *buf,
        return res;
 }
 
-static ssize_t fuse_direct_write(struct file *file, const char __user *buf,
-                                size_t count, loff_t *ppos)
+static ssize_t __fuse_direct_write(struct file *file, const char __user *buf,
+                                  size_t count, loff_t *ppos)
 {
        struct inode *inode = file->f_path.dentry->d_inode;
        ssize_t res;
 
-       if (is_bad_inode(inode))
-               return -EIO;
-
-       /* Don't allow parallel writes to the same file */
-       mutex_lock(&inode->i_mutex);
        res = generic_write_checks(file, ppos, &count, 0);
        if (!res) {
                res = fuse_direct_io(file, buf, count, ppos, 1);
                if (res > 0)
                        fuse_write_update_size(inode, *ppos);
        }
-       mutex_unlock(&inode->i_mutex);
 
        fuse_invalidate_attr(inode);
 
        return res;
 }
 
+static ssize_t fuse_direct_write(struct file *file, const char __user *buf,
+                                size_t count, loff_t *ppos)
+{
+       struct inode *inode = file->f_path.dentry->d_inode;
+       ssize_t res;
+
+       if (is_bad_inode(inode))
+               return -EIO;
+
+       /* Don't allow parallel writes to the same file */
+       mutex_lock(&inode->i_mutex);
+       res = __fuse_direct_write(file, buf, count, ppos);
+       mutex_unlock(&inode->i_mutex);
+
+       return res;
+}
+
 static void fuse_writepage_free(struct fuse_conn *fc, struct fuse_req *req)
 {
        __free_page(req->pages[0]);
@@ -2077,6 +2120,57 @@ int fuse_notify_poll_wakeup(struct fuse_conn *fc,
        return 0;
 }
 
+static ssize_t fuse_loop_dio(struct file *filp, const struct iovec *iov,
+                            unsigned long nr_segs, loff_t *ppos, int rw)
+{
+       const struct iovec *vector = iov;
+       ssize_t ret = 0;
+
+       while (nr_segs > 0) {
+               void __user *base;
+               size_t len;
+               ssize_t nr;
+
+               base = vector->iov_base;
+               len = vector->iov_len;
+               vector++;
+               nr_segs--;
+
+               if (rw == WRITE)
+                       nr = __fuse_direct_write(filp, base, len, ppos);
+               else
+                       nr = fuse_direct_read(filp, base, len, ppos);
+
+               if (nr < 0) {
+                       if (!ret)
+                               ret = nr;
+                       break;
+               }
+               ret += nr;
+               if (nr != len)
+                       break;
+       }
+
+       return ret;
+}
+
+
+static ssize_t
+fuse_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
+                       loff_t offset, unsigned long nr_segs)
+{
+       ssize_t ret = 0;
+       struct file *file = NULL;
+       loff_t pos = 0;
+
+       file = iocb->ki_filp;
+       pos = offset;
+
+       ret = fuse_loop_dio(file, iov, nr_segs, &pos, rw);
+
+       return ret;
+}
+
 static const struct file_operations fuse_file_operations = {
        .llseek         = fuse_file_llseek,
        .read           = do_sync_read,
@@ -2120,6 +2214,7 @@ static const struct address_space_operations fuse_file_aops  = {
        .readpages      = fuse_readpages,
        .set_page_dirty = __set_page_dirty_nobuffers,
        .bmap           = fuse_bmap,
+       .direct_IO      = fuse_direct_IO,
 };
 
 void fuse_init_file_inode(struct inode *inode)
index 4aec5995867e95c8c0df3e00d93b1e5ae39d25c0..26783eb2b1fc9465602cc0f452c49aa3e72d32b5 100644 (file)
@@ -947,6 +947,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
        sb->s_magic = FUSE_SUPER_MAGIC;
        sb->s_op = &fuse_super_operations;
        sb->s_maxbytes = MAX_LFS_FILESIZE;
+       sb->s_time_gran = 1;
        sb->s_export_op = &fuse_export_operations;
 
        file = fget(d.fd);
index 3ddcbb1c0a432728f626986b1d057d11aafdce84..13ad1539fbf2479cd7f69a45611cd3d6a460688f 100644 (file)
@@ -241,7 +241,7 @@ static int decode_nlm4_stat(struct xdr_stream *xdr, __be32 *stat)
        p = xdr_inline_decode(xdr, 4);
        if (unlikely(p == NULL))
                goto out_overflow;
-       if (unlikely(*p > nlm4_failed))
+       if (unlikely(ntohl(*p) > ntohl(nlm4_failed)))
                goto out_bad_xdr;
        *stat = *p;
        return 0;
index 3d35e3e80c1ccfac1367647b6ac417ba3f5bd1b2..d269ada7670e155c7544a2aa01ea0697e98f3991 100644 (file)
@@ -236,7 +236,7 @@ static int decode_nlm_stat(struct xdr_stream *xdr,
        p = xdr_inline_decode(xdr, 4);
        if (unlikely(p == NULL))
                goto out_overflow;
-       if (unlikely(*p > nlm_lck_denied_grace_period))
+       if (unlikely(ntohl(*p) > ntohl(nlm_lck_denied_grace_period)))
                goto out_enum;
        *stat = *p;
        return 0;
index 08c6e36ab2eb05d8c28f68394a326573a7f52658..43f46cd9edea84e18040381a2647a54ca59debb0 100644 (file)
@@ -803,13 +803,13 @@ encode_entry_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name,
        return p;
 }
 
-static int
+static __be32
 compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp,
                const char *name, int namlen)
 {
        struct svc_export       *exp;
        struct dentry           *dparent, *dchild;
-       int rv = 0;
+       __be32 rv = nfserr_noent;
 
        dparent = cd->fh.fh_dentry;
        exp  = cd->fh.fh_export;
@@ -817,26 +817,20 @@ compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp,
        if (isdotent(name, namlen)) {
                if (namlen == 2) {
                        dchild = dget_parent(dparent);
-                       if (dchild == dparent) {
-                               /* filesystem root - cannot return filehandle for ".." */
-                               dput(dchild);
-                               return -ENOENT;
-                       }
+                       /* filesystem root - cannot return filehandle for ".." */
+                       if (dchild == dparent)
+                               goto out;
                } else
                        dchild = dget(dparent);
        } else
                dchild = lookup_one_len(name, dparent, namlen);
        if (IS_ERR(dchild))
-               return -ENOENT;
-       rv = -ENOENT;
+               return rv;
        if (d_mountpoint(dchild))
                goto out;
-       rv = fh_compose(fhp, exp, dchild, &cd->fh);
-       if (rv)
-               goto out;
        if (!dchild->d_inode)
                goto out;
-       rv = 0;
+       rv = fh_compose(fhp, exp, dchild, &cd->fh);
 out:
        dput(dchild);
        return rv;
@@ -845,7 +839,7 @@ out:
 static __be32 *encode_entryplus_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, int namlen)
 {
        struct svc_fh   fh;
-       int err;
+       __be32 err;
 
        fh_init(&fh, NFS3_FHSIZE);
        err = compose_entry_fh(cd, &fh, name, namlen);
index 2ed14dfd00a231e9c813b78b3d728bcdfb849b06..987e719fbae8c64f2776f914e7f4104ee04be492 100644 (file)
@@ -235,15 +235,15 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o
                 */
                if (open->op_createmode == NFS4_CREATE_EXCLUSIVE && status == 0)
                        open->op_bmval[1] = (FATTR4_WORD1_TIME_ACCESS |
-                                               FATTR4_WORD1_TIME_MODIFY);
+                                                       FATTR4_WORD1_TIME_MODIFY);
        } else {
                status = nfsd_lookup(rqstp, current_fh,
                                     open->op_fname.data, open->op_fname.len, resfh);
                fh_unlock(current_fh);
-               if (status)
-                       goto out;
-               status = nfsd_check_obj_isreg(resfh);
        }
+       if (status)
+               goto out;
+       status = nfsd_check_obj_isreg(resfh);
        if (status)
                goto out;
 
@@ -841,6 +841,7 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
              struct nfsd4_setattr *setattr)
 {
        __be32 status = nfs_ok;
+       int err;
 
        if (setattr->sa_iattr.ia_valid & ATTR_SIZE) {
                nfs4_lock_state();
@@ -852,9 +853,9 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                        return status;
                }
        }
-       status = fh_want_write(&cstate->current_fh);
-       if (status)
-               return status;
+       err = fh_want_write(&cstate->current_fh);
+       if (err)
+               return nfserrno(err);
        status = nfs_ok;
 
        status = check_attr_support(rqstp, cstate, setattr->sa_bmval,
index 1841f8bf845e7440bba605f25357a512a8a5b0b0..7f71c69cdcdfdcbd7245a71820b9f13e1a0bb135 100644 (file)
@@ -4211,16 +4211,14 @@ out:
  * vfs_test_lock.  (Arguably perhaps test_lock should be done with an
  * inode operation.)
  */
-static int nfsd_test_lock(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file_lock *lock)
+static __be32 nfsd_test_lock(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file_lock *lock)
 {
        struct file *file;
-       int err;
-
-       err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file);
-       if (err)
-               return err;
-       err = vfs_test_lock(file, lock);
-       nfsd_close(file);
+       __be32 err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file);
+       if (!err) {
+               err = nfserrno(vfs_test_lock(file, lock));
+               nfsd_close(file);
+       }
        return err;
 }
 
@@ -4234,7 +4232,6 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        struct inode *inode;
        struct file_lock file_lock;
        struct nfs4_lockowner *lo;
-       int error;
        __be32 status;
 
        if (locks_in_grace())
@@ -4280,12 +4277,10 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 
        nfs4_transform_lock_offset(&file_lock);
 
-       status = nfs_ok;
-       error = nfsd_test_lock(rqstp, &cstate->current_fh, &file_lock);
-       if (error) {
-               status = nfserrno(error);
+       status = nfsd_test_lock(rqstp, &cstate->current_fh, &file_lock);
+       if (status)
                goto out;
-       }
+
        if (file_lock.fl_type != F_UNLCK) {
                status = nfserr_denied;
                nfs4_set_lock_denied(&file_lock, &lockt->lt_denied);
index bcd8904ab1e36dd807f26379392000fb114f9bc6..74c00bc92b9af6b01e95e55c119b90d61fbf9d34 100644 (file)
@@ -1392,7 +1392,7 @@ nfsd4_decode_test_stateid(struct nfsd4_compoundargs *argp, struct nfsd4_test_sta
        for (i = 0; i < test_stateid->ts_num_ids; i++) {
                stateid = kmalloc(sizeof(struct nfsd4_test_stateid_id), GFP_KERNEL);
                if (!stateid) {
-                       status = PTR_ERR(stateid);
+                       status = nfserrno(-ENOMEM);
                        goto out;
                }
 
@@ -3410,7 +3410,7 @@ nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, int nfserr,
        *p++ = htonl(test_stateid->ts_num_ids);
 
        list_for_each_entry_safe(stateid, next, &test_stateid->ts_stateid_list, ts_id_list) {
-               *p++ = htonl(stateid->ts_id_status);
+               *p++ = stateid->ts_id_status;
        }
 
        ADJUST_ARGS();
index 296d671654d6a12fbb89567ea6b80cfd26a1829f..568666156ea4f59525d67207551ee8c45a3b730e 100644 (file)
@@ -1458,7 +1458,7 @@ do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
                switch (createmode) {
                case NFS3_CREATE_UNCHECKED:
                        if (! S_ISREG(dchild->d_inode->i_mode))
-                               err = nfserr_exist;
+                               goto out;
                        else if (truncp) {
                                /* in nfsv4, we need to treat this case a little
                                 * differently.  we don't want to truncate the
index 3165aebb43c87934b743ecf08e5f02cef586d771..31b9463fba1fb19259da764d94372ffffc0f6008 100644 (file)
@@ -1134,7 +1134,7 @@ static int ocfs2_adjust_rightmost_branch(handle_t *handle,
        }
 
        el = path_leaf_el(path);
-       rec = &el->l_recs[le32_to_cpu(el->l_next_free_rec) - 1];
+       rec = &el->l_recs[le16_to_cpu(el->l_next_free_rec) - 1];
 
        ocfs2_adjust_rightmost_records(handle, et, path, rec);
 
index cf782338266421779e5ba8fa165786b006f4c2aa..9f32d7cbb7a3701f1f28d938b17ae4d057dc4e84 100644 (file)
@@ -1036,14 +1036,14 @@ static int ocfs2_get_refcount_cpos_end(struct ocfs2_caching_info *ci,
 
        tmp_el = left_path->p_node[subtree_root].el;
        blkno = left_path->p_node[subtree_root+1].bh->b_blocknr;
-       for (i = 0; i < le32_to_cpu(tmp_el->l_next_free_rec); i++) {
+       for (i = 0; i < le16_to_cpu(tmp_el->l_next_free_rec); i++) {
                if (le64_to_cpu(tmp_el->l_recs[i].e_blkno) == blkno) {
                        *cpos_end = le32_to_cpu(tmp_el->l_recs[i+1].e_cpos);
                        break;
                }
        }
 
-       BUG_ON(i == le32_to_cpu(tmp_el->l_next_free_rec));
+       BUG_ON(i == le16_to_cpu(tmp_el->l_next_free_rec));
 
 out:
        ocfs2_free_path(left_path);
@@ -1468,7 +1468,7 @@ static int ocfs2_divide_leaf_refcount_block(struct buffer_head *ref_leaf_bh,
 
        trace_ocfs2_divide_leaf_refcount_block(
                (unsigned long long)ref_leaf_bh->b_blocknr,
-               le32_to_cpu(rl->rl_count), le32_to_cpu(rl->rl_used));
+               le16_to_cpu(rl->rl_count), le16_to_cpu(rl->rl_used));
 
        /*
         * XXX: Improvement later.
@@ -2411,7 +2411,7 @@ static int ocfs2_calc_refcount_meta_credits(struct super_block *sb,
                                rb = (struct ocfs2_refcount_block *)
                                                        prev_bh->b_data;
 
-                               if (le64_to_cpu(rb->rf_records.rl_used) +
+                               if (le16_to_cpu(rb->rf_records.rl_used) +
                                    recs_add >
                                    le16_to_cpu(rb->rf_records.rl_count))
                                        ref_blocks++;
@@ -2476,7 +2476,7 @@ static int ocfs2_calc_refcount_meta_credits(struct super_block *sb,
        if (prev_bh) {
                rb = (struct ocfs2_refcount_block *)prev_bh->b_data;
 
-               if (le64_to_cpu(rb->rf_records.rl_used) + recs_add >
+               if (le16_to_cpu(rb->rf_records.rl_used) + recs_add >
                    le16_to_cpu(rb->rf_records.rl_count))
                        ref_blocks++;
 
@@ -3629,7 +3629,7 @@ int ocfs2_refcounted_xattr_delete_need(struct inode *inode,
                         * one will split a refcount rec, so totally we need
                         * clusters * 2 new refcount rec.
                         */
-                       if (le64_to_cpu(rb->rf_records.rl_used) + clusters * 2 >
+                       if (le16_to_cpu(rb->rf_records.rl_used) + clusters * 2 >
                            le16_to_cpu(rb->rf_records.rl_count))
                                ref_blocks++;
 
index ba5d97e4a73e8a43e64fc3cfa55fb9b97d4ec6a5..f169da4624fd07c5964c3d24d3b65e8a0dcd5ed7 100644 (file)
@@ -600,7 +600,7 @@ static void ocfs2_bg_alloc_cleanup(handle_t *handle,
                ret = ocfs2_free_clusters(handle, cluster_ac->ac_inode,
                                          cluster_ac->ac_bh,
                                          le64_to_cpu(rec->e_blkno),
-                                         le32_to_cpu(rec->e_leaf_clusters));
+                                         le16_to_cpu(rec->e_leaf_clusters));
                if (ret)
                        mlog_errno(ret);
                /* Try all the clusters to free */
@@ -1628,7 +1628,7 @@ static int ocfs2_bg_discontig_fix_by_rec(struct ocfs2_suballoc_result *res,
 {
        unsigned int bpc = le16_to_cpu(cl->cl_bpc);
        unsigned int bitoff = le32_to_cpu(rec->e_cpos) * bpc;
-       unsigned int bitcount = le32_to_cpu(rec->e_leaf_clusters) * bpc;
+       unsigned int bitcount = le16_to_cpu(rec->e_leaf_clusters) * bpc;
 
        if (res->sr_bit_offset < bitoff)
                return 0;
index 8ba2c9460b28fb90bfee024aa8f73601f6c4cf68..8f2ab8fef929f42b81f3d9a75c564b42455dc06e 100644 (file)
@@ -593,7 +593,7 @@ struct fuse_dirent {
        __u64   off;
        __u32   namelen;
        __u32   type;
-       char name[0];
+       char name[];
 };
 
 #define FUSE_NAME_OFFSET offsetof(struct fuse_dirent, name)
index 2463b61003336b0f176b5ed851aa8776a5202697..1f90de0cfdbe7ed344fccdf9eb04e774c5493adc 100644 (file)
@@ -666,23 +666,11 @@ struct twl4030_codec_data {
        unsigned int check_defaults:1;
        unsigned int reset_registers:1;
        unsigned int hs_extmute:1;
-       u16 hs_left_step;
-       u16 hs_right_step;
-       u16 hf_left_step;
-       u16 hf_right_step;
        void (*set_hs_extmute)(int mute);
 };
 
 struct twl4030_vibra_data {
        unsigned int    coexist;
-
-       /* twl6040 */
-       unsigned int vibldrv_res;       /* left driver resistance */
-       unsigned int vibrdrv_res;       /* right driver resistance */
-       unsigned int viblmotor_res;     /* left motor resistance */
-       unsigned int vibrmotor_res;     /* right motor resistance */
-       int vddvibl_uV;                 /* VDDVIBL volt, set 0 for fixed reg */
-       int vddvibr_uV;                 /* VDDVIBR volt, set 0 for fixed reg */
 };
 
 struct twl4030_audio_data {
index 665a260c7e09948fa3b5e3516efca2890edef840..72cbf08d45fbc878d5198eda807b12dbdffa6268 100644 (file)
@@ -596,6 +596,7 @@ void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id);
 
 #ifdef CONFIG_IOMMU_API
 int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot);
+void kvm_iommu_unmap_pages(struct kvm *kvm, struct kvm_memory_slot *slot);
 int kvm_iommu_map_guest(struct kvm *kvm);
 int kvm_iommu_unmap_guest(struct kvm *kvm);
 int kvm_assign_device(struct kvm *kvm,
@@ -609,6 +610,11 @@ static inline int kvm_iommu_map_pages(struct kvm *kvm,
        return 0;
 }
 
+static inline void kvm_iommu_unmap_pages(struct kvm *kvm,
+                                        struct kvm_memory_slot *slot)
+{
+}
+
 static inline int kvm_iommu_map_guest(struct kvm *kvm)
 {
        return -ENODEV;
index 9890687f582de0c36cdbcc56cf252a381e82e8ee..5a049dfaf1533174d7293810b132128c5e3f2121 100644 (file)
@@ -8,41 +8,14 @@
 #ifndef __MFD_DB5500_PRCMU_H
 #define __MFD_DB5500_PRCMU_H
 
-#ifdef CONFIG_MFD_DB5500_PRCMU
-
-void db5500_prcmu_early_init(void);
-int db5500_prcmu_set_epod(u16 epod_id, u8 epod_state);
-int db5500_prcmu_set_display_clocks(void);
-int db5500_prcmu_disable_dsipll(void);
-int db5500_prcmu_enable_dsipll(void);
-int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size);
-int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size);
-void db5500_prcmu_enable_wakeups(u32 wakeups);
-int db5500_prcmu_request_clock(u8 clock, bool enable);
-void db5500_prcmu_config_abb_event_readout(u32 abb_events);
-void db5500_prcmu_get_abb_event_buffer(void __iomem **buf);
-int prcmu_resetout(u8 resoutn, u8 state);
-int db5500_prcmu_set_power_state(u8 state, bool keep_ulp_clk,
-       bool keep_ap_pll);
-int db5500_prcmu_config_esram0_deep_sleep(u8 state);
-void db5500_prcmu_system_reset(u16 reset_code);
-u16 db5500_prcmu_get_reset_code(void);
-bool db5500_prcmu_is_ac_wake_requested(void);
-int db5500_prcmu_set_arm_opp(u8 opp);
-int db5500_prcmu_get_arm_opp(void);
-
-#else /* !CONFIG_UX500_SOC_DB5500 */
-
-static inline void db5500_prcmu_early_init(void) {}
-
-static inline int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size)
+static inline int prcmu_resetout(u8 resoutn, u8 state)
 {
-       return -ENOSYS;
+       return 0;
 }
 
-static inline int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size)
+static inline int db5500_prcmu_set_epod(u16 epod_id, u8 epod_state)
 {
-       return -ENOSYS;
+       return 0;
 }
 
 static inline int db5500_prcmu_request_clock(u8 clock, bool enable)
@@ -50,69 +23,82 @@ static inline int db5500_prcmu_request_clock(u8 clock, bool enable)
        return 0;
 }
 
-static inline int db5500_prcmu_set_display_clocks(void)
+static inline int db5500_prcmu_set_power_state(u8 state, bool keep_ulp_clk,
+       bool keep_ap_pll)
 {
        return 0;
 }
 
-static inline int db5500_prcmu_disable_dsipll(void)
+static inline int db5500_prcmu_config_esram0_deep_sleep(u8 state)
 {
        return 0;
 }
 
-static inline int db5500_prcmu_enable_dsipll(void)
+static inline u16 db5500_prcmu_get_reset_code(void)
 {
        return 0;
 }
 
-static inline int db5500_prcmu_config_esram0_deep_sleep(u8 state)
+static inline bool db5500_prcmu_is_ac_wake_requested(void)
 {
        return 0;
 }
 
-static inline void db5500_prcmu_enable_wakeups(u32 wakeups) {}
-
-static inline int prcmu_resetout(u8 resoutn, u8 state)
+static inline int db5500_prcmu_set_arm_opp(u8 opp)
 {
        return 0;
 }
 
-static inline int db5500_prcmu_set_epod(u16 epod_id, u8 epod_state)
+static inline int db5500_prcmu_get_arm_opp(void)
 {
        return 0;
 }
 
-static inline void db5500_prcmu_get_abb_event_buffer(void __iomem **buf) {}
 static inline void db5500_prcmu_config_abb_event_readout(u32 abb_events) {}
 
-static inline int db5500_prcmu_set_power_state(u8 state, bool keep_ulp_clk,
-       bool keep_ap_pll)
-{
-       return 0;
-}
+static inline void db5500_prcmu_get_abb_event_buffer(void __iomem **buf) {}
 
 static inline void db5500_prcmu_system_reset(u16 reset_code) {}
 
-static inline u16 db5500_prcmu_get_reset_code(void)
+static inline void db5500_prcmu_enable_wakeups(u32 wakeups) {}
+
+#ifdef CONFIG_MFD_DB5500_PRCMU
+
+void db5500_prcmu_early_init(void);
+int db5500_prcmu_set_display_clocks(void);
+int db5500_prcmu_disable_dsipll(void);
+int db5500_prcmu_enable_dsipll(void);
+int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size);
+int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size);
+
+#else /* !CONFIG_UX500_SOC_DB5500 */
+
+static inline void db5500_prcmu_early_init(void) {}
+
+static inline int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size)
 {
-       return 0;
+       return -ENOSYS;
 }
 
-static inline bool db5500_prcmu_is_ac_wake_requested(void)
+static inline int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size)
 {
-       return 0;
+       return -ENOSYS;
 }
 
-static inline int db5500_prcmu_set_arm_opp(u8 opp)
+static inline int db5500_prcmu_set_display_clocks(void)
 {
        return 0;
 }
 
-static inline int db5500_prcmu_get_arm_opp(void)
+static inline int db5500_prcmu_disable_dsipll(void)
 {
        return 0;
 }
 
+static inline int db5500_prcmu_enable_dsipll(void)
+{
+       return 0;
+}
 
 #endif /* CONFIG_MFD_DB5500_PRCMU */
 
index a2c61609d21dbf6ab5ffe386e2721e58ac388ffe..0b64b19d81abf9e89e3d609f020e10e2ac9952b6 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <linux/mutex.h>
 #include <linux/types.h>
+#include <linux/regmap.h>
 
 #define RC5T583_MAX_REGS               0xF8
 
@@ -279,14 +280,44 @@ struct rc5t583_platform_data {
        bool            enable_shutdown;
 };
 
-int rc5t583_write(struct device *dev, u8 reg, uint8_t val);
-int rc5t583_read(struct device *dev, uint8_t reg, uint8_t *val);
-int rc5t583_set_bits(struct device *dev, unsigned int reg,
-               unsigned int bit_mask);
-int rc5t583_clear_bits(struct device *dev, unsigned int reg,
-               unsigned int bit_mask);
-int rc5t583_update(struct device *dev, unsigned int reg,
-               unsigned int val, unsigned int mask);
+static inline int rc5t583_write(struct device *dev, uint8_t reg, uint8_t val)
+{
+       struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
+       return regmap_write(rc5t583->regmap, reg, val);
+}
+
+static inline int rc5t583_read(struct device *dev, uint8_t reg, uint8_t *val)
+{
+       struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
+       unsigned int ival;
+       int ret;
+       ret = regmap_read(rc5t583->regmap, reg, &ival);
+       if (!ret)
+               *val = (uint8_t)ival;
+       return ret;
+}
+
+static inline int rc5t583_set_bits(struct device *dev, unsigned int reg,
+                       unsigned int bit_mask)
+{
+       struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
+       return regmap_update_bits(rc5t583->regmap, reg, bit_mask, bit_mask);
+}
+
+static inline int rc5t583_clear_bits(struct device *dev, unsigned int reg,
+                       unsigned int bit_mask)
+{
+       struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
+       return regmap_update_bits(rc5t583->regmap, reg, bit_mask, 0);
+}
+
+static inline int rc5t583_update(struct device *dev, unsigned int reg,
+               unsigned int val, unsigned int mask)
+{
+       struct rc5t583 *rc5t583 = dev_get_drvdata(dev);
+       return regmap_update_bits(rc5t583->regmap, reg, mask, val);
+}
+
 int rc5t583_ext_power_req_config(struct device *dev, int deepsleep_id,
        int ext_pwr_req, int deepsleep_slot_nr);
 int rc5t583_irq_init(struct rc5t583 *rc5t583, int irq, int irq_base);
index 9bc9ac651dad9bf2be544961c18e06fd1bfbd119..b15b5f03f5c44c74473f30e46411876000bf5863 100644 (file)
 #define TWL6040_SYSCLK_SEL_LPPLL       0
 #define TWL6040_SYSCLK_SEL_HPPLL       1
 
+struct twl6040_codec_data {
+       u16 hs_left_step;
+       u16 hs_right_step;
+       u16 hf_left_step;
+       u16 hf_right_step;
+};
+
+struct twl6040_vibra_data {
+       unsigned int vibldrv_res;       /* left driver resistance */
+       unsigned int vibrdrv_res;       /* right driver resistance */
+       unsigned int viblmotor_res;     /* left motor resistance */
+       unsigned int vibrmotor_res;     /* right motor resistance */
+       int vddvibl_uV;                 /* VDDVIBL volt, set 0 for fixed reg */
+       int vddvibr_uV;                 /* VDDVIBR volt, set 0 for fixed reg */
+};
+
+struct twl6040_platform_data {
+       int audpwron_gpio;      /* audio power-on gpio */
+       unsigned int irq_base;
+
+       struct twl6040_codec_data *codec;
+       struct twl6040_vibra_data *vibra;
+};
+
+struct regmap;
+
 struct twl6040 {
        struct device *dev;
+       struct regmap *regmap;
        struct mutex mutex;
        struct mutex io_mutex;
        struct mutex irq_mutex;
index d8738a464b94a71822f191bdd45bcac29b01814c..74aa71bea1e4ff6bf0bd7a43dfdff37c870438ee 100644 (file)
@@ -1393,29 +1393,20 @@ extern int install_special_mapping(struct mm_struct *mm,
 
 extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
 
-extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
-       unsigned long len, unsigned long prot,
-       unsigned long flag, unsigned long pgoff);
 extern unsigned long mmap_region(struct file *file, unsigned long addr,
        unsigned long len, unsigned long flags,
        vm_flags_t vm_flags, unsigned long pgoff);
-
-static inline unsigned long do_mmap(struct file *file, unsigned long addr,
-       unsigned long len, unsigned long prot,
-       unsigned long flag, unsigned long offset)
-{
-       unsigned long ret = -EINVAL;
-       if ((offset + PAGE_ALIGN(len)) < offset)
-               goto out;
-       if (!(offset & ~PAGE_MASK))
-               ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
-out:
-       return ret;
-}
-
+extern unsigned long do_mmap(struct file *, unsigned long,
+        unsigned long, unsigned long,
+        unsigned long, unsigned long);
 extern int do_munmap(struct mm_struct *, unsigned long, size_t);
 
-extern unsigned long do_brk(unsigned long, unsigned long);
+/* These take the mm semaphore themselves */
+extern unsigned long vm_brk(unsigned long, unsigned long);
+extern int vm_munmap(unsigned long, size_t);
+extern unsigned long vm_mmap(struct file *, unsigned long,
+        unsigned long, unsigned long,
+        unsigned long, unsigned long);
 
 /* truncate.c */
 extern void truncate_inode_pages(struct address_space *, loff_t);
index 01beae78f07935e45d1a04ac544e8826ad90618a..629b823f88362b44001cf09dc1559d1e86780dad 100644 (file)
@@ -481,7 +481,7 @@ struct mmc_driver {
        struct device_driver drv;
        int (*probe)(struct mmc_card *);
        void (*remove)(struct mmc_card *);
-       int (*suspend)(struct mmc_card *, pm_message_t);
+       int (*suspend)(struct mmc_card *);
        int (*resume)(struct mmc_card *);
 };
 
index b8d4001212b30bbd94f7a8d47a3afe32e5dd229e..5b7d84ac954a2c7a5e0b7f19f3529bb01e1a981f 100644 (file)
@@ -1,3 +1,4 @@
+header-y += cld.h
 header-y += debug.h
 header-y += export.h
 header-y += nfsfh.h
index f67810f8f21b1e6468af6c61e044923c005e0da4..38ab3f46346ff4852eabc4e0bbfc3fc2d5e2e793 100644 (file)
@@ -94,6 +94,7 @@ struct usb_phy {
 
        struct usb_otg          *otg;
 
+       struct device           *io_dev;
        struct usb_phy_io_ops   *io_ops;
        void __iomem            *io_priv;
 
index 2f526627e4f575c50468b51015270c35d2179721..0c505361da197a9a46c8b2665af7b5520ad11974 100644 (file)
@@ -177,8 +177,8 @@ int mpi_rshift(MPI x, MPI a, unsigned n)
  */
 int mpi_lshift_limbs(MPI a, unsigned int count)
 {
-       mpi_ptr_t ap = a->d;
-       int n = a->nlimbs;
+       const int n = a->nlimbs;
+       mpi_ptr_t ap;
        int i;
 
        if (!count || !n)
@@ -187,6 +187,7 @@ int mpi_lshift_limbs(MPI a, unsigned int count)
        if (RESIZE_IF_NEEDED(a, n + count) < 0)
                return -ENOMEM;
 
+       ap = a->d;
        for (i = n - 1; i >= 0; i--)
                ap[i + count] = ap[i];
        for (i = 0; i < count; i++)
index 99f285599501482e8b48c77eb768a62981811cf6..a44eab3157f8dc4b25e686b643ccacbc8449e041 100644 (file)
@@ -330,6 +330,9 @@ static int __init_memblock memblock_add_region(struct memblock_type *type,
        phys_addr_t end = base + memblock_cap_size(base, &size);
        int i, nr_new;
 
+       if (!size)
+               return 0;
+
        /* special case for empty array */
        if (type->regions[0].size == 0) {
                WARN_ON(type->cnt != 1 || type->total_size);
@@ -430,6 +433,9 @@ static int __init_memblock memblock_isolate_range(struct memblock_type *type,
 
        *start_rgn = *end_rgn = 0;
 
+       if (!size)
+               return 0;
+
        /* we'll create at most two more regions */
        while (type->cnt + 2 > type->max)
                if (memblock_double_array(type) < 0)
@@ -514,7 +520,6 @@ int __init_memblock memblock_reserve(phys_addr_t base, phys_addr_t size)
                     (unsigned long long)base,
                     (unsigned long long)base + size,
                     (void *)_RET_IP_);
-       BUG_ON(0 == size);
 
        return memblock_add_region(_rgn, base, size, MAX_NUMNODES);
 }
index a7165a60d0a7d4a688270d6cfc14f80b9af08dd5..b868def9bcc1e1f20c05406b1e9b90e0eae5d182 100644 (file)
@@ -3392,6 +3392,7 @@ void mem_cgroup_replace_page_cache(struct page *oldpage,
         * the newpage may be on LRU(or pagevec for LRU) already. We lock
         * LRU while we overwrite pc->mem_cgroup.
         */
+       pc = lookup_page_cgroup(newpage);
        __mem_cgroup_commit_charge(memcg, newpage, 1, pc, type, true);
 }
 
index a7bf6a31c9f62be11cb8e5819322565b7cf2c266..848ef52d96031f5061bc86582aa0120ccd0394e8 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -240,6 +240,8 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
        return next;
 }
 
+static unsigned long do_brk(unsigned long addr, unsigned long len);
+
 SYSCALL_DEFINE1(brk, unsigned long, brk)
 {
        unsigned long rlim, retval;
@@ -951,7 +953,7 @@ static inline unsigned long round_hint_to_min(unsigned long hint)
  * The caller must hold down_write(&current->mm->mmap_sem).
  */
 
-unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
+static unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
                        unsigned long len, unsigned long prot,
                        unsigned long flags, unsigned long pgoff)
 {
@@ -1087,7 +1089,32 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
 
        return mmap_region(file, addr, len, flags, vm_flags, pgoff);
 }
-EXPORT_SYMBOL(do_mmap_pgoff);
+
+unsigned long do_mmap(struct file *file, unsigned long addr,
+       unsigned long len, unsigned long prot,
+       unsigned long flag, unsigned long offset)
+{
+       if (unlikely(offset + PAGE_ALIGN(len) < offset))
+               return -EINVAL;
+       if (unlikely(offset & ~PAGE_MASK))
+               return -EINVAL;
+       return do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
+}
+EXPORT_SYMBOL(do_mmap);
+
+unsigned long vm_mmap(struct file *file, unsigned long addr,
+       unsigned long len, unsigned long prot,
+       unsigned long flag, unsigned long offset)
+{
+       unsigned long ret;
+       struct mm_struct *mm = current->mm;
+
+       down_write(&mm->mmap_sem);
+       ret = do_mmap(file, addr, len, prot, flag, offset);
+       up_write(&mm->mmap_sem);
+       return ret;
+}
+EXPORT_SYMBOL(vm_mmap);
 
 SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len,
                unsigned long, prot, unsigned long, flags,
@@ -2105,21 +2132,25 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
 
        return 0;
 }
-
 EXPORT_SYMBOL(do_munmap);
 
-SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len)
+int vm_munmap(unsigned long start, size_t len)
 {
        int ret;
        struct mm_struct *mm = current->mm;
 
-       profile_munmap(addr);
-
        down_write(&mm->mmap_sem);
-       ret = do_munmap(mm, addr, len);
+       ret = do_munmap(mm, start, len);
        up_write(&mm->mmap_sem);
        return ret;
 }
+EXPORT_SYMBOL(vm_munmap);
+
+SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len)
+{
+       profile_munmap(addr);
+       return vm_munmap(addr, len);
+}
 
 static inline void verify_mm_writelocked(struct mm_struct *mm)
 {
@@ -2136,7 +2167,7 @@ static inline void verify_mm_writelocked(struct mm_struct *mm)
  *  anonymous maps.  eventually we may be able to do some
  *  brk-specific accounting here.
  */
-unsigned long do_brk(unsigned long addr, unsigned long len)
+static unsigned long do_brk(unsigned long addr, unsigned long len)
 {
        struct mm_struct * mm = current->mm;
        struct vm_area_struct * vma, * prev;
@@ -2232,7 +2263,17 @@ out:
        return addr;
 }
 
-EXPORT_SYMBOL(do_brk);
+unsigned long vm_brk(unsigned long addr, unsigned long len)
+{
+       struct mm_struct *mm = current->mm;
+       unsigned long ret;
+
+       down_write(&mm->mmap_sem);
+       ret = do_brk(addr, len);
+       up_write(&mm->mmap_sem);
+       return ret;
+}
+EXPORT_SYMBOL(vm_brk);
 
 /* Release all mmaps. */
 void exit_mmap(struct mm_struct *mm)
index f59e170fceb4e01046a339d8878f5030dea8a4f9..bb8f4f004a82ce57abb0653a9a8ed72d533f5c45 100644 (file)
@@ -1233,7 +1233,7 @@ enomem:
 /*
  * handle mapping creation for uClinux
  */
-unsigned long do_mmap_pgoff(struct file *file,
+static unsigned long do_mmap_pgoff(struct file *file,
                            unsigned long addr,
                            unsigned long len,
                            unsigned long prot,
@@ -1470,7 +1470,32 @@ error_getting_region:
        show_free_areas(0);
        return -ENOMEM;
 }
-EXPORT_SYMBOL(do_mmap_pgoff);
+
+unsigned long do_mmap(struct file *file, unsigned long addr,
+       unsigned long len, unsigned long prot,
+       unsigned long flag, unsigned long offset)
+{
+       if (unlikely(offset + PAGE_ALIGN(len) < offset))
+               return -EINVAL;
+       if (unlikely(offset & ~PAGE_MASK))
+               return -EINVAL;
+       return do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
+}
+EXPORT_SYMBOL(do_mmap);
+
+unsigned long vm_mmap(struct file *file, unsigned long addr,
+       unsigned long len, unsigned long prot,
+       unsigned long flag, unsigned long offset)
+{
+       unsigned long ret;
+       struct mm_struct *mm = current->mm;
+
+       down_write(&mm->mmap_sem);
+       ret = do_mmap(file, addr, len, prot, flag, offset);
+       up_write(&mm->mmap_sem);
+       return ret;
+}
+EXPORT_SYMBOL(vm_mmap);
 
 SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len,
                unsigned long, prot, unsigned long, flags,
@@ -1709,16 +1734,22 @@ erase_whole_vma:
 }
 EXPORT_SYMBOL(do_munmap);
 
-SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len)
+int vm_munmap(unsigned long addr, size_t len)
 {
-       int ret;
        struct mm_struct *mm = current->mm;
+       int ret;
 
        down_write(&mm->mmap_sem);
        ret = do_munmap(mm, addr, len);
        up_write(&mm->mmap_sem);
        return ret;
 }
+EXPORT_SYMBOL(vm_munmap);
+
+SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len)
+{
+       return vm_munmap(addr, len);
+}
 
 /*
  * release all the mappings made in a process's VM space
@@ -1744,7 +1775,7 @@ void exit_mmap(struct mm_struct *mm)
        kleave("");
 }
 
-unsigned long do_brk(unsigned long addr, unsigned long len)
+unsigned long vm_brk(unsigned long addr, unsigned long len)
 {
        return -ENOMEM;
 }
index de639eeeed506b76b54220e7e7f86ed879af02a1..faea0ec612bfed2932ca5dc25868fe00888a5afc 100755 (executable)
@@ -1869,12 +1869,6 @@ sub process {
                            "No space is necessary after a cast\n" . $hereprev);
                }
 
-               if ($rawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
-                   $prevrawline =~ /^\+[ \t]*$/) {
-                       CHK("BLOCK_COMMENT_STYLE",
-                           "Don't begin block comments with only a /* line, use /* comment...\n" . $hereprev);
-               }
-
 # check for spaces at the beginning of a line.
 # Exceptions:
 #  1) within comments
index 17a5798c29dae96a19a5804b90512390c1df332c..7a2d372f4885a479bff7c97140b45124950c9e19 100644 (file)
@@ -12,8 +12,8 @@
 BCJ=
 LZMA2OPTS=
 
-case $ARCH in
-       x86|x86_64)     BCJ=--x86 ;;
+case $SRCARCH in
+       x86)            BCJ=--x86 ;;
        powerpc)        BCJ=--powerpc ;;
        ia64)           BCJ=--ia64; LZMA2OPTS=pb=4 ;;
        arm)            BCJ=--arm ;;
index 0cf4b53480a778ffeacd46149aa785c63db81c07..71a166a05975bfef1ea92f68473dc147063b4a7b 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/securebits.h>
 #include <linux/user_namespace.h>
 #include <linux/binfmts.h>
+#include <linux/personality.h>
 
 /*
  * If a non-root user executes a setuid-root binary in
@@ -505,6 +506,11 @@ int cap_bprm_set_creds(struct linux_binprm *bprm)
        }
 skip:
 
+       /* if we have fs caps, clear dangerous personality flags */
+       if (!cap_issubset(new->cap_permitted, old->cap_permitted))
+               bprm->per_clear |= PER_CLEAR_ON_SETID;
+
+
        /* Don't let someone trace a set[ug]id/setpcap binary with the revised
         * credentials unless they have the appropriate permit
         */
index 10056f2f6df3624284c70a3e23678d020dab191c..45c32f074166b270fe5434cfcc24ffa076f8b7a3 100644 (file)
@@ -3640,8 +3640,38 @@ struct security_operations smack_ops = {
 };
 
 
-static __init void init_smack_know_list(void)
+static __init void init_smack_known_list(void)
 {
+       /*
+        * Initialize CIPSO locks
+        */
+       spin_lock_init(&smack_known_huh.smk_cipsolock);
+       spin_lock_init(&smack_known_hat.smk_cipsolock);
+       spin_lock_init(&smack_known_star.smk_cipsolock);
+       spin_lock_init(&smack_known_floor.smk_cipsolock);
+       spin_lock_init(&smack_known_invalid.smk_cipsolock);
+       spin_lock_init(&smack_known_web.smk_cipsolock);
+       /*
+        * Initialize rule list locks
+        */
+       mutex_init(&smack_known_huh.smk_rules_lock);
+       mutex_init(&smack_known_hat.smk_rules_lock);
+       mutex_init(&smack_known_floor.smk_rules_lock);
+       mutex_init(&smack_known_star.smk_rules_lock);
+       mutex_init(&smack_known_invalid.smk_rules_lock);
+       mutex_init(&smack_known_web.smk_rules_lock);
+       /*
+        * Initialize rule lists
+        */
+       INIT_LIST_HEAD(&smack_known_huh.smk_rules);
+       INIT_LIST_HEAD(&smack_known_hat.smk_rules);
+       INIT_LIST_HEAD(&smack_known_star.smk_rules);
+       INIT_LIST_HEAD(&smack_known_floor.smk_rules);
+       INIT_LIST_HEAD(&smack_known_invalid.smk_rules);
+       INIT_LIST_HEAD(&smack_known_web.smk_rules);
+       /*
+        * Create the known labels list
+        */
        list_add(&smack_known_huh.list, &smack_known_list);
        list_add(&smack_known_hat.list, &smack_known_list);
        list_add(&smack_known_star.list, &smack_known_list);
@@ -3676,16 +3706,8 @@ static __init int smack_init(void)
        cred = (struct cred *) current->cred;
        cred->security = tsp;
 
-       /* initialize the smack_know_list */
-       init_smack_know_list();
-       /*
-        * Initialize locks
-        */
-       spin_lock_init(&smack_known_huh.smk_cipsolock);
-       spin_lock_init(&smack_known_hat.smk_cipsolock);
-       spin_lock_init(&smack_known_star.smk_cipsolock);
-       spin_lock_init(&smack_known_floor.smk_cipsolock);
-       spin_lock_init(&smack_known_invalid.smk_cipsolock);
+       /* initialize the smack_known_list */
+       init_smack_known_list();
 
        /*
         * Register with LSM
index 5c32f36ff70618dfb08e3040c94060238dfa44da..038811cb7e625eb48e331c351d079232248dfb83 100644 (file)
@@ -1614,20 +1614,6 @@ static int __init init_smk_fs(void)
        smk_cipso_doi();
        smk_unlbl_ambient(NULL);
 
-       mutex_init(&smack_known_floor.smk_rules_lock);
-       mutex_init(&smack_known_hat.smk_rules_lock);
-       mutex_init(&smack_known_huh.smk_rules_lock);
-       mutex_init(&smack_known_invalid.smk_rules_lock);
-       mutex_init(&smack_known_star.smk_rules_lock);
-       mutex_init(&smack_known_web.smk_rules_lock);
-
-       INIT_LIST_HEAD(&smack_known_floor.smk_rules);
-       INIT_LIST_HEAD(&smack_known_hat.smk_rules);
-       INIT_LIST_HEAD(&smack_known_huh.smk_rules);
-       INIT_LIST_HEAD(&smack_known_invalid.smk_rules);
-       INIT_LIST_HEAD(&smack_known_star.smk_rules);
-       INIT_LIST_HEAD(&smack_known_web.smk_rules);
-
        return err;
 }
 
index 14a286a7bf2b01686e450b2a3bc258df59f24e21..857586135d1820ee9310b2794716f4aef2c903eb 100644 (file)
@@ -419,6 +419,7 @@ EXPORT_SYMBOL(snd_ctl_make_virtual_master);
  * snd_ctl_add_vmaster_hook - Add a hook to a vmaster control
  * @kcontrol: vmaster kctl element
  * @hook: the hook function
+ * @private_data: the private_data pointer to be saved
  *
  * Adds the given hook to the vmaster control element so that it's called
  * at each time when the value is changed.
index bdd0857b88710bb4fb2489766bcb4ea3fa26b79e..7ffc182e084478fac3e7ca4cf98523d4e68867d5 100644 (file)
@@ -38,4 +38,4 @@ static int __init alsa_sound_last_init(void)
        return 0;
 }
 
-__initcall(alsa_sound_last_init);
+late_initcall_sync(alsa_sound_last_init);
index a36488d94aaad9521f1b8368ad3b35c947591f07..d906c5b74cf0e7b047a4e702c71ba8b6d0e5d5de 100644 (file)
@@ -3971,9 +3971,14 @@ static void cx_auto_init_output(struct hda_codec *codec)
        int i;
 
        mute_outputs(codec, spec->multiout.num_dacs, spec->multiout.dac_nids);
-       for (i = 0; i < cfg->hp_outs; i++)
+       for (i = 0; i < cfg->hp_outs; i++) {
+               unsigned int val = PIN_OUT;
+               if (snd_hda_query_pin_caps(codec, cfg->hp_pins[i]) &
+                   AC_PINCAP_HP_DRV)
+                       val |= AC_PINCTL_HP_EN;
                snd_hda_codec_write(codec, cfg->hp_pins[i], 0,
-                                   AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
+                                   AC_VERB_SET_PIN_WIDGET_CONTROL, val);
+       }
        mute_outputs(codec, cfg->hp_outs, cfg->hp_pins);
        mute_outputs(codec, cfg->line_outs, cfg->line_out_pins);
        mute_outputs(codec, cfg->speaker_outs, cfg->speaker_pins);
@@ -4391,8 +4396,10 @@ static void apply_pin_fixup(struct hda_codec *codec,
 
 enum {
        CXT_PINCFG_LENOVO_X200,
+       CXT_PINCFG_LENOVO_TP410,
 };
 
+/* ThinkPad X200 & co with cxt5051 */
 static const struct cxt_pincfg cxt_pincfg_lenovo_x200[] = {
        { 0x16, 0x042140ff }, /* HP (seq# overridden) */
        { 0x17, 0x21a11000 }, /* dock-mic */
@@ -4401,15 +4408,33 @@ static const struct cxt_pincfg cxt_pincfg_lenovo_x200[] = {
        {}
 };
 
+/* ThinkPad 410/420/510/520, X201 & co with cxt5066 */
+static const struct cxt_pincfg cxt_pincfg_lenovo_tp410[] = {
+       { 0x19, 0x042110ff }, /* HP (seq# overridden) */
+       { 0x1a, 0x21a190f0 }, /* dock-mic */
+       { 0x1c, 0x212140ff }, /* dock-HP */
+       {}
+};
+
 static const struct cxt_pincfg *cxt_pincfg_tbl[] = {
        [CXT_PINCFG_LENOVO_X200] = cxt_pincfg_lenovo_x200,
+       [CXT_PINCFG_LENOVO_TP410] = cxt_pincfg_lenovo_tp410,
 };
 
-static const struct snd_pci_quirk cxt_fixups[] = {
+static const struct snd_pci_quirk cxt5051_fixups[] = {
        SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT_PINCFG_LENOVO_X200),
        {}
 };
 
+static const struct snd_pci_quirk cxt5066_fixups[] = {
+       SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410),
+       SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo T410", CXT_PINCFG_LENOVO_TP410),
+       SND_PCI_QUIRK(0x17aa, 0x215f, "Lenovo T510", CXT_PINCFG_LENOVO_TP410),
+       SND_PCI_QUIRK(0x17aa, 0x21ce, "Lenovo T420", CXT_PINCFG_LENOVO_TP410),
+       SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520", CXT_PINCFG_LENOVO_TP410),
+       {}
+};
+
 /* add "fake" mute amp-caps to DACs on cx5051 so that mixer mute switches
  * can be created (bko#42825)
  */
@@ -4446,13 +4471,13 @@ static int patch_conexant_auto(struct hda_codec *codec)
        case 0x14f15051:
                add_cx5051_fake_mutes(codec);
                codec->pin_amp_workaround = 1;
+               apply_pin_fixup(codec, cxt5051_fixups, cxt_pincfg_tbl);
                break;
        default:
                codec->pin_amp_workaround = 1;
+               apply_pin_fixup(codec, cxt5066_fixups, cxt_pincfg_tbl);
        }
 
-       apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl);
-
        /* Show mute-led control only on HP laptops
         * This is a sort of white-list: on HP laptops, EAPD corresponds
         * only to the mute-LED without actualy amp function.  Meanwhile,
index 2508f8109f11be254c7e23df9a722ec3d5d3e015..e65e3543305568a9ab910057502ba583f656e724 100644 (file)
@@ -1445,6 +1445,13 @@ enum {
        ALC_FIXUP_ACT_BUILD,
 };
 
+static void alc_apply_pincfgs(struct hda_codec *codec,
+                             const struct alc_pincfg *cfg)
+{
+       for (; cfg->nid; cfg++)
+               snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
+}
+
 static void alc_apply_fixup(struct hda_codec *codec, int action)
 {
        struct alc_spec *spec = codec->spec;
@@ -1478,9 +1485,7 @@ static void alc_apply_fixup(struct hda_codec *codec, int action)
                        snd_printdd(KERN_INFO "hda_codec: %s: "
                                    "Apply pincfg for %s\n",
                                    codec->chip_name, modelname);
-                       for (; cfg->nid; cfg++)
-                               snd_hda_codec_set_pincfg(codec, cfg->nid,
-                                                        cfg->val);
+                       alc_apply_pincfgs(codec, cfg);
                        break;
                case ALC_FIXUP_VERBS:
                        if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs)
@@ -4861,6 +4866,7 @@ enum {
        ALC260_FIXUP_GPIO1_TOGGLE,
        ALC260_FIXUP_REPLACER,
        ALC260_FIXUP_HP_B1900,
+       ALC260_FIXUP_KN1,
 };
 
 static void alc260_gpio1_automute(struct hda_codec *codec)
@@ -4888,6 +4894,36 @@ static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
        }
 }
 
+static void alc260_fixup_kn1(struct hda_codec *codec,
+                            const struct alc_fixup *fix, int action)
+{
+       struct alc_spec *spec = codec->spec;
+       static const struct alc_pincfg pincfgs[] = {
+               { 0x0f, 0x02214000 }, /* HP/speaker */
+               { 0x12, 0x90a60160 }, /* int mic */
+               { 0x13, 0x02a19000 }, /* ext mic */
+               { 0x18, 0x01446000 }, /* SPDIF out */
+               /* disable bogus I/O pins */
+               { 0x10, 0x411111f0 },
+               { 0x11, 0x411111f0 },
+               { 0x14, 0x411111f0 },
+               { 0x15, 0x411111f0 },
+               { 0x16, 0x411111f0 },
+               { 0x17, 0x411111f0 },
+               { 0x19, 0x411111f0 },
+               { }
+       };
+
+       switch (action) {
+       case ALC_FIXUP_ACT_PRE_PROBE:
+               alc_apply_pincfgs(codec, pincfgs);
+               break;
+       case ALC_FIXUP_ACT_PROBE:
+               spec->init_amp = ALC_INIT_NONE;
+               break;
+       }
+}
+
 static const struct alc_fixup alc260_fixups[] = {
        [ALC260_FIXUP_HP_DC5750] = {
                .type = ALC_FIXUP_PINS,
@@ -4938,7 +4974,11 @@ static const struct alc_fixup alc260_fixups[] = {
                .v.func = alc260_fixup_gpio1_toggle,
                .chained = true,
                .chain_id = ALC260_FIXUP_COEF,
-       }
+       },
+       [ALC260_FIXUP_KN1] = {
+               .type = ALC_FIXUP_FUNC,
+               .v.func = alc260_fixup_kn1,
+       },
 };
 
 static const struct snd_pci_quirk alc260_fixup_tbl[] = {
@@ -4948,6 +4988,7 @@ static const struct snd_pci_quirk alc260_fixup_tbl[] = {
        SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750),
        SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900),
        SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1),
+       SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1),
        SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER),
        SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF),
        {}
index 33a9946b492cb333184b1a9405c11f553fc55566..4742cac26aa9b4058a58220897e45c2e826dc47d 100644 (file)
@@ -5063,12 +5063,11 @@ static void stac92xx_update_led_status(struct hda_codec *codec, int enabled)
        if (spec->gpio_led_polarity)
                muted = !muted;
 
-       /*polarity defines *not* muted state level*/
        if (!spec->vref_mute_led_nid) {
                if (muted)
-                       spec->gpio_data &= ~spec->gpio_led; /* orange */
+                       spec->gpio_data |= spec->gpio_led;
                else
-                       spec->gpio_data |= spec->gpio_led; /* white */
+                       spec->gpio_data &= ~spec->gpio_led;
                stac_gpio_set(codec, spec->gpio_mask,
                                spec->gpio_dir, spec->gpio_data);
        } else {
index 6508e8b790bb16076d3539261db7df43032438e4..59d8efaa17e96eec921774fad61fd149884f2241 100644 (file)
@@ -57,7 +57,7 @@ config SND_SOC_ALL_CODECS
        select SND_SOC_TPA6130A2 if I2C
        select SND_SOC_TLV320DAC33 if I2C
        select SND_SOC_TWL4030 if TWL4030_CORE
-       select SND_SOC_TWL6040 if TWL4030_CORE
+       select SND_SOC_TWL6040 if TWL6040_CORE
        select SND_SOC_UDA134X
        select SND_SOC_UDA1380 if I2C
        select SND_SOC_WL1273 if MFD_WL1273_CORE
@@ -276,7 +276,6 @@ config SND_SOC_TWL4030
        tristate
 
 config SND_SOC_TWL6040
-       select TWL6040_CORE
        tristate
 
 config SND_SOC_UDA134X
index 2d8c6b825e57b9ecd17253c5de57432260ecdaab..dc7509b9d53aa27f4580c923bfe81b2baa7fbff6 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/pm.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
-#include <linux/i2c/twl.h>
 #include <linux/mfd/twl6040.h>
 
 #include <sound/core.h>
@@ -1528,7 +1527,7 @@ static int twl6040_resume(struct snd_soc_codec *codec)
 static int twl6040_probe(struct snd_soc_codec *codec)
 {
        struct twl6040_data *priv;
-       struct twl4030_codec_data *pdata = dev_get_platdata(codec->dev);
+       struct twl6040_codec_data *pdata = dev_get_platdata(codec->dev);
        struct platform_device *pdev = container_of(codec->dev,
                                                   struct platform_device, dev);
        int ret = 0;
index e00dd0b1139ca17144048a41148fb2a656b2db7c..deafbfaacdbf13644d72009ddeadd18c5eb81eea 100644 (file)
@@ -97,7 +97,7 @@ config SND_OMAP_SOC_SDP3430
 
 config SND_OMAP_SOC_OMAP_ABE_TWL6040
        tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec"
-       depends on TWL4030_CORE && SND_OMAP_SOC && ARCH_OMAP4
+       depends on TWL6040_CORE && SND_OMAP_SOC && ARCH_OMAP4
        select SND_OMAP_SOC_DMIC
        select SND_OMAP_SOC_MCPDM
        select SND_SOC_TWL6040
index 416684be0ad308a6df2a69d22f41409de05f7466..26b823b61aa175f2f0d8a475e6574a8615ae0e32 100644 (file)
@@ -19,3 +19,5 @@ TAGS
 cscope*
 config.mak
 config.mak.autogen
+*-bison.*
+*-flex.*
index 820371f10d1b1b96e1be9332d454f6ee053aaf34..03059e75665a267b39baa45b5f7e107557b96542 100644 (file)
@@ -237,21 +237,20 @@ export PERL_PATH
 FLEX = $(CROSS_COMPILE)flex
 BISON= $(CROSS_COMPILE)bison
 
-event-parser:
-       $(QUIET_BISON)$(BISON) -v util/parse-events.y -d -o $(OUTPUT)util/parse-events-bison.c
+$(OUTPUT)util/parse-events-flex.c: util/parse-events.l
        $(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/parse-events-flex.h -t util/parse-events.l > $(OUTPUT)util/parse-events-flex.c
 
-$(OUTPUT)util/parse-events-flex.c: event-parser
-$(OUTPUT)util/parse-events-bison.c: event-parser
+$(OUTPUT)util/parse-events-bison.c: util/parse-events.y
+       $(QUIET_BISON)$(BISON) -v util/parse-events.y -d -o $(OUTPUT)util/parse-events-bison.c
 
-pmu-parser:
-       $(QUIET_BISON)$(BISON) -v util/pmu.y -d -o $(OUTPUT)util/pmu-bison.c
+$(OUTPUT)util/pmu-flex.c: util/pmu.l
        $(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/pmu-flex.h -t util/pmu.l > $(OUTPUT)util/pmu-flex.c
 
-$(OUTPUT)util/pmu-flex.c: pmu-parser
-$(OUTPUT)util/pmu-bison.c: pmu-parser
+$(OUTPUT)util/pmu-bison.c: util/pmu.y
+       $(QUIET_BISON)$(BISON) -v util/pmu.y -d -o $(OUTPUT)util/pmu-bison.c
 
-$(OUTPUT)util/parse-events.o: event-parser pmu-parser
+$(OUTPUT)util/parse-events.o: $(OUTPUT)util/parse-events-flex.c $(OUTPUT)util/parse-events-bison.c
+$(OUTPUT)util/pmu.o: $(OUTPUT)util/pmu-flex.c $(OUTPUT)util/pmu-bison.c
 
 LIB_FILE=$(OUTPUT)libperf.a
 
@@ -527,7 +526,7 @@ else
 endif
 
 ifdef NO_GTK2
-       BASIC_CFLAGS += -DNO_GTK2
+       BASIC_CFLAGS += -DNO_GTK2_SUPPORT
 else
        FLAGS_GTK2=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(shell pkg-config --libs --cflags gtk+-2.0)
        ifneq ($(call try-cc,$(SOURCE_GTK2),$(FLAGS_GTK2)),y)
@@ -852,8 +851,6 @@ help:
        @echo '  html           - make html documentation'
        @echo '  info           - make GNU info documentation (access with info <foo>)'
        @echo '  pdf            - make pdf documentation'
-       @echo '  event-parser   - make event parser code'
-       @echo '  pmu-parser     - make pmu format parser code'
        @echo '  TAGS           - use etags to make tag information for source browsing'
        @echo '  tags           - use ctags to make tag information for source browsing'
        @echo '  cscope - use cscope to make interactive browsing database'
index 677e59d62a8dc3ae0475ab31d8c78acaeca50e51..95b6f8b6177a98e45bc295bf4096b753aab70696 100644 (file)
@@ -29,13 +29,14 @@ if [ ! -s $BUILDIDS ] ; then
 fi
 
 MANIFEST=$(mktemp /tmp/perf-archive-manifest.XXXXXX)
+PERF_BUILDID_LINKDIR=$(readlink -f $PERF_BUILDID_DIR)/
 
 cut -d ' ' -f 1 $BUILDIDS | \
 while read build_id ; do
        linkname=$PERF_BUILDID_DIR.build-id/${build_id:0:2}/${build_id:2}
        filename=$(readlink -f $linkname)
        echo ${linkname#$PERF_BUILDID_DIR} >> $MANIFEST
-       echo ${filename#$PERF_BUILDID_DIR} >> $MANIFEST
+       echo ${filename#$PERF_BUILDID_LINKDIR} >> $MANIFEST
 done
 
 tar cfj $PERF_DATA.tar.bz2 -C $PERF_BUILDID_DIR -T $MANIFEST
index 00923cda4d9c301c1741b7fc209226ffe54740b1..1efd3bee6336bd6f1052ee76684e25cd489fa163 100644 (file)
@@ -876,11 +876,11 @@ static int perf_session_deliver_event(struct perf_session *session,
                dump_sample(session, event, sample);
                if (evsel == NULL) {
                        ++session->hists.stats.nr_unknown_id;
-                       return -1;
+                       return 0;
                }
                if (machine == NULL) {
                        ++session->hists.stats.nr_unprocessable_samples;
-                       return -1;
+                       return 0;
                }
                return tool->sample(tool, event, sample, evsel, machine);
        case PERF_RECORD_MMAP:
index a457d2138f49ac8ed860507de8c9068566368889..e9fff9830bf0bf6f2229603516ebdd633996fd20 100644 (file)
@@ -240,9 +240,13 @@ int kvm_iommu_map_guest(struct kvm *kvm)
                return -ENODEV;
        }
 
+       mutex_lock(&kvm->slots_lock);
+
        kvm->arch.iommu_domain = iommu_domain_alloc(&pci_bus_type);
-       if (!kvm->arch.iommu_domain)
-               return -ENOMEM;
+       if (!kvm->arch.iommu_domain) {
+               r = -ENOMEM;
+               goto out_unlock;
+       }
 
        if (!allow_unsafe_assigned_interrupts &&
            !iommu_domain_has_cap(kvm->arch.iommu_domain,
@@ -253,17 +257,16 @@ int kvm_iommu_map_guest(struct kvm *kvm)
                       " module option.\n", __func__);
                iommu_domain_free(kvm->arch.iommu_domain);
                kvm->arch.iommu_domain = NULL;
-               return -EPERM;
+               r = -EPERM;
+               goto out_unlock;
        }
 
        r = kvm_iommu_map_memslots(kvm);
        if (r)
-               goto out_unmap;
-
-       return 0;
+               kvm_iommu_unmap_memslots(kvm);
 
-out_unmap:
-       kvm_iommu_unmap_memslots(kvm);
+out_unlock:
+       mutex_unlock(&kvm->slots_lock);
        return r;
 }
 
@@ -310,6 +313,11 @@ static void kvm_iommu_put_pages(struct kvm *kvm,
        }
 }
 
+void kvm_iommu_unmap_pages(struct kvm *kvm, struct kvm_memory_slot *slot)
+{
+       kvm_iommu_put_pages(kvm, slot->base_gfn, slot->npages);
+}
+
 static int kvm_iommu_unmap_memslots(struct kvm *kvm)
 {
        int idx;
@@ -320,7 +328,7 @@ static int kvm_iommu_unmap_memslots(struct kvm *kvm)
        slots = kvm_memslots(kvm);
 
        kvm_for_each_memslot(memslot, slots)
-               kvm_iommu_put_pages(kvm, memslot->base_gfn, memslot->npages);
+               kvm_iommu_unmap_pages(kvm, memslot);
 
        srcu_read_unlock(&kvm->srcu, idx);
 
@@ -335,7 +343,11 @@ int kvm_iommu_unmap_guest(struct kvm *kvm)
        if (!domain)
                return 0;
 
+       mutex_lock(&kvm->slots_lock);
        kvm_iommu_unmap_memslots(kvm);
+       kvm->arch.iommu_domain = NULL;
+       mutex_unlock(&kvm->slots_lock);
+
        iommu_domain_free(domain);
        return 0;
 }
index 42b73930a6de6b2210708aca55903f87a9bab459..9739b533ca2e6954f75c98fc1bb307e641aedf94 100644 (file)
@@ -808,12 +808,13 @@ int __kvm_set_memory_region(struct kvm *kvm,
        if (r)
                goto out_free;
 
-       /* map the pages in iommu page table */
+       /* map/unmap the pages in iommu page table */
        if (npages) {
                r = kvm_iommu_map_pages(kvm, &new);
                if (r)
                        goto out_free;
-       }
+       } else
+               kvm_iommu_unmap_pages(kvm, &old);
 
        r = -ENOMEM;
        slots = kmemdup(kvm->memslots, sizeof(struct kvm_memslots),