Merge tag 'backport/v3.14.24-ltsi-rc1/micrel-20141210' into backport/v3.14.24-ltsi...
authorSimon Horman <horms+renesas@verge.net.au>
Wed, 10 Dec 2014 04:54:00 +0000 (13:54 +0900)
committerSimon Horman <horms+renesas@verge.net.au>
Wed, 10 Dec 2014 04:54:00 +0000 (13:54 +0900)
536 files changed:
Documentation/.gitignore [deleted file]
Documentation/arm/SH-Mobile/.gitignore [new file with mode: 0644]
Documentation/arm/SH-Mobile/vrl4.c
Documentation/devicetree/bindings/ata/sata_rcar.txt
Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
Documentation/devicetree/bindings/i2c/trivial-devices.txt
Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
Documentation/devicetree/bindings/interrupt-controller/renesas,intc-irqpin.txt
Documentation/devicetree/bindings/mmc/tmio_mmc.txt
Documentation/devicetree/bindings/pci/pci-rcar-gen2.txt [new file with mode: 0644]
Documentation/devicetree/bindings/phy/rcar-gen2-phy.txt [new file with mode: 0644]
Documentation/devicetree/bindings/regulator/da9210.txt
Documentation/devicetree/bindings/sound/renesas,rsnd.txt
Documentation/devicetree/bindings/spi/sh-msiof.txt
Documentation/devicetree/bindings/spi/spi-rspi.txt
Documentation/devicetree/bindings/thermal/rcar-thermal.txt
Documentation/devicetree/bindings/timer/renesas,cmt.txt
Documentation/devicetree/bindings/timer/renesas,mtu2.txt
Documentation/devicetree/bindings/timer/renesas,tmu.txt
Documentation/devicetree/bindings/vendor-prefixes.txt
Documentation/driver-model/devres.txt
Documentation/filesystems/.gitignore [new file with mode: 0644]
Documentation/gpio/consumer.txt
Documentation/laptops/.gitignore [new file with mode: 0644]
Documentation/networking/timestamping/.gitignore
Documentation/phy.txt
Documentation/prctl/.gitignore [new file with mode: 0644]
Documentation/prctl/disable-tsc-ctxt-sw-stress-test.c
Documentation/prctl/disable-tsc-on-off-stress-test.c
Documentation/prctl/disable-tsc-test.c
Documentation/ptp/.gitignore [new file with mode: 0644]
Documentation/timers/.gitignore [new file with mode: 0644]
Documentation/vDSO/.gitignore [new file with mode: 0644]
Documentation/video4linux/.gitignore [deleted file]
MAINTAINERS
Makefile
arch/arm/Kconfig
arch/arm/Kconfig.debug
arch/arm/boot/compressed/head.S
arch/arm/boot/dts/Makefile
arch/arm/boot/dts/emev2-kzm9d.dts
arch/arm/boot/dts/emev2.dtsi
arch/arm/boot/dts/imx53-smd.dts
arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi [new file with mode: 0644]
arch/arm/boot/dts/r7s72100-genmai.dts
arch/arm/boot/dts/r7s72100.dtsi
arch/arm/boot/dts/r8a73a4-ape6evm-reference.dts
arch/arm/boot/dts/r8a73a4.dtsi
arch/arm/boot/dts/r8a7740-armadillo800eva-reference.dts [deleted file]
arch/arm/boot/dts/r8a7740-armadillo800eva.dts
arch/arm/boot/dts/r8a7740.dtsi
arch/arm/boot/dts/r8a7778-bockw-reference.dts
arch/arm/boot/dts/r8a7778.dtsi
arch/arm/boot/dts/r8a7779-marzen.dts
arch/arm/boot/dts/r8a7779.dtsi
arch/arm/boot/dts/r8a7790-lager.dts
arch/arm/boot/dts/r8a7790.dtsi
arch/arm/boot/dts/r8a7791-henninger.dts
arch/arm/boot/dts/r8a7791-koelsch.dts
arch/arm/boot/dts/r8a7791.dtsi
arch/arm/boot/dts/r8a7794-alt.dts [new file with mode: 0644]
arch/arm/boot/dts/r8a7794.dtsi [new file with mode: 0644]
arch/arm/boot/dts/sh7372.dtsi
arch/arm/boot/dts/sh73a0-kzm9g-reference.dts
arch/arm/boot/dts/sh73a0.dtsi
arch/arm/configs/ape6evm_defconfig
arch/arm/configs/bockw_defconfig
arch/arm/configs/koelsch_defconfig [deleted file]
arch/arm/configs/kzm9g_defconfig
arch/arm/configs/lager_defconfig
arch/arm/configs/marzen_defconfig
arch/arm/configs/shmobile_defconfig
arch/arm/include/asm/arch_timer.h
arch/arm/include/asm/thread_info.h
arch/arm/include/debug/renesas-scif.S [new file with mode: 0644]
arch/arm/kernel/kprobes-common.c
arch/arm/kernel/kprobes-thumb.c
arch/arm/kernel/kprobes.c
arch/arm/kernel/traps.c
arch/arm/mach-shmobile/Kconfig
arch/arm/mach-shmobile/Makefile
arch/arm/mach-shmobile/Makefile.boot
arch/arm/mach-shmobile/board-ape6evm-reference.c
arch/arm/mach-shmobile/board-ape6evm.c
arch/arm/mach-shmobile/board-armadillo800eva-reference.c [deleted file]
arch/arm/mach-shmobile/board-armadillo800eva.c
arch/arm/mach-shmobile/board-bockw-reference.c
arch/arm/mach-shmobile/board-bockw.c
arch/arm/mach-shmobile/board-genmai-reference.c [deleted file]
arch/arm/mach-shmobile/board-genmai.c [deleted file]
arch/arm/mach-shmobile/board-koelsch-reference.c [deleted file]
arch/arm/mach-shmobile/board-koelsch.c [deleted file]
arch/arm/mach-shmobile/board-kzm9g-reference.c
arch/arm/mach-shmobile/board-kzm9g.c
arch/arm/mach-shmobile/board-lager-reference.c
arch/arm/mach-shmobile/board-lager.c
arch/arm/mach-shmobile/board-mackerel.c
arch/arm/mach-shmobile/board-marzen-reference.c
arch/arm/mach-shmobile/board-marzen.c
arch/arm/mach-shmobile/clock-r7s72100.c [deleted file]
arch/arm/mach-shmobile/clock-r8a73a4.c
arch/arm/mach-shmobile/clock-r8a7740.c
arch/arm/mach-shmobile/clock-r8a7778.c
arch/arm/mach-shmobile/clock-r8a7779.c
arch/arm/mach-shmobile/clock-r8a7790.c
arch/arm/mach-shmobile/clock-r8a7791.c [deleted file]
arch/arm/mach-shmobile/clock-sh7372.c
arch/arm/mach-shmobile/clock-sh73a0.c
arch/arm/mach-shmobile/clock.c
arch/arm/mach-shmobile/clock.h
arch/arm/mach-shmobile/common.h
arch/arm/mach-shmobile/console.c
arch/arm/mach-shmobile/dma-register.h
arch/arm/mach-shmobile/headsmp-scu.S
arch/arm/mach-shmobile/intc-sh7372.c
arch/arm/mach-shmobile/intc-sh73a0.c
arch/arm/mach-shmobile/intc.h
arch/arm/mach-shmobile/irqs.h
arch/arm/mach-shmobile/platsmp-apmu.c
arch/arm/mach-shmobile/platsmp-apmu.h [new file with mode: 0644]
arch/arm/mach-shmobile/pm-r8a7740.c
arch/arm/mach-shmobile/pm-r8a7779.c
arch/arm/mach-shmobile/pm-rcar.c
arch/arm/mach-shmobile/pm-rmobile.c
arch/arm/mach-shmobile/pm-rmobile.h
arch/arm/mach-shmobile/r7s72100.h [deleted file]
arch/arm/mach-shmobile/r8a73a4.h
arch/arm/mach-shmobile/r8a7740.h
arch/arm/mach-shmobile/r8a7778.h
arch/arm/mach-shmobile/r8a7779.h
arch/arm/mach-shmobile/r8a7790.h
arch/arm/mach-shmobile/r8a7791.h
arch/arm/mach-shmobile/setup-emev2.c
arch/arm/mach-shmobile/setup-r7s72100.c
arch/arm/mach-shmobile/setup-r8a73a4.c
arch/arm/mach-shmobile/setup-r8a7740.c
arch/arm/mach-shmobile/setup-r8a7778.c
arch/arm/mach-shmobile/setup-r8a7779.c
arch/arm/mach-shmobile/setup-r8a7790.c
arch/arm/mach-shmobile/setup-r8a7791.c
arch/arm/mach-shmobile/setup-r8a7794.c [new file with mode: 0644]
arch/arm/mach-shmobile/setup-rcar-gen2.c
arch/arm/mach-shmobile/setup-sh7372.c
arch/arm/mach-shmobile/setup-sh73a0.c
arch/arm/mach-shmobile/sh73a0.h
arch/arm/mach-shmobile/sleep-sh7372.S
arch/arm/mach-shmobile/smp-emev2.c
arch/arm/mach-shmobile/smp-r8a7779.c
arch/arm/mach-shmobile/smp-r8a7790.c
arch/arm/mach-shmobile/smp-r8a7791.c
arch/arm/mach-shmobile/smp-sh73a0.c
arch/arm/mach-shmobile/timer.c
arch/arm/mm/Kconfig
arch/arm/mm/proc-v7.S
arch/arm/mm/proc-xscale.S
arch/arm/plat-samsung/Makefile
arch/arm64/include/asm/arch_timer.h
arch/arm64/kernel/insn.c
arch/arm64/lib/clear_user.S
arch/mips/loongson/common/Makefile
arch/mips/oprofile/backtrace.c
arch/parisc/include/uapi/asm/shmbuf.h
arch/parisc/kernel/syscall_table.S
arch/powerpc/platforms/powernv/pci-ioda.c
arch/powerpc/platforms/powernv/pci.c
arch/powerpc/platforms/pseries/msi.c
arch/powerpc/xmon/xmon.c
arch/sparc/include/asm/atomic_32.h
arch/sparc/include/asm/cmpxchg_32.h
arch/sparc/include/asm/vio.h
arch/sparc/include/uapi/asm/swab.h
arch/sparc/kernel/pci_schizo.c
arch/sparc/kernel/smp_64.c
arch/sparc/lib/atomic32.c
arch/x86/boot/compressed/Makefile
arch/x86/boot/compressed/head_32.S
arch/x86/boot/compressed/head_64.S
arch/x86/boot/compressed/misc.c
arch/x86/boot/compressed/mkpiggy.c
arch/x86/include/asm/cpufeature.h
arch/x86/include/asm/kvm_para.h
arch/x86/include/asm/page_32_types.h
arch/x86/include/asm/page_64_types.h
arch/x86/include/asm/thread_info.h
arch/x86/include/asm/traps.h
arch/x86/kernel/cpu/amd.c
arch/x86/kernel/cpu/common.c
arch/x86/kernel/cpu/microcode/amd_early.c
arch/x86/kernel/cpu/perf_event_intel.c
arch/x86/kernel/dumpstack_64.c
arch/x86/kernel/entry_64.S
arch/x86/kernel/ptrace.c
arch/x86/kernel/traps.c
arch/x86/kvm/x86.c
arch/x86/mm/init_64.c
arch/x86/mm/pgtable.c
arch/x86/tools/calc_run_size.pl [new file with mode: 0644]
arch/xtensa/include/uapi/asm/unistd.h
drivers/ata/ahci.c
drivers/ata/sata_rcar.c
drivers/base/devres.c
drivers/base/power/Makefile
drivers/base/power/domain.c
drivers/base/power/runtime.c
drivers/base/regmap/regmap.c
drivers/block/sunvdc.c
drivers/block/zram/zram_drv.c
drivers/char/hw_random/pseries-rng.c
drivers/clk/shmobile/Makefile
drivers/clk/shmobile/clk-rcar-gen2.c
drivers/clocksource/arm_arch_timer.c
drivers/clocksource/sun4i_timer.c
drivers/crypto/caam/caamhash.c
drivers/crypto/caam/key_gen.c
drivers/crypto/caam/sg_sw_sec4.h
drivers/firewire/core-cdev.c
drivers/gpio/devres.c
drivers/gpio/gpiolib.c
drivers/gpu/drm/radeon/cik.c
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r600_dpm.c
drivers/gpu/drm/radeon/radeon_irq_kms.c
drivers/gpu/drm/radeon/rs600.c
drivers/gpu/drm/radeon/rs690.c
drivers/gpu/drm/radeon/rv515.c
drivers/gpu/drm/radeon/si.c
drivers/gpu/drm/rcar-du/Kconfig
drivers/gpu/drm/rcar-du/rcar_du_crtc.c
drivers/gpu/drm/rcar-du/rcar_du_crtc.h
drivers/gpu/drm/rcar-du/rcar_du_drv.c
drivers/gpu/drm/rcar-du/rcar_du_drv.h
drivers/gpu/drm/rcar-du/rcar_du_encoder.c
drivers/gpu/drm/rcar-du/rcar_du_encoder.h
drivers/gpu/drm/rcar-du/rcar_du_group.c
drivers/gpu/drm/rcar-du/rcar_du_group.h
drivers/gpu/drm/rcar-du/rcar_du_kms.c
drivers/gpu/drm/rcar-du/rcar_du_kms.h
drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c
drivers/gpu/drm/rcar-du/rcar_du_lvdscon.h
drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c
drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.h
drivers/gpu/drm/rcar-du/rcar_du_plane.c
drivers/gpu/drm/rcar-du/rcar_du_plane.h
drivers/gpu/drm/rcar-du/rcar_du_vgacon.c
drivers/gpu/drm/rcar-du/rcar_du_vgacon.h
drivers/i2c/algos/i2c-algo-bit.c
drivers/i2c/algos/i2c-algo-pca.c
drivers/i2c/algos/i2c-algo-pcf.c
drivers/i2c/algos/i2c-algo-pcf.h
drivers/i2c/busses/i2c-ali1535.c
drivers/i2c/busses/i2c-ali15x3.c
drivers/i2c/busses/i2c-amd756-s4882.c
drivers/i2c/busses/i2c-amd756.c
drivers/i2c/busses/i2c-au1550.c
drivers/i2c/busses/i2c-cpm.c
drivers/i2c/busses/i2c-davinci.c
drivers/i2c/busses/i2c-designware-core.c
drivers/i2c/busses/i2c-designware-core.h
drivers/i2c/busses/i2c-designware-pcidrv.c
drivers/i2c/busses/i2c-designware-platdrv.c
drivers/i2c/busses/i2c-eg20t.c
drivers/i2c/busses/i2c-elektor.c
drivers/i2c/busses/i2c-hydra.c
drivers/i2c/busses/i2c-i801.c
drivers/i2c/busses/i2c-imx.c
drivers/i2c/busses/i2c-iop3xx.h
drivers/i2c/busses/i2c-isch.c
drivers/i2c/busses/i2c-ismt.c
drivers/i2c/busses/i2c-nforce2-s4985.c
drivers/i2c/busses/i2c-nforce2.c
drivers/i2c/busses/i2c-omap.c
drivers/i2c/busses/i2c-parport-light.c
drivers/i2c/busses/i2c-parport.c
drivers/i2c/busses/i2c-parport.h
drivers/i2c/busses/i2c-pasemi.c
drivers/i2c/busses/i2c-pca-isa.c
drivers/i2c/busses/i2c-piix4.c
drivers/i2c/busses/i2c-pmcmsp.c
drivers/i2c/busses/i2c-powermac.c
drivers/i2c/busses/i2c-rcar.c
drivers/i2c/busses/i2c-s3c2410.c
drivers/i2c/busses/i2c-sh_mobile.c
drivers/i2c/busses/i2c-sibyte.c
drivers/i2c/busses/i2c-simtec.c
drivers/i2c/busses/i2c-sis5595.c
drivers/i2c/busses/i2c-sis630.c
drivers/i2c/busses/i2c-sis96x.c
drivers/i2c/busses/i2c-taos-evm.c
drivers/i2c/busses/i2c-via.c
drivers/i2c/busses/i2c-viapro.c
drivers/i2c/busses/i2c-xiic.c
drivers/i2c/busses/scx200_acb.c
drivers/i2c/i2c-boardinfo.c
drivers/i2c/i2c-core.c
drivers/i2c/i2c-core.h
drivers/i2c/i2c-dev.c
drivers/i2c/i2c-smbus.c
drivers/i2c/i2c-stub.c
drivers/infiniband/core/uverbs_cmd.c
drivers/infiniband/ulp/isert/ib_isert.c
drivers/infiniband/ulp/srpt/ib_srpt.c
drivers/input/joystick/xpad.c
drivers/input/mouse/alps.c
drivers/input/mouse/synaptics.c
drivers/irqchip/irq-renesas-intc-irqpin.c
drivers/md/dm-bufio.c
drivers/md/dm-raid.c
drivers/md/dm-thin.c
drivers/md/md.c
drivers/md/persistent-data/dm-btree-internal.h
drivers/md/persistent-data/dm-btree-spine.c
drivers/md/persistent-data/dm-btree.c
drivers/media/platform/exynos4-is/media-dev.c
drivers/media/platform/exynos4-is/mipi-csis.c
drivers/media/usb/ttusb-dec/ttusbdecfe.c
drivers/media/v4l2-core/v4l2-of.c
drivers/mfd/da9055-core.c
drivers/mmc/card/block.c
drivers/mmc/host/sh_mobile_sdhi.c
drivers/mmc/host/tmio_mmc.c
drivers/mmc/host/tmio_mmc.h
drivers/mmc/host/tmio_mmc_dma.c
drivers/mmc/host/tmio_mmc_pio.c
drivers/net/bonding/bond_main.c
drivers/net/can/dev.c
drivers/net/can/usb/esd_usb2.c
drivers/net/ethernet/smsc/smsc911x.c
drivers/net/ethernet/sun/sunvnet.c
drivers/net/ieee802154/fakehard.c
drivers/net/macvtap.c
drivers/net/ppp/pptp.c
drivers/net/tun.c
drivers/net/usb/qmi_wwan.c
drivers/net/virtio_net.c
drivers/net/vxlan.c
drivers/net/wimax/Makefile
drivers/net/wireless/ath/ath9k/ar9003_phy.c
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/iwlwifi/iwl-trans.h
drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
drivers/net/wireless/iwlwifi/mvm/fw-api.h
drivers/net/wireless/iwlwifi/mvm/fw.c
drivers/net/wireless/iwlwifi/mvm/ops.c
drivers/net/wireless/iwlwifi/pcie/trans.c
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/rt2x00/rt2x00queue.c
drivers/of/address.c
drivers/of/base.c
drivers/pci/host/pci-rcar-gen2.c
drivers/pci/msi.c
drivers/pci/probe.c
drivers/phy/Kconfig
drivers/phy/Makefile
drivers/phy/phy-bcm-kona-usb2.c
drivers/phy/phy-core.c
drivers/phy/phy-exynos-dp-video.c
drivers/phy/phy-exynos-mipi-video.c
drivers/phy/phy-mvebu-sata.c
drivers/phy/phy-omap-usb2.c
drivers/phy/phy-rcar-gen2.c [new file with mode: 0644]
drivers/phy/phy-twl4030-usb.c
drivers/pinctrl/sh-pfc/core.c
drivers/pinctrl/sh-pfc/core.h
drivers/pinctrl/sh-pfc/pfc-r8a73a4.c
drivers/pinctrl/sh-pfc/pfc-r8a7740.c
drivers/pinctrl/sh-pfc/pfc-sh7372.c
drivers/pinctrl/sh-pfc/pfc-sh73a0.c
drivers/pinctrl/sh-pfc/sh_pfc.h
drivers/platform/x86/dell-wmi.c
drivers/power/bq2415x_charger.c
drivers/power/charger-manager.c
drivers/scsi/bnx2fc/bnx2fc_fcoe.c
drivers/scsi/scsi_devinfo.c
drivers/scsi/scsi_error.c
drivers/sh/pm_runtime.c
drivers/spi/spi-dw.c
drivers/spi/spi-rspi.c
drivers/spi/spi-sh-msiof.c
drivers/staging/rtl8188eu/os_dep/usb_intf.c
drivers/target/target_core_transport.c
drivers/tty/serial/serial_core.c
drivers/tty/serial/sh-sci.c
drivers/usb/chipidea/core.c
drivers/usb/chipidea/host.c
drivers/usb/core/hcd.c
drivers/usb/core/hub.c
drivers/usb/core/hub.h
drivers/usb/core/port.c
drivers/usb/core/quirks.c
drivers/usb/core/usb-acpi.c
drivers/usb/core/usb.h
drivers/usb/host/ehci-fsl.c
drivers/usb/host/ehci-hub.c
drivers/usb/host/ehci-msm.c
drivers/usb/host/ehci-tegra.c
drivers/usb/host/ohci-omap.c
drivers/usb/host/xhci-pci.c
drivers/usb/host/xhci-plat.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.c
drivers/usb/host/xhci.h
drivers/usb/phy/phy-rcar-gen2-usb.c
drivers/usb/renesas_usbhs/Kconfig
drivers/usb/renesas_usbhs/common.c
drivers/usb/serial/cp210x.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio_ids.h
drivers/usb/serial/keyspan.c
drivers/usb/serial/ssu100.c
drivers/vhost/scsi.c
fs/aio.c
fs/btrfs/compression.c
fs/btrfs/file.c
fs/cramfs/inode.c
fs/fuse/file.c
fs/gfs2/meta_io.c
fs/gfs2/meta_io.h
fs/gfs2/ops_fstype.c
fs/ioprio.c
fs/jffs2/fs.c
fs/locks.c
fs/nfs/blocklayout/blocklayout.c
fs/nfs/delegation.c
fs/nfs/delegation.h
fs/nfs/direct.c
fs/nfs/inode.c
fs/nfs/nfs4proc.c
fs/nfs/pagelist.c
fs/nfsd/nfs4callback.c
fs/nfsd/nfscache.c
fs/nfsd/nfsd.h
fs/super.c
include/asm-generic/gpio.h
include/dt-bindings/clock/r8a7740-clock.h [new file with mode: 0644]
include/dt-bindings/clock/r8a7790-clock.h
include/dt-bindings/clock/r8a7791-clock.h
include/dt-bindings/clock/r8a7794-clock.h [new file with mode: 0644]
include/dt-bindings/pinctrl/dra.h
include/linux/bitops.h
include/linux/clocksource.h
include/linux/compaction.h
include/linux/crash_dump.h
include/linux/device.h
include/linux/gpio/consumer.h
include/linux/gpio/driver.h
include/linux/iio/events.h
include/linux/inetdevice.h
include/linux/kgdb.h
include/linux/memory.h
include/linux/mfd/tmio.h
include/linux/migrate.h
include/linux/mm.h
include/linux/mmc/host.h
include/linux/mmzone.h
include/linux/nfs_xdr.h
include/linux/of.h
include/linux/of_graph.h
include/linux/pagemap.h
include/linux/pagevec.h
include/linux/pci.h
include/linux/phy/phy.h
include/linux/pinctrl/pinconf-generic.h
include/linux/platform_data/rcar-du.h
include/linux/pm_runtime.h
include/linux/power/charger-manager.h
include/linux/radix-tree.h
include/linux/shmem_fs.h
include/linux/usb/chipidea.h
include/linux/usb/hcd.h
include/media/v4l2-of.h
include/net/sctp/sctp.h
include/net/sctp/sm.h
include/sound/soc-dpcm.h
include/trace/events/compaction.h
include/uapi/linux/netfilter/xt_bpf.h
ipc/ipc_sysctl.c
kernel/audit.c
kernel/audit_tree.c
kernel/events/core.c
kernel/events/uprobes.c
kernel/rcu/tree.c
lib/radix-tree.c
mm/compaction.c
mm/filemap.c
mm/internal.h
mm/madvise.c
mm/memory-failure.c
mm/memory_hotplug.c
mm/mempolicy.c
mm/migrate.c
mm/mincore.c
mm/page_alloc.c
mm/readahead.c
mm/shmem.c
mm/swap.c
mm/truncate.c
mm/vmscan.c
net/batman-adv/hard-interface.c
net/ceph/crypto.c
net/ipv4/fib_rules.c
net/ipv4/ping.c
net/ipv6/ip6_gre.c
net/ipv6/ip6_tunnel.c
net/ipv6/ip6_vti.c
net/ipv6/sit.c
net/ipx/af_ipx.c
net/mac80211/ibss.c
net/mac80211/ieee80211_i.h
net/mac80211/iface.c
net/mac80211/mesh.c
net/mac80211/mlme.c
net/mac80211/rx.c
net/mac80211/spectmgmt.c
net/netfilter/ipset/ip_set_core.c
net/netfilter/nfnetlink_log.c
net/netfilter/nft_compat.c
net/sctp/associola.c
net/sctp/auth.c
net/sctp/inqueue.c
net/sctp/sm_make_chunk.c
net/sctp/sm_statefuns.c
sound/soc/codecs/Kconfig
sound/soc/codecs/sgtl5000.c
sound/soc/codecs/sgtl5000.h
sound/soc/codecs/wm_adsp.c
sound/soc/sh/fsi.c
sound/soc/sh/rcar/core.c
sound/soc/sh/rcar/dvc.c
sound/soc/sh/rcar/gen.c
sound/soc/sh/rcar/rsnd.h
sound/soc/sh/rcar/src.c
sound/soc/sh/rcar/ssi.c
sound/soc/soc-pcm.c
sound/usb/mixer_quirks.c
sound/usb/quirks.c

diff --git a/Documentation/.gitignore b/Documentation/.gitignore
deleted file mode 100644 (file)
index bcd907b..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-filesystems/dnotify_test
-laptops/dslm
-timers/hpet_example
-vm/hugepage-mmap
-vm/hugepage-shm
-vm/map_hugetlb
-
diff --git a/Documentation/arm/SH-Mobile/.gitignore b/Documentation/arm/SH-Mobile/.gitignore
new file mode 100644 (file)
index 0000000..c928dbf
--- /dev/null
@@ -0,0 +1 @@
+vrl4
index e8a1913..4cbbba5 100644 (file)
@@ -77,7 +77,7 @@ struct hdr {
 
 #define ROUND_UP(x)    ((x + ALIGN - 1) & ~(ALIGN - 1))
 
-ssize_t do_read(int fd, void *buf, size_t count)
+static ssize_t do_read(int fd, void *buf, size_t count)
 {
        size_t offset = 0;
        ssize_t l;
@@ -98,7 +98,7 @@ ssize_t do_read(int fd, void *buf, size_t count)
        return offset;
 }
 
-ssize_t do_write(int fd, const void *buf, size_t count)
+static ssize_t do_write(int fd, const void *buf, size_t count)
 {
        size_t offset = 0;
        ssize_t l;
@@ -117,7 +117,7 @@ ssize_t do_write(int fd, const void *buf, size_t count)
        return offset;
 }
 
-ssize_t write_zero(int fd, size_t len)
+static ssize_t write_zero(int fd, size_t len)
 {
        size_t i = len;
 
index 1e61113..80ae87a 100644 (file)
@@ -3,8 +3,10 @@
 Required properties:
 - compatible           : should contain one of the following:
                          - "renesas,sata-r8a7779" for R-Car H1
-                         - "renesas,sata-r8a7790" for R-Car H2
-                         - "renesas,sata-r8a7791" for R-Car M2
+                         - "renesas,sata-r8a7790-es1" for R-Car H2 ES1
+                         - "renesas,sata-r8a7790" for R-Car H2 other than ES1
+                         - "renesas,sata-r8a7791" for R-Car M2-W
+                         - "renesas,sata-r8a7793" for R-Car M2-N
 - reg                  : address and length of the SATA registers;
 - interrupts           : must consist of one interrupt specifier.
 
index 8a92b5f..a5f5223 100644 (file)
@@ -11,9 +11,12 @@ Required Properties:
 
   - compatible: Must be one of the following
     - "renesas,r7s72100-mstp-clocks" for R7S72100 (RZ) MSTP gate clocks
+    - "renesas,r8a7740-mstp-clocks" for R8A7740 (R-Mobile A1) MSTP gate clocks
     - "renesas,r8a7779-mstp-clocks" for R8A7779 (R-Car H1) MSTP gate clocks
     - "renesas,r8a7790-mstp-clocks" for R8A7790 (R-Car H2) MSTP gate clocks
     - "renesas,r8a7791-mstp-clocks" for R8A7791 (R-Car M2) MSTP gate clocks
+    - "renesas,r8a7794-mstp-clocks" for R8A7794 (R-Car E2) MSTP gate clocks
+    - "renesas,sh73a0-mstp-clocks" for SH73A0 (SH-MobileAG5) MSTP gate clocks
     - "renesas,cpg-mstp-clock" for generic MSTP gate clocks
   - reg: Base address and length of the I/O mapped registers used by the MSTP
     clocks. The first register is the clock control register and is mandatory.
index 1a1ac2e..858267c 100644 (file)
@@ -29,7 +29,7 @@ dallas,ds1775         Tiny Digital Thermometer and Thermostat
 dallas,ds3232          Extremely Accurate I²C RTC with Integrated Crystal and SRAM
 dallas,ds4510          CPU Supervisor with Nonvolatile Memory and Programmable I/O
 dallas,ds75            Digital Thermometer and Thermostat
-dialog,da9053          DA9053: flexible system level PMIC with multicore support
+dlg,da9053             DA9053: flexible system level PMIC with multicore support
 epson,rx8025           High-Stability. I2C-Bus INTERFACE REAL TIME CLOCK MODULE
 epson,rx8581           I2C-BUS INTERFACE REAL TIME CLOCK MODULE
 fsl,mag3110            MAG3110: Xtrinsic High Accuracy, 3D Magnetometer
index ce6a1a0..8a3c408 100644 (file)
@@ -30,10 +30,6 @@ should only be used when a device has multiple interrupt parents.
   Example:
        interrupts-extended = <&intc1 5 1>, <&intc2 1 0>;
 
-A device node may contain either "interrupts" or "interrupts-extended", but not
-both. If both properties are present, then the operating system should log an
-error and use only the data in "interrupts".
-
 2) Interrupt controller nodes
 -----------------------------
 
index 1f8b0c5..c73acd0 100644 (file)
@@ -2,7 +2,13 @@ DT bindings for the R-/SH-Mobile irqpin controller
 
 Required properties:
 
-- compatible: has to be "renesas,intc-irqpin"
+- compatible: has to be "renesas,intc-irqpin-<soctype>", "renesas,intc-irqpin"
+  as fallback.
+  Examples with soctypes are:
+    - "renesas,intc-irqpin-r8a7740" (R-Mobile A1)
+    - "renesas,intc-irqpin-r8a7778" (R-Car M1A)
+    - "renesas,intc-irqpin-r8a7779" (R-Car H1)
+    - "renesas,intc-irqpin-sh73a0" (SH-Mobile AG5)
 - #interrupt-cells: has to be <2>: an interrupt index and flags, as defined in
   interrupts.txt in this directory
 
index fa0f327..400b640 100644 (file)
@@ -19,6 +19,9 @@ Required properties:
                "renesas,sdhi-r8a7779" - SDHI IP on R8A7779 SoC
                "renesas,sdhi-r8a7790" - SDHI IP on R8A7790 SoC
                "renesas,sdhi-r8a7791" - SDHI IP on R8A7791 SoC
+               "renesas,sdhi-r8a7792" - SDHI IP on R8A7792 SoC
+               "renesas,sdhi-r8a7793" - SDHI IP on R8A7793 SoC
+               "renesas,sdhi-r8a7794" - SDHI IP on R8A7794 SoC
 
 Optional properties:
 - toshiba,mmc-wrprotect-disable: write-protect detection is unavailable
diff --git a/Documentation/devicetree/bindings/pci/pci-rcar-gen2.txt b/Documentation/devicetree/bindings/pci/pci-rcar-gen2.txt
new file mode 100644 (file)
index 0000000..d8ef5bf
--- /dev/null
@@ -0,0 +1,66 @@
+Renesas AHB to PCI bridge
+-------------------------
+
+This is the bridge used internally to connect the USB controllers to the
+AHB. There is one bridge instance per USB port connected to the internal
+OHCI and EHCI controllers.
+
+Required properties:
+- compatible: "renesas,pci-r8a7790" for the R8A7790 SoC;
+             "renesas,pci-r8a7791" for the R8A7791 SoC.
+- reg: A list of physical regions to access the device: the first is
+       the operational registers for the OHCI/EHCI controllers and the
+       second is for the bridge configuration and control registers.
+- interrupts: interrupt for the device.
+- clocks: The reference to the device clock.
+- bus-range: The PCI bus number range; as this is a single bus, the range
+            should be specified as the same value twice.
+- #address-cells: must be 3.
+- #size-cells: must be 2.
+- #interrupt-cells: must be 1.
+- interrupt-map: standard property used to define the mapping of the PCI
+  interrupts to the GIC interrupts.
+- interrupt-map-mask: standard property that helps to define the interrupt
+  mapping.
+
+Example SoC configuration:
+
+       pci0: pci@ee090000  {
+               compatible = "renesas,pci-r8a7790";
+               clocks = <&mstp7_clks R8A7790_CLK_EHCI>;
+               reg = <0x0 0xee090000 0x0 0xc00>,
+                     <0x0 0xee080000 0x0 0x1100>;
+               interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>;
+               status = "disabled";
+
+               bus-range = <0 0>;
+               #address-cells = <3>;
+               #size-cells = <2>;
+               #interrupt-cells = <1>;
+               interrupt-map-mask = <0xff00 0 0 0x7>;
+               interrupt-map = <0x0000 0 0 1 &gic 0 108 IRQ_TYPE_LEVEL_HIGH
+                                0x0800 0 0 1 &gic 0 108 IRQ_TYPE_LEVEL_HIGH
+                                0x1000 0 0 2 &gic 0 108 IRQ_TYPE_LEVEL_HIGH>;
+
+               pci@0,1 {
+                       reg = <0x800 0 0 0 0>;
+                       device_type = "pci";
+                       phys = <&usbphy 0 0>;
+                       phy-names = "usb";
+               };
+
+               pci@0,2 {
+                       reg = <0x1000 0 0 0 0>;
+                       device_type = "pci";
+                       phys = <&usbphy 0 0>;
+                       phy-names = "usb";
+               };
+       };
+
+Example board setup:
+
+&pci0 {
+       status = "okay";
+       pinctrl-0 = <&usb0_pins>;
+       pinctrl-names = "default";
+};
diff --git a/Documentation/devicetree/bindings/phy/rcar-gen2-phy.txt b/Documentation/devicetree/bindings/phy/rcar-gen2-phy.txt
new file mode 100644 (file)
index 0000000..00fc52a
--- /dev/null
@@ -0,0 +1,51 @@
+* Renesas R-Car generation 2 USB PHY
+
+This file provides information on what the device node for the R-Car generation
+2 USB PHY contains.
+
+Required properties:
+- compatible: "renesas,usb-phy-r8a7790" if the device is a part of R8A7790 SoC.
+             "renesas,usb-phy-r8a7791" if the device is a part of R8A7791 SoC.
+- reg: offset and length of the register block.
+- #address-cells: number of address cells for the USB channel subnodes, must
+                 be <1>.
+- #size-cells: number of size cells for the USB channel subnodes, must be <0>.
+- clocks: clock phandle and specifier pair.
+- clock-names: string, clock input name, must be "usbhs".
+
+The USB PHY device tree node should have the subnodes corresponding to the USB
+channels. These subnodes must contain the following properties:
+- reg: the USB controller selector; see the table below for the values.
+- #phy-cells: see phy-bindings.txt in the same directory, must be <1>.
+
+The phandle's argument in the PHY specifier is the USB controller selector for
+the USB channel; see the selector meanings below:
+
++-----------+---------------+---------------+
+|\ Selector |               |               |
++ --------- +       0       |       1       |
+| Channel  \|               |               |
++-----------+---------------+---------------+
+| 0         | PCI EHCI/OHCI | HS-USB        |
+| 2         | PCI EHCI/OHCI | xHCI          |
++-----------+---------------+---------------+
+
+Example (Lager board):
+
+       usb-phy@e6590100 {
+               compatible = "renesas,usb-phy-r8a7790";
+               reg = <0 0xe6590100 0 0x100>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&mstp7_clks R8A7790_CLK_HSUSB>;
+               clock-names = "usbhs";
+
+               usb-channel@0 {
+                       reg = <0>;
+                       #phy-cells = <1>;
+               };
+               usb-channel@2 {
+                       reg = <2>;
+                       #phy-cells = <1>;
+               };
+       };
index f120f22..3297c53 100644 (file)
@@ -2,7 +2,7 @@
 
 Required properties:
 
-- compatible:  must be "diasemi,da9210"
+- compatible:  must be "dlg,da9210"
 - reg:         the i2c slave address of the regulator. It should be 0x68.
 
 Any standard regulator properties can be used to configure the single da9210
@@ -11,7 +11,7 @@ DCDC.
 Example:
 
        da9210@68 {
-               compatible = "diasemi,da9210";
+               compatible = "dlg,da9210";
                reg = <0x68>;
 
                regulator-min-microvolt = <900000>;
index aa697ab..2dd690b 100644 (file)
@@ -1,8 +1,12 @@
 Renesas R-Car sound
 
 Required properties:
-- compatible                   : "renesas,rcar_sound-gen1" if generation1
+- compatible                   : "renesas,rcar_sound-<soctype>", fallbacks
+                                 "renesas,rcar_sound-gen1" if generation1, and
                                  "renesas,rcar_sound-gen2" if generation2
+                                 Examples with soctypes are:
+                                   - "renesas,rcar_sound-r8a7790" (R-Car H2)
+                                   - "renesas,rcar_sound-r8a7791" (R-Car M2-W)
 - reg                          : Should contain the register physical address.
                                  required register is
                                   SRU/ADG/SSI      if generation1
@@ -35,9 +39,9 @@ DAI subnode properties:
 
 Example:
 
-rcar_sound: rcar_sound@0xffd90000 {
+rcar_sound: rcar_sound@ec500000 {
        #sound-dai-cells = <1>;
-       compatible = "renesas,rcar_sound-gen2";
+       compatible = "renesas,rcar_sound-r8a7791", "renesas,rcar_sound-gen2";
        reg =   <0 0xec500000 0 0x1000>, /* SCU */
                <0 0xec5a0000 0 0x100>,  /* ADG */
                <0 0xec540000 0 0x1000>, /* SSIU */
index f24baf3..d11c372 100644 (file)
@@ -6,8 +6,17 @@ Required properties:
                         "renesas,sh-mobile-msiof" for SH Mobile series.
                         Examples with soctypes are:
                         "renesas,msiof-r8a7790" (R-Car H2)
-                        "renesas,msiof-r8a7791" (R-Car M2)
-- reg                  : Offset and length of the register set for the device
+                        "renesas,msiof-r8a7791" (R-Car M2-W)
+                        "renesas,msiof-r8a7792" (R-Car V2H)
+                        "renesas,msiof-r8a7793" (R-Car M2-N)
+                        "renesas,msiof-r8a7794" (R-Car E2)
+- reg                  : A list of offsets and lengths of the register sets for
+                        the device.
+                        If only one register set is present, it is to be used
+                        by both the CPU and the DMA engine.
+                        If two register sets are present, the first is to be
+                        used by the CPU, and the second is to be used by the
+                        DMA engine.
 - interrupt-parent     : The phandle for the interrupt controller that
                         services interrupts for this device
 - interrupts           : Interrupt specifier
@@ -17,12 +26,16 @@ Required properties:
 Optional properties:
 - clocks               : Must contain a reference to the functional clock.
 - num-cs               : Total number of chip-selects (default is 1)
+- dmas                 : Must contain a list of two references to DMA
+                        specifiers, one for transmission, and one for
+                        reception.
+- dma-names            : Must contain a list of two DMA names, "tx" and "rx".
 
 Optional properties, deprecated for soctype-specific bindings:
 - renesas,tx-fifo-size : Overrides the default tx fifo size given in words
                         (default is 64)
 - renesas,rx-fifo-size : Overrides the default rx fifo size given in words
-                        (default is 64, or 256 on R-Car H2 and M2)
+                        (default is 64, or 256 on R-Car Gen2)
 
 Pinctrl properties might be needed, too.  See
 Documentation/devicetree/bindings/pinctrl/renesas,*.
@@ -31,9 +44,11 @@ Example:
 
        msiof0: spi@e6e20000 {
                compatible = "renesas,msiof-r8a7791";
-               reg = <0 0xe6e20000 0 0x0064>;
+               reg = <0 0xe6e20000 0 0x0064>, <0 0xe7e20000 0 0x0064>;
                interrupts = <0 156 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp0_clks R8A7791_CLK_MSIOF0>;
+               dmas = <&dmac0 0x51>, <&dmac0 0x52>;
+               dma-names = "tx", "rx";
                #address-cells = <1>;
                #size-cells = <0>;
                status = "disabled";
index 95f9b21..8f4169f 100644 (file)
@@ -7,9 +7,14 @@ Required properties:
                     "renesas,rspi-<soctype>", "renesas,rspi-rz" as fallback.
                     For Quad Serial Peripheral Interface on R-Car Gen2:
                     "renesas,qspi-<soctype>", "renesas,qspi" as fallback.
-                    Examples of valid soctypes are "sh7757" (SH),
-                    "r7s72100" (RZ/A1H), "r8a7790" (R-Car H2), and
-                    "r8a7791" (R-Car M2).
+                    Examples with soctypes are:
+                       - "renesas,rspi-sh7757" (SH)
+                       - "renesas,rspi-r7s72100" (RZ/A1H)
+                       - "renesas,qspi-r8a7790" (R-Car H2)
+                       - "renesas,qspi-r8a7791" (R-Car M2-W)
+                       - "renesas,qspi-r8a7792" (R-Car V2H)
+                       - "renesas,qspi-r8a7793" (R-Car M2-N)
+                       - "renesas,qspi-r8a7794" (R-Car E2)
 - reg              : Address start and address range size of the device
 - interrupts       : A list of interrupt-specifiers, one for each entry in
                     interrupt-names.
@@ -27,7 +32,10 @@ Required properties:
 - #size-cells      : Must be <0>
 
 Optional properties:
-- clocks:           : Must contain a reference to the functional clock.
+- clocks           : Must contain a reference to the functional clock.
+- dmas             : Must contain a list of two references to DMA specifiers,
+                    one for transmission, and one for reception.
+- dma-names        : Must contain a list of two DMA names, "tx" and "rx".
 
 Pinctrl properties might be needed, too.  See
 Documentation/devicetree/bindings/pinctrl/renesas,*.
@@ -56,4 +64,6 @@ Examples:
                num-cs = <1>;
                #address-cells = <1>;
                #size-cells = <0>;
+               dmas = <&dmac0 0x17>, <&dmac0 0x18>;
+               dma-names = "tx", "rx";
        };
index 0ef00be..43404b1 100644 (file)
@@ -7,7 +7,10 @@ Required properties:
                            - "renesas,thermal-r8a73a4" (R-Mobile AP6)
                            - "renesas,thermal-r8a7779" (R-Car H1)
                            - "renesas,thermal-r8a7790" (R-Car H2)
-                           - "renesas,thermal-r8a7791" (R-Car M2)
+                           - "renesas,thermal-r8a7791" (R-Car M2-W)
+                           - "renesas,thermal-r8a7792" (R-Car V2H)
+                           - "renesas,thermal-r8a7793" (R-Car M2-N)
+                           - "renesas,thermal-r8a7794" (R-Car E2)
 - reg                  : Address range of the thermal registers.
                          The 1st reg will be recognized as common register
                          if it has "interrupts".
index a17418b..1a05c1b 100644 (file)
@@ -11,15 +11,47 @@ datasheets.
 
 Required Properties:
 
-  - compatible: must contain one of the following.
-    - "renesas,cmt-32" for the 32-bit CMT
+  - compatible: must contain one or more of the following:
+    - "renesas,cmt-32-r8a7740" for the r8a7740 32-bit CMT
+               (CMT0)
+    - "renesas,cmt-32-sh7372" for the sh7372 32-bit CMT
+               (CMT0)
+    - "renesas,cmt-32-sh73a0" for the sh73a0 32-bit CMT
+               (CMT0)
+    - "renesas,cmt-32" for all 32-bit CMT without fast clock support
                (CMT0 on sh7372, sh73a0 and r8a7740)
-    - "renesas,cmt-32-fast" for the 32-bit CMT with fast clock support
+               This is a fallback for the above renesas,cmt-32-* entries.
+
+    - "renesas,cmt-32-fast-r8a7740" for the r8a7740 32-bit CMT with fast
+               clock support (CMT[234])
+    - "renesas,cmt-32-fast-sh7372" for the sh7372 32-bit CMT with fast
+               clock support (CMT[234])
+    - "renesas,cmt-32-fast-sh73a0" for the sh73A0 32-bit CMT with fast
+               clock support (CMT[234])
+    - "renesas,cmt-32-fast" for all 32-bit CMT with fast clock support
                (CMT[234] on sh7372, sh73a0 and r8a7740)
-    - "renesas,cmt-48" for the 48-bit CMT
+               This is a fallback for the above renesas,cmt-32-fast-* entries.
+
+    - "renesas,cmt-48-sh7372" for the sh7372 48-bit CMT
+               (CMT1)
+    - "renesas,cmt-48-sh73a0" for the sh73A0 48-bit CMT
+               (CMT1)
+    - "renesas,cmt-48-r8a7740" for the r8a7740 48-bit CMT
+               (CMT1)
+    - "renesas,cmt-48" for all non-second generation 48-bit CMT
                (CMT1 on sh7372, sh73a0 and r8a7740)
-    - "renesas,cmt-48-gen2" for the second generation 48-bit CMT
+               This is a fallback for the above renesas,cmt-48-* entries.
+
+    - "renesas,cmt-48-r8a73a4" for the r8a73a4 48-bit CMT
+               (CMT[01])
+    - "renesas,cmt-48-r8a7790" for the r8a7790 48-bit CMT
+               (CMT[01])
+    - "renesas,cmt-48-r8a7791" for the r8a7791 48-bit CMT
+               (CMT[01])
+    - "renesas,cmt-48-gen2" for all second generation 48-bit CMT
                (CMT[01] on r8a73a4, r8a7790 and r8a7791)
+               This is a fallback for the renesas,cmt-48-r8a73a4,
+               renesas,cmt-48-r8a7790 and renesas,cmt-48-r8a7791 entries.
 
   - reg: base address and length of the registers block for the timer module.
   - interrupts: interrupt-specifier for the timer, one per channel.
@@ -36,7 +68,7 @@ Example: R8A7790 (R-Car H2) CMT0 node
        them channels 0 and 1 in the documentation.
 
        cmt0: timer@ffca0000 {
-               compatible = "renesas,cmt-48-gen2";
+               compatible = "renesas,cmt-48-r8a7790", "renesas,cmt-48-gen2";
                reg = <0 0xffca0000 0 0x1004>;
                interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>,
                             <0 142 IRQ_TYPE_LEVEL_HIGH>;
index 917453f..d9a8d5a 100644 (file)
@@ -8,7 +8,10 @@ are independent. The MTU2 hardware supports five channels indexed from 0 to 4.
 
 Required Properties:
 
-  - compatible: must contain "renesas,mtu2"
+  - compatible: must be one or more of the following:
+    - "renesas,mtu2-r7s72100" for the r7s72100 MTU2
+    - "renesas,mtu2" for any MTU2
+      This is a fallback for the above renesas,mtu2-* entries
 
   - reg: base address and length of the registers block for the timer module.
 
@@ -26,7 +29,7 @@ Required Properties:
 Example: R7S72100 (RZ/A1H) MTU2 node
 
        mtu2: timer@fcff0000 {
-               compatible = "renesas,mtu2";
+               compatible = "renesas,mtu2-r7s72100", "renesas,mtu2";
                reg = <0xfcff0000 0x400>;
                interrupts = <0 139 IRQ_TYPE_LEVEL_HIGH>,
                             <0 146 IRQ_TYPE_LEVEL_HIGH>,
index 425d0c5..7db89fb 100644 (file)
@@ -8,7 +8,10 @@ are independent. The TMU hardware supports up to three channels.
 
 Required Properties:
 
-  - compatible: must contain "renesas,tmu"
+  - compatible: must contain one or more of the following:
+    - "renesas,tmu-r8a7779" for the r8a7779 TMU
+    - "renesas,tmu" for any TMU.
+      This is a fallback for the above renesas,tmu-* entries
 
   - reg: base address and length of the registers block for the timer module.
 
@@ -27,7 +30,7 @@ Optional Properties:
 Example: R8A7779 (R-Car H1) TMU0 node
 
        tmu0: timer@ffd80000 {
-               compatible = "renesas,tmu";
+               compatible = "renesas,tmu-r8a7779", "renesas,tmu";
                reg = <0xffd80000 0x30>;
                interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>,
                             <0 33 IRQ_TYPE_LEVEL_HIGH>,
index 40ce2df..644f547 100644 (file)
@@ -1,6 +1,4 @@
-Device tree binding vendor prefix registry.  Keep list in alphabetical order.
-
-This isn't an exhaustive list, but you should add new prefixes to it before
+Device tree binding vendor prefix registry.  Keep list in alphabetical order.  This isn't an exhaustive list, but you should add new prefixes to it before
 using them to avoid name-space collisions.
 
 active-semi    Active-Semi International Inc
@@ -29,6 +27,7 @@ cortina       Cortina Systems, Inc.
 dallas Maxim Integrated Products (formerly Dallas Semiconductor)
 davicom        DAVICOM Semiconductor, Inc.
 denx   Denx Software Engineering
+dlg    Dialog Semiconductor
 edt    Emerging Display Technologies
 emmicro        EM Microelectronic
 epfl   Ecole Polytechnique Fédérale de Lausanne
index 4f7897e..57e328f 100644 (file)
@@ -287,6 +287,12 @@ REGULATOR
   devm_regulator_bulk_get()
   devm_regulator_register()
 
+  devm_mdiobus_free()
+
+MEM
+  devm_kasprintf()
+  devm_kvasprintf()
+
 CLOCK
   devm_clk_get()
   devm_clk_put()
@@ -308,3 +314,10 @@ SLAVE DMA ENGINE
 
 SPI
   devm_spi_register_master()
+
+GPIO
+  devm_gpiod_get()
+  devm_gpiod_get_index()
+  devm_gpiod_get_optional()
+  devm_gpiod_get_index_optional()
+  devm_gpiod_put()
diff --git a/Documentation/filesystems/.gitignore b/Documentation/filesystems/.gitignore
new file mode 100644 (file)
index 0000000..31d6e42
--- /dev/null
@@ -0,0 +1 @@
+dnotify_test
index e42f77d..1cdf6ac 100644 (file)
@@ -29,13 +29,24 @@ gpiod_get() functions. Like many other kernel subsystems, gpiod_get() takes the
 device that will use the GPIO and the function the requested GPIO is supposed to
 fulfill:
 
-       struct gpio_desc *gpiod_get(struct device *dev, const char *con_id)
+       struct gpio_desc *gpiod_get(struct device *dev, const char *con_id,
+                                   enum gpiod_flags flags)
 
 If a function is implemented by using several GPIOs together (e.g. a simple LED
 device that displays digits), an additional index argument can be specified:
 
        struct gpio_desc *gpiod_get_index(struct device *dev,
-                                         const char *con_id, unsigned int idx)
+                                         const char *con_id, unsigned int idx,
+                                         enum gpiod_flags flags)
+
+The flags parameter is used to optionally specify a direction and initial value
+for the GPIO. Values can be:
+
+* GPIOD_ASIS or 0 to not initialize the GPIO at all. The direction must be set
+  later with one of the dedicated functions.
+* GPIOD_IN to initialize the GPIO as input.
+* GPIOD_OUT_LOW to initialize the GPIO as output with a value of 0.
+* GPIOD_OUT_HIGH to initialize the GPIO as output with a value of 1.
 
 Both functions return either a valid GPIO descriptor, or an error code checkable
 with IS_ERR() (they will never return a NULL pointer). -ENOENT will be returned
@@ -46,11 +57,13 @@ errors and an absence of GPIO for optional GPIO parameters.
 
 Device-managed variants of these functions are also defined:
 
-       struct gpio_desc *devm_gpiod_get(struct device *dev, const char *con_id)
+       struct gpio_desc *devm_gpiod_get(struct device *dev, const char *con_id,
+                                        enum gpiod_flags flags)
 
        struct gpio_desc *devm_gpiod_get_index(struct device *dev,
                                               const char *con_id,
-                                              unsigned int idx)
+                                              unsigned int idx,
+                                              enum gpiod_flags flags)
 
 A GPIO descriptor can be disposed of using the gpiod_put() function:
 
@@ -67,8 +80,9 @@ Using GPIOs
 
 Setting Direction
 -----------------
-The first thing a driver must do with a GPIO is setting its direction. This is
-done by invoking one of the gpiod_direction_*() functions:
+The first thing a driver must do with a GPIO is setting its direction. If no
+direction-setting flags have been given to gpiod_get*(), this is done by
+invoking one of the gpiod_direction_*() functions:
 
        int gpiod_direction_input(struct gpio_desc *desc)
        int gpiod_direction_output(struct gpio_desc *desc, int value)
@@ -154,6 +168,7 @@ raw line value:
        void gpiod_set_raw_value(struct gpio_desc *desc, int value)
        int gpiod_get_raw_value_cansleep(const struct gpio_desc *desc)
        void gpiod_set_raw_value_cansleep(struct gpio_desc *desc, int value)
+       int gpiod_direction_output_raw(struct gpio_desc *desc, int value)
 
 The active-low state of a GPIO can also be queried using the following call:
 
diff --git a/Documentation/laptops/.gitignore b/Documentation/laptops/.gitignore
new file mode 100644 (file)
index 0000000..da2bd06
--- /dev/null
@@ -0,0 +1,2 @@
+dslm
+freefall
index ebff6ee..c6594af 100644 (file)
@@ -53,10 +53,12 @@ unregister the PHY.
 The PHY driver should create the PHY in order for other peripheral controllers
 to make use of it. The PHY framework provides 2 APIs to create the PHY.
 
-struct phy *phy_create(struct device *dev, const struct phy_ops *ops,
-        struct phy_init_data *init_data);
-struct phy *devm_phy_create(struct device *dev, const struct phy_ops *ops,
-       struct phy_init_data *init_data);
+struct phy *phy_create(struct device *dev, struct device_node *node,
+                      const struct phy_ops *ops,
+                      struct phy_init_data *init_data);
+struct phy *devm_phy_create(struct device *dev, struct device_node *node,
+                           const struct phy_ops *ops,
+                           struct phy_init_data *init_data);
 
 The PHY drivers can use one of the above 2 APIs to create the PHY by passing
 the device pointer, phy ops and init_data.
diff --git a/Documentation/prctl/.gitignore b/Documentation/prctl/.gitignore
new file mode 100644 (file)
index 0000000..0b5c274
--- /dev/null
@@ -0,0 +1,3 @@
+disable-tsc-ctxt-sw-stress-test
+disable-tsc-on-off-stress-test
+disable-tsc-test
index f8e8e95..81fdd42 100644 (file)
 # define PR_TSC_SIGSEGV                2   /* throw a SIGSEGV instead of reading the TSC */
 #endif
 
-uint64_t rdtsc() {
+static uint64_t rdtsc(void)
+{
 uint32_t lo, hi;
 /* We cannot use "=A", since this would use %rax on x86_64 */
 __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
 return (uint64_t)hi << 32 | lo;
 }
 
-void sigsegv_expect(int sig)
+static void sigsegv_expect(int sig)
 {
        /* */
 }
 
-void segvtask(void)
+static void segvtask(void)
 {
        if (prctl(PR_SET_TSC, PR_TSC_SIGSEGV) < 0)
        {
@@ -54,13 +55,13 @@ void segvtask(void)
 }
 
 
-void sigsegv_fail(int sig)
+static void sigsegv_fail(int sig)
 {
        fprintf(stderr, "FATAL ERROR, rdtsc() failed while enabled\n");
        exit(0);
 }
 
-void rdtsctask(void)
+static void rdtsctask(void)
 {
        if (prctl(PR_SET_TSC, PR_TSC_ENABLE) < 0)
        {
index 1fcd914..4d83a27 100644 (file)
@@ -29,7 +29,8 @@
 
 /* snippet from wikipedia :-) */
 
-uint64_t rdtsc() {
+static uint64_t rdtsc(void)
+{
 uint32_t lo, hi;
 /* We cannot use "=A", since this would use %rax on x86_64 */
 __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
@@ -38,7 +39,7 @@ return (uint64_t)hi << 32 | lo;
 
 int should_segv = 0;
 
-void sigsegv_cb(int sig)
+static void sigsegv_cb(int sig)
 {
        if (!should_segv)
        {
@@ -55,7 +56,7 @@ void sigsegv_cb(int sig)
        rdtsc();
 }
 
-void task(void)
+static void task(void)
 {
        signal(SIGSEGV, sigsegv_cb);
        alarm(10);
index 843c81e..2541e65 100644 (file)
@@ -29,14 +29,15 @@ const char *tsc_names[] =
        [PR_TSC_SIGSEGV] = "PR_TSC_SIGSEGV",
 };
 
-uint64_t rdtsc() {
+static uint64_t rdtsc(void)
+{
 uint32_t lo, hi;
 /* We cannot use "=A", since this would use %rax on x86_64 */
 __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
 return (uint64_t)hi << 32 | lo;
 }
 
-void sigsegv_cb(int sig)
+static void sigsegv_cb(int sig)
 {
        int tsc_val = 0;
 
diff --git a/Documentation/ptp/.gitignore b/Documentation/ptp/.gitignore
new file mode 100644 (file)
index 0000000..f562e49
--- /dev/null
@@ -0,0 +1 @@
+testptp
diff --git a/Documentation/timers/.gitignore b/Documentation/timers/.gitignore
new file mode 100644 (file)
index 0000000..c5c45d7
--- /dev/null
@@ -0,0 +1 @@
+hpet_example
diff --git a/Documentation/vDSO/.gitignore b/Documentation/vDSO/.gitignore
new file mode 100644 (file)
index 0000000..133bf9e
--- /dev/null
@@ -0,0 +1,2 @@
+vdso_test
+vdso_standalone_test_x86
diff --git a/Documentation/video4linux/.gitignore b/Documentation/video4linux/.gitignore
deleted file mode 100644 (file)
index 9527039..0000000
+++ /dev/null
@@ -1 +0,0 @@
-v4lgrab
index 8cea0d2..a2fa744 100644 (file)
@@ -1262,6 +1262,19 @@ W:       http://oss.renesas.com
 Q:     http://patchwork.kernel.org/project/linux-sh/list/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git next
 S:     Supported
+F:     arch/arm/boot/dts/emev2*
+F:     arch/arm/boot/dts/r7s*
+F:     arch/arm/boot/dts/r8a*
+F:     arch/arm/boot/dts/sh*
+F:     arch/arm/configs/ape6evm_defconfig
+F:     arch/arm/configs/armadillo800eva_defconfig
+F:     arch/arm/configs/bockw_defconfig
+F:     arch/arm/configs/kzm9g_defconfig
+F:     arch/arm/configs/lager_defconfig
+F:     arch/arm/configs/mackerel_defconfig
+F:     arch/arm/configs/marzen_defconfig
+F:     arch/arm/configs/shmobile_defconfig
+F:     arch/arm/include/debug/renesas-scif.S
 F:     arch/arm/mach-shmobile/
 F:     drivers/sh/
 
index d0c19fc..de8d637 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 3
 PATCHLEVEL = 14
-SUBLEVEL = 24
+SUBLEVEL = 26
 EXTRAVERSION = -ltsi
 NAME = Remembering Coco
 
index 69fc8c1..9542b56 100644 (file)
@@ -677,6 +677,7 @@ config ARCH_SHMOBILE_LEGACY
        select ARCH_SHMOBILE
        select ARM_PATCH_PHYS_VIRT
        select CLKDEV_LOOKUP
+       select CPU_V7
        select GENERIC_CLOCKEVENTS
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
@@ -687,6 +688,7 @@ config ARCH_SHMOBILE_LEGACY
        select NO_IOPORT_MAP
        select PINCTRL
        select PM_GENERIC_DOMAINS if PM
+       select SH_CLK_CPG
        select SPARSE_IRQ
        help
          Support for Renesas ARM SoC platforms using a non-multiplatform
index 0531da8..ba02316 100644 (file)
@@ -626,6 +626,64 @@ choice
                  Say Y here if you want kernel low-level debugging support
                  on Rockchip based platforms.
 
+       config DEBUG_R7S72100_SCIF2
+               bool "Kernel low-level debugging messages via SCIF2 on R7S72100"
+               depends on ARCH_R7S72100
+               help
+                 Say Y here if you want kernel low-level debugging support
+                 via SCIF2 on Renesas RZ/A1H (R7S72100).
+
+       config DEBUG_RCAR_GEN1_SCIF0
+               bool "Kernel low-level debugging messages via SCIF0 on R8A7778"
+               depends on ARCH_R8A7778
+               help
+                 Say Y here if you want kernel low-level debugging support
+                 via SCIF0 on Renesas R-Car M1A (R8A7778).
+
+       config DEBUG_RCAR_GEN1_SCIF2
+               bool "Kernel low-level debugging messages via SCIF2 on R8A7779"
+               depends on ARCH_R8A7779
+               help
+                 Say Y here if you want kernel low-level debugging support
+                 via SCIF2 on Renesas R-Car H1 (R8A7779).
+
+       config DEBUG_RCAR_GEN2_SCIF0
+               bool "Kernel low-level debugging messages via SCIF0 on R8A7790/R8A7791/R8A7793)"
+               depends on ARCH_R8A7790 || ARCH_R8A7791 || ARCH_R8A7793
+               help
+                 Say Y here if you want kernel low-level debugging support
+                 via SCIF0 on Renesas R-Car H2 (R8A7790), M2-W (R8A7791), or
+                 M2-N (R8A7793).
+
+       config DEBUG_RCAR_GEN2_SCIF2
+               bool "Kernel low-level debugging messages via SCIF2 on R8A7794"
+               depends on ARCH_R8A7794
+               help
+                 Say Y here if you want kernel low-level debugging support
+                 via SCIF2 on Renesas R-Car E2 (R8A7794).
+
+       config DEBUG_RMOBILE_SCIFA0
+               bool "Kernel low-level debugging messages via SCIFA0 on R8A73A4/SH7372"
+               depends on ARCH_R8A73A4 || ARCH_SH7372
+               help
+                 Say Y here if you want kernel low-level debugging support
+                 via SCIFA0 on Renesas R-Mobile APE6 (R8A73A4) or SH-Mobile
+                 AP4 (SH7372).
+
+       config DEBUG_RMOBILE_SCIFA1
+               bool "Kernel low-level debugging messages via SCIFA1 on R8A7740"
+               depends on ARCH_R8A7740
+               help
+                 Say Y here if you want kernel low-level debugging support
+                 via SCIFA1 on Renesas R-Mobile A1 (R8A7740).
+
+       config DEBUG_RMOBILE_SCIFA4
+               bool "Kernel low-level debugging messages via SCIFA4 on SH73A0"
+               depends on ARCH_SH73A0
+               help
+                 Say Y here if you want kernel low-level debugging support
+                 via SCIFA4 on Renesas SH-Mobile AG5 (SH73A0).
+
        config DEBUG_S3C_UART0
                depends on PLAT_SAMSUNG
                select DEBUG_EXYNOS_UART if ARCH_EXYNOS
@@ -977,6 +1035,14 @@ config DEBUG_LL_INCLUDE
                                 DEBUG_IMX6SL_UART
        default "debug/msm.S" if DEBUG_MSM_UART
        default "debug/omap2plus.S" if DEBUG_OMAP2PLUS_UART
+       default "debug/renesas-scif.S" if DEBUG_R7S72100_SCIF2
+       default "debug/renesas-scif.S" if DEBUG_RCAR_GEN1_SCIF0
+       default "debug/renesas-scif.S" if DEBUG_RCAR_GEN1_SCIF2
+       default "debug/renesas-scif.S" if DEBUG_RCAR_GEN2_SCIF0
+       default "debug/renesas-scif.S" if DEBUG_RCAR_GEN2_SCIF2
+       default "debug/renesas-scif.S" if DEBUG_RMOBILE_SCIFA0
+       default "debug/renesas-scif.S" if DEBUG_RMOBILE_SCIFA1
+       default "debug/renesas-scif.S" if DEBUG_RMOBILE_SCIFA4
        default "debug/sirf.S" if DEBUG_SIRFPRIMA2_UART1 || DEBUG_SIRFMARCO_UART1
        default "debug/sti.S" if DEBUG_STI_UART
        default "debug/tegra.S" if DEBUG_TEGRA_UART
@@ -1048,6 +1114,12 @@ config DEBUG_UART_PHYS
        default 0xd4017000 if DEBUG_MMP_UART2
        default 0xd4018000 if DEBUG_MMP_UART3
        default 0xe0000000 if ARCH_SPEAR13XX
+       default 0xe6c40000 if DEBUG_RMOBILE_SCIFA0
+       default 0xe6c50000 if DEBUG_RMOBILE_SCIFA1
+       default 0xe6c80000 if DEBUG_RMOBILE_SCIFA4
+       default 0xe6e58000 if DEBUG_RCAR_GEN2_SCIF2
+       default 0xe6e60000 if DEBUG_RCAR_GEN2_SCIF0
+       default 0xe8008000 if DEBUG_R7S72100_SCIF2
        default 0xf0000be0 if ARCH_EBSA110
        default 0xf1012000 if DEBUG_MVEBU_UART_ALTERNATE
        default 0xf1012000 if ARCH_DOVE || ARCH_KIRKWOOD || ARCH_MV78XX0 || \
@@ -1058,11 +1130,19 @@ config DEBUG_UART_PHYS
        default 0xfe800000 if ARCH_IOP32X
        default 0xffc02000 if DEBUG_SOCFPGA_UART
        default 0xffd82340 if ARCH_IOP13XX
+       default 0xffe40000 if DEBUG_RCAR_GEN1_SCIF0
+       default 0xffe42000 if DEBUG_RCAR_GEN1_SCIF2
        default 0xfff36000 if DEBUG_HIGHBANK_UART
        default 0xfffff700 if ARCH_IOP33X
        depends on DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \
                DEBUG_LL_UART_EFM32 || \
-               DEBUG_UART_8250 || DEBUG_UART_PL01X
+               DEBUG_UART_8250 || DEBUG_UART_PL01X || \\
+               DEBUG_R7S72100_SCIF2 || \
+               DEBUG_RCAR_GEN1_SCIF0 || DEBUG_RCAR_GEN1_SCIF2 || \
+               DEBUG_RCAR_GEN2_SCIF0 || DEBUG_RCAR_GEN2_SCIF2 || \
+               DEBUG_RMOBILE_SCIFA0 || DEBUG_RMOBILE_SCIFA1 || \
+               DEBUG_RMOBILE_SCIFA4 || DEBUG_S3C24XX_UART || \
+               DEBUG_UART_BCM63XX
 
 config DEBUG_UART_VIRT
        hex "Virtual base address of debug UART"
index 066b034..8017cde 100644 (file)
@@ -400,8 +400,7 @@ dtb_check_done:
                add     sp, sp, r6
 #endif
 
-               tst     r4, #1
-               bleq    cache_clean_flush
+               bl      cache_clean_flush
 
                adr     r0, BSYM(restart)
                add     r0, r0, r6
@@ -1050,6 +1049,8 @@ cache_clean_flush:
                b       call_cache_fn
 
 __armv4_mpu_cache_flush:
+               tst     r4, #1
+               movne   pc, lr
                mov     r2, #1
                mov     r3, #0
                mcr     p15, 0, ip, c7, c6, 0   @ invalidate D cache
@@ -1067,6 +1068,8 @@ __armv4_mpu_cache_flush:
                mov     pc, lr
                
 __fa526_cache_flush:
+               tst     r4, #1
+               movne   pc, lr
                mov     r1, #0
                mcr     p15, 0, r1, c7, c14, 0  @ clean and invalidate D cache
                mcr     p15, 0, r1, c7, c5, 0   @ flush I cache
@@ -1075,13 +1078,16 @@ __fa526_cache_flush:
 
 __armv6_mmu_cache_flush:
                mov     r1, #0
-               mcr     p15, 0, r1, c7, c14, 0  @ clean+invalidate D
+               tst     r4, #1
+               mcreq   p15, 0, r1, c7, c14, 0  @ clean+invalidate D
                mcr     p15, 0, r1, c7, c5, 0   @ invalidate I+BTB
-               mcr     p15, 0, r1, c7, c15, 0  @ clean+invalidate unified
+               mcreq   p15, 0, r1, c7, c15, 0  @ clean+invalidate unified
                mcr     p15, 0, r1, c7, c10, 4  @ drain WB
                mov     pc, lr
 
 __armv7_mmu_cache_flush:
+               tst     r4, #1
+               bne     iflush
                mrc     p15, 0, r10, c0, c1, 5  @ read ID_MMFR1
                tst     r10, #0xf << 16         @ hierarchical cache (ARMv7)
                mov     r10, #0
@@ -1142,6 +1148,8 @@ iflush:
                mov     pc, lr
 
 __armv5tej_mmu_cache_flush:
+               tst     r4, #1
+               movne   pc, lr
 1:             mrc     p15, 0, r15, c7, c14, 3 @ test,clean,invalidate D cache
                bne     1b
                mcr     p15, 0, r0, c7, c5, 0   @ flush I cache
@@ -1149,6 +1157,8 @@ __armv5tej_mmu_cache_flush:
                mov     pc, lr
 
 __armv4_mmu_cache_flush:
+               tst     r4, #1
+               movne   pc, lr
                mov     r2, #64*1024            @ default: 32K dcache size (*2)
                mov     r11, #32                @ default: 32 byte line size
                mrc     p15, 0, r3, c0, c0, 1   @ read cache type
@@ -1182,6 +1192,8 @@ no_cache_id:
 
 __armv3_mmu_cache_flush:
 __armv3_mpu_cache_flush:
+               tst     r4, #1
+               movne   pc, lr
                mov     r1, #0
                mcr     p15, 0, r1, c7, c0, 0   @ invalidate whole cache v3
                mov     pc, lr
index 29cc71e..e744f93 100644 (file)
@@ -248,7 +248,6 @@ dtb-$(CONFIG_ARCH_SHMOBILE_LEGACY) += r7s72100-genmai.dtb \
        r8a7740-armadillo800eva.dtb \
        r8a7778-bockw.dtb \
        r8a7778-bockw-reference.dtb \
-       r8a7740-armadillo800eva-reference.dtb \
        r8a7779-marzen.dtb \
        r8a7791-koelsch.dtb \
        r8a7790-lager.dtb \
@@ -262,7 +261,8 @@ dtb-$(CONFIG_ARCH_SHMOBILE_MULTI) += emev2-kzm9d.dtb \
        r8a7791-henninger.dtb \
        r8a7791-koelsch.dtb \
        r8a7790-lager.dtb \
-       r8a7779-marzen.dtb
+       r8a7779-marzen.dtb \
+       r8a7794-alt.dtb
 dtb-$(CONFIG_ARCH_SOCFPGA) += socfpga_arria5_socdk.dtb \
        socfpga_cyclone5_socdk.dtb \
        socfpga_cyclone5_sockit.dtb \
index 50ccd15..667d323 100644 (file)
 
        chosen {
                bootargs = "console=ttyS1,115200n81 ignore_loglevel root=/dev/nfs ip=dhcp";
-       };
-
-       reg_1p8v: regulator@0 {
-               compatible = "regulator-fixed";
-               regulator-name = "fixed-1.8V";
-               regulator-min-microvolt = <1800000>;
-               regulator-max-microvolt = <1800000>;
-               regulator-always-on;
-               regulator-boot-on;
-       };
-
-       reg_3p3v: regulator@1 {
-               compatible = "regulator-fixed";
-               regulator-name = "fixed-3.3V";
-               regulator-min-microvolt = <3300000>;
-               regulator-max-microvolt = <3300000>;
-               regulator-always-on;
-               regulator-boot-on;
-       };
-
-       lan9220@20000000 {
-               compatible = "smsc,lan9220", "smsc,lan9115";
-               reg = <0x20000000 0x10000>;
-               phy-mode = "mii";
-               interrupt-parent = <&gpio0>;
-               interrupts = <1 IRQ_TYPE_EDGE_RISING>;
-               reg-io-width = <4>;
-               smsc,irq-active-high;
-               smsc,irq-push-pull;
-               vddvario-supply = <&reg_1p8v>;
-               vdd33a-supply = <&reg_3p3v>;
+               stdout-path = &uart1;
        };
 
        gpio_keys {
                        gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>;
                };
        };
+
+       reg_1p8v: regulator@0 {
+               compatible = "regulator-fixed";
+               regulator-name = "fixed-1.8V";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               regulator-always-on;
+               regulator-boot-on;
+       };
+
+       reg_3p3v: regulator@1 {
+               compatible = "regulator-fixed";
+               regulator-name = "fixed-3.3V";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+               regulator-boot-on;
+       };
+
+       lan9220@20000000 {
+               compatible = "smsc,lan9220", "smsc,lan9115";
+               reg = <0x20000000 0x10000>;
+               phy-mode = "mii";
+               interrupt-parent = <&gpio0>;
+               interrupts = <1 IRQ_TYPE_EDGE_RISING>;
+               reg-io-width = <4>;
+               smsc,irq-active-high;
+               smsc,irq-push-pull;
+               vddvario-supply = <&reg_1p8v>;
+               vdd33a-supply = <&reg_3p3v>;
+       };
 };
index 00eeed3..cc7bfe0 100644 (file)
@@ -55,7 +55,7 @@
                             <0 121 IRQ_TYPE_LEVEL_HIGH>;
        };
 
-       smu@e0110000 {
+       clocks@e0110000 {
                compatible = "renesas,emev2-smu";
                reg = <0xe0110000 0x10000>;
                #address-cells = <2>;
                };
        };
 
-       sti@e0180000 {
+       timer@e0180000 {
                compatible = "renesas,em-sti";
                reg = <0xe0180000 0x54>;
                interrupts = <0 125 IRQ_TYPE_LEVEL_HIGH>;
                clock-names = "sclk";
        };
 
-       uart@e1020000 {
+       uart0: serial@e1020000 {
                compatible = "renesas,em-uart";
                reg = <0xe1020000 0x38>;
                interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>;
                clock-names = "sclk";
        };
 
-       uart@e1030000 {
+       uart1: serial@e1030000 {
                compatible = "renesas,em-uart";
                reg = <0xe1030000 0x38>;
                interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>;
                clock-names = "sclk";
        };
 
-       uart@e1040000 {
+       uart2: serial@e1040000 {
                compatible = "renesas,em-uart";
                reg = <0xe1040000 0x38>;
                interrupts = <0 10 IRQ_TYPE_LEVEL_HIGH>;
                clock-names = "sclk";
        };
 
-       uart@e1050000 {
+       uart3: serial@e1050000 {
                compatible = "renesas,em-uart";
                reg = <0xe1050000 0x38>;
                interrupts = <0 11 IRQ_TYPE_LEVEL_HIGH>;
index a9b6e10..fb85ba9 100644 (file)
        };
 
        pmic: dialog@48 {
-               compatible = "dialog,da9053", "dialog,da9052";
+               compatible = "dlg,da9053", "dlg,da9052";
                reg = <0x48>;
        };
 };
diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi
new file mode 100644 (file)
index 0000000..0e50bb0
--- /dev/null
@@ -0,0 +1,357 @@
+/*
+ * Copyright 2013 Christian Hemp, Phytec Messtechnik GmbH
+ *
+ * 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 <dt-bindings/gpio/gpio.h>
+
+/ {
+       model = "Phytec phyFLEX-i.MX6 Ouad";
+       compatible = "phytec,imx6q-pfla02", "fsl,imx6q";
+
+       memory {
+               reg = <0x10000000 0x80000000>;
+       };
+
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               reg_usb_otg_vbus: regulator@0 {
+                       compatible = "regulator-fixed";
+                       reg = <0>;
+                       regulator-name = "usb_otg_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio4 15 0>;
+               };
+
+               reg_usb_h1_vbus: regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "usb_h1_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio1 0 0>;
+               };
+       };
+
+       gpio_leds: leds {
+               compatible = "gpio-leds";
+
+               green {
+                       label = "phyflex:green";
+                       gpios = <&gpio1 30 0>;
+               };
+
+               red {
+                       label = "phyflex:red";
+                       gpios = <&gpio2 31 0>;
+               };
+       };
+};
+
+&ecspi3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ecspi3>;
+       status = "okay";
+       fsl,spi-num-chipselects = <1>;
+       cs-gpios = <&gpio4 24 0>;
+
+       flash@0 {
+               compatible = "m25p80";
+               spi-max-frequency = <20000000>;
+               reg = <0>;
+       };
+};
+
+&i2c1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       eeprom@50 {
+               compatible = "atmel,24c32";
+               reg = <0x50>;
+       };
+
+       pmic@58 {
+               compatible = "dlg,da9063";
+               reg = <0x58>;
+               interrupt-parent = <&gpio4>;
+               interrupts = <17 0x8>; /* active-low GPIO4_17 */
+
+               regulators {
+                       vddcore_reg: bcore1 {
+                               regulator-min-microvolt = <730000>;
+                               regulator-max-microvolt = <1380000>;
+                               regulator-always-on;
+                       };
+
+                       vddsoc_reg: bcore2 {
+                               regulator-min-microvolt = <730000>;
+                               regulator-max-microvolt = <1380000>;
+                               regulator-always-on;
+                       };
+
+                       vdd_ddr3_reg: bpro {
+                               regulator-min-microvolt = <1500000>;
+                               regulator-max-microvolt = <1500000>;
+                               regulator-always-on;
+                       };
+
+                       vdd_3v3_reg: bperi {
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vdd_buckmem_reg: bmem {
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vdd_eth_reg: bio {
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <1200000>;
+                               regulator-always-on;
+                       };
+
+                       vdd_eth_io_reg: ldo4 {
+                               regulator-min-microvolt = <2500000>;
+                               regulator-max-microvolt = <2500000>;
+                               regulator-always-on;
+                       };
+
+                       vdd_mx6_snvs_reg: ldo5 {
+                               regulator-min-microvolt = <3000000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-always-on;
+                       };
+
+                       vdd_3v3_pmic_io_reg: ldo6 {
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vdd_sd0_reg: ldo9 {
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+
+                       vdd_sd1_reg: ldo10 {
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+
+                       vdd_mx6_high_reg: ldo11 {
+                               regulator-min-microvolt = <3000000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-always-on;
+                       };
+               };
+       };
+};
+
+&iomuxc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_hog>;
+
+       imx6q-phytec-pfla02 {
+               pinctrl_hog: hoggrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_D23__GPIO3_IO23 0x80000000
+                               MX6QDL_PAD_DISP0_DAT3__GPIO4_IO24 0x80000000 /* SPI NOR chipselect */
+                               MX6QDL_PAD_DI0_PIN15__GPIO4_IO17  0x80000000 /* PMIC interrupt */
+                               MX6QDL_PAD_ENET_TXD0__GPIO1_IO30 0x80000000 /* Green LED */
+                               MX6QDL_PAD_EIM_EB3__GPIO2_IO31 0x80000000 /* Red LED */
+                       >;
+               };
+
+               pinctrl_ecspi3: ecspi3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_DISP0_DAT2__ECSPI3_MISO      0x100b1
+                               MX6QDL_PAD_DISP0_DAT1__ECSPI3_MOSI      0x100b1
+                               MX6QDL_PAD_DISP0_DAT0__ECSPI3_SCLK      0x100b1
+                       >;
+               };
+
+               pinctrl_enet: enetgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_ENET_MDIO__ENET_MDIO         0x1b0b0
+                               MX6QDL_PAD_ENET_MDC__ENET_MDC           0x1b0b0
+                               MX6QDL_PAD_RGMII_TXC__RGMII_TXC         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD0__RGMII_TD0         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD1__RGMII_TD1         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD2__RGMII_TD2         0x1b0b0
+                               MX6QDL_PAD_RGMII_TD3__RGMII_TD3         0x1b0b0
+                               MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL   0x1b0b0
+                               MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK    0x1b0b0
+                               MX6QDL_PAD_RGMII_RXC__RGMII_RXC         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD0__RGMII_RD0         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD1__RGMII_RD1         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD2__RGMII_RD2         0x1b0b0
+                               MX6QDL_PAD_RGMII_RD3__RGMII_RD3         0x1b0b0
+                               MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL   0x1b0b0
+                               MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN       0x1b0b0
+                       >;
+               };
+
+               pinctrl_gpmi_nand: gpminandgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_NANDF_CLE__NAND_CLE          0xb0b1
+                               MX6QDL_PAD_NANDF_ALE__NAND_ALE          0xb0b1
+                               MX6QDL_PAD_NANDF_WP_B__NAND_WP_B        0xb0b1
+                               MX6QDL_PAD_NANDF_RB0__NAND_READY_B      0xb000
+                               MX6QDL_PAD_NANDF_CS0__NAND_CE0_B        0xb0b1
+                               MX6QDL_PAD_NANDF_CS1__NAND_CE1_B        0xb0b1
+                               MX6QDL_PAD_SD4_CMD__NAND_RE_B           0xb0b1
+                               MX6QDL_PAD_SD4_CLK__NAND_WE_B           0xb0b1
+                               MX6QDL_PAD_NANDF_D0__NAND_DATA00        0xb0b1
+                               MX6QDL_PAD_NANDF_D1__NAND_DATA01        0xb0b1
+                               MX6QDL_PAD_NANDF_D2__NAND_DATA02        0xb0b1
+                               MX6QDL_PAD_NANDF_D3__NAND_DATA03        0xb0b1
+                               MX6QDL_PAD_NANDF_D4__NAND_DATA04        0xb0b1
+                               MX6QDL_PAD_NANDF_D5__NAND_DATA05        0xb0b1
+                               MX6QDL_PAD_NANDF_D6__NAND_DATA06        0xb0b1
+                               MX6QDL_PAD_NANDF_D7__NAND_DATA07        0xb0b1
+                               MX6QDL_PAD_SD4_DAT0__NAND_DQS           0x00b1
+                       >;
+               };
+
+               pinctrl_i2c1: i2c1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_D21__I2C1_SCL            0x4001b8b1
+                               MX6QDL_PAD_EIM_D28__I2C1_SDA            0x4001b8b1
+                       >;
+               };
+
+               pinctrl_uart3: uart3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_D24__UART3_TX_DATA       0x1b0b1
+                               MX6QDL_PAD_EIM_D25__UART3_RX_DATA       0x1b0b1
+                               MX6QDL_PAD_EIM_D30__UART3_RTS_B         0x1b0b1
+                               MX6QDL_PAD_EIM_D31__UART3_CTS_B         0x1b0b1
+                       >;
+               };
+
+               pinctrl_uart4: uart4grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_KEY_COL0__UART4_TX_DATA      0x1b0b1
+                               MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA      0x1b0b1
+                       >;
+               };
+
+               pinctrl_usbh1: usbh1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_GPIO_0__USB_H1_PWR           0x80000000
+                       >;
+               };
+
+               pinctrl_usbotg: usbotggrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_GPIO_1__USB_OTG_ID           0x17059
+                               MX6QDL_PAD_KEY_COL4__USB_OTG_OC         0x1b0b0
+                               MX6QDL_PAD_KEY_ROW4__GPIO4_IO15         0x80000000
+                       >;
+               };
+
+               pinctrl_usdhc2: usdhc2grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD2_CMD__SD2_CMD             0x17059
+                               MX6QDL_PAD_SD2_CLK__SD2_CLK             0x10059
+                               MX6QDL_PAD_SD2_DAT0__SD2_DATA0          0x17059
+                               MX6QDL_PAD_SD2_DAT1__SD2_DATA1          0x17059
+                               MX6QDL_PAD_SD2_DAT2__SD2_DATA2          0x17059
+                               MX6QDL_PAD_SD2_DAT3__SD2_DATA3          0x17059
+                       >;
+               };
+
+               pinctrl_usdhc3: usdhc3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD3_CMD__SD3_CMD             0x17059
+                               MX6QDL_PAD_SD3_CLK__SD3_CLK             0x10059
+                               MX6QDL_PAD_SD3_DAT0__SD3_DATA0          0x17059
+                               MX6QDL_PAD_SD3_DAT1__SD3_DATA1          0x17059
+                               MX6QDL_PAD_SD3_DAT2__SD3_DATA2          0x17059
+                               MX6QDL_PAD_SD3_DAT3__SD3_DATA3          0x17059
+                       >;
+               };
+
+               pinctrl_usdhc3_cdwp: usdhc3cdwp {
+                       fsl,pins = <
+                               MX6QDL_PAD_ENET_RXD0__GPIO1_IO27 0x80000000
+                               MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000
+                       >;
+               };
+       };
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet>;
+       phy-mode = "rgmii";
+       phy-reset-gpios = <&gpio3 23 GPIO_ACTIVE_LOW>;
+       phy-supply = <&vdd_eth_io_reg>;
+       status = "disabled";
+};
+
+&gpmi {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_gpmi_nand>;
+       nand-on-flash-bbt;
+       status = "disabled";
+};
+
+&uart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart3>;
+       status = "disabled";
+};
+
+&uart4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart4>;
+       status = "disabled";
+};
+
+&usbh1 {
+       vbus-supply = <&reg_usb_h1_vbus>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbh1>;
+       status = "disabled";
+};
+
+&usbotg {
+       vbus-supply = <&reg_usb_otg_vbus>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg>;
+       disable-over-current;
+       status = "disabled";
+};
+
+&usdhc2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc2>;
+       cd-gpios = <&gpio1 4 0>;
+       wp-gpios = <&gpio1 2 0>;
+       status = "disabled";
+};
+
+&usdhc3 {
+        pinctrl-names = "default";
+        pinctrl-0 = <&pinctrl_usdhc3
+                    &pinctrl_usdhc3_cdwp>;
+        cd-gpios = <&gpio1 27 0>;
+        wp-gpios = <&gpio1 29 0>;
+        status = "disabled";
+};
index 2070546..1518c5b 100644 (file)
@@ -21,7 +21,8 @@
        };
 
        chosen {
-               bootargs = "console=ttySC2,115200 ignore_loglevel rw root=/dev/nfs ip=dhcp";
+               bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp";
+               stdout-path = &scif2;
        };
 
        memory {
        clock-frequency = <48000000>;
 };
 
+&mtu2 {
+       status = "ok";
+};
+
 &i2c2 {
        status = "okay";
        clock-frequency = <400000>;
index bdee225..277e73c 100644 (file)
                        clock-output-names = "usb_x1";
                };
 
-               /* Special CPG clocks */
-               cpg_clocks: cpg_clocks@fcfe0000 {
-                       #clock-cells = <1>;
-                       compatible = "renesas,r7s72100-cpg-clocks",
-                                    "renesas,rz-cpg-clocks";
-                       reg = <0xfcfe0000 0x18>;
-                       clocks = <&extal_clk>, <&usb_x1_clk>;
-                       clock-output-names = "pll", "i", "g";
-               };
-
                /* Fixed factor clocks */
                b_clk: b_clk {
                        #clock-cells = <0>;
                        clock-output-names = "p0";
                };
 
+               /* Special CPG clocks */
+               cpg_clocks: cpg_clocks@fcfe0000 {
+                       #clock-cells = <1>;
+                       compatible = "renesas,r7s72100-cpg-clocks",
+                                    "renesas,rz-cpg-clocks";
+                       reg = <0xfcfe0000 0x18>;
+                       clocks = <&extal_clk>, <&usb_x1_clk>;
+                       clock-output-names = "pll", "i", "g";
+               };
+
                /* MSTP clocks */
                mstp3_clks: mstp3_clks@fcfe0420 {
                        #clock-cells = <1>;
                };
        };
 
-       gic: interrupt-controller@e8201000 {
-               compatible = "arm,cortex-a9-gic";
-               #interrupt-cells = <3>;
-               #address-cells = <0>;
-               interrupt-controller;
-               reg = <0xe8201000 0x1000>,
-                       <0xe8202000 0x1000>;
-       };
-
-       i2c0: i2c@fcfee000 {
-               #address-cells = <1>;
-               #size-cells = <0>;
-               compatible = "renesas,riic-r7s72100", "renesas,riic-rz";
-               reg = <0xfcfee000 0x44>;
-               interrupts = <0 157 IRQ_TYPE_LEVEL_HIGH>,
-                            <0 158 IRQ_TYPE_EDGE_RISING>,
-                            <0 159 IRQ_TYPE_EDGE_RISING>,
-                            <0 160 IRQ_TYPE_LEVEL_HIGH>,
-                            <0 161 IRQ_TYPE_LEVEL_HIGH>,
-                            <0 162 IRQ_TYPE_LEVEL_HIGH>,
-                            <0 163 IRQ_TYPE_LEVEL_HIGH>,
-                            <0 164 IRQ_TYPE_LEVEL_HIGH>;
-               clocks = <&mstp9_clks R7S72100_CLK_I2C0>;
-               clock-frequency = <100000>;
-               status = "disabled";
-       };
-
-       i2c1: i2c@fcfee400 {
-               #address-cells = <1>;
-               #size-cells = <0>;
-               compatible = "renesas,riic-r7s72100", "renesas,riic-rz";
-               reg = <0xfcfee400 0x44>;
-               interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>,
-                            <0 166 IRQ_TYPE_EDGE_RISING>,
-                            <0 167 IRQ_TYPE_EDGE_RISING>,
-                            <0 168 IRQ_TYPE_LEVEL_HIGH>,
-                            <0 169 IRQ_TYPE_LEVEL_HIGH>,
-                            <0 170 IRQ_TYPE_LEVEL_HIGH>,
-                            <0 171 IRQ_TYPE_LEVEL_HIGH>,
-                            <0 172 IRQ_TYPE_LEVEL_HIGH>;
-               clocks = <&mstp9_clks R7S72100_CLK_I2C1>;
-               clock-frequency = <100000>;
-               status = "disabled";
-       };
-
-       i2c2: i2c@fcfee800 {
-               #address-cells = <1>;
-               #size-cells = <0>;
-               compatible = "renesas,riic-r7s72100", "renesas,riic-rz";
-               reg = <0xfcfee800 0x44>;
-               interrupts = <0 173 IRQ_TYPE_LEVEL_HIGH>,
-                            <0 174 IRQ_TYPE_EDGE_RISING>,
-                            <0 175 IRQ_TYPE_EDGE_RISING>,
-                            <0 176 IRQ_TYPE_LEVEL_HIGH>,
-                            <0 177 IRQ_TYPE_LEVEL_HIGH>,
-                            <0 178 IRQ_TYPE_LEVEL_HIGH>,
-                            <0 179 IRQ_TYPE_LEVEL_HIGH>,
-                            <0 180 IRQ_TYPE_LEVEL_HIGH>;
-               clocks = <&mstp9_clks R7S72100_CLK_I2C2>;
-               clock-frequency = <100000>;
-               status = "disabled";
-       };
-
-       i2c3: i2c@fcfeec00 {
-               #address-cells = <1>;
-               #size-cells = <0>;
-               compatible = "renesas,riic-r7s72100", "renesas,riic-rz";
-               reg = <0xfcfeec00 0x44>;
-               interrupts = <0 181 IRQ_TYPE_LEVEL_HIGH>,
-                            <0 182 IRQ_TYPE_EDGE_RISING>,
-                            <0 183 IRQ_TYPE_EDGE_RISING>,
-                            <0 184 IRQ_TYPE_LEVEL_HIGH>,
-                            <0 185 IRQ_TYPE_LEVEL_HIGH>,
-                            <0 186 IRQ_TYPE_LEVEL_HIGH>,
-                            <0 187 IRQ_TYPE_LEVEL_HIGH>,
-                            <0 188 IRQ_TYPE_LEVEL_HIGH>;
-               clocks = <&mstp9_clks R7S72100_CLK_I2C3>;
-               clock-frequency = <100000>;
-               status = "disabled";
-       };
-
        scif0: serial@e8007000 {
                compatible = "renesas,scif-r7s72100", "renesas,scif";
                reg = <0xe8007000 64>;
                #size-cells = <0>;
                status = "disabled";
        };
+
+       gic: interrupt-controller@e8201000 {
+               compatible = "arm,cortex-a9-gic";
+               #interrupt-cells = <3>;
+               #address-cells = <0>;
+               interrupt-controller;
+               reg = <0xe8201000 0x1000>,
+                       <0xe8202000 0x1000>;
+       };
+
+       i2c0: i2c@fcfee000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "renesas,riic-r7s72100", "renesas,riic-rz";
+               reg = <0xfcfee000 0x44>;
+               interrupts = <0 157 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 158 IRQ_TYPE_EDGE_RISING>,
+                            <0 159 IRQ_TYPE_EDGE_RISING>,
+                            <0 160 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 161 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 162 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 163 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 164 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp9_clks R7S72100_CLK_I2C0>;
+               clock-frequency = <100000>;
+               status = "disabled";
+       };
+
+       i2c1: i2c@fcfee400 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "renesas,riic-r7s72100", "renesas,riic-rz";
+               reg = <0xfcfee400 0x44>;
+               interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 166 IRQ_TYPE_EDGE_RISING>,
+                            <0 167 IRQ_TYPE_EDGE_RISING>,
+                            <0 168 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 169 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 170 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 171 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 172 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp9_clks R7S72100_CLK_I2C1>;
+               clock-frequency = <100000>;
+               status = "disabled";
+       };
+
+       i2c2: i2c@fcfee800 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "renesas,riic-r7s72100", "renesas,riic-rz";
+               reg = <0xfcfee800 0x44>;
+               interrupts = <0 173 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 174 IRQ_TYPE_EDGE_RISING>,
+                            <0 175 IRQ_TYPE_EDGE_RISING>,
+                            <0 176 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 177 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 178 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 179 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 180 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp9_clks R7S72100_CLK_I2C2>;
+               clock-frequency = <100000>;
+               status = "disabled";
+       };
+
+       i2c3: i2c@fcfeec00 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "renesas,riic-r7s72100", "renesas,riic-rz";
+               reg = <0xfcfeec00 0x44>;
+               interrupts = <0 181 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 182 IRQ_TYPE_EDGE_RISING>,
+                            <0 183 IRQ_TYPE_EDGE_RISING>,
+                            <0 184 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 185 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 186 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 187 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 188 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp9_clks R7S72100_CLK_I2C3>;
+               clock-frequency = <100000>;
+               status = "disabled";
+       };
+
+       mtu2: timer@fcff0000 {
+               compatible = "renesas,mtu2-r7s72100", "renesas,mtu2";
+               reg = <0xfcff0000 0x400>;
+               interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "tgi0a";
+               clocks = <&mstp3_clks R7S72100_CLK_MTU2>;
+               clock-names = "fck";
+               status = "disabled";
+       };
 };
index a860f32..84e05f7 100644 (file)
@@ -21,7 +21,8 @@
        };
 
        chosen {
-               bootargs = "console=ttySC0,115200 ignore_loglevel rw";
+               bootargs = "ignore_loglevel rw";
+               stdout-path = &scifa0;
        };
 
        memory@40000000 {
        voltage-tolerance = <1>; /* 1% */
 };
 
+&cmt1 {
+       status = "okay";
+};
+
 &pfc {
        scifa0_pins: serial0 {
                renesas,groups = "scifa0_data";
index d8ec505..5ac57ba 100644 (file)
                };
        };
 
-       gic: interrupt-controller@f1001000 {
-               compatible = "arm,cortex-a15-gic";
-               #interrupt-cells = <3>;
-               #address-cells = <0>;
-               interrupt-controller;
-               reg = <0 0xf1001000 0 0x1000>,
-                       <0 0xf1002000 0 0x1000>,
-                       <0 0xf1004000 0 0x2000>,
-                       <0 0xf1006000 0 0x2000>;
-               interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
-       };
-
        timer {
                compatible = "arm,armv7-timer";
                interrupts = <1 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
                             <1 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
        };
 
+       dmac: dma-multiplexer {
+               compatible = "renesas,shdma-mux";
+               #dma-cells = <1>;
+               dma-channels = <20>;
+               dma-requests = <256>;
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               dma0: dma-controller@e6700020 {
+                       compatible = "renesas,shdma-r8a73a4";
+                       reg = <0 0xe6700020 0 0x89e0>;
+                       interrupts = <0 220 IRQ_TYPE_LEVEL_HIGH
+                                       0 200 IRQ_TYPE_LEVEL_HIGH
+                                       0 201 IRQ_TYPE_LEVEL_HIGH
+                                       0 202 IRQ_TYPE_LEVEL_HIGH
+                                       0 203 IRQ_TYPE_LEVEL_HIGH
+                                       0 204 IRQ_TYPE_LEVEL_HIGH
+                                       0 205 IRQ_TYPE_LEVEL_HIGH
+                                       0 206 IRQ_TYPE_LEVEL_HIGH
+                                       0 207 IRQ_TYPE_LEVEL_HIGH
+                                       0 208 IRQ_TYPE_LEVEL_HIGH
+                                       0 209 IRQ_TYPE_LEVEL_HIGH
+                                       0 210 IRQ_TYPE_LEVEL_HIGH
+                                       0 211 IRQ_TYPE_LEVEL_HIGH
+                                       0 212 IRQ_TYPE_LEVEL_HIGH
+                                       0 213 IRQ_TYPE_LEVEL_HIGH
+                                       0 214 IRQ_TYPE_LEVEL_HIGH
+                                       0 215 IRQ_TYPE_LEVEL_HIGH
+                                       0 216 IRQ_TYPE_LEVEL_HIGH
+                                       0 217 IRQ_TYPE_LEVEL_HIGH
+                                       0 218 IRQ_TYPE_LEVEL_HIGH
+                                       0 219 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "error",
+                                       "ch0", "ch1", "ch2", "ch3",
+                                       "ch4", "ch5", "ch6", "ch7",
+                                       "ch8", "ch9", "ch10", "ch11",
+                                       "ch12", "ch13", "ch14", "ch15",
+                                       "ch16", "ch17", "ch18", "ch19";
+               };
+       };
+
+       pfc: pfc@e6050000 {
+               compatible = "renesas,pfc-r8a73a4";
+               reg = <0 0xe6050000 0 0x9000>;
+               gpio-controller;
+               #gpio-cells = <2>;
+               interrupts-extended =
+                       <&irqc0  0 0>, <&irqc0  1 0>, <&irqc0  2 0>, <&irqc0  3 0>,
+                       <&irqc0  4 0>, <&irqc0  5 0>, <&irqc0  6 0>, <&irqc0  7 0>,
+                       <&irqc0  8 0>, <&irqc0  9 0>, <&irqc0 10 0>, <&irqc0 11 0>,
+                       <&irqc0 12 0>, <&irqc0 13 0>, <&irqc0 14 0>, <&irqc0 15 0>,
+                       <&irqc0 16 0>, <&irqc0 17 0>, <&irqc0 18 0>, <&irqc0 19 0>,
+                       <&irqc0 20 0>, <&irqc0 21 0>, <&irqc0 22 0>, <&irqc0 23 0>,
+                       <&irqc0 24 0>, <&irqc0 25 0>, <&irqc0 26 0>, <&irqc0 27 0>,
+                       <&irqc0 28 0>, <&irqc0 29 0>, <&irqc0 30 0>, <&irqc0 31 0>,
+                       <&irqc1  0 0>, <&irqc1  1 0>, <&irqc1  2 0>, <&irqc1  3 0>,
+                       <&irqc1  4 0>, <&irqc1  5 0>, <&irqc1  6 0>, <&irqc1  7 0>,
+                       <&irqc1  8 0>, <&irqc1  9 0>, <&irqc1 10 0>, <&irqc1 11 0>,
+                       <&irqc1 12 0>, <&irqc1 13 0>, <&irqc1 14 0>, <&irqc1 15 0>,
+                       <&irqc1 16 0>, <&irqc1 17 0>, <&irqc1 18 0>, <&irqc1 19 0>,
+                       <&irqc1 20 0>, <&irqc1 21 0>, <&irqc1 22 0>, <&irqc1 23 0>,
+                       <&irqc1 24 0>, <&irqc1 25 0>;
+       };
+
+       i2c5: i2c@e60b0000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic";
+               reg = <0 0xe60b0000 0 0x428>;
+               interrupts = <0 179 IRQ_TYPE_LEVEL_HIGH>;
+
+               status = "disabled";
+       };
+
+       cmt1: timer@e6130000 {
+               compatible = "renesas,cmt-48-r8a73a4", "renesas,cmt-48-gen2";
+               reg = <0 0xe6130000 0 0x1004>;
+               interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>;
+
+               renesas,channels-mask = <0xff>;
+
+               status = "disabled";
+       };
+
        irqc0: interrupt-controller@e61c0000 {
-               compatible = "renesas,irqc";
+               compatible = "renesas,irqc-r8a73a4", "renesas,irqc";
                #interrupt-cells = <2>;
                interrupt-controller;
                reg = <0 0xe61c0000 0 0x200>;
        };
 
        irqc1: interrupt-controller@e61c0200 {
-               compatible = "renesas,irqc";
+               compatible = "renesas,irqc-r8a73a4", "renesas,irqc";
                #interrupt-cells = <2>;
                interrupt-controller;
                reg = <0 0xe61c0200 0 0x200>;
                             <0 57 IRQ_TYPE_LEVEL_HIGH>;
        };
 
-       dmac: dma-multiplexer@0 {
-               compatible = "renesas,shdma-mux";
-               #dma-cells = <1>;
-               dma-channels = <20>;
-               dma-requests = <256>;
-               #address-cells = <2>;
-               #size-cells = <2>;
-               ranges;
-
-               dma0: dma-controller@e6700020 {
-                       compatible = "renesas,shdma-r8a73a4";
-                       reg = <0 0xe6700020 0 0x89e0>;
-                       interrupts = <0 220 IRQ_TYPE_LEVEL_HIGH
-                                       0 200 IRQ_TYPE_LEVEL_HIGH
-                                       0 201 IRQ_TYPE_LEVEL_HIGH
-                                       0 202 IRQ_TYPE_LEVEL_HIGH
-                                       0 203 IRQ_TYPE_LEVEL_HIGH
-                                       0 204 IRQ_TYPE_LEVEL_HIGH
-                                       0 205 IRQ_TYPE_LEVEL_HIGH
-                                       0 206 IRQ_TYPE_LEVEL_HIGH
-                                       0 207 IRQ_TYPE_LEVEL_HIGH
-                                       0 208 IRQ_TYPE_LEVEL_HIGH
-                                       0 209 IRQ_TYPE_LEVEL_HIGH
-                                       0 210 IRQ_TYPE_LEVEL_HIGH
-                                       0 211 IRQ_TYPE_LEVEL_HIGH
-                                       0 212 IRQ_TYPE_LEVEL_HIGH
-                                       0 213 IRQ_TYPE_LEVEL_HIGH
-                                       0 214 IRQ_TYPE_LEVEL_HIGH
-                                       0 215 IRQ_TYPE_LEVEL_HIGH
-                                       0 216 IRQ_TYPE_LEVEL_HIGH
-                                       0 217 IRQ_TYPE_LEVEL_HIGH
-                                       0 218 IRQ_TYPE_LEVEL_HIGH
-                                       0 219 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-names = "error",
-                                       "ch0", "ch1", "ch2", "ch3",
-                                       "ch4", "ch5", "ch6", "ch7",
-                                       "ch8", "ch9", "ch10", "ch11",
-                                       "ch12", "ch13", "ch14", "ch15",
-                                       "ch16", "ch17", "ch18", "ch19";
-               };
-       };
-
        thermal@e61f0000 {
-               compatible = "renesas,rcar-thermal";
+               compatible = "renesas,thermal-r8a73a4", "renesas,rcar-thermal";
                reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>,
                         <0 0xe61f0200 0 0x38>, <0 0xe61f0300 0 0x38>;
                interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>;
        i2c0: i2c@e6500000 {
                #address-cells = <1>;
                #size-cells = <0>;
-               compatible = "renesas,rmobile-iic";
+               compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic";
                reg = <0 0xe6500000 0 0x428>;
                interrupts = <0 174 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        i2c1: i2c@e6510000 {
                #address-cells = <1>;
                #size-cells = <0>;
-               compatible = "renesas,rmobile-iic";
+               compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic";
                reg = <0 0xe6510000 0 0x428>;
                interrupts = <0 175 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        i2c2: i2c@e6520000 {
                #address-cells = <1>;
                #size-cells = <0>;
-               compatible = "renesas,rmobile-iic";
+               compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic";
                reg = <0 0xe6520000 0 0x428>;
                interrupts = <0 176 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        i2c3: i2c@e6530000 {
                #address-cells = <1>;
                #size-cells = <0>;
-               compatible = "renesas,rmobile-iic";
+               compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic";
                reg = <0 0xe6530000 0 0x428>;
                interrupts = <0 177 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        i2c4: i2c@e6540000 {
                #address-cells = <1>;
                #size-cells = <0>;
-               compatible = "renesas,rmobile-iic";
+               compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic";
                reg = <0 0xe6540000 0 0x428>;
                interrupts = <0 178 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
 
-       i2c5: i2c@e60b0000 {
-               #address-cells = <1>;
-               #size-cells = <0>;
-               compatible = "renesas,rmobile-iic";
-               reg = <0 0xe60b0000 0 0x428>;
-               interrupts = <0 179 IRQ_TYPE_LEVEL_HIGH>;
-               status = "disabled";
-       };
-
        i2c6: i2c@e6550000 {
                #address-cells = <1>;
                #size-cells = <0>;
-               compatible = "renesas,rmobile-iic";
+               compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic";
                reg = <0 0xe6550000 0 0x428>;
                interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        i2c7: i2c@e6560000 {
                #address-cells = <1>;
                #size-cells = <0>;
-               compatible = "renesas,rmobile-iic";
+               compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic";
                reg = <0 0xe6560000 0 0x428>;
                interrupts = <0 185 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        i2c8: i2c@e6570000 {
                #address-cells = <1>;
                #size-cells = <0>;
-               compatible = "renesas,rmobile-iic";
+               compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic";
                reg = <0 0xe6570000 0 0x428>;
                interrupts = <0 173 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
 
+       scifb0: serial@e6c20000 {
+               compatible = "renesas,scifb-r8a73a4", "renesas,scifb";
+               reg = <0 0xe6c20000 0 0x100>;
+               interrupts = <0 148 IRQ_TYPE_LEVEL_HIGH>;
+               status = "disabled";
+       };
+
+       scifb1: serial@e6c30000 {
+               compatible = "renesas,scifb-r8a73a4", "renesas,scifb";
+               reg = <0 0xe6c30000 0 0x100>;
+               interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH>;
+               status = "disabled";
+       };
+
        scifa0: serial@e6c40000 {
                compatible = "renesas,scifa-r8a73a4", "renesas,scifa";
                reg = <0 0xe6c40000 0 0x100>;
                status = "disabled";
        };
 
-       scifb2: serial@e6c20000 {
-               compatible = "renesas,scifb-r8a73a4", "renesas,scifb";
-               reg = <0 0xe6c20000 0 0x100>;
-               interrupts = <0 148 IRQ_TYPE_LEVEL_HIGH>;
-               status = "disabled";
-       };
-
-       scifb3: serial@e6c30000 {
-               compatible = "renesas,scifb-r8a73a4", "renesas,scifb";
-               reg = <0 0xe6c30000 0 0x100>;
-               interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH>;
-               status = "disabled";
-       };
-
-       scifb4: serial@e6ce0000 {
+       scifb2: serial@e6ce0000 {
                compatible = "renesas,scifb-r8a73a4", "renesas,scifb";
                reg = <0 0xe6ce0000 0 0x100>;
                interrupts = <0 150 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
 
-       scifb5: serial@e6cf0000 {
+       scifb3: serial@e6cf0000 {
                compatible = "renesas,scifb-r8a73a4", "renesas,scifb";
                reg = <0 0xe6cf0000 0 0x100>;
                interrupts = <0 151 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
 
-       mmcif0: mmc@ee200000 {
-               compatible = "renesas,sh-mmcif";
-               reg = <0 0xee200000 0 0x80>;
-               interrupts = <0 169 IRQ_TYPE_LEVEL_HIGH>;
-               reg-io-width = <4>;
-               status = "disabled";
-       };
-
-       mmcif1: mmc@ee220000 {
-               compatible = "renesas,sh-mmcif";
-               reg = <0 0xee220000 0 0x80>;
-               interrupts = <0 170 IRQ_TYPE_LEVEL_HIGH>;
-               reg-io-width = <4>;
-               status = "disabled";
-       };
-
-       pfc: pfc@e6050000 {
-               compatible = "renesas,pfc-r8a73a4";
-               reg = <0 0xe6050000 0 0x9000>;
-               gpio-controller;
-               #gpio-cells = <2>;
-               interrupts-extended =
-                       <&irqc0  0 0>, <&irqc0  1 0>, <&irqc0  2 0>, <&irqc0  3 0>,
-                       <&irqc0  4 0>, <&irqc0  5 0>, <&irqc0  6 0>, <&irqc0  7 0>,
-                       <&irqc0  8 0>, <&irqc0  9 0>, <&irqc0 10 0>, <&irqc0 11 0>,
-                       <&irqc0 12 0>, <&irqc0 13 0>, <&irqc0 14 0>, <&irqc0 15 0>,
-                       <&irqc0 16 0>, <&irqc0 17 0>, <&irqc0 18 0>, <&irqc0 19 0>,
-                       <&irqc0 20 0>, <&irqc0 21 0>, <&irqc0 22 0>, <&irqc0 23 0>,
-                       <&irqc0 24 0>, <&irqc0 25 0>, <&irqc0 26 0>, <&irqc0 27 0>,
-                       <&irqc0 28 0>, <&irqc0 29 0>, <&irqc0 30 0>, <&irqc0 31 0>,
-                       <&irqc1  0 0>, <&irqc1  1 0>, <&irqc1  2 0>, <&irqc1  3 0>,
-                       <&irqc1  4 0>, <&irqc1  5 0>, <&irqc1  6 0>, <&irqc1  7 0>,
-                       <&irqc1  8 0>, <&irqc1  9 0>, <&irqc1 10 0>, <&irqc1 11 0>,
-                       <&irqc1 12 0>, <&irqc1 13 0>, <&irqc1 14 0>, <&irqc1 15 0>,
-                       <&irqc1 16 0>, <&irqc1 17 0>, <&irqc1 18 0>, <&irqc1 19 0>,
-                       <&irqc1 20 0>, <&irqc1 21 0>, <&irqc1 22 0>, <&irqc1 23 0>,
-                       <&irqc1 24 0>, <&irqc1 25 0>;
-       };
-
        sdhi0: sd@ee100000 {
                compatible = "renesas,sdhi-r8a73a4";
                reg = <0 0xee100000 0 0x100>;
                cap-sd-highspeed;
                status = "disabled";
        };
+
+       mmcif0: mmc@ee200000 {
+               compatible = "renesas,sh-mmcif";
+               reg = <0 0xee200000 0 0x80>;
+               interrupts = <0 169 IRQ_TYPE_LEVEL_HIGH>;
+               reg-io-width = <4>;
+               status = "disabled";
+       };
+
+       mmcif1: mmc@ee220000 {
+               compatible = "renesas,sh-mmcif";
+               reg = <0 0xee220000 0 0x80>;
+               interrupts = <0 170 IRQ_TYPE_LEVEL_HIGH>;
+               reg-io-width = <4>;
+               status = "disabled";
+       };
+
+       gic: interrupt-controller@f1001000 {
+               compatible = "arm,cortex-a15-gic";
+               #interrupt-cells = <3>;
+               #address-cells = <0>;
+               interrupt-controller;
+               reg = <0 0xf1001000 0 0x1000>,
+                       <0 0xf1002000 0 0x1000>,
+                       <0 0xf1004000 0 0x2000>,
+                       <0 0xf1006000 0 0x2000>;
+               interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+       };
 };
diff --git a/arch/arm/boot/dts/r8a7740-armadillo800eva-reference.dts b/arch/arm/boot/dts/r8a7740-armadillo800eva-reference.dts
deleted file mode 100644 (file)
index ee9e7d5..0000000
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * Reference Device Tree Source for the armadillo 800 eva board
- *
- * Copyright (C) 2012 Renesas Solutions Corp.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- */
-
-/dts-v1/;
-#include "r8a7740.dtsi"
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/input/input.h>
-#include <dt-bindings/interrupt-controller/irq.h>
-#include <dt-bindings/pwm/pwm.h>
-
-/ {
-       model = "armadillo 800 eva reference";
-       compatible = "renesas,armadillo800eva-reference", "renesas,r8a7740";
-
-       aliases {
-               serial1 = &scifa1;
-       };
-
-       chosen {
-               bootargs = "console=tty0 console=ttySC1,115200 ignore_loglevel root=/dev/nfs ip=dhcp rw";
-       };
-
-       memory {
-               device_type = "memory";
-               reg = <0x40000000 0x20000000>;
-       };
-
-       reg_3p3v: regulator@0 {
-               compatible = "regulator-fixed";
-               regulator-name = "fixed-3.3V";
-               regulator-min-microvolt = <3300000>;
-               regulator-max-microvolt = <3300000>;
-               regulator-always-on;
-               regulator-boot-on;
-       };
-
-       vcc_sdhi0: regulator@1 {
-               compatible = "regulator-fixed";
-
-               regulator-name = "SDHI0 Vcc";
-               regulator-min-microvolt = <3300000>;
-               regulator-max-microvolt = <3300000>;
-
-               gpio = <&pfc 75 GPIO_ACTIVE_HIGH>;
-               enable-active-high;
-       };
-
-       vccq_sdhi0: regulator@2 {
-               compatible = "regulator-gpio";
-
-               regulator-name = "SDHI0 VccQ";
-               regulator-min-microvolt = <1800000>;
-               regulator-max-microvolt = <3300000>;
-               vin-supply = <&vcc_sdhi0>;
-
-               enable-gpio = <&pfc 74 GPIO_ACTIVE_HIGH>;
-               gpios = <&pfc 17 GPIO_ACTIVE_HIGH>;
-               states = <3300000 0
-                         1800000 1>;
-
-               enable-active-high;
-       };
-
-       reg_5p0v: regulator@3 {
-               compatible = "regulator-fixed";
-               regulator-name = "fixed-5.0V";
-               regulator-min-microvolt = <5000000>;
-               regulator-max-microvolt = <5000000>;
-               regulator-always-on;
-               regulator-boot-on;
-       };
-
-       gpio-keys {
-               compatible = "gpio-keys";
-
-               power-key {
-                       gpios = <&pfc 99 GPIO_ACTIVE_LOW>;
-                       linux,code = <KEY_POWER>;
-                       label = "SW3";
-                       gpio-key,wakeup;
-               };
-
-               back-key {
-                       gpios = <&pfc 100 GPIO_ACTIVE_LOW>;
-                       linux,code = <KEY_BACK>;
-                       label = "SW4";
-               };
-
-               menu-key {
-                       gpios = <&pfc 97 GPIO_ACTIVE_LOW>;
-                       linux,code = <KEY_MENU>;
-                       label = "SW5";
-               };
-
-               home-key {
-                       gpios = <&pfc 98 GPIO_ACTIVE_LOW>;
-                       linux,code = <KEY_HOME>;
-                       label = "SW6";
-               };
-       };
-
-       leds {
-               compatible = "gpio-leds";
-               led3 {
-                       gpios = <&pfc 102 GPIO_ACTIVE_HIGH>;
-                       label = "LED3";
-               };
-               led4 {
-                       gpios = <&pfc 111 GPIO_ACTIVE_HIGH>;
-                       label = "LED4";
-               };
-               led5 {
-                       gpios = <&pfc 110 GPIO_ACTIVE_HIGH>;
-                       label = "LED5";
-               };
-               led6 {
-                       gpios = <&pfc 177 GPIO_ACTIVE_HIGH>;
-                       label = "LED6";
-               };
-       };
-
-       i2c2: i2c@2 {
-               #address-cells = <1>;
-               #size-cells = <0>;
-               compatible = "i2c-gpio";
-               gpios = <&pfc 208 GPIO_ACTIVE_HIGH /* sda */
-                        &pfc 91 GPIO_ACTIVE_HIGH /* scl */
-                       >;
-               i2c-gpio,delay-us = <5>;
-       };
-
-       backlight {
-               compatible = "pwm-backlight";
-               pwms = <&tpu 2 33333 PWM_POLARITY_INVERTED>;
-               brightness-levels = <0 1 2 4 8 16 32 64 128 255>;
-               default-brightness-level = <9>;
-               pinctrl-0 = <&backlight_pins>;
-               pinctrl-names = "default";
-               power-supply = <&reg_5p0v>;
-               enable-gpios = <&pfc 61 GPIO_ACTIVE_HIGH>;
-       };
-
-       sound {
-               compatible = "simple-audio-card";
-
-               simple-audio-card,format = "i2s";
-
-               simple-audio-card,cpu {
-                       sound-dai = <&sh_fsi2 0>;
-                       bitclock-inversion;
-               };
-
-               simple-audio-card,codec {
-                       sound-dai = <&wm8978>;
-                       bitclock-master;
-                       frame-master;
-                       system-clock-frequency = <12288000>;
-               };
-       };
-};
-
-&ether {
-       pinctrl-0 = <&ether_pins>;
-       pinctrl-names = "default";
-
-       phy-handle = <&phy0>;
-       status = "ok";
-
-       phy0: ethernet-phy@0 {
-               reg = <0>;
-       };
-};
-
-&i2c0 {
-       status = "okay";
-       touchscreen@55 {
-               compatible = "sitronix,st1232";
-               reg = <0x55>;
-               interrupt-parent = <&irqpin1>;
-               interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
-               pinctrl-0 = <&st1232_pins>;
-               pinctrl-names = "default";
-               gpios = <&pfc 166 GPIO_ACTIVE_LOW>;
-       };
-
-       wm8978: wm8978@1a {
-               #sound-dai-cells = <0>;
-               compatible = "wlf,wm8978";
-               reg = <0x1a>;
-       };
-};
-
-&i2c2 {
-       status = "okay";
-       rtc@30 {
-               compatible = "sii,s35390a";
-               reg = <0x30>;
-       };
-};
-
-&pfc {
-       ether_pins: ether {
-               renesas,groups = "gether_mii", "gether_int";
-               renesas,function = "gether";
-       };
-
-       scifa1_pins: serial1 {
-               renesas,groups = "scifa1_data";
-               renesas,function = "scifa1";
-       };
-
-       st1232_pins: touchscreen {
-               renesas,groups = "intc_irq10";
-               renesas,function = "intc";
-       };
-
-       backlight_pins: backlight {
-               renesas,groups = "tpu0_to2_1";
-               renesas,function = "tpu0";
-       };
-
-       mmc0_pins: mmc0 {
-               renesas,groups = "mmc0_data8_1", "mmc0_ctrl_1";
-               renesas,function = "mmc0";
-       };
-
-       sdhi0_pins: sd0 {
-               renesas,groups = "sdhi0_data4", "sdhi0_ctrl", "sdhi0_wp";
-               renesas,function = "sdhi0";
-       };
-
-       fsia_pins: sounda {
-               renesas,groups = "fsia_sclk_in", "fsia_mclk_out",
-                                "fsia_data_in_1", "fsia_data_out_0";
-               renesas,function = "fsia";
-       };
-};
-
-&tpu {
-       status = "okay";
-};
-
-&mmcif0 {
-       pinctrl-0 = <&mmc0_pins>;
-       pinctrl-names = "default";
-
-       vmmc-supply = <&reg_3p3v>;
-       bus-width = <8>;
-       non-removable;
-       status = "okay";
-};
-
-&scifa1 {
-       pinctrl-0 = <&scifa1_pins>;
-       pinctrl-names = "default";
-
-       status = "okay";
-};
-
-&sdhi0 {
-       pinctrl-0 = <&sdhi0_pins>;
-       pinctrl-names = "default";
-
-       vmmc-supply = <&vcc_sdhi0>;
-       vqmmc-supply = <&vccq_sdhi0>;
-       bus-width = <4>;
-       cd-gpios = <&pfc 167 GPIO_ACTIVE_LOW>;
-       status = "okay";
-};
-
-&sh_fsi2 {
-       pinctrl-0 = <&fsia_pins>;
-       pinctrl-names = "default";
-
-       status = "okay";
-};
index a06a11e..d4af4d8 100644 (file)
 
 /dts-v1/;
 #include "r8a7740.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pwm/pwm.h>
 
 / {
        model = "armadillo 800 eva";
-       compatible = "renesas,armadillo800eva";
+       compatible = "renesas,armadillo800eva", "renesas,r8a7740";
+
+       aliases {
+               serial1 = &scifa1;
+       };
 
        chosen {
                bootargs = "console=tty0 console=ttySC1,115200 earlyprintk=sh-sci.1,115200 ignore_loglevel root=/dev/nfs ip=dhcp rw";
+               stdout-path = &scifa1;
        };
 
        memory {
                device_type = "memory";
                reg = <0x40000000 0x20000000>;
        };
+
+       reg_3p3v: regulator@0 {
+               compatible = "regulator-fixed";
+               regulator-name = "fixed-3.3V";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+               regulator-boot-on;
+       };
+
+       vcc_sdhi0: regulator@1 {
+               compatible = "regulator-fixed";
+
+               regulator-name = "SDHI0 Vcc";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+
+               gpio = <&pfc 75 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       vccq_sdhi0: regulator@2 {
+               compatible = "regulator-gpio";
+
+               regulator-name = "SDHI0 VccQ";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <3300000>;
+               vin-supply = <&vcc_sdhi0>;
+
+               enable-gpio = <&pfc 74 GPIO_ACTIVE_HIGH>;
+               gpios = <&pfc 17 GPIO_ACTIVE_HIGH>;
+               states = <3300000 0
+                         1800000 1>;
+
+               enable-active-high;
+       };
+
+       reg_5p0v: regulator@3 {
+               compatible = "regulator-fixed";
+               regulator-name = "fixed-5.0V";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-always-on;
+               regulator-boot-on;
+       };
+
+       keyboard {
+               compatible = "gpio-keys";
+
+               power-key {
+                       gpios = <&pfc 99 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_POWER>;
+                       label = "SW3";
+                       gpio-key,wakeup;
+               };
+
+               back-key {
+                       gpios = <&pfc 100 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_BACK>;
+                       label = "SW4";
+               };
+
+               menu-key {
+                       gpios = <&pfc 97 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_MENU>;
+                       label = "SW5";
+               };
+
+               home-key {
+                       gpios = <&pfc 98 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_HOME>;
+                       label = "SW6";
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               led3 {
+                       gpios = <&pfc 102 GPIO_ACTIVE_HIGH>;
+                       label = "LED3";
+               };
+               led4 {
+                       gpios = <&pfc 111 GPIO_ACTIVE_HIGH>;
+                       label = "LED4";
+               };
+               led5 {
+                       gpios = <&pfc 110 GPIO_ACTIVE_HIGH>;
+                       label = "LED5";
+               };
+               led6 {
+                       gpios = <&pfc 177 GPIO_ACTIVE_HIGH>;
+                       label = "LED6";
+               };
+       };
+
+       i2c2: i2c@2 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "i2c-gpio";
+               gpios = <&pfc 208 GPIO_ACTIVE_HIGH /* sda */
+                        &pfc 91 GPIO_ACTIVE_HIGH /* scl */
+                       >;
+               i2c-gpio,delay-us = <5>;
+       };
+
+       backlight {
+               compatible = "pwm-backlight";
+               pwms = <&tpu 2 33333 PWM_POLARITY_INVERTED>;
+               brightness-levels = <0 1 2 4 8 16 32 64 128 255>;
+               default-brightness-level = <9>;
+               pinctrl-0 = <&backlight_pins>;
+               pinctrl-names = "default";
+               power-supply = <&reg_5p0v>;
+               enable-gpios = <&pfc 61 GPIO_ACTIVE_HIGH>;
+       };
+
+       sound {
+               compatible = "simple-audio-card";
+
+               simple-audio-card,format = "i2s";
+
+               simple-audio-card,cpu {
+                       sound-dai = <&sh_fsi2 0>;
+                       bitclock-inversion;
+               };
+
+               simple-audio-card,codec {
+                       sound-dai = <&wm8978>;
+                       bitclock-master;
+                       frame-master;
+                       system-clock-frequency = <12288000>;
+               };
+       };
+};
+
+&ether {
+       pinctrl-0 = <&ether_pins>;
+       pinctrl-names = "default";
+
+       phy-handle = <&phy0>;
+       status = "ok";
+
+       phy0: ethernet-phy@0 {
+               reg = <0>;
+       };
+};
+
+&extal1_clk {
+       clock-frequency = <25000000>;
+};
+&extal2_clk {
+       clock-frequency = <48000000>;
+};
+&fsibck_clk {
+       clock-frequency = <12288000>;
+};
+&cpg_clocks {
+       renesas,mode = <0x05>; /* MD_CK0 | MD_CK2 */
+};
+
+&cmt1 {
+       status = "ok";
+};
+
+&i2c0 {
+       status = "okay";
+       touchscreen@55 {
+               compatible = "sitronix,st1232";
+               reg = <0x55>;
+               interrupt-parent = <&irqpin1>;
+               interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+               pinctrl-0 = <&st1232_pins>;
+               pinctrl-names = "default";
+               gpios = <&pfc 166 GPIO_ACTIVE_LOW>;
+       };
+
+       wm8978: wm8978@1a {
+               #sound-dai-cells = <0>;
+               compatible = "wlf,wm8978";
+               reg = <0x1a>;
+       };
+};
+
+&i2c2 {
+       status = "okay";
+       rtc@30 {
+               compatible = "sii,s35390a";
+               reg = <0x30>;
+       };
+};
+
+&pfc {
+       ether_pins: ether {
+               renesas,groups = "gether_mii", "gether_int";
+               renesas,function = "gether";
+       };
+
+       scifa1_pins: serial1 {
+               renesas,groups = "scifa1_data";
+               renesas,function = "scifa1";
+       };
+
+       st1232_pins: touchscreen {
+               renesas,groups = "intc_irq10";
+               renesas,function = "intc";
+       };
+
+       backlight_pins: backlight {
+               renesas,groups = "tpu0_to2_1";
+               renesas,function = "tpu0";
+       };
+
+       mmc0_pins: mmc0 {
+               renesas,groups = "mmc0_data8_1", "mmc0_ctrl_1";
+               renesas,function = "mmc0";
+       };
+
+       sdhi0_pins: sd0 {
+               renesas,groups = "sdhi0_data4", "sdhi0_ctrl", "sdhi0_wp";
+               renesas,function = "sdhi0";
+       };
+
+       fsia_pins: sounda {
+               renesas,groups = "fsia_sclk_in", "fsia_mclk_out",
+                                "fsia_data_in_1", "fsia_data_out_0";
+               renesas,function = "fsia";
+       };
+};
+
+&tpu {
+       status = "okay";
+};
+
+&mmcif0 {
+       pinctrl-0 = <&mmc0_pins>;
+       pinctrl-names = "default";
+
+       vmmc-supply = <&reg_3p3v>;
+       bus-width = <8>;
+       non-removable;
+       status = "okay";
+};
+
+&scifa1 {
+       pinctrl-0 = <&scifa1_pins>;
+       pinctrl-names = "default";
+
+       status = "okay";
+};
+
+&sdhi0 {
+       pinctrl-0 = <&sdhi0_pins>;
+       pinctrl-names = "default";
+
+       vmmc-supply = <&vcc_sdhi0>;
+       vqmmc-supply = <&vccq_sdhi0>;
+       bus-width = <4>;
+       cd-gpios = <&pfc 167 GPIO_ACTIVE_LOW>;
+       status = "okay";
+};
+
+&sh_fsi2 {
+       pinctrl-0 = <&fsia_pins>;
+       pinctrl-names = "default";
+
+       status = "okay";
+};
+
+&tmu0 {
+       status = "okay";
 };
index bda18fb..a8a674b 100644 (file)
@@ -10,6 +10,7 @@
 
 /include/ "skeleton.dtsi"
 
+#include <dt-bindings/clock/r8a7740-clock.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 
 / {
                interrupts = <0 83 IRQ_TYPE_LEVEL_HIGH>;
        };
 
+       cmt1: timer@e6138000 {
+               compatible = "renesas,cmt-48-r8a7740", "renesas,cmt-48";
+               reg = <0xe6138000 0x170>;
+               interrupts = <0 58 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp3_clks R8A7740_CLK_CMT1>;
+               clock-names = "fck";
+
+               renesas,channels-mask = <0x3f>;
+
+               status = "disabled";
+       };
+
        /* irqpin0: IRQ0 - IRQ7 */
        irqpin0: irqpin@e6900000 {
                compatible = "renesas,intc-irqpin-r8a7740", "renesas,intc-irqpin";
@@ -58,6 +71,7 @@
                              0 149 IRQ_TYPE_LEVEL_HIGH
                              0 149 IRQ_TYPE_LEVEL_HIGH
                              0 149 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks R8A7740_CLK_INTCA>;
        };
 
        /* irqpin1: IRQ8 - IRQ15 */
@@ -78,6 +92,7 @@
                              0 149 IRQ_TYPE_LEVEL_HIGH
                              0 149 IRQ_TYPE_LEVEL_HIGH
                              0 149 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks R8A7740_CLK_INTCA>;
        };
 
        /* irqpin2: IRQ16 - IRQ23 */
                              0 149 IRQ_TYPE_LEVEL_HIGH
                              0 149 IRQ_TYPE_LEVEL_HIGH
                              0 149 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks R8A7740_CLK_INTCA>;
        };
 
        /* irqpin3: IRQ24 - IRQ31 */
                              0 149 IRQ_TYPE_LEVEL_HIGH
                              0 149 IRQ_TYPE_LEVEL_HIGH
                              0 149 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks R8A7740_CLK_INTCA>;
        };
 
        ether: ethernet@e9a00000 {
                reg = <0xe9a00000 0x800>,
                      <0xe9a01800 0x800>;
                interrupts = <0 110 IRQ_TYPE_LEVEL_HIGH>;
-               /* clocks = <&mstp3_clks R8A7740_CLK_GETHER>; */
+               clocks = <&mstp3_clks R8A7740_CLK_GETHER>;
                phy-mode = "mii";
                #address-cells = <1>;
                #size-cells = <0>;
                              0 202 IRQ_TYPE_LEVEL_HIGH
                              0 203 IRQ_TYPE_LEVEL_HIGH
                              0 204 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp1_clks R8A7740_CLK_IIC0>;
                status = "disabled";
        };
 
                              0 71 IRQ_TYPE_LEVEL_HIGH
                              0 72 IRQ_TYPE_LEVEL_HIGH
                              0 73 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp3_clks R8A7740_CLK_IIC1>;
                status = "disabled";
        };
 
                compatible = "renesas,scifa-r8a7740", "renesas,scifa";
                reg = <0xe6c40000 0x100>;
                interrupts = <0 100 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks R8A7740_CLK_SCIFA0>;
+               clock-names = "sci_ick";
                status = "disabled";
        };
 
                compatible = "renesas,scifa-r8a7740", "renesas,scifa";
                reg = <0xe6c50000 0x100>;
                interrupts = <0 101 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks R8A7740_CLK_SCIFA1>;
+               clock-names = "sci_ick";
                status = "disabled";
        };
 
                compatible = "renesas,scifa-r8a7740", "renesas,scifa";
                reg = <0xe6c60000 0x100>;
                interrupts = <0 102 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks R8A7740_CLK_SCIFA2>;
+               clock-names = "sci_ick";
                status = "disabled";
        };
 
                compatible = "renesas,scifa-r8a7740", "renesas,scifa";
                reg = <0xe6c70000 0x100>;
                interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks R8A7740_CLK_SCIFA3>;
+               clock-names = "sci_ick";
                status = "disabled";
        };
 
                compatible = "renesas,scifa-r8a7740", "renesas,scifa";
                reg = <0xe6c80000 0x100>;
                interrupts = <0 104 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks R8A7740_CLK_SCIFA4>;
+               clock-names = "sci_ick";
                status = "disabled";
        };
 
                compatible = "renesas,scifa-r8a7740", "renesas,scifa";
                reg = <0xe6cb0000 0x100>;
                interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks R8A7740_CLK_SCIFA5>;
+               clock-names = "sci_ick";
                status = "disabled";
        };
 
                compatible = "renesas,scifa-r8a7740", "renesas,scifa";
                reg = <0xe6cc0000 0x100>;
                interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks R8A7740_CLK_SCIFA6>;
+               clock-names = "sci_ick";
                status = "disabled";
        };
 
                compatible = "renesas,scifa-r8a7740", "renesas,scifa";
                reg = <0xe6cd0000 0x100>;
                interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks R8A7740_CLK_SCIFA7>;
+               clock-names = "sci_ick";
                status = "disabled";
        };
 
                compatible = "renesas,scifb-r8a7740", "renesas,scifb";
                reg = <0xe6c30000 0x100>;
                interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks R8A7740_CLK_SCIFB>;
+               clock-names = "sci_ick";
                status = "disabled";
        };
 
        tpu: pwm@e6600000 {
                compatible = "renesas,tpu-r8a7740", "renesas,tpu";
                reg = <0xe6600000 0x100>;
+               clocks = <&mstp3_clks R8A7740_CLK_TPU0>;
                status = "disabled";
                #pwm-cells = <3>;
        };
                reg = <0xe6bd0000 0x100>;
                interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH
                              0 57 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp3_clks R8A7740_CLK_MMC>;
                status = "disabled";
        };
 
                interrupts = <0 117 IRQ_TYPE_LEVEL_HIGH
                              0 118 IRQ_TYPE_LEVEL_HIGH
                              0 119 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp3_clks R8A7740_CLK_SDHI0>;
                cap-sd-highspeed;
                cap-sdio-irq;
                status = "disabled";
                interrupts = <0 121 IRQ_TYPE_LEVEL_HIGH
                              0 122 IRQ_TYPE_LEVEL_HIGH
                              0 123 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp3_clks R8A7740_CLK_SDHI1>;
                cap-sd-highspeed;
                cap-sdio-irq;
                status = "disabled";
                interrupts = <0 125 IRQ_TYPE_LEVEL_HIGH
                              0 126 IRQ_TYPE_LEVEL_HIGH
                              0 127 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp4_clks R8A7740_CLK_SDHI2>;
                cap-sd-highspeed;
                cap-sdio-irq;
                status = "disabled";
                compatible = "renesas,fsi2-r8a7740", "renesas,sh_fsi2";
                reg = <0xfe1f0000 0x400>;
                interrupts = <0 9 0x4>;
+               clocks = <&mstp3_clks R8A7740_CLK_FSI>;
+               status = "disabled";
+       };
+
+       tmu0: timer@fff80000 {
+               compatible = "renesas,tmu-r8a7740", "renesas,tmu";
+               reg = <0xfff80000 0x2c>;
+               interrupts = <0 198 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 199 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 200 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp1_clks R8A7740_CLK_TMU0>;
+               clock-names = "fck";
+
+               #renesas,channels = <3>;
+
                status = "disabled";
        };
+
+       tmu1: timer@fff90000 {
+               compatible = "renesas,tmu-r8a7740", "renesas,tmu";
+               reg = <0xfff90000 0x2c>;
+               interrupts = <0 170 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 171 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 172 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp1_clks R8A7740_CLK_TMU1>;
+               clock-names = "fck";
+
+               #renesas,channels = <3>;
+
+               status = "disabled";
+       };
+
+       clocks {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               /* External root clock */
+               extalr_clk: extalr_clk {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <32768>;
+                       clock-output-names = "extalr";
+               };
+               extal1_clk: extal1_clk {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <0>;
+                       clock-output-names = "extal1";
+               };
+               extal2_clk: extal2_clk {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <0>;
+                       clock-output-names = "extal2";
+               };
+               dv_clk: dv_clk {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <27000000>;
+                       clock-output-names = "dv";
+               };
+               fsiack_clk: fsiack_clk {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <0>;
+                       clock-output-names = "fsiack";
+               };
+               fsibck_clk: fsibck_clk {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <0>;
+                       clock-output-names = "fsibck";
+               };
+
+               /* Special CPG clocks */
+               cpg_clocks: cpg_clocks@e6150000 {
+                       compatible = "renesas,r8a7740-cpg-clocks";
+                       reg = <0xe6150000 0x10000>;
+                       clocks = <&extal1_clk>, <&extalr_clk>;
+                       #clock-cells = <1>;
+                       clock-output-names = "system", "pllc0", "pllc1",
+                                            "pllc2", "r",
+                                            "usb24s",
+                                            "i", "zg", "b", "m1", "hp",
+                                            "hpp", "usbp", "s", "zb", "m3",
+                                            "cp";
+               };
+
+               /* Variable factor clocks (DIV6) */
+               sub_clk: sub_clk@e6150080 {
+                       compatible = "renesas,r8a7740-div6-clock", "renesas,cpg-div6-clock";
+                       reg = <0xe6150080 4>;
+                       clocks = <&pllc1_div2_clk>;
+                       #clock-cells = <0>;
+                       clock-output-names = "sub";
+               };
+
+               /* Fixed factor clocks */
+               pllc1_div2_clk: pllc1_div2_clk {
+                       compatible = "fixed-factor-clock";
+                       clocks = <&cpg_clocks R8A7740_CLK_PLLC1>;
+                       #clock-cells = <0>;
+                       clock-div = <2>;
+                       clock-mult = <1>;
+                       clock-output-names = "pllc1_div2";
+               };
+               extal1_div2_clk: extal1_div2_clk {
+                       compatible = "fixed-factor-clock";
+                       clocks = <&extal1_clk>;
+                       #clock-cells = <0>;
+                       clock-div = <2>;
+                       clock-mult = <1>;
+                       clock-output-names = "extal1_div2";
+               };
+
+               /* Gate clocks */
+               subck_clks: subck_clks@e6150080 {
+                       compatible = "renesas,r8a7740-mstp-clocks", "renesas,cpg-mstp-clocks";
+                       reg = <0xe6150080 4>;
+                       clocks = <&sub_clk>, <&sub_clk>;
+                       #clock-cells = <1>;
+                       renesas,clock-indices = <
+                               R8A7740_CLK_SUBCK R8A7740_CLK_SUBCK2
+                       >;
+                       clock-output-names =
+                               "subck", "subck2";
+               };
+               mstp1_clks: mstp1_clks@e6150134 {
+                       compatible = "renesas,r8a7740-mstp-clocks", "renesas,cpg-mstp-clocks";
+                       reg = <0xe6150134 4>, <0xe6150038 4>;
+                       clocks = <&cpg_clocks R8A7740_CLK_S>,
+                                <&cpg_clocks R8A7740_CLK_S>, <&sub_clk>,
+                                <&cpg_clocks R8A7740_CLK_B>,
+                                <&cpg_clocks R8A7740_CLK_HPP>, <&sub_clk>,
+                                <&cpg_clocks R8A7740_CLK_B>;
+                       #clock-cells = <1>;
+                       renesas,clock-indices = <
+                               R8A7740_CLK_CEU21 R8A7740_CLK_CEU20 R8A7740_CLK_TMU0
+                               R8A7740_CLK_LCDC1 R8A7740_CLK_IIC0 R8A7740_CLK_TMU1
+                               R8A7740_CLK_LCDC0
+                       >;
+                       clock-output-names =
+                               "ceu21", "ceu20", "tmu0", "lcdc1", "iic0",
+                               "tmu1", "lcdc0";
+               };
+               mstp2_clks: mstp2_clks@e6150138 {
+                       compatible = "renesas,r8a7740-mstp-clocks", "renesas,cpg-mstp-clocks";
+                       reg = <0xe6150138 4>, <0xe6150040 4>;
+                       clocks = <&sub_clk>, <&cpg_clocks R8A7740_CLK_HP>,
+                                <&sub_clk>, <&cpg_clocks R8A7740_CLK_HP>,
+                                <&cpg_clocks R8A7740_CLK_HP>,
+                                <&cpg_clocks R8A7740_CLK_HP>,
+                                <&cpg_clocks R8A7740_CLK_HP>,
+                                <&sub_clk>, <&sub_clk>, <&sub_clk>,
+                                <&sub_clk>, <&sub_clk>, <&sub_clk>,
+                                <&sub_clk>;
+                       #clock-cells = <1>;
+                       renesas,clock-indices = <
+                               R8A7740_CLK_SCIFA6 R8A7740_CLK_INTCA
+                               R8A7740_CLK_SCIFA7
+                               R8A7740_CLK_DMAC1 R8A7740_CLK_DMAC2
+                               R8A7740_CLK_DMAC3 R8A7740_CLK_USBDMAC
+                               R8A7740_CLK_SCIFA5 R8A7740_CLK_SCIFB
+                               R8A7740_CLK_SCIFA0 R8A7740_CLK_SCIFA1
+                               R8A7740_CLK_SCIFA2 R8A7740_CLK_SCIFA3
+                               R8A7740_CLK_SCIFA4
+                       >;
+                       clock-output-names =
+                               "scifa6", "intca",
+                               "scifa7", "dmac1", "dmac2", "dmac3",
+                               "usbdmac", "scifa5", "scifb", "scifa0", "scifa1",
+                               "scifa2", "scifa3", "scifa4";
+               };
+               mstp3_clks: mstp3_clks@e615013c {
+                       compatible = "renesas,r8a7740-mstp-clocks", "renesas,cpg-mstp-clocks";
+                       reg = <0xe615013c 4>, <0xe6150048 4>;
+                       clocks = <&cpg_clocks R8A7740_CLK_R>,
+                                <&cpg_clocks R8A7740_CLK_HP>,
+                                <&sub_clk>,
+                                <&cpg_clocks R8A7740_CLK_HP>,
+                                <&cpg_clocks R8A7740_CLK_HP>,
+                                <&cpg_clocks R8A7740_CLK_HP>,
+                                <&cpg_clocks R8A7740_CLK_HP>,
+                                <&cpg_clocks R8A7740_CLK_HP>,
+                                <&cpg_clocks R8A7740_CLK_HP>;
+                       #clock-cells = <1>;
+                       renesas,clock-indices = <
+                               R8A7740_CLK_CMT1 R8A7740_CLK_FSI R8A7740_CLK_IIC1
+                               R8A7740_CLK_USBF R8A7740_CLK_SDHI0 R8A7740_CLK_SDHI1
+                               R8A7740_CLK_MMC R8A7740_CLK_GETHER R8A7740_CLK_TPU0
+                       >;
+                       clock-output-names =
+                               "cmt1", "fsi", "iic1", "usbf", "sdhi0", "sdhi1",
+                               "mmc", "gether", "tpu0";
+               };
+               mstp4_clks: mstp4_clks@e6150140 {
+                       compatible = "renesas,r8a7740-mstp-clocks", "renesas,cpg-mstp-clocks";
+                       reg = <0xe6150140 4>, <0xe615004c 4>;
+                       clocks = <&cpg_clocks R8A7740_CLK_HP>,
+                                <&cpg_clocks R8A7740_CLK_HP>,
+                                <&cpg_clocks R8A7740_CLK_HP>,
+                                <&cpg_clocks R8A7740_CLK_HP>;
+                       #clock-cells = <1>;
+                       renesas,clock-indices = <
+                               R8A7740_CLK_USBH R8A7740_CLK_SDHI2
+                               R8A7740_CLK_USBFUNC R8A7740_CLK_USBPHY
+                       >;
+                       clock-output-names =
+                               "usbhost", "sdhi2", "usbfunc", "usphy";
+               };
+       };
 };
index 3342c74..04c0c37 100644 (file)
@@ -28,7 +28,8 @@
        };
 
        chosen {
-               bootargs = "console=ttySC0,115200 ignore_loglevel root=/dev/nfs ip=dhcp rw";
+               bootargs = "ignore_loglevel root=/dev/nfs ip=dhcp rw";
+               stdout-path = &scif0;
        };
 
        memory {
        status = "okay";
 };
 
+&tmu0 {
+       status = "okay";
+};
+
 &pfc {
        scif0_pins: serial0 {
                renesas,groups = "scif0_data_a", "scif0_ctrl";
index ecfdf4b..ef85339 100644 (file)
        interrupt-parent = <&gic>;
 
        cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
                cpu@0 {
+                       device_type = "cpu";
                        compatible = "arm,cortex-a9";
+                       reg = <0>;
+                       clock-frequency = <800000000>;
                };
        };
 
                status = "disabled";
        };
 
+       tmu0: timer@ffd80000 {
+               compatible = "renesas,tmu-r8a7778", "renesas,tmu";
+               reg = <0xffd80000 0x30>;
+               interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 33 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 34 IRQ_TYPE_LEVEL_HIGH>;
+
+               #renesas,channels = <3>;
+
+               status = "disabled";
+       };
+
+       tmu1: timer@ffd81000 {
+               compatible = "renesas,tmu-r8a7778", "renesas,tmu";
+               reg = <0xffd81000 0x30>;
+               interrupts = <0 36 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 37 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 38 IRQ_TYPE_LEVEL_HIGH>;
+
+               #renesas,channels = <3>;
+
+               status = "disabled";
+       };
+
+       tmu2: timer@ffd82000 {
+               compatible = "renesas,tmu-r8a7778", "renesas,tmu";
+               reg = <0xffd82000 0x30>;
+               interrupts = <0 40 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 41 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 42 IRQ_TYPE_LEVEL_HIGH>;
+
+               #renesas,channels = <3>;
+
+               status = "disabled";
+       };
+
        scif0: serial@ffe40000 {
                compatible = "renesas,scif-r8a7778", "renesas,scif";
                reg = <0xffe40000 0x100>;
                compatible = "renesas,sdhi-r8a7778";
                reg = <0xffe4c000 0x100>;
                interrupts = <0 87 IRQ_TYPE_LEVEL_HIGH>;
-               cap-sd-highspeed;
-               cap-sdio-irq;
                status = "disabled";
        };
 
                compatible = "renesas,sdhi-r8a7778";
                reg = <0xffe4d000 0x100>;
                interrupts = <0 88 IRQ_TYPE_LEVEL_HIGH>;
-               cap-sd-highspeed;
-               cap-sdio-irq;
                status = "disabled";
        };
 
                compatible = "renesas,sdhi-r8a7778";
                reg = <0xffe4f000 0x100>;
                interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>;
-               cap-sd-highspeed;
-               cap-sdio-irq;
                status = "disabled";
        };
 
index 5745555..e83d40e 100644 (file)
@@ -25,6 +25,7 @@
 
        chosen {
                bootargs = "console=ttySC2,115200 ignore_loglevel root=/dev/nfs ip=on";
+               stdout-path = &scif2;
        };
 
        memory {
                        gpios = <&gpio4 31 GPIO_ACTIVE_HIGH>;
                };
        };
+
+       vga-encoder {
+               compatible = "adi,adv7123";
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+                               vga_enc_in: endpoint {
+                                       remote-endpoint = <&du_out_rgb0>;
+                               };
+                       };
+                       port@1 {
+                               reg = <1>;
+                               vga_enc_out: endpoint {
+                                       remote-endpoint = <&vga_in>;
+                               };
+                       };
+               };
+       };
+
+       vga {
+               compatible = "vga-connector";
+
+               port {
+                       vga_in: endpoint {
+                               remote-endpoint = <&vga_enc_out>;
+                       };
+               };
+       };
+
+       lvds-encoder {
+               compatible = "thine,thc63lvdm83d";
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+                               lvds_enc_in: endpoint {
+                                       remote-endpoint = <&du_out_rgb1>;
+                               };
+                       };
+                       port@1 {
+                               reg = <1>;
+                               lvds_connector: endpoint {
+                               };
+                       };
+               };
+       };
+};
+
+&du {
+       pinctrl-0 = <&du_pins>;
+       pinctrl-names = "default";
+       status = "okay";
+
+       ports {
+               port@0 {
+                       endpoint {
+                               remote-endpoint = <&vga_enc_in>;
+                       };
+               };
+               port@1 {
+                       endpoint {
+                               remote-endpoint = <&lvds_enc_in>;
+                       };
+               };
+       };
 };
 
 &irqpin0 {
        clock-frequency = <31250000>;
 };
 
+&tmu0 {
+       status = "okay";
+};
+
 &pfc {
+       du_pins: du {
+               du0 {
+                       renesas,groups = "du0_rgb888", "du0_sync_1", "du0_clk_out_0";
+                       renesas,function = "du0";
+               };
+               du1 {
+                       renesas,groups = "du1_rgb666", "du1_sync_1", "du1_clk_out";
+                       renesas,function = "du1";
+               };
+       };
+
        lan0_pins: lan0 {
                intc {
                        renesas,groups = "intc_irq1_b";
index 58d0d95..ede9a29 100644 (file)
        scif0: serial@ffe40000 {
                compatible = "renesas,scif-r8a7779", "renesas,scif";
                reg = <0xffe40000 0x100>;
-               interrupt-parent = <&gic>;
                interrupts = <0 88 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&cpg_clocks R8A7779_CLK_P>;
                clock-names = "sci_ick";
        scif1: serial@ffe41000 {
                compatible = "renesas,scif-r8a7779", "renesas,scif";
                reg = <0xffe41000 0x100>;
-               interrupt-parent = <&gic>;
                interrupts = <0 89 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&cpg_clocks R8A7779_CLK_P>;
                clock-names = "sci_ick";
        scif2: serial@ffe42000 {
                compatible = "renesas,scif-r8a7779", "renesas,scif";
                reg = <0xffe42000 0x100>;
-               interrupt-parent = <&gic>;
                interrupts = <0 90 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&cpg_clocks R8A7779_CLK_P>;
                clock-names = "sci_ick";
        scif3: serial@ffe43000 {
                compatible = "renesas,scif-r8a7779", "renesas,scif";
                reg = <0xffe43000 0x100>;
-               interrupt-parent = <&gic>;
                interrupts = <0 91 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&cpg_clocks R8A7779_CLK_P>;
                clock-names = "sci_ick";
        scif4: serial@ffe44000 {
                compatible = "renesas,scif-r8a7779", "renesas,scif";
                reg = <0xffe44000 0x100>;
-               interrupt-parent = <&gic>;
                interrupts = <0 92 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&cpg_clocks R8A7779_CLK_P>;
                clock-names = "sci_ick";
        scif5: serial@ffe45000 {
                compatible = "renesas,scif-r8a7779", "renesas,scif";
                reg = <0xffe45000 0x100>;
-               interrupt-parent = <&gic>;
                interrupts = <0 93 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&cpg_clocks R8A7779_CLK_P>;
                clock-names = "sci_ick";
        };
 
        thermal@ffc48000 {
-               compatible = "renesas,rcar-thermal";
+               compatible = "renesas,thermal-r8a7779", "renesas,rcar-thermal";
                reg = <0xffc48000 0x38>;
        };
 
+       tmu0: timer@ffd80000 {
+               compatible = "renesas,tmu-r8a7779", "renesas,tmu";
+               reg = <0xffd80000 0x30>;
+               interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 33 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 34 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp0_clks R8A7779_CLK_TMU0>;
+               clock-names = "fck";
+
+               #renesas,channels = <3>;
+
+               status = "disabled";
+       };
+
+       tmu1: timer@ffd81000 {
+               compatible = "renesas,tmu-r8a7779", "renesas,tmu";
+               reg = <0xffd81000 0x30>;
+               interrupts = <0 36 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 37 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 38 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp0_clks R8A7779_CLK_TMU1>;
+               clock-names = "fck";
+
+               #renesas,channels = <3>;
+
+               status = "disabled";
+       };
+
+       tmu2: timer@ffd82000 {
+               compatible = "renesas,tmu-r8a7779", "renesas,tmu";
+               reg = <0xffd82000 0x30>;
+               interrupts = <0 40 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 41 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 42 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp0_clks R8A7779_CLK_TMU2>;
+               clock-names = "fck";
+
+               #renesas,channels = <3>;
+
+               status = "disabled";
+       };
+
        sata: sata@fc600000 {
-               compatible = "renesas,rcar-sata";
+               compatible = "renesas,sata-r8a7779", "renesas,rcar-sata";
                reg = <0xfc600000 0x2000>;
                interrupts = <0 100 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp1_clks R8A7779_CLK_SATA>;
                reg = <0xffe4c000 0x100>;
                interrupts = <0 104 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp3_clks R8A7779_CLK_SDHI0>;
-               cap-sd-highspeed;
-               cap-sdio-irq;
                status = "disabled";
        };
 
                reg = <0xffe4d000 0x100>;
                interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp3_clks R8A7779_CLK_SDHI1>;
-               cap-sd-highspeed;
-               cap-sdio-irq;
                status = "disabled";
        };
 
                reg = <0xffe4e000 0x100>;
                interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp3_clks R8A7779_CLK_SDHI2>;
-               cap-sd-highspeed;
-               cap-sdio-irq;
                status = "disabled";
        };
 
                reg = <0xffe4f000 0x100>;
                interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp3_clks R8A7779_CLK_SDHI3>;
-               cap-sd-highspeed;
-               cap-sdio-irq;
                status = "disabled";
        };
 
                status = "disabled";
        };
 
+       du: display@fff80000 {
+               compatible = "renesas,du-r8a7779";
+               reg = <0 0xfff80000 0 0x40000>;
+               interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp1_clks R8A7779_CLK_DU>;
+               status = "disabled";
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+                               du_out_rgb0: endpoint {
+                               };
+                       };
+                       port@1 {
+                               reg = <1>;
+                               du_out_rgb1: endpoint {
+                               };
+                       };
+               };
+       };
+
        clocks {
                #address-cells = <1>;
                #size-cells = <1>;
                /* Gate clocks */
                mstp0_clks: clocks@ffc80030 {
                        compatible = "renesas,r8a7779-mstp-clocks",
-                                    "renesas,cpg-mstp-clocks";
+                                    "renesas,cpg-mstp-clocks";
                        reg = <0xffc80030 4>;
                        clocks = <&cpg_clocks R8A7779_CLK_S>,
-                                <&cpg_clocks R8A7779_CLK_P>,
+                                <&cpg_clocks R8A7779_CLK_P>,
                                 <&cpg_clocks R8A7779_CLK_P>,
                                 <&cpg_clocks R8A7779_CLK_P>,
                                 <&cpg_clocks R8A7779_CLK_S>,
                };
                mstp1_clks: clocks@ffc80034 {
                        compatible = "renesas,r8a7779-mstp-clocks",
-                                    "renesas,cpg-mstp-clocks";
+                                    "renesas,cpg-mstp-clocks";
                        reg = <0xffc80034 4>, <0xffc80044 4>;
                        clocks = <&cpg_clocks R8A7779_CLK_P>,
                                 <&cpg_clocks R8A7779_CLK_P>,
                };
                mstp3_clks: clocks@ffc8003c {
                        compatible = "renesas,r8a7779-mstp-clocks",
-                                    "renesas,cpg-mstp-clocks";
+                                    "renesas,cpg-mstp-clocks";
                        reg = <0xffc8003c 4>;
                        clocks = <&s4_clk>, <&s4_clk>, <&s4_clk>, <&s4_clk>,
                                 <&s4_clk>, <&s4_clk>;
index 2bff0a7..fac52a0 100644 (file)
@@ -9,6 +9,34 @@
  * kind, whether express or implied.
  */
 
+/*
+ * SSI-AK4643
+ *
+ * SW1: 1: AK4643
+ *      2: CN22
+ *      3: ADV7511
+ *
+ * This command is required when Playback/Capture
+ *
+ *     amixer set "LINEOUT Mixer DACL" on
+ *     amixer set "DVC Out" 100%
+ *     amixer set "DVC In" 100%
+ *
+ * You can use Mute
+ *
+ *     amixer set "DVC Out Mute" on
+ *     amixer set "DVC In Mute" on
+ *
+ * You can use Volume Ramp
+ *
+ *     amixer set "DVC Out Ramp Up Rate"   "0.125 dB/64 steps"
+ *     amixer set "DVC Out Ramp Down Rate" "0.125 dB/512 steps"
+ *     amixer set "DVC Out Ramp" on
+ *     aplay xxx.wav &
+ *     amixer set "DVC Out"  80%  // Volume Down
+ *     amixer set "DVC Out" 100%  // Volume Up
+ */
+
 /dts-v1/;
 #include "r8a7790.dtsi"
 #include <dt-bindings/gpio/gpio.h>
        compatible = "renesas,lager", "renesas,r8a7790";
 
        aliases {
-               serial6 = &scif0;
-               serial7 = &scif1;
+               serial6 = &scifa0;
+               serial7 = &scifa1;
        };
 
        chosen {
                bootargs = "console=ttySC6,115200 ignore_loglevel rw root=/dev/nfs ip=dhcp";
+               stdout-path = &scifa0;
        };
 
        memory@40000000 {
@@ -32,7 +61,7 @@
                reg = <0 0x40000000 0 0x40000000>;
        };
 
-       memory@180000000 {
+       memory@140000000 {
                device_type = "memory";
                reg = <1 0x40000000 0 0xc0000000>;
        };
@@ -42,7 +71,7 @@
                #size-cells = <1>;
        };
 
-       gpio_keys {
+       keyboard {
                compatible = "gpio-keys";
 
                button@1 {
                states = <3300000 1
                          1800000 0>;
        };
+
+       sound {
+               compatible = "simple-audio-card";
+
+               simple-audio-card,format = "left_j";
+               simple-audio-card,bitclock-master = <&sndcodec>;
+               simple-audio-card,frame-master = <&sndcodec>;
+
+               sndcpu: simple-audio-card,cpu {
+                       sound-dai = <&rcar_sound>;
+               };
+
+               sndcodec: simple-audio-card,codec {
+                       sound-dai = <&ak4643>;
+                       system-clock-frequency = <11289600>;
+               };
+       };
+
+       vga-encoder {
+               compatible = "adi,adv7123";
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+                               adv7123_in: endpoint {
+                                       remote-endpoint = <&du_out_rgb>;
+                               };
+                       };
+                       port@1 {
+                               reg = <1>;
+                               adv7123_out: endpoint {
+                                       remote-endpoint = <&vga_in>;
+                               };
+                       };
+               };
+       };
+
+       vga {
+               compatible = "vga-connector";
+
+               port {
+                       vga_in: endpoint {
+                               remote-endpoint = <&adv7123_out>;
+                       };
+               };
+       };
+};
+
+&du {
+       pinctrl-0 = <&du_pins>;
+       pinctrl-names = "default";
+       status = "okay";
+
+       ports {
+               port@0 {
+                       endpoint {
+                               remote-endpoint = <&adv7123_in>;
+                       };
+               };
+               port@2 {
+                       lvds_connector: endpoint {
+                       };
+               };
+       };
 };
 
 &extal_clk {
 };
 
 &pfc {
-       pinctrl-0 = <&du_pins>;
-       pinctrl-names = "default";
-
        du_pins: du {
                renesas,groups = "du_rgb666", "du_sync_1", "du_clk_out_0";
                renesas,function = "du";
        };
 
-       scif0_pins: serial0 {
-               renesas,groups = "scif0_data";
-               renesas,function = "scif0";
+       scifa0_pins: serial0 {
+               renesas,groups = "scifa0_data";
+               renesas,function = "scifa0";
        };
 
        ether_pins: ether {
                renesas,function = "intc";
        };
 
-       scif1_pins: serial1 {
-               renesas,groups = "scif1_data";
-               renesas,function = "scif1";
+       scifa1_pins: serial1 {
+               renesas,groups = "scifa1_data";
+               renesas,function = "scifa1";
        };
 
        sdhi0_pins: sd0 {
                renesas,function = "iic3";
        };
 
+       hsusb_pins: hsusb {
+               renesas,groups = "usb0_ovc_vbus";
+               renesas,function = "usb0";
+       };
+
        usb0_pins: usb0 {
                renesas,groups = "usb0";
                renesas,function = "usb0";
                renesas,groups = "usb2";
                renesas,function = "usb2";
        };
+
+       vin1_pins: vin {
+               renesas,groups = "vin1_data8", "vin1_clk";
+               renesas,function = "vin1";
+       };
+
+       sound_pins: sound {
+               renesas,groups = "ssi0129_ctrl", "ssi0_data", "ssi1_data";
+               renesas,function = "ssi";
+       };
+
+       sound_clk_pins: sound_clk {
+               renesas,groups = "audio_clk_a";
+               renesas,function = "audio_clk";
+       };
 };
 
 &ether {
        };
 };
 
+&cmt0 {
+       status = "ok";
+};
+
 &mmcif1 {
        pinctrl-0 = <&mmc1_pins>;
        pinctrl-names = "default";
        };
 };
 
-&scif0 {
-       pinctrl-0 = <&scif0_pins>;
+&scifa0 {
+       pinctrl-0 = <&scifa0_pins>;
        pinctrl-names = "default";
 
        status = "okay";
 };
 
-&scif1 {
-       pinctrl-0 = <&scif1_pins>;
+&scifa1 {
+       pinctrl-0 = <&scifa1_pins>;
        pinctrl-names = "default";
 
        status = "okay";
        status = "ok";
        pinctrl-0 = <&iic2_pins>;
        pinctrl-names = "default";
+
+       clock-frequency = <100000>;
+
+       ak4643: sound-codec@12 {
+               compatible = "asahi-kasei,ak4643";
+               #sound-dai-cells = <0>;
+               reg = <0x12>;
+       };
+
+       composite-in@20 {
+               compatible = "adi,adv7180";
+               reg = <0x20>;
+               remote = <&vin1>;
+
+               port {
+                       adv7180: endpoint {
+                               bus-width = <8>;
+                               remote-endpoint = <&vin1ep0>;
+                       };
+               };
+       };
 };
 
 &iic3 {
        status = "okay";
 
        vdd_dvfs: regulator@68 {
-               compatible = "diasemi,da9210";
+               compatible = "dlg,da9210";
                reg = <0x68>;
 
                regulator-min-microvolt = <1000000>;
        pinctrl-names = "default";
 };
 
+&xhci {
+       status = "okay";
+       pinctrl-0 = <&usb2_pins>;
+       pinctrl-names = "default";
+};
+
 &pci2 {
        status = "okay";
        pinctrl-0 = <&usb2_pins>;
        pinctrl-names = "default";
 };
+
+&hsusb {
+       status = "okay";
+       pinctrl-0 = <&hsusb_pins>;
+       pinctrl-names = "default";
+       renesas,enable-gpio = <&gpio5 18 GPIO_ACTIVE_HIGH>;
+};
+
+&usbphy {
+       status = "okay";
+};
+
+/* composite video input */
+&vin1 {
+       pinctrl-0 = <&vin1_pins>;
+       pinctrl-names = "default";
+
+       status = "ok";
+
+       port {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               vin1ep0: endpoint {
+                       remote-endpoint = <&adv7180>;
+                       bus-width = <8>;
+               };
+       };
+};
+
+&rcar_sound {
+       pinctrl-0 = <&sound_pins &sound_clk_pins>;
+       pinctrl-names = "default";
+
+       #sound-dai-cells = <0>;
+
+       status = "okay";
+
+       rcar_sound,dai {
+               dai0 {
+                       playback = <&ssi0 &src2 &dvc0>;
+                       capture  = <&ssi1 &src3 &dvc1>;
+               };
+       };
+};
+
+&ssi1 {
+       shared-pin;
+};
index d9ddecb..af7e255 100644 (file)
                spi2 = &msiof1;
                spi3 = &msiof2;
                spi4 = &msiof3;
+               vin0 = &vin0;
+               vin1 = &vin1;
+               vin2 = &vin2;
+               vin3 = &vin3;
        };
 
        cpus {
                             <1 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
        };
 
+       cmt0: timer@ffca0000 {
+               compatible = "renesas,cmt-48-r8a7790", "renesas,cmt-48-gen2";
+               reg = <0 0xffca0000 0 0x1004>;
+               interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 143 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp1_clks R8A7790_CLK_CMT0>;
+               clock-names = "fck";
+
+               renesas,channels-mask = <0x60>;
+
+               status = "disabled";
+       };
+
+       cmt1: timer@e6130000 {
+               compatible = "renesas,cmt-48-r8a7790", "renesas,cmt-48-gen2";
+               reg = <0 0xe6130000 0 0x1004>;
+               interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 121 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 122 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 123 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 124 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 125 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 126 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 127 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp3_clks R8A7790_CLK_CMT1>;
+               clock-names = "fck";
+
+               renesas,channels-mask = <0xff>;
+
+               status = "disabled";
+       };
+
        irqc0: interrupt-controller@e61c0000 {
                compatible = "renesas,irqc-r8a7790", "renesas,irqc";
                #interrupt-cells = <2>;
                             <0 3 IRQ_TYPE_LEVEL_HIGH>;
        };
 
+       dmac0: dma-controller@e6700000 {
+               compatible = "renesas,rcar-dmac";
+               reg = <0 0xe6700000 0 0x20000>;
+               interrupts = <0 197 IRQ_TYPE_LEVEL_HIGH
+                             0 200 IRQ_TYPE_LEVEL_HIGH
+                             0 201 IRQ_TYPE_LEVEL_HIGH
+                             0 202 IRQ_TYPE_LEVEL_HIGH
+                             0 203 IRQ_TYPE_LEVEL_HIGH
+                             0 204 IRQ_TYPE_LEVEL_HIGH
+                             0 205 IRQ_TYPE_LEVEL_HIGH
+                             0 206 IRQ_TYPE_LEVEL_HIGH
+                             0 207 IRQ_TYPE_LEVEL_HIGH
+                             0 208 IRQ_TYPE_LEVEL_HIGH
+                             0 209 IRQ_TYPE_LEVEL_HIGH
+                             0 210 IRQ_TYPE_LEVEL_HIGH
+                             0 211 IRQ_TYPE_LEVEL_HIGH
+                             0 212 IRQ_TYPE_LEVEL_HIGH
+                             0 213 IRQ_TYPE_LEVEL_HIGH
+                             0 214 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "error",
+                               "ch0", "ch1", "ch2", "ch3",
+                               "ch4", "ch5", "ch6", "ch7",
+                               "ch8", "ch9", "ch10", "ch11",
+                               "ch12", "ch13", "ch14";
+               clocks = <&mstp2_clks R8A7790_CLK_SYS_DMAC0>;
+               clock-names = "fck";
+               #dma-cells = <1>;
+               dma-channels = <15>;
+       };
+
+       dmac1: dma-controller@e6720000 {
+               compatible = "renesas,rcar-dmac";
+               reg = <0 0xe6720000 0 0x20000>;
+               interrupts = <0 220 IRQ_TYPE_LEVEL_HIGH
+                             0 216 IRQ_TYPE_LEVEL_HIGH
+                             0 217 IRQ_TYPE_LEVEL_HIGH
+                             0 218 IRQ_TYPE_LEVEL_HIGH
+                             0 219 IRQ_TYPE_LEVEL_HIGH
+                             0 308 IRQ_TYPE_LEVEL_HIGH
+                             0 309 IRQ_TYPE_LEVEL_HIGH
+                             0 310 IRQ_TYPE_LEVEL_HIGH
+                             0 311 IRQ_TYPE_LEVEL_HIGH
+                             0 312 IRQ_TYPE_LEVEL_HIGH
+                             0 313 IRQ_TYPE_LEVEL_HIGH
+                             0 314 IRQ_TYPE_LEVEL_HIGH
+                             0 315 IRQ_TYPE_LEVEL_HIGH
+                             0 316 IRQ_TYPE_LEVEL_HIGH
+                             0 317 IRQ_TYPE_LEVEL_HIGH
+                             0 318 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "error",
+                               "ch0", "ch1", "ch2", "ch3",
+                               "ch4", "ch5", "ch6", "ch7",
+                               "ch8", "ch9", "ch10", "ch11",
+                               "ch12", "ch13", "ch14";
+               clocks = <&mstp2_clks R8A7790_CLK_SYS_DMAC1>;
+               clock-names = "fck";
+               #dma-cells = <1>;
+               dma-channels = <15>;
+       };
+
+       audma0: dma-controller@ec700000 {
+               compatible = "renesas,rcar-dmac";
+               reg = <0 0xec700000 0 0x10000>;
+               interrupts =    <0 346 IRQ_TYPE_LEVEL_HIGH
+                                0 320 IRQ_TYPE_LEVEL_HIGH
+                                0 321 IRQ_TYPE_LEVEL_HIGH
+                                0 322 IRQ_TYPE_LEVEL_HIGH
+                                0 323 IRQ_TYPE_LEVEL_HIGH
+                                0 324 IRQ_TYPE_LEVEL_HIGH
+                                0 325 IRQ_TYPE_LEVEL_HIGH
+                                0 326 IRQ_TYPE_LEVEL_HIGH
+                                0 327 IRQ_TYPE_LEVEL_HIGH
+                                0 328 IRQ_TYPE_LEVEL_HIGH
+                                0 329 IRQ_TYPE_LEVEL_HIGH
+                                0 330 IRQ_TYPE_LEVEL_HIGH
+                                0 331 IRQ_TYPE_LEVEL_HIGH
+                                0 332 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "error",
+                               "ch0", "ch1", "ch2", "ch3",
+                               "ch4", "ch5", "ch6", "ch7",
+                               "ch8", "ch9", "ch10", "ch11",
+                               "ch12";
+               clocks = <&mstp5_clks R8A7790_CLK_AUDIO_DMAC0>;
+               clock-names = "fck";
+               #dma-cells = <1>;
+               dma-channels = <13>;
+       };
+
+       audma1: dma-controller@ec720000 {
+               compatible = "renesas,rcar-dmac";
+               reg = <0 0xec720000 0 0x10000>;
+               interrupts =    <0 347 IRQ_TYPE_LEVEL_HIGH
+                                0 333 IRQ_TYPE_LEVEL_HIGH
+                                0 334 IRQ_TYPE_LEVEL_HIGH
+                                0 335 IRQ_TYPE_LEVEL_HIGH
+                                0 336 IRQ_TYPE_LEVEL_HIGH
+                                0 337 IRQ_TYPE_LEVEL_HIGH
+                                0 338 IRQ_TYPE_LEVEL_HIGH
+                                0 339 IRQ_TYPE_LEVEL_HIGH
+                                0 340 IRQ_TYPE_LEVEL_HIGH
+                                0 341 IRQ_TYPE_LEVEL_HIGH
+                                0 342 IRQ_TYPE_LEVEL_HIGH
+                                0 343 IRQ_TYPE_LEVEL_HIGH
+                                0 344 IRQ_TYPE_LEVEL_HIGH
+                                0 345 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "error",
+                               "ch0", "ch1", "ch2", "ch3",
+                               "ch4", "ch5", "ch6", "ch7",
+                               "ch8", "ch9", "ch10", "ch11",
+                               "ch12";
+               clocks = <&mstp5_clks R8A7790_CLK_AUDIO_DMAC1>;
+               clock-names = "fck";
+               #dma-cells = <1>;
+               dma-channels = <13>;
+       };
+
+       audmapp: dma-controller@ec740000 {
+               compatible = "renesas,rcar-audmapp";
+               #dma-cells = <1>;
+
+               reg = <0 0xec740000 0 0x200>;
+       };
+
        i2c0: i2c@e6508000 {
                #address-cells = <1>;
                #size-cells = <0>;
                reg = <0 0xe6500000 0 0x425>;
                interrupts = <0 174 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp3_clks R8A7790_CLK_IIC0>;
+               dmas = <&dmac0 0x61>, <&dmac0 0x62>;
+               dma-names = "tx", "rx";
                status = "disabled";
        };
 
                reg = <0 0xe6510000 0 0x425>;
                interrupts = <0 175 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp3_clks R8A7790_CLK_IIC1>;
+               dmas = <&dmac0 0x65>, <&dmac0 0x66>;
+               dma-names = "tx", "rx";
                status = "disabled";
        };
 
                reg = <0 0xe6520000 0 0x425>;
                interrupts = <0 176 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp3_clks R8A7790_CLK_IIC2>;
+               dmas = <&dmac0 0x69>, <&dmac0 0x6a>;
+               dma-names = "tx", "rx";
                status = "disabled";
        };
 
                reg = <0 0xe60b0000 0 0x425>;
                interrupts = <0 173 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp9_clks R8A7790_CLK_IICDVFS>;
+               dmas = <&dmac0 0x77>, <&dmac0 0x78>;
+               dma-names = "tx", "rx";
                status = "disabled";
        };
 
-       mmcif0: mmcif@ee200000 {
+       mmcif0: mmc@ee200000 {
                compatible = "renesas,mmcif-r8a7790", "renesas,sh-mmcif";
                reg = <0 0xee200000 0 0x80>;
                interrupts = <0 169 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp3_clks R8A7790_CLK_MMCIF0>;
+               dmas = <&dmac0 0xd1>, <&dmac0 0xd2>;
+               dma-names = "tx", "rx";
                reg-io-width = <4>;
                status = "disabled";
        };
                reg = <0 0xee220000 0 0x80>;
                interrupts = <0 170 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp3_clks R8A7790_CLK_MMCIF1>;
+               dmas = <&dmac0 0xe1>, <&dmac0 0xe2>;
+               dma-names = "tx", "rx";
                reg-io-width = <4>;
                status = "disabled";
        };
                reg = <0 0xee100000 0 0x200>;
                interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp3_clks R8A7790_CLK_SDHI0>;
-               cap-sd-highspeed;
                status = "disabled";
        };
 
                reg = <0 0xee120000 0 0x200>;
                interrupts = <0 166 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp3_clks R8A7790_CLK_SDHI1>;
-               cap-sd-highspeed;
                status = "disabled";
        };
 
                reg = <0 0xee140000 0 0x100>;
                interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp3_clks R8A7790_CLK_SDHI2>;
-               cap-sd-highspeed;
                status = "disabled";
        };
 
                reg = <0 0xee160000 0 0x100>;
                interrupts = <0 168 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp3_clks R8A7790_CLK_SDHI3>;
-               cap-sd-highspeed;
                status = "disabled";
        };
 
                status = "disabled";
        };
 
+       hsusb: usb@e6590000 {
+               compatible = "renesas,usbhs-r8a7790";
+               reg = <0 0xe6590000 0 0x100>;
+               interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp7_clks R8A7790_CLK_HSUSB>;
+               renesas,buswait = <4>;
+               phys = <&usb0 1>;
+               phy-names = "usb";
+               status = "disabled";
+       };
+
+       usbphy: usb-phy@e6590100 {
+               compatible = "renesas,usb-phy-r8a7790";
+               reg = <0 0xe6590100 0 0x100>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&mstp7_clks R8A7790_CLK_HSUSB>;
+               clock-names = "usbhs";
+               status = "disabled";
+
+               usb0: usb-channel@0 {
+                       reg = <0>;
+                       #phy-cells = <1>;
+               };
+               usb2: usb-channel@2 {
+                       reg = <2>;
+                       #phy-cells = <1>;
+               };
+       };
+
+       vin0: video@e6ef0000 {
+               compatible = "renesas,vin-r8a7790";
+               clocks = <&mstp8_clks R8A7790_CLK_VIN0>;
+               reg = <0 0xe6ef0000 0 0x1000>;
+               interrupts = <0 188 IRQ_TYPE_LEVEL_HIGH>;
+               status = "disabled";
+       };
+
+       vin1: video@e6ef1000 {
+               compatible = "renesas,vin-r8a7790";
+               clocks = <&mstp8_clks R8A7790_CLK_VIN1>;
+               reg = <0 0xe6ef1000 0 0x1000>;
+               interrupts = <0 189 IRQ_TYPE_LEVEL_HIGH>;
+               status = "disabled";
+       };
+
+       vin2: video@e6ef2000 {
+               compatible = "renesas,vin-r8a7790";
+               clocks = <&mstp8_clks R8A7790_CLK_VIN2>;
+               reg = <0 0xe6ef2000 0 0x1000>;
+               interrupts = <0 190 IRQ_TYPE_LEVEL_HIGH>;
+               status = "disabled";
+       };
+
+       vin3: video@e6ef3000 {
+               compatible = "renesas,vin-r8a7790";
+               clocks = <&mstp8_clks R8A7790_CLK_VIN3>;
+               reg = <0 0xe6ef3000 0 0x1000>;
+               interrupts = <0 191 IRQ_TYPE_LEVEL_HIGH>;
+               status = "disabled";
+       };
+
+       vsp1@fe920000 {
+               compatible = "renesas,vsp1";
+               reg = <0 0xfe920000 0 0x8000>;
+               interrupts = <0 266 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp1_clks R8A7790_CLK_VSP1_R>;
+
+               renesas,has-sru;
+               renesas,#rpf = <5>;
+               renesas,#uds = <1>;
+               renesas,#wpf = <4>;
+       };
+
+       vsp1@fe928000 {
+               compatible = "renesas,vsp1";
+               reg = <0 0xfe928000 0 0x8000>;
+               interrupts = <0 267 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp1_clks R8A7790_CLK_VSP1_S>;
+
+               renesas,has-lut;
+               renesas,has-sru;
+               renesas,#rpf = <5>;
+               renesas,#uds = <3>;
+               renesas,#wpf = <4>;
+       };
+
+       vsp1@fe930000 {
+               compatible = "renesas,vsp1";
+               reg = <0 0xfe930000 0 0x8000>;
+               interrupts = <0 246 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp1_clks R8A7790_CLK_VSP1_DU0>;
+
+               renesas,has-lif;
+               renesas,has-lut;
+               renesas,#rpf = <4>;
+               renesas,#uds = <1>;
+               renesas,#wpf = <4>;
+       };
+
+       vsp1@fe938000 {
+               compatible = "renesas,vsp1";
+               reg = <0 0xfe938000 0 0x8000>;
+               interrupts = <0 247 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp1_clks R8A7790_CLK_VSP1_DU1>;
+
+               renesas,has-lif;
+               renesas,has-lut;
+               renesas,#rpf = <4>;
+               renesas,#uds = <1>;
+               renesas,#wpf = <4>;
+       };
+
+       du: display@feb00000 {
+               compatible = "renesas,du-r8a7790";
+               reg = <0 0xfeb00000 0 0x70000>,
+                     <0 0xfeb90000 0 0x1c>,
+                     <0 0xfeb94000 0 0x1c>;
+               reg-names = "du", "lvds.0", "lvds.1";
+               interrupts = <0 256 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 268 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 269 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp7_clks R8A7790_CLK_DU0>,
+                        <&mstp7_clks R8A7790_CLK_DU1>,
+                        <&mstp7_clks R8A7790_CLK_DU2>,
+                        <&mstp7_clks R8A7790_CLK_LVDS0>,
+                        <&mstp7_clks R8A7790_CLK_LVDS1>;
+               clock-names = "du.0", "du.1", "du.2", "lvds.0", "lvds.1";
+               status = "disabled";
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+                               du_out_rgb: endpoint {
+                               };
+                       };
+                       port@1 {
+                               reg = <1>;
+                               du_out_lvds0: endpoint {
+                               };
+                       };
+                       port@2 {
+                               reg = <2>;
+                               du_out_lvds1: endpoint {
+                               };
+                       };
+               };
+       };
+
        clocks {
                #address-cells = <2>;
                #size-cells = <2>;
                        #clock-cells = <0>;
                        clock-output-names = "sd2";
                };
-               sd3_clk: sd3_clk@e615007c {
+               sd3_clk: sd3_clk@e615026c {
                        compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock";
-                       reg = <0 0xe615007c 0 4>;
+                       reg = <0 0xe615026c 0 4>;
                        clocks = <&pll1_div2_clk>;
                        #clock-cells = <0>;
                        clock-output-names = "sd3";
                mstp1_clks: mstp1_clks@e6150134 {
                        compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
                        reg = <0 0xe6150134 0 4>, <0 0xe6150038 0 4>;
-                       clocks = <&p_clk>, <&p_clk>, <&p_clk>, <&rclk_clk>,
-                                <&cp_clk>, <&zs_clk>, <&zs_clk>, <&zs_clk>,
-                                <&zs_clk>;
+                       clocks = <&zs_clk>, <&zs_clk>, <&zs_clk>, <&zs_clk>, <&m2_clk>,
+                                <&zs_clk>, <&p_clk>, <&zg_clk>, <&zs_clk>, <&zs_clk>,
+                                <&zs_clk>, <&zs_clk>, <&p_clk>, <&p_clk>, <&rclk_clk>,
+                                <&cp_clk>, <&zs_clk>, <&zs_clk>, <&zs_clk>, <&zs_clk>;
                        #clock-cells = <1>;
                        renesas,clock-indices = <
-                               R8A7790_CLK_TMU1 R8A7790_CLK_TMU3 R8A7790_CLK_TMU2
-                               R8A7790_CLK_CMT0 R8A7790_CLK_TMU0 R8A7790_CLK_VSP1_DU1
-                               R8A7790_CLK_VSP1_DU0 R8A7790_CLK_VSP1_R R8A7790_CLK_VSP1_S
+                               R8A7790_CLK_VCP1 R8A7790_CLK_VCP0 R8A7790_CLK_VPC1
+                               R8A7790_CLK_VPC0 R8A7790_CLK_JPU R8A7790_CLK_SSP1
+                               R8A7790_CLK_TMU1 R8A7790_CLK_3DG R8A7790_CLK_2DDMAC
+                               R8A7790_CLK_FDP1_2 R8A7790_CLK_FDP1_1 R8A7790_CLK_FDP1_0
+                               R8A7790_CLK_TMU3 R8A7790_CLK_TMU2 R8A7790_CLK_CMT0
+                               R8A7790_CLK_TMU0 R8A7790_CLK_VSP1_DU1 R8A7790_CLK_VSP1_DU0
+                               R8A7790_CLK_VSP1_R R8A7790_CLK_VSP1_S
                        >;
                        clock-output-names =
-                               "tmu1", "tmu3", "tmu2", "cmt0", "tmu0", "vsp1-du1",
-                               "vsp1-du0", "vsp1-rt", "vsp1-sy";
+                               "vcp1", "vcp0", "vpc1", "vpc0", "jpu", "ssp1",
+                               "tmu1", "3dg", "2ddmac", "fdp1-2", "fdp1-1",
+                               "fdp1-0", "tmu3", "tmu2", "cmt0", "tmu0",
+                               "vsp1-du1", "vsp1-du0", "vsp1-rt", "vsp1-sy";
                };
                mstp2_clks: mstp2_clks@e6150138 {
                        compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
                        reg = <0 0xe6150138 0 4>, <0 0xe6150040 0 4>;
                        clocks = <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>,
-                                <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>;
+                                <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>, <&zs_clk>,
+                                <&zs_clk>;
                        #clock-cells = <1>;
                        renesas,clock-indices = <
                                R8A7790_CLK_SCIFA2 R8A7790_CLK_SCIFA1 R8A7790_CLK_SCIFA0
                                R8A7790_CLK_MSIOF2 R8A7790_CLK_SCIFB0 R8A7790_CLK_SCIFB1
                                R8A7790_CLK_MSIOF1 R8A7790_CLK_MSIOF3 R8A7790_CLK_SCIFB2
+                               R8A7790_CLK_SYS_DMAC1 R8A7790_CLK_SYS_DMAC0
                        >;
                        clock-output-names =
                                "scifa2", "scifa1", "scifa0", "msiof2", "scifb0",
-                               "scifb1", "msiof1", "msiof3", "scifb2";
+                               "scifb1", "msiof1", "msiof3", "scifb2",
+                               "sys-dmac1", "sys-dmac0";
                };
                mstp3_clks: mstp3_clks@e615013c {
                        compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
                        reg = <0 0xe615013c 0 4>, <0 0xe6150048 0 4>;
                        clocks = <&hp_clk>, <&cp_clk>, <&mmc1_clk>, <&sd3_clk>,
                                 <&sd2_clk>, <&cpg_clocks R8A7790_CLK_SD1>, <&cpg_clocks R8A7790_CLK_SD0>, <&mmc0_clk>,
-                                <&hp_clk>, <&mp_clk>, <&hp_clk>, <&mp_clk>, <&rclk_clk>;
+                                <&hp_clk>, <&mp_clk>, <&hp_clk>, <&mp_clk>, <&rclk_clk>,
+                                <&hp_clk>, <&hp_clk>;
                        #clock-cells = <1>;
                        renesas,clock-indices = <
                                R8A7790_CLK_IIC2 R8A7790_CLK_TPU0 R8A7790_CLK_MMCIF1 R8A7790_CLK_SDHI3
                                R8A7790_CLK_SDHI2 R8A7790_CLK_SDHI1 R8A7790_CLK_SDHI0 R8A7790_CLK_MMCIF0
                                R8A7790_CLK_IIC0 R8A7790_CLK_PCIEC R8A7790_CLK_IIC1 R8A7790_CLK_SSUSB R8A7790_CLK_CMT1
+                               R8A7790_CLK_USBDMAC0 R8A7790_CLK_USBDMAC1
                        >;
                        clock-output-names =
                                "iic2", "tpu0", "mmcif1", "sdhi3",
                                "sdhi2", "sdhi1", "sdhi0", "mmcif0",
-                               "iic0", "pciec", "iic1", "ssusb", "cmt1";
+                               "iic0", "pciec", "iic1", "ssusb", "cmt1",
+                               "usbdmac0", "usbdmac1";
                };
                mstp5_clks: mstp5_clks@e6150144 {
                        compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
                        reg = <0 0xe6150144 0 4>, <0 0xe615003c 0 4>;
-                       clocks = <&extal_clk>, <&p_clk>;
+                       clocks = <&hp_clk>, <&hp_clk>, <&extal_clk>, <&p_clk>;
                        #clock-cells = <1>;
-                       renesas,clock-indices = <R8A7790_CLK_THERMAL R8A7790_CLK_PWM>;
-                       clock-output-names = "thermal", "pwm";
+                       renesas,clock-indices = <R8A7790_CLK_AUDIO_DMAC0 R8A7790_CLK_AUDIO_DMAC1
+                                                R8A7790_CLK_THERMAL R8A7790_CLK_PWM>;
+                       clock-output-names = "audmac0", "audmac1", "thermal", "pwm";
                };
                mstp7_clks: mstp7_clks@e615014c {
                        compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
                reg = <0 0xe6b10000 0 0x2c>;
                interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp9_clks R8A7790_CLK_QSPI_MOD>;
+               dmas = <&dmac0 0x17>, <&dmac0 0x18>;
+               dma-names = "tx", "rx";
                num-cs = <1>;
                #address-cells = <1>;
                #size-cells = <0>;
 
        msiof0: spi@e6e20000 {
                compatible = "renesas,msiof-r8a7790";
-               reg = <0 0xe6e20000 0 0x0064>;
+               reg = <0 0xe6e20000 0 0x0064>, <0 0xe7e20000 0 0x0064>;
                interrupts = <0 156 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp0_clks R8A7790_CLK_MSIOF0>;
+               dmas = <&dmac0 0x51>, <&dmac0 0x52>;
+               dma-names = "tx", "rx";
                #address-cells = <1>;
                #size-cells = <0>;
                status = "disabled";
 
        msiof1: spi@e6e10000 {
                compatible = "renesas,msiof-r8a7790";
-               reg = <0 0xe6e10000 0 0x0064>;
+               reg = <0 0xe6e10000 0 0x0064>, <0 0xe7e10000 0 0x0064>;
                interrupts = <0 157 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp2_clks R8A7790_CLK_MSIOF1>;
+               dmas = <&dmac0 0x55>, <&dmac0 0x56>;
+               dma-names = "tx", "rx";
                #address-cells = <1>;
                #size-cells = <0>;
                status = "disabled";
 
        msiof2: spi@e6e00000 {
                compatible = "renesas,msiof-r8a7790";
-               reg = <0 0xe6e00000 0 0x0064>;
+               reg = <0 0xe6e00000 0 0x0064>, <0 0xe7e00000 0 0x0064>;
                interrupts = <0 158 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp2_clks R8A7790_CLK_MSIOF2>;
+               dmas = <&dmac0 0x41>, <&dmac0 0x42>;
+               dma-names = "tx", "rx";
                #address-cells = <1>;
                #size-cells = <0>;
                status = "disabled";
 
        msiof3: spi@e6c90000 {
                compatible = "renesas,msiof-r8a7790";
-               reg = <0 0xe6c90000 0 0x0064>;
+               reg = <0 0xe6c90000 0 0x0064>, <0 0xe7c90000 0 0x0064>;
                interrupts = <0 159 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp2_clks R8A7790_CLK_MSIOF3>;
+               dmas = <&dmac0 0x45>, <&dmac0 0x46>;
+               dma-names = "tx", "rx";
                #address-cells = <1>;
                #size-cells = <0>;
                status = "disabled";
        };
 
+       xhci: usb@ee000000 {
+               compatible = "renesas,xhci-r8a7790";
+               reg = <0 0xee000000 0 0xc00>;
+               interrupts = <0 101 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp3_clks R8A7790_CLK_SSUSB>;
+               phys = <&usb2 1>;
+               phy-names = "usb";
+               status = "disabled";
+       };
+
        pci0: pci@ee090000 {
                compatible = "renesas,pci-r8a7790";
                device_type = "pci";
                interrupt-map = <0x0000 0 0 1 &gic 0 108 IRQ_TYPE_LEVEL_HIGH
                                 0x0800 0 0 1 &gic 0 108 IRQ_TYPE_LEVEL_HIGH
                                 0x1000 0 0 2 &gic 0 108 IRQ_TYPE_LEVEL_HIGH>;
+
+               usb@0,1 {
+                       reg = <0x800 0 0 0 0>;
+                       device_type = "pci";
+                       phys = <&usb0 0>;
+                       phy-names = "usb";
+               };
+
+               usb@0,2 {
+                       reg = <0x1000 0 0 0 0>;
+                       device_type = "pci";
+                       phys = <&usb0 0>;
+                       phy-names = "usb";
+               };
        };
 
        pci1: pci@ee0b0000 {
                interrupt-map = <0x0000 0 0 1 &gic 0 113 IRQ_TYPE_LEVEL_HIGH
                                 0x0800 0 0 1 &gic 0 113 IRQ_TYPE_LEVEL_HIGH
                                 0x1000 0 0 2 &gic 0 113 IRQ_TYPE_LEVEL_HIGH>;
+
+               usb@0,1 {
+                       reg = <0x800 0 0 0 0>;
+                       device_type = "pci";
+                       phys = <&usb2 0>;
+                       phy-names = "usb";
+               };
+
+               usb@0,2 {
+                       reg = <0x1000 0 0 0 0>;
+                       device_type = "pci";
+                       phys = <&usb2 0>;
+                       phy-names = "usb";
+               };
        };
 
        pciec: pcie@fe000000 {
                status = "disabled";
        };
 
-       rcar_sound: rcar_sound@0xec500000 {
+       rcar_sound: rcar_sound@ec500000 {
                #sound-dai-cells = <1>;
                compatible =  "renesas,rcar_sound-r8a7790", "renesas,rcar_sound-gen2", "renesas,rcar_sound";
-               interrupt-parent = <&gic>;
                reg =   <0 0xec500000 0 0x1000>, /* SCU */
                        <0 0xec5a0000 0 0x100>,  /* ADG */
                        <0 0xec540000 0 0x1000>, /* SSIU */
index 3a2ef0a..740e386 100644 (file)
@@ -23,6 +23,7 @@
 
        chosen {
                bootargs = "console=ttySC0,38400 ignore_loglevel rw root=/dev/nfs ip=dhcp";
+               stdout-path = &scif0;
        };
 
        memory@40000000 {
                renesas,groups = "usb1";
                renesas,function = "usb1";
        };
+
+       vin0_pins: vin0 {
+               renesas,groups = "vin0_data8", "vin0_clk";
+               renesas,function = "vin0";
+       };
 };
 
 &scif0 {
 
        status = "okay";
        clock-frequency = <400000>;
+
+       composite-in@20 {
+               compatible = "adi,adv7180";
+               reg = <0x20>;
+               remote = <&vin0>;
+
+               port {
+                       adv7180: endpoint {
+                               bus-width = <8>;
+                               remote-endpoint = <&vin0ep>;
+                       };
+               };
+       };
 };
 
 &qspi {
        pinctrl-names = "default";
 };
 
+&hsusb {
+       status = "okay";
+       pinctrl-0 = <&usb0_pins>;
+       pinctrl-names = "default";
+       renesas,enable-gpio = <&gpio5 31 GPIO_ACTIVE_HIGH>;
+};
+
+&usbphy {
+       status = "okay";
+};
+
 &pcie_bus_clk {
        status = "okay";
 };
 &pciec {
        status = "okay";
 };
+
+/* composite video input */
+&vin0 {
+       status = "ok";
+       pinctrl-0 = <&vin0_pins>;
+       pinctrl-names = "default";
+
+       port {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               vin0ep: endpoint {
+                       remote-endpoint = <&adv7180>;
+                       bus-width = <8>;
+               };
+       };
+};
index be59014..990af16 100644 (file)
  * kind, whether express or implied.
  */
 
+/*
+ * SSI-AK4643
+ *
+ * SW1: 1: AK4643
+ *      2: CN22
+ *      3: ADV7511
+ *
+ * This command is required when Playback/Capture
+ *
+ *     amixer set "LINEOUT Mixer DACL" on
+ *     amixer set "DVC Out" 100%
+ *     amixer set "DVC In" 100%
+ *
+ * You can use Mute
+ *
+ *     amixer set "DVC Out Mute" on
+ *     amixer set "DVC In Mute" on
+ *
+ * You can use Volume Ramp
+ *
+ *     amixer set "DVC Out Ramp Up Rate"   "0.125 dB/64 steps"
+ *     amixer set "DVC Out Ramp Down Rate" "0.125 dB/512 steps"
+ *     amixer set "DVC Out Ramp" on
+ *     aplay xxx.wav &
+ *     amixer set "DVC Out"  80%  // Volume Down
+ *     amixer set "DVC Out" 100%  // Volume Up
+ */
+
 /dts-v1/;
 #include "r8a7791.dtsi"
 #include <dt-bindings/gpio/gpio.h>
@@ -25,7 +53,8 @@
        };
 
        chosen {
-               bootargs = "console=ttySC6,115200 ignore_loglevel rw root=/dev/nfs ip=dhcp";
+               bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp";
+               stdout-path = &scif0;
        };
 
        memory@40000000 {
@@ -43,7 +72,7 @@
                #size-cells = <1>;
        };
 
-       gpio-keys {
+       keyboard {
                compatible = "gpio-keys";
 
                key-1 {
                compatible = "gpio-leds";
                led6 {
                        gpios = <&gpio2 19 GPIO_ACTIVE_HIGH>;
+                       label = "LED6";
                };
                led7 {
                        gpios = <&gpio2 20 GPIO_ACTIVE_HIGH>;
+                       label = "LED7";
                };
                led8 {
                        gpios = <&gpio2 21 GPIO_ACTIVE_HIGH>;
+                       label = "LED8";
                };
        };
 
                states = <3300000 1
                          1800000 0>;
        };
+
+       sound {
+               compatible = "simple-audio-card";
+
+               simple-audio-card,format = "left_j";
+               simple-audio-card,bitclock-master = <&sndcodec>;
+               simple-audio-card,frame-master = <&sndcodec>;
+
+               sndcpu: simple-audio-card,cpu {
+                       sound-dai = <&rcar_sound>;
+               };
+
+               sndcodec: simple-audio-card,codec {
+                       sound-dai = <&ak4643>;
+                       system-clock-frequency = <11289600>;
+               };
+       };
+};
+
+&du {
+       pinctrl-0 = <&du_pins>;
+       pinctrl-names = "default";
+       status = "okay";
+
+       ports {
+               port@1 {
+                       lvds_connector: endpoint {
+                       };
+               };
+       };
 };
 
 &extal_clk {
 };
 
 &pfc {
-       pinctrl-0 = <&du_pins>;
-       pinctrl-names = "default";
-
        i2c2_pins: i2c2 {
                renesas,groups = "i2c2";
                renesas,function = "i2c2";
                renesas,groups = "usb1";
                renesas,function = "usb1";
        };
+
+       vin1_pins: vin1 {
+               renesas,groups = "vin1_data8", "vin1_clk";
+               renesas,function = "vin1";
+       };
+
+       sound_pins: sound {
+               renesas,groups = "ssi0129_ctrl", "ssi0_data", "ssi1_data";
+               renesas,function = "ssi";
+       };
+
+       sound_clk_pins: sound_clk {
+               renesas,groups = "audio_clk_a";
+               renesas,function = "audio_clk";
+       };
 };
 
 &ether {
        };
 };
 
+&cmt0 {
+       status = "ok";
+};
+
 &sata0 {
        status = "okay";
 };
        pinctrl-names = "default";
 
        status = "okay";
-       clock-frequency = <400000>;
+       clock-frequency = <100000>;
+
+       ak4643: sound-codec@12 {
+               compatible = "asahi-kasei,ak4643";
+               #sound-dai-cells = <0>;
+               reg = <0x12>;
+       };
+
+       composite-in@20 {
+               compatible = "adi,adv7180";
+               reg = <0x20>;
+               remote = <&vin1>;
+
+               port {
+                       adv7180: endpoint {
+                               bus-width = <8>;
+                               remote-endpoint = <&vin1ep>;
+                       };
+               };
+       };
 
        eeprom@50 {
                compatible = "renesas,24c02";
        clock-frequency = <100000>;
 
        vdd_dvfs: regulator@68 {
-               compatible = "diasemi,da9210";
+               compatible = "dlg,da9210";
                reg = <0x68>;
 
                regulator-min-microvolt = <1000000>;
        pinctrl-names = "default";
 };
 
+&hsusb {
+       status = "okay";
+       pinctrl-0 = <&usb0_pins>;
+       pinctrl-names = "default";
+       renesas,enable-gpio = <&gpio5 31 GPIO_ACTIVE_HIGH>;
+};
+
+&usbphy {
+       status = "okay";
+};
+
 &pcie_bus_clk {
        status = "okay";
 };
 &cpu0 {
        cpu0-supply = <&vdd_dvfs>;
 };
+
+/* composite video input */
+&vin1 {
+       status = "ok";
+       pinctrl-0 = <&vin1_pins>;
+       pinctrl-names = "default";
+
+       port {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               vin1ep: endpoint {
+                       remote-endpoint = <&adv7180>;
+                       bus-width = <8>;
+               };
+       };
+};
+
+&rcar_sound {
+       pinctrl-0 = <&sound_pins &sound_clk_pins>;
+       pinctrl-names = "default";
+
+       #sound-dai-cells = <0>;
+
+       status = "okay";
+
+       rcar_sound,dai {
+               dai0 {
+                       playback = <&ssi0 &src2 &dvc0>;
+                       capture  = <&ssi1 &src3 &dvc1>;
+               };
+       };
+};
+
+&ssi1 {
+       shared-pin;
+};
index 0d82a4b..77c0bee 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Device Tree Source for the r8a7791 SoC
  *
- * Copyright (C) 2013 Renesas Electronics Corporation
+ * Copyright (C) 2013-2014 Renesas Electronics Corporation
  * Copyright (C) 2013-2014 Renesas Solutions Corp.
  * Copyright (C) 2014 Cogent Embedded Inc.
  *
@@ -34,6 +34,9 @@
                spi1 = &msiof0;
                spi2 = &msiof1;
                spi3 = &msiof2;
+               vin0 = &vin0;
+               vin1 = &vin1;
+               vin2 = &vin2;
        };
 
        cpus {
                             <1 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
        };
 
+       cmt0: timer@ffca0000 {
+               compatible = "renesas,cmt-48-r8a7791", "renesas,cmt-48-gen2";
+               reg = <0 0xffca0000 0 0x1004>;
+               interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 143 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp1_clks R8A7791_CLK_CMT0>;
+               clock-names = "fck";
+
+               renesas,channels-mask = <0x60>;
+
+               status = "disabled";
+       };
+
+       cmt1: timer@e6130000 {
+               compatible = "renesas,cmt-48-r8a7791", "renesas,cmt-48-gen2";
+               reg = <0 0xe6130000 0 0x1004>;
+               interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 121 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 122 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 123 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 124 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 125 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 126 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 127 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp3_clks R8A7791_CLK_CMT1>;
+               clock-names = "fck";
+
+               renesas,channels-mask = <0xff>;
+
+               status = "disabled";
+       };
+
        irqc0: interrupt-controller@e61c0000 {
                compatible = "renesas,irqc-r8a7791", "renesas,irqc";
                #interrupt-cells = <2>;
                             <0 17 IRQ_TYPE_LEVEL_HIGH>;
        };
 
+       dmac0: dma-controller@e6700000 {
+               compatible = "renesas,rcar-dmac";
+               reg = <0 0xe6700000 0 0x20000>;
+               interrupts = <0 197 IRQ_TYPE_LEVEL_HIGH
+                             0 200 IRQ_TYPE_LEVEL_HIGH
+                             0 201 IRQ_TYPE_LEVEL_HIGH
+                             0 202 IRQ_TYPE_LEVEL_HIGH
+                             0 203 IRQ_TYPE_LEVEL_HIGH
+                             0 204 IRQ_TYPE_LEVEL_HIGH
+                             0 205 IRQ_TYPE_LEVEL_HIGH
+                             0 206 IRQ_TYPE_LEVEL_HIGH
+                             0 207 IRQ_TYPE_LEVEL_HIGH
+                             0 208 IRQ_TYPE_LEVEL_HIGH
+                             0 209 IRQ_TYPE_LEVEL_HIGH
+                             0 210 IRQ_TYPE_LEVEL_HIGH
+                             0 211 IRQ_TYPE_LEVEL_HIGH
+                             0 212 IRQ_TYPE_LEVEL_HIGH
+                             0 213 IRQ_TYPE_LEVEL_HIGH
+                             0 214 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "error",
+                               "ch0", "ch1", "ch2", "ch3",
+                               "ch4", "ch5", "ch6", "ch7",
+                               "ch8", "ch9", "ch10", "ch11",
+                               "ch12", "ch13", "ch14";
+               clocks = <&mstp2_clks R8A7791_CLK_SYS_DMAC0>;
+               clock-names = "fck";
+               #dma-cells = <1>;
+               dma-channels = <15>;
+       };
+
+       dmac1: dma-controller@e6720000 {
+               compatible = "renesas,rcar-dmac";
+               reg = <0 0xe6720000 0 0x20000>;
+               interrupts = <0 220 IRQ_TYPE_LEVEL_HIGH
+                             0 216 IRQ_TYPE_LEVEL_HIGH
+                             0 217 IRQ_TYPE_LEVEL_HIGH
+                             0 218 IRQ_TYPE_LEVEL_HIGH
+                             0 219 IRQ_TYPE_LEVEL_HIGH
+                             0 308 IRQ_TYPE_LEVEL_HIGH
+                             0 309 IRQ_TYPE_LEVEL_HIGH
+                             0 310 IRQ_TYPE_LEVEL_HIGH
+                             0 311 IRQ_TYPE_LEVEL_HIGH
+                             0 312 IRQ_TYPE_LEVEL_HIGH
+                             0 313 IRQ_TYPE_LEVEL_HIGH
+                             0 314 IRQ_TYPE_LEVEL_HIGH
+                             0 315 IRQ_TYPE_LEVEL_HIGH
+                             0 316 IRQ_TYPE_LEVEL_HIGH
+                             0 317 IRQ_TYPE_LEVEL_HIGH
+                             0 318 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "error",
+                               "ch0", "ch1", "ch2", "ch3",
+                               "ch4", "ch5", "ch6", "ch7",
+                               "ch8", "ch9", "ch10", "ch11",
+                               "ch12", "ch13", "ch14";
+               clocks = <&mstp2_clks R8A7791_CLK_SYS_DMAC1>;
+               clock-names = "fck";
+               #dma-cells = <1>;
+               dma-channels = <15>;
+       };
+
+       audma0: dma-controller@ec700000 {
+               compatible = "renesas,rcar-dmac";
+               reg = <0 0xec700000 0 0x10000>;
+               interrupts =    <0 346 IRQ_TYPE_LEVEL_HIGH
+                                0 320 IRQ_TYPE_LEVEL_HIGH
+                                0 321 IRQ_TYPE_LEVEL_HIGH
+                                0 322 IRQ_TYPE_LEVEL_HIGH
+                                0 323 IRQ_TYPE_LEVEL_HIGH
+                                0 324 IRQ_TYPE_LEVEL_HIGH
+                                0 325 IRQ_TYPE_LEVEL_HIGH
+                                0 326 IRQ_TYPE_LEVEL_HIGH
+                                0 327 IRQ_TYPE_LEVEL_HIGH
+                                0 328 IRQ_TYPE_LEVEL_HIGH
+                                0 329 IRQ_TYPE_LEVEL_HIGH
+                                0 330 IRQ_TYPE_LEVEL_HIGH
+                                0 331 IRQ_TYPE_LEVEL_HIGH
+                                0 332 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "error",
+                               "ch0", "ch1", "ch2", "ch3",
+                               "ch4", "ch5", "ch6", "ch7",
+                               "ch8", "ch9", "ch10", "ch11",
+                               "ch12";
+               clocks = <&mstp5_clks R8A7791_CLK_AUDIO_DMAC0>;
+               clock-names = "fck";
+               #dma-cells = <1>;
+               dma-channels = <13>;
+       };
+
+       audma1: dma-controller@ec720000 {
+               compatible = "renesas,rcar-dmac";
+               reg = <0 0xec720000 0 0x10000>;
+               interrupts =    <0 347 IRQ_TYPE_LEVEL_HIGH
+                                0 333 IRQ_TYPE_LEVEL_HIGH
+                                0 334 IRQ_TYPE_LEVEL_HIGH
+                                0 335 IRQ_TYPE_LEVEL_HIGH
+                                0 336 IRQ_TYPE_LEVEL_HIGH
+                                0 337 IRQ_TYPE_LEVEL_HIGH
+                                0 338 IRQ_TYPE_LEVEL_HIGH
+                                0 339 IRQ_TYPE_LEVEL_HIGH
+                                0 340 IRQ_TYPE_LEVEL_HIGH
+                                0 341 IRQ_TYPE_LEVEL_HIGH
+                                0 342 IRQ_TYPE_LEVEL_HIGH
+                                0 343 IRQ_TYPE_LEVEL_HIGH
+                                0 344 IRQ_TYPE_LEVEL_HIGH
+                                0 345 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "error",
+                               "ch0", "ch1", "ch2", "ch3",
+                               "ch4", "ch5", "ch6", "ch7",
+                               "ch8", "ch9", "ch10", "ch11",
+                               "ch12";
+               clocks = <&mstp5_clks R8A7791_CLK_AUDIO_DMAC1>;
+               clock-names = "fck";
+               #dma-cells = <1>;
+               dma-channels = <13>;
+       };
+
+       audmapp: dma-controller@ec740000 {
+               compatible = "renesas,rcar-audmapp";
+               #dma-cells = <1>;
+
+               reg = <0 0xec740000 0 0x200>;
+       };
+
        /* The memory map in the User's Manual maps the cores to bus numbers */
        i2c0: i2c@e6508000 {
                #address-cells = <1>;
                reg = <0 0xe60b0000 0 0x425>;
                interrupts = <0 173 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp9_clks R8A7791_CLK_IICDVFS>;
+               dmas = <&dmac0 0x77>, <&dmac0 0x78>;
+               dma-names = "tx", "rx";
                status = "disabled";
        };
 
                reg = <0 0xe6500000 0 0x425>;
                interrupts = <0 174 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp3_clks R8A7791_CLK_IIC0>;
+               dmas = <&dmac0 0x61>, <&dmac0 0x62>;
+               dma-names = "tx", "rx";
                status = "disabled";
        };
 
                reg = <0 0xe6510000 0 0x425>;
                interrupts = <0 175 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp3_clks R8A7791_CLK_IIC1>;
+               dmas = <&dmac0 0x65>, <&dmac0 0x66>;
+               dma-names = "tx", "rx";
                status = "disabled";
        };
 
                #gpio-range-cells = <3>;
        };
 
+       mmcif0: mmc@ee200000 {
+               compatible = "renesas,mmcif-r8a7791", "renesas,sh-mmcif";
+               reg = <0 0xee200000 0 0x80>;
+               interrupts = <0 169 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp3_clks R8A7791_CLK_MMCIF0>;
+               dmas = <&dmac0 0xd1>, <&dmac0 0xd2>;
+               dma-names = "tx", "rx";
+               reg-io-width = <4>;
+               status = "disabled";
+       };
+
        sdhi0: sd@ee100000 {
                compatible = "renesas,sdhi-r8a7791";
                reg = <0 0xee100000 0 0x200>;
                status = "disabled";
        };
 
+       hsusb: usb@e6590000 {
+               compatible = "renesas,usbhs-r8a7791";
+               reg = <0 0xe6590000 0 0x100>;
+               interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp7_clks R8A7791_CLK_HSUSB>;
+               renesas,buswait = <4>;
+               phys = <&usb0 1>;
+               phy-names = "usb";
+               status = "disabled";
+       };
+
+       usbphy: usb-phy@e6590100 {
+               compatible = "renesas,usb-phy-r8a7791";
+               reg = <0 0xe6590100 0 0x100>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&mstp7_clks R8A7791_CLK_HSUSB>;
+               clock-names = "usbhs";
+               status = "disabled";
+
+               usb0: usb-channel@0 {
+                       reg = <0>;
+                       #phy-cells = <1>;
+               };
+               usb2: usb-channel@2 {
+                       reg = <2>;
+                       #phy-cells = <1>;
+               };
+       };
+
+       vin0: video@e6ef0000 {
+               compatible = "renesas,vin-r8a7791";
+               clocks = <&mstp8_clks R8A7791_CLK_VIN0>;
+               reg = <0 0xe6ef0000 0 0x1000>;
+               interrupts = <0 188 IRQ_TYPE_LEVEL_HIGH>;
+               status = "disabled";
+       };
+
+       vin1: video@e6ef1000 {
+               compatible = "renesas,vin-r8a7791";
+               clocks = <&mstp8_clks R8A7791_CLK_VIN1>;
+               reg = <0 0xe6ef1000 0 0x1000>;
+               interrupts = <0 189 IRQ_TYPE_LEVEL_HIGH>;
+               status = "disabled";
+       };
+
+       vin2: video@e6ef2000 {
+               compatible = "renesas,vin-r8a7791";
+               clocks = <&mstp8_clks R8A7791_CLK_VIN2>;
+               reg = <0 0xe6ef2000 0 0x1000>;
+               interrupts = <0 190 IRQ_TYPE_LEVEL_HIGH>;
+               status = "disabled";
+       };
+
+       vsp1@fe928000 {
+               compatible = "renesas,vsp1";
+               reg = <0 0xfe928000 0 0x8000>;
+               interrupts = <0 267 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp1_clks R8A7791_CLK_VSP1_S>;
+
+               renesas,has-lut;
+               renesas,has-sru;
+               renesas,#rpf = <5>;
+               renesas,#uds = <3>;
+               renesas,#wpf = <4>;
+       };
+
+       vsp1@fe930000 {
+               compatible = "renesas,vsp1";
+               reg = <0 0xfe930000 0 0x8000>;
+               interrupts = <0 246 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp1_clks R8A7791_CLK_VSP1_DU0>;
+
+               renesas,has-lif;
+               renesas,has-lut;
+               renesas,#rpf = <4>;
+               renesas,#uds = <1>;
+               renesas,#wpf = <4>;
+       };
+
+       vsp1@fe938000 {
+               compatible = "renesas,vsp1";
+               reg = <0 0xfe938000 0 0x8000>;
+               interrupts = <0 247 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp1_clks R8A7791_CLK_VSP1_DU1>;
+
+               renesas,has-lif;
+               renesas,has-lut;
+               renesas,#rpf = <4>;
+               renesas,#uds = <1>;
+               renesas,#wpf = <4>;
+       };
+
+       du: display@feb00000 {
+               compatible = "renesas,du-r8a7791";
+               reg = <0 0xfeb00000 0 0x40000>,
+                     <0 0xfeb90000 0 0x1c>;
+               reg-names = "du", "lvds.0";
+               interrupts = <0 256 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 268 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp7_clks R8A7791_CLK_DU0>,
+                        <&mstp7_clks R8A7791_CLK_DU1>,
+                        <&mstp7_clks R8A7791_CLK_LVDS0>;
+               clock-names = "du.0", "du.1", "lvds.0";
+               status = "disabled";
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+                               du_out_rgb: endpoint {
+                               };
+                       };
+                       port@1 {
+                               reg = <1>;
+                               du_out_lvds0: endpoint {
+                               };
+                       };
+               };
+       };
+
        clocks {
                #address-cells = <2>;
                #size-cells = <2>;
                mstp1_clks: mstp1_clks@e6150134 {
                        compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
                        reg = <0 0xe6150134 0 4>, <0 0xe6150038 0 4>;
-                       clocks = <&p_clk>, <&p_clk>, <&p_clk>, <&rclk_clk>,
-                                <&cp_clk>, <&zs_clk>, <&zs_clk>, <&zs_clk>;
+                       clocks = <&zs_clk>, <&zs_clk>, <&m2_clk>, <&zs_clk>, <&p_clk>,
+                                <&zg_clk>, <&zs_clk>, <&zs_clk>, <&zs_clk>, <&p_clk>,
+                                <&p_clk>, <&rclk_clk>, <&cp_clk>, <&zs_clk>, <&zs_clk>,
+                                <&zs_clk>;
                        #clock-cells = <1>;
                        renesas,clock-indices = <
-                               R8A7791_CLK_TMU1 R8A7791_CLK_TMU3 R8A7791_CLK_TMU2
-                               R8A7791_CLK_CMT0 R8A7791_CLK_TMU0 R8A7791_CLK_VSP1_DU1
-                               R8A7791_CLK_VSP1_DU0 R8A7791_CLK_VSP1_S
+                               R8A7791_CLK_VCP0 R8A7791_CLK_VPC0 R8A7791_CLK_JPU
+                               R8A7791_CLK_SSP1 R8A7791_CLK_TMU1 R8A7791_CLK_3DG
+                               R8A7791_CLK_2DDMAC R8A7791_CLK_FDP1_1 R8A7791_CLK_FDP1_0
+                               R8A7791_CLK_TMU3 R8A7791_CLK_TMU2 R8A7791_CLK_CMT0
+                               R8A7791_CLK_TMU0 R8A7791_CLK_VSP1_DU1 R8A7791_CLK_VSP1_DU0
+                               R8A7791_CLK_VSP1_S
                        >;
                        clock-output-names =
-                               "tmu1", "tmu3", "tmu2", "cmt0", "tmu0", "vsp1-du1",
-                               "vsp1-du0", "vsp1-sy";
+                               "vcp0", "vpc0", "jpu", "ssp1", "tmu1", "3dg",
+                               "2ddmac", "fdp1-1", "fdp1-0", "tmu3", "tmu2", "cmt0",
+                               "tmu0", "vsp1-du1", "vsp1-du0", "vsp1-sy";
                };
                mstp2_clks: mstp2_clks@e6150138 {
                        compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
                        compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
                        reg = <0 0xe615013c 0 4>, <0 0xe6150048 0 4>;
                        clocks = <&cp_clk>, <&sd2_clk>, <&sd1_clk>, <&cpg_clocks R8A7791_CLK_SD0>,
-                                <&mmc0_clk>, <&hp_clk>, <&mp_clk>, <&hp_clk>, <&mp_clk>, <&rclk_clk>;
+                                <&mmc0_clk>, <&hp_clk>, <&mp_clk>, <&hp_clk>, <&mp_clk>, <&rclk_clk>,
+                                <&hp_clk>, <&hp_clk>;
                        #clock-cells = <1>;
                        renesas,clock-indices = <
                                R8A7791_CLK_TPU0 R8A7791_CLK_SDHI2 R8A7791_CLK_SDHI1 R8A7791_CLK_SDHI0
                                R8A7791_CLK_MMCIF0 R8A7791_CLK_IIC0 R8A7791_CLK_PCIEC R8A7791_CLK_IIC1
                                R8A7791_CLK_SSUSB R8A7791_CLK_CMT1
+                               R8A7791_CLK_USBDMAC0 R8A7791_CLK_USBDMAC1
                        >;
                        clock-output-names =
                                "tpu0", "sdhi2", "sdhi1", "sdhi0",
-                               "mmcif0", "i2c7", "pciec", "i2c8", "ssusb", "cmt1";
+                               "mmcif0", "i2c7", "pciec", "i2c8", "ssusb", "cmt1",
+                               "usbdmac0", "usbdmac1";
                };
                mstp5_clks: mstp5_clks@e6150144 {
                        compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
                        reg = <0 0xe6150144 0 4>, <0 0xe615003c 0 4>;
-                       clocks = <&extal_clk>, <&p_clk>;
+                       clocks = <&hp_clk>, <&hp_clk>, <&extal_clk>, <&p_clk>;
                        #clock-cells = <1>;
-                       renesas,clock-indices = <R8A7791_CLK_THERMAL R8A7791_CLK_PWM>;
-                       clock-output-names = "thermal", "pwm";
+                       renesas,clock-indices = <R8A7791_CLK_AUDIO_DMAC0 R8A7791_CLK_AUDIO_DMAC1
+                                                R8A7791_CLK_THERMAL R8A7791_CLK_PWM>;
+                       clock-output-names = "audmac0", "audmac1", "thermal", "pwm";
                };
                mstp7_clks: mstp7_clks@e615014c {
                        compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
                reg = <0 0xe6b10000 0 0x2c>;
                interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp9_clks R8A7791_CLK_QSPI_MOD>;
+               dmas = <&dmac0 0x17>, <&dmac0 0x18>;
+               dma-names = "tx", "rx";
                num-cs = <1>;
                #address-cells = <1>;
                #size-cells = <0>;
 
        msiof0: spi@e6e20000 {
                compatible = "renesas,msiof-r8a7791";
-               reg = <0 0xe6e20000 0 0x0064>;
+               reg = <0 0xe6e20000 0 0x0064>, <0 0xe7e20000 0 0x0064>;
                interrupts = <0 156 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp0_clks R8A7791_CLK_MSIOF0>;
+               dmas = <&dmac0 0x51>, <&dmac0 0x52>;
+               dma-names = "tx", "rx";
                #address-cells = <1>;
                #size-cells = <0>;
                status = "disabled";
 
        msiof1: spi@e6e10000 {
                compatible = "renesas,msiof-r8a7791";
-               reg = <0 0xe6e10000 0 0x0064>;
+               reg = <0 0xe6e10000 0 0x0064>, <0 0xe7e10000 0 0x0064>;
                interrupts = <0 157 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp2_clks R8A7791_CLK_MSIOF1>;
+               dmas = <&dmac0 0x55>, <&dmac0 0x56>;
+               dma-names = "tx", "rx";
                #address-cells = <1>;
                #size-cells = <0>;
                status = "disabled";
 
        msiof2: spi@e6e00000 {
                compatible = "renesas,msiof-r8a7791";
-               reg = <0 0xe6e00000 0 0x0064>;
+               reg = <0 0xe6e00000 0 0x0064>, <0 0xe7e00000 0 0x0064>;
                interrupts = <0 158 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp2_clks R8A7791_CLK_MSIOF2>;
+               dmas = <&dmac0 0x41>, <&dmac0 0x42>;
+               dma-names = "tx", "rx";
                #address-cells = <1>;
                #size-cells = <0>;
                status = "disabled";
        };
 
+       xhci: usb@ee000000 {
+               compatible = "renesas,xhci-r8a7791";
+               reg = <0 0xee000000 0 0xc00>;
+               interrupts = <0 101 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp3_clks R8A7791_CLK_SSUSB>;
+               phys = <&usb2 1>;
+               phy-names = "usb";
+               status = "disabled";
+       };
+
        pci0: pci@ee090000 {
                compatible = "renesas,pci-r8a7791";
                device_type = "pci";
                interrupt-map = <0x0000 0 0 1 &gic 0 108 IRQ_TYPE_LEVEL_HIGH
                                 0x0800 0 0 1 &gic 0 108 IRQ_TYPE_LEVEL_HIGH
                                 0x1000 0 0 2 &gic 0 108 IRQ_TYPE_LEVEL_HIGH>;
+
+               usb@0,1 {
+                       reg = <0x800 0 0 0 0>;
+                       device_type = "pci";
+                       phys = <&usb0 0>;
+                       phy-names = "usb";
+               };
+
+               usb@0,2 {
+                       reg = <0x1000 0 0 0 0>;
+                       device_type = "pci";
+                       phys = <&usb0 0>;
+                       phy-names = "usb";
+               };
        };
 
        pci1: pci@ee0d0000 {
                interrupt-map = <0x0000 0 0 1 &gic 0 113 IRQ_TYPE_LEVEL_HIGH
                                 0x0800 0 0 1 &gic 0 113 IRQ_TYPE_LEVEL_HIGH
                                 0x1000 0 0 2 &gic 0 113 IRQ_TYPE_LEVEL_HIGH>;
+
+               usb@0,1 {
+                       reg = <0x800 0 0 0 0>;
+                       device_type = "pci";
+                       phys = <&usb2 0>;
+                       phy-names = "usb";
+               };
+
+               usb@0,2 {
+                       reg = <0x1000 0 0 0 0>;
+                       device_type = "pci";
+                       phys = <&usb2 0>;
+                       phy-names = "usb";
+               };
        };
 
        pciec: pcie@fe000000 {
                status = "disabled";
        };
 
-       rcar_sound: rcar_sound@0xec500000 {
+       rcar_sound: rcar_sound@ec500000 {
                #sound-dai-cells = <1>;
                compatible =  "renesas,rcar_sound-r8a7791", "renesas,rcar_sound-gen2", "renesas,rcar_sound";
-               interrupt-parent = <&gic>;
                reg =   <0 0xec500000 0 0x1000>, /* SCU */
                        <0 0xec5a0000 0 0x100>,  /* ADG */
                        <0 0xec540000 0 0x1000>, /* SSIU */
diff --git a/arch/arm/boot/dts/r8a7794-alt.dts b/arch/arm/boot/dts/r8a7794-alt.dts
new file mode 100644 (file)
index 0000000..f2cf757
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Device Tree Source for the Alt board
+ *
+ * Copyright (C) 2014 Renesas Electronics Corporation
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+/dts-v1/;
+#include "r8a7794.dtsi"
+
+/ {
+       model = "Alt";
+       compatible = "renesas,alt", "renesas,r8a7794";
+
+       aliases {
+               serial0 = &scif2;
+       };
+
+       chosen {
+               bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp";
+               stdout-path = &scif2;
+       };
+
+       memory@40000000 {
+               device_type = "memory";
+               reg = <0 0x40000000 0 0x40000000>;
+       };
+
+       lbsc {
+               #address-cells = <1>;
+               #size-cells = <1>;
+       };
+};
+
+&extal_clk {
+       clock-frequency = <20000000>;
+};
+
+&cmt0 {
+       status = "ok";
+};
+
+&scif2 {
+       status = "ok";
+};
diff --git a/arch/arm/boot/dts/r8a7794.dtsi b/arch/arm/boot/dts/r8a7794.dtsi
new file mode 100644 (file)
index 0000000..19c9de3
--- /dev/null
@@ -0,0 +1,542 @@
+/*
+ * Device Tree Source for the r8a7794 SoC
+ *
+ * Copyright (C) 2014 Renesas Electronics Corporation
+ * Copyright (C) 2014 Ulrich Hecht
+ *
+ * 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 <dt-bindings/clock/r8a7794-clock.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+       compatible = "renesas,r8a7794";
+       interrupt-parent = <&gic>;
+       #address-cells = <2>;
+       #size-cells = <2>;
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu0: cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a7";
+                       reg = <0>;
+                       clock-frequency = <1000000000>;
+               };
+
+               cpu1: cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a7";
+                       reg = <1>;
+                       clock-frequency = <1000000000>;
+               };
+       };
+
+       gic: interrupt-controller@f1001000 {
+               compatible = "arm,cortex-a7-gic";
+               #interrupt-cells = <3>;
+               #address-cells = <0>;
+               interrupt-controller;
+               reg = <0 0xf1001000 0 0x1000>,
+                       <0 0xf1002000 0 0x1000>,
+                       <0 0xf1004000 0 0x2000>,
+                       <0 0xf1006000 0 0x2000>;
+               interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+       };
+
+       cmt0: timer@ffca0000 {
+               compatible = "renesas,cmt-48-gen2";
+               reg = <0 0xffca0000 0 0x1004>;
+               interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 143 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp1_clks R8A7794_CLK_CMT0>;
+               clock-names = "fck";
+
+               renesas,channels-mask = <0x60>;
+
+               status = "disabled";
+       };
+
+       cmt1: timer@e6130000 {
+               compatible = "renesas,cmt-48-gen2";
+               reg = <0 0xe6130000 0 0x1004>;
+               interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 121 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 122 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 123 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 124 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 125 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 126 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 127 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp3_clks R8A7794_CLK_CMT1>;
+               clock-names = "fck";
+
+               renesas,channels-mask = <0xff>;
+
+               status = "disabled";
+       };
+
+       timer {
+               compatible = "arm,armv7-timer";
+               interrupts = <1 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+                            <1 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+                            <1 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+                            <1 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+       };
+
+       irqc0: interrupt-controller@e61c0000 {
+               compatible = "renesas,irqc-r8a7794", "renesas,irqc";
+               #interrupt-cells = <2>;
+               interrupt-controller;
+               reg = <0 0xe61c0000 0 0x200>;
+               interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 1 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 2 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 3 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 12 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 13 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 14 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 15 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 16 IRQ_TYPE_LEVEL_HIGH>,
+                            <0 17 IRQ_TYPE_LEVEL_HIGH>;
+       };
+
+       scifa0: serial@e6c40000 {
+               compatible = "renesas,scifa-r8a7794", "renesas,scifa";
+               reg = <0 0xe6c40000 0 64>;
+               interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks R8A7794_CLK_SCIFA0>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       scifa1: serial@e6c50000 {
+               compatible = "renesas,scifa-r8a7794", "renesas,scifa";
+               reg = <0 0xe6c50000 0 64>;
+               interrupts = <0 145 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks R8A7794_CLK_SCIFA1>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       scifa2: serial@e6c60000 {
+               compatible = "renesas,scifa-r8a7794", "renesas,scifa";
+               reg = <0 0xe6c60000 0 64>;
+               interrupts = <0 151 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks R8A7794_CLK_SCIFA2>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       scifa3: serial@e6c70000 {
+               compatible = "renesas,scifa-r8a7794", "renesas,scifa";
+               reg = <0 0xe6c70000 0 64>;
+               interrupts = <0 29 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp11_clks R8A7794_CLK_SCIFA3>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       scifa4: serial@e6c78000 {
+               compatible = "renesas,scifa-r8a7794", "renesas,scifa";
+               reg = <0 0xe6c78000 0 64>;
+               interrupts = <0 30 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp11_clks R8A7794_CLK_SCIFA4>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       scifa5: serial@e6c80000 {
+               compatible = "renesas,scifa-r8a7794", "renesas,scifa";
+               reg = <0 0xe6c80000 0 64>;
+               interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp11_clks R8A7794_CLK_SCIFA5>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       scifb0: serial@e6c20000 {
+               compatible = "renesas,scifb-r8a7794", "renesas,scifb";
+               reg = <0 0xe6c20000 0 64>;
+               interrupts = <0 148 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks R8A7794_CLK_SCIFB0>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       scifb1: serial@e6c30000 {
+               compatible = "renesas,scifb-r8a7794", "renesas,scifb";
+               reg = <0 0xe6c30000 0 64>;
+               interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks R8A7794_CLK_SCIFB1>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       scifb2: serial@e6ce0000 {
+               compatible = "renesas,scifb-r8a7794", "renesas,scifb";
+               reg = <0 0xe6ce0000 0 64>;
+               interrupts = <0 150 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks R8A7794_CLK_SCIFB2>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       scif0: serial@e6e60000 {
+               compatible = "renesas,scif-r8a7794", "renesas,scif";
+               reg = <0 0xe6e60000 0 64>;
+               interrupts = <0 152 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp7_clks R8A7794_CLK_SCIF0>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       scif1: serial@e6e68000 {
+               compatible = "renesas,scif-r8a7794", "renesas,scif";
+               reg = <0 0xe6e68000 0 64>;
+               interrupts = <0 153 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp7_clks R8A7794_CLK_SCIF1>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       scif2: serial@e6e58000 {
+               compatible = "renesas,scif-r8a7794", "renesas,scif";
+               reg = <0 0xe6e58000 0 64>;
+               interrupts = <0 22 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp7_clks R8A7794_CLK_SCIF2>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       scif3: serial@e6ea8000 {
+               compatible = "renesas,scif-r8a7794", "renesas,scif";
+               reg = <0 0xe6ea8000 0 64>;
+               interrupts = <0 23 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp7_clks R8A7794_CLK_SCIF3>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       scif4: serial@e6ee0000 {
+               compatible = "renesas,scif-r8a7794", "renesas,scif";
+               reg = <0 0xe6ee0000 0 64>;
+               interrupts = <0 24 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp7_clks R8A7794_CLK_SCIF4>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       scif5: serial@e6ee8000 {
+               compatible = "renesas,scif-r8a7794", "renesas,scif";
+               reg = <0 0xe6ee8000 0 64>;
+               interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp7_clks R8A7794_CLK_SCIF5>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       hscif0: serial@e62c0000 {
+               compatible = "renesas,hscif-r8a7794", "renesas,hscif";
+               reg = <0 0xe62c0000 0 96>;
+               interrupts = <0 154 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp7_clks R8A7794_CLK_HSCIF0>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       hscif1: serial@e62c8000 {
+               compatible = "renesas,hscif-r8a7794", "renesas,hscif";
+               reg = <0 0xe62c8000 0 96>;
+               interrupts = <0 155 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp7_clks R8A7794_CLK_HSCIF1>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       hscif2: serial@e62d0000 {
+               compatible = "renesas,hscif-r8a7794", "renesas,hscif";
+               reg = <0 0xe62d0000 0 96>;
+               interrupts = <0 21 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp7_clks R8A7794_CLK_HSCIF2>;
+               clock-names = "sci_ick";
+               status = "disabled";
+       };
+
+       clocks {
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               /* External root clock */
+               extal_clk: extal_clk {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       /* This value must be overriden by the board. */
+                       clock-frequency = <0>;
+                       clock-output-names = "extal";
+               };
+
+               /* Special CPG clocks */
+               cpg_clocks: cpg_clocks@e6150000 {
+                       compatible = "renesas,r8a7794-cpg-clocks",
+                                    "renesas,rcar-gen2-cpg-clocks";
+                       reg = <0 0xe6150000 0 0x1000>;
+                       clocks = <&extal_clk>;
+                       #clock-cells = <1>;
+                       clock-output-names = "main", "pll0", "pll1", "pll3",
+                                            "lb", "qspi", "sdh", "sd0", "z";
+               };
+
+               /* Fixed factor clocks */
+               pll1_div2_clk: pll1_div2_clk {
+                       compatible = "fixed-factor-clock";
+                       clocks = <&cpg_clocks R8A7794_CLK_PLL1>;
+                       #clock-cells = <0>;
+                       clock-div = <2>;
+                       clock-mult = <1>;
+                       clock-output-names = "pll1_div2";
+               };
+               zg_clk: zg_clk {
+                       compatible = "fixed-factor-clock";
+                       clocks = <&cpg_clocks R8A7794_CLK_PLL1>;
+                       #clock-cells = <0>;
+                       clock-div = <6>;
+                       clock-mult = <1>;
+                       clock-output-names = "zg";
+               };
+               zx_clk: zx_clk {
+                       compatible = "fixed-factor-clock";
+                       clocks = <&cpg_clocks R8A7794_CLK_PLL1>;
+                       #clock-cells = <0>;
+                       clock-div = <3>;
+                       clock-mult = <1>;
+                       clock-output-names = "zx";
+               };
+               zs_clk: zs_clk {
+                       compatible = "fixed-factor-clock";
+                       clocks = <&cpg_clocks R8A7794_CLK_PLL1>;
+                       #clock-cells = <0>;
+                       clock-div = <6>;
+                       clock-mult = <1>;
+                       clock-output-names = "zs";
+               };
+               hp_clk: hp_clk {
+                       compatible = "fixed-factor-clock";
+                       clocks = <&cpg_clocks R8A7794_CLK_PLL1>;
+                       #clock-cells = <0>;
+                       clock-div = <12>;
+                       clock-mult = <1>;
+                       clock-output-names = "hp";
+               };
+               i_clk: i_clk {
+                       compatible = "fixed-factor-clock";
+                       clocks = <&cpg_clocks R8A7794_CLK_PLL1>;
+                       #clock-cells = <0>;
+                       clock-div = <2>;
+                       clock-mult = <1>;
+                       clock-output-names = "i";
+               };
+               b_clk: b_clk {
+                       compatible = "fixed-factor-clock";
+                       clocks = <&cpg_clocks R8A7794_CLK_PLL1>;
+                       #clock-cells = <0>;
+                       clock-div = <12>;
+                       clock-mult = <1>;
+                       clock-output-names = "b";
+               };
+               p_clk: p_clk {
+                       compatible = "fixed-factor-clock";
+                       clocks = <&cpg_clocks R8A7794_CLK_PLL1>;
+                       #clock-cells = <0>;
+                       clock-div = <24>;
+                       clock-mult = <1>;
+                       clock-output-names = "p";
+               };
+               cl_clk: cl_clk {
+                       compatible = "fixed-factor-clock";
+                       clocks = <&cpg_clocks R8A7794_CLK_PLL1>;
+                       #clock-cells = <0>;
+                       clock-div = <48>;
+                       clock-mult = <1>;
+                       clock-output-names = "cl";
+               };
+               m2_clk: m2_clk {
+                       compatible = "fixed-factor-clock";
+                       clocks = <&cpg_clocks R8A7794_CLK_PLL1>;
+                       #clock-cells = <0>;
+                       clock-div = <8>;
+                       clock-mult = <1>;
+                       clock-output-names = "m2";
+               };
+               imp_clk: imp_clk {
+                       compatible = "fixed-factor-clock";
+                       clocks = <&cpg_clocks R8A7794_CLK_PLL1>;
+                       #clock-cells = <0>;
+                       clock-div = <4>;
+                       clock-mult = <1>;
+                       clock-output-names = "imp";
+               };
+               rclk_clk: rclk_clk {
+                       compatible = "fixed-factor-clock";
+                       clocks = <&cpg_clocks R8A7794_CLK_PLL1>;
+                       #clock-cells = <0>;
+                       clock-div = <(48 * 1024)>;
+                       clock-mult = <1>;
+                       clock-output-names = "rclk";
+               };
+               oscclk_clk: oscclk_clk {
+                       compatible = "fixed-factor-clock";
+                       clocks = <&cpg_clocks R8A7794_CLK_PLL1>;
+                       #clock-cells = <0>;
+                       clock-div = <(12 * 1024)>;
+                       clock-mult = <1>;
+                       clock-output-names = "oscclk";
+               };
+               zb3_clk: zb3_clk {
+                       compatible = "fixed-factor-clock";
+                       clocks = <&cpg_clocks R8A7794_CLK_PLL3>;
+                       #clock-cells = <0>;
+                       clock-div = <4>;
+                       clock-mult = <1>;
+                       clock-output-names = "zb3";
+               };
+               zb3d2_clk: zb3d2_clk {
+                       compatible = "fixed-factor-clock";
+                       clocks = <&cpg_clocks R8A7794_CLK_PLL3>;
+                       #clock-cells = <0>;
+                       clock-div = <8>;
+                       clock-mult = <1>;
+                       clock-output-names = "zb3d2";
+               };
+               ddr_clk: ddr_clk {
+                       compatible = "fixed-factor-clock";
+                       clocks = <&cpg_clocks R8A7794_CLK_PLL3>;
+                       #clock-cells = <0>;
+                       clock-div = <8>;
+                       clock-mult = <1>;
+                       clock-output-names = "ddr";
+               };
+               mp_clk: mp_clk {
+                       compatible = "fixed-factor-clock";
+                       clocks = <&pll1_div2_clk>;
+                       #clock-cells = <0>;
+                       clock-div = <15>;
+                       clock-mult = <1>;
+                       clock-output-names = "mp";
+               };
+               cp_clk: cp_clk {
+                       compatible = "fixed-factor-clock";
+                       clocks = <&cpg_clocks R8A7794_CLK_PLL1>;
+                       #clock-cells = <0>;
+                       clock-div = <48>;
+                       clock-mult = <1>;
+                       clock-output-names = "cp";
+               };
+
+               acp_clk: acp_clk {
+                       compatible = "fixed-factor-clock";
+                       clocks = <&extal_clk>;
+                       #clock-cells = <0>;
+                       clock-div = <2>;
+                       clock-mult = <1>;
+                       clock-output-names = "acp";
+               };
+
+               /* Gate clocks */
+               mstp0_clks: mstp0_clks@e6150130 {
+                       compatible = "renesas,r8a7794-mstp-clocks", "renesas,cpg-mstp-clocks";
+                       reg = <0 0xe6150130 0 4>, <0 0xe6150030 0 4>;
+                       clocks = <&mp_clk>;
+                       #clock-cells = <1>;
+                       renesas,clock-indices = <R8A7794_CLK_MSIOF0>;
+                       clock-output-names = "msiof0";
+               };
+               mstp1_clks: mstp1_clks@e6150134 {
+                       compatible = "renesas,r8a7794-mstp-clocks", "renesas,cpg-mstp-clocks";
+                       reg = <0 0xe6150134 0 4>, <0 0xe6150038 0 4>;
+                       clocks = <&zs_clk>, <&zs_clk>, <&p_clk>, <&zg_clk>, <&zs_clk>,
+                                <&zs_clk>, <&p_clk>, <&p_clk>, <&rclk_clk>, <&cp_clk>,
+                                <&zs_clk>, <&zs_clk>;
+                       #clock-cells = <1>;
+                       renesas,clock-indices = <
+                               R8A7794_CLK_VCP0 R8A7794_CLK_VPC0 R8A7794_CLK_TMU1
+                               R8A7794_CLK_3DG R8A7794_CLK_2DDMAC R8A7794_CLK_FDP1_0
+                               R8A7794_CLK_TMU3 R8A7794_CLK_TMU2 R8A7794_CLK_CMT0
+                               R8A7794_CLK_TMU0 R8A7794_CLK_VSP1_DU0 R8A7794_CLK_VSP1_S
+                       >;
+                       clock-output-names =
+                               "vcp0", "vpc0", "tmu1", "3dg", "2ddmac", "fdp1-0",
+                               "tmu3", "tmu2", "cmt0", "tmu0", "vsp1-du0", "vsps";
+               };
+               mstp2_clks: mstp2_clks@e6150138 {
+                       compatible = "renesas,r8a7794-mstp-clocks", "renesas,cpg-mstp-clocks";
+                       reg = <0 0xe6150138 0 4>, <0 0xe6150040 0 4>;
+                       clocks = <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>,
+                                <&mp_clk>, <&mp_clk>, <&mp_clk>;
+                       #clock-cells = <1>;
+                       renesas,clock-indices = <
+                               R8A7794_CLK_SCIFA2 R8A7794_CLK_SCIFA1 R8A7794_CLK_SCIFA0
+                               R8A7794_CLK_MSIOF2 R8A7794_CLK_SCIFB0 R8A7794_CLK_SCIFB1
+                               R8A7794_CLK_MSIOF1 R8A7794_CLK_SCIFB2
+                       >;
+                       clock-output-names =
+                               "scifa2", "scifa1", "scifa0", "msiof2", "scifb0",
+                               "scifb1", "msiof1", "scifb2";
+               };
+               mstp3_clks: mstp3_clks@e615013c {
+                       compatible = "renesas,r8a7794-mstp-clocks", "renesas,cpg-mstp-clocks";
+                       reg = <0 0xe615013c 0 4>, <0 0xe6150048 0 4>;
+                       clocks = <&rclk_clk>;
+                       #clock-cells = <1>;
+                       renesas,clock-indices = <
+                               R8A7794_CLK_CMT1
+                       >;
+                       clock-output-names =
+                               "cmt1";
+               };
+               mstp7_clks: mstp7_clks@e615014c {
+                       compatible = "renesas,r8a7794-mstp-clocks", "renesas,cpg-mstp-clocks";
+                       reg = <0 0xe615014c 0 4>, <0 0xe61501c4 0 4>;
+                       clocks = <&zs_clk>, <&p_clk>, <&p_clk>, <&zs_clk>,
+                                <&zs_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>;
+                       #clock-cells = <1>;
+                       renesas,clock-indices = <
+                               R8A7794_CLK_HSCIF2 R8A7794_CLK_SCIF5
+                               R8A7794_CLK_SCIF4 R8A7794_CLK_HSCIF1 R8A7794_CLK_HSCIF0
+                               R8A7794_CLK_SCIF3 R8A7794_CLK_SCIF2 R8A7794_CLK_SCIF1
+                               R8A7794_CLK_SCIF0
+                       >;
+                       clock-output-names =
+                               "hscif2", "scif5", "scif4", "hscif1", "hscif0",
+                               "scif3", "scif2", "scif1", "scif0";
+               };
+               mstp8_clks: mstp8_clks@e6150990 {
+                       compatible = "renesas,r8a7794-mstp-clocks", "renesas,cpg-mstp-clocks";
+                       reg = <0 0xe6150990 0 4>, <0 0xe61509a0 0 4>;
+                       clocks = <&zg_clk>, <&zg_clk>, <&p_clk>;
+                       #clock-cells = <1>;
+                       renesas,clock-indices = <
+                               R8A7794_CLK_VIN1 R8A7794_CLK_VIN0 R8A7794_CLK_ETHER
+                       >;
+                       clock-output-names =
+                               "vin1", "vin0", "ether";
+               };
+               mstp11_clks: mstp11_clks@e615099c {
+                       compatible = "renesas,r8a7794-mstp-clocks", "renesas,cpg-mstp-clocks";
+                       reg = <0 0xe615099c 0 4>, <0 0xe61509ac 0 4>;
+                       clocks = <&mp_clk>, <&mp_clk>, <&mp_clk>;
+                       #clock-cells = <1>;
+                       renesas,clock-indices = <
+                               R8A7794_CLK_SCIFA3 R8A7794_CLK_SCIFA4 R8A7794_CLK_SCIFA5
+                       >;
+                       clock-output-names = "scifa3", "scifa4", "scifa5";
+               };
+       };
+};
index 249f65b..f863a10 100644 (file)
@@ -21,6 +21,7 @@
                        compatible = "arm,cortex-a8";
                        device_type = "cpu";
                        reg = <0x0>;
+                       clock-frequency = <800000000>;
                };
        };
 
index 18662ae..939be12 100644 (file)
@@ -40,6 +40,7 @@
 
        chosen {
                bootargs = "console=tty0 console=ttySC4,115200 root=/dev/nfs ip=dhcp ignore_loglevel rw";
+               stdout-path = &scifa4;
        };
 
        memory {
@@ -66,7 +67,7 @@
        };
 
        vmmc_sdhi0: regulator@2 {
-               compatible = "regulator-fixed";
+               compatible = "regulator-fixed";
                regulator-name = "SDHI0 Vcc";
                regulator-min-microvolt = <3300000>;
                regulator-max-microvolt = <3300000>;
@@ -75,7 +76,7 @@
        };
 
        vmmc_sdhi2: regulator@3 {
-               compatible = "regulator-fixed";
+               compatible = "regulator-fixed";
                regulator-name = "SDHI2 Vcc";
                regulator-min-microvolt = <3300000>;
                regulator-max-microvolt = <3300000>;
                compatible = "gpio-leds";
                led1 {
                        gpios = <&pfc 20 GPIO_ACTIVE_LOW>;
+                       label = "LED1";
                };
                led2 {
                        gpios = <&pfc 21 GPIO_ACTIVE_LOW>;
+                       label = "LED2";
                };
                led3 {
                        gpios = <&pfc 22 GPIO_ACTIVE_LOW>;
+                       label = "LED3";
                };
                led4 {
                        gpios = <&pfc 23 GPIO_ACTIVE_LOW>;
+                       label = "LED4";
                };
        };
 
-       gpio-keys {
+       keyboard {
                compatible = "gpio-keys";
 
                back-key {
        };
 };
 
+&cmt1 {
+       status = "ok";
+};
+
 &i2c0 {
        status = "okay";
        as3711@40 {
                };
        };
 
-       ak4648: ak4648@0x12 {
+       ak4648: ak4648@12 {
                #sound-dai-cells = <0>;
                compatible = "asahi-kasei,ak4648";
                reg = <0x12>;
index 910b790..d8def5a 100644 (file)
@@ -14,6 +14,7 @@
 
 / {
        compatible = "renesas,sh73a0";
+       interrupt-parent = <&gic>;
 
        cpus {
                #address-cells = <1>;
                        device_type = "cpu";
                        compatible = "arm,cortex-a9";
                        reg = <0>;
+                       clock-frequency = <1196000000>;
                };
                cpu@1 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a9";
                        reg = <1>;
+                       clock-frequency = <1196000000>;
                };
        };
 
                             <0 56 IRQ_TYPE_LEVEL_HIGH>;
        };
 
+       cmt1: timer@e6138000 {
+               compatible = "renesas,cmt-48-sh73a0", "renesas,cmt-48";
+               reg = <0xe6138000 0x200>;
+               interrupts = <0 65 IRQ_TYPE_LEVEL_HIGH>;
+
+               renesas,channels-mask = <0x3f>;
+
+               status = "disabled";
+       };
+
        irqpin0: irqpin@e6900000 {
                compatible = "renesas,intc-irqpin-sh73a0", "renesas,intc-irqpin";
                #interrupt-cells = <2>;
@@ -54,7 +67,6 @@
                        <0xe6900020 1>,
                        <0xe6900040 1>,
                        <0xe6900060 1>;
-               interrupt-parent = <&gic>;
                interrupts = <0 1 IRQ_TYPE_LEVEL_HIGH
                              0 2 IRQ_TYPE_LEVEL_HIGH
                              0 3 IRQ_TYPE_LEVEL_HIGH
@@ -74,7 +86,6 @@
                        <0xe6900024 1>,
                        <0xe6900044 1>,
                        <0xe6900064 1>;
-               interrupt-parent = <&gic>;
                interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH
                              0 10 IRQ_TYPE_LEVEL_HIGH
                              0 11 IRQ_TYPE_LEVEL_HIGH
                        <0xe6900028 1>,
                        <0xe6900048 1>,
                        <0xe6900068 1>;
-               interrupt-parent = <&gic>;
                interrupts = <0 17 IRQ_TYPE_LEVEL_HIGH
                              0 18 IRQ_TYPE_LEVEL_HIGH
                              0 19 IRQ_TYPE_LEVEL_HIGH
                        <0xe690002c 1>,
                        <0xe690004c 1>,
                        <0xe690006c 1>;
-               interrupt-parent = <&gic>;
                interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH
                              0 26 IRQ_TYPE_LEVEL_HIGH
                              0 27 IRQ_TYPE_LEVEL_HIGH
        i2c0: i2c@e6820000 {
                #address-cells = <1>;
                #size-cells = <0>;
-               compatible = "renesas,rmobile-iic";
+               compatible = "renesas,iic-sh73a0", "renesas,rmobile-iic";
                reg = <0xe6820000 0x425>;
-               interrupt-parent = <&gic>;
                interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH
                              0 168 IRQ_TYPE_LEVEL_HIGH
                              0 169 IRQ_TYPE_LEVEL_HIGH
        i2c1: i2c@e6822000 {
                #address-cells = <1>;
                #size-cells = <0>;
-               compatible = "renesas,rmobile-iic";
+               compatible = "renesas,iic-sh73a0", "renesas,rmobile-iic";
                reg = <0xe6822000 0x425>;
-               interrupt-parent = <&gic>;
                interrupts = <0 51 IRQ_TYPE_LEVEL_HIGH
                              0 52 IRQ_TYPE_LEVEL_HIGH
                              0 53 IRQ_TYPE_LEVEL_HIGH
        i2c2: i2c@e6824000 {
                #address-cells = <1>;
                #size-cells = <0>;
-               compatible = "renesas,rmobile-iic";
+               compatible = "renesas,iic-sh73a0", "renesas,rmobile-iic";
                reg = <0xe6824000 0x425>;
-               interrupt-parent = <&gic>;
                interrupts = <0 171 IRQ_TYPE_LEVEL_HIGH
                              0 172 IRQ_TYPE_LEVEL_HIGH
                              0 173 IRQ_TYPE_LEVEL_HIGH
        i2c3: i2c@e6826000 {
                #address-cells = <1>;
                #size-cells = <0>;
-               compatible = "renesas,rmobile-iic";
+               compatible = "renesas,iic-sh73a0", "renesas,rmobile-iic";
                reg = <0xe6826000 0x425>;
-               interrupt-parent = <&gic>;
                interrupts = <0 183 IRQ_TYPE_LEVEL_HIGH
                              0 184 IRQ_TYPE_LEVEL_HIGH
                              0 185 IRQ_TYPE_LEVEL_HIGH
        i2c4: i2c@e6828000 {
                #address-cells = <1>;
                #size-cells = <0>;
-               compatible = "renesas,rmobile-iic";
+               compatible = "renesas,iic-sh73a0", "renesas,rmobile-iic";
                reg = <0xe6828000 0x425>;
-               interrupt-parent = <&gic>;
                interrupts = <0 187 IRQ_TYPE_LEVEL_HIGH
                              0 188 IRQ_TYPE_LEVEL_HIGH
                              0 189 IRQ_TYPE_LEVEL_HIGH
        mmcif: mmc@e6bd0000 {
                compatible = "renesas,sh-mmcif";
                reg = <0xe6bd0000 0x100>;
-               interrupt-parent = <&gic>;
                interrupts = <0 140 IRQ_TYPE_LEVEL_HIGH
                              0 141 IRQ_TYPE_LEVEL_HIGH>;
                reg-io-width = <4>;
        sdhi0: sd@ee100000 {
                compatible = "renesas,sdhi-sh73a0";
                reg = <0xee100000 0x100>;
-               interrupt-parent = <&gic>;
                interrupts = <0 83 IRQ_TYPE_LEVEL_HIGH
                              0 84 IRQ_TYPE_LEVEL_HIGH
                              0 85 IRQ_TYPE_LEVEL_HIGH>;
        sdhi1: sd@ee120000 {
                compatible = "renesas,sdhi-sh73a0";
                reg = <0xee120000 0x100>;
-               interrupt-parent = <&gic>;
                interrupts = <0 88 IRQ_TYPE_LEVEL_HIGH
                              0 89 IRQ_TYPE_LEVEL_HIGH>;
                toshiba,mmc-wrprotect-disable;
        sdhi2: sd@ee140000 {
                compatible = "renesas,sdhi-sh73a0";
                reg = <0xee140000 0x100>;
-               interrupt-parent = <&gic>;
                interrupts = <0 104 IRQ_TYPE_LEVEL_HIGH
                              0 105 IRQ_TYPE_LEVEL_HIGH>;
                toshiba,mmc-wrprotect-disable;
        scifa0: serial@e6c40000 {
                compatible = "renesas,scifa-sh73a0", "renesas,scifa";
                reg = <0xe6c40000 0x100>;
-               interrupt-parent = <&gic>;
                interrupts = <0 72 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
        scifa1: serial@e6c50000 {
                compatible = "renesas,scifa-sh73a0", "renesas,scifa";
                reg = <0xe6c50000 0x100>;
-               interrupt-parent = <&gic>;
                interrupts = <0 73 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
        scifa2: serial@e6c60000 {
                compatible = "renesas,scifa-sh73a0", "renesas,scifa";
                reg = <0xe6c60000 0x100>;
-               interrupt-parent = <&gic>;
                interrupts = <0 74 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
        scifa3: serial@e6c70000 {
                compatible = "renesas,scifa-sh73a0", "renesas,scifa";
                reg = <0xe6c70000 0x100>;
-               interrupt-parent = <&gic>;
                interrupts = <0 75 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
        scifa4: serial@e6c80000 {
                compatible = "renesas,scifa-sh73a0", "renesas,scifa";
                reg = <0xe6c80000 0x100>;
-               interrupt-parent = <&gic>;
                interrupts = <0 78 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
        scifa5: serial@e6cb0000 {
                compatible = "renesas,scifa-sh73a0", "renesas,scifa";
                reg = <0xe6cb0000 0x100>;
-               interrupt-parent = <&gic>;
                interrupts = <0 79 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
        scifa6: serial@e6cc0000 {
                compatible = "renesas,scifa-sh73a0", "renesas,scifa";
                reg = <0xe6cc0000 0x100>;
-               interrupt-parent = <&gic>;
                interrupts = <0 156 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
        scifa7: serial@e6cd0000 {
                compatible = "renesas,scifa-sh73a0", "renesas,scifa";
                reg = <0xe6cd0000 0x100>;
-               interrupt-parent = <&gic>;
                interrupts = <0 143 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
        scifb8: serial@e6c30000 {
                compatible = "renesas,scifb-sh73a0", "renesas,scifb";
                reg = <0xe6c30000 0x100>;
-               interrupt-parent = <&gic>;
                interrupts = <0 80 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
                #sound-dai-cells = <1>;
                compatible = "renesas,sh_fsi2";
                reg = <0xec230000 0x400>;
-               interrupt-parent = <&gic>;
                interrupts = <0 146 0x4>;
                status = "disabled";
        };
index bb396c0..db81d8c 100644 (file)
@@ -12,7 +12,6 @@ CONFIG_KALLSYMS_ALL=y
 CONFIG_EMBEDDED=y
 CONFIG_PERF_EVENTS=y
 CONFIG_SLAB=y
-# CONFIG_BLOCK is not set
 CONFIG_ARCH_SHMOBILE_LEGACY=y
 CONFIG_ARCH_R8A73A4=y
 CONFIG_MACH_APE6EVM=y
@@ -34,6 +33,7 @@ CONFIG_ARM_APPENDED_DTB=y
 CONFIG_VFP=y
 CONFIG_NEON=y
 CONFIG_BINFMT_MISC=y
+CONFIG_PM_RUNTIME=y
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
@@ -64,6 +64,8 @@ CONFIG_SERIAL_NONSTANDARD=y
 CONFIG_SERIAL_SH_SCI=y
 CONFIG_SERIAL_SH_SCI_NR_UARTS=12
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_I2C=y
+CONFIG_I2C_SH_MOBILE=y
 CONFIG_GPIO_SH_PFC=y
 CONFIG_GPIOLIB=y
 # CONFIG_HWMON is not set
@@ -72,11 +74,17 @@ CONFIG_RCAR_THERMAL=y
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_GPIO=y
+CONFIG_REGULATOR_MAX8973=y
 # CONFIG_HID is not set
 # CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+CONFIG_MMC_SDHI=y
+CONFIG_MMC_SH_MMCIF=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_GPIO=y
+CONFIG_DMADEVICES=y
+CONFIG_SH_DMAE=y
 # CONFIG_IOMMU_SUPPORT is not set
 # CONFIG_DNOTIFY is not set
 CONFIG_TMPFS=y
index e816140..1dde5da 100644 (file)
@@ -29,7 +29,6 @@ CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_ARM_APPENDED_DTB=y
 CONFIG_VFP=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-# CONFIG_SUSPEND is not set
 CONFIG_PM_RUNTIME=y
 CONFIG_NET=y
 CONFIG_PACKET=y
@@ -55,6 +54,7 @@ CONFIG_MTD_BLOCK=y
 CONFIG_MTD_CFI=y
 CONFIG_MTD_CFI_AMDSTD=y
 CONFIG_MTD_M25P80=y
+CONFIG_MTD_SPI_NOR=y
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_NETDEVICES=y
@@ -82,6 +82,7 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y
 # CONFIG_HWMON is not set
 CONFIG_I2C=y
 CONFIG_I2C_RCAR=y
+CONFIG_GPIO_RCAR=y
 CONFIG_REGULATOR=y
 CONFIG_MEDIA_SUPPORT=y
 CONFIG_MEDIA_CAMERA_SUPPORT=y
diff --git a/arch/arm/configs/koelsch_defconfig b/arch/arm/configs/koelsch_defconfig
deleted file mode 100644 (file)
index 86faab5..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-CONFIG_SYSVIPC=y
-CONFIG_NO_HZ=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=16
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_EMBEDDED=y
-CONFIG_PERF_EVENTS=y
-CONFIG_SLAB=y
-CONFIG_ARCH_SHMOBILE_LEGACY=y
-CONFIG_ARCH_R8A7791=y
-CONFIG_MACH_KOELSCH=y
-# CONFIG_SWP_EMULATE is not set
-CONFIG_CPU_BPREDICT_DISABLE=y
-CONFIG_PL310_ERRATA_588369=y
-CONFIG_ARM_ERRATA_754322=y
-CONFIG_SMP=y
-CONFIG_SCHED_MC=y
-CONFIG_NR_CPUS=8
-CONFIG_AEABI=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_ARM_APPENDED_DTB=y
-CONFIG_KEXEC=y
-CONFIG_AUTO_ZRELADDR=y
-CONFIG_VFP=y
-CONFIG_NEON=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-CONFIG_PM_RUNTIME=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_DEVTMPFS=y
-CONFIG_DEVTMPFS_MOUNT=y
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_BLK_DEV_SD=y
-CONFIG_ATA=y
-CONFIG_SATA_RCAR=y
-CONFIG_MTD=y
-CONFIG_MTD_M25P80=y
-CONFIG_NETDEVICES=y
-# CONFIG_NET_VENDOR_ARC is not set
-# CONFIG_NET_CADENCE is not set
-# 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_MARVELL is not set
-# CONFIG_NET_VENDOR_MICREL is not set
-# CONFIG_NET_VENDOR_NATSEMI is not set
-CONFIG_SH_ETH=y
-# CONFIG_NET_VENDOR_SEEQ is not set
-# CONFIG_NET_VENDOR_SMSC is not set
-# CONFIG_NET_VENDOR_STMICRO is not set
-# CONFIG_NET_VENDOR_VIA is not set
-# CONFIG_NET_VENDOR_WIZNET is not set
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-CONFIG_KEYBOARD_GPIO=y
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_SERIAL_SH_SCI=y
-CONFIG_SERIAL_SH_SCI_NR_UARTS=20
-CONFIG_SERIAL_SH_SCI_CONSOLE=y
-CONFIG_I2C=y
-CONFIG_I2C_RCAR=y
-CONFIG_SPI=y
-CONFIG_SPI_RSPI=y
-CONFIG_GPIOLIB=y
-CONFIG_GPIO_RCAR=y
-# CONFIG_HWMON is not set
-CONFIG_THERMAL=y
-CONFIG_RCAR_THERMAL=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_REGULATOR_GPIO=y
-# CONFIG_HID is not set
-# CONFIG_USB_SUPPORT is not set
-CONFIG_MMC=y
-CONFIG_MMC_SDHI=y
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_GPIO=y
-# CONFIG_IOMMU_SUPPORT is not set
-# CONFIG_DNOTIFY is not set
-CONFIG_TMPFS=y
-CONFIG_CONFIGFS_FS=y
-# CONFIG_MISC_FILESYSTEMS is not set
-CONFIG_NFS_FS=y
-CONFIG_ROOT_NFS=y
-# CONFIG_ENABLE_WARN_DEPRECATED is not set
-# CONFIG_ENABLE_MUST_CHECK is not set
-# CONFIG_ARM_UNWIND is not set
index bd097d4..8cb115d 100644 (file)
@@ -119,6 +119,7 @@ CONFIG_MMC_SDHI=y
 CONFIG_MMC_SH_MMCIF=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_RS5C372=y
 CONFIG_DMADEVICES=y
index 5870244..929c571 100644 (file)
@@ -22,6 +22,9 @@ CONFIG_ARM_ERRATA_458693=y
 CONFIG_ARM_ERRATA_460075=y
 CONFIG_ARM_ERRATA_743622=y
 CONFIG_ARM_ERRATA_754322=y
+CONFIG_PCI=y
+CONFIG_PCI_RCAR_GEN2=y
+CONFIG_PCI_RCAR_GEN2_PCIE=y
 CONFIG_HAVE_ARM_ARCH_TIMER=y
 CONFIG_AEABI=y
 # CONFIG_OABI_COMPAT is not set
@@ -53,6 +56,7 @@ CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_MTD=y
 CONFIG_MTD_M25P80=y
+CONFIG_MTD_SPI_NOR=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_ATA=y
 CONFIG_SATA_RCAR=y
@@ -85,11 +89,12 @@ CONFIG_SERIAL_SH_SCI=y
 CONFIG_SERIAL_SH_SCI_NR_UARTS=10
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 # CONFIG_HW_RANDOM is not set
-CONFIG_I2C=y
 CONFIG_I2C_GPIO=y
+CONFIG_I2C_SH_MOBILE=y
 CONFIG_I2C_RCAR=y
 CONFIG_SPI=y
 CONFIG_SPI_RSPI=y
+CONFIG_SPI_SH_MSIOF=y
 CONFIG_GPIO_SH_PFC=y
 CONFIG_GPIOLIB=y
 CONFIG_GPIO_RCAR=y
@@ -98,6 +103,7 @@ CONFIG_THERMAL=y
 CONFIG_RCAR_THERMAL=y
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_DA9210=y
 CONFIG_REGULATOR_GPIO=y
 CONFIG_MEDIA_SUPPORT=y
 CONFIG_MEDIA_CAMERA_SUPPORT=y
index 92994f7..ff91630 100644 (file)
@@ -84,6 +84,7 @@ CONFIG_GPIO_RCAR=y
 CONFIG_THERMAL=y
 CONFIG_RCAR_THERMAL=y
 CONFIG_SSB=y
+CONFIG_REGULATOR=y
 CONFIG_MEDIA_SUPPORT=y
 CONFIG_MEDIA_CAMERA_SUPPORT=y
 CONFIG_V4L_PLATFORM_DRIVERS=y
index 3b13614..63fb531 100644 (file)
@@ -3,6 +3,7 @@ CONFIG_NO_HZ=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=16
+CONFIG_BLK_DEV_INITRD=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_EMBEDDED=y
@@ -11,10 +12,11 @@ CONFIG_SLAB=y
 CONFIG_ARCH_SHMOBILE_MULTI=y
 CONFIG_ARCH_EMEV2=y
 CONFIG_ARCH_R7S72100=y
+CONFIG_ARCH_R8A7740=y
 CONFIG_ARCH_R8A7779=y
 CONFIG_ARCH_R8A7790=y
 CONFIG_ARCH_R8A7791=y
-CONFIG_MACH_KOELSCH=y
+CONFIG_ARCH_R8A7794=y
 CONFIG_MACH_LAGER=y
 CONFIG_MACH_MARZEN=y
 # CONFIG_SWP_EMULATE is not set
@@ -49,6 +51,7 @@ CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_MTD=y
 CONFIG_MTD_M25P80=y
+CONFIG_MTD_SPI_NOR=y
 CONFIG_EEPROM_AT24=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_ATA=y
@@ -73,6 +76,8 @@ CONFIG_SMSC_PHY=y
 # CONFIG_INPUT_MOUSEDEV_PSAUX is not set
 CONFIG_KEYBOARD_GPIO=y
 # CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ST1232=y
 # CONFIG_LEGACY_PTYS is not set
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
@@ -82,6 +87,7 @@ CONFIG_SERIAL_SH_SCI=y
 CONFIG_SERIAL_SH_SCI_NR_UARTS=20
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_I2C_GPIO=y
+CONFIG_I2C_RIIC=y
 CONFIG_I2C_SH_MOBILE=y
 CONFIG_I2C_RCAR=y
 CONFIG_SPI=y
@@ -110,10 +116,17 @@ CONFIG_VIDEO_RENESAS_VSP1=y
 CONFIG_VIDEO_ADV7180=y
 CONFIG_DRM=y
 CONFIG_DRM_RCAR_DU=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_PWM=y
 CONFIG_SOUND=y
 CONFIG_SND=y
 CONFIG_SND_SOC=y
+CONFIG_SND_SOC_SH4_FSI=y
 CONFIG_SND_SOC_RCAR=y
+CONFIG_SND_SOC_AK4642=y
+CONFIG_SND_SOC_WM8978=y
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_OHCI_HCD=y
@@ -130,9 +143,14 @@ CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_GPIO=y
 CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_S35390A=y
 CONFIG_DMADEVICES=y
 CONFIG_SH_DMAE=y
+CONFIG_RCAR_AUDMAC_PP=y
+CONFIG_RCAR_DMAC=y
 # CONFIG_IOMMU_SUPPORT is not set
+CONFIG_PWM=y
+CONFIG_PWM_RENESAS_TPU=y
 # CONFIG_DNOTIFY is not set
 CONFIG_MSDOS_FS=y
 CONFIG_VFAT_FS=y
index 0704e0c..92793ba 100644 (file)
@@ -99,31 +99,6 @@ static inline void arch_timer_set_cntkctl(u32 cntkctl)
        asm volatile("mcr p15, 0, %0, c14, c1, 0" : : "r" (cntkctl));
 }
 
-static inline void arch_counter_set_user_access(void)
-{
-       u32 cntkctl = arch_timer_get_cntkctl();
-
-       /* Disable user access to both physical/virtual counters/timers */
-       /* Also disable virtual event stream */
-       cntkctl &= ~(ARCH_TIMER_USR_PT_ACCESS_EN
-                       | ARCH_TIMER_USR_VT_ACCESS_EN
-                       | ARCH_TIMER_VIRT_EVT_EN
-                       | ARCH_TIMER_USR_VCT_ACCESS_EN
-                       | ARCH_TIMER_USR_PCT_ACCESS_EN);
-       arch_timer_set_cntkctl(cntkctl);
-}
-
-static inline void arch_timer_evtstrm_enable(int divider)
-{
-       u32 cntkctl = arch_timer_get_cntkctl();
-       cntkctl &= ~ARCH_TIMER_EVT_TRIGGER_MASK;
-       /* Set the divider and enable virtual event stream */
-       cntkctl |= (divider << ARCH_TIMER_EVT_TRIGGER_SHIFT)
-                       | ARCH_TIMER_VIRT_EVT_EN;
-       arch_timer_set_cntkctl(cntkctl);
-       elf_hwcap |= HWCAP_EVTSTRM;
-}
-
 #endif
 
 #endif
index 71a06b2..3e635ee 100644 (file)
@@ -43,16 +43,6 @@ struct cpu_context_save {
        __u32   extra[2];               /* Xscale 'acc' register, etc */
 };
 
-struct arm_restart_block {
-       union {
-               /* For user cache flushing */
-               struct {
-                       unsigned long start;
-                       unsigned long end;
-               } cache;
-       };
-};
-
 /*
  * low level task data that entry.S needs immediate access to.
  * __switch_to() assumes cpu_context follows immediately after cpu_domain.
@@ -78,7 +68,6 @@ struct thread_info {
        unsigned long           thumbee_state;  /* ThumbEE Handler Base register */
 #endif
        struct restart_block    restart_block;
-       struct arm_restart_block        arm_restart_block;
 };
 
 #define INIT_THREAD_INFO(tsk)                                          \
diff --git a/arch/arm/include/debug/renesas-scif.S b/arch/arm/include/debug/renesas-scif.S
new file mode 100644 (file)
index 0000000..97820a8
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Renesas SCIF(A) debugging macro include header
+ *
+ * Based on r8a7790.S
+ *
+ * Copyright (C) 2012-2013 Renesas Electronics Corporation
+ * Copyright (C) 1994-1999 Russell King
+ *
+ * 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.
+ */
+
+#define SCIF_PHYS      CONFIG_DEBUG_UART_PHYS
+#define SCIF_VIRT      ((SCIF_PHYS & 0x00ffffff) | 0xfd000000)
+
+#if CONFIG_DEBUG_UART_PHYS < 0xe6e00000
+/* SCIFA */
+#define FTDR           0x20
+#define FSR            0x14
+#else
+/* SCIF */
+#define FTDR           0x0c
+#define FSR            0x10
+#endif
+
+#define TDFE   (1 << 5)
+#define TEND   (1 << 6)
+
+       .macro  addruart, rp, rv, tmp
+       ldr     \rp, =SCIF_PHYS
+       ldr     \rv, =SCIF_VIRT
+       .endm
+
+       .macro  waituart, rd, rx
+1001:  ldrh    \rd, [\rx, #FSR]
+       tst     \rd, #TDFE
+       beq     1001b
+       .endm
+
+       .macro  senduart, rd, rx
+       strb    \rd, [\rx, #FTDR]
+       ldrh    \rd, [\rx, #FSR]
+       bic     \rd, \rd, #TEND
+       strh    \rd, [\rx, #FSR]
+       .endm
+
+       .macro  busyuart, rd, rx
+1001:  ldrh    \rd, [\rx, #FSR]
+       tst     \rd, #TEND
+       beq     1001b
+       .endm
index 18a7628..380c20f 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/kprobes.h>
 #include <asm/system_info.h>
+#include <asm/opcodes.h>
 
 #include "kprobes.h"
 
@@ -305,7 +306,8 @@ kprobe_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 
        if (handler) {
                /* We can emulate the instruction in (possibly) modified form */
-               asi->insn[0] = (insn & 0xfff00000) | (rn << 16) | reglist;
+               asi->insn[0] = __opcode_to_mem_arm((insn & 0xfff00000) |
+                                                  (rn << 16) | reglist);
                asi->insn_handler = handler;
                return INSN_GOOD;
        }
@@ -334,13 +336,14 @@ prepare_emulated_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi,
 #ifdef CONFIG_THUMB2_KERNEL
        if (thumb) {
                u16 *thumb_insn = (u16 *)asi->insn;
-               thumb_insn[1] = 0x4770; /* Thumb bx lr */
-               thumb_insn[2] = 0x4770; /* Thumb bx lr */
+               /* Thumb bx lr */
+               thumb_insn[1] = __opcode_to_mem_thumb16(0x4770);
+               thumb_insn[2] = __opcode_to_mem_thumb16(0x4770);
                return insn;
        }
-       asi->insn[1] = 0xe12fff1e; /* ARM bx lr */
+       asi->insn[1] = __opcode_to_mem_arm(0xe12fff1e); /* ARM bx lr */
 #else
-       asi->insn[1] = 0xe1a0f00e; /* mov pc, lr */
+       asi->insn[1] = __opcode_to_mem_arm(0xe1a0f00e); /* mov pc, lr */
 #endif
        /* Make an ARM instruction unconditional */
        if (insn < 0xe0000000)
@@ -360,12 +363,12 @@ set_emulated_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi,
        if (thumb) {
                u16 *ip = (u16 *)asi->insn;
                if (is_wide_instruction(insn))
-                       *ip++ = insn >> 16;
-               *ip++ = insn;
+                       *ip++ = __opcode_to_mem_thumb16(insn >> 16);
+               *ip++ = __opcode_to_mem_thumb16(insn);
                return;
        }
 #endif
-       asi->insn[0] = insn;
+       asi->insn[0] = __opcode_to_mem_arm(insn);
 }
 
 /*
index 6123daf..241222c 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/kprobes.h>
 #include <linux/module.h>
+#include <asm/opcodes.h>
 
 #include "kprobes.h"
 
@@ -163,9 +164,9 @@ t32_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi)
        enum kprobe_insn ret = kprobe_decode_ldmstm(insn, asi);
 
        /* Fixup modified instruction to have halfwords in correct order...*/
-       insn = asi->insn[0];
-       ((u16 *)asi->insn)[0] = insn >> 16;
-       ((u16 *)asi->insn)[1] = insn & 0xffff;
+       insn = __mem_to_opcode_arm(asi->insn[0]);
+       ((u16 *)asi->insn)[0] = __opcode_to_mem_thumb16(insn >> 16);
+       ((u16 *)asi->insn)[1] = __opcode_to_mem_thumb16(insn & 0xffff);
 
        return ret;
 }
@@ -1153,7 +1154,7 @@ t16_decode_hiregs(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 {
        insn &= ~0x00ff;
        insn |= 0x001; /* Set Rdn = R1 and Rm = R0 */
-       ((u16 *)asi->insn)[0] = insn;
+       ((u16 *)asi->insn)[0] = __opcode_to_mem_thumb16(insn);
        asi->insn_handler = t16_emulate_hiregs;
        return INSN_GOOD;
 }
@@ -1182,8 +1183,10 @@ t16_decode_push(kprobe_opcode_t insn, struct arch_specific_insn *asi)
         * and call it with R9=SP and LR in the register list represented
         * by R8.
         */
-       ((u16 *)asi->insn)[0] = 0xe929;         /* 1st half STMDB R9!,{} */
-       ((u16 *)asi->insn)[1] = insn & 0x1ff;   /* 2nd half (register list) */
+       /* 1st half STMDB R9!,{} */
+       ((u16 *)asi->insn)[0] = __opcode_to_mem_thumb16(0xe929);
+       /* 2nd half (register list) */
+       ((u16 *)asi->insn)[1] = __opcode_to_mem_thumb16(insn & 0x1ff);
        asi->insn_handler = t16_emulate_push;
        return INSN_GOOD;
 }
@@ -1232,8 +1235,10 @@ t16_decode_pop(kprobe_opcode_t insn, struct arch_specific_insn *asi)
         * and call it with R9=SP and PC in the register list represented
         * by R8.
         */
-       ((u16 *)asi->insn)[0] = 0xe8b9;         /* 1st half LDMIA R9!,{} */
-       ((u16 *)asi->insn)[1] = insn & 0x1ff;   /* 2nd half (register list) */
+       /* 1st half LDMIA R9!,{} */
+       ((u16 *)asi->insn)[0] = __opcode_to_mem_thumb16(0xe8b9);
+       /* 2nd half (register list) */
+       ((u16 *)asi->insn)[1] = __opcode_to_mem_thumb16(insn & 0x1ff);
        asi->insn_handler = insn & 0x100 ? t16_emulate_pop_pc
                                         : t16_emulate_pop_nopc;
        return INSN_GOOD;
index a7b621e..49a87b6 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/stop_machine.h>
 #include <linux/stringify.h>
 #include <asm/traps.h>
+#include <asm/opcodes.h>
 #include <asm/cacheflush.h>
 
 #include "kprobes.h"
@@ -62,10 +63,10 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
 #ifdef CONFIG_THUMB2_KERNEL
        thumb = true;
        addr &= ~1; /* Bit 0 would normally be set to indicate Thumb code */
-       insn = ((u16 *)addr)[0];
+       insn = __mem_to_opcode_thumb16(((u16 *)addr)[0]);
        if (is_wide_instruction(insn)) {
-               insn <<= 16;
-               insn |= ((u16 *)addr)[1];
+               u16 inst2 = __mem_to_opcode_thumb16(((u16 *)addr)[1]);
+               insn = __opcode_thumb32_compose(insn, inst2);
                decode_insn = thumb32_kprobe_decode_insn;
        } else
                decode_insn = thumb16_kprobe_decode_insn;
@@ -73,7 +74,7 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
        thumb = false;
        if (addr & 0x3)
                return -EINVAL;
-       insn = *p->addr;
+       insn = __mem_to_opcode_arm(*p->addr);
        decode_insn = arm_kprobe_decode_insn;
 #endif
 
index 9265b8b..3f31443 100644 (file)
@@ -510,8 +510,6 @@ static int bad_syscall(int n, struct pt_regs *regs)
        return regs->ARM_r0;
 }
 
-static long do_cache_op_restart(struct restart_block *);
-
 static inline int
 __do_cache_op(unsigned long start, unsigned long end)
 {
@@ -520,24 +518,8 @@ __do_cache_op(unsigned long start, unsigned long end)
        do {
                unsigned long chunk = min(PAGE_SIZE, end - start);
 
-               if (signal_pending(current)) {
-                       struct thread_info *ti = current_thread_info();
-
-                       ti->restart_block = (struct restart_block) {
-                               .fn     = do_cache_op_restart,
-                       };
-
-                       ti->arm_restart_block = (struct arm_restart_block) {
-                               {
-                                       .cache = {
-                                               .start  = start,
-                                               .end    = end,
-                                       },
-                               },
-                       };
-
-                       return -ERESTART_RESTARTBLOCK;
-               }
+               if (fatal_signal_pending(current))
+                       return 0;
 
                ret = flush_cache_user_range(start, start + chunk);
                if (ret)
@@ -550,15 +532,6 @@ __do_cache_op(unsigned long start, unsigned long end)
        return 0;
 }
 
-static long do_cache_op_restart(struct restart_block *unused)
-{
-       struct arm_restart_block *restart_block;
-
-       restart_block = &current_thread_info()->arm_restart_block;
-       return __do_cache_op(restart_block->cache.start,
-                            restart_block->cache.end);
-}
-
 static inline int
 do_cache_op(unsigned long start, unsigned long end, int flags)
 {
index 3e23801..b8b90e2 100644 (file)
@@ -1,5 +1,31 @@
 config ARCH_SHMOBILE
        bool
+       select ZONE_DMA if ARM_LPAE
+
+config PM_RCAR
+       bool
+
+config PM_RMOBILE
+       bool
+
+config ARCH_RCAR_GEN1
+       bool
+       select PM_RCAR if PM || SMP
+       select RENESAS_INTC_IRQPIN
+       select SYS_SUPPORTS_SH_TMU
+
+config ARCH_RCAR_GEN2
+       bool
+       select PM_RCAR if PM || SMP
+       select RENESAS_IRQC
+       select SYS_SUPPORTS_SH_CMT
+       select PCI_DOMAINS if PCI
+
+config ARCH_RMOBILE
+       bool
+       select PM_RMOBILE if PM && !ARCH_SHMOBILE_MULTI
+       select SYS_SUPPORTS_SH_CMT
+       select SYS_SUPPORTS_SH_TMU
 
 config ARCH_SHMOBILE_MULTI
        bool "Renesas ARM SoCs" if ARCH_MULTI_V7
@@ -27,31 +53,28 @@ config ARCH_R7S72100
        bool "RZ/A1H (R7S72100)"
        select SYS_SUPPORTS_SH_MTU2
 
+config ARCH_R8A7740
+       bool "R-Mobile A1 (R8A77400)"
+       select ARCH_RMOBILE
+       select RENESAS_INTC_IRQPIN
+
 config ARCH_R8A7779
        bool "R-Car H1 (R8A77790)"
-       select RENESAS_INTC_IRQPIN
-       select SYS_SUPPORTS_SH_TMU
+       select ARCH_RCAR_GEN1
 
 config ARCH_R8A7790
        bool "R-Car H2 (R8A77900)"
-       select RENESAS_IRQC
-       select SYS_SUPPORTS_SH_CMT
+       select ARCH_RCAR_GEN2
 
 config ARCH_R8A7791
-       bool "R-Car M2 (R8A77910)"
-       select RENESAS_IRQC
-       select SYS_SUPPORTS_SH_CMT
-
-comment "Renesas ARM SoCs Board Type"
+       bool "R-Car M2-W (R8A77910)"
+       select ARCH_RCAR_GEN2
 
-config MACH_GENMAI
-       bool "Genmai board"
-       depends on ARCH_R7S72100
+config ARCH_R8A7794
+       bool "R-Car E2 (R8A77940)"
+       select ARCH_RCAR_GEN2
 
-config MACH_KOELSCH
-       bool "Koelsch board"
-       depends on ARCH_R8A7791
-       select MICREL_PHY if SH_ETH
+comment "Renesas ARM SoCs Board Type"
 
 config MACH_LAGER
        bool "Lager board"
@@ -72,95 +95,55 @@ comment "Renesas ARM SoCs System Type"
 
 config ARCH_SH7372
        bool "SH-Mobile AP4 (SH7372)"
+       select ARCH_RMOBILE
        select ARCH_WANT_OPTIONAL_GPIOLIB
        select ARM_CPU_SUSPEND if PM || CPU_IDLE
-       select CPU_V7
-       select SH_CLK_CPG
        select SH_INTC
-       select SYS_SUPPORTS_SH_CMT
-       select SYS_SUPPORTS_SH_TMU
 
 config ARCH_SH73A0
        bool "SH-Mobile AG5 (R8A73A00)"
+       select ARCH_RMOBILE
        select ARCH_WANT_OPTIONAL_GPIOLIB
        select ARM_GIC
-       select CPU_V7
        select I2C
-       select SH_CLK_CPG
        select SH_INTC
        select RENESAS_INTC_IRQPIN
-       select SYS_SUPPORTS_SH_CMT
-       select SYS_SUPPORTS_SH_TMU
 
 config ARCH_R8A73A4
        bool "R-Mobile APE6 (R8A73A40)"
+       select ARCH_RMOBILE
        select ARCH_WANT_OPTIONAL_GPIOLIB
        select ARM_GIC
-       select CPU_V7
-       select SH_CLK_CPG
        select RENESAS_IRQC
        select ARCH_HAS_CPUFREQ
        select ARCH_HAS_OPP
-       select SYS_SUPPORTS_SH_CMT
-       select SYS_SUPPORTS_SH_TMU
 
 config ARCH_R8A7740
        bool "R-Mobile A1 (R8A77400)"
+       select ARCH_RMOBILE
        select ARCH_WANT_OPTIONAL_GPIOLIB
        select ARM_GIC
-       select CPU_V7
-       select SH_CLK_CPG
        select RENESAS_INTC_IRQPIN
-       select SYS_SUPPORTS_SH_CMT
-       select SYS_SUPPORTS_SH_TMU
 
 config ARCH_R8A7778
        bool "R-Car M1A (R8A77781)"
+       select ARCH_RCAR_GEN1
        select ARCH_WANT_OPTIONAL_GPIOLIB
-       select CPU_V7
-       select SH_CLK_CPG
        select ARM_GIC
-       select SYS_SUPPORTS_SH_TMU
-       select RENESAS_INTC_IRQPIN
 
 config ARCH_R8A7779
        bool "R-Car H1 (R8A77790)"
+       select ARCH_RCAR_GEN1
        select ARCH_WANT_OPTIONAL_GPIOLIB
        select ARM_GIC
-       select CPU_V7
-       select SH_CLK_CPG
-       select RENESAS_INTC_IRQPIN
-       select SYS_SUPPORTS_SH_TMU
 
 config ARCH_R8A7790
        bool "R-Car H2 (R8A77900)"
+       select ARCH_RCAR_GEN2
        select ARCH_WANT_OPTIONAL_GPIOLIB
        select ARM_GIC
-       select CPU_V7
        select MIGHT_HAVE_PCI
-       select SH_CLK_CPG
-       select RENESAS_IRQC
        select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
-       select SYS_SUPPORTS_SH_CMT
-
-config ARCH_R8A7791
-       bool "R-Car M2 (R8A77910)"
-       select ARCH_WANT_OPTIONAL_GPIOLIB
-       select ARM_GIC
-       select CPU_V7
-       select MIGHT_HAVE_PCI
-       select SH_CLK_CPG
-       select RENESAS_IRQC
-       select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
-       select SYS_SUPPORTS_SH_CMT
-
-config ARCH_R7S72100
-       bool "RZ/A1H (R7S72100)"
-       select ARCH_WANT_OPTIONAL_GPIOLIB
-       select ARM_GIC
-       select CPU_V7
-       select SH_CLK_CPG
-       select SYS_SUPPORTS_SH_MTU2
 
 comment "Renesas ARM SoCs Board Type"
 
@@ -200,21 +183,6 @@ config MACH_ARMADILLO800EVA
        select SND_SOC_WM8978 if SND_SIMPLE_CARD
        select USE_OF
 
-config MACH_ARMADILLO800EVA_REFERENCE
-       bool "Armadillo-800 EVA board - Reference Device Tree Implementation"
-       depends on ARCH_R8A7740
-       select ARCH_REQUIRE_GPIOLIB
-       select REGULATOR_FIXED_VOLTAGE if REGULATOR
-       select SMSC_PHY if SH_ETH
-       select SND_SOC_WM8978 if SND_SIMPLE_CARD
-       select USE_OF
-       ---help---
-          Use reference implementation of Armadillo800 EVA board support
-          which makes greater use of device tree at the expense
-          of not supporting a number of devices.
-
-          This is intended to aid developers
-
 config MACH_BOCKW
        bool "BOCK-W platform"
        depends on ARCH_R8A7778
@@ -237,11 +205,6 @@ config MACH_BOCKW_REFERENCE
 
           This is intended to aid developers
 
-config MACH_GENMAI
-       bool "Genmai board"
-       depends on ARCH_R7S72100
-       select USE_OF
-
 config MACH_MARZEN
        bool "MARZEN board"
        depends on ARCH_R8A7779
@@ -256,12 +219,6 @@ config MACH_LAGER
        select MICREL_PHY if SH_ETH
        select SND_SOC_AK4642 if SND_SIMPLE_CARD
 
-config MACH_KOELSCH
-       bool "Koelsch board"
-       depends on ARCH_R8A7791
-       select USE_OF
-       select MICREL_PHY if SH_ETH
-
 config MACH_KZM9G
        bool "KZM-A9-GT board"
        depends on ARCH_SH73A0
index fe3878a..b55cac0 100644 (file)
@@ -2,27 +2,25 @@
 # Makefile for the linux kernel.
 #
 
-ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/arch/arm/mach-shmobile/include
-
 # Common objects
 obj-y                          := timer.o console.o
 
 # CPU objects
-obj-$(CONFIG_ARCH_SH7372)      += setup-sh7372.o intc-sh7372.o
-obj-$(CONFIG_ARCH_SH73A0)      += setup-sh73a0.o intc-sh73a0.o
+obj-$(CONFIG_ARCH_SH7372)      += setup-sh7372.o intc-sh7372.o pm-sh7372.o
+obj-$(CONFIG_ARCH_SH73A0)      += setup-sh73a0.o intc-sh73a0.o pm-sh73a0.o
 obj-$(CONFIG_ARCH_R8A73A4)     += setup-r8a73a4.o
-obj-$(CONFIG_ARCH_R8A7740)     += setup-r8a7740.o
+obj-$(CONFIG_ARCH_R8A7740)     += setup-r8a7740.o pm-r8a7740.o
 obj-$(CONFIG_ARCH_R8A7778)     += setup-r8a7778.o
-obj-$(CONFIG_ARCH_R8A7779)     += setup-r8a7779.o
-obj-$(CONFIG_ARCH_R8A7790)     += setup-r8a7790.o
-obj-$(CONFIG_ARCH_R8A7790)     += setup-r8a7790.o setup-rcar-gen2.o
-obj-$(CONFIG_ARCH_R8A7791)     += setup-r8a7791.o setup-rcar-gen2.o
+obj-$(CONFIG_ARCH_R8A7779)     += setup-r8a7779.o pm-r8a7779.o
+obj-$(CONFIG_ARCH_R8A7790)     += setup-r8a7790.o pm-r8a7790.o
+obj-$(CONFIG_ARCH_R8A7791)     += setup-r8a7791.o pm-r8a7791.o
+obj-$(CONFIG_ARCH_R8A7794)     += setup-r8a7794.o
 obj-$(CONFIG_ARCH_EMEV2)       += setup-emev2.o
 obj-$(CONFIG_ARCH_R7S72100)    += setup-r7s72100.o
 
 # Clock objects
-obj-y                          += clock.o
 ifndef CONFIG_COMMON_CLK
+obj-y                          += clock.o
 obj-$(CONFIG_ARCH_SH7372)      += clock-sh7372.o
 obj-$(CONFIG_ARCH_SH73A0)      += clock-sh73a0.o
 obj-$(CONFIG_ARCH_R8A73A4)     += clock-r8a73a4.o
@@ -30,14 +28,14 @@ obj-$(CONFIG_ARCH_R8A7740)  += clock-r8a7740.o
 obj-$(CONFIG_ARCH_R8A7778)     += clock-r8a7778.o
 obj-$(CONFIG_ARCH_R8A7779)     += clock-r8a7779.o
 obj-$(CONFIG_ARCH_R8A7790)     += clock-r8a7790.o
-obj-$(CONFIG_ARCH_R8A7791)     += clock-r8a7791.o
-obj-$(CONFIG_ARCH_R7S72100)    += clock-r7s72100.o
 endif
 
 # CPU reset vector handling objects
 cpu-y                          := platsmp.o headsmp.o
-cpu-$(CONFIG_ARCH_R8A7790)     += platsmp-apmu.o
-cpu-$(CONFIG_ARCH_R8A7791)     += platsmp-apmu.o
+
+# Shared SoC family objects
+obj-$(CONFIG_ARCH_RCAR_GEN2)   += setup-rcar-gen2.o platsmp-apmu.o $(cpu-y)
+CFLAGS_setup-rcar-gen2.o       += -march=armv7-a
 
 # SMP objects
 smp-y                          := $(cpu-y)
@@ -51,20 +49,14 @@ smp-$(CONFIG_ARCH_EMEV2)    += smp-emev2.o headsmp-scu.o platsmp-scu.o
 obj-$(CONFIG_SUSPEND)          += suspend.o
 obj-$(CONFIG_CPU_IDLE)         += cpuidle.o
 obj-$(CONFIG_CPU_FREQ)         += cpufreq.o
-obj-$(CONFIG_ARCH_SH7372)      += pm-sh7372.o sleep-sh7372.o pm-rmobile.o
-obj-$(CONFIG_ARCH_SH73A0)      += pm-sh73a0.o
-obj-$(CONFIG_ARCH_R8A7740)     += pm-r8a7740.o pm-rmobile.o
-obj-$(CONFIG_ARCH_R8A7779)     += pm-r8a7779.o pm-rcar.o
-obj-$(CONFIG_ARCH_R8A7790)     += pm-r8a7790.o pm-rcar.o $(cpu-y)
-obj-$(CONFIG_ARCH_R8A7791)     += pm-r8a7791.o pm-rcar.o $(cpu-y)
+obj-$(CONFIG_PM_RCAR)          += pm-rcar.o
+obj-$(CONFIG_PM_RMOBILE)       += pm-rmobile.o
 
-# IRQ objects
-obj-$(CONFIG_ARCH_SH7372)      += entry-intc.o
+# special sh7372 handling for IRQ objects and low level sleep code
+obj-$(CONFIG_ARCH_SH7372)      += entry-intc.o sleep-sh7372.o
 
 # Board objects
 ifdef CONFIG_ARCH_SHMOBILE_MULTI
-obj-$(CONFIG_MACH_GENMAI)      += board-genmai-reference.o
-obj-$(CONFIG_MACH_KOELSCH)     += board-koelsch-reference.o
 obj-$(CONFIG_MACH_LAGER)       += board-lager-reference.o
 obj-$(CONFIG_MACH_MARZEN)      += board-marzen-reference.o
 else
@@ -73,12 +65,9 @@ obj-$(CONFIG_MACH_APE6EVM_REFERENCE) += board-ape6evm-reference.o
 obj-$(CONFIG_MACH_MACKEREL)    += board-mackerel.o
 obj-$(CONFIG_MACH_BOCKW)       += board-bockw.o
 obj-$(CONFIG_MACH_BOCKW_REFERENCE)     += board-bockw-reference.o
-obj-$(CONFIG_MACH_GENMAI)      += board-genmai.o
 obj-$(CONFIG_MACH_MARZEN)      += board-marzen.o
 obj-$(CONFIG_MACH_LAGER)       += board-lager.o
 obj-$(CONFIG_MACH_ARMADILLO800EVA)     += board-armadillo800eva.o
-obj-$(CONFIG_MACH_ARMADILLO800EVA_REFERENCE)   += board-armadillo800eva-reference.o
-obj-$(CONFIG_MACH_KOELSCH)     += board-koelsch.o
 obj-$(CONFIG_MACH_KZM9G)       += board-kzm9g.o
 obj-$(CONFIG_MACH_KZM9G_REFERENCE)     += board-kzm9g-reference.o
 endif
index ebf97d4..57d00ed 100644 (file)
@@ -3,11 +3,8 @@ loadaddr-y     :=
 loadaddr-$(CONFIG_MACH_APE6EVM) += 0x40008000
 loadaddr-$(CONFIG_MACH_APE6EVM_REFERENCE) += 0x40008000
 loadaddr-$(CONFIG_MACH_ARMADILLO800EVA) += 0x40008000
-loadaddr-$(CONFIG_MACH_ARMADILLO800EVA_REFERENCE) += 0x40008000
 loadaddr-$(CONFIG_MACH_BOCKW) += 0x60008000
 loadaddr-$(CONFIG_MACH_BOCKW_REFERENCE) += 0x60008000
-loadaddr-$(CONFIG_MACH_GENMAI) += 0x08008000
-loadaddr-$(CONFIG_MACH_KOELSCH) += 0x40008000
 loadaddr-$(CONFIG_MACH_KZM9G) += 0x41008000
 loadaddr-$(CONFIG_MACH_KZM9G_REFERENCE) += 0x41008000
 loadaddr-$(CONFIG_MACH_LAGER) += 0x40008000
index 2f7723e..3b68370 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
 #include <linux/gpio.h>
@@ -48,9 +44,7 @@ static void __init ape6evm_add_standard_devices(void)
        clk_put(parent);
        clk_put(mp);
 
-       r8a73a4_add_dt_devices();
        of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
-       platform_device_register_simple("cpufreq-cpu0", -1, NULL, 0);
 }
 
 static const char *ape6evm_boards_compat_dt[] __initdata = {
@@ -59,7 +53,8 @@ static const char *ape6evm_boards_compat_dt[] __initdata = {
 };
 
 DT_MACHINE_START(APE6EVM_DT, "ape6evm")
-       .init_early     = r8a73a4_init_early,
+       .init_early     = shmobile_init_delay,
        .init_machine   = ape6evm_add_standard_devices,
+       .init_late      = shmobile_init_late,
        .dt_compat      = ape6evm_boards_compat_dt,
 MACHINE_END
index 4855678..e62a143 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
 #include <linux/gpio.h>
@@ -283,7 +279,8 @@ static const char *ape6evm_boards_compat_dt[] __initdata = {
 };
 
 DT_MACHINE_START(APE6EVM_DT, "ape6evm")
-       .init_early     = r8a73a4_init_early,
+       .init_early     = shmobile_init_delay,
        .init_machine   = ape6evm_add_standard_devices,
+       .init_late      = shmobile_init_late,
        .dt_compat      = ape6evm_boards_compat_dt,
 MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-armadillo800eva-reference.c b/arch/arm/mach-shmobile/board-armadillo800eva-reference.c
deleted file mode 100644 (file)
index 36fab42..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * armadillo 800 eva board support
- *
- * Copyright (C) 2012 Renesas Solutions Corp.
- * Copyright (C) 2012 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/kernel.h>
-#include <linux/gpio.h>
-#include <linux/io.h>
-
-#include <asm/mach/arch.h>
-#include <asm/hardware/cache-l2x0.h>
-
-#include "common.h"
-#include "r8a7740.h"
-
-/*
- * CON1                Camera Module
- * CON2                Extension Bus
- * CON3                HDMI Output
- * CON4                Composite Video Output
- * CON5                H-UDI JTAG
- * CON6                ARM JTAG
- * CON7                SD1
- * CON8                SD2
- * CON9                RTC BackUp
- * CON10       Monaural Mic Input
- * CON11       Stereo Headphone Output
- * CON12       Audio Line Output(L)
- * CON13       Audio Line Output(R)
- * CON14       AWL13 Module
- * CON15       Extension
- * CON16       LCD1
- * CON17       LCD2
- * CON19       Power Input
- * CON20       USB1
- * CON21       USB2
- * CON22       Serial
- * CON23       LAN
- * CON24       USB3
- * LED1                Camera LED (Yellow)
- * LED2                Power LED (Green)
- * LED3-LED6   User LED (Yellow)
- * LED7                LAN link LED (Green)
- * LED8                LAN activity LED (Yellow)
- */
-
-/*
- * DipSwitch
- *
- *                    SW1
- *
- * -12345678-+---------------+----------------------------
- *  1        | boot          | hermit
- *  0        | boot          | OS auto boot
- * -12345678-+---------------+----------------------------
- *   00      | boot device   | eMMC
- *   10      | boot device   | SDHI0 (CON7)
- *   01      | boot device   | -
- *   11      | boot device   | Extension Buss (CS0)
- * -12345678-+---------------+----------------------------
- *     0     | Extension Bus | D8-D15 disable, eMMC enable
- *     1     | Extension Bus | D8-D15 enable,  eMMC disable
- * -12345678-+---------------+----------------------------
- *      0    | SDHI1         | COM8 disable, COM14 enable
- *      1    | SDHI1         | COM8 enable,  COM14 disable
- * -12345678-+---------------+----------------------------
- *       0   | USB0          | COM20 enable,  COM24 disable
- *       1   | USB0          | COM20 disable, COM24 enable
- * -12345678-+---------------+----------------------------
- *        00 | JTAG          | SH-X2
- *        10 | JTAG          | ARM
- *        01 | JTAG          | -
- *        11 | JTAG          | Boundary Scan
- *-----------+---------------+----------------------------
- */
-
-/*
- * FSI-WM8978
- *
- * this command is required when playback.
- *
- * # amixer set "Headphone" 50
- *
- * this command is required when capture.
- *
- * # amixer set "Input PGA" 15
- * # amixer set "Left Input Mixer MicP" on
- * # amixer set "Left Input Mixer MicN" on
- * # amixer set "Right Input Mixer MicN" on
- * # amixer set "Right Input Mixer MicP" on
- */
-
-/*
- * USB function
- *
- * When you use USB Function,
- * set SW1.6 ON, and connect cable to CN24.
- *
- * USBF needs workaround on R8A7740 chip.
- * These are a little bit complex.
- * see
- *     usbhsf_power_ctrl()
- */
-
-static void __init eva_clock_init(void)
-{
-       struct clk *system      = clk_get(NULL, "system_clk");
-       struct clk *xtal1       = clk_get(NULL, "extal1");
-       struct clk *usb24s      = clk_get(NULL, "usb24s");
-       struct clk *fsibck      = clk_get(NULL, "fsibck");
-
-       if (IS_ERR(system)      ||
-           IS_ERR(xtal1)       ||
-           IS_ERR(usb24s)      ||
-           IS_ERR(fsibck)) {
-               pr_err("armadillo800eva board clock init failed\n");
-               goto clock_error;
-       }
-
-       /* armadillo 800 eva extal1 is 24MHz */
-       clk_set_rate(xtal1, 24000000);
-
-       /* usb24s use extal1 (= system) clock (= 24MHz) */
-       clk_set_parent(usb24s, system);
-
-       /* FSIBCK is 12.288MHz, and it is parent of FSI-B */
-       clk_set_rate(fsibck, 12288000);
-
-clock_error:
-       if (!IS_ERR(system))
-               clk_put(system);
-       if (!IS_ERR(xtal1))
-               clk_put(xtal1);
-       if (!IS_ERR(usb24s))
-               clk_put(usb24s);
-       if (!IS_ERR(fsibck))
-               clk_put(fsibck);
-}
-
-/*
- * board init
- */
-static void __init eva_init(void)
-{
-       r8a7740_clock_init(MD_CK0 | MD_CK2);
-       eva_clock_init();
-
-       r8a7740_meram_workaround();
-
-#ifdef CONFIG_CACHE_L2X0
-       /* Early BRESP enable, Shared attribute override enable, 32K*8way */
-       l2x0_init(IOMEM(0xf0002000), 0x40440000, 0x82000fff);
-#endif
-
-       r8a7740_add_standard_devices_dt();
-
-       r8a7740_pm_init();
-}
-
-#define RESCNT2 IOMEM(0xe6188020)
-static void eva_restart(enum reboot_mode mode, const char *cmd)
-{
-       /* Do soft power on reset */
-       writel(1 << 31, RESCNT2);
-}
-
-static const char *eva_boards_compat_dt[] __initdata = {
-       "renesas,armadillo800eva-reference",
-       NULL,
-};
-
-DT_MACHINE_START(ARMADILLO800EVA_DT, "armadillo800eva-reference")
-       .map_io         = r8a7740_map_io,
-       .init_early     = shmobile_init_delay,
-       .init_irq       = r8a7740_init_irq_of,
-       .init_machine   = eva_init,
-       .init_late      = shmobile_init_late,
-       .dt_compat      = eva_boards_compat_dt,
-       .restart        = eva_restart,
-MACHINE_END
index 922887b..89c1df8 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
  */
 
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/err.h>
-#include <linux/kernel.h>
-#include <linux/input.h>
-#include <linux/platform_data/st1232_pdata.h>
-#include <linux/irq.h>
-#include <linux/platform_device.h>
 #include <linux/gpio.h>
 #include <linux/gpio_keys.h>
-#include <linux/regulator/driver.h>
+#include <linux/i2c-gpio.h>
+#include <linux/input.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/mfd/tmio.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/sh_mmcif.h>
+#include <linux/mmc/sh_mobile_sdhi.h>
 #include <linux/pinctrl/machine.h>
+#include <linux/platform_data/st1232_pdata.h>
+#include <linux/platform_device.h>
 #include <linux/pwm.h>
 #include <linux/pwm_backlight.h>
+#include <linux/reboot.h>
+#include <linux/regulator/driver.h>
 #include <linux/regulator/fixed.h>
 #include <linux/regulator/gpio-regulator.h>
 #include <linux/regulator/machine.h>
 #include <linux/sh_eth.h>
-#include <linux/videodev2.h>
 #include <linux/usb/renesas_usbhs.h>
-#include <linux/mfd/tmio.h>
-#include <linux/mmc/host.h>
-#include <linux/mmc/sh_mmcif.h>
-#include <linux/mmc/sh_mobile_sdhi.h>
-#include <linux/i2c-gpio.h>
-#include <linux/reboot.h>
+#include <linux/videodev2.h>
 
-#include <media/mt9t112.h>
-#include <media/sh_mobile_ceu.h>
-#include <media/soc_camera.h>
-#include <asm/page.h>
+#include <asm/hardware/cache-l2x0.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
-#include <asm/hardware/cache-l2x0.h>
-#include <video/sh_mobile_lcdc.h>
-#include <video/sh_mobile_hdmi.h>
+#include <asm/page.h>
+#include <media/mt9t112.h>
+#include <media/sh_mobile_ceu.h>
+#include <media/soc_camera.h>
 #include <sound/sh_fsi.h>
 #include <sound/simple_card.h>
+#include <video/sh_mobile_hdmi.h>
+#include <video/sh_mobile_lcdc.h>
 
 #include "common.h"
 #include "irqs.h"
@@ -1231,7 +1226,18 @@ clock_error:
 #define GPIO_PORT8CR   IOMEM(0xe6050008)
 static void __init eva_init(void)
 {
-       struct platform_device *usb = NULL;
+       static struct pm_domain_device domain_devices[] __initdata = {
+               { "A4LC", &lcdc0_device },
+               { "A4LC", &hdmi_lcdc_device },
+               { "A4MP", &hdmi_device },
+               { "A4MP", &fsi_device },
+               { "A4R",  &ceu0_device },
+               { "A4S",  &sh_eth_device },
+               { "A3SP", &pwm_device },
+               { "A3SP", &sdhi0_device },
+               { "A3SP", &sh_mmcif_device },
+       };
+       struct platform_device *usb = NULL, *sdhi1 = NULL;
 
        regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers,
                                     ARRAY_SIZE(fixed3v3_power_consumers), 3300000);
@@ -1300,6 +1306,7 @@ static void __init eva_init(void)
 
                platform_device_register(&vcc_sdhi1);
                platform_device_register(&sdhi1_device);
+               sdhi1 = &sdhi1_device;
        }
 
 
@@ -1316,10 +1323,12 @@ static void __init eva_init(void)
        platform_add_devices(eva_devices,
                             ARRAY_SIZE(eva_devices));
 
-       rmobile_add_device_to_domain("A4LC", &lcdc0_device);
-       rmobile_add_device_to_domain("A4LC", &hdmi_lcdc_device);
+       rmobile_add_devices_to_domains(domain_devices,
+                                      ARRAY_SIZE(domain_devices));
        if (usb)
                rmobile_add_device_to_domain("A3SP", usb);
+       if (sdhi1)
+               rmobile_add_device_to_domain("A3SP", sdhi1);
 
        r8a7740_pm_init();
 }
index ba840cd..d649ade 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
 #include <linux/of_platform.h>
@@ -80,8 +76,9 @@ static const char *bockw_boards_compat_dt[] __initdata = {
 };
 
 DT_MACHINE_START(BOCKW_DT, "bockw")
-       .init_early     = r8a7778_init_delay,
+       .init_early     = shmobile_init_delay,
        .init_irq       = r8a7778_init_irq_dt,
        .init_machine   = bockw_init,
+       .init_late      = shmobile_init_late,
        .dt_compat      = bockw_boards_compat_dt,
 MACHINE_END
index b4e4789..75a7054 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
 #include <linux/mfd/tmio.h>
@@ -736,7 +732,7 @@ static const char *bockw_boards_compat_dt[] __initdata = {
 };
 
 DT_MACHINE_START(BOCKW_DT, "bockw")
-       .init_early     = r8a7778_init_delay,
+       .init_early     = shmobile_init_delay,
        .init_irq       = r8a7778_init_irq_dt,
        .init_machine   = bockw_init,
        .dt_compat      = bockw_boards_compat_dt,
diff --git a/arch/arm/mach-shmobile/board-genmai-reference.c b/arch/arm/mach-shmobile/board-genmai-reference.c
deleted file mode 100644 (file)
index e5448f7..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Genmai board support
- *
- * Copyright (C) 2013  Renesas Solutions Corp.
- * Copyright (C) 2013  Magnus Damm
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <linux/kernel.h>
-#include <linux/of_platform.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-
-#include "clock.h"
-#include "common.h"
-#include "r7s72100.h"
-
-/*
- * This is a really crude hack to provide clkdev support to platform
- * devices until they get moved to DT.
- */
-static const struct clk_name clk_names[] = {
-       { "mtu2", "fck", "sh-mtu2" },
-};
-
-static void __init genmai_add_standard_devices(void)
-{
-       shmobile_clk_workaround(clk_names, ARRAY_SIZE(clk_names), true);
-       r7s72100_add_dt_devices();
-       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
-}
-
-static const char * const genmai_boards_compat_dt[] __initconst = {
-       "renesas,genmai",
-       NULL,
-};
-
-DT_MACHINE_START(GENMAI_DT, "genmai")
-       .init_early     = shmobile_init_delay,
-       .init_machine   = genmai_add_standard_devices,
-       .dt_compat      = genmai_boards_compat_dt,
-MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-genmai.c b/arch/arm/mach-shmobile/board-genmai.c
deleted file mode 100644 (file)
index e2a3ba4..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Genmai board support
- *
- * Copyright (C) 2013-2014  Renesas Solutions Corp.
- * Copyright (C) 2013  Magnus Damm
- * Copyright (C) 2014  Cogent Embedded, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/serial_sci.h>
-#include <linux/sh_eth.h>
-#include <linux/spi/rspi.h>
-#include <linux/spi/spi.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-
-#include "common.h"
-#include "irqs.h"
-#include "r7s72100.h"
-
-/* Ether */
-static const struct sh_eth_plat_data ether_pdata __initconst = {
-       .phy                    = 0x00, /* PD60610 */
-       .edmac_endian           = EDMAC_LITTLE_ENDIAN,
-       .phy_interface          = PHY_INTERFACE_MODE_MII,
-       .no_ether_link          = 1
-};
-
-static const struct resource ether_resources[] __initconst = {
-       DEFINE_RES_MEM(0xe8203000, 0x800),
-       DEFINE_RES_MEM(0xe8204800, 0x200),
-       DEFINE_RES_IRQ(gic_iid(359)),
-};
-
-static const struct platform_device_info ether_info __initconst = {
-       .parent         = &platform_bus,
-       .name           = "r7s72100-ether",
-       .id             = -1,
-       .res            = ether_resources,
-       .num_res        = ARRAY_SIZE(ether_resources),
-       .data           = &ether_pdata,
-       .size_data      = sizeof(ether_pdata),
-       .dma_mask       = DMA_BIT_MASK(32),
-};
-
-/* RSPI */
-#define RSPI_RESOURCE(idx, baseaddr, irq)                              \
-static const struct resource rspi##idx##_resources[] __initconst = {   \
-       DEFINE_RES_MEM(baseaddr, 0x24),                                 \
-       DEFINE_RES_IRQ_NAMED(irq, "error"),                             \
-       DEFINE_RES_IRQ_NAMED(irq + 1, "rx"),                            \
-       DEFINE_RES_IRQ_NAMED(irq + 2, "tx"),                            \
-}
-
-RSPI_RESOURCE(0, 0xe800c800, gic_iid(270));
-RSPI_RESOURCE(1, 0xe800d000, gic_iid(273));
-RSPI_RESOURCE(2, 0xe800d800, gic_iid(276));
-RSPI_RESOURCE(3, 0xe800e000, gic_iid(279));
-RSPI_RESOURCE(4, 0xe800e800, gic_iid(282));
-
-static const struct rspi_plat_data rspi_pdata __initconst = {
-       .num_chipselect = 1,
-};
-
-#define r7s72100_register_rspi(idx)                                       \
-       platform_device_register_resndata(&platform_bus, "rspi-rz", idx,   \
-                                       rspi##idx##_resources,             \
-                                       ARRAY_SIZE(rspi##idx##_resources), \
-                                       &rspi_pdata, sizeof(rspi_pdata))
-
-static const struct spi_board_info spi_info[] __initconst = {
-       {
-               .modalias               = "wm8978",
-               .max_speed_hz           = 5000000,
-               .bus_num                = 4,
-               .chip_select            = 0,
-       },
-};
-
-/* SCIF */
-#define R7S72100_SCIF(index, baseaddr, irq)                            \
-static const struct plat_sci_port scif##index##_platform_data = {      \
-       .type           = PORT_SCIF,                                    \
-       .regtype        = SCIx_SH2_SCIF_FIFODATA_REGTYPE,               \
-       .flags          = UPF_BOOT_AUTOCONF | UPF_IOREMAP,              \
-       .scscr          = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE | \
-                         SCSCR_REIE,                                   \
-};                                                                     \
-                                                                       \
-static struct resource scif##index##_resources[] = {                   \
-       DEFINE_RES_MEM(baseaddr, 0x100),                                \
-       DEFINE_RES_IRQ(irq + 1),                                        \
-       DEFINE_RES_IRQ(irq + 2),                                        \
-       DEFINE_RES_IRQ(irq + 3),                                        \
-       DEFINE_RES_IRQ(irq),                                            \
-}                                                                      \
-
-R7S72100_SCIF(0, 0xe8007000, gic_iid(221));
-R7S72100_SCIF(1, 0xe8007800, gic_iid(225));
-R7S72100_SCIF(2, 0xe8008000, gic_iid(229));
-R7S72100_SCIF(3, 0xe8008800, gic_iid(233));
-R7S72100_SCIF(4, 0xe8009000, gic_iid(237));
-R7S72100_SCIF(5, 0xe8009800, gic_iid(241));
-R7S72100_SCIF(6, 0xe800a000, gic_iid(245));
-R7S72100_SCIF(7, 0xe800a800, gic_iid(249));
-
-#define r7s72100_register_scif(index)                                         \
-       platform_device_register_resndata(&platform_bus, "sh-sci", index,      \
-                                         scif##index##_resources,             \
-                                         ARRAY_SIZE(scif##index##_resources), \
-                                         &scif##index##_platform_data,        \
-                                         sizeof(scif##index##_platform_data))
-
-static void __init genmai_add_standard_devices(void)
-{
-       r7s72100_clock_init();
-       r7s72100_add_dt_devices();
-
-       platform_device_register_full(&ether_info);
-
-       r7s72100_register_rspi(0);
-       r7s72100_register_rspi(1);
-       r7s72100_register_rspi(2);
-       r7s72100_register_rspi(3);
-       r7s72100_register_rspi(4);
-       spi_register_board_info(spi_info, ARRAY_SIZE(spi_info));
-
-       r7s72100_register_scif(0);
-       r7s72100_register_scif(1);
-       r7s72100_register_scif(2);
-       r7s72100_register_scif(3);
-       r7s72100_register_scif(4);
-       r7s72100_register_scif(5);
-       r7s72100_register_scif(6);
-       r7s72100_register_scif(7);
-}
-
-static const char * const genmai_boards_compat_dt[] __initconst = {
-       "renesas,genmai",
-       NULL,
-};
-
-DT_MACHINE_START(GENMAI_DT, "genmai")
-       .init_early     = shmobile_init_delay,
-       .init_machine   = genmai_add_standard_devices,
-       .dt_compat      = genmai_boards_compat_dt,
-MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-koelsch-reference.c b/arch/arm/mach-shmobile/board-koelsch-reference.c
deleted file mode 100644 (file)
index 3ff88c1..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Koelsch board support - Reference DT implementation
- *
- * Copyright (C) 2013  Renesas Electronics Corporation
- * Copyright (C) 2013  Renesas Solutions Corp.
- * Copyright (C) 2013  Magnus Damm
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <linux/dma-mapping.h>
-#include <linux/kernel.h>
-#include <linux/of_platform.h>
-#include <linux/platform_data/rcar-du.h>
-
-#include <asm/mach/arch.h>
-
-#include "clock.h"
-#include "common.h"
-#include "irqs.h"
-#include "r8a7791.h"
-#include "rcar-gen2.h"
-
-/* DU */
-static struct rcar_du_encoder_data koelsch_du_encoders[] = {
-       {
-               .type = RCAR_DU_ENCODER_NONE,
-               .output = RCAR_DU_OUTPUT_LVDS0,
-               .connector.lvds.panel = {
-                       .width_mm = 210,
-                       .height_mm = 158,
-                       .mode = {
-                               .clock = 65000,
-                               .hdisplay = 1024,
-                               .hsync_start = 1048,
-                               .hsync_end = 1184,
-                               .htotal = 1344,
-                               .vdisplay = 768,
-                               .vsync_start = 771,
-                               .vsync_end = 777,
-                               .vtotal = 806,
-                               .flags = 0,
-                       },
-               },
-       },
-};
-
-static struct rcar_du_platform_data koelsch_du_pdata = {
-       .encoders = koelsch_du_encoders,
-       .num_encoders = ARRAY_SIZE(koelsch_du_encoders),
-};
-
-static const struct resource du_resources[] __initconst = {
-       DEFINE_RES_MEM(0xfeb00000, 0x40000),
-       DEFINE_RES_MEM_NAMED(0xfeb90000, 0x1c, "lvds.0"),
-       DEFINE_RES_IRQ(gic_spi(256)),
-       DEFINE_RES_IRQ(gic_spi(268)),
-};
-
-static void __init koelsch_add_du_device(void)
-{
-       struct platform_device_info info = {
-               .name = "rcar-du-r8a7791",
-               .id = -1,
-               .res = du_resources,
-               .num_res = ARRAY_SIZE(du_resources),
-               .data = &koelsch_du_pdata,
-               .size_data = sizeof(koelsch_du_pdata),
-               .dma_mask = DMA_BIT_MASK(32),
-       };
-
-       platform_device_register_full(&info);
-}
-
-/*
- * This is a really crude hack to provide clkdev support to platform
- * devices until they get moved to DT.
- */
-static const struct clk_name clk_names[] __initconst = {
-       { "cmt0", "fck", "sh-cmt-48-gen2.0" },
-       { "du0", "du.0", "rcar-du-r8a7791" },
-       { "du1", "du.1", "rcar-du-r8a7791" },
-       { "lvds0", "lvds.0", "rcar-du-r8a7791" },
-};
-
-static void __init koelsch_add_standard_devices(void)
-{
-       shmobile_clk_workaround(clk_names, ARRAY_SIZE(clk_names), false);
-       r8a7791_add_dt_devices();
-       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
-
-       koelsch_add_du_device();
-}
-
-static const char * const koelsch_boards_compat_dt[] __initconst = {
-       "renesas,koelsch",
-       "renesas,koelsch-reference",
-       NULL,
-};
-
-DT_MACHINE_START(KOELSCH_DT, "koelsch")
-       .smp            = smp_ops(r8a7791_smp_ops),
-       .init_early     = shmobile_init_delay,
-       .init_time      = rcar_gen2_timer_init,
-       .init_machine   = koelsch_add_standard_devices,
-       .init_late      = shmobile_init_late,
-       .reserve        = rcar_gen2_reserve,
-       .dt_compat      = koelsch_boards_compat_dt,
-MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-koelsch.c b/arch/arm/mach-shmobile/board-koelsch.c
deleted file mode 100644 (file)
index 2cd3194..0000000
+++ /dev/null
@@ -1,533 +0,0 @@
-/*
- * Koelsch board support
- *
- * Copyright (C) 2013  Renesas Electronics Corporation
- * Copyright (C) 2013-2014  Renesas Solutions Corp.
- * Copyright (C) 2013  Magnus Damm
- * Copyright (C) 2014  Cogent Embedded, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <linux/dma-mapping.h>
-#include <linux/gpio.h>
-#include <linux/gpio_keys.h>
-#include <linux/input.h>
-#include <linux/irq.h>
-#include <linux/kernel.h>
-#include <linux/leds.h>
-#include <linux/mfd/tmio.h>
-#include <linux/mmc/host.h>
-#include <linux/mmc/sh_mobile_sdhi.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-#include <linux/phy.h>
-#include <linux/pinctrl/machine.h>
-#include <linux/platform_data/gpio-rcar.h>
-#include <linux/platform_data/rcar-du.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/driver.h>
-#include <linux/regulator/fixed.h>
-#include <linux/regulator/gpio-regulator.h>
-#include <linux/regulator/machine.h>
-#include <linux/sh_eth.h>
-#include <linux/spi/flash.h>
-#include <linux/spi/rspi.h>
-#include <linux/spi/spi.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-
-#include "common.h"
-#include "irqs.h"
-#include "r8a7791.h"
-#include "rcar-gen2.h"
-
-/* DU */
-static struct rcar_du_encoder_data koelsch_du_encoders[] = {
-       {
-               .type = RCAR_DU_ENCODER_NONE,
-               .output = RCAR_DU_OUTPUT_LVDS0,
-               .connector.lvds.panel = {
-                       .width_mm = 210,
-                       .height_mm = 158,
-                       .mode = {
-                               .clock = 65000,
-                               .hdisplay = 1024,
-                               .hsync_start = 1048,
-                               .hsync_end = 1184,
-                               .htotal = 1344,
-                               .vdisplay = 768,
-                               .vsync_start = 771,
-                               .vsync_end = 777,
-                               .vtotal = 806,
-                               .flags = 0,
-                       },
-               },
-       },
-};
-
-static const struct rcar_du_platform_data koelsch_du_pdata __initconst = {
-       .encoders = koelsch_du_encoders,
-       .num_encoders = ARRAY_SIZE(koelsch_du_encoders),
-};
-
-static const struct resource du_resources[] __initconst = {
-       DEFINE_RES_MEM(0xfeb00000, 0x40000),
-       DEFINE_RES_MEM_NAMED(0xfeb90000, 0x1c, "lvds.0"),
-       DEFINE_RES_IRQ(gic_spi(256)),
-       DEFINE_RES_IRQ(gic_spi(268)),
-};
-
-static void __init koelsch_add_du_device(void)
-{
-       struct platform_device_info info = {
-               .name = "rcar-du-r8a7791",
-               .id = -1,
-               .res = du_resources,
-               .num_res = ARRAY_SIZE(du_resources),
-               .data = &koelsch_du_pdata,
-               .size_data = sizeof(koelsch_du_pdata),
-               .dma_mask = DMA_BIT_MASK(32),
-       };
-
-       platform_device_register_full(&info);
-}
-
-/* Ether */
-static const struct sh_eth_plat_data ether_pdata __initconst = {
-       .phy                    = 0x1,
-       .phy_irq                = irq_pin(0),
-       .edmac_endian           = EDMAC_LITTLE_ENDIAN,
-       .phy_interface          = PHY_INTERFACE_MODE_RMII,
-       .ether_link_active_low  = 1,
-};
-
-static const struct resource ether_resources[] __initconst = {
-       DEFINE_RES_MEM(0xee700000, 0x400),
-       DEFINE_RES_IRQ(gic_spi(162)),
-};
-
-static const struct platform_device_info ether_info __initconst = {
-       .parent         = &platform_bus,
-       .name           = "r8a7791-ether",
-       .id             = -1,
-       .res            = ether_resources,
-       .num_res        = ARRAY_SIZE(ether_resources),
-       .data           = &ether_pdata,
-       .size_data      = sizeof(ether_pdata),
-       .dma_mask       = DMA_BIT_MASK(32),
-};
-
-/* LEDS */
-static struct gpio_led koelsch_leds[] = {
-       {
-               .name           = "led8",
-               .gpio           = RCAR_GP_PIN(2, 21),
-               .default_state  = LEDS_GPIO_DEFSTATE_ON,
-       }, {
-               .name           = "led7",
-               .gpio           = RCAR_GP_PIN(2, 20),
-               .default_state  = LEDS_GPIO_DEFSTATE_ON,
-       }, {
-               .name           = "led6",
-               .gpio           = RCAR_GP_PIN(2, 19),
-               .default_state  = LEDS_GPIO_DEFSTATE_ON,
-       },
-};
-
-static const struct gpio_led_platform_data koelsch_leds_pdata __initconst = {
-       .leds           = koelsch_leds,
-       .num_leds       = ARRAY_SIZE(koelsch_leds),
-};
-
-/* GPIO KEY */
-#define GPIO_KEY(c, g, d, ...) \
-       { .code = c, .gpio = g, .desc = d, .active_low = 1, \
-         .wakeup = 1, .debounce_interval = 20 }
-
-static struct gpio_keys_button gpio_buttons[] = {
-       GPIO_KEY(KEY_4,         RCAR_GP_PIN(5, 3),      "SW2-pin4"),
-       GPIO_KEY(KEY_3,         RCAR_GP_PIN(5, 2),      "SW2-pin3"),
-       GPIO_KEY(KEY_2,         RCAR_GP_PIN(5, 1),      "SW2-pin2"),
-       GPIO_KEY(KEY_1,         RCAR_GP_PIN(5, 0),      "SW2-pin1"),
-       GPIO_KEY(KEY_G,         RCAR_GP_PIN(7, 6),      "SW36"),
-       GPIO_KEY(KEY_F,         RCAR_GP_PIN(7, 5),      "SW35"),
-       GPIO_KEY(KEY_E,         RCAR_GP_PIN(7, 4),      "SW34"),
-       GPIO_KEY(KEY_D,         RCAR_GP_PIN(7, 3),      "SW33"),
-       GPIO_KEY(KEY_C,         RCAR_GP_PIN(7, 2),      "SW32"),
-       GPIO_KEY(KEY_B,         RCAR_GP_PIN(7, 1),      "SW31"),
-       GPIO_KEY(KEY_A,         RCAR_GP_PIN(7, 0),      "SW30"),
-};
-
-static const struct gpio_keys_platform_data koelsch_keys_pdata __initconst = {
-       .buttons        = gpio_buttons,
-       .nbuttons       = ARRAY_SIZE(gpio_buttons),
-};
-
-/* QSPI */
-static const struct resource qspi_resources[] __initconst = {
-       DEFINE_RES_MEM(0xe6b10000, 0x1000),
-       DEFINE_RES_IRQ_NAMED(gic_spi(184), "mux"),
-};
-
-static const struct rspi_plat_data qspi_pdata __initconst = {
-       .num_chipselect = 1,
-};
-
-/* SPI Flash memory (Spansion S25FL512SAGMFIG11 64 MiB) */
-static struct mtd_partition spi_flash_part[] = {
-       {
-               .name           = "loader",
-               .offset         = 0x00000000,
-               .size           = 512 * 1024,
-               .mask_flags     = MTD_WRITEABLE,
-       },
-       {
-               .name           = "bootenv",
-               .offset         = MTDPART_OFS_APPEND,
-               .size           = 512 * 1024,
-               .mask_flags     = MTD_WRITEABLE,
-       },
-       {
-               .name           = "data",
-               .offset         = MTDPART_OFS_APPEND,
-               .size           = MTDPART_SIZ_FULL,
-       },
-};
-
-static const struct flash_platform_data spi_flash_data = {
-       .name           = "m25p80",
-       .parts          = spi_flash_part,
-       .nr_parts       = ARRAY_SIZE(spi_flash_part),
-       .type           = "s25fl512s",
-};
-
-static const struct spi_board_info spi_info[] __initconst = {
-       {
-               .modalias       = "m25p80",
-               .platform_data  = &spi_flash_data,
-               .mode           = SPI_MODE_0 | SPI_TX_QUAD | SPI_RX_QUAD,
-               .max_speed_hz   = 30000000,
-               .bus_num        = 0,
-               .chip_select    = 0,
-       },
-};
-
-/* SATA0 */
-static const struct resource sata0_resources[] __initconst = {
-       DEFINE_RES_MEM(0xee300000, 0x2000),
-       DEFINE_RES_IRQ(gic_spi(105)),
-};
-
-static const struct platform_device_info sata0_info __initconst = {
-       .parent         = &platform_bus,
-       .name           = "sata-r8a7791",
-       .id             = 0,
-       .res            = sata0_resources,
-       .num_res        = ARRAY_SIZE(sata0_resources),
-       .dma_mask       = DMA_BIT_MASK(32),
-};
-
-/* I2C */
-static const struct resource i2c_resources[] __initconst = {
-       /* I2C0 */
-       DEFINE_RES_MEM(0xE6508000, 0x40),
-       DEFINE_RES_IRQ(gic_spi(287)),
-       /* I2C1 */
-       DEFINE_RES_MEM(0xE6518000, 0x40),
-       DEFINE_RES_IRQ(gic_spi(288)),
-       /* I2C2 */
-       DEFINE_RES_MEM(0xE6530000, 0x40),
-       DEFINE_RES_IRQ(gic_spi(286)),
-       /* I2C3 */
-       DEFINE_RES_MEM(0xE6540000, 0x40),
-       DEFINE_RES_IRQ(gic_spi(290)),
-       /* I2C4 */
-       DEFINE_RES_MEM(0xE6520000, 0x40),
-       DEFINE_RES_IRQ(gic_spi(19)),
-       /* I2C5 */
-       DEFINE_RES_MEM(0xE6528000, 0x40),
-       DEFINE_RES_IRQ(gic_spi(20)),
-};
-
-static void __init koelsch_add_i2c(unsigned idx)
-{
-       unsigned res_idx = idx * 2;
-
-       BUG_ON(res_idx >= ARRAY_SIZE(i2c_resources));
-
-       platform_device_register_simple("i2c-rcar_gen2", idx,
-                                       i2c_resources + res_idx, 2);
-}
-
-#define SDHI_REGULATOR(idx, vdd_pin, vccq_pin)                         \
-static struct regulator_consumer_supply vcc_sdhi##idx##_consumer =     \
-       REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi." #idx);               \
-                                                                       \
-static struct regulator_init_data vcc_sdhi##idx##_init_data = {                \
-       .constraints = {                                                \
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,              \
-       },                                                              \
-       .consumer_supplies      = &vcc_sdhi##idx##_consumer,            \
-       .num_consumer_supplies  = 1,                                    \
-};                                                                     \
-                                                                       \
-static const struct fixed_voltage_config vcc_sdhi##idx##_info __initconst = {\
-       .supply_name    = "SDHI" #idx "Vcc",                            \
-       .microvolts     = 3300000,                                      \
-       .gpio           = vdd_pin,                                      \
-       .enable_high    = 1,                                            \
-       .init_data      = &vcc_sdhi##idx##_init_data,                   \
-};                                                                     \
-                                                                       \
-static struct regulator_consumer_supply vccq_sdhi##idx##_consumer =    \
-       REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi." #idx);              \
-                                                                       \
-static struct regulator_init_data vccq_sdhi##idx##_init_data = {       \
-       .constraints = {                                                \
-               .input_uV       = 3300000,                              \
-               .min_uV         = 1800000,                              \
-               .max_uV         = 3300000,                              \
-               .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |            \
-                                 REGULATOR_CHANGE_STATUS,              \
-       },                                                              \
-       .consumer_supplies      = &vccq_sdhi##idx##_consumer,           \
-       .num_consumer_supplies  = 1,                                    \
-};                                                                     \
-                                                                       \
-static struct gpio vccq_sdhi##idx##_gpio =                             \
-       { vccq_pin, GPIOF_OUT_INIT_HIGH, "vccq-sdhi" #idx };            \
-                                                                       \
-static struct gpio_regulator_state vccq_sdhi##idx##_states[] = {       \
-       { .value = 1800000, .gpios = 0 },                               \
-       { .value = 3300000, .gpios = 1 },                               \
-};                                                                     \
-                                                                       \
-static const struct gpio_regulator_config vccq_sdhi##idx##_info __initconst = {\
-       .supply_name    = "vqmmc",                                      \
-       .gpios          = &vccq_sdhi##idx##_gpio,                       \
-       .nr_gpios       = 1,                                            \
-       .states         = vccq_sdhi##idx##_states,                      \
-       .nr_states      = ARRAY_SIZE(vccq_sdhi##idx##_states),          \
-       .type           = REGULATOR_VOLTAGE,                            \
-       .init_data      = &vccq_sdhi##idx##_init_data,                  \
-};
-
-SDHI_REGULATOR(0, RCAR_GP_PIN(7, 17), RCAR_GP_PIN(2, 12));
-SDHI_REGULATOR(1, RCAR_GP_PIN(7, 18), RCAR_GP_PIN(2, 13));
-SDHI_REGULATOR(2, RCAR_GP_PIN(7, 19), RCAR_GP_PIN(2, 26));
-
-/* SDHI0 */
-static struct sh_mobile_sdhi_info sdhi0_info __initdata = {
-       .tmio_caps      = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
-                         MMC_CAP_POWER_OFF_CARD,
-       .tmio_caps2     = MMC_CAP2_NO_MULTI_READ,
-       .tmio_flags     = TMIO_MMC_HAS_IDLE_WAIT,
-};
-
-static struct resource sdhi0_resources[] __initdata = {
-       DEFINE_RES_MEM(0xee100000, 0x200),
-       DEFINE_RES_IRQ(gic_spi(165)),
-};
-
-/* SDHI1 */
-static struct sh_mobile_sdhi_info sdhi1_info __initdata = {
-       .tmio_caps      = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
-                         MMC_CAP_POWER_OFF_CARD,
-       .tmio_caps2     = MMC_CAP2_NO_MULTI_READ,
-       .tmio_flags     = TMIO_MMC_HAS_IDLE_WAIT,
-};
-
-static struct resource sdhi1_resources[] __initdata = {
-       DEFINE_RES_MEM(0xee140000, 0x100),
-       DEFINE_RES_IRQ(gic_spi(167)),
-};
-
-/* SDHI2 */
-static struct sh_mobile_sdhi_info sdhi2_info __initdata = {
-       .tmio_caps      = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
-                         MMC_CAP_POWER_OFF_CARD,
-       .tmio_caps2     = MMC_CAP2_NO_MULTI_READ,
-       .tmio_flags     = TMIO_MMC_HAS_IDLE_WAIT |
-                         TMIO_MMC_WRPROTECT_DISABLE,
-};
-
-static struct resource sdhi2_resources[] __initdata = {
-       DEFINE_RES_MEM(0xee160000, 0x100),
-       DEFINE_RES_IRQ(gic_spi(168)),
-};
-
-static const struct pinctrl_map koelsch_pinctrl_map[] = {
-       /* DU */
-       PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7791", "pfc-r8a7791",
-                                 "du_rgb666", "du"),
-       PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7791", "pfc-r8a7791",
-                                 "du_sync", "du"),
-       PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7791", "pfc-r8a7791",
-                                 "du_clk_out_0", "du"),
-       /* Ether */
-       PIN_MAP_MUX_GROUP_DEFAULT("r8a7791-ether", "pfc-r8a7791",
-                                 "eth_link", "eth"),
-       PIN_MAP_MUX_GROUP_DEFAULT("r8a7791-ether", "pfc-r8a7791",
-                                 "eth_mdio", "eth"),
-       PIN_MAP_MUX_GROUP_DEFAULT("r8a7791-ether", "pfc-r8a7791",
-                                 "eth_rmii", "eth"),
-       PIN_MAP_MUX_GROUP_DEFAULT("r8a7791-ether", "pfc-r8a7791",
-                                 "intc_irq0", "intc"),
-       /* QSPI */
-       PIN_MAP_MUX_GROUP_DEFAULT("qspi.0", "pfc-r8a7791",
-                                 "qspi_ctrl", "qspi"),
-       PIN_MAP_MUX_GROUP_DEFAULT("qspi.0", "pfc-r8a7791",
-                                 "qspi_data4", "qspi"),
-       /* SCIF0 (CN19: DEBUG SERIAL0) */
-       PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.6", "pfc-r8a7791",
-                                 "scif0_data_d", "scif0"),
-       /* SCIF1 (CN20: DEBUG SERIAL1) */
-       PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.7", "pfc-r8a7791",
-                                 "scif1_data_d", "scif1"),
-       /* I2C1 */
-       PIN_MAP_MUX_GROUP_DEFAULT("i2c-rcar_gen2.1", "pfc-r8a7791",
-                                 "i2c1_e", "i2c1"),
-       /* I2C2 */
-       PIN_MAP_MUX_GROUP_DEFAULT("i2c-rcar_gen2.2", "pfc-r8a7791",
-                                 "i2c2", "i2c2"),
-       /* I2C4 */
-       PIN_MAP_MUX_GROUP_DEFAULT("i2c-rcar_gen2.4", "pfc-r8a7791",
-                                 "i2c4_c", "i2c4"),
-       /* SDHI0 */
-       PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7791",
-                                 "sdhi0_data4", "sdhi0"),
-       PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7791",
-                                 "sdhi0_ctrl", "sdhi0"),
-       PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7791",
-                                 "sdhi0_cd", "sdhi0"),
-       PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7791",
-                                 "sdhi0_wp", "sdhi0"),
-       /* SDHI2 */
-       PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.1", "pfc-r8a7791",
-                                 "sdhi1_data4", "sdhi1"),
-       PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.1", "pfc-r8a7791",
-                                 "sdhi1_ctrl", "sdhi1"),
-       PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.1", "pfc-r8a7791",
-                                 "sdhi1_cd", "sdhi1"),
-       PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.1", "pfc-r8a7791",
-                                 "sdhi1_wp", "sdhi1"),
-       /* SDHI2 */
-       PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.2", "pfc-r8a7791",
-                                 "sdhi2_data4", "sdhi2"),
-       PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.2", "pfc-r8a7791",
-                                 "sdhi2_ctrl", "sdhi2"),
-       PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.2", "pfc-r8a7791",
-                                 "sdhi2_cd", "sdhi2"),
-};
-
-static void __init koelsch_add_standard_devices(void)
-{
-       r8a7791_clock_init();
-       pinctrl_register_mappings(koelsch_pinctrl_map,
-                                 ARRAY_SIZE(koelsch_pinctrl_map));
-       r8a7791_pinmux_init();
-       r8a7791_add_standard_devices();
-       platform_device_register_full(&ether_info);
-       platform_device_register_data(&platform_bus, "leds-gpio", -1,
-                                     &koelsch_leds_pdata,
-                                     sizeof(koelsch_leds_pdata));
-       platform_device_register_data(&platform_bus, "gpio-keys", -1,
-                                     &koelsch_keys_pdata,
-                                     sizeof(koelsch_keys_pdata));
-       platform_device_register_resndata(&platform_bus, "qspi", 0,
-                                         qspi_resources,
-                                         ARRAY_SIZE(qspi_resources),
-                                         &qspi_pdata, sizeof(qspi_pdata));
-       spi_register_board_info(spi_info, ARRAY_SIZE(spi_info));
-
-       koelsch_add_du_device();
-
-       platform_device_register_full(&sata0_info);
-
-       koelsch_add_i2c(1);
-       koelsch_add_i2c(2);
-       koelsch_add_i2c(4);
-       koelsch_add_i2c(5);
-
-       platform_device_register_data(&platform_bus, "reg-fixed-voltage", 0,
-                                     &vcc_sdhi0_info, sizeof(struct fixed_voltage_config));
-       platform_device_register_data(&platform_bus, "reg-fixed-voltage", 1,
-                                     &vcc_sdhi1_info, sizeof(struct fixed_voltage_config));
-       platform_device_register_data(&platform_bus, "reg-fixed-voltage", 2,
-                                     &vcc_sdhi2_info, sizeof(struct fixed_voltage_config));
-       platform_device_register_data(&platform_bus, "gpio-regulator", 0,
-                                     &vccq_sdhi0_info, sizeof(struct gpio_regulator_config));
-       platform_device_register_data(&platform_bus, "gpio-regulator", 1,
-                                     &vccq_sdhi1_info, sizeof(struct gpio_regulator_config));
-       platform_device_register_data(&platform_bus, "gpio-regulator", 2,
-                                     &vccq_sdhi2_info, sizeof(struct gpio_regulator_config));
-
-       platform_device_register_resndata(&platform_bus, "sh_mobile_sdhi", 0,
-                                         sdhi0_resources, ARRAY_SIZE(sdhi0_resources),
-                                         &sdhi0_info, sizeof(struct sh_mobile_sdhi_info));
-
-       platform_device_register_resndata(&platform_bus, "sh_mobile_sdhi", 1,
-                                         sdhi1_resources, ARRAY_SIZE(sdhi1_resources),
-                                         &sdhi1_info, sizeof(struct sh_mobile_sdhi_info));
-
-       platform_device_register_resndata(&platform_bus, "sh_mobile_sdhi", 2,
-                                         sdhi2_resources, ARRAY_SIZE(sdhi2_resources),
-                                         &sdhi2_info, sizeof(struct sh_mobile_sdhi_info));
-
-}
-
-/*
- * Ether LEDs on the Koelsch board are named LINK and ACTIVE which corresponds
- * to non-default 01 setting of the Micrel KSZ8041 PHY control register 1 bits
- * 14-15. We have to set them back to 01 from the default 00 value each time
- * the PHY is reset. It's also important because the PHY's LED0 signal is
- * connected to SoC's ETH_LINK signal and in the PHY's default mode it will
- * bounce on and off after each packet, which we apparently want to avoid.
- */
-static int koelsch_ksz8041_fixup(struct phy_device *phydev)
-{
-       u16 phyctrl1 = phy_read(phydev, 0x1e);
-
-       phyctrl1 &= ~0xc000;
-       phyctrl1 |= 0x4000;
-       return phy_write(phydev, 0x1e, phyctrl1);
-}
-
-static void __init koelsch_init(void)
-{
-       koelsch_add_standard_devices();
-
-       irq_set_irq_type(irq_pin(0), IRQ_TYPE_LEVEL_LOW);
-
-       if (IS_ENABLED(CONFIG_PHYLIB))
-               phy_register_fixup_for_id("r8a7791-ether-ff:01",
-                                         koelsch_ksz8041_fixup);
-}
-
-static const char * const koelsch_boards_compat_dt[] __initconst = {
-       "renesas,koelsch",
-       NULL,
-};
-
-DT_MACHINE_START(KOELSCH_DT, "koelsch")
-       .smp            = smp_ops(r8a7791_smp_ops),
-       .init_early     = shmobile_init_delay,
-       .init_time      = rcar_gen2_timer_init,
-       .init_machine   = koelsch_init,
-       .init_late      = shmobile_init_late,
-       .reserve        = rcar_gen2_reserve,
-       .dt_compat      = koelsch_boards_compat_dt,
-MACHINE_END
index 95307cd..359debb 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
 #include <linux/delay.h>
@@ -43,6 +39,13 @@ static void __init kzm_init(void)
 #endif
 }
 
+#define RESCNT2 IOMEM(0xe6188020)
+static void kzm9g_restart(enum reboot_mode mode, const char *cmd)
+{
+       /* Do soft power on reset */
+       writel((1 << 31), RESCNT2);
+}
+
 static const char *kzm9g_boards_compat_dt[] __initdata = {
        "renesas,kzm9g-reference",
        NULL,
@@ -51,8 +54,9 @@ static const char *kzm9g_boards_compat_dt[] __initdata = {
 DT_MACHINE_START(KZM9G_DT, "kzm9g-reference")
        .smp            = smp_ops(sh73a0_smp_ops),
        .map_io         = sh73a0_map_io,
-       .init_early     = sh73a0_init_delay,
-       .nr_irqs        = NR_IRQS_LEGACY,
+       .init_early     = shmobile_init_delay,
        .init_machine   = kzm_init,
+       .init_late      = shmobile_init_late,
+       .restart        = kzm9g_restart,
        .dt_compat      = kzm9g_boards_compat_dt,
 MACHINE_END
index c4336cc..f66f980 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
 #include <linux/delay.h>
@@ -50,6 +46,7 @@
 #include <video/sh_mobile_lcdc.h>
 
 #include "common.h"
+#include "intc.h"
 #include "irqs.h"
 #include "sh73a0.h"
 
@@ -910,7 +907,6 @@ DT_MACHINE_START(KZM9G_DT, "kzm9g")
        .smp            = smp_ops(sh73a0_smp_ops),
        .map_io         = sh73a0_map_io,
        .init_early     = sh73a0_add_early_devices,
-       .nr_irqs        = NR_IRQS_LEGACY,
        .init_irq       = sh73a0_init_irq,
        .init_machine   = kzm_init,
        .init_late      = shmobile_init_late,
index 41c808e..fa06bdb 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-#include <linux/dma-mapping.h>
 #include <linux/init.h>
 #include <linux/of_platform.h>
-#include <linux/platform_data/rcar-du.h>
 
 #include <asm/mach/arch.h>
 
-#include "clock.h"
 #include "common.h"
-#include "irqs.h"
 #include "r8a7790.h"
 #include "rcar-gen2.h"
 
-/* DU */
-static struct rcar_du_encoder_data lager_du_encoders[] = {
-       {
-               .type = RCAR_DU_ENCODER_VGA,
-               .output = RCAR_DU_OUTPUT_DPAD0,
-       }, {
-               .type = RCAR_DU_ENCODER_NONE,
-               .output = RCAR_DU_OUTPUT_LVDS1,
-               .connector.lvds.panel = {
-                       .width_mm = 210,
-                       .height_mm = 158,
-                       .mode = {
-                               .clock = 65000,
-                               .hdisplay = 1024,
-                               .hsync_start = 1048,
-                               .hsync_end = 1184,
-                               .htotal = 1344,
-                               .vdisplay = 768,
-                               .vsync_start = 771,
-                               .vsync_end = 777,
-                               .vtotal = 806,
-                               .flags = 0,
-                       },
-               },
-       },
-};
-
-static struct rcar_du_platform_data lager_du_pdata = {
-       .encoders = lager_du_encoders,
-       .num_encoders = ARRAY_SIZE(lager_du_encoders),
-};
-
-static const struct resource du_resources[] __initconst = {
-       DEFINE_RES_MEM(0xfeb00000, 0x70000),
-       DEFINE_RES_MEM_NAMED(0xfeb90000, 0x1c, "lvds.0"),
-       DEFINE_RES_MEM_NAMED(0xfeb94000, 0x1c, "lvds.1"),
-       DEFINE_RES_IRQ(gic_spi(256)),
-       DEFINE_RES_IRQ(gic_spi(268)),
-       DEFINE_RES_IRQ(gic_spi(269)),
-};
-
-static void __init lager_add_du_device(void)
-{
-       struct platform_device_info info = {
-               .name = "rcar-du-r8a7790",
-               .id = -1,
-               .res = du_resources,
-               .num_res = ARRAY_SIZE(du_resources),
-               .data = &lager_du_pdata,
-               .size_data = sizeof(lager_du_pdata),
-               .dma_mask = DMA_BIT_MASK(32),
-       };
-
-       platform_device_register_full(&info);
-}
-
-/*
- * This is a really crude hack to provide clkdev support to platform
- * devices until they get moved to DT.
- */
-static const struct clk_name clk_names[] __initconst = {
-       { "cmt0", "fck", "sh-cmt-48-gen2.0" },
-       { "du0", "du.0", "rcar-du-r8a7790" },
-       { "du1", "du.1", "rcar-du-r8a7790" },
-       { "du2", "du.2", "rcar-du-r8a7790" },
-       { "lvds0", "lvds.0", "rcar-du-r8a7790" },
-       { "lvds1", "lvds.1", "rcar-du-r8a7790" },
-};
-
-static void __init lager_add_standard_devices(void)
-{
-       shmobile_clk_workaround(clk_names, ARRAY_SIZE(clk_names), false);
-       r8a7790_add_dt_devices();
-       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
-
-       lager_add_du_device();
-}
-
 static const char *lager_boards_compat_dt[] __initdata = {
        "renesas,lager",
        "renesas,lager-reference",
@@ -119,7 +33,6 @@ DT_MACHINE_START(LAGER_DT, "lager")
        .smp            = smp_ops(r8a7790_smp_ops),
        .init_early     = shmobile_init_delay,
        .init_time      = rcar_gen2_timer_init,
-       .init_machine   = lager_add_standard_devices,
        .init_late      = shmobile_init_late,
        .reserve        = rcar_gen2_reserve,
        .dt_compat      = lager_boards_compat_dt,
index b8b2b44..64abf61 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
 #include <linux/gpio.h>
@@ -99,16 +95,15 @@ static struct rcar_du_encoder_data lager_du_encoders[] = {
                        .width_mm = 210,
                        .height_mm = 158,
                        .mode = {
-                               .clock = 65000,
-                               .hdisplay = 1024,
-                               .hsync_start = 1048,
-                               .hsync_end = 1184,
-                               .htotal = 1344,
-                               .vdisplay = 768,
-                               .vsync_start = 771,
-                               .vsync_end = 777,
-                               .vtotal = 806,
-                               .flags = 0,
+                               .pixelclock = 65000000,
+                               .hactive = 1024,
+                               .hfront_porch = 20,
+                               .hback_porch = 160,
+                               .hsync_len = 136,
+                               .vactive = 768,
+                               .vfront_porch = 3,
+                               .vback_porch = 29,
+                               .vsync_len = 6,
                        },
                },
        },
@@ -634,7 +629,6 @@ static void __init lager_add_rsnd_device(void)
 static struct sh_mobile_sdhi_info sdhi0_info __initdata = {
        .tmio_caps      = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
                          MMC_CAP_POWER_OFF_CARD,
-       .tmio_caps2     = MMC_CAP2_NO_MULTI_READ,
        .tmio_flags     = TMIO_MMC_HAS_IDLE_WAIT |
                          TMIO_MMC_WRPROTECT_DISABLE,
 };
@@ -648,7 +642,6 @@ static struct resource sdhi0_resources[] __initdata = {
 static struct sh_mobile_sdhi_info sdhi2_info __initdata = {
        .tmio_caps      = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
                          MMC_CAP_POWER_OFF_CARD,
-       .tmio_caps2     = MMC_CAP2_NO_MULTI_READ,
        .tmio_flags     = TMIO_MMC_HAS_IDLE_WAIT |
                          TMIO_MMC_WRPROTECT_DISABLE,
 };
index 79f448e..ed10870 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 #include <linux/delay.h>
 #include <linux/kernel.h>
@@ -63,6 +59,7 @@
 #include <asm/mach-types.h>
 
 #include "common.h"
+#include "intc.h"
 #include "irqs.h"
 #include "pm-rmobile.h"
 #include "sh-gpio.h"
@@ -1420,7 +1417,7 @@ static const struct pinctrl_map mackerel_pinctrl_map[] = {
 #define USCCR1         IOMEM(0xE6058144)
 static void __init mackerel_init(void)
 {
-       struct pm_domain_device domain_devices[] = {
+       static struct pm_domain_device domain_devices[] __initdata = {
                { "A4LC", &lcdc_device, },
                { "A4LC", &hdmi_lcdc_device, },
                { "A4LC", &meram_device, },
index 21b3e1c..b15eb92 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
 #include <linux/clk/shmobile.h>
@@ -26,7 +22,6 @@
 #include <asm/irq.h>
 #include <asm/mach/arch.h>
 
-#include "clock.h"
 #include "common.h"
 #include "irqs.h"
 #include "r8a7779.h"
@@ -37,18 +32,8 @@ static void __init marzen_init_timer(void)
        clocksource_of_init();
 }
 
-/*
- * This is a really crude hack to provide clkdev support to platform
- * devices until they get moved to DT.
- */
-static const struct clk_name clk_names[] __initconst = {
-       { "tmu0", "fck", "sh-tmu.0" },
-};
-
 static void __init marzen_init(void)
 {
-       shmobile_clk_workaround(clk_names, ARRAY_SIZE(clk_names), false);
-       r8a7779_add_standard_devices_dt();
        of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
        r8a7779_init_irq_extpin_dt(1); /* IRQ1 as individual interrupt */
 }
@@ -64,8 +49,8 @@ DT_MACHINE_START(MARZEN, "marzen")
        .map_io         = r8a7779_map_io,
        .init_early     = shmobile_init_delay,
        .init_time      = marzen_init_timer,
-       .nr_irqs        = NR_IRQS_LEGACY,
        .init_irq       = r8a7779_init_irq_dt,
        .init_machine   = marzen_init,
+       .init_late      = shmobile_init_late,
        .dt_compat      = marzen_boards_compat_dt,
 MACHINE_END
index 25a1037..891650e 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
 #include <linux/kernel.h>
@@ -192,16 +188,15 @@ static struct rcar_du_encoder_data du_encoders[] = {
                        .width_mm = 210,
                        .height_mm = 158,
                        .mode = {
-                               .clock = 65000,
-                               .hdisplay = 1024,
-                               .hsync_start = 1048,
-                               .hsync_end = 1184,
-                               .htotal = 1344,
-                               .vdisplay = 768,
-                               .vsync_start = 771,
-                               .vsync_end = 777,
-                               .vtotal = 806,
-                               .flags = 0,
+                               .pixelclock = 65000000,
+                               .hactive = 1024,
+                               .hfront_porch = 20,
+                               .hback_porch = 160,
+                               .hsync_len = 136,
+                               .vactive = 768,
+                               .vfront_porch = 3,
+                               .vback_porch = 29,
+                               .vsync_len = 6,
                        },
                },
        },
diff --git a/arch/arm/mach-shmobile/clock-r7s72100.c b/arch/arm/mach-shmobile/clock-r7s72100.c
deleted file mode 100644 (file)
index 3eb2ec4..0000000
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * r7a72100 clock framework support
- *
- * Copyright (C) 2013  Renesas Solutions Corp.
- * Copyright (C) 2012  Phil Edworthy
- * Copyright (C) 2011  Magnus Damm
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/io.h>
-#include <linux/sh_clk.h>
-#include <linux/clkdev.h>
-
-#include "common.h"
-#include "r7s72100.h"
-
-/* Frequency Control Registers */
-#define FRQCR          0xfcfe0010
-#define FRQCR2         0xfcfe0014
-/* Standby Control Registers */
-#define STBCR3         0xfcfe0420
-#define STBCR4         0xfcfe0424
-#define STBCR7         0xfcfe0430
-#define STBCR9         0xfcfe0438
-#define STBCR10                0xfcfe043c
-
-#define PLL_RATE 30
-
-static struct clk_mapping cpg_mapping = {
-       .phys   = 0xfcfe0000,
-       .len    = 0x1000,
-};
-
-/* Fixed 32 KHz root clock for RTC */
-static struct clk r_clk = {
-       .rate           = 32768,
-};
-
-/*
- * Default rate for the root input clock, reset this with clk_set_rate()
- * from the platform code.
- */
-static struct clk extal_clk = {
-       .rate           = 13330000,
-       .mapping        = &cpg_mapping,
-};
-
-static unsigned long pll_recalc(struct clk *clk)
-{
-       return clk->parent->rate * PLL_RATE;
-}
-
-static struct sh_clk_ops pll_clk_ops = {
-       .recalc         = pll_recalc,
-};
-
-static struct clk pll_clk = {
-       .ops            = &pll_clk_ops,
-       .parent         = &extal_clk,
-       .flags          = CLK_ENABLE_ON_INIT,
-};
-
-static unsigned long bus_recalc(struct clk *clk)
-{
-       return clk->parent->rate / 3;
-}
-
-static struct sh_clk_ops bus_clk_ops = {
-       .recalc         = bus_recalc,
-};
-
-static struct clk bus_clk = {
-       .ops            = &bus_clk_ops,
-       .parent         = &pll_clk,
-       .flags          = CLK_ENABLE_ON_INIT,
-};
-
-static unsigned long peripheral0_recalc(struct clk *clk)
-{
-       return clk->parent->rate / 12;
-}
-
-static struct sh_clk_ops peripheral0_clk_ops = {
-       .recalc         = peripheral0_recalc,
-};
-
-static struct clk peripheral0_clk = {
-       .ops            = &peripheral0_clk_ops,
-       .parent         = &pll_clk,
-       .flags          = CLK_ENABLE_ON_INIT,
-};
-
-static unsigned long peripheral1_recalc(struct clk *clk)
-{
-       return clk->parent->rate / 6;
-}
-
-static struct sh_clk_ops peripheral1_clk_ops = {
-       .recalc         = peripheral1_recalc,
-};
-
-static struct clk peripheral1_clk = {
-       .ops            = &peripheral1_clk_ops,
-       .parent         = &pll_clk,
-       .flags          = CLK_ENABLE_ON_INIT,
-};
-
-struct clk *main_clks[] = {
-       &r_clk,
-       &extal_clk,
-       &pll_clk,
-       &bus_clk,
-       &peripheral0_clk,
-       &peripheral1_clk,
-};
-
-static int div2[] = { 1, 3, 0, 3 }; /* 1, 2/3, reserve, 1/3 */
-static int multipliers[] = { 1, 2, 1, 1 };
-
-static struct clk_div_mult_table div4_div_mult_table = {
-       .divisors = div2,
-       .nr_divisors = ARRAY_SIZE(div2),
-       .multipliers = multipliers,
-       .nr_multipliers = ARRAY_SIZE(multipliers),
-};
-
-static struct clk_div4_table div4_table = {
-       .div_mult_table = &div4_div_mult_table,
-};
-
-enum { DIV4_I,
-       DIV4_NR };
-
-#define DIV4(_reg, _bit, _mask, _flags) \
-       SH_CLK_DIV4(&pll_clk, _reg, _bit, _mask, _flags)
-
-/* The mask field specifies the div2 entries that are valid */
-struct clk div4_clks[DIV4_NR] = {
-       [DIV4_I]  = DIV4(FRQCR, 8, 0xB, CLK_ENABLE_REG_16BIT
-                                       | CLK_ENABLE_ON_INIT),
-};
-
-enum {
-       MSTP107, MSTP106, MSTP105, MSTP104, MSTP103,
-       MSTP97, MSTP96, MSTP95, MSTP94,
-       MSTP74,
-       MSTP47, MSTP46, MSTP45, MSTP44, MSTP43, MSTP42, MSTP41, MSTP40,
-       MSTP33, MSTP_NR
-};
-
-static struct clk mstp_clks[MSTP_NR] = {
-       [MSTP107] = SH_CLK_MSTP8(&peripheral1_clk, STBCR10, 7, 0), /* RSPI0 */
-       [MSTP106] = SH_CLK_MSTP8(&peripheral1_clk, STBCR10, 6, 0), /* RSPI1 */
-       [MSTP105] = SH_CLK_MSTP8(&peripheral1_clk, STBCR10, 5, 0), /* RSPI2 */
-       [MSTP104] = SH_CLK_MSTP8(&peripheral1_clk, STBCR10, 4, 0), /* RSPI3 */
-       [MSTP103] = SH_CLK_MSTP8(&peripheral1_clk, STBCR10, 3, 0), /* RSPI4 */
-       [MSTP97] = SH_CLK_MSTP8(&peripheral0_clk, STBCR9, 7, 0), /* RIIC0 */
-       [MSTP96] = SH_CLK_MSTP8(&peripheral0_clk, STBCR9, 6, 0), /* RIIC1 */
-       [MSTP95] = SH_CLK_MSTP8(&peripheral0_clk, STBCR9, 5, 0), /* RIIC2 */
-       [MSTP94] = SH_CLK_MSTP8(&peripheral0_clk, STBCR9, 4, 0), /* RIIC3 */
-       [MSTP74] = SH_CLK_MSTP8(&peripheral1_clk, STBCR7, 4, 0), /* Ether */
-       [MSTP47] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 7, 0), /* SCIF0 */
-       [MSTP46] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 6, 0), /* SCIF1 */
-       [MSTP45] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 5, 0), /* SCIF2 */
-       [MSTP44] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 4, 0), /* SCIF3 */
-       [MSTP43] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 3, 0), /* SCIF4 */
-       [MSTP42] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 2, 0), /* SCIF5 */
-       [MSTP41] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 1, 0), /* SCIF6 */
-       [MSTP40] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 0, 0), /* SCIF7 */
-       [MSTP33] = SH_CLK_MSTP8(&peripheral0_clk, STBCR3, 3, 0), /* MTU2 */
-};
-
-static struct clk_lookup lookups[] = {
-       /* main clocks */
-       CLKDEV_CON_ID("rclk", &r_clk),
-       CLKDEV_CON_ID("extal", &extal_clk),
-       CLKDEV_CON_ID("pll_clk", &pll_clk),
-       CLKDEV_CON_ID("peripheral_clk", &peripheral1_clk),
-
-       /* DIV4 clocks */
-       CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),
-
-       /* MSTP clocks */
-       CLKDEV_DEV_ID("rspi-rz.0", &mstp_clks[MSTP107]),
-       CLKDEV_DEV_ID("rspi-rz.1", &mstp_clks[MSTP106]),
-       CLKDEV_DEV_ID("rspi-rz.2", &mstp_clks[MSTP105]),
-       CLKDEV_DEV_ID("rspi-rz.3", &mstp_clks[MSTP104]),
-       CLKDEV_DEV_ID("rspi-rz.4", &mstp_clks[MSTP103]),
-       CLKDEV_DEV_ID("r7s72100-ether", &mstp_clks[MSTP74]),
-
-       /* ICK */
-       CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP47]),
-       CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP46]),
-       CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP45]),
-       CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[MSTP44]),
-       CLKDEV_ICK_ID("sci_fck", "sh-sci.4", &mstp_clks[MSTP43]),
-       CLKDEV_ICK_ID("sci_fck", "sh-sci.5", &mstp_clks[MSTP42]),
-       CLKDEV_ICK_ID("sci_fck", "sh-sci.6", &mstp_clks[MSTP41]),
-       CLKDEV_ICK_ID("sci_fck", "sh-sci.7", &mstp_clks[MSTP40]),
-       CLKDEV_ICK_ID("fck", "sh-mtu2", &mstp_clks[MSTP33]),
-};
-
-void __init r7s72100_clock_init(void)
-{
-       int k, ret = 0;
-
-       for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
-               ret = clk_register(main_clks[k]);
-
-       clkdev_add_table(lookups, ARRAY_SIZE(lookups));
-
-       if (!ret)
-               ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
-
-       if (!ret)
-               ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
-
-       if (!ret)
-               shmobile_clk_init();
-       else
-               panic("failed to setup rza1 clocks\n");
-}
index c2330ea..1cf44dc 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 #include <linux/init.h>
 #include <linux/io.h>
index 0794f04..9cac824 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -455,7 +451,7 @@ enum {
        MSTP128, MSTP127, MSTP125,
        MSTP116, MSTP111, MSTP100, MSTP117,
 
-       MSTP230,
+       MSTP230, MSTP229,
        MSTP222,
        MSTP218, MSTP217, MSTP216, MSTP214,
        MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
@@ -474,11 +470,12 @@ static struct clk mstp_clks[MSTP_NR] = {
        [MSTP127] = SH_CLK_MSTP32(&div4_clks[DIV4_S],   SMSTPCR1, 27, 0), /* CEU20 */
        [MSTP125] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
        [MSTP117] = SH_CLK_MSTP32(&div4_clks[DIV4_B],   SMSTPCR1, 17, 0), /* LCDC1 */
-       [MSTP116] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */
+       [MSTP116] = SH_CLK_MSTP32(&div4_clks[DIV4_HPP], SMSTPCR1, 16, 0), /* IIC0 */
        [MSTP111] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR1, 11, 0), /* TMU1 */
        [MSTP100] = SH_CLK_MSTP32(&div4_clks[DIV4_B],   SMSTPCR1,  0, 0), /* LCDC0 */
 
        [MSTP230] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 30, 0), /* SCIFA6 */
+       [MSTP229] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR2, 29, 0), /* INTCA */
        [MSTP222] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 22, 0), /* SCIFA7 */
        [MSTP218] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR2, 18, 0), /* DMAC1 */
        [MSTP217] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],  SMSTPCR2, 17, 0), /* DMAC2 */
@@ -575,6 +572,10 @@ static struct clk_lookup lookups[] = {
        CLKDEV_DEV_ID("sh-dma-engine.0",        &mstp_clks[MSTP218]),
        CLKDEV_DEV_ID("sh-sci.7",               &mstp_clks[MSTP222]),
        CLKDEV_DEV_ID("e6cd0000.serial",        &mstp_clks[MSTP222]),
+       CLKDEV_DEV_ID("renesas_intc_irqpin.0",  &mstp_clks[MSTP229]),
+       CLKDEV_DEV_ID("renesas_intc_irqpin.1",  &mstp_clks[MSTP229]),
+       CLKDEV_DEV_ID("renesas_intc_irqpin.2",  &mstp_clks[MSTP229]),
+       CLKDEV_DEV_ID("renesas_intc_irqpin.3",  &mstp_clks[MSTP229]),
        CLKDEV_DEV_ID("sh-sci.6",               &mstp_clks[MSTP230]),
        CLKDEV_DEV_ID("e6cc0000.serial",        &mstp_clks[MSTP230]),
 
index 67980a0..e8510c3 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 /*
index c51f9db..fa8ab2c 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include <linux/bitops.h>
 #include <linux/init.h>
index 126ddaf..f9bbc5f 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 #include <linux/init.h>
 #include <linux/io.h>
@@ -68,7 +64,7 @@
 
 #define SDCKCR         0xE6150074
 #define SD2CKCR                0xE6150078
-#define SD3CKCR                0xE615007C
+#define SD3CKCR                0xE615026C
 #define MMC0CKCR       0xE6150240
 #define MMC1CKCR       0xE6150244
 #define SSPCKCR                0xE6150248
diff --git a/arch/arm/mach-shmobile/clock-r8a7791.c b/arch/arm/mach-shmobile/clock-r8a7791.c
deleted file mode 100644 (file)
index 453b231..0000000
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- * r8a7791 clock framework support
- *
- * Copyright (C) 2013  Renesas Electronics Corporation
- * Copyright (C) 2013  Renesas Solutions Corp.
- * Copyright (C) 2013  Magnus Damm
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <linux/sh_clk.h>
-#include <linux/clkdev.h>
-#include "clock.h"
-#include "common.h"
-#include "rcar-gen2.h"
-
-/*
- *   MD                EXTAL           PLL0    PLL1    PLL3
- * 14 13 19    (MHz)           *1      *1
- *---------------------------------------------------
- * 0  0  0     15 x 1          x172/2  x208/2  x106
- * 0  0  1     15 x 1          x172/2  x208/2  x88
- * 0  1  0     20 x 1          x130/2  x156/2  x80
- * 0  1  1     20 x 1          x130/2  x156/2  x66
- * 1  0  0     26 / 2          x200/2  x240/2  x122
- * 1  0  1     26 / 2          x200/2  x240/2  x102
- * 1  1  0     30 / 2          x172/2  x208/2  x106
- * 1  1  1     30 / 2          x172/2  x208/2  x88
- *
- * *1 :        Table 7.6 indicates VCO ouput (PLLx = VCO/2)
- *     see "p1 / 2" on R8A7791_CLOCK_ROOT() below
- */
-
-#define CPG_BASE 0xe6150000
-#define CPG_LEN 0x1000
-
-#define SMSTPCR0       0xE6150130
-#define SMSTPCR1       0xE6150134
-#define SMSTPCR2       0xe6150138
-#define SMSTPCR3       0xE615013C
-#define SMSTPCR5       0xE6150144
-#define SMSTPCR7       0xe615014c
-#define SMSTPCR8       0xE6150990
-#define SMSTPCR9       0xE6150994
-#define SMSTPCR10      0xE6150998
-#define SMSTPCR11      0xE615099C
-
-#define MSTPSR1                IOMEM(0xe6150038)
-#define MSTPSR2                IOMEM(0xe6150040)
-#define MSTPSR3                IOMEM(0xe6150048)
-#define MSTPSR5                IOMEM(0xe615003c)
-#define MSTPSR7                IOMEM(0xe61501c4)
-#define MSTPSR8                IOMEM(0xe61509a0)
-#define MSTPSR9                IOMEM(0xe61509a4)
-#define MSTPSR11       IOMEM(0xe61509ac)
-
-#define SDCKCR         0xE6150074
-#define SD1CKCR                0xE6150078
-#define SD2CKCR                0xE615026c
-#define MMC0CKCR       0xE6150240
-#define MMC1CKCR       0xE6150244
-#define SSPCKCR                0xE6150248
-#define SSPRSCKCR      0xE615024C
-
-static struct clk_mapping cpg_mapping = {
-       .phys   = CPG_BASE,
-       .len    = CPG_LEN,
-};
-
-static struct clk extal_clk = {
-       /* .rate will be updated on r8a7791_clock_init() */
-       .mapping        = &cpg_mapping,
-};
-
-static struct sh_clk_ops followparent_clk_ops = {
-       .recalc = followparent_recalc,
-};
-
-static struct clk main_clk = {
-       /* .parent will be set r8a73a4_clock_init */
-       .ops    = &followparent_clk_ops,
-};
-
-/*
- * clock ratio of these clock will be updated
- * on r8a7791_clock_init()
- */
-SH_FIXED_RATIO_CLK_SET(pll1_clk,               main_clk,       1, 1);
-SH_FIXED_RATIO_CLK_SET(pll3_clk,               main_clk,       1, 1);
-SH_FIXED_RATIO_CLK_SET(qspi_clk,               pll1_clk,       1, 1);
-
-/* fixed ratio clock */
-SH_FIXED_RATIO_CLK_SET(extal_div2_clk,         extal_clk,      1, 2);
-SH_FIXED_RATIO_CLK_SET(cp_clk,                 extal_clk,      1, 2);
-
-SH_FIXED_RATIO_CLK_SET(pll1_div2_clk,          pll1_clk,       1, 2);
-SH_FIXED_RATIO_CLK_SET(hp_clk,                 pll1_clk,       1, 12);
-SH_FIXED_RATIO_CLK_SET(p_clk,                  pll1_clk,       1, 24);
-SH_FIXED_RATIO_CLK_SET(rclk_clk,               pll1_clk,       1, (48 * 1024));
-SH_FIXED_RATIO_CLK_SET(mp_clk,                 pll1_div2_clk,  1, 15);
-SH_FIXED_RATIO_CLK_SET(zg_clk,                 pll1_clk,       1, 3);
-SH_FIXED_RATIO_CLK_SET(zx_clk,                 pll1_clk,       1, 3);
-SH_FIXED_RATIO_CLK_SET(zs_clk,                 pll1_clk,       1, 6);
-
-static struct clk *main_clks[] = {
-       &extal_clk,
-       &extal_div2_clk,
-       &main_clk,
-       &pll1_clk,
-       &pll1_div2_clk,
-       &pll3_clk,
-       &hp_clk,
-       &p_clk,
-       &qspi_clk,
-       &rclk_clk,
-       &mp_clk,
-       &cp_clk,
-       &zg_clk,
-       &zx_clk,
-       &zs_clk,
-};
-
-/* SDHI (DIV4) clock */
-static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18, 24, 0, 36, 48, 10 };
-
-static struct clk_div_mult_table div4_div_mult_table = {
-       .divisors = divisors,
-       .nr_divisors = ARRAY_SIZE(divisors),
-};
-
-static struct clk_div4_table div4_table = {
-       .div_mult_table = &div4_div_mult_table,
-};
-
-enum {
-       DIV4_SDH, DIV4_SD0,
-       DIV4_NR
-};
-
-static struct clk div4_clks[DIV4_NR] = {
-       [DIV4_SDH] = SH_CLK_DIV4(&pll1_clk, SDCKCR, 8, 0x0dff, CLK_ENABLE_ON_INIT),
-       [DIV4_SD0] = SH_CLK_DIV4(&pll1_clk, SDCKCR, 4, 0x1df0, CLK_ENABLE_ON_INIT),
-};
-
-/* DIV6 clocks */
-enum {
-       DIV6_SD1, DIV6_SD2,
-       DIV6_NR
-};
-
-static struct clk div6_clks[DIV6_NR] = {
-       [DIV6_SD1]      = SH_CLK_DIV6(&pll1_div2_clk, SD1CKCR, 0),
-       [DIV6_SD2]      = SH_CLK_DIV6(&pll1_div2_clk, SD2CKCR, 0),
-};
-
-/* MSTP */
-enum {
-       MSTP1108, MSTP1107, MSTP1106,
-       MSTP931, MSTP930, MSTP929, MSTP928, MSTP927, MSTP925,
-       MSTP917,
-       MSTP815, MSTP814,
-       MSTP813,
-       MSTP811, MSTP810, MSTP809,
-       MSTP726, MSTP724, MSTP723, MSTP721, MSTP720,
-       MSTP719, MSTP718, MSTP715, MSTP714,
-       MSTP522,
-       MSTP314, MSTP312, MSTP311,
-       MSTP216, MSTP207, MSTP206,
-       MSTP204, MSTP203, MSTP202,
-       MSTP124,
-       MSTP_NR
-};
-
-static struct clk mstp_clks[MSTP_NR] = {
-       [MSTP1108] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR11, 8, MSTPSR11, 0), /* SCIFA5 */
-       [MSTP1107] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR11, 7, MSTPSR11, 0), /* SCIFA4 */
-       [MSTP1106] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR11, 6, MSTPSR11, 0), /* SCIFA3 */
-       [MSTP931] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 31, MSTPSR9, 0), /* I2C0 */
-       [MSTP930] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 30, MSTPSR9, 0), /* I2C1 */
-       [MSTP929] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 29, MSTPSR9, 0), /* I2C2 */
-       [MSTP928] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 28, MSTPSR9, 0), /* I2C3 */
-       [MSTP927] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 27, MSTPSR9, 0), /* I2C4 */
-       [MSTP925] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 25, MSTPSR9, 0), /* I2C5 */
-       [MSTP917] = SH_CLK_MSTP32_STS(&qspi_clk, SMSTPCR9, 17, MSTPSR9, 0), /* QSPI */
-       [MSTP815] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 15, MSTPSR8, 0), /* SATA0 */
-       [MSTP814] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 14, MSTPSR8, 0), /* SATA1 */
-       [MSTP813] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR8, 13, MSTPSR8, 0), /* Ether */
-       [MSTP811] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8, 11, MSTPSR8, 0), /* VIN0 */
-       [MSTP810] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8, 10, MSTPSR8, 0), /* VIN1 */
-       [MSTP809] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8, 9, MSTPSR8, 0), /* VIN2 */
-       [MSTP726] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 26, MSTPSR7, 0), /* LVDS0 */
-       [MSTP724] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 24, MSTPSR7, 0), /* DU0 */
-       [MSTP723] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 23, MSTPSR7, 0), /* DU1 */
-       [MSTP721] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 21, MSTPSR7, 0), /* SCIF0 */
-       [MSTP720] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 20, MSTPSR7, 0), /* SCIF1 */
-       [MSTP719] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 19, MSTPSR7, 0), /* SCIF2 */
-       [MSTP718] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 18, MSTPSR7, 0), /* SCIF3 */
-       [MSTP715] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 15, MSTPSR7, 0), /* SCIF4 */
-       [MSTP714] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 14, MSTPSR7, 0), /* SCIF5 */
-       [MSTP522] = SH_CLK_MSTP32_STS(&extal_clk, SMSTPCR5, 22, MSTPSR5, 0), /* Thermal */
-       [MSTP314] = SH_CLK_MSTP32_STS(&div4_clks[DIV4_SD0], SMSTPCR3, 14, MSTPSR3, 0), /* SDHI0 */
-       [MSTP312] = SH_CLK_MSTP32_STS(&div6_clks[DIV6_SD1], SMSTPCR3, 12, MSTPSR3, 0), /* SDHI1 */
-       [MSTP311] = SH_CLK_MSTP32_STS(&div6_clks[DIV6_SD2], SMSTPCR3, 11, MSTPSR3, 0), /* SDHI2 */
-       [MSTP216] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 16, MSTPSR2, 0), /* SCIFB2 */
-       [MSTP207] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 7, MSTPSR2, 0), /* SCIFB1 */
-       [MSTP206] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 6, MSTPSR2, 0), /* SCIFB0 */
-       [MSTP204] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 4, MSTPSR2, 0), /* SCIFA0 */
-       [MSTP203] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 3, MSTPSR2, 0), /* SCIFA1 */
-       [MSTP202] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 2, MSTPSR2, 0), /* SCIFA2 */
-       [MSTP124] = SH_CLK_MSTP32_STS(&rclk_clk, SMSTPCR1, 24, MSTPSR1, 0), /* CMT0 */
-};
-
-static struct clk_lookup lookups[] = {
-
-       /* main clocks */
-       CLKDEV_CON_ID("extal",          &extal_clk),
-       CLKDEV_CON_ID("extal_div2",     &extal_div2_clk),
-       CLKDEV_CON_ID("main",           &main_clk),
-       CLKDEV_CON_ID("pll1",           &pll1_clk),
-       CLKDEV_CON_ID("pll1_div2",      &pll1_div2_clk),
-       CLKDEV_CON_ID("pll3",           &pll3_clk),
-       CLKDEV_CON_ID("zg",             &zg_clk),
-       CLKDEV_CON_ID("zs",             &zs_clk),
-       CLKDEV_CON_ID("hp",             &hp_clk),
-       CLKDEV_CON_ID("p",              &p_clk),
-       CLKDEV_CON_ID("qspi",           &qspi_clk),
-       CLKDEV_CON_ID("rclk",           &rclk_clk),
-       CLKDEV_CON_ID("mp",             &mp_clk),
-       CLKDEV_CON_ID("cp",             &cp_clk),
-       CLKDEV_CON_ID("peripheral_clk", &hp_clk),
-
-       /* MSTP */
-       CLKDEV_ICK_ID("lvds.0", "rcar-du-r8a7791", &mstp_clks[MSTP726]),
-       CLKDEV_ICK_ID("du.0", "rcar-du-r8a7791", &mstp_clks[MSTP724]),
-       CLKDEV_ICK_ID("du.1", "rcar-du-r8a7791", &mstp_clks[MSTP723]),
-       CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
-       CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
-       CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP206]), /* SCIFB0 */
-       CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP207]), /* SCIFB1 */
-       CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP216]), /* SCIFB2 */
-       CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP202]), /* SCIFA2 */
-       CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP721]), /* SCIF0 */
-       CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP720]), /* SCIF1 */
-       CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP719]), /* SCIF2 */
-       CLKDEV_DEV_ID("sh-sci.9", &mstp_clks[MSTP718]), /* SCIF3 */
-       CLKDEV_DEV_ID("sh-sci.10", &mstp_clks[MSTP715]), /* SCIF4 */
-       CLKDEV_DEV_ID("sh-sci.11", &mstp_clks[MSTP714]), /* SCIF5 */
-       CLKDEV_DEV_ID("sh-sci.12", &mstp_clks[MSTP1106]), /* SCIFA3 */
-       CLKDEV_DEV_ID("sh-sci.13", &mstp_clks[MSTP1107]), /* SCIFA4 */
-       CLKDEV_DEV_ID("sh-sci.14", &mstp_clks[MSTP1108]), /* SCIFA5 */
-       CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]),
-       CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP312]),
-       CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]),
-       CLKDEV_ICK_ID("fck", "sh-cmt-48-gen2.0", &mstp_clks[MSTP124]),
-       CLKDEV_DEV_ID("qspi.0", &mstp_clks[MSTP917]),
-       CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]),
-       CLKDEV_DEV_ID("i2c-rcar_gen2.0", &mstp_clks[MSTP931]),
-       CLKDEV_DEV_ID("i2c-rcar_gen2.1", &mstp_clks[MSTP930]),
-       CLKDEV_DEV_ID("i2c-rcar_gen2.2", &mstp_clks[MSTP929]),
-       CLKDEV_DEV_ID("i2c-rcar_gen2.3", &mstp_clks[MSTP928]),
-       CLKDEV_DEV_ID("i2c-rcar_gen2.4", &mstp_clks[MSTP927]),
-       CLKDEV_DEV_ID("i2c-rcar_gen2.5", &mstp_clks[MSTP925]),
-       CLKDEV_DEV_ID("r8a7791-ether", &mstp_clks[MSTP813]), /* Ether */
-       CLKDEV_DEV_ID("r8a7791-vin.0", &mstp_clks[MSTP811]),
-       CLKDEV_DEV_ID("r8a7791-vin.1", &mstp_clks[MSTP810]),
-       CLKDEV_DEV_ID("r8a7791-vin.2", &mstp_clks[MSTP809]),
-       CLKDEV_DEV_ID("sata-r8a7791.0", &mstp_clks[MSTP815]),
-       CLKDEV_DEV_ID("sata-r8a7791.1", &mstp_clks[MSTP814]),
-};
-
-#define R8A7791_CLOCK_ROOT(e, m, p0, p1, p30, p31)             \
-       extal_clk.rate  = e * 1000 * 1000;                      \
-       main_clk.parent = m;                                    \
-       SH_CLK_SET_RATIO(&pll1_clk_ratio, p1 / 2, 1);           \
-       if (mode & MD(19))                                      \
-               SH_CLK_SET_RATIO(&pll3_clk_ratio, p31, 1);      \
-       else                                                    \
-               SH_CLK_SET_RATIO(&pll3_clk_ratio, p30, 1)
-
-
-void __init r8a7791_clock_init(void)
-{
-       u32 mode = rcar_gen2_read_mode_pins();
-       int k, ret = 0;
-
-       switch (mode & (MD(14) | MD(13))) {
-       case 0:
-               R8A7791_CLOCK_ROOT(15, &extal_clk, 172, 208, 106, 88);
-               break;
-       case MD(13):
-               R8A7791_CLOCK_ROOT(20, &extal_clk, 130, 156, 80, 66);
-               break;
-       case MD(14):
-               R8A7791_CLOCK_ROOT(26, &extal_div2_clk, 200, 240, 122, 102);
-               break;
-       case MD(13) | MD(14):
-               R8A7791_CLOCK_ROOT(30, &extal_div2_clk, 172, 208, 106, 88);
-               break;
-       }
-
-       if ((mode & (MD(3) | MD(2) | MD(1))) == MD(2))
-               SH_CLK_SET_RATIO(&qspi_clk_ratio, 1, 16);
-       else
-               SH_CLK_SET_RATIO(&qspi_clk_ratio, 1, 20);
-
-       for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
-               ret = clk_register(main_clks[k]);
-
-       if (!ret)
-               ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
-
-       if (!ret)
-               ret = sh_clk_div6_register(div6_clks, DIV6_NR);
-
-       if (!ret)
-               ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
-
-       clkdev_add_table(lookups, ARRAY_SIZE(lookups));
-
-       if (!ret)
-               shmobile_clk_init();
-       else
-               goto epanic;
-
-       return;
-
-epanic:
-       panic("failed to setup r8a7791 clocks\n");
-}
index 7071676..3bc92f4 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
index 02a6f45..6b4c1f3 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
index 806f940..34f056f 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
  */
+
+#include <linux/export.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-
-#ifdef CONFIG_COMMON_CLK
-#include <linux/clk.h>
-#include <linux/clkdev.h>
-#include "clock.h"
-
-void __init shmobile_clk_workaround(const struct clk_name *clks,
-                                   int nr_clks, bool enable)
-{
-       const struct clk_name *clkn;
-       struct clk *clk;
-       unsigned int i;
-
-       for (i = 0; i < nr_clks; ++i) {
-               clkn = clks + i;
-               clk = clk_get(NULL, clkn->clk);
-               if (!IS_ERR(clk)) {
-                       clk_register_clkdev(clk, clkn->con_id, clkn->dev_id);
-                       if (enable)
-                               clk_prepare_enable(clk);
-                       clk_put(clk);
-               }
-       }
-}
-
-#else /* CONFIG_COMMON_CLK */
 #include <linux/sh_clk.h>
-#include <linux/export.h>
+
 #include "clock.h"
 #include "common.h"
 
@@ -84,5 +56,3 @@ void __clk_put(struct clk *clk)
 {
 }
 EXPORT_SYMBOL(__clk_put);
-
-#endif /* CONFIG_COMMON_CLK */
index 31b6417..cf3552e 100644 (file)
@@ -1,19 +1,6 @@
 #ifndef CLOCK_H
 #define CLOCK_H
 
-#ifdef CONFIG_COMMON_CLK
-/* temporary clock configuration helper for platform devices */
-
-struct clk_name {
-       const char *clk;
-       const char *con_id;
-       const char *dev_id;
-};
-
-void shmobile_clk_workaround(const struct clk_name *clks, int nr_clks,
-                            bool enable);
-
-#else /* CONFIG_COMMON_CLK */
 /* legacy clock implementation */
 
 struct clk;
@@ -52,5 +39,4 @@ do {                  \
        (p)->div = d;   \
 } while (0)
 
-#endif /* CONFIG_COMMON_CLK */
 #endif
index 9805608..309025e 100644 (file)
@@ -2,8 +2,6 @@
 #define __ARCH_MACH_COMMON_H
 
 extern void shmobile_earlytimer_init(void);
-extern void shmobile_setup_delay(unsigned int max_cpu_core_mhz,
-                        unsigned int mult, unsigned int div);
 extern void shmobile_init_delay(void);
 struct twd_local_timer;
 extern void shmobile_setup_console(void);
@@ -21,11 +19,6 @@ extern void shmobile_boot_scu(void);
 extern void shmobile_smp_scu_prepare_cpus(unsigned int max_cpus);
 extern void shmobile_smp_scu_cpu_die(unsigned int cpu);
 extern int shmobile_smp_scu_cpu_kill(unsigned int cpu);
-extern void shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus);
-extern int shmobile_smp_apmu_boot_secondary(unsigned int cpu,
-                                           struct task_struct *idle);
-extern void shmobile_smp_apmu_cpu_die(unsigned int cpu);
-extern int shmobile_smp_apmu_cpu_kill(unsigned int cpu);
 struct clk;
 extern int shmobile_clk_init(void);
 extern void shmobile_handle_irq_intc(struct pt_regs *);
index f2e79f2..e329ccb 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
index 97c40bd..52a2f66 100644 (file)
@@ -52,8 +52,8 @@ static const unsigned int dma_ts_shift[] = {
        ((((i) & TS_LOW_BIT) << TS_LOW_SHIFT) |\
         (((i) & TS_HI_BIT)  << TS_HI_SHIFT))
 
-#define CHCR_TX(xmit_sz) (DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL((xmit_sz)))
-#define CHCR_RX(xmit_sz) (DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL((xmit_sz)))
+#define CHCR_TX(xmit_sz) (DM_FIX | SM_INC | RS_ERS | TS_INDEX2VAL((xmit_sz)))
+#define CHCR_RX(xmit_sz) (DM_INC | SM_FIX | RS_ERS | TS_INDEX2VAL((xmit_sz)))
 
 
 /*
index f45dde7..69df8bf 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
  */
 
 #include <linux/linkage.h>
index e2af00b..1ccf49c 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
index 44457a9..9e36180 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
index a5603c7..40b2ad4 100644 (file)
@@ -287,4 +287,9 @@ static struct intc_desc p ## _desc __initdata = {                   \
                             p ## _sense_registers, NULL),              \
 }
 
+/* INTCS */
+#define INTCS_VECT_BASE                0x3400
+#define INTCS_VECT(n, vect)    INTC_VECT((n), INTCS_VECT_BASE + (vect))
+#define intcs_evt2irq(evt)     evt2irq(INTCS_VECT_BASE + (evt))
+
 #endif  /* __ASM_MACH_INTC_H */
index 4ff2d2a..3070f6d 100644 (file)
@@ -1,18 +1,12 @@
 #ifndef __SHMOBILE_IRQS_H
 #define __SHMOBILE_IRQS_H
 
-#include <linux/sh_intc.h>
-#include <mach/irqs.h>
+#include "include/mach/irqs.h"
 
 /* GIC */
 #define gic_spi(nr)            ((nr) + 32)
 #define gic_iid(nr)            (nr) /* ICCIAR / interrupt ID */
 
-/* INTCS */
-#define INTCS_VECT_BASE                0x3400
-#define INTCS_VECT(n, vect)    INTC_VECT((n), INTCS_VECT_BASE + (vect))
-#define intcs_evt2irq(evt)     evt2irq(INTCS_VECT_BASE + (evt))
-
 /* GPIO IRQ */
 #define _GPIO_IRQ_BASE         2500
 #define GPIO_IRQ_BASE(x)       (_GPIO_IRQ_BASE + (32 * x))
index 2c06810..f483b56 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * SMP support for SoCs with APMU
  *
+ * Copyright (C) 2014  Renesas Electronics Corporation
  * Copyright (C) 2013  Magnus Damm
  *
  * This program is free software; you can redistribute it and/or modify
@@ -22,6 +23,7 @@
 #include <asm/smp_plat.h>
 #include <asm/suspend.h>
 #include "common.h"
+#include "platsmp-apmu.h"
 
 static struct {
        void __iomem *iomem;
@@ -83,28 +85,15 @@ static void apmu_init_cpu(struct resource *res, int cpu, int bit)
        pr_debug("apmu ioremap %d %d %pr\n", cpu, bit, res);
 }
 
-static struct {
-       struct resource iomem;
-       int cpus[4];
-} apmu_config[] = {
-       {
-               .iomem = DEFINE_RES_MEM(0xe6152000, 0x88),
-               .cpus = { 0, 1, 2, 3 },
-       },
-       {
-               .iomem = DEFINE_RES_MEM(0xe6151000, 0x88),
-               .cpus = { 0x100, 0x101, 0x102, 0x103 },
-       }
-};
-
-static void apmu_parse_cfg(void (*fn)(struct resource *res, int cpu, int bit))
+static void apmu_parse_cfg(void (*fn)(struct resource *res, int cpu, int bit),
+                          struct rcar_apmu_config *apmu_config, int num)
 {
        u32 id;
        int k;
        int bit, index;
        bool is_allowed;
 
-       for (k = 0; k < ARRAY_SIZE(apmu_config); k++) {
+       for (k = 0; k < num; k++) {
                /* only enable the cluster that includes the boot CPU */
                is_allowed = false;
                for (bit = 0; bit < ARRAY_SIZE(apmu_config[k].cpus); bit++) {
@@ -128,14 +117,16 @@ static void apmu_parse_cfg(void (*fn)(struct resource *res, int cpu, int bit))
        }
 }
 
-void __init shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus)
+void __init shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus,
+                                          struct rcar_apmu_config *apmu_config,
+                                          int num)
 {
        /* install boot code shared by all CPUs */
        shmobile_boot_fn = virt_to_phys(shmobile_smp_boot);
        shmobile_boot_arg = MPIDR_HWID_BITMASK;
 
        /* perform per-cpu setup */
-       apmu_parse_cfg(apmu_init_cpu);
+       apmu_parse_cfg(apmu_init_cpu, apmu_config, num);
 }
 
 #ifdef CONFIG_SMP
diff --git a/arch/arm/mach-shmobile/platsmp-apmu.h b/arch/arm/mach-shmobile/platsmp-apmu.h
new file mode 100644 (file)
index 0000000..99d2c6f
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * rmobile apmu definition
+ *
+ * Copyright (C) 2014  Renesas Electronics Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef PLATSMP_APMU_H
+#define PLATSMP_APMU_H
+
+#include <linux/ioport.h>
+
+struct rcar_apmu_config {
+       struct resource iomem;
+       int cpus[4];
+};
+
+extern void shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus,
+                                          struct rcar_apmu_config *apmu_config,
+                                          int num);
+extern int shmobile_smp_apmu_boot_secondary(unsigned int cpu,
+                                           struct task_struct *idle);
+extern void shmobile_smp_apmu_cpu_die(unsigned int cpu);
+extern int shmobile_smp_apmu_cpu_kill(unsigned int cpu);
+
+#endif /* PLATSMP_APMU_H */
index a0d44d5..ac2eecd 100644 (file)
 #include "common.h"
 #include "pm-rmobile.h"
 
-#ifdef CONFIG_PM
-static int r8a7740_pd_a4s_suspend(void)
+#if defined(CONFIG_PM) && !defined(CONFIG_ARCH_MULTIPLATFORM)
+static int r8a7740_pd_a3sm_suspend(void)
 {
        /*
-        * The A4S domain contains the CPU core and therefore it should
-        * only be turned off if the CPU is in use.
+        * The A3SM domain contains the CPU core and therefore it should
+        * only be turned off if the CPU is not in use.
         */
        return -EBUSY;
 }
@@ -32,34 +32,67 @@ static int r8a7740_pd_a3sp_suspend(void)
        return console_suspend_enabled ? 0 : -EBUSY;
 }
 
+static int r8a7740_pd_d4_suspend(void)
+{
+       /*
+        * The D4 domain contains the Coresight-ETM hardware block and
+        * therefore it should only be turned off if the debug module is
+        * not in use.
+        */
+       return -EBUSY;
+}
+
 static struct rmobile_pm_domain r8a7740_pm_domains[] = {
        {
+               .genpd.name     = "A4LC",
+               .bit_shift      = 1,
+       }, {
+               .genpd.name     = "A4MP",
+               .bit_shift      = 2,
+       }, {
+               .genpd.name     = "D4",
+               .bit_shift      = 3,
+               .gov            = &pm_domain_always_on_gov,
+               .suspend        = r8a7740_pd_d4_suspend,
+       }, {
+               .genpd.name     = "A4R",
+               .bit_shift      = 5,
+       }, {
+               .genpd.name     = "A3RV",
+               .bit_shift      = 6,
+       }, {
                .genpd.name     = "A4S",
                .bit_shift      = 10,
-               .gov            = &pm_domain_always_on_gov,
                .no_debug       = true,
-               .suspend        = r8a7740_pd_a4s_suspend,
-       },
-       {
+       }, {
                .genpd.name     = "A3SP",
                .bit_shift      = 11,
                .gov            = &pm_domain_always_on_gov,
                .no_debug       = true,
                .suspend        = r8a7740_pd_a3sp_suspend,
-       },
-       {
-               .genpd.name     = "A4LC",
-               .bit_shift      = 1,
+       }, {
+               .genpd.name     = "A3SM",
+               .bit_shift      = 12,
+               .gov            = &pm_domain_always_on_gov,
+               .suspend        = r8a7740_pd_a3sm_suspend,
+       }, {
+               .genpd.name     = "A3SG",
+               .bit_shift      = 13,
+       }, {
+               .genpd.name     = "A4SU",
+               .bit_shift      = 20,
        },
 };
 
 void __init r8a7740_init_pm_domains(void)
 {
        rmobile_init_domains(r8a7740_pm_domains, ARRAY_SIZE(r8a7740_pm_domains));
+       pm_genpd_add_subdomain_names("A4R", "A3RV");
        pm_genpd_add_subdomain_names("A4S", "A3SP");
+       pm_genpd_add_subdomain_names("A4S", "A3SM");
+       pm_genpd_add_subdomain_names("A4S", "A3SG");
 }
-
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM && !CONFIG_ARCH_MULTIPLATFORM */
 
 #ifdef CONFIG_SUSPEND
 static int r8a7740_enter_suspend(suspend_state_t suspend_state)
index 69f70b7..82fe3d7 100644 (file)
@@ -87,7 +87,6 @@ static void r8a7779_init_pm_domain(struct r8a7779_pm_domain *r8a7779_pd)
        genpd->dev_ops.stop = pm_clk_suspend;
        genpd->dev_ops.start = pm_clk_resume;
        genpd->dev_ops.active_wakeup = pd_active_wakeup;
-       genpd->dev_irq_safe = true;
        genpd->power_off = pd_power_down;
        genpd->power_on = pd_power_up;
 
index 34b8a56..00022ee 100644 (file)
@@ -31,8 +31,6 @@
 #define SYSCISR_RETRIES 1000
 #define SYSCISR_DELAY_US 1
 
-#if defined(CONFIG_PM) || defined(CONFIG_SMP)
-
 static void __iomem *rcar_sysc_base;
 static DEFINE_SPINLOCK(rcar_sysc_lock); /* SMP CPUs + I/O devices */
 
@@ -137,5 +135,3 @@ void __iomem *rcar_sysc_init(phys_addr_t base)
 
        return rcar_sysc_base;
 }
-
-#endif /* CONFIG_PM || CONFIG_SMP */
index ebdd16e..717e641 100644 (file)
@@ -27,7 +27,6 @@
 #define PSTR_RETRIES   100
 #define PSTR_DELAY_US  10
 
-#ifdef CONFIG_PM
 static int rmobile_pd_power_down(struct generic_pm_domain *genpd)
 {
        struct rmobile_pm_domain *rmobile_pd = to_rmobile_pd(genpd);
@@ -111,7 +110,6 @@ static void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd)
        genpd->dev_ops.stop             = pm_clk_suspend;
        genpd->dev_ops.start            = pm_clk_resume;
        genpd->dev_ops.active_wakeup    = rmobile_pd_active_wakeup;
-       genpd->dev_irq_safe             = true;
        genpd->power_off                = rmobile_pd_power_down;
        genpd->power_on                 = rmobile_pd_power_up;
        __rmobile_pd_power_up(rmobile_pd, false);
@@ -151,4 +149,3 @@ void rmobile_add_devices_to_domains(struct pm_domain_device data[],
                rmobile_add_device_to_domain_td(data[j].domain_name,
                                                data[j].pdev, &latencies);
 }
-#endif /* CONFIG_PM */
index 690553a..8f66b34 100644 (file)
@@ -36,7 +36,7 @@ struct pm_domain_device {
        struct platform_device *pdev;
 };
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_RMOBILE
 extern void rmobile_init_domains(struct rmobile_pm_domain domains[], int num);
 extern void rmobile_add_device_to_domain_td(const char *domain_name,
                                            struct platform_device *pdev,
@@ -58,6 +58,6 @@ extern void rmobile_add_devices_to_domains(struct pm_domain_device data[],
 
 static inline void rmobile_add_devices_to_domains(struct pm_domain_device d[],
                                                  int size) {}
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_RMOBILE */
 
 #endif /* PM_RMOBILE_H */
diff --git a/arch/arm/mach-shmobile/r7s72100.h b/arch/arm/mach-shmobile/r7s72100.h
deleted file mode 100644 (file)
index efb723c..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef __ASM_R7S72100_H__
-#define __ASM_R7S72100_H__
-
-void r7s72100_add_dt_devices(void);
-void r7s72100_clock_init(void);
-
-#endif /* __ASM_R7S72100_H__ */
index ce8bdd1..70dcd84 100644 (file)
@@ -11,9 +11,7 @@ enum {
 };
 
 void r8a73a4_add_standard_devices(void);
-void r8a73a4_add_dt_devices(void);
 void r8a73a4_clock_init(void);
 void r8a73a4_pinmux_init(void);
-void r8a73a4_init_early(void);
 
 #endif /* __ASM_R8A73A4_H__ */
index 1d1a5fd..ca7805a 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
 #ifndef __ASM_R8A7740_H__
@@ -49,15 +45,14 @@ extern void r8a7740_init_irq_of(void);
 extern void r8a7740_map_io(void);
 extern void r8a7740_add_early_devices(void);
 extern void r8a7740_add_standard_devices(void);
-extern void r8a7740_add_standard_devices_dt(void);
 extern void r8a7740_clock_init(u8 md_ck);
 extern void r8a7740_pinmux_init(void);
 extern void r8a7740_pm_init(void);
 
-#ifdef CONFIG_PM
+#if defined(CONFIG_PM) && !defined(CONFIG_ARCH_MULTIPLATFORM)
 extern void __init r8a7740_init_pm_domains(void);
 #else
 static inline void r8a7740_init_pm_domains(void) {}
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM && !CONFIG_ARCH_MULTIPLATFORM */
 
 #endif /* __ASM_R8A7740_H__ */
index f4076a5..f64fedb 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 #ifndef __ASM_R8A7778_H__
 #define __ASM_R8A7778_H__
@@ -71,7 +67,6 @@ extern void r8a7778_add_standard_devices_dt(void);
 extern void r8a7778_add_dt_devices(void);
 
 extern void r8a7778_init_late(void);
-extern void r8a7778_init_delay(void);
 extern void r8a7778_init_irq_dt(void);
 extern void r8a7778_clock_init(void);
 extern void r8a7778_init_irq_extpin(int irlm);
index 5415c71..19f9704 100644 (file)
@@ -17,7 +17,6 @@ extern void r8a7779_map_io(void);
 extern void r8a7779_earlytimer_init(void);
 extern void r8a7779_add_early_devices(void);
 extern void r8a7779_add_standard_devices(void);
-extern void r8a7779_add_standard_devices_dt(void);
 extern void r8a7779_init_late(void);
 extern u32 r8a7779_read_mode_pins(void);
 extern void r8a7779_clock_init(void);
index 459827f..388f051 100644 (file)
@@ -27,7 +27,6 @@ enum {
 };
 
 void r8a7790_add_standard_devices(void);
-void r8a7790_add_dt_devices(void);
 void r8a7790_clock_init(void);
 void r8a7790_pinmux_init(void);
 void r8a7790_pm_init(void);
index 86eae7b..6cf11eb 100644 (file)
@@ -1,10 +1,6 @@
 #ifndef __ASM_R8A7791_H__
 #define __ASM_R8A7791_H__
 
-void r8a7791_add_standard_devices(void);
-void r8a7791_add_dt_devices(void);
-void r8a7791_clock_init(void);
-void r8a7791_pinmux_init(void);
 void r8a7791_pm_init(void);
 extern struct smp_operations r8a7791_smp_ops;
 
index b06a9e8..aad97be 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
index 4a98b23..1711747 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-#include <linux/irq.h>
 #include <linux/kernel.h>
-#include <linux/of_platform.h>
-#include <linux/sh_timer.h>
 
 #include <asm/mach/arch.h>
 
 #include "common.h"
-#include "irqs.h"
-#include "r7s72100.h"
-
-static struct resource mtu2_resources[] __initdata = {
-       DEFINE_RES_MEM(0xfcff0000, 0x400),
-       DEFINE_RES_IRQ_NAMED(gic_iid(139), "tgi0a"),
-};
-
-#define r7s72100_register_mtu2()                                       \
-       platform_device_register_resndata(&platform_bus, "sh-mtu2",     \
-                                         -1, mtu2_resources,           \
-                                         ARRAY_SIZE(mtu2_resources),   \
-                                         NULL, 0)
-
-void __init r7s72100_add_dt_devices(void)
-{
-       r7s72100_register_mtu2();
-}
 
-#ifdef CONFIG_USE_OF
 static const char *r7s72100_boards_compat_dt[] __initdata = {
        "renesas,r7s72100",
        NULL,
@@ -53,6 +27,6 @@ static const char *r7s72100_boards_compat_dt[] __initdata = {
 
 DT_MACHINE_START(R7S72100_DT, "Generic R7S72100 (Flattened Device Tree)")
        .init_early     = shmobile_init_delay,
+       .init_late      = shmobile_init_late,
        .dt_compat      = r7s72100_boards_compat_dt,
 MACHINE_END
-#endif /* CONFIG_USE_OF */
index 2e1ec5e..28ec83e 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 #include <linux/irq.h>
 #include <linux/kernel.h>
@@ -180,18 +176,13 @@ static struct resource cmt1_resources[] = {
        DEFINE_RES_IRQ(gic_spi(120)),
 };
 
-#define r8a7790_register_cmt(idx)                                      \
+#define r8a73a4_register_cmt(idx)                                      \
        platform_device_register_resndata(&platform_bus, "sh-cmt-48-gen2", \
                                          idx, cmt##idx##_resources,    \
                                          ARRAY_SIZE(cmt##idx##_resources), \
                                          &cmt##idx##_platform_data,    \
                                          sizeof(struct sh_timer_config))
 
-void __init r8a73a4_add_dt_devices(void)
-{
-       r8a7790_register_cmt(1);
-}
-
 /* DMA */
 static const struct sh_dmae_slave_config dma_slaves[] = {
        {
@@ -282,7 +273,7 @@ static struct resource dma_resources[] = {
 
 void __init r8a73a4_add_standard_devices(void)
 {
-       r8a73a4_add_dt_devices();
+       r8a73a4_register_cmt(1);
        r8a73a4_register_scif(0);
        r8a73a4_register_scif(1);
        r8a73a4_register_scif(2);
@@ -295,13 +286,6 @@ void __init r8a73a4_add_standard_devices(void)
        r8a73a4_register_dmac();
 }
 
-void __init r8a73a4_init_early(void)
-{
-#ifndef CONFIG_ARM_ARCH_TIMER
-       shmobile_setup_delay(1500, 2, 4); /* Cortex-A15 @ 1500MHz */
-#endif
-}
-
 #ifdef CONFIG_USE_OF
 
 static const char *r8a73a4_boards_compat_dt[] __initdata = {
@@ -310,7 +294,8 @@ static const char *r8a73a4_boards_compat_dt[] __initdata = {
 };
 
 DT_MACHINE_START(R8A73A4_DT, "Generic R8A73A4 (Flattened Device Tree)")
-       .init_early     = r8a73a4_init_early,
+       .init_early     = shmobile_init_delay,
+       .init_late      = shmobile_init_late,
        .dt_compat      = r8a73a4_boards_compat_dt,
 MACHINE_END
 #endif /* CONFIG_USE_OF */
index 3d5eaca..79ad93d 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
@@ -36,6 +32,7 @@
 #include <asm/mach/map.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
+#include <asm/hardware/cache-l2x0.h>
 
 #include "common.h"
 #include "dma-register.h"
@@ -70,6 +67,7 @@ static struct map_desc r8a7740_io_desc[] __initdata = {
 
 void __init r8a7740_map_io(void)
 {
+       debug_ll_io_init();
        iotable_init(r8a7740_io_desc, ARRAY_SIZE(r8a7740_io_desc));
 }
 
@@ -311,10 +309,6 @@ static struct platform_device ipmmu_device = {
        .num_resources  = ARRAY_SIZE(ipmmu_resources),
 };
 
-static struct platform_device *r8a7740_devices_dt[] __initdata = {
-       &cmt1_device,
-};
-
 static struct platform_device *r8a7740_early_devices[] __initdata = {
        &scif0_device,
        &scif1_device,
@@ -331,6 +325,7 @@ static struct platform_device *r8a7740_early_devices[] __initdata = {
        &irqpin3_device,
        &tmu0_device,
        &ipmmu_device,
+       &cmt1_device,
 };
 
 /* DMA */
@@ -747,6 +742,30 @@ static void r8a7740_i2c_workaround(struct platform_device *pdev)
 
 void __init r8a7740_add_standard_devices(void)
 {
+       static struct pm_domain_device domain_devices[] __initdata = {
+               { "A4R",  &tmu0_device },
+               { "A4R",  &i2c0_device },
+               { "A4S",  &irqpin0_device },
+               { "A4S",  &irqpin1_device },
+               { "A4S",  &irqpin2_device },
+               { "A4S",  &irqpin3_device },
+               { "A3SP", &scif0_device },
+               { "A3SP", &scif1_device },
+               { "A3SP", &scif2_device },
+               { "A3SP", &scif3_device },
+               { "A3SP", &scif4_device },
+               { "A3SP", &scif5_device },
+               { "A3SP", &scif6_device },
+               { "A3SP", &scif7_device },
+               { "A3SP", &scif8_device },
+               { "A3SP", &i2c1_device },
+               { "A3SP", &ipmmu_device },
+               { "A3SP", &dma0_device },
+               { "A3SP", &dma1_device },
+               { "A3SP", &dma2_device },
+               { "A3SP", &usb_dma_device },
+       };
+
        /* I2C work-around */
        r8a7740_i2c_workaround(&i2c0_device);
        r8a7740_i2c_workaround(&i2c1_device);
@@ -756,31 +775,18 @@ void __init r8a7740_add_standard_devices(void)
        /* add devices */
        platform_add_devices(r8a7740_early_devices,
                            ARRAY_SIZE(r8a7740_early_devices));
-       platform_add_devices(r8a7740_devices_dt,
-                           ARRAY_SIZE(r8a7740_devices_dt));
        platform_add_devices(r8a7740_late_devices,
                             ARRAY_SIZE(r8a7740_late_devices));
 
        /* add devices to PM domain  */
-
-       rmobile_add_device_to_domain("A3SP",    &scif0_device);
-       rmobile_add_device_to_domain("A3SP",    &scif1_device);
-       rmobile_add_device_to_domain("A3SP",    &scif2_device);
-       rmobile_add_device_to_domain("A3SP",    &scif3_device);
-       rmobile_add_device_to_domain("A3SP",    &scif4_device);
-       rmobile_add_device_to_domain("A3SP",    &scif5_device);
-       rmobile_add_device_to_domain("A3SP",    &scif6_device);
-       rmobile_add_device_to_domain("A3SP",    &scif7_device);
-       rmobile_add_device_to_domain("A3SP",    &scif8_device);
-       rmobile_add_device_to_domain("A3SP",    &i2c1_device);
+       rmobile_add_devices_to_domains(domain_devices,
+                                      ARRAY_SIZE(domain_devices));
 }
 
 void __init r8a7740_add_early_devices(void)
 {
        early_platform_add_devices(r8a7740_early_devices,
                                   ARRAY_SIZE(r8a7740_early_devices));
-       early_platform_add_devices(r8a7740_devices_dt,
-                                  ARRAY_SIZE(r8a7740_devices_dt));
 
        /* setup early console here as well */
        shmobile_setup_console();
@@ -788,13 +794,6 @@ void __init r8a7740_add_early_devices(void)
 
 #ifdef CONFIG_USE_OF
 
-void __init r8a7740_add_standard_devices_dt(void)
-{
-       platform_add_devices(r8a7740_devices_dt,
-                           ARRAY_SIZE(r8a7740_devices_dt));
-       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
-}
-
 void __init r8a7740_init_irq_of(void)
 {
        void __iomem *intc_prio_base = ioremap_nocache(0xe6900010, 0x10);
@@ -827,8 +826,20 @@ void __init r8a7740_init_irq_of(void)
 
 static void __init r8a7740_generic_init(void)
 {
-       r8a7740_clock_init(0);
-       r8a7740_add_standard_devices_dt();
+       r8a7740_meram_workaround();
+
+#ifdef CONFIG_CACHE_L2X0
+       /* Shared attribute override enable, 32K*8way */
+       l2x0_init(IOMEM(0xf0002000), 0x00400000, 0xc20f0fff);
+#endif
+       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
+#define RESCNT2 IOMEM(0xe6188020)
+static void r8a7740_restart(enum reboot_mode mode, const char *cmd)
+{
+       /* Do soft power on reset */
+       writel(1 << 31, RESCNT2);
 }
 
 static const char *r8a7740_boards_compat_dt[] __initdata = {
@@ -843,6 +854,7 @@ DT_MACHINE_START(R8A7740_DT, "Generic R8A7740 (Flattened Device Tree)")
        .init_machine   = r8a7740_generic_init,
        .init_late      = shmobile_init_late,
        .dt_compat      = r8a7740_boards_compat_dt,
+       .restart        = r8a7740_restart,
 MACHINE_END
 
 #endif /* CONFIG_USE_OF */
index 8d83264..6961c2d 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
 #include <linux/kernel.h>
@@ -293,8 +289,6 @@ void __init r8a7778_add_dt_devices(void)
                l2x0_init(base, 0x40470000, 0x82000fff);
        }
 #endif
-
-       r8a7778_register_tmu(0);
 }
 
 /* HPB-DMA */
@@ -502,6 +496,7 @@ static void __init r8a7778_register_hpb_dmae(void)
 void __init r8a7778_add_standard_devices(void)
 {
        r8a7778_add_dt_devices();
+       r8a7778_register_tmu(0);
        r8a7778_register_scif(0);
        r8a7778_register_scif(1);
        r8a7778_register_scif(2);
@@ -521,6 +516,7 @@ void __init r8a7778_add_standard_devices(void)
 
 void __init r8a7778_init_late(void)
 {
+       shmobile_init_late();
        platform_device_register_full(&ehci_info);
        platform_device_register_full(&ohci_info);
 }
@@ -572,11 +568,6 @@ void __init r8a7778_init_irq_extpin(int irlm)
                        &irqpin_platform_data, sizeof(irqpin_platform_data));
 }
 
-void __init r8a7778_init_delay(void)
-{
-       shmobile_setup_delay(800, 1, 3); /* Cortex-A9 @ 800MHz */
-}
-
 #ifdef CONFIG_USE_OF
 #define INT2SMSKCR0    0x82288 /* 0xfe782288 */
 #define INT2SMSKCR1    0x8228c /* 0xfe78228c */
@@ -608,10 +599,10 @@ static const char *r8a7778_compat_dt[] __initdata = {
 };
 
 DT_MACHINE_START(R8A7778_DT, "Generic R8A7778 (Flattened Device Tree)")
-       .init_early     = r8a7778_init_delay,
+       .init_early     = shmobile_init_delay,
        .init_irq       = r8a7778_init_irq_dt,
+       .init_late      = shmobile_init_late,
        .dt_compat      = r8a7778_compat_dt,
-       .init_late      = r8a7778_init_late,
 MACHINE_END
 
 #endif /* CONFIG_USE_OF */
index 5845df3..67c26c5 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include "r8a7779.h"
 
 static struct map_desc r8a7779_io_desc[] __initdata = {
-       /* 2M entity map for 0xf0000000 (MPCORE) */
+       /* 2M identity mapping for 0xf0000000 (MPCORE) */
        {
                .virtual        = 0xf0000000,
                .pfn            = __phys_to_pfn(0xf0000000),
                .length         = SZ_2M,
                .type           = MT_DEVICE_NONSHARED
        },
-       /* 16M entity map for 0xfexxxxxx (DMAC-S/HPBREG/INTC2/LRAM/DBSC) */
+       /* 16M identity mapping for 0xfexxxxxx (DMAC-S/HPBREG/INTC2/LRAM/DBSC) */
        {
                .virtual        = 0xfe000000,
                .pfn            = __phys_to_pfn(0xfe000000),
@@ -70,6 +66,7 @@ static struct map_desc r8a7779_io_desc[] __initdata = {
 
 void __init r8a7779_map_io(void)
 {
+       debug_ll_io_init();
        iotable_init(r8a7779_io_desc, ARRAY_SIZE(r8a7779_io_desc));
 }
 
@@ -641,7 +638,7 @@ static void __init r8a7779_register_hpb_dmae(void)
                                          sizeof(dma_platform_data));
 }
 
-static struct platform_device *r8a7779_devices_dt[] __initdata = {
+static struct platform_device *r8a7779_early_devices[] __initdata = {
        &tmu0_device,
 };
 
@@ -669,8 +666,8 @@ void __init r8a7779_add_standard_devices(void)
 
        r8a7779_init_pm_domains();
 
-       platform_add_devices(r8a7779_devices_dt,
-                           ARRAY_SIZE(r8a7779_devices_dt));
+       platform_add_devices(r8a7779_early_devices,
+                           ARRAY_SIZE(r8a7779_early_devices));
        platform_add_devices(r8a7779_standard_devices,
                            ARRAY_SIZE(r8a7779_standard_devices));
        r8a7779_register_hpb_dmae();
@@ -678,12 +675,12 @@ void __init r8a7779_add_standard_devices(void)
 
 void __init r8a7779_add_early_devices(void)
 {
-       early_platform_add_devices(r8a7779_devices_dt,
-                                  ARRAY_SIZE(r8a7779_devices_dt));
+       early_platform_add_devices(r8a7779_early_devices,
+                                  ARRAY_SIZE(r8a7779_early_devices));
 
        /* Early serial console setup is not included here due to
         * memory map collisions. The SCIF serial ports in r8a7779
-        * are difficult to entity map 1:1 due to collision with the
+        * are difficult to identity map 1:1 due to collision with the
         * virtual memory range used by the coherent DMA code on ARM.
         *
         * Anyone wanting to debug early can remove UPF_IOREMAP from
@@ -739,12 +736,6 @@ void __init r8a7779_init_irq_dt(void)
        __raw_writel(0x003fee3f, INT2SMSKCR4);
 }
 
-void __init r8a7779_add_standard_devices_dt(void)
-{
-       platform_add_devices(r8a7779_devices_dt,
-                            ARRAY_SIZE(r8a7779_devices_dt));
-}
-
 #define MODEMR         0xffcc0020
 
 u32 __init r8a7779_read_mode_pins(void)
@@ -771,10 +762,8 @@ static const char *r8a7779_compat_dt[] __initdata = {
 DT_MACHINE_START(R8A7779_DT, "Generic R8A7779 (Flattened Device Tree)")
        .map_io         = r8a7779_map_io,
        .init_early     = shmobile_init_delay,
-       .nr_irqs        = NR_IRQS_LEGACY,
        .init_irq       = r8a7779_init_irq_dt,
-       .init_machine   = r8a7779_add_standard_devices_dt,
-       .init_late      = r8a7779_init_late,
+       .init_late      = shmobile_init_late,
        .dt_compat      = r8a7779_compat_dt,
 MACHINE_END
 #endif /* CONFIG_USE_OF */
index c37d82d..7325170 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
 #include <linux/irq.h>
@@ -282,11 +278,6 @@ static struct resource cmt0_resources[] = {
                                          &cmt##idx##_platform_data,    \
                                          sizeof(struct sh_timer_config))
 
-void __init r8a7790_add_dt_devices(void)
-{
-       r8a7790_register_cmt(0);
-}
-
 void __init r8a7790_add_standard_devices(void)
 {
        r8a7790_register_scif(0);
@@ -299,7 +290,7 @@ void __init r8a7790_add_standard_devices(void)
        r8a7790_register_scif(7);
        r8a7790_register_scif(8);
        r8a7790_register_scif(9);
-       r8a7790_add_dt_devices();
+       r8a7790_register_cmt(0);
        r8a7790_register_irqc(0);
        r8a7790_register_thermal();
        r8a7790_register_i2c(0);
index 8823324..ef8eb3a 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-#include <linux/irq.h>
-#include <linux/kernel.h>
-#include <linux/of_platform.h>
-#include <linux/platform_data/gpio-rcar.h>
-#include <linux/platform_data/irq-renesas-irqc.h>
-#include <linux/serial_sci.h>
-#include <linux/sh_timer.h>
+#include <linux/init.h>
 
 #include <asm/mach/arch.h>
 
 #include "common.h"
-#include "irqs.h"
 #include "r8a7791.h"
 #include "rcar-gen2.h"
 
-static const struct resource pfc_resources[] __initconst = {
-       DEFINE_RES_MEM(0xe6060000, 0x250),
-};
-
-#define r8a7791_register_pfc()                                         \
-       platform_device_register_simple("pfc-r8a7791", -1, pfc_resources, \
-                                       ARRAY_SIZE(pfc_resources))
-
-#define R8A7791_GPIO(idx, base, nr)                                    \
-static const struct resource r8a7791_gpio##idx##_resources[] __initconst = { \
-       DEFINE_RES_MEM((base), 0x50),                                   \
-       DEFINE_RES_IRQ(gic_spi(4 + (idx))),                             \
-};                                                                     \
-                                                                       \
-static const struct gpio_rcar_config                                   \
-r8a7791_gpio##idx##_platform_data __initconst = {                      \
-       .gpio_base      = 32 * (idx),                                   \
-       .irq_base       = 0,                                            \
-       .number_of_pins = (nr),                                         \
-       .pctl_name      = "pfc-r8a7791",                                \
-       .has_both_edge_trigger = 1,                                     \
-};                                                                     \
-
-R8A7791_GPIO(0, 0xe6050000, 32);
-R8A7791_GPIO(1, 0xe6051000, 32);
-R8A7791_GPIO(2, 0xe6052000, 32);
-R8A7791_GPIO(3, 0xe6053000, 32);
-R8A7791_GPIO(4, 0xe6054000, 32);
-R8A7791_GPIO(5, 0xe6055000, 32);
-R8A7791_GPIO(6, 0xe6055400, 32);
-R8A7791_GPIO(7, 0xe6055800, 26);
-
-#define r8a7791_register_gpio(idx)                                     \
-       platform_device_register_resndata(&platform_bus, "gpio_rcar", idx, \
-               r8a7791_gpio##idx##_resources,                          \
-               ARRAY_SIZE(r8a7791_gpio##idx##_resources),              \
-               &r8a7791_gpio##idx##_platform_data,                     \
-               sizeof(r8a7791_gpio##idx##_platform_data))
-
-void __init r8a7791_pinmux_init(void)
-{
-       r8a7791_register_pfc();
-       r8a7791_register_gpio(0);
-       r8a7791_register_gpio(1);
-       r8a7791_register_gpio(2);
-       r8a7791_register_gpio(3);
-       r8a7791_register_gpio(4);
-       r8a7791_register_gpio(5);
-       r8a7791_register_gpio(6);
-       r8a7791_register_gpio(7);
-}
-
-#define __R8A7791_SCIF(scif_type, index, baseaddr, irq)                        \
-static struct plat_sci_port scif##index##_platform_data = {            \
-       .type           = scif_type,                                    \
-       .flags          = UPF_BOOT_AUTOCONF | UPF_IOREMAP,              \
-       .scscr          = SCSCR_RE | SCSCR_TE,                          \
-};                                                                     \
-                                                                       \
-static struct resource scif##index##_resources[] = {                   \
-       DEFINE_RES_MEM(baseaddr, 0x100),                                \
-       DEFINE_RES_IRQ(irq),                                            \
-}
-
-#define R8A7791_SCIF(index, baseaddr, irq)                             \
-       __R8A7791_SCIF(PORT_SCIF, index, baseaddr, irq)
-
-#define R8A7791_SCIFA(index, baseaddr, irq)                            \
-       __R8A7791_SCIF(PORT_SCIFA, index, baseaddr, irq)
-
-#define R8A7791_SCIFB(index, baseaddr, irq)                            \
-       __R8A7791_SCIF(PORT_SCIFB, index, baseaddr, irq)
-
-R8A7791_SCIFA(0,  0xe6c40000, gic_spi(144)); /* SCIFA0 */
-R8A7791_SCIFA(1,  0xe6c50000, gic_spi(145)); /* SCIFA1 */
-R8A7791_SCIFB(2,  0xe6c20000, gic_spi(148)); /* SCIFB0 */
-R8A7791_SCIFB(3,  0xe6c30000, gic_spi(149)); /* SCIFB1 */
-R8A7791_SCIFB(4,  0xe6ce0000, gic_spi(150)); /* SCIFB2 */
-R8A7791_SCIFA(5,  0xe6c60000, gic_spi(151)); /* SCIFA2 */
-R8A7791_SCIF(6,   0xe6e60000, gic_spi(152)); /* SCIF0 */
-R8A7791_SCIF(7,   0xe6e68000, gic_spi(153)); /* SCIF1 */
-R8A7791_SCIF(8,   0xe6e58000, gic_spi(22)); /* SCIF2 */
-R8A7791_SCIF(9,   0xe6ea8000, gic_spi(23)); /* SCIF3 */
-R8A7791_SCIF(10,  0xe6ee0000, gic_spi(24)); /* SCIF4 */
-R8A7791_SCIF(11,  0xe6ee8000, gic_spi(25)); /* SCIF5 */
-R8A7791_SCIFA(12, 0xe6c70000, gic_spi(29)); /* SCIFA3 */
-R8A7791_SCIFA(13, 0xe6c78000, gic_spi(30)); /* SCIFA4 */
-R8A7791_SCIFA(14, 0xe6c80000, gic_spi(31)); /* SCIFA5 */
-
-#define r8a7791_register_scif(index)                                          \
-       platform_device_register_resndata(&platform_bus, "sh-sci", index,      \
-                                         scif##index##_resources,             \
-                                         ARRAY_SIZE(scif##index##_resources), \
-                                         &scif##index##_platform_data,        \
-                                         sizeof(scif##index##_platform_data))
-
-static struct sh_timer_config cmt0_platform_data = {
-       .channels_mask = 0x60,
-};
-
-static struct resource cmt0_resources[] = {
-       DEFINE_RES_MEM(0xffca0000, 0x1004),
-       DEFINE_RES_IRQ(gic_spi(142)),
-};
-
-#define r8a7791_register_cmt(idx)                                      \
-       platform_device_register_resndata(&platform_bus, "sh-cmt-48-gen2", \
-                                         idx, cmt##idx##_resources,    \
-                                         ARRAY_SIZE(cmt##idx##_resources), \
-                                         &cmt##idx##_platform_data,    \
-                                         sizeof(struct sh_timer_config))
-
-static struct renesas_irqc_config irqc0_data = {
-       .irq_base = irq_pin(0), /* IRQ0 -> IRQ9 */
-};
-
-static struct resource irqc0_resources[] = {
-       DEFINE_RES_MEM(0xe61c0000, 0x200), /* IRQC Event Detector Block_0 */
-       DEFINE_RES_IRQ(gic_spi(0)), /* IRQ0 */
-       DEFINE_RES_IRQ(gic_spi(1)), /* IRQ1 */
-       DEFINE_RES_IRQ(gic_spi(2)), /* IRQ2 */
-       DEFINE_RES_IRQ(gic_spi(3)), /* IRQ3 */
-       DEFINE_RES_IRQ(gic_spi(12)), /* IRQ4 */
-       DEFINE_RES_IRQ(gic_spi(13)), /* IRQ5 */
-       DEFINE_RES_IRQ(gic_spi(14)), /* IRQ6 */
-       DEFINE_RES_IRQ(gic_spi(15)), /* IRQ7 */
-       DEFINE_RES_IRQ(gic_spi(16)), /* IRQ8 */
-       DEFINE_RES_IRQ(gic_spi(17)), /* IRQ9 */
-};
-
-#define r8a7791_register_irqc(idx)                                     \
-       platform_device_register_resndata(&platform_bus, "renesas_irqc", \
-                                         idx, irqc##idx##_resources,   \
-                                         ARRAY_SIZE(irqc##idx##_resources), \
-                                         &irqc##idx##_data,            \
-                                         sizeof(struct renesas_irqc_config))
-
-static const struct resource thermal_resources[] __initconst = {
-       DEFINE_RES_MEM(0xe61f0000, 0x14),
-       DEFINE_RES_MEM(0xe61f0100, 0x38),
-       DEFINE_RES_IRQ(gic_spi(69)),
-};
-
-#define r8a7791_register_thermal()                                     \
-       platform_device_register_simple("rcar_thermal", -1,             \
-                                       thermal_resources,              \
-                                       ARRAY_SIZE(thermal_resources))
-
-void __init r8a7791_add_dt_devices(void)
-{
-       r8a7791_register_cmt(0);
-}
-
-void __init r8a7791_add_standard_devices(void)
-{
-       r8a7791_register_scif(0);
-       r8a7791_register_scif(1);
-       r8a7791_register_scif(2);
-       r8a7791_register_scif(3);
-       r8a7791_register_scif(4);
-       r8a7791_register_scif(5);
-       r8a7791_register_scif(6);
-       r8a7791_register_scif(7);
-       r8a7791_register_scif(8);
-       r8a7791_register_scif(9);
-       r8a7791_register_scif(10);
-       r8a7791_register_scif(11);
-       r8a7791_register_scif(12);
-       r8a7791_register_scif(13);
-       r8a7791_register_scif(14);
-       r8a7791_add_dt_devices();
-       r8a7791_register_irqc(0);
-       r8a7791_register_thermal();
-}
-
-#ifdef CONFIG_USE_OF
 static const char *r8a7791_boards_compat_dt[] __initdata = {
        "renesas,r8a7791",
        NULL,
@@ -223,4 +36,3 @@ DT_MACHINE_START(R8A7791_DT, "Generic R8A7791 (Flattened Device Tree)")
        .reserve        = rcar_gen2_reserve,
        .dt_compat      = r8a7791_boards_compat_dt,
 MACHINE_END
-#endif /* CONFIG_USE_OF */
diff --git a/arch/arm/mach-shmobile/setup-r8a7794.c b/arch/arm/mach-shmobile/setup-r8a7794.c
new file mode 100644 (file)
index 0000000..d2b0930
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * r8a7794 processor support
+ *
+ * Copyright (C) 2014  Renesas Electronics Corporation
+ * Copyright (C) 2014  Ulrich Hecht
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/of_platform.h>
+#include "common.h"
+#include "rcar-gen2.h"
+#include <asm/mach/arch.h>
+
+static const char * const r8a7794_boards_compat_dt[] __initconst = {
+       "renesas,r8a7794",
+       NULL,
+};
+
+DT_MACHINE_START(R8A7794_DT, "Generic R8A7794 (Flattened Device Tree)")
+       .init_early     = shmobile_init_delay,
+       .init_late      = shmobile_init_late,
+       .init_time      = rcar_gen2_timer_init,
+       .reserve        = rcar_gen2_reserve,
+       .dt_compat      = r8a7794_boards_compat_dt,
+MACHINE_END
index 73fb2a6..e1e76e1 100644 (file)
@@ -3,6 +3,7 @@
  *
  * Copyright (C) 2013  Renesas Solutions Corp.
  * Copyright (C) 2013  Magnus Damm
+ * Copyright (C) 2014  Ulrich Hecht
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
 #include <linux/clk/shmobile.h>
@@ -24,6 +21,7 @@
 #include <linux/dma-contiguous.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
+#include <linux/of.h>
 #include <linux/of_fdt.h>
 #include <asm/mach/arch.h>
 #include "common.h"
@@ -54,37 +52,61 @@ void __init rcar_gen2_timer_init(void)
 {
 #if defined(CONFIG_ARM_ARCH_TIMER) || defined(CONFIG_COMMON_CLK)
        u32 mode = rcar_gen2_read_mode_pins();
+       bool is_e2 = (bool)of_find_compatible_node(NULL, NULL,
+               "renesas,r8a7794");
 #endif
 #ifdef CONFIG_ARM_ARCH_TIMER
        void __iomem *base;
        int extal_mhz = 0;
        u32 freq;
 
-       /* At Linux boot time the r8a7790 arch timer comes up
-        * with the counter disabled. Moreover, it may also report
-        * a potentially incorrect fixed 13 MHz frequency. To be
-        * correct these registers need to be updated to use the
-        * frequency EXTAL / 2 which can be determined by the MD pins.
-        */
-
-       switch (mode & (MD(14) | MD(13))) {
-       case 0:
-               extal_mhz = 15;
-               break;
-       case MD(13):
-               extal_mhz = 20;
-               break;
-       case MD(14):
-               extal_mhz = 26;
-               break;
-       case MD(13) | MD(14):
-               extal_mhz = 30;
-               break;
+       if (is_e2) {
+               freq = 260000000 / 8;   /* ZS / 8 */
+               /* CNTVOFF has to be initialized either from non-secure
+                * Hypervisor mode or secure Monitor mode with SCR.NS==1.
+                * If TrustZone is enabled then it should be handled by the
+                * secure code.
+                */
+               asm volatile(
+               "       cps     0x16\n"
+               "       mrc     p15, 0, r1, c1, c1, 0\n"
+               "       orr     r0, r1, #1\n"
+               "       mcr     p15, 0, r0, c1, c1, 0\n"
+               "       isb\n"
+               "       mov     r0, #0\n"
+               "       mcrr    p15, 4, r0, r0, c14\n"
+               "       isb\n"
+               "       mcr     p15, 0, r1, c1, c1, 0\n"
+               "       isb\n"
+               "       cps     0x13\n"
+                       : : : "r0", "r1");
+       } else {
+               /* At Linux boot time the r8a7790 arch timer comes up
+                * with the counter disabled. Moreover, it may also report
+                * a potentially incorrect fixed 13 MHz frequency. To be
+                * correct these registers need to be updated to use the
+                * frequency EXTAL / 2 which can be determined by the MD pins.
+                */
+
+               switch (mode & (MD(14) | MD(13))) {
+               case 0:
+                       extal_mhz = 15;
+                       break;
+               case MD(13):
+                       extal_mhz = 20;
+                       break;
+               case MD(14):
+                       extal_mhz = 26;
+                       break;
+               case MD(13) | MD(14):
+                       extal_mhz = 30;
+                       break;
+               }
+
+               /* The arch timer frequency equals EXTAL / 2 */
+               freq = extal_mhz * (1000000 / 2);
        }
 
-       /* The arch timer frequency equals EXTAL / 2 */
-       freq = extal_mhz * (1000000 / 2);
-
        /* Remap "armgcnt address map" space */
        base = ioremap(0xe6080000, PAGE_SIZE);
 
index 9cdfcdf..458a2cf 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
 
 #include "common.h"
 #include "dma-register.h"
+#include "intc.h"
 #include "irqs.h"
 #include "pm-rmobile.h"
 #include "sh7372.h"
 
 static struct map_desc sh7372_io_desc[] __initdata = {
-       /* create a 1:1 entity map for 0xe6xxxxxx
+       /* create a 1:1 identity mapping for 0xe6xxxxxx
         * used by CPGA, INTC and PFC.
         */
        {
@@ -59,6 +56,7 @@ static struct map_desc sh7372_io_desc[] __initdata = {
 
 void __init sh7372_map_io(void)
 {
+       debug_ll_io_init();
        iotable_init(sh7372_io_desc, ARRAY_SIZE(sh7372_io_desc));
 }
 
@@ -927,7 +925,7 @@ static struct platform_device *sh7372_late_devices[] __initdata = {
 
 void __init sh7372_add_standard_devices(void)
 {
-       struct pm_domain_device domain_devices[] = {
+       static struct pm_domain_device domain_devices[] __initdata = {
                { "A3RV", &vpu_device, },
                { "A4MP", &spu0_device, },
                { "A4MP", &spu1_device, },
@@ -984,7 +982,7 @@ void __init sh7372_add_early_devices(void)
 
 void __init sh7372_add_early_devices_dt(void)
 {
-       shmobile_setup_delay(800, 1, 3); /* Cortex-A8 @ 800MHz */
+       shmobile_init_delay();
 
        sh7372_add_early_devices();
 }
@@ -1008,10 +1006,10 @@ static const char *sh7372_boards_compat_dt[] __initdata = {
 DT_MACHINE_START(SH7372_DT, "Generic SH7372 (Flattened Device Tree)")
        .map_io         = sh7372_map_io,
        .init_early     = sh7372_add_early_devices_dt,
-       .nr_irqs        = NR_IRQS_LEGACY,
        .init_irq       = sh7372_init_irq,
        .handle_irq     = shmobile_handle_irq_intc,
        .init_machine   = sh7372_add_standard_devices_dt,
+       .init_late      = shmobile_init_late,
        .dt_compat      = sh7372_boards_compat_dt,
 MACHINE_END
 
index 2c802ae..93ebe34 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -26,6 +22,7 @@
 #include <linux/of_platform.h>
 #include <linux/delay.h>
 #include <linux/input.h>
+#include <linux/i2c/i2c-sh_mobile.h>
 #include <linux/io.h>
 #include <linux/serial_sci.h>
 #include <linux/sh_dma.h>
 
 #include "common.h"
 #include "dma-register.h"
+#include "intc.h"
 #include "irqs.h"
 #include "sh73a0.h"
 
 static struct map_desc sh73a0_io_desc[] __initdata = {
-       /* create a 1:1 entity map for 0xe6xxxxxx
+       /* create a 1:1 identity mapping for 0xe6xxxxxx
         * used by CPGA, INTC and PFC.
         */
        {
@@ -57,6 +55,7 @@ static struct map_desc sh73a0_io_desc[] __initdata = {
 
 void __init sh73a0_map_io(void)
 {
+       debug_ll_io_init();
        iotable_init(sh73a0_io_desc, ARRAY_SIZE(sh73a0_io_desc));
 }
 
@@ -191,11 +190,18 @@ static struct resource i2c4_resources[] = {
        },
 };
 
+static struct i2c_sh_mobile_platform_data i2c_platform_data = {
+       .clks_per_count = 2,
+};
+
 static struct platform_device i2c0_device = {
        .name           = "i2c-sh_mobile",
        .id             = 0,
        .resource       = i2c0_resources,
        .num_resources  = ARRAY_SIZE(i2c0_resources),
+       .dev            = {
+               .platform_data  = &i2c_platform_data,
+       },
 };
 
 static struct platform_device i2c1_device = {
@@ -203,6 +209,9 @@ static struct platform_device i2c1_device = {
        .id             = 1,
        .resource       = i2c1_resources,
        .num_resources  = ARRAY_SIZE(i2c1_resources),
+       .dev            = {
+               .platform_data  = &i2c_platform_data,
+       },
 };
 
 static struct platform_device i2c2_device = {
@@ -210,6 +219,9 @@ static struct platform_device i2c2_device = {
        .id             = 2,
        .resource       = i2c2_resources,
        .num_resources  = ARRAY_SIZE(i2c2_resources),
+       .dev            = {
+               .platform_data  = &i2c_platform_data,
+       },
 };
 
 static struct platform_device i2c3_device = {
@@ -217,6 +229,9 @@ static struct platform_device i2c3_device = {
        .id             = 3,
        .resource       = i2c3_resources,
        .num_resources  = ARRAY_SIZE(i2c3_resources),
+       .dev            = {
+               .platform_data  = &i2c_platform_data,
+       },
 };
 
 static struct platform_device i2c4_device = {
@@ -224,6 +239,9 @@ static struct platform_device i2c4_device = {
        .id             = 4,
        .resource       = i2c4_resources,
        .num_resources  = ARRAY_SIZE(i2c4_resources),
+       .dev            = {
+               .platform_data  = &i2c_platform_data,
+       },
 };
 
 static const struct sh_dmae_slave_config sh73a0_dmae_slaves[] = {
@@ -696,10 +714,6 @@ static struct platform_device irqpin3_device = {
        },
 };
 
-static struct platform_device *sh73a0_devices_dt[] __initdata = {
-       &cmt1_device,
-};
-
 static struct platform_device *sh73a0_early_devices[] __initdata = {
        &scif0_device,
        &scif1_device,
@@ -712,6 +726,7 @@ static struct platform_device *sh73a0_early_devices[] __initdata = {
        &scif8_device,
        &tmu0_device,
        &ipmmu_device,
+       &cmt1_device,
 };
 
 static struct platform_device *sh73a0_late_devices[] __initdata = {
@@ -736,25 +751,18 @@ void __init sh73a0_add_standard_devices(void)
        /* Clear software reset bit on SY-DMAC module */
        __raw_writel(__raw_readl(SRCR2) & ~(1 << 18), SRCR2);
 
-       platform_add_devices(sh73a0_devices_dt,
-                           ARRAY_SIZE(sh73a0_devices_dt));
        platform_add_devices(sh73a0_early_devices,
                            ARRAY_SIZE(sh73a0_early_devices));
        platform_add_devices(sh73a0_late_devices,
                            ARRAY_SIZE(sh73a0_late_devices));
 }
 
-void __init sh73a0_init_delay(void)
-{
-       shmobile_setup_delay(1196, 44, 46); /* Cortex-A9 @ 1196MHz */
-}
-
 /* do nothing for !CONFIG_SMP or !CONFIG_HAVE_TWD */
 void __init __weak sh73a0_register_twd(void) { }
 
 void __init sh73a0_earlytimer_init(void)
 {
-       sh73a0_init_delay();
+       shmobile_init_delay();
        sh73a0_clock_init();
        shmobile_earlytimer_init();
        sh73a0_register_twd();
@@ -762,8 +770,6 @@ void __init sh73a0_earlytimer_init(void)
 
 void __init sh73a0_add_early_devices(void)
 {
-       early_platform_add_devices(sh73a0_devices_dt,
-                                  ARRAY_SIZE(sh73a0_devices_dt));
        early_platform_add_devices(sh73a0_early_devices,
                                   ARRAY_SIZE(sh73a0_early_devices));
 
@@ -775,17 +781,17 @@ void __init sh73a0_add_early_devices(void)
 
 void __init sh73a0_add_standard_devices_dt(void)
 {
-       struct platform_device_info devinfo = { .name = "cpufreq-cpu0", .id = -1, };
-
        /* clocks are setup late during boot in the case of DT */
        sh73a0_clock_init();
 
-       platform_add_devices(sh73a0_devices_dt,
-                            ARRAY_SIZE(sh73a0_devices_dt));
        of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
 
-       /* Instantiate cpufreq-cpu0 */
-       platform_device_register_full(&devinfo);
+#define RESCNT2 IOMEM(0xe6188020)
+static void sh73a0_restart(enum reboot_mode mode, const char *cmd)
+{
+       /* Do soft power on reset */
+       writel((1 << 31), RESCNT2);
 }
 
 static const char *sh73a0_boards_compat_dt[] __initdata = {
@@ -796,9 +802,10 @@ static const char *sh73a0_boards_compat_dt[] __initdata = {
 DT_MACHINE_START(SH73A0_DT, "Generic SH73A0 (Flattened Device Tree)")
        .smp            = smp_ops(sh73a0_smp_ops),
        .map_io         = sh73a0_map_io,
-       .init_early     = sh73a0_init_delay,
-       .nr_irqs        = NR_IRQS_LEGACY,
+       .init_early     = shmobile_init_delay,
        .init_machine   = sh73a0_add_standard_devices_dt,
+       .init_late      = shmobile_init_late,
+       .restart        = sh73a0_restart,
        .dt_compat      = sh73a0_boards_compat_dt,
 MACHINE_END
 #endif /* CONFIG_USE_OF */
index 359b582..f037c64 100644 (file)
@@ -71,7 +71,6 @@ enum {
 #define SH73A0_PINT0_IRQ(irq) ((irq) + 700)
 #define SH73A0_PINT1_IRQ(irq) ((irq) + 732)
 
-extern void sh73a0_init_delay(void);
 extern void sh73a0_init_irq(void);
 extern void sh73a0_init_irq_dt(void);
 extern void sh73a0_map_io(void);
index 9782862..146b8de 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
  */
 
 #include <linux/linkage.h>
index 6ff1df1..baff3b5 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
index 3100e35..3f761f8 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
index 2311694..9c3da13 100644 (file)
@@ -21,6 +21,7 @@
 #include <asm/smp_plat.h>
 
 #include "common.h"
+#include "platsmp-apmu.h"
 #include "pm-rcar.h"
 #include "r8a7790.h"
 
@@ -34,10 +35,23 @@ static struct rcar_sysc_ch r8a7790_ca7_scu = {
        .isr_bit = 21, /* CA7-SCU */
 };
 
+static struct rcar_apmu_config r8a7790_apmu_config[] = {
+       {
+               .iomem = DEFINE_RES_MEM(0xe6152000, 0x88),
+               .cpus = { 0, 1, 2, 3 },
+       },
+       {
+               .iomem = DEFINE_RES_MEM(0xe6151000, 0x88),
+               .cpus = { 0x100, 0x0101, 0x102, 0x103 },
+       }
+};
+
 static void __init r8a7790_smp_prepare_cpus(unsigned int max_cpus)
 {
        /* let APMU code install data related to shmobile_boot_vector */
-       shmobile_smp_apmu_prepare_cpus(max_cpus);
+       shmobile_smp_apmu_prepare_cpus(max_cpus,
+                                      r8a7790_apmu_config,
+                                      ARRAY_SIZE(r8a7790_apmu_config));
 
        /* turn on power to SCU */
        r8a7790_pm_init();
index f743386..7e49e0a 100644 (file)
 #include <asm/smp_plat.h>
 
 #include "common.h"
+#include "platsmp-apmu.h"
 #include "r8a7791.h"
 #include "rcar-gen2.h"
 
+static struct rcar_apmu_config r8a7791_apmu_config[] = {
+       {
+               .iomem = DEFINE_RES_MEM(0xe6152000, 0x88),
+               .cpus = { 0, 1 },
+       }
+};
+
 static void __init r8a7791_smp_prepare_cpus(unsigned int max_cpus)
 {
        /* let APMU code install data related to shmobile_boot_vector */
-       shmobile_smp_apmu_prepare_cpus(max_cpus);
+       shmobile_smp_apmu_prepare_cpus(max_cpus,
+                                      r8a7791_apmu_config,
+                                      ARRAY_SIZE(r8a7791_apmu_config));
 
        r8a7791_pm_init();
 }
index 22d8f87..c16dbfe 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
index 942efdc..f1d027a 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
  */
 #include <linux/platform_device.h>
 #include <linux/clocksource.h>
 #include <linux/delay.h>
 #include <linux/of_address.h>
 
-void __init shmobile_setup_delay_hz(unsigned int max_cpu_core_hz,
-                                   unsigned int mult, unsigned int div)
+static void __init shmobile_setup_delay_hz(unsigned int max_cpu_core_hz,
+                                          unsigned int mult, unsigned int div)
 {
        /* calculate a worst-case loops-per-jiffy value
         * based on maximum cpu core hz setting and the
@@ -40,28 +35,12 @@ void __init shmobile_setup_delay_hz(unsigned int max_cpu_core_hz,
                preset_lpj = max_cpu_core_hz / value;
 }
 
-void __init shmobile_setup_delay(unsigned int max_cpu_core_mhz,
-                                unsigned int mult, unsigned int div)
-{
-       /* calculate a worst-case loops-per-jiffy value
-        * based on maximum cpu core mhz setting and the
-        * __delay() implementation in arch/arm/lib/delay.S
-        *
-        * this will result in a longer delay than expected
-        * when the cpu core runs on lower frequencies.
-        */
-
-       unsigned int value = (1000000 * mult) / (HZ * div);
-
-       if (!preset_lpj)
-               preset_lpj = max_cpu_core_mhz * value;
-}
-
 void __init shmobile_init_delay(void)
 {
        struct device_node *np, *cpus;
-       bool is_a8_a9 = false;
+       bool is_a7_a8_a9 = false;
        bool is_a15 = false;
+       bool has_arch_timer = false;
        u32 max_freq = 0;
 
        cpus = of_find_node_by_path("/cpus");
@@ -75,10 +54,15 @@ void __init shmobile_init_delay(void)
                        max_freq = max(max_freq, freq);
 
                if (of_device_is_compatible(np, "arm,cortex-a8") ||
-                   of_device_is_compatible(np, "arm,cortex-a9"))
-                       is_a8_a9 = true;
-               else if (of_device_is_compatible(np, "arm,cortex-a15"))
+                   of_device_is_compatible(np, "arm,cortex-a9")) {
+                       is_a7_a8_a9 = true;
+               } else if (of_device_is_compatible(np, "arm,cortex-a7")) {
+                       is_a7_a8_a9 = true;
+                       has_arch_timer = true;
+               } else if (of_device_is_compatible(np, "arm,cortex-a15")) {
                        is_a15 = true;
+                       has_arch_timer = true;
+               }
        }
 
        of_node_put(cpus);
@@ -86,10 +70,12 @@ void __init shmobile_init_delay(void)
        if (!max_freq)
                return;
 
-       if (is_a8_a9)
-               shmobile_setup_delay_hz(max_freq, 1, 3);
-       else if (is_a15 && !IS_ENABLED(CONFIG_ARM_ARCH_TIMER))
-               shmobile_setup_delay_hz(max_freq, 2, 4);
+       if (!has_arch_timer || !IS_ENABLED(CONFIG_ARM_ARCH_TIMER)) {
+               if (is_a7_a8_a9)
+                       shmobile_setup_delay_hz(max_freq, 1, 3);
+               else if (is_a15)
+                       shmobile_setup_delay_hz(max_freq, 2, 4);
+       }
 }
 
 static void __init shmobile_late_time_init(void)
index ca8ecde..e9c290c 100644 (file)
@@ -798,6 +798,7 @@ config NEED_KUSER_HELPERS
 
 config KUSER_HELPERS
        bool "Enable kuser helpers in vector page" if !NEED_KUSER_HELPERS
+       depends on MMU
        default y
        help
          Warning: disabling this option may break user programs.
index 74f6033..fdedc31 100644 (file)
@@ -211,7 +211,6 @@ __v7_pj4b_setup:
 /* Auxiliary Debug Modes Control 1 Register */
 #define PJ4B_STATIC_BP (1 << 2) /* Enable Static BP */
 #define PJ4B_INTER_PARITY (1 << 8) /* Disable Internal Parity Handling */
-#define PJ4B_BCK_OFF_STREX (1 << 5) /* Enable the back off of STREX instr */
 #define PJ4B_CLEAN_LINE (1 << 16) /* Disable data transfer for clean line */
 
 /* Auxiliary Debug Modes Control 2 Register */
@@ -234,7 +233,6 @@ __v7_pj4b_setup:
        /* Auxiliary Debug Modes Control 1 Register */
        mrc     p15, 1, r0, c15, c1, 1
        orr     r0, r0, #PJ4B_CLEAN_LINE
-       orr     r0, r0, #PJ4B_BCK_OFF_STREX
        orr     r0, r0, #PJ4B_INTER_PARITY
        bic     r0, r0, #PJ4B_STATIC_BP
        mcr     p15, 1, r0, c15, c1, 1
index d19b1cf..b34b95f 100644 (file)
@@ -535,7 +535,7 @@ ENTRY(cpu_xscale_do_suspend)
        mrc     p15, 0, r5, c15, c1, 0  @ CP access reg
        mrc     p15, 0, r6, c13, c0, 0  @ PID
        mrc     p15, 0, r7, c3, c0, 0   @ domain ID
-       mrc     p15, 0, r8, c1, c1, 0   @ auxiliary control reg
+       mrc     p15, 0, r8, c1, c0, 1   @ auxiliary control reg
        mrc     p15, 0, r9, c1, c0, 0   @ control reg
        bic     r4, r4, #2              @ clear frequency change bit
        stmia   r0, {r4 - r9}           @ store cp regs
@@ -552,7 +552,7 @@ ENTRY(cpu_xscale_do_resume)
        mcr     p15, 0, r6, c13, c0, 0  @ PID
        mcr     p15, 0, r7, c3, c0, 0   @ domain ID
        mcr     p15, 0, r1, c2, c0, 0   @ translation table base addr
-       mcr     p15, 0, r8, c1, c1, 0   @ auxiliary control reg
+       mcr     p15, 0, r8, c1, c0, 1   @ auxiliary control reg
        mov     r0, r9                  @ control register
        b       cpu_resume_mmu
 ENDPROC(cpu_xscale_do_resume)
index 9267d29..65f758b 100644 (file)
@@ -6,7 +6,6 @@
 
 obj-y                          :=
 obj-m                          :=
-obj-n                          := dummy.o
 obj-                           :=
 
 # Objects we always build independent of SoC choice
index 9400596..f190971 100644 (file)
@@ -104,37 +104,6 @@ static inline void arch_timer_set_cntkctl(u32 cntkctl)
        asm volatile("msr       cntkctl_el1, %0" : : "r" (cntkctl));
 }
 
-static inline void arch_counter_set_user_access(void)
-{
-       u32 cntkctl = arch_timer_get_cntkctl();
-
-       /* Disable user access to the timers and the physical counter */
-       /* Also disable virtual event stream */
-       cntkctl &= ~(ARCH_TIMER_USR_PT_ACCESS_EN
-                       | ARCH_TIMER_USR_VT_ACCESS_EN
-                       | ARCH_TIMER_VIRT_EVT_EN
-                       | ARCH_TIMER_USR_PCT_ACCESS_EN);
-
-       /* Enable user access to the virtual counter */
-       cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN;
-
-       arch_timer_set_cntkctl(cntkctl);
-}
-
-static inline void arch_timer_evtstrm_enable(int divider)
-{
-       u32 cntkctl = arch_timer_get_cntkctl();
-       cntkctl &= ~ARCH_TIMER_EVT_TRIGGER_MASK;
-       /* Set the divider and enable virtual event stream */
-       cntkctl |= (divider << ARCH_TIMER_EVT_TRIGGER_SHIFT)
-                       | ARCH_TIMER_VIRT_EVT_EN;
-       arch_timer_set_cntkctl(cntkctl);
-       elf_hwcap |= HWCAP_EVTSTRM;
-#ifdef CONFIG_COMPAT
-       compat_elf_hwcap |= COMPAT_HWCAP_EVTSTRM;
-#endif
-}
-
 static inline u64 arch_counter_get_cntvct(void)
 {
        u64 cval;
index 92f3683..565e26f 100644 (file)
@@ -156,9 +156,10 @@ static int __kprobes aarch64_insn_patch_text_cb(void *arg)
                 * which ends with "dsb; isb" pair guaranteeing global
                 * visibility.
                 */
-               atomic_set(&pp->cpu_count, -1);
+               /* Notify other processors with an additional increment. */
+               atomic_inc(&pp->cpu_count);
        } else {
-               while (atomic_read(&pp->cpu_count) != -1)
+               while (atomic_read(&pp->cpu_count) <= num_online_cpus())
                        cpu_relax();
                isb();
        }
index 6e0ed93..c17967f 100644 (file)
@@ -46,7 +46,7 @@ USER(9f, strh wzr, [x0], #2   )
        sub     x1, x1, #2
 4:     adds    x1, x1, #1
        b.mi    5f
-       strb    wzr, [x0]
+USER(9f, strb  wzr, [x0]       )
 5:     mov     x0, #0
        ret
 ENDPROC(__clear_user)
index 9e4484c..9005a8d 100644 (file)
@@ -11,7 +11,8 @@ obj-$(CONFIG_PCI) += pci.o
 # Serial port support
 #
 obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
-obj-$(CONFIG_SERIAL_8250) += serial.o
+loongson-serial-$(CONFIG_SERIAL_8250) := serial.o
+obj-y += $(loongson-serial-m) $(loongson-serial-y)
 obj-$(CONFIG_LOONGSON_UART_BASE) += uart_base.o
 obj-$(CONFIG_LOONGSON_MC146818) += rtc.o
 
index 6854ed5..83a1dfd 100644 (file)
@@ -92,7 +92,7 @@ static inline int unwind_user_frame(struct stackframe *old_frame,
                                /* This marks the end of the previous function,
                                   which means we overran. */
                                break;
-                       stack_size = (unsigned) stack_adjustment;
+                       stack_size = (unsigned long) stack_adjustment;
                } else if (is_ra_save_ins(&ip)) {
                        int ra_slot = ip.i_format.simmediate;
                        if (ra_slot < 0)
index 0a3eada..f395cde 100644 (file)
@@ -36,23 +36,16 @@ struct shmid64_ds {
        unsigned int            __unused2;
 };
 
-#ifdef CONFIG_64BIT
-/* The 'unsigned int' (formerly 'unsigned long') data types below will
- * ensure that a 32-bit app calling shmctl(*,IPC_INFO,*) will work on
- * a wide kernel, but if some of these values are meant to contain pointers
- * they may need to be 'long long' instead. -PB XXX FIXME
- */
-#endif
 struct shminfo64 {
-       unsigned int    shmmax;
-       unsigned int    shmmin;
-       unsigned int    shmmni;
-       unsigned int    shmseg;
-       unsigned int    shmall;
-       unsigned int    __unused1;
-       unsigned int    __unused2;
-       unsigned int    __unused3;
-       unsigned int    __unused4;
+       unsigned long   shmmax;
+       unsigned long   shmmin;
+       unsigned long   shmmni;
+       unsigned long   shmseg;
+       unsigned long   shmall;
+       unsigned long   __unused1;
+       unsigned long   __unused2;
+       unsigned long   __unused3;
+       unsigned long   __unused4;
 };
 
 #endif /* _PARISC_SHMBUF_H */
index 7dd8a3b..fc77d53 100644 (file)
        ENTRY_COMP(msgsnd)
        ENTRY_COMP(msgrcv)
        ENTRY_SAME(msgget)              /* 190 */
-       ENTRY_SAME(msgctl)
-       ENTRY_SAME(shmat)
+       ENTRY_COMP(msgctl)
+       ENTRY_COMP(shmat)
        ENTRY_SAME(shmdt)
        ENTRY_SAME(shmget)
-       ENTRY_SAME(shmctl)              /* 195 */
+       ENTRY_COMP(shmctl)              /* 195 */
        ENTRY_SAME(ni_syscall)          /* streams1 */
        ENTRY_SAME(ni_syscall)          /* streams2 */
        ENTRY_SAME(lstat64)
        ENTRY_SAME(epoll_ctl)           /* 225 */
        ENTRY_SAME(epoll_wait)
        ENTRY_SAME(remap_file_pages)
-       ENTRY_SAME(semtimedop)
+       ENTRY_COMP(semtimedop)
        ENTRY_COMP(mq_open)
        ENTRY_SAME(mq_unlink)           /* 230 */
        ENTRY_COMP(mq_timedsend)
index beedaf0..d558b85 100644 (file)
@@ -902,7 +902,6 @@ static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev,
                                  unsigned int is_64, struct msi_msg *msg)
 {
        struct pnv_ioda_pe *pe = pnv_ioda_get_pe(dev);
-       struct pci_dn *pdn = pci_get_pdn(dev);
        struct irq_data *idata;
        struct irq_chip *ichip;
        unsigned int xive_num = hwirq - phb->msi_base;
@@ -918,7 +917,7 @@ static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev,
                return -ENXIO;
 
        /* Force 32-bit MSI on some broken devices */
-       if (pdn && pdn->force_32bit_msi)
+       if (dev->no_64bit_msi)
                is_64 = 0;
 
        /* Assign XIVE to PE */
index 8518817..52c1162 100644 (file)
@@ -1,3 +1,4 @@
+
 /*
  * Support PCI/PCIe on PowerNV platforms
  *
@@ -50,9 +51,8 @@ static int pnv_msi_check_device(struct pci_dev* pdev, int nvec, int type)
 {
        struct pci_controller *hose = pci_bus_to_host(pdev->bus);
        struct pnv_phb *phb = hose->private_data;
-       struct pci_dn *pdn = pci_get_pdn(pdev);
 
-       if (pdn && pdn->force_32bit_msi && !phb->msi32_support)
+       if (pdev->no_64bit_msi && !phb->msi32_support)
                return -ENODEV;
 
        return (phb && phb->msi_bmp.bitmap) ? 0 : -ENODEV;
index 0c882e8..6849d85 100644 (file)
@@ -428,7 +428,7 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type)
         */
 again:
        if (type == PCI_CAP_ID_MSI) {
-               if (pdn->force_32bit_msi) {
+               if (pdev->no_64bit_msi) {
                        rc = rtas_change_msi(pdn, RTAS_CHANGE_32MSI_FN, nvec);
                        if (rc < 0) {
                                /*
index b079098..bc5fbc2 100644 (file)
@@ -288,10 +288,10 @@ static inline void disable_surveillance(void)
        args.token = rtas_token("set-indicator");
        if (args.token == RTAS_UNKNOWN_SERVICE)
                return;
-       args.nargs = 3;
-       args.nret = 1;
+       args.nargs = cpu_to_be32(3);
+       args.nret = cpu_to_be32(1);
        args.rets = &args.args[3];
-       args.args[0] = SURVEILLANCE_TOKEN;
+       args.args[0] = cpu_to_be32(SURVEILLANCE_TOKEN);
        args.args[1] = 0;
        args.args[2] = 0;
        enter_rtas(__pa(&args));
index 905832a..a0ed182 100644 (file)
@@ -21,7 +21,7 @@
 
 extern int __atomic_add_return(int, atomic_t *);
 extern int atomic_cmpxchg(atomic_t *, int, int);
-#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+extern int atomic_xchg(atomic_t *, int);
 extern int __atomic_add_unless(atomic_t *, int, int);
 extern void atomic_set(atomic_t *, int);
 
index 1fae1a0..ae0f9a7 100644 (file)
 #ifndef __ARCH_SPARC_CMPXCHG__
 #define __ARCH_SPARC_CMPXCHG__
 
-static inline unsigned long xchg_u32(__volatile__ unsigned long *m, unsigned long val)
-{
-       __asm__ __volatile__("swap [%2], %0"
-                            : "=&r" (val)
-                            : "0" (val), "r" (m)
-                            : "memory");
-       return val;
-}
-
+extern unsigned long __xchg_u32(volatile u32 *m, u32 new);
 extern void __xchg_called_with_bad_pointer(void);
 
 static inline unsigned long __xchg(unsigned long x, __volatile__ void * ptr, int size)
 {
        switch (size) {
        case 4:
-               return xchg_u32(ptr, x);
+               return __xchg_u32(ptr, x);
        }
        __xchg_called_with_bad_pointer();
        return x;
index 432afa8..55841c1 100644 (file)
@@ -118,12 +118,18 @@ struct vio_disk_attr_info {
        u8                      vdisk_type;
 #define VD_DISK_TYPE_SLICE     0x01 /* Slice in block device   */
 #define VD_DISK_TYPE_DISK      0x02 /* Entire block device     */
-       u16                     resv1;
+       u8                      vdisk_mtype;            /* v1.1 */
+#define VD_MEDIA_TYPE_FIXED    0x01 /* Fixed device */
+#define VD_MEDIA_TYPE_CD       0x02 /* CD Device    */
+#define VD_MEDIA_TYPE_DVD      0x03 /* DVD Device   */
+       u8                      resv1;
        u32                     vdisk_block_size;
        u64                     operations;
-       u64                     vdisk_size;
+       u64                     vdisk_size;             /* v1.1 */
        u64                     max_xfer_size;
-       u64                     resv2[2];
+       u32                     phys_block_size;        /* v1.2 */
+       u32                     resv2;
+       u64                     resv3[1];
 };
 
 struct vio_disk_desc {
@@ -259,7 +265,7 @@ static inline u32 vio_dring_avail(struct vio_dring_state *dr,
                                  unsigned int ring_size)
 {
        return (dr->pending -
-               ((dr->prod - dr->cons) & (ring_size - 1)));
+               ((dr->prod - dr->cons) & (ring_size - 1)) - 1);
 }
 
 #define VIO_MAX_TYPE_LEN       32
index a34ad07..4c7c12d 100644 (file)
@@ -9,9 +9,9 @@ static inline __u16 __arch_swab16p(const __u16 *addr)
 {
        __u16 ret;
 
-       __asm__ __volatile__ ("lduha [%1] %2, %0"
+       __asm__ __volatile__ ("lduha [%2] %3, %0"
                              : "=r" (ret)
-                             : "r" (addr), "i" (ASI_PL));
+                             : "m" (*addr), "r" (addr), "i" (ASI_PL));
        return ret;
 }
 #define __arch_swab16p __arch_swab16p
@@ -20,9 +20,9 @@ static inline __u32 __arch_swab32p(const __u32 *addr)
 {
        __u32 ret;
 
-       __asm__ __volatile__ ("lduwa [%1] %2, %0"
+       __asm__ __volatile__ ("lduwa [%2] %3, %0"
                              : "=r" (ret)
-                             : "r" (addr), "i" (ASI_PL));
+                             : "m" (*addr), "r" (addr), "i" (ASI_PL));
        return ret;
 }
 #define __arch_swab32p __arch_swab32p
@@ -31,9 +31,9 @@ static inline __u64 __arch_swab64p(const __u64 *addr)
 {
        __u64 ret;
 
-       __asm__ __volatile__ ("ldxa [%1] %2, %0"
+       __asm__ __volatile__ ("ldxa [%2] %3, %0"
                              : "=r" (ret)
-                             : "r" (addr), "i" (ASI_PL));
+                             : "m" (*addr), "r" (addr), "i" (ASI_PL));
        return ret;
 }
 #define __arch_swab64p __arch_swab64p
index 8f76f23..f9c6813 100644 (file)
@@ -581,7 +581,7 @@ static irqreturn_t schizo_pcierr_intr_other(struct pci_pbm_info *pbm)
 {
        unsigned long csr_reg, csr, csr_error_bits;
        irqreturn_t ret = IRQ_NONE;
-       u16 stat;
+       u32 stat;
 
        csr_reg = pbm->pbm_regs + SCHIZO_PCI_CTRL;
        csr = upa_readq(csr_reg);
@@ -617,7 +617,7 @@ static irqreturn_t schizo_pcierr_intr_other(struct pci_pbm_info *pbm)
                               pbm->name);
                ret = IRQ_HANDLED;
        }
-       pci_read_config_word(pbm->pci_bus->self, PCI_STATUS, &stat);
+       pbm->pci_ops->read(pbm->pci_bus, 0, PCI_STATUS, 2, &stat);
        if (stat & (PCI_STATUS_PARITY |
                    PCI_STATUS_SIG_TARGET_ABORT |
                    PCI_STATUS_REC_TARGET_ABORT |
@@ -625,7 +625,7 @@ static irqreturn_t schizo_pcierr_intr_other(struct pci_pbm_info *pbm)
                    PCI_STATUS_SIG_SYSTEM_ERROR)) {
                printk("%s: PCI bus error, PCI_STATUS[%04x]\n",
                       pbm->name, stat);
-               pci_write_config_word(pbm->pci_bus->self, PCI_STATUS, 0xffff);
+               pbm->pci_ops->write(pbm->pci_bus, 0, PCI_STATUS, 2, 0xffff);
                ret = IRQ_HANDLED;
        }
        return ret;
index 50c3dd0..9af0a5d 100644 (file)
@@ -823,13 +823,17 @@ void arch_send_call_function_single_ipi(int cpu)
 void __irq_entry smp_call_function_client(int irq, struct pt_regs *regs)
 {
        clear_softint(1 << irq);
+       irq_enter();
        generic_smp_call_function_interrupt();
+       irq_exit();
 }
 
 void __irq_entry smp_call_function_single_client(int irq, struct pt_regs *regs)
 {
        clear_softint(1 << irq);
+       irq_enter();
        generic_smp_call_function_single_interrupt();
+       irq_exit();
 }
 
 static void tsb_sync(void *info)
index 1d32b54..8f2f94d 100644 (file)
@@ -40,6 +40,19 @@ int __atomic_add_return(int i, atomic_t *v)
 }
 EXPORT_SYMBOL(__atomic_add_return);
 
+int atomic_xchg(atomic_t *v, int new)
+{
+       int ret;
+       unsigned long flags;
+
+       spin_lock_irqsave(ATOMIC_HASH(v), flags);
+       ret = v->counter;
+       v->counter = new;
+       spin_unlock_irqrestore(ATOMIC_HASH(v), flags);
+       return ret;
+}
+EXPORT_SYMBOL(atomic_xchg);
+
 int atomic_cmpxchg(atomic_t *v, int old, int new)
 {
        int ret;
@@ -132,3 +145,17 @@ unsigned long __cmpxchg_u32(volatile u32 *ptr, u32 old, u32 new)
        return (unsigned long)prev;
 }
 EXPORT_SYMBOL(__cmpxchg_u32);
+
+unsigned long __xchg_u32(volatile u32 *ptr, u32 new)
+{
+       unsigned long flags;
+       u32 prev;
+
+       spin_lock_irqsave(ATOMIC_HASH(ptr), flags);
+       prev = *ptr;
+       *ptr = new;
+       spin_unlock_irqrestore(ATOMIC_HASH(ptr), flags);
+
+       return (unsigned long)prev;
+}
+EXPORT_SYMBOL(__xchg_u32);
index 0fcd913..14fe7cb 100644 (file)
@@ -75,8 +75,10 @@ suffix-$(CONFIG_KERNEL_XZ)   := xz
 suffix-$(CONFIG_KERNEL_LZO)    := lzo
 suffix-$(CONFIG_KERNEL_LZ4)    := lz4
 
+RUN_SIZE = $(shell objdump -h vmlinux | \
+            perl $(srctree)/arch/x86/tools/calc_run_size.pl)
 quiet_cmd_mkpiggy = MKPIGGY $@
-      cmd_mkpiggy = $(obj)/mkpiggy $< > $@ || ( rm -f $@ ; false )
+      cmd_mkpiggy = $(obj)/mkpiggy $< $(RUN_SIZE) > $@ || ( rm -f $@ ; false )
 
 targets += piggy.S
 $(obj)/piggy.S: $(obj)/vmlinux.bin.$(suffix-y) $(obj)/mkpiggy FORCE
index f45ab7a..c5b56ed 100644 (file)
@@ -186,7 +186,8 @@ relocated:
  * Do the decompression, and jump to the new kernel..
  */
                                /* push arguments for decompress_kernel: */
-       pushl   $z_output_len   /* decompressed length */
+       pushl   $z_run_size     /* size of kernel with .bss and .brk */
+       pushl   $z_output_len   /* decompressed length, end of relocs */
        leal    z_extract_offset_negative(%ebx), %ebp
        pushl   %ebp            /* output address */
        pushl   $z_input_len    /* input_len */
@@ -196,7 +197,7 @@ relocated:
        pushl   %eax            /* heap area */
        pushl   %esi            /* real mode pointer */
        call    decompress_kernel /* returns kernel location in %eax */
-       addl    $24, %esp
+       addl    $28, %esp
 
 /*
  * Jump to the decompressed kernel.
index b10fa66..34bbc09 100644 (file)
@@ -334,13 +334,16 @@ relocated:
  * Do the decompression, and jump to the new kernel..
  */
        pushq   %rsi                    /* Save the real mode argument */
+       movq    $z_run_size, %r9        /* size of kernel with .bss and .brk */
+       pushq   %r9
        movq    %rsi, %rdi              /* real mode address */
        leaq    boot_heap(%rip), %rsi   /* malloc area for uncompression */
        leaq    input_data(%rip), %rdx  /* input_data */
        movl    $z_input_len, %ecx      /* input_len */
        movq    %rbp, %r8               /* output target address */
-       movq    $z_output_len, %r9      /* decompressed length */
+       movq    $z_output_len, %r9      /* decompressed length, end of relocs */
        call    decompress_kernel       /* returns kernel location in %rax */
+       popq    %r9
        popq    %rsi
 
 /*
index 196eaf3..eb25ca1 100644 (file)
@@ -393,7 +393,8 @@ asmlinkage void *decompress_kernel(void *rmode, memptr heap,
                                  unsigned char *input_data,
                                  unsigned long input_len,
                                  unsigned char *output,
-                                 unsigned long output_len)
+                                 unsigned long output_len,
+                                 unsigned long run_size)
 {
        real_mode = rmode;
 
@@ -416,8 +417,14 @@ asmlinkage void *decompress_kernel(void *rmode, memptr heap,
        free_mem_ptr     = heap;        /* Heap */
        free_mem_end_ptr = heap + BOOT_HEAP_SIZE;
 
-       output = choose_kernel_location(input_data, input_len,
-                                       output, output_len);
+       /*
+        * The memory hole needed for the kernel is the larger of either
+        * the entire decompressed kernel plus relocation table, or the
+        * entire decompressed kernel plus .bss and .brk sections.
+        */
+       output = choose_kernel_location(input_data, input_len, output,
+                                       output_len > run_size ? output_len
+                                                             : run_size);
 
        /* Validate memory location choices. */
        if ((unsigned long)output & (MIN_KERNEL_ALIGN - 1))
index b669ab6..d8222f2 100644 (file)
@@ -36,11 +36,13 @@ int main(int argc, char *argv[])
        uint32_t olen;
        long ilen;
        unsigned long offs;
+       unsigned long run_size;
        FILE *f = NULL;
        int retval = 1;
 
-       if (argc < 2) {
-               fprintf(stderr, "Usage: %s compressed_file\n", argv[0]);
+       if (argc < 3) {
+               fprintf(stderr, "Usage: %s compressed_file run_size\n",
+                               argv[0]);
                goto bail;
        }
 
@@ -74,6 +76,7 @@ int main(int argc, char *argv[])
        offs += olen >> 12;     /* Add 8 bytes for each 32K block */
        offs += 64*1024 + 128;  /* Add 64K + 128 bytes slack */
        offs = (offs+4095) & ~4095; /* Round to a 4K boundary */
+       run_size = atoi(argv[2]);
 
        printf(".section \".rodata..compressed\",\"a\",@progbits\n");
        printf(".globl z_input_len\n");
@@ -85,6 +88,8 @@ int main(int argc, char *argv[])
        /* z_extract_offset_negative allows simplification of head_32.S */
        printf(".globl z_extract_offset_negative\n");
        printf("z_extract_offset_negative = -0x%lx\n", offs);
+       printf(".globl z_run_size\n");
+       printf("z_run_size = %lu\n", run_size);
 
        printf(".globl input_data, input_data_end\n");
        printf("input_data:\n");
index 5f12968..1717156 100644 (file)
 #define X86_FEATURE_DECODEASSISTS (8*32+12) /* AMD Decode Assists support */
 #define X86_FEATURE_PAUSEFILTER (8*32+13) /* AMD filtered pause intercept */
 #define X86_FEATURE_PFTHRESHOLD (8*32+14) /* AMD pause filter threshold */
+#define X86_FEATURE_VMMCALL    (8*32+15) /* Prefer vmmcall to vmcall */
 
 
 /* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9 */
index c7678e4..e62cf89 100644 (file)
@@ -2,6 +2,7 @@
 #define _ASM_X86_KVM_PARA_H
 
 #include <asm/processor.h>
+#include <asm/alternative.h>
 #include <uapi/asm/kvm_para.h>
 
 extern void kvmclock_init(void);
@@ -16,10 +17,15 @@ static inline bool kvm_check_and_clear_guest_paused(void)
 }
 #endif /* CONFIG_KVM_GUEST */
 
-/* This instruction is vmcall.  On non-VT architectures, it will generate a
- * trap that we will then rewrite to the appropriate instruction.
+#ifdef CONFIG_DEBUG_RODATA
+#define KVM_HYPERCALL \
+        ALTERNATIVE(".byte 0x0f,0x01,0xc1", ".byte 0x0f,0x01,0xd9", X86_FEATURE_VMMCALL)
+#else
+/* On AMD processors, vmcall will generate a trap that we will
+ * then rewrite to the appropriate instruction.
  */
 #define KVM_HYPERCALL ".byte 0x0f,0x01,0xc1"
+#endif
 
 /* For KVM hypercalls, a three-byte sequence of either the vmcall or the vmmcall
  * instruction.  The hypervisor may replace it with something else but only the
index f48b17d..3a52ee0 100644 (file)
@@ -20,7 +20,6 @@
 #define THREAD_SIZE_ORDER      1
 #define THREAD_SIZE            (PAGE_SIZE << THREAD_SIZE_ORDER)
 
-#define STACKFAULT_STACK 0
 #define DOUBLEFAULT_STACK 1
 #define NMI_STACK 0
 #define DEBUG_STACK 0
index 8de6d9c..d54d1ee 100644 (file)
 #define IRQ_STACK_ORDER 2
 #define IRQ_STACK_SIZE (PAGE_SIZE << IRQ_STACK_ORDER)
 
-#define STACKFAULT_STACK 1
-#define DOUBLEFAULT_STACK 2
-#define NMI_STACK 3
-#define DEBUG_STACK 4
-#define MCE_STACK 5
-#define N_EXCEPTION_STACKS 5  /* hw limit: 7 */
+#define DOUBLEFAULT_STACK 1
+#define NMI_STACK 2
+#define DEBUG_STACK 3
+#define MCE_STACK 4
+#define N_EXCEPTION_STACKS 4  /* hw limit: 7 */
 
 #define PUD_PAGE_SIZE          (_AC(1, UL) << PUD_SHIFT)
 #define PUD_PAGE_MASK          (~(PUD_PAGE_SIZE-1))
index e1940c0..e870ea9 100644 (file)
@@ -144,7 +144,7 @@ struct thread_info {
 /* Only used for 64 bit */
 #define _TIF_DO_NOTIFY_MASK                                            \
        (_TIF_SIGPENDING | _TIF_MCE_NOTIFY | _TIF_NOTIFY_RESUME |       \
-        _TIF_USER_RETURN_NOTIFY)
+        _TIF_USER_RETURN_NOTIFY | _TIF_UPROBE)
 
 /* flags to check in __switch_to() */
 #define _TIF_WORK_CTXSW                                                        \
index 58d66fe..b409b17 100644 (file)
@@ -39,6 +39,7 @@ asmlinkage void simd_coprocessor_error(void);
 
 #ifdef CONFIG_TRACING
 asmlinkage void trace_page_fault(void);
+#define trace_stack_segment stack_segment
 #define trace_divide_error divide_error
 #define trace_bounds bounds
 #define trace_invalid_op invalid_op
index c67ffa6..c005fdd 100644 (file)
@@ -508,6 +508,13 @@ static void early_init_amd(struct cpuinfo_x86 *c)
        }
 #endif
 
+       /*
+        * This is only needed to tell the kernel whether to use VMCALL
+        * and VMMCALL.  VMMCALL is never executed except under virt, so
+        * we can set it unconditionally.
+        */
+       set_cpu_cap(c, X86_FEATURE_VMMCALL);
+
        /* F16h erratum 793, CVE-2013-6885 */
        if (c->x86 == 0x16 && c->x86_model <= 0xf) {
                u64 val;
index 3f27f5f..e6bddd5 100644 (file)
@@ -144,6 +144,8 @@ EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
 
 static int __init x86_xsave_setup(char *s)
 {
+       if (strlen(s))
+               return 0;
        setup_clear_cpu_cap(X86_FEATURE_XSAVE);
        setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT);
        setup_clear_cpu_cap(X86_FEATURE_AVX);
index 617a9e2..b63773b 100644 (file)
@@ -108,12 +108,13 @@ static size_t compute_container_size(u8 *data, u32 total_size)
  * load_microcode_amd() to save equivalent cpu table and microcode patches in
  * kernel heap memory.
  */
-static void apply_ucode_in_initrd(void *ucode, size_t size)
+static void apply_ucode_in_initrd(void *ucode, size_t size, bool save_patch)
 {
        struct equiv_cpu_entry *eq;
        size_t *cont_sz;
        u32 *header;
        u8  *data, **cont;
+       u8 (*patch)[PATCH_MAX_SIZE];
        u16 eq_id = 0;
        int offset, left;
        u32 rev, eax, ebx, ecx, edx;
@@ -123,10 +124,12 @@ static void apply_ucode_in_initrd(void *ucode, size_t size)
        new_rev = (u32 *)__pa_nodebug(&ucode_new_rev);
        cont_sz = (size_t *)__pa_nodebug(&container_size);
        cont    = (u8 **)__pa_nodebug(&container);
+       patch   = (u8 (*)[PATCH_MAX_SIZE])__pa_nodebug(&amd_ucode_patch);
 #else
        new_rev = &ucode_new_rev;
        cont_sz = &container_size;
        cont    = &container;
+       patch   = &amd_ucode_patch;
 #endif
 
        data   = ucode;
@@ -213,9 +216,9 @@ static void apply_ucode_in_initrd(void *ucode, size_t size)
                                rev = mc->hdr.patch_id;
                                *new_rev = rev;
 
-                               /* save ucode patch */
-                               memcpy(amd_ucode_patch, mc,
-                                      min_t(u32, header[1], PATCH_MAX_SIZE));
+                               if (save_patch)
+                                       memcpy(patch, mc,
+                                              min_t(u32, header[1], PATCH_MAX_SIZE));
                        }
                }
 
@@ -246,7 +249,7 @@ void __init load_ucode_amd_bsp(void)
        *data = cp.data;
        *size = cp.size;
 
-       apply_ucode_in_initrd(cp.data, cp.size);
+       apply_ucode_in_initrd(cp.data, cp.size, true);
 }
 
 #ifdef CONFIG_X86_32
@@ -263,7 +266,7 @@ void load_ucode_amd_ap(void)
        size_t *usize;
        void **ucode;
 
-       mc = (struct microcode_amd *)__pa(amd_ucode_patch);
+       mc = (struct microcode_amd *)__pa_nodebug(amd_ucode_patch);
        if (mc->hdr.patch_id && mc->hdr.processor_rev_id) {
                __apply_microcode_amd(mc);
                return;
@@ -275,7 +278,7 @@ void load_ucode_amd_ap(void)
        if (!*ucode || !*usize)
                return;
 
-       apply_ucode_in_initrd(*ucode, *usize);
+       apply_ucode_in_initrd(*ucode, *usize, false);
 }
 
 static void __init collect_cpu_sig_on_bsp(void *arg)
@@ -339,7 +342,7 @@ void load_ucode_amd_ap(void)
                 * AP has a different equivalence ID than BSP, looks like
                 * mixed-steppings silicon so go through the ucode blob anew.
                 */
-               apply_ucode_in_initrd(ucode_cpio.data, ucode_cpio.size);
+               apply_ucode_in_initrd(ucode_cpio.data, ucode_cpio.size, false);
        }
 }
 #endif
@@ -347,7 +350,9 @@ void load_ucode_amd_ap(void)
 int __init save_microcode_in_initrd_amd(void)
 {
        unsigned long cont;
+       int retval = 0;
        enum ucode_state ret;
+       u8 *cont_va;
        u32 eax;
 
        if (!container)
@@ -355,13 +360,15 @@ int __init save_microcode_in_initrd_amd(void)
 
 #ifdef CONFIG_X86_32
        get_bsp_sig();
-       cont = (unsigned long)container;
+       cont    = (unsigned long)container;
+       cont_va = __va(container);
 #else
        /*
         * We need the physical address of the container for both bitness since
         * boot_params.hdr.ramdisk_image is a physical address.
         */
-       cont = __pa(container);
+       cont    = __pa(container);
+       cont_va = container;
 #endif
 
        /*
@@ -372,6 +379,8 @@ int __init save_microcode_in_initrd_amd(void)
        if (relocated_ramdisk)
                container = (u8 *)(__va(relocated_ramdisk) +
                             (cont - boot_params.hdr.ramdisk_image));
+       else
+               container = cont_va;
 
        if (ucode_new_rev)
                pr_info("microcode: updated early to new patch_level=0x%08x\n",
@@ -382,7 +391,7 @@ int __init save_microcode_in_initrd_amd(void)
 
        ret = load_microcode_amd(eax, container, container_size);
        if (ret != UCODE_OK)
-               return -EINVAL;
+               retval = -EINVAL;
 
        /*
         * This will be freed any msec now, stash patches for the current
@@ -391,5 +400,5 @@ int __init save_microcode_in_initrd_amd(void)
        container = NULL;
        container_size = 0;
 
-       return 0;
+       return retval;
 }
index 1340ebf..5ee8064 100644 (file)
@@ -2475,6 +2475,9 @@ __init int intel_pmu_init(void)
        case 62: /* IvyBridge EP */
                memcpy(hw_cache_event_ids, snb_hw_cache_event_ids,
                       sizeof(hw_cache_event_ids));
+               /* dTLB-load-misses on IVB is different than SNB */
+               hw_cache_event_ids[C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = 0x8108; /* DTLB_LOAD_MISSES.DEMAND_LD_MISS_CAUSES_A_WALK */
+
                memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs,
                       sizeof(hw_cache_extra_regs));
 
index addb207..66e274a 100644 (file)
@@ -24,7 +24,6 @@ static char x86_stack_ids[][8] = {
                [ DEBUG_STACK-1                 ]       = "#DB",
                [ NMI_STACK-1                   ]       = "NMI",
                [ DOUBLEFAULT_STACK-1           ]       = "#DF",
-               [ STACKFAULT_STACK-1            ]       = "#SS",
                [ MCE_STACK-1                   ]       = "#MC",
 #if DEBUG_STKSZ > EXCEPTION_STKSZ
                [ N_EXCEPTION_STACKS ...
index 03cd2a8..02553d6 100644 (file)
@@ -1053,9 +1053,15 @@ ENTRY(native_iret)
        jnz native_irq_return_ldt
 #endif
 
+.global native_irq_return_iret
 native_irq_return_iret:
+       /*
+        * This may fault.  Non-paranoid faults on return to userspace are
+        * handled by fixup_bad_iret.  These include #SS, #GP, and #NP.
+        * Double-faults due to espfix64 are handled in do_double_fault.
+        * Other faults here are fatal.
+        */
        iretq
-       _ASM_EXTABLE(native_irq_return_iret, bad_iret)
 
 #ifdef CONFIG_X86_ESPFIX64
 native_irq_return_ldt:
@@ -1083,25 +1089,6 @@ native_irq_return_ldt:
        jmp native_irq_return_iret
 #endif
 
-       .section .fixup,"ax"
-bad_iret:
-       /*
-        * The iret traps when the %cs or %ss being restored is bogus.
-        * We've lost the original trap vector and error code.
-        * #GPF is the most likely one to get for an invalid selector.
-        * So pretend we completed the iret and took the #GPF in user mode.
-        *
-        * We are now running with the kernel GS after exception recovery.
-        * But error_entry expects us to have user GS to match the user %cs,
-        * so swap back.
-        */
-       pushq $0
-
-       SWAPGS
-       jmp general_protection
-
-       .previous
-
        /* edi: workmask, edx: work */
 retint_careful:
        CFI_RESTORE_STATE
@@ -1147,37 +1134,6 @@ ENTRY(retint_kernel)
        CFI_ENDPROC
 END(common_interrupt)
 
-       /*
-        * If IRET takes a fault on the espfix stack, then we
-        * end up promoting it to a doublefault.  In that case,
-        * modify the stack to make it look like we just entered
-        * the #GP handler from user space, similar to bad_iret.
-        */
-#ifdef CONFIG_X86_ESPFIX64
-       ALIGN
-__do_double_fault:
-       XCPT_FRAME 1 RDI+8
-       movq RSP(%rdi),%rax             /* Trap on the espfix stack? */
-       sarq $PGDIR_SHIFT,%rax
-       cmpl $ESPFIX_PGD_ENTRY,%eax
-       jne do_double_fault             /* No, just deliver the fault */
-       cmpl $__KERNEL_CS,CS(%rdi)
-       jne do_double_fault
-       movq RIP(%rdi),%rax
-       cmpq $native_irq_return_iret,%rax
-       jne do_double_fault             /* This shouldn't happen... */
-       movq PER_CPU_VAR(kernel_stack),%rax
-       subq $(6*8-KERNEL_STACK_OFFSET),%rax    /* Reset to original stack */
-       movq %rax,RSP(%rdi)
-       movq $0,(%rax)                  /* Missing (lost) #GP error code */
-       movq $general_protection,RIP(%rdi)
-       retq
-       CFI_ENDPROC
-END(__do_double_fault)
-#else
-# define __do_double_fault do_double_fault
-#endif
-
 /*
  * End of kprobes section
  */
@@ -1379,7 +1335,7 @@ zeroentry overflow do_overflow
 zeroentry bounds do_bounds
 zeroentry invalid_op do_invalid_op
 zeroentry device_not_available do_device_not_available
-paranoiderrorentry double_fault __do_double_fault
+paranoiderrorentry double_fault do_double_fault
 zeroentry coprocessor_segment_overrun do_coprocessor_segment_overrun
 errorentry invalid_TSS do_invalid_TSS
 errorentry segment_not_present do_segment_not_present
@@ -1549,7 +1505,7 @@ apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \
 
 paranoidzeroentry_ist debug do_debug DEBUG_STACK
 paranoidzeroentry_ist int3 do_int3 DEBUG_STACK
-paranoiderrorentry stack_segment do_stack_segment
+errorentry stack_segment do_stack_segment
 #ifdef CONFIG_XEN
 zeroentry xen_debug do_debug
 zeroentry xen_int3 do_int3
@@ -1659,16 +1615,15 @@ error_sti:
 
 /*
  * There are two places in the kernel that can potentially fault with
- * usergs. Handle them here. The exception handlers after iret run with
- * kernel gs again, so don't set the user space flag. B stepping K8s
- * sometimes report an truncated RIP for IRET exceptions returning to
- * compat mode. Check for these here too.
+ * usergs. Handle them here.  B stepping K8s sometimes report a
+ * truncated RIP for IRET exceptions returning to compat mode. Check
+ * for these here too.
  */
 error_kernelspace:
        incl %ebx
        leaq native_irq_return_iret(%rip),%rcx
        cmpq %rcx,RIP+8(%rsp)
-       je error_swapgs
+       je error_bad_iret
        movl %ecx,%eax  /* zero extend */
        cmpq %rax,RIP+8(%rsp)
        je bstep_iret
@@ -1679,7 +1634,15 @@ error_kernelspace:
 bstep_iret:
        /* Fix truncated RIP */
        movq %rcx,RIP+8(%rsp)
-       jmp error_swapgs
+       /* fall through */
+
+error_bad_iret:
+       SWAPGS
+       mov %rsp,%rdi
+       call fixup_bad_iret
+       mov %rax,%rsp
+       decl %ebx       /* Return to usergs */
+       jmp error_sti
        CFI_ENDPROC
 END(error_entry)
 
index 7461f50..0686fe3 100644 (file)
@@ -1441,15 +1441,6 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
        force_sig_info(SIGTRAP, &info, tsk);
 }
 
-
-#ifdef CONFIG_X86_32
-# define IS_IA32       1
-#elif defined CONFIG_IA32_EMULATION
-# define IS_IA32       is_compat_task()
-#else
-# define IS_IA32       0
-#endif
-
 /*
  * We must return the syscall number to actually look up in the table.
  * This can be -1L to skip running any syscall at all.
@@ -1487,7 +1478,7 @@ long syscall_trace_enter(struct pt_regs *regs)
        if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
                trace_sys_enter(regs, regs->orig_ax);
 
-       if (IS_IA32)
+       if (is_ia32_task())
                audit_syscall_entry(AUDIT_ARCH_I386,
                                    regs->orig_ax,
                                    regs->bx, regs->cx,
index 57409f6..f9d976e 100644 (file)
@@ -218,32 +218,40 @@ DO_ERROR_INFO(X86_TRAP_UD,     SIGILL,  "invalid opcode",         invalid_op,                  ILL
 DO_ERROR     (X86_TRAP_OLD_MF, SIGFPE,  "coprocessor segment overrun", coprocessor_segment_overrun                       )
 DO_ERROR     (X86_TRAP_TS,     SIGSEGV, "invalid TSS",                 invalid_TSS                                       )
 DO_ERROR     (X86_TRAP_NP,     SIGBUS,  "segment not present",         segment_not_present                               )
-#ifdef CONFIG_X86_32
 DO_ERROR     (X86_TRAP_SS,     SIGBUS,  "stack segment",               stack_segment                                     )
-#endif
 DO_ERROR_INFO(X86_TRAP_AC,     SIGBUS,  "alignment check",             alignment_check,             BUS_ADRALN, 0        )
 
 #ifdef CONFIG_X86_64
 /* Runs on IST stack */
-dotraplinkage void do_stack_segment(struct pt_regs *regs, long error_code)
-{
-       enum ctx_state prev_state;
-
-       prev_state = exception_enter();
-       if (notify_die(DIE_TRAP, "stack segment", regs, error_code,
-                      X86_TRAP_SS, SIGBUS) != NOTIFY_STOP) {
-               preempt_conditional_sti(regs);
-               do_trap(X86_TRAP_SS, SIGBUS, "stack segment", regs, error_code, NULL);
-               preempt_conditional_cli(regs);
-       }
-       exception_exit(prev_state);
-}
-
 dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code)
 {
        static const char str[] = "double fault";
        struct task_struct *tsk = current;
 
+#ifdef CONFIG_X86_ESPFIX64
+       extern unsigned char native_irq_return_iret[];
+
+       /*
+        * If IRET takes a non-IST fault on the espfix64 stack, then we
+        * end up promoting it to a doublefault.  In that case, modify
+        * the stack to make it look like we just entered the #GP
+        * handler from user space, similar to bad_iret.
+        */
+       if (((long)regs->sp >> PGDIR_SHIFT) == ESPFIX_PGD_ENTRY &&
+               regs->cs == __KERNEL_CS &&
+               regs->ip == (unsigned long)native_irq_return_iret)
+       {
+               struct pt_regs *normal_regs = task_pt_regs(current);
+
+               /* Fake a #GP(0) from userspace. */
+               memmove(&normal_regs->ip, (void *)regs->sp, 5*8);
+               normal_regs->orig_ax = 0;  /* Missing (lost) #GP error code */
+               regs->ip = (unsigned long)general_protection;
+               regs->sp = (unsigned long)&normal_regs->orig_ax;
+               return;
+       }
+#endif
+
        exception_enter();
        /* Return not checked because double check cannot be ignored */
        notify_die(DIE_TRAP, str, regs, error_code, X86_TRAP_DF, SIGSEGV);
@@ -376,6 +384,35 @@ asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs)
                *regs = *eregs;
        return regs;
 }
+
+struct bad_iret_stack {
+       void *error_entry_ret;
+       struct pt_regs regs;
+};
+
+asmlinkage __visible
+struct bad_iret_stack *fixup_bad_iret(struct bad_iret_stack *s)
+{
+       /*
+        * This is called from entry_64.S early in handling a fault
+        * caused by a bad iret to user mode.  To handle the fault
+        * correctly, we want move our stack frame to task_pt_regs
+        * and we want to pretend that the exception came from the
+        * iret target.
+        */
+       struct bad_iret_stack *new_stack =
+               container_of(task_pt_regs(current),
+                            struct bad_iret_stack, regs);
+
+       /* Copy the IRET target to the new stack. */
+       memmove(&new_stack->regs.ip, (void *)s->regs.sp, 5*8);
+
+       /* Copy the remainder of the stack from the current stack. */
+       memmove(new_stack, s, offsetof(struct bad_iret_stack, regs.ip));
+
+       BUG_ON(!user_mode_vm(&new_stack->regs));
+       return new_stack;
+}
 #endif
 
 /*
@@ -748,7 +785,7 @@ void __init trap_init(void)
        set_intr_gate(X86_TRAP_OLD_MF, coprocessor_segment_overrun);
        set_intr_gate(X86_TRAP_TS, invalid_TSS);
        set_intr_gate(X86_TRAP_NP, segment_not_present);
-       set_intr_gate_ist(X86_TRAP_SS, &stack_segment, STACKFAULT_STACK);
+       set_intr_gate(X86_TRAP_SS, stack_segment);
        set_intr_gate(X86_TRAP_GP, general_protection);
        set_intr_gate(X86_TRAP_SPURIOUS, spurious_interrupt_bug);
        set_intr_gate(X86_TRAP_MF, coprocessor_error);
index 51c2851..fab97ad 100644 (file)
@@ -4911,7 +4911,7 @@ static int handle_emulation_failure(struct kvm_vcpu *vcpu)
 
        ++vcpu->stat.insn_emulation_fail;
        trace_kvm_emulate_insn_failed(vcpu);
-       if (!is_guest_mode(vcpu)) {
+       if (!is_guest_mode(vcpu) && kvm_x86_ops->get_cpl(vcpu) == 0) {
                vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
                vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION;
                vcpu->run->internal.ndata = 0;
index f35c66c..2308a40 100644 (file)
@@ -1110,7 +1110,7 @@ void mark_rodata_ro(void)
        unsigned long end = (unsigned long) &__end_rodata_hpage_align;
        unsigned long text_end = PFN_ALIGN(&__stop___ex_table);
        unsigned long rodata_end = PFN_ALIGN(&__end_rodata);
-       unsigned long all_end = PFN_ALIGN(&_end);
+       unsigned long all_end;
 
        printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n",
               (end - start) >> 10);
@@ -1121,7 +1121,16 @@ void mark_rodata_ro(void)
        /*
         * The rodata/data/bss/brk section (but not the kernel text!)
         * should also be not-executable.
+        *
+        * We align all_end to PMD_SIZE because the existing mapping
+        * is a full PMD. If we would align _brk_end to PAGE_SIZE we
+        * split the PMD and the reminder between _brk_end and the end
+        * of the PMD will remain mapped executable.
+        *
+        * Any PMD which was setup after the one which covers _brk_end
+        * has been zapped already via cleanup_highmem().
         */
+       all_end = roundup((unsigned long)_brk_end, PMD_SIZE);
        set_memory_nx(rodata_start, (all_end - rodata_start) >> PAGE_SHIFT);
 
        rodata_test();
index c96314a..0004ac7 100644 (file)
@@ -399,13 +399,20 @@ int pmdp_test_and_clear_young(struct vm_area_struct *vma,
 int ptep_clear_flush_young(struct vm_area_struct *vma,
                           unsigned long address, pte_t *ptep)
 {
-       int young;
-
-       young = ptep_test_and_clear_young(vma, address, ptep);
-       if (young)
-               flush_tlb_page(vma, address);
-
-       return young;
+       /*
+        * On x86 CPUs, clearing the accessed bit without a TLB flush
+        * doesn't cause data corruption. [ It could cause incorrect
+        * page aging and the (mistaken) reclaim of hot pages, but the
+        * chance of that should be relatively low. ]
+        *
+        * So as a performance optimization don't flush the TLB when
+        * clearing the accessed bit, it will eventually be flushed by
+        * a context switch or a VM operation anyway. [ In the rare
+        * event of it not getting flushed for a long time the delay
+        * shouldn't really matter because there's no real memory
+        * pressure for swapout to react to. ]
+        */
+       return ptep_test_and_clear_young(vma, address, ptep);
 }
 
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
diff --git a/arch/x86/tools/calc_run_size.pl b/arch/x86/tools/calc_run_size.pl
new file mode 100644 (file)
index 0000000..23210ba
--- /dev/null
@@ -0,0 +1,39 @@
+#!/usr/bin/perl
+#
+# Calculate the amount of space needed to run the kernel, including room for
+# the .bss and .brk sections.
+#
+# Usage:
+# objdump -h a.out | perl calc_run_size.pl
+use strict;
+
+my $mem_size = 0;
+my $file_offset = 0;
+
+my $sections=" *[0-9]+ \.(?:bss|brk) +";
+while (<>) {
+       if (/^$sections([0-9a-f]+) +(?:[0-9a-f]+ +){2}([0-9a-f]+)/) {
+               my $size = hex($1);
+               my $offset = hex($2);
+               $mem_size += $size;
+               if ($file_offset == 0) {
+                       $file_offset = $offset;
+               } elsif ($file_offset != $offset) {
+                       # BFD linker shows the same file offset in ELF.
+                       # Gold linker shows them as consecutive.
+                       next if ($file_offset + $mem_size == $offset + $size);
+
+                       printf STDERR "file_offset: 0x%lx\n", $file_offset;
+                       printf STDERR "mem_size: 0x%lx\n", $mem_size;
+                       printf STDERR "offset: 0x%lx\n", $offset;
+                       printf STDERR "size: 0x%lx\n", $size;
+
+                       die ".bss and .brk are non-contiguous\n";
+               }
+       }
+}
+
+if ($file_offset == 0) {
+       die "Never found .bss or .brk file offset\n";
+}
+printf("%d\n", $mem_size + $file_offset);
index b939552..50084f7 100644 (file)
@@ -384,7 +384,8 @@ __SYSCALL(174, sys_chroot, 1)
 #define __NR_pivot_root                        175
 __SYSCALL(175, sys_pivot_root, 2)
 #define __NR_umount                            176
-__SYSCALL(176, sys_umount, 2)
+__SYSCALL(176, sys_oldumount, 1)
+#define __ARCH_WANT_SYS_OLDUMOUNT
 #define __NR_swapoff                           177
 __SYSCALL(177, sys_swapoff, 1)
 #define __NR_sync                              178
index 00663d6..e662f14 100644 (file)
@@ -61,6 +61,7 @@ enum board_ids {
        /* board IDs by feature in alphabetical order */
        board_ahci,
        board_ahci_ign_iferr,
+       board_ahci_nomsi,
        board_ahci_noncq,
        board_ahci_nosntf,
        board_ahci_yes_fbs,
@@ -122,6 +123,13 @@ static const struct ata_port_info ahci_port_info[] = {
                .udma_mask      = ATA_UDMA6,
                .port_ops       = &ahci_ops,
        },
+       [board_ahci_nomsi] = {
+               AHCI_HFLAGS     (AHCI_HFLAG_NO_MSI),
+               .flags          = AHCI_FLAG_COMMON,
+               .pio_mask       = ATA_PIO4,
+               .udma_mask      = ATA_UDMA6,
+               .port_ops       = &ahci_ops,
+       },
        [board_ahci_noncq] = {
                AHCI_HFLAGS     (AHCI_HFLAG_NO_NCQ),
                .flags          = AHCI_FLAG_COMMON,
@@ -314,6 +322,11 @@ static const struct pci_device_id ahci_pci_tbl[] = {
        { PCI_VDEVICE(INTEL, 0x8c87), board_ahci }, /* 9 Series RAID */
        { PCI_VDEVICE(INTEL, 0x8c8e), board_ahci }, /* 9 Series RAID */
        { PCI_VDEVICE(INTEL, 0x8c8f), board_ahci }, /* 9 Series RAID */
+       { PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H AHCI */
+       { PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H RAID */
+       { PCI_VDEVICE(INTEL, 0xa105), board_ahci }, /* Sunrise Point-H RAID */
+       { PCI_VDEVICE(INTEL, 0xa107), board_ahci }, /* Sunrise Point-H RAID */
+       { PCI_VDEVICE(INTEL, 0xa10f), board_ahci }, /* Sunrise Point-H RAID */
 
        /* JMicron 360/1/3/5/6, match class to avoid IDE function */
        { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
@@ -476,10 +489,10 @@ static const struct pci_device_id ahci_pci_tbl[] = {
        { PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci },   /* ASM1062 */
 
        /*
-        * Samsung SSDs found on some macbooks.  NCQ times out.
-        * https://bugzilla.kernel.org/show_bug.cgi?id=60731
+        * Samsung SSDs found on some macbooks.  NCQ times out if MSI is
+        * enabled.  https://bugzilla.kernel.org/show_bug.cgi?id=60731
         */
-       { PCI_VDEVICE(SAMSUNG, 0x1600), board_ahci_noncq },
+       { PCI_VDEVICE(SAMSUNG, 0x1600), board_ahci_nomsi },
 
        /* Enmotus */
        { PCI_DEVICE(0x1c44, 0x8000), board_ahci },
index 61eb6d7..ea1fbc1 100644 (file)
 enum sata_rcar_type {
        RCAR_GEN1_SATA,
        RCAR_GEN2_SATA,
+       RCAR_R8A7790_ES1_SATA,
 };
 
 struct sata_rcar_priv {
@@ -763,6 +764,9 @@ static void sata_rcar_setup_port(struct ata_host *host)
        ap->udma_mask   = ATA_UDMA6;
        ap->flags       |= ATA_FLAG_SATA;
 
+       if (priv->type == RCAR_R8A7790_ES1_SATA)
+               ap->flags       |= ATA_FLAG_NO_DIPM;
+
        ioaddr->cmd_addr = base + SDATA_REG;
        ioaddr->ctl_addr = base + SSDEVCON_REG;
        ioaddr->scr_addr = base + SCRSSTS_REG;
@@ -792,6 +796,7 @@ static void sata_rcar_init_controller(struct ata_host *host)
                sata_rcar_gen1_phy_init(priv);
                break;
        case RCAR_GEN2_SATA:
+       case RCAR_R8A7790_ES1_SATA:
                sata_rcar_gen2_phy_init(priv);
                break;
        default:
@@ -838,9 +843,17 @@ static struct of_device_id sata_rcar_match[] = {
                .data = (void *)RCAR_GEN2_SATA
        },
        {
+               .compatible = "renesas,sata-r8a7790-es1",
+               .data = (void *)RCAR_R8A7790_ES1_SATA
+       },
+       {
                .compatible = "renesas,sata-r8a7791",
                .data = (void *)RCAR_GEN2_SATA
        },
+       {
+               .compatible = "renesas,sata-r8a7793",
+               .data = (void *)RCAR_GEN2_SATA
+       },
        { },
 };
 MODULE_DEVICE_TABLE(of, sata_rcar_match);
@@ -849,7 +862,9 @@ static const struct platform_device_id sata_rcar_id_table[] = {
        { "sata_rcar", RCAR_GEN1_SATA }, /* Deprecated by "sata-r8a7779" */
        { "sata-r8a7779", RCAR_GEN1_SATA },
        { "sata-r8a7790", RCAR_GEN2_SATA },
+       { "sata-r8a7790-es1", RCAR_R8A7790_ES1_SATA },
        { "sata-r8a7791", RCAR_GEN2_SATA },
+       { "sata-r8a7793", RCAR_GEN2_SATA },
        { },
 };
 MODULE_DEVICE_TABLE(platform, sata_rcar_id_table);
index 545c4de..c8d295a 100644 (file)
@@ -791,6 +791,62 @@ void * devm_kmalloc(struct device *dev, size_t size, gfp_t gfp)
 EXPORT_SYMBOL_GPL(devm_kmalloc);
 
 /**
+ * devm_kvasprintf - Allocate resource managed space and format a string
+ *                  into that.
+ * @dev: Device to allocate memory for
+ * @gfp: the GFP mask used in the devm_kmalloc() call when
+ *       allocating memory
+ * @fmt: The printf()-style format string
+ * @ap: Arguments for the format string
+ * RETURNS:
+ * Pointer to allocated string on success, NULL on failure.
+ */
+char *devm_kvasprintf(struct device *dev, gfp_t gfp, const char *fmt,
+                     va_list ap)
+{
+       unsigned int len;
+       char *p;
+       va_list aq;
+
+       va_copy(aq, ap);
+       len = vsnprintf(NULL, 0, fmt, aq);
+       va_end(aq);
+
+       p = devm_kmalloc(dev, len+1, gfp);
+       if (!p)
+               return NULL;
+
+       vsnprintf(p, len+1, fmt, ap);
+
+       return p;
+}
+EXPORT_SYMBOL(devm_kvasprintf);
+
+/**
+ * devm_kasprintf - Allocate resource managed space and format a string
+ *                 into that.
+ * @dev: Device to allocate memory for
+ * @gfp: the GFP mask used in the devm_kmalloc() call when
+ *       allocating memory
+ * @fmt: The printf()-style format string
+ * @...: Arguments for the format string
+ * RETURNS:
+ * Pointer to allocated string on success, NULL on failure.
+ */
+char *devm_kasprintf(struct device *dev, gfp_t gfp, const char *fmt, ...)
+{
+       va_list ap;
+       char *p;
+
+       va_start(ap, fmt);
+       p = devm_kvasprintf(dev, gfp, fmt, ap);
+       va_end(ap);
+
+       return p;
+}
+EXPORT_SYMBOL_GPL(devm_kasprintf);
+
+/**
  * devm_kfree - Resource-managed kfree
  * @dev: Device this memory belongs to
  * @p: Memory to free
index 2e58ebb..1cb8544 100644 (file)
@@ -1,6 +1,5 @@
-obj-$(CONFIG_PM)       += sysfs.o generic_ops.o common.o qos.o
+obj-$(CONFIG_PM)       += sysfs.o generic_ops.o common.o qos.o runtime.o
 obj-$(CONFIG_PM_SLEEP) += main.o wakeup.o
-obj-$(CONFIG_PM_RUNTIME)       += runtime.o
 obj-$(CONFIG_PM_TRACE_RTC)     += trace.o
 obj-$(CONFIG_PM_OPP)   += opp.o
 obj-$(CONFIG_PM_GENERIC_DOMAINS)       +=  domain.o domain_governor.o
index bfb8955..f3bfc42 100644 (file)
@@ -721,6 +721,13 @@ void pm_genpd_poweroff_unused(void)
        mutex_unlock(&gpd_list_lock);
 }
 
+static int __init genpd_poweroff_unused(void)
+{
+       pm_genpd_poweroff_unused();
+       return 0;
+}
+late_initcall(genpd_poweroff_unused);
+
 #else
 
 static inline int genpd_dev_pm_qos_notifier(struct notifier_block *nb,
index 72e00e6..4776cf5 100644 (file)
 #include <trace/events/rpm.h>
 #include "power.h"
 
+#define RPM_GET_CALLBACK(dev, cb)                              \
+({                                                             \
+       int (*__rpm_cb)(struct device *__d);                    \
+                                                               \
+       if (dev->pm_domain)                                     \
+               __rpm_cb = dev->pm_domain->ops.cb;              \
+       else if (dev->type && dev->type->pm)                    \
+               __rpm_cb = dev->type->pm->cb;                   \
+       else if (dev->class && dev->class->pm)                  \
+               __rpm_cb = dev->class->pm->cb;                  \
+       else if (dev->bus && dev->bus->pm)                      \
+               __rpm_cb = dev->bus->pm->cb;                    \
+       else                                                    \
+               __rpm_cb = NULL;                                \
+                                                               \
+       if (!__rpm_cb && dev->driver && dev->driver->pm)        \
+               __rpm_cb = dev->driver->pm->cb;                 \
+                                                               \
+       __rpm_cb;                                               \
+})
+
+static int (*rpm_get_suspend_cb(struct device *dev))(struct device *)
+{
+       return RPM_GET_CALLBACK(dev, runtime_suspend);
+}
+
+static int (*rpm_get_resume_cb(struct device *dev))(struct device *)
+{
+       return RPM_GET_CALLBACK(dev, runtime_resume);
+}
+
+#ifdef CONFIG_PM_RUNTIME
+static int (*rpm_get_idle_cb(struct device *dev))(struct device *)
+{
+       return RPM_GET_CALLBACK(dev, runtime_idle);
+}
+
 static int rpm_resume(struct device *dev, int rpmflags);
 static int rpm_suspend(struct device *dev, int rpmflags);
 
@@ -310,19 +347,7 @@ static int rpm_idle(struct device *dev, int rpmflags)
 
        dev->power.idle_notification = true;
 
-       if (dev->pm_domain)
-               callback = dev->pm_domain->ops.runtime_idle;
-       else if (dev->type && dev->type->pm)
-               callback = dev->type->pm->runtime_idle;
-       else if (dev->class && dev->class->pm)
-               callback = dev->class->pm->runtime_idle;
-       else if (dev->bus && dev->bus->pm)
-               callback = dev->bus->pm->runtime_idle;
-       else
-               callback = NULL;
-
-       if (!callback && dev->driver && dev->driver->pm)
-               callback = dev->driver->pm->runtime_idle;
+       callback = rpm_get_idle_cb(dev);
 
        if (callback)
                retval = __rpm_callback(callback, dev);
@@ -492,19 +517,7 @@ static int rpm_suspend(struct device *dev, int rpmflags)
 
        __update_runtime_status(dev, RPM_SUSPENDING);
 
-       if (dev->pm_domain)
-               callback = dev->pm_domain->ops.runtime_suspend;
-       else if (dev->type && dev->type->pm)
-               callback = dev->type->pm->runtime_suspend;
-       else if (dev->class && dev->class->pm)
-               callback = dev->class->pm->runtime_suspend;
-       else if (dev->bus && dev->bus->pm)
-               callback = dev->bus->pm->runtime_suspend;
-       else
-               callback = NULL;
-
-       if (!callback && dev->driver && dev->driver->pm)
-               callback = dev->driver->pm->runtime_suspend;
+       callback = rpm_get_suspend_cb(dev);
 
        retval = rpm_callback(callback, dev);
        if (retval)
@@ -724,19 +737,7 @@ static int rpm_resume(struct device *dev, int rpmflags)
 
        __update_runtime_status(dev, RPM_RESUMING);
 
-       if (dev->pm_domain)
-               callback = dev->pm_domain->ops.runtime_resume;
-       else if (dev->type && dev->type->pm)
-               callback = dev->type->pm->runtime_resume;
-       else if (dev->class && dev->class->pm)
-               callback = dev->class->pm->runtime_resume;
-       else if (dev->bus && dev->bus->pm)
-               callback = dev->bus->pm->runtime_resume;
-       else
-               callback = NULL;
-
-       if (!callback && dev->driver && dev->driver->pm)
-               callback = dev->driver->pm->runtime_resume;
+       callback = rpm_get_resume_cb(dev);
 
        retval = rpm_callback(callback, dev);
        if (retval) {
@@ -1401,3 +1402,86 @@ void pm_runtime_remove(struct device *dev)
        if (dev->power.irq_safe && dev->parent)
                pm_runtime_put(dev->parent);
 }
+#endif
+
+/**
+ * pm_runtime_force_suspend - Force a device into suspend state if needed.
+ * @dev: Device to suspend.
+ *
+ * Disable runtime PM so we safely can check the device's runtime PM status and
+ * if it is active, invoke it's .runtime_suspend callback to bring it into
+ * suspend state. Keep runtime PM disabled to preserve the state unless we
+ * encounter errors.
+ *
+ * Typically this function may be invoked from a system suspend callback to make
+ * sure the device is put into low power state.
+ */
+int pm_runtime_force_suspend(struct device *dev)
+{
+       int (*callback)(struct device *);
+       int ret = 0;
+
+       pm_runtime_disable(dev);
+
+       /*
+        * Note that pm_runtime_status_suspended() returns false while
+        * !CONFIG_PM_RUNTIME, which means the device will be put into low
+        * power state.
+        */
+       if (pm_runtime_status_suspended(dev))
+               return 0;
+
+       callback = rpm_get_suspend_cb(dev);
+
+       if (!callback) {
+               ret = -ENOSYS;
+               goto err;
+       }
+
+       ret = callback(dev);
+       if (ret)
+               goto err;
+
+       pm_runtime_set_suspended(dev);
+       return 0;
+err:
+       pm_runtime_enable(dev);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(pm_runtime_force_suspend);
+
+/**
+ * pm_runtime_force_resume - Force a device into resume state.
+ * @dev: Device to resume.
+ *
+ * Prior invoking this function we expect the user to have brought the device
+ * into low power state by a call to pm_runtime_force_suspend(). Here we reverse
+ * those actions and brings the device into full power. We update the runtime PM
+ * status and re-enables runtime PM.
+ *
+ * Typically this function may be invoked from a system resume callback to make
+ * sure the device is put into full power state.
+ */
+int pm_runtime_force_resume(struct device *dev)
+{
+       int (*callback)(struct device *);
+       int ret = 0;
+
+       callback = rpm_get_resume_cb(dev);
+
+       if (!callback) {
+               ret = -ENOSYS;
+               goto out;
+       }
+
+       ret = callback(dev);
+       if (ret)
+               goto out;
+
+       pm_runtime_set_active(dev);
+       pm_runtime_mark_last_busy(dev);
+out:
+       pm_runtime_enable(dev);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(pm_runtime_force_resume);
index f6cff3b..2f9a3d8 100644 (file)
@@ -1557,8 +1557,10 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
        } else {
                void *wval;
 
-               if (!val_count)
-                       return -EINVAL;
+               if (!val_count) {
+                       ret = -EINVAL;
+                       goto out;
+               }
 
                wval = kmemdup(val, val_count * val_bytes, GFP_KERNEL);
                if (!wval) {
index 5814deb..0ebadf9 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/blkdev.h>
 #include <linux/hdreg.h>
 #include <linux/genhd.h>
+#include <linux/cdrom.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/completion.h>
@@ -22,8 +23,8 @@
 
 #define DRV_MODULE_NAME                "sunvdc"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "1.0"
-#define DRV_MODULE_RELDATE     "June 25, 2007"
+#define DRV_MODULE_VERSION     "1.1"
+#define DRV_MODULE_RELDATE     "February 13, 2013"
 
 static char version[] =
        DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
@@ -32,7 +33,7 @@ MODULE_DESCRIPTION("Sun LDOM virtual disk client driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_MODULE_VERSION);
 
-#define VDC_TX_RING_SIZE       256
+#define VDC_TX_RING_SIZE       512
 
 #define WAITING_FOR_LINK_UP    0x01
 #define WAITING_FOR_TX_SPACE   0x02
@@ -65,11 +66,9 @@ struct vdc_port {
        u64                     operations;
        u32                     vdisk_size;
        u8                      vdisk_type;
+       u8                      vdisk_mtype;
 
        char                    disk_name[32];
-
-       struct vio_disk_geom    geom;
-       struct vio_disk_vtoc    label;
 };
 
 static inline struct vdc_port *to_vdc_port(struct vio_driver_state *vio)
@@ -79,9 +78,16 @@ static inline struct vdc_port *to_vdc_port(struct vio_driver_state *vio)
 
 /* Ordered from largest major to lowest */
 static struct vio_version vdc_versions[] = {
+       { .major = 1, .minor = 1 },
        { .major = 1, .minor = 0 },
 };
 
+static inline int vdc_version_supported(struct vdc_port *port,
+                                       u16 major, u16 minor)
+{
+       return port->vio.ver.major == major && port->vio.ver.minor >= minor;
+}
+
 #define VDCBLK_NAME    "vdisk"
 static int vdc_major;
 #define PARTITION_SHIFT        3
@@ -94,18 +100,54 @@ static inline u32 vdc_tx_dring_avail(struct vio_dring_state *dr)
 static int vdc_getgeo(struct block_device *bdev, struct hd_geometry *geo)
 {
        struct gendisk *disk = bdev->bd_disk;
-       struct vdc_port *port = disk->private_data;
+       sector_t nsect = get_capacity(disk);
+       sector_t cylinders = nsect;
 
-       geo->heads = (u8) port->geom.num_hd;
-       geo->sectors = (u8) port->geom.num_sec;
-       geo->cylinders = port->geom.num_cyl;
+       geo->heads = 0xff;
+       geo->sectors = 0x3f;
+       sector_div(cylinders, geo->heads * geo->sectors);
+       geo->cylinders = cylinders;
+       if ((sector_t)(geo->cylinders + 1) * geo->heads * geo->sectors < nsect)
+               geo->cylinders = 0xffff;
 
        return 0;
 }
 
+/* Add ioctl/CDROM_GET_CAPABILITY to support cdrom_id in udev
+ * when vdisk_mtype is VD_MEDIA_TYPE_CD or VD_MEDIA_TYPE_DVD.
+ * Needed to be able to install inside an ldom from an iso image.
+ */
+static int vdc_ioctl(struct block_device *bdev, fmode_t mode,
+                    unsigned command, unsigned long argument)
+{
+       int i;
+       struct gendisk *disk;
+
+       switch (command) {
+       case CDROMMULTISESSION:
+               pr_debug(PFX "Multisession CDs not supported\n");
+               for (i = 0; i < sizeof(struct cdrom_multisession); i++)
+                       if (put_user(0, (char __user *)(argument + i)))
+                               return -EFAULT;
+               return 0;
+
+       case CDROM_GET_CAPABILITY:
+               disk = bdev->bd_disk;
+
+               if (bdev->bd_disk && (disk->flags & GENHD_FL_CD))
+                       return 0;
+               return -EINVAL;
+
+       default:
+               pr_debug(PFX "ioctl %08x not supported\n", command);
+               return -EINVAL;
+       }
+}
+
 static const struct block_device_operations vdc_fops = {
        .owner          = THIS_MODULE,
        .getgeo         = vdc_getgeo,
+       .ioctl          = vdc_ioctl,
 };
 
 static void vdc_finish(struct vio_driver_state *vio, int err, int waiting_for)
@@ -165,9 +207,9 @@ static int vdc_handle_attr(struct vio_driver_state *vio, void *arg)
        struct vio_disk_attr_info *pkt = arg;
 
        viodbg(HS, "GOT ATTR stype[0x%x] ops[%llx] disk_size[%llu] disk_type[%x] "
-              "xfer_mode[0x%x] blksz[%u] max_xfer[%llu]\n",
+              "mtype[0x%x] xfer_mode[0x%x] blksz[%u] max_xfer[%llu]\n",
               pkt->tag.stype, pkt->operations,
-              pkt->vdisk_size, pkt->vdisk_type,
+              pkt->vdisk_size, pkt->vdisk_type, pkt->vdisk_mtype,
               pkt->xfer_mode, pkt->vdisk_block_size,
               pkt->max_xfer_size);
 
@@ -192,8 +234,11 @@ static int vdc_handle_attr(struct vio_driver_state *vio, void *arg)
                }
 
                port->operations = pkt->operations;
-               port->vdisk_size = pkt->vdisk_size;
                port->vdisk_type = pkt->vdisk_type;
+               if (vdc_version_supported(port, 1, 1)) {
+                       port->vdisk_size = pkt->vdisk_size;
+                       port->vdisk_mtype = pkt->vdisk_mtype;
+               }
                if (pkt->max_xfer_size < port->max_xfer_size)
                        port->max_xfer_size = pkt->max_xfer_size;
                port->vdisk_block_size = pkt->vdisk_block_size;
@@ -236,7 +281,9 @@ static void vdc_end_one(struct vdc_port *port, struct vio_dring_state *dr,
 
        __blk_end_request(req, (desc->status ? -EIO : 0), desc->size);
 
-       if (blk_queue_stopped(port->disk->queue))
+       /* restart blk queue when ring is half emptied */
+       if (blk_queue_stopped(port->disk->queue) &&
+           vdc_tx_dring_avail(dr) * 100 / VDC_TX_RING_SIZE >= 50)
                blk_start_queue(port->disk->queue);
 }
 
@@ -388,12 +435,6 @@ static int __send_request(struct request *req)
        for (i = 0; i < nsg; i++)
                len += sg[i].length;
 
-       if (unlikely(vdc_tx_dring_avail(dr) < 1)) {
-               blk_stop_queue(port->disk->queue);
-               err = -ENOMEM;
-               goto out;
-       }
-
        desc = vio_dring_cur(dr);
 
        err = ldc_map_sg(port->vio.lp, sg, nsg,
@@ -433,21 +474,32 @@ static int __send_request(struct request *req)
                port->req_id++;
                dr->prod = (dr->prod + 1) & (VDC_TX_RING_SIZE - 1);
        }
-out:
 
        return err;
 }
 
-static void do_vdc_request(struct request_queue *q)
+static void do_vdc_request(struct request_queue *rq)
 {
-       while (1) {
-               struct request *req = blk_fetch_request(q);
+       struct request *req;
 
-               if (!req)
-                       break;
+       while ((req = blk_peek_request(rq)) != NULL) {
+               struct vdc_port *port;
+               struct vio_dring_state *dr;
 
-               if (__send_request(req) < 0)
-                       __blk_end_request_all(req, -EIO);
+               port = req->rq_disk->private_data;
+               dr = &port->vio.drings[VIO_DRIVER_TX_RING];
+               if (unlikely(vdc_tx_dring_avail(dr) < 1))
+                       goto wait;
+
+               blk_start_request(req);
+
+               if (__send_request(req) < 0) {
+                       blk_requeue_request(rq, req);
+wait:
+                       /* Avoid pointless unplugs. */
+                       blk_stop_queue(rq);
+                       break;
+               }
        }
 }
 
@@ -656,25 +708,27 @@ static int probe_disk(struct vdc_port *port)
        if (comp.err)
                return comp.err;
 
-       err = generic_request(port, VD_OP_GET_VTOC,
-                             &port->label, sizeof(port->label));
-       if (err < 0) {
-               printk(KERN_ERR PFX "VD_OP_GET_VTOC returns error %d\n", err);
-               return err;
-       }
-
-       err = generic_request(port, VD_OP_GET_DISKGEOM,
-                             &port->geom, sizeof(port->geom));
-       if (err < 0) {
-               printk(KERN_ERR PFX "VD_OP_GET_DISKGEOM returns "
-                      "error %d\n", err);
-               return err;
+       if (vdc_version_supported(port, 1, 1)) {
+               /* vdisk_size should be set during the handshake, if it wasn't
+                * then the underlying disk is reserved by another system
+                */
+               if (port->vdisk_size == -1)
+                       return -ENODEV;
+       } else {
+               struct vio_disk_geom geom;
+
+               err = generic_request(port, VD_OP_GET_DISKGEOM,
+                                     &geom, sizeof(geom));
+               if (err < 0) {
+                       printk(KERN_ERR PFX "VD_OP_GET_DISKGEOM returns "
+                              "error %d\n", err);
+                       return err;
+               }
+               port->vdisk_size = ((u64)geom.num_cyl *
+                                   (u64)geom.num_hd *
+                                   (u64)geom.num_sec);
        }
 
-       port->vdisk_size = ((u64)port->geom.num_cyl *
-                           (u64)port->geom.num_hd *
-                           (u64)port->geom.num_sec);
-
        q = blk_init_queue(do_vdc_request, &port->vio.lock);
        if (!q) {
                printk(KERN_ERR PFX "%s: Could not allocate queue.\n",
@@ -691,6 +745,10 @@ static int probe_disk(struct vdc_port *port)
 
        port->disk = g;
 
+       /* Each segment in a request is up to an aligned page in size. */
+       blk_queue_segment_boundary(q, PAGE_SIZE - 1);
+       blk_queue_max_segment_size(q, PAGE_SIZE);
+
        blk_queue_max_segments(q, port->ring_cookies);
        blk_queue_max_hw_sectors(q, port->max_xfer_size);
        g->major = vdc_major;
@@ -704,9 +762,32 @@ static int probe_disk(struct vdc_port *port)
 
        set_capacity(g, port->vdisk_size);
 
-       printk(KERN_INFO PFX "%s: %u sectors (%u MB)\n",
+       if (vdc_version_supported(port, 1, 1)) {
+               switch (port->vdisk_mtype) {
+               case VD_MEDIA_TYPE_CD:
+                       pr_info(PFX "Virtual CDROM %s\n", port->disk_name);
+                       g->flags |= GENHD_FL_CD;
+                       g->flags |= GENHD_FL_REMOVABLE;
+                       set_disk_ro(g, 1);
+                       break;
+
+               case VD_MEDIA_TYPE_DVD:
+                       pr_info(PFX "Virtual DVD %s\n", port->disk_name);
+                       g->flags |= GENHD_FL_CD;
+                       g->flags |= GENHD_FL_REMOVABLE;
+                       set_disk_ro(g, 1);
+                       break;
+
+               case VD_MEDIA_TYPE_FIXED:
+                       pr_info(PFX "Virtual Hard disk %s\n", port->disk_name);
+                       break;
+               }
+       }
+
+       pr_info(PFX "%s: %u sectors (%u MB) protocol %d.%d\n",
               g->disk_name,
-              port->vdisk_size, (port->vdisk_size >> (20 - 9)));
+              port->vdisk_size, (port->vdisk_size >> (20 - 9)),
+              port->vio.ver.major, port->vio.ver.minor);
 
        add_disk(g);
 
@@ -765,6 +846,7 @@ static int vdc_port_probe(struct vio_dev *vdev, const struct vio_device_id *id)
        else
                snprintf(port->disk_name, sizeof(port->disk_name),
                         VDCBLK_NAME "%c", 'a' + ((int)vdev->dev_no % 26));
+       port->vdisk_size = -1;
 
        err = vio_driver_init(&port->vio, vdev, VDEV_DISK,
                              vdc_versions, ARRAY_SIZE(vdc_versions),
index 51c557c..d8ddb8e 100644 (file)
@@ -447,7 +447,8 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
        }
 
        if (page_zero_filled(uncmem)) {
-               kunmap_atomic(user_mem);
+               if (user_mem)
+                       kunmap_atomic(user_mem);
                /* Free memory associated with this sector now. */
                write_lock(&zram->meta->tb_lock);
                zram_free_page(zram, index);
index ab7ffde..f38f2c1 100644 (file)
 #include <asm/vio.h>
 
 
-static int pseries_rng_data_read(struct hwrng *rng, u32 *data)
+static int pseries_rng_read(struct hwrng *rng, void *data, size_t max, bool wait)
 {
+       u64 buffer[PLPAR_HCALL_BUFSIZE];
+       size_t size = max < 8 ? max : 8;
        int rc;
 
-       rc = plpar_hcall(H_RANDOM, (unsigned long *)data);
+       rc = plpar_hcall(H_RANDOM, (unsigned long *)buffer);
        if (rc != H_SUCCESS) {
                pr_err_ratelimited("H_RANDOM call failed %d\n", rc);
                return -EIO;
        }
+       memcpy(data, buffer, size);
 
        /* The hypervisor interface returns 64 bits */
-       return 8;
+       return size;
 }
 
 /**
@@ -55,7 +58,7 @@ static unsigned long pseries_rng_get_desired_dma(struct vio_dev *vdev)
 
 static struct hwrng pseries_rng = {
        .name           = KBUILD_MODNAME,
-       .data_read      = pseries_rng_data_read,
+       .read           = pseries_rng_read,
 };
 
 static int __init pseries_rng_probe(struct vio_dev *dev,
index e002923..960bf22 100644 (file)
@@ -4,7 +4,6 @@ obj-$(CONFIG_ARCH_R8A7740)              += clk-r8a7740.o
 obj-$(CONFIG_ARCH_R8A7779)             += clk-r8a7779.o
 obj-$(CONFIG_ARCH_R8A7790)             += clk-rcar-gen2.o
 obj-$(CONFIG_ARCH_R8A7791)             += clk-rcar-gen2.o
+obj-$(CONFIG_ARCH_R8A7794)             += clk-rcar-gen2.o
 obj-$(CONFIG_ARCH_SHMOBILE_MULTI)      += clk-div6.o
 obj-$(CONFIG_ARCH_SHMOBILE_MULTI)      += clk-mstp.o
-# for emply built-in.o
-obj-n  := dummy
index dff7f79..e996425 100644 (file)
@@ -202,6 +202,7 @@ static const struct clk_div_table cpg_sdh_div_table[] = {
 };
 
 static const struct clk_div_table cpg_sd01_div_table[] = {
+       {  4,  8 },
        {  5, 12 }, {  6, 16 }, {  7, 18 }, {  8, 24 },
        { 10, 36 }, { 11, 48 }, { 12, 10 }, {  0,  0 },
 };
index 95fb944..01469a4 100644 (file)
@@ -296,6 +296,21 @@ static void __arch_timer_setup(unsigned type,
        clockevents_config_and_register(clk, arch_timer_rate, 0xf, 0x7fffffff);
 }
 
+static void arch_timer_evtstrm_enable(int divider)
+{
+       u32 cntkctl = arch_timer_get_cntkctl();
+
+       cntkctl &= ~ARCH_TIMER_EVT_TRIGGER_MASK;
+       /* Set the divider and enable virtual event stream */
+       cntkctl |= (divider << ARCH_TIMER_EVT_TRIGGER_SHIFT)
+                       | ARCH_TIMER_VIRT_EVT_EN;
+       arch_timer_set_cntkctl(cntkctl);
+       elf_hwcap |= HWCAP_EVTSTRM;
+#ifdef CONFIG_COMPAT
+       compat_elf_hwcap |= COMPAT_HWCAP_EVTSTRM;
+#endif
+}
+
 static void arch_timer_configure_evtstream(void)
 {
        int evt_stream_div, pos;
@@ -309,6 +324,23 @@ static void arch_timer_configure_evtstream(void)
        arch_timer_evtstrm_enable(min(pos, 15));
 }
 
+static void arch_counter_set_user_access(void)
+{
+       u32 cntkctl = arch_timer_get_cntkctl();
+
+       /* Disable user access to the timers and the physical counter */
+       /* Also disable virtual event stream */
+       cntkctl &= ~(ARCH_TIMER_USR_PT_ACCESS_EN
+                       | ARCH_TIMER_USR_VT_ACCESS_EN
+                       | ARCH_TIMER_VIRT_EVT_EN
+                       | ARCH_TIMER_USR_PCT_ACCESS_EN);
+
+       /* Enable user access to the virtual counter */
+       cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN;
+
+       arch_timer_set_cntkctl(cntkctl);
+}
+
 static int arch_timer_setup(struct clock_event_device *clk)
 {
        __arch_timer_setup(ARCH_CP15_TIMER, clk);
index bf497af..7d19f86 100644 (file)
@@ -182,6 +182,12 @@ static void __init sun4i_timer_init(struct device_node *node)
        /* Make sure timer is stopped before playing with interrupts */
        sun4i_clkevt_time_stop(0);
 
+       sun4i_clockevent.cpumask = cpu_possible_mask;
+       sun4i_clockevent.irq = irq;
+
+       clockevents_config_and_register(&sun4i_clockevent, rate,
+                                       TIMER_SYNC_TICKS, 0xffffffff);
+
        ret = setup_irq(irq, &sun4i_timer_irq);
        if (ret)
                pr_warn("failed to setup irq %d\n", irq);
@@ -189,12 +195,6 @@ static void __init sun4i_timer_init(struct device_node *node)
        /* Enable timer0 interrupt */
        val = readl(timer_base + TIMER_IRQ_EN_REG);
        writel(val | TIMER_IRQ_EN(0), timer_base + TIMER_IRQ_EN_REG);
-
-       sun4i_clockevent.cpumask = cpu_possible_mask;
-       sun4i_clockevent.irq = irq;
-
-       clockevents_config_and_register(&sun4i_clockevent, rate,
-                                       TIMER_SYNC_TICKS, 0xffffffff);
 }
 CLOCKSOURCE_OF_DECLARE(sun4i, "allwinner,sun4i-timer",
                       sun4i_timer_init);
index a412745..d97a03d 100644 (file)
@@ -835,8 +835,9 @@ static int ahash_update_ctx(struct ahash_request *req)
                                           edesc->sec4_sg + sec4_sg_src_index,
                                           chained);
                        if (*next_buflen) {
-                               sg_copy_part(next_buf, req->src, to_hash -
-                                            *buflen, req->nbytes);
+                               scatterwalk_map_and_copy(next_buf, req->src,
+                                                        to_hash - *buflen,
+                                                        *next_buflen, 0);
                                state->current_buf = !state->current_buf;
                        }
                } else {
@@ -869,7 +870,8 @@ static int ahash_update_ctx(struct ahash_request *req)
                        kfree(edesc);
                }
        } else if (*next_buflen) {
-               sg_copy(buf + *buflen, req->src, req->nbytes);
+               scatterwalk_map_and_copy(buf + *buflen, req->src, 0,
+                                        req->nbytes, 0);
                *buflen = *next_buflen;
                *next_buflen = last_buflen;
        }
@@ -1216,8 +1218,9 @@ static int ahash_update_no_ctx(struct ahash_request *req)
                src_map_to_sec4_sg(jrdev, req->src, src_nents,
                                   edesc->sec4_sg + 1, chained);
                if (*next_buflen) {
-                       sg_copy_part(next_buf, req->src, to_hash - *buflen,
-                                   req->nbytes);
+                       scatterwalk_map_and_copy(next_buf, req->src,
+                                                to_hash - *buflen,
+                                                *next_buflen, 0);
                        state->current_buf = !state->current_buf;
                }
 
@@ -1248,7 +1251,8 @@ static int ahash_update_no_ctx(struct ahash_request *req)
                        kfree(edesc);
                }
        } else if (*next_buflen) {
-               sg_copy(buf + *buflen, req->src, req->nbytes);
+               scatterwalk_map_and_copy(buf + *buflen, req->src, 0,
+                                        req->nbytes, 0);
                *buflen = *next_buflen;
                *next_buflen = 0;
        }
@@ -1405,7 +1409,8 @@ static int ahash_update_first(struct ahash_request *req)
                }
 
                if (*next_buflen)
-                       sg_copy_part(next_buf, req->src, to_hash, req->nbytes);
+                       scatterwalk_map_and_copy(next_buf, req->src, to_hash,
+                                                *next_buflen, 0);
 
                sh_len = desc_len(sh_desc);
                desc = edesc->hw_desc;
@@ -1438,7 +1443,8 @@ static int ahash_update_first(struct ahash_request *req)
                state->update = ahash_update_no_ctx;
                state->finup = ahash_finup_no_ctx;
                state->final = ahash_final_no_ctx;
-               sg_copy(next_buf, req->src, req->nbytes);
+               scatterwalk_map_and_copy(next_buf, req->src, 0,
+                                        req->nbytes, 0);
        }
 #ifdef DEBUG
        print_hex_dump(KERN_ERR, "next buf@"__stringify(__LINE__)": ",
index ea2e406..b872eed 100644 (file)
@@ -51,23 +51,29 @@ int gen_split_key(struct device *jrdev, u8 *key_out, int split_key_len,
        u32 *desc;
        struct split_key_result result;
        dma_addr_t dma_addr_in, dma_addr_out;
-       int ret = 0;
+       int ret = -ENOMEM;
 
        desc = kmalloc(CAAM_CMD_SZ * 6 + CAAM_PTR_SZ * 2, GFP_KERNEL | GFP_DMA);
        if (!desc) {
                dev_err(jrdev, "unable to allocate key input memory\n");
-               return -ENOMEM;
+               return ret;
        }
 
-       init_job_desc(desc, 0);
-
        dma_addr_in = dma_map_single(jrdev, (void *)key_in, keylen,
                                     DMA_TO_DEVICE);
        if (dma_mapping_error(jrdev, dma_addr_in)) {
                dev_err(jrdev, "unable to map key input memory\n");
-               kfree(desc);
-               return -ENOMEM;
+               goto out_free;
        }
+
+       dma_addr_out = dma_map_single(jrdev, key_out, split_key_pad_len,
+                                     DMA_FROM_DEVICE);
+       if (dma_mapping_error(jrdev, dma_addr_out)) {
+               dev_err(jrdev, "unable to map key output memory\n");
+               goto out_unmap_in;
+       }
+
+       init_job_desc(desc, 0);
        append_key(desc, dma_addr_in, keylen, CLASS_2 | KEY_DEST_CLASS_REG);
 
        /* Sets MDHA up into an HMAC-INIT */
@@ -84,13 +90,6 @@ int gen_split_key(struct device *jrdev, u8 *key_out, int split_key_len,
         * FIFO_STORE with the explicit split-key content store
         * (0x26 output type)
         */
-       dma_addr_out = dma_map_single(jrdev, key_out, split_key_pad_len,
-                                     DMA_FROM_DEVICE);
-       if (dma_mapping_error(jrdev, dma_addr_out)) {
-               dev_err(jrdev, "unable to map key output memory\n");
-               kfree(desc);
-               return -ENOMEM;
-       }
        append_fifo_store(desc, dma_addr_out, split_key_len,
                          LDST_CLASS_2_CCB | FIFOST_TYPE_SPLIT_KEK);
 
@@ -118,10 +117,10 @@ int gen_split_key(struct device *jrdev, u8 *key_out, int split_key_len,
 
        dma_unmap_single(jrdev, dma_addr_out, split_key_pad_len,
                         DMA_FROM_DEVICE);
+out_unmap_in:
        dma_unmap_single(jrdev, dma_addr_in, keylen, DMA_TO_DEVICE);
-
+out_free:
        kfree(desc);
-
        return ret;
 }
 EXPORT_SYMBOL(gen_split_key);
index b12ff85..ce28a56 100644 (file)
@@ -116,57 +116,3 @@ static int dma_unmap_sg_chained(struct device *dev, struct scatterlist *sg,
        }
        return nents;
 }
-
-/* Map SG page in kernel virtual address space and copy */
-static inline void sg_map_copy(u8 *dest, struct scatterlist *sg,
-                              int len, int offset)
-{
-       u8 *mapped_addr;
-
-       /*
-        * Page here can be user-space pinned using get_user_pages
-        * Same must be kmapped before use and kunmapped subsequently
-        */
-       mapped_addr = kmap_atomic(sg_page(sg));
-       memcpy(dest, mapped_addr + offset, len);
-       kunmap_atomic(mapped_addr);
-}
-
-/* Copy from len bytes of sg to dest, starting from beginning */
-static inline void sg_copy(u8 *dest, struct scatterlist *sg, unsigned int len)
-{
-       struct scatterlist *current_sg = sg;
-       int cpy_index = 0, next_cpy_index = current_sg->length;
-
-       while (next_cpy_index < len) {
-               sg_map_copy(dest + cpy_index, current_sg, current_sg->length,
-                           current_sg->offset);
-               current_sg = scatterwalk_sg_next(current_sg);
-               cpy_index = next_cpy_index;
-               next_cpy_index += current_sg->length;
-       }
-       if (cpy_index < len)
-               sg_map_copy(dest + cpy_index, current_sg, len-cpy_index,
-                           current_sg->offset);
-}
-
-/* Copy sg data, from to_skip to end, to dest */
-static inline void sg_copy_part(u8 *dest, struct scatterlist *sg,
-                                     int to_skip, unsigned int end)
-{
-       struct scatterlist *current_sg = sg;
-       int sg_index, cpy_index, offset;
-
-       sg_index = current_sg->length;
-       while (sg_index <= to_skip) {
-               current_sg = scatterwalk_sg_next(current_sg);
-               sg_index += current_sg->length;
-       }
-       cpy_index = sg_index - to_skip;
-       offset = current_sg->offset + current_sg->length - cpy_index;
-       sg_map_copy(dest, current_sg, cpy_index, offset);
-       if (end - sg_index) {
-               current_sg = scatterwalk_sg_next(current_sg);
-               sg_copy(dest + cpy_index, current_sg, end - sg_index);
-       }
-}
index d7d5c8a..6d44568 100644 (file)
@@ -1637,8 +1637,7 @@ static int dispatch_ioctl(struct client *client,
            _IOC_SIZE(cmd) > sizeof(buffer))
                return -ENOTTY;
 
-       if (_IOC_DIR(cmd) == _IOC_READ)
-               memset(&buffer, 0, _IOC_SIZE(cmd));
+       memset(&buffer, 0, sizeof(buffer));
 
        if (_IOC_DIR(cmd) & _IOC_WRITE)
                if (copy_from_user(&buffer, arg, _IOC_SIZE(cmd)))
index 307464f..41b2f40 100644 (file)
@@ -39,31 +39,53 @@ static int devm_gpiod_match(struct device *dev, void *res, void *data)
  * devm_gpiod_get - Resource-managed gpiod_get()
  * @dev:       GPIO consumer
  * @con_id:    function within the GPIO consumer
+ * @flags:     optional GPIO initialization flags
  *
  * Managed gpiod_get(). GPIO descriptors returned from this function are
  * automatically disposed on driver detach. See gpiod_get() for detailed
  * information about behavior and return values.
  */
-struct gpio_desc *__must_check devm_gpiod_get(struct device *dev,
-                                             const char *con_id)
+struct gpio_desc *__must_check __devm_gpiod_get(struct device *dev,
+                                             const char *con_id,
+                                             enum gpiod_flags flags)
 {
-       return devm_gpiod_get_index(dev, con_id, 0);
+       return devm_gpiod_get_index(dev, con_id, 0, flags);
 }
-EXPORT_SYMBOL(devm_gpiod_get);
+EXPORT_SYMBOL(__devm_gpiod_get);
+
+/**
+ * devm_gpiod_get_optional - Resource-managed gpiod_get_optional()
+ * @dev: GPIO consumer
+ * @con_id: function within the GPIO consumer
+ * @flags: optional GPIO initialization flags
+ *
+ * Managed gpiod_get_optional(). GPIO descriptors returned from this function
+ * are automatically disposed on driver detach. See gpiod_get_optional() for
+ * detailed information about behavior and return values.
+ */
+struct gpio_desc *__must_check __devm_gpiod_get_optional(struct device *dev,
+                                                      const char *con_id,
+                                                      enum gpiod_flags flags)
+{
+       return devm_gpiod_get_index_optional(dev, con_id, 0, flags);
+}
+EXPORT_SYMBOL(__devm_gpiod_get_optional);
 
 /**
  * devm_gpiod_get_index - Resource-managed gpiod_get_index()
  * @dev:       GPIO consumer
  * @con_id:    function within the GPIO consumer
  * @idx:       index of the GPIO to obtain in the consumer
+ * @flags:     optional GPIO initialization flags
  *
  * Managed gpiod_get_index(). GPIO descriptors returned from this function are
  * automatically disposed on driver detach. See gpiod_get_index() for detailed
  * information about behavior and return values.
  */
-struct gpio_desc *__must_check devm_gpiod_get_index(struct device *dev,
+struct gpio_desc *__must_check __devm_gpiod_get_index(struct device *dev,
                                                    const char *con_id,
-                                                   unsigned int idx)
+                                                   unsigned int idx,
+                                                   enum gpiod_flags flags)
 {
        struct gpio_desc **dr;
        struct gpio_desc *desc;
@@ -73,7 +95,7 @@ struct gpio_desc *__must_check devm_gpiod_get_index(struct device *dev,
        if (!dr)
                return ERR_PTR(-ENOMEM);
 
-       desc = gpiod_get_index(dev, con_id, idx);
+       desc = gpiod_get_index(dev, con_id, idx, flags);
        if (IS_ERR(desc)) {
                devres_free(dr);
                return desc;
@@ -84,7 +106,36 @@ struct gpio_desc *__must_check devm_gpiod_get_index(struct device *dev,
 
        return desc;
 }
-EXPORT_SYMBOL(devm_gpiod_get_index);
+EXPORT_SYMBOL(__devm_gpiod_get_index);
+
+/**
+ * devm_gpiod_get_index_optional - Resource-managed gpiod_get_index_optional()
+ * @dev: GPIO consumer
+ * @con_id: function within the GPIO consumer
+ * @index: index of the GPIO to obtain in the consumer
+ * @flags: optional GPIO initialization flags
+ *
+ * Managed gpiod_get_index_optional(). GPIO descriptors returned from this
+ * function are automatically disposed on driver detach. See
+ * gpiod_get_index_optional() for detailed information about behavior and
+ * return values.
+ */
+struct gpio_desc *__must_check __devm_gpiod_get_index_optional(struct device *dev,
+                                                            const char *con_id,
+                                                            unsigned int index,
+                                                        enum gpiod_flags flags)
+{
+       struct gpio_desc *desc;
+
+       desc = devm_gpiod_get_index(dev, con_id, index, flags);
+       if (IS_ERR(desc)) {
+               if (PTR_ERR(desc) == -ENOENT)
+                       return NULL;
+       }
+
+       return desc;
+}
+EXPORT_SYMBOL(__devm_gpiod_get_index_optional);
 
 /**
  * devm_gpiod_put - Resource-managed gpiod_put()
index 50c4922..1cc33de 100644 (file)
@@ -164,16 +164,17 @@ struct gpio_desc *gpio_to_desc(unsigned gpio)
 EXPORT_SYMBOL_GPL(gpio_to_desc);
 
 /**
- * Convert an offset on a certain chip to a corresponding descriptor
+ * Get the GPIO descriptor corresponding to the given hw number for this chip.
  */
-static struct gpio_desc *gpiochip_offset_to_desc(struct gpio_chip *chip,
-                                                unsigned int offset)
+struct gpio_desc *gpiochip_get_desc(struct gpio_chip *chip,
+                                   u16 hwnum)
 {
-       if (offset >= chip->ngpio)
+       if (hwnum >= chip->ngpio)
                return ERR_PTR(-EINVAL);
 
-       return &chip->desc[offset];
+       return &chip->desc[hwnum];
 }
+EXPORT_SYMBOL_GPL(gpiochip_get_desc);
 
 /**
  * Convert a GPIO descriptor to the integer namespace.
@@ -350,9 +351,9 @@ static ssize_t gpio_direction_store(struct device *dev,
        if (!test_bit(FLAG_EXPORT, &desc->flags))
                status = -EIO;
        else if (sysfs_streq(buf, "high"))
-               status = gpiod_direction_output(desc, 1);
+               status = gpiod_direction_output_raw(desc, 1);
        else if (sysfs_streq(buf, "out") || sysfs_streq(buf, "low"))
-               status = gpiod_direction_output(desc, 0);
+               status = gpiod_direction_output_raw(desc, 0);
        else if (sysfs_streq(buf, "in"))
                status = gpiod_direction_input(desc);
        else
@@ -1590,7 +1591,7 @@ int gpio_request_one(unsigned gpio, unsigned long flags, const char *label)
        if (flags & GPIOF_DIR_IN)
                err = gpiod_direction_input(desc);
        else
-               err = gpiod_direction_output(desc,
+               err = gpiod_direction_output_raw(desc,
                                (flags & GPIOF_INIT_HIGH) ? 1 : 0);
 
        if (err)
@@ -1756,28 +1757,13 @@ fail:
 }
 EXPORT_SYMBOL_GPL(gpiod_direction_input);
 
-/**
- * gpiod_direction_output - set the GPIO direction to input
- * @desc:      GPIO to set to output
- * @value:     initial output value of the GPIO
- *
- * Set the direction of the passed GPIO to output, such as gpiod_set_value() can
- * be called safely on it. The initial value of the output must be specified.
- *
- * Return 0 in case of success, else an error code.
- */
-int gpiod_direction_output(struct gpio_desc *desc, int value)
+static int _gpiod_direction_output_raw(struct gpio_desc *desc, int value)
 {
        unsigned long           flags;
        struct gpio_chip        *chip;
        int                     status = -EINVAL;
        int offset;
 
-       if (!desc || !desc->chip) {
-               pr_warn("%s: invalid GPIO\n", __func__);
-               return -EINVAL;
-       }
-
        /* GPIOs used for IRQs shall not be set as output */
        if (test_bit(FLAG_USED_AS_IRQ, &desc->flags)) {
                gpiod_err(desc,
@@ -1840,6 +1826,50 @@ fail:
                gpiod_dbg(desc, "%s: gpio status %d\n", __func__, status);
        return status;
 }
+
+/**
+ * gpiod_direction_output_raw - set the GPIO direction to output
+ * @desc:      GPIO to set to output
+ * @value:     initial output value of the GPIO
+ *
+ * Set the direction of the passed GPIO to output, such as gpiod_set_value() can
+ * be called safely on it. The initial value of the output must be specified
+ * as raw value on the physical line without regard for the ACTIVE_LOW status.
+ *
+ * Return 0 in case of success, else an error code.
+ */
+int gpiod_direction_output_raw(struct gpio_desc *desc, int value)
+{
+       if (!desc || !desc->chip) {
+               pr_warn("%s: invalid GPIO\n", __func__);
+               return -EINVAL;
+       }
+       return _gpiod_direction_output_raw(desc, value);
+}
+EXPORT_SYMBOL_GPL(gpiod_direction_output_raw);
+
+/**
+ * gpiod_direction_output - set the GPIO direction to input
+ * @desc:      GPIO to set to output
+ * @value:     initial output value of the GPIO
+ *
+ * Set the direction of the passed GPIO to output, such as gpiod_set_value() can
+ * be called safely on it. The initial value of the output must be specified
+ * as the logical value of the GPIO, i.e. taking its ACTIVE_LOW status into
+ * account.
+ *
+ * Return 0 in case of success, else an error code.
+ */
+int gpiod_direction_output(struct gpio_desc *desc, int value)
+{
+       if (!desc || !desc->chip) {
+               pr_warn("%s: invalid GPIO\n", __func__);
+               return -EINVAL;
+       }
+       if (test_bit(FLAG_ACTIVE_LOW, &desc->flags))
+               value = !value;
+       return _gpiod_direction_output_raw(desc, value);
+}
 EXPORT_SYMBOL_GPL(gpiod_direction_output);
 
 /**
@@ -2161,7 +2191,7 @@ EXPORT_SYMBOL_GPL(gpiod_lock_as_irq);
 
 int gpio_lock_as_irq(struct gpio_chip *chip, unsigned int offset)
 {
-       return gpiod_lock_as_irq(gpiochip_offset_to_desc(chip, offset));
+       return gpiod_lock_as_irq(gpiochip_get_desc(chip, offset));
 }
 EXPORT_SYMBOL_GPL(gpio_lock_as_irq);
 
@@ -2183,7 +2213,7 @@ EXPORT_SYMBOL_GPL(gpiod_unlock_as_irq);
 
 void gpio_unlock_as_irq(struct gpio_chip *chip, unsigned int offset)
 {
-       return gpiod_unlock_as_irq(gpiochip_offset_to_desc(chip, offset));
+       return gpiod_unlock_as_irq(gpiochip_get_desc(chip, offset));
 }
 EXPORT_SYMBOL_GPL(gpio_unlock_as_irq);
 
@@ -2404,7 +2434,7 @@ static struct gpio_desc *gpiod_find(struct device *dev, const char *con_id,
                        return ERR_PTR(-EINVAL);
                }
 
-               desc = gpiochip_offset_to_desc(chip, p->chip_hwnum);
+               desc = gpiochip_get_desc(chip, p->chip_hwnum);
                *flags = p->flags;
 
                return desc;
@@ -2417,22 +2447,43 @@ static struct gpio_desc *gpiod_find(struct device *dev, const char *con_id,
  * gpio_get - obtain a GPIO for a given GPIO function
  * @dev:       GPIO consumer, can be NULL for system-global GPIOs
  * @con_id:    function within the GPIO consumer
+ * @flags:     optional GPIO initialization flags
  *
  * Return the GPIO descriptor corresponding to the function con_id of device
  * dev, -ENOENT if no GPIO has been assigned to the requested function, or
  * another IS_ERR() code if an error occured while trying to acquire the GPIO.
  */
-struct gpio_desc *__must_check gpiod_get(struct device *dev, const char *con_id)
+struct gpio_desc *__must_check __gpiod_get(struct device *dev, const char *con_id,
+                                        enum gpiod_flags flags)
 {
-       return gpiod_get_index(dev, con_id, 0);
+       return gpiod_get_index(dev, con_id, 0, flags);
 }
-EXPORT_SYMBOL_GPL(gpiod_get);
+EXPORT_SYMBOL_GPL(__gpiod_get);
+
+/**
+ * gpiod_get_optional - obtain an optional GPIO for a given GPIO function
+ * @dev: GPIO consumer, can be NULL for system-global GPIOs
+ * @con_id: function within the GPIO consumer
+ * @flags: optional GPIO initialization flags
+ *
+ * This is equivalent to gpiod_get(), except that when no GPIO was assigned to
+ * the requested function it will return NULL. This is convenient for drivers
+ * that need to handle optional GPIOs.
+ */
+struct gpio_desc *__must_check __gpiod_get_optional(struct device *dev,
+                                                 const char *con_id,
+                                                 enum gpiod_flags flags)
+{
+       return gpiod_get_index_optional(dev, con_id, 0, flags);
+}
+EXPORT_SYMBOL_GPL(__gpiod_get_optional);
 
 /**
  * gpiod_get_index - obtain a GPIO from a multi-index GPIO function
  * @dev:       GPIO consumer, can be NULL for system-global GPIOs
  * @con_id:    function within the GPIO consumer
  * @idx:       index of the GPIO to obtain in the consumer
+ * @flags:     optional GPIO initialization flags
  *
  * This variant of gpiod_get() allows to access GPIOs other than the first
  * defined one for functions that define several GPIOs.
@@ -2441,23 +2492,24 @@ EXPORT_SYMBOL_GPL(gpiod_get);
  * requested function and/or index, or another IS_ERR() code if an error
  * occured while trying to acquire the GPIO.
  */
-struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
+struct gpio_desc *__must_check __gpiod_get_index(struct device *dev,
                                               const char *con_id,
-                                              unsigned int idx)
+                                              unsigned int idx,
+                                              enum gpiod_flags flags)
 {
        struct gpio_desc *desc = NULL;
        int status;
-       enum gpio_lookup_flags flags = 0;
+       enum gpio_lookup_flags lookupflags = 0;
 
        dev_dbg(dev, "GPIO lookup for consumer %s\n", con_id);
 
        /* Using device tree? */
        if (IS_ENABLED(CONFIG_OF) && dev && dev->of_node) {
                dev_dbg(dev, "using device tree for GPIO lookup\n");
-               desc = of_find_gpio(dev, con_id, idx, &flags);
+               desc = of_find_gpio(dev, con_id, idx, &lookupflags);
        } else if (IS_ENABLED(CONFIG_ACPI) && dev && ACPI_HANDLE(dev)) {
                dev_dbg(dev, "using ACPI for GPIO lookup\n");
-               desc = acpi_find_gpio(dev, con_id, idx, &flags);
+               desc = acpi_find_gpio(dev, con_id, idx, &lookupflags);
        }
 
        /*
@@ -2466,7 +2518,7 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
         */
        if (!desc || desc == ERR_PTR(-ENOENT)) {
                dev_dbg(dev, "using lookup tables for GPIO lookup");
-               desc = gpiod_find(dev, con_id, idx, &flags);
+               desc = gpiod_find(dev, con_id, idx, &lookupflags);
        }
 
        if (IS_ERR(desc)) {
@@ -2479,16 +2531,62 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
        if (status < 0)
                return ERR_PTR(status);
 
-       if (flags & GPIO_ACTIVE_LOW)
+       if (lookupflags & GPIO_ACTIVE_LOW)
                set_bit(FLAG_ACTIVE_LOW, &desc->flags);
-       if (flags & GPIO_OPEN_DRAIN)
+       if (lookupflags & GPIO_OPEN_DRAIN)
                set_bit(FLAG_OPEN_DRAIN, &desc->flags);
-       if (flags & GPIO_OPEN_SOURCE)
+       if (lookupflags & GPIO_OPEN_SOURCE)
                set_bit(FLAG_OPEN_SOURCE, &desc->flags);
 
+       /* No particular flag request, return here... */
+       if (flags & GPIOD_FLAGS_BIT_DIR_SET)
+               return desc;
+
+       /* Process flags */
+       if (flags & GPIOD_FLAGS_BIT_DIR_OUT)
+               status = gpiod_direction_output(desc,
+                                             flags & GPIOD_FLAGS_BIT_DIR_VAL);
+       else
+               status = gpiod_direction_input(desc);
+
+       if (status < 0) {
+               dev_dbg(dev, "setup of GPIO %s failed\n", con_id);
+               gpiod_put(desc);
+               return ERR_PTR(status);
+       }
+
+       return desc;
+}
+EXPORT_SYMBOL_GPL(__gpiod_get_index);
+
+/**
+ * gpiod_get_index_optional - obtain an optional GPIO from a multi-index GPIO
+ *                            function
+ * @dev: GPIO consumer, can be NULL for system-global GPIOs
+ * @con_id: function within the GPIO consumer
+ * @index: index of the GPIO to obtain in the consumer
+ * @flags: optional GPIO initialization flags
+ *
+ * This is equivalent to gpiod_get_index(), except that when no GPIO with the
+ * specified index was assigned to the requested function it will return NULL.
+ * This is convenient for drivers that need to handle optional GPIOs.
+ */
+struct gpio_desc *__must_check __gpiod_get_index_optional(struct device *dev,
+                                                       const char *con_id,
+                                                       unsigned int index,
+                                                       enum gpiod_flags flags)
+{
+       struct gpio_desc *desc;
+
+       desc = gpiod_get_index(dev, con_id, index, flags);
+       if (IS_ERR(desc)) {
+               if (PTR_ERR(desc) == -ENOENT)
+                       return NULL;
+       }
+
        return desc;
 }
-EXPORT_SYMBOL_GPL(gpiod_get_index);
+EXPORT_SYMBOL_GPL(__gpiod_get_index_optional);
 
 /**
  * gpiod_put - dispose of a GPIO descriptor
index ab5c265..ddf70d6 100644 (file)
@@ -3936,8 +3936,8 @@ static int cik_cp_gfx_start(struct radeon_device *rdev)
        /* init the CE partitions.  CE only used for gfx on CIK */
        radeon_ring_write(ring, PACKET3(PACKET3_SET_BASE, 2));
        radeon_ring_write(ring, PACKET3_BASE_INDEX(CE_PARTITION_BASE));
-       radeon_ring_write(ring, 0xc000);
-       radeon_ring_write(ring, 0xc000);
+       radeon_ring_write(ring, 0x8000);
+       radeon_ring_write(ring, 0x8000);
 
        /* setup clear context state */
        radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
@@ -8893,6 +8893,9 @@ void dce8_bandwidth_update(struct radeon_device *rdev)
        u32 num_heads = 0, lb_size;
        int i;
 
+       if (!rdev->mode_info.mode_config_initialized)
+               return;
+
        radeon_update_display_priority(rdev);
 
        for (i = 0; i < rdev->num_crtc; i++) {
index 4b3c5f7..7138f3e 100644 (file)
@@ -2362,6 +2362,9 @@ void evergreen_bandwidth_update(struct radeon_device *rdev)
        u32 num_heads = 0, lb_size;
        int i;
 
+       if (!rdev->mode_info.mode_config_initialized)
+               return;
+
        radeon_update_display_priority(rdev);
 
        for (i = 0; i < rdev->num_crtc; i++) {
@@ -2570,6 +2573,7 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav
                                        WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);
                                        tmp |= EVERGREEN_CRTC_BLANK_DATA_EN;
                                        WREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i], tmp);
+                                       WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0);
                                }
                        } else {
                                tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]);
index 3cc78bb..07620e1 100644 (file)
@@ -3219,6 +3219,9 @@ void r100_bandwidth_update(struct radeon_device *rdev)
        uint32_t pixel_bytes1 = 0;
        uint32_t pixel_bytes2 = 0;
 
+       if (!rdev->mode_info.mode_config_initialized)
+               return;
+
        radeon_update_display_priority(rdev);
 
        if (rdev->mode_info.crtcs[0]->base.enabled) {
index 813db8d..3334f91 100644 (file)
@@ -1209,7 +1209,7 @@ int r600_parse_extended_power_table(struct radeon_device *rdev)
                                        (mode_info->atom_context->bios + data_offset +
                                         le16_to_cpu(ext_hdr->usPowerTuneTableOffset));
                                rdev->pm.dpm.dyn_state.cac_tdp_table->maximum_power_delivery_limit =
-                                       ppt->usMaximumPowerDeliveryLimit;
+                                       le16_to_cpu(ppt->usMaximumPowerDeliveryLimit);
                                pt = &ppt->power_tune_table;
                        } else {
                                ATOM_PPLIB_POWERTUNE_Table *ppt = (ATOM_PPLIB_POWERTUNE_Table *)
index 089c9ff..b3f0293 100644 (file)
@@ -202,6 +202,16 @@ static bool radeon_msi_ok(struct radeon_device *rdev)
        if (rdev->flags & RADEON_IS_AGP)
                return false;
 
+       /*
+        * Older chips have a HW limitation, they can only generate 40 bits
+        * of address for "64-bit" MSIs which breaks on some platforms, notably
+        * IBM POWER servers, so we limit them
+        */
+       if (rdev->family < CHIP_BONAIRE) {
+               dev_info(rdev->dev, "radeon: MSI limited to 32-bit\n");
+               rdev->pdev->no_64bit_msi = 1;
+       }
+
        /* force MSI on */
        if (radeon_msi == 1)
                return true;
index 95b693c..e5619d5 100644 (file)
@@ -890,6 +890,9 @@ void rs600_bandwidth_update(struct radeon_device *rdev)
        u32 d1mode_priority_a_cnt, d2mode_priority_a_cnt;
        /* FIXME: implement full support */
 
+       if (!rdev->mode_info.mode_config_initialized)
+               return;
+
        radeon_update_display_priority(rdev);
 
        if (rdev->mode_info.crtcs[0]->base.enabled)
index 3462b64..0a2d36e 100644 (file)
@@ -579,6 +579,9 @@ void rs690_bandwidth_update(struct radeon_device *rdev)
        u32 d1mode_priority_a_cnt, d1mode_priority_b_cnt;
        u32 d2mode_priority_a_cnt, d2mode_priority_b_cnt;
 
+       if (!rdev->mode_info.mode_config_initialized)
+               return;
+
        radeon_update_display_priority(rdev);
 
        if (rdev->mode_info.crtcs[0]->base.enabled)
index 237dd29..b49965a 100644 (file)
@@ -1276,6 +1276,9 @@ void rv515_bandwidth_update(struct radeon_device *rdev)
        struct drm_display_mode *mode0 = NULL;
        struct drm_display_mode *mode1 = NULL;
 
+       if (!rdev->mode_info.mode_config_initialized)
+               return;
+
        radeon_update_display_priority(rdev);
 
        if (rdev->mode_info.crtcs[0]->base.enabled)
index 559564c..52b64ad 100644 (file)
@@ -2227,6 +2227,9 @@ void dce6_bandwidth_update(struct radeon_device *rdev)
        u32 num_heads = 0, lb_size;
        int i;
 
+       if (!rdev->mode_info.mode_config_initialized)
+               return;
+
        radeon_update_display_priority(rdev);
 
        for (i = 0; i < rdev->num_crtc; i++) {
index 2e3d7b5..c96f608 100644 (file)
@@ -6,6 +6,7 @@ config DRM_RCAR_DU
        select DRM_KMS_CMA_HELPER
        select DRM_GEM_CMA_HELPER
        select DRM_KMS_FB_HELPER
+       select VIDEOMODE_HELPERS
        help
          Choose this option if you have an R-Car chipset.
          If M is selected the module will be called rcar-du-drm.
index fbf4be3..e97cbb3 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * rcar_du_crtc.c  --  R-Car Display Unit CRTCs
  *
- * Copyright (C) 2013 Renesas Corporation
+ * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
index 43e7575..e97ae50 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * rcar_du_crtc.h  --  R-Car Display Unit CRTCs
  *
- * Copyright (C) 2013 Renesas Corporation
+ * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
index fda64b7..b9b7651 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * rcar_du_drv.c  --  R-Car Display Unit DRM driver
  *
- * Copyright (C) 2013 Renesas Corporation
+ * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
@@ -15,6 +15,7 @@
 #include <linux/io.h>
 #include <linux/mm.h>
 #include <linux/module.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/pm.h>
 #include <linux/slab.h>
 #include "rcar_du_regs.h"
 
 /* -----------------------------------------------------------------------------
+ * Device Information
+ */
+
+static const struct rcar_du_device_info rcar_du_r8a7779_info = {
+       .features = 0,
+       .num_crtcs = 2,
+       .routes = {
+               /* R8A7779 has two RGB outputs and one (currently unsupported)
+                * TCON output.
+                */
+               [RCAR_DU_OUTPUT_DPAD0] = {
+                       .possible_crtcs = BIT(0),
+                       .encoder_type = DRM_MODE_ENCODER_NONE,
+                       .port = 0,
+               },
+               [RCAR_DU_OUTPUT_DPAD1] = {
+                       .possible_crtcs = BIT(1) | BIT(0),
+                       .encoder_type = DRM_MODE_ENCODER_NONE,
+                       .port = 1,
+               },
+       },
+       .num_lvds = 0,
+};
+
+static const struct rcar_du_device_info rcar_du_r8a7790_info = {
+       .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK | RCAR_DU_FEATURE_DEFR8,
+       .quirks = RCAR_DU_QUIRK_ALIGN_128B | RCAR_DU_QUIRK_LVDS_LANES,
+       .num_crtcs = 3,
+       .routes = {
+               /* R8A7790 has one RGB output, two LVDS outputs and one
+                * (currently unsupported) TCON output.
+                */
+               [RCAR_DU_OUTPUT_DPAD0] = {
+                       .possible_crtcs = BIT(2) | BIT(1) | BIT(0),
+                       .encoder_type = DRM_MODE_ENCODER_NONE,
+                       .port = 0,
+               },
+               [RCAR_DU_OUTPUT_LVDS0] = {
+                       .possible_crtcs = BIT(0),
+                       .encoder_type = DRM_MODE_ENCODER_LVDS,
+                       .port = 1,
+               },
+               [RCAR_DU_OUTPUT_LVDS1] = {
+                       .possible_crtcs = BIT(2) | BIT(1),
+                       .encoder_type = DRM_MODE_ENCODER_LVDS,
+                       .port = 2,
+               },
+       },
+       .num_lvds = 2,
+};
+
+static const struct rcar_du_device_info rcar_du_r8a7791_info = {
+       .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK | RCAR_DU_FEATURE_DEFR8,
+       .num_crtcs = 2,
+       .routes = {
+               /* R8A7791 has one RGB output, one LVDS output and one
+                * (currently unsupported) TCON output.
+                */
+               [RCAR_DU_OUTPUT_DPAD0] = {
+                       .possible_crtcs = BIT(1),
+                       .encoder_type = DRM_MODE_ENCODER_NONE,
+                       .port = 0,
+               },
+               [RCAR_DU_OUTPUT_LVDS0] = {
+                       .possible_crtcs = BIT(0),
+                       .encoder_type = DRM_MODE_ENCODER_LVDS,
+                       .port = 1,
+               },
+       },
+       .num_lvds = 1,
+};
+
+static const struct platform_device_id rcar_du_id_table[] = {
+       { "rcar-du-r8a7779", (kernel_ulong_t)&rcar_du_r8a7779_info },
+       { "rcar-du-r8a7790", (kernel_ulong_t)&rcar_du_r8a7790_info },
+       { "rcar-du-r8a7791", (kernel_ulong_t)&rcar_du_r8a7791_info },
+       { }
+};
+
+MODULE_DEVICE_TABLE(platform, rcar_du_id_table);
+
+static const struct of_device_id rcar_du_of_table[] = {
+       { .compatible = "renesas,du-r8a7779", .data = &rcar_du_r8a7779_info },
+       { .compatible = "renesas,du-r8a7790", .data = &rcar_du_r8a7790_info },
+       { .compatible = "renesas,du-r8a7791", .data = &rcar_du_r8a7791_info },
+       { }
+};
+
+MODULE_DEVICE_TABLE(of, rcar_du_of_table);
+
+/* -----------------------------------------------------------------------------
  * DRM operations
  */
 
@@ -53,12 +145,13 @@ static int rcar_du_unload(struct drm_device *dev)
 static int rcar_du_load(struct drm_device *dev, unsigned long flags)
 {
        struct platform_device *pdev = dev->platformdev;
+       struct device_node *np = pdev->dev.of_node;
        struct rcar_du_platform_data *pdata = pdev->dev.platform_data;
        struct rcar_du_device *rcdu;
        struct resource *mem;
        int ret;
 
-       if (pdata == NULL) {
+       if (pdata == NULL && np == NULL) {
                dev_err(dev->dev, "no platform data\n");
                return -ENODEV;
        }
@@ -71,7 +164,8 @@ static int rcar_du_load(struct drm_device *dev, unsigned long flags)
 
        rcdu->dev = &pdev->dev;
        rcdu->pdata = pdata;
-       rcdu->info = (struct rcar_du_device_info *)pdev->id_entry->driver_data;
+       rcdu->info = np ? of_match_device(rcar_du_of_table, rcdu->dev)->data
+                  : (void *)platform_get_device_id(pdev)->driver_data;
        rcdu->ddev = dev;
        dev->dev_private = rcdu;
 
@@ -231,77 +325,6 @@ static int rcar_du_remove(struct platform_device *pdev)
        return 0;
 }
 
-static const struct rcar_du_device_info rcar_du_r8a7779_info = {
-       .features = 0,
-       .num_crtcs = 2,
-       .routes = {
-               /* R8A7779 has two RGB outputs and one (currently unsupported)
-                * TCON output.
-                */
-               [RCAR_DU_OUTPUT_DPAD0] = {
-                       .possible_crtcs = BIT(0),
-                       .encoder_type = DRM_MODE_ENCODER_NONE,
-               },
-               [RCAR_DU_OUTPUT_DPAD1] = {
-                       .possible_crtcs = BIT(1) | BIT(0),
-                       .encoder_type = DRM_MODE_ENCODER_NONE,
-               },
-       },
-       .num_lvds = 0,
-};
-
-static const struct rcar_du_device_info rcar_du_r8a7790_info = {
-       .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK | RCAR_DU_FEATURE_DEFR8,
-       .quirks = RCAR_DU_QUIRK_ALIGN_128B | RCAR_DU_QUIRK_LVDS_LANES,
-       .num_crtcs = 3,
-       .routes = {
-               /* R8A7790 has one RGB output, two LVDS outputs and one
-                * (currently unsupported) TCON output.
-                */
-               [RCAR_DU_OUTPUT_DPAD0] = {
-                       .possible_crtcs = BIT(2) | BIT(1) | BIT(0),
-                       .encoder_type = DRM_MODE_ENCODER_NONE,
-               },
-               [RCAR_DU_OUTPUT_LVDS0] = {
-                       .possible_crtcs = BIT(0),
-                       .encoder_type = DRM_MODE_ENCODER_LVDS,
-               },
-               [RCAR_DU_OUTPUT_LVDS1] = {
-                       .possible_crtcs = BIT(2) | BIT(1),
-                       .encoder_type = DRM_MODE_ENCODER_LVDS,
-               },
-       },
-       .num_lvds = 2,
-};
-
-static const struct rcar_du_device_info rcar_du_r8a7791_info = {
-       .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK | RCAR_DU_FEATURE_DEFR8,
-       .num_crtcs = 2,
-       .routes = {
-               /* R8A7791 has one RGB output, one LVDS output and one
-                * (currently unsupported) TCON output.
-                */
-               [RCAR_DU_OUTPUT_DPAD0] = {
-                       .possible_crtcs = BIT(1),
-                       .encoder_type = DRM_MODE_ENCODER_NONE,
-               },
-               [RCAR_DU_OUTPUT_LVDS0] = {
-                       .possible_crtcs = BIT(0),
-                       .encoder_type = DRM_MODE_ENCODER_LVDS,
-               },
-       },
-       .num_lvds = 1,
-};
-
-static const struct platform_device_id rcar_du_id_table[] = {
-       { "rcar-du-r8a7779", (kernel_ulong_t)&rcar_du_r8a7779_info },
-       { "rcar-du-r8a7790", (kernel_ulong_t)&rcar_du_r8a7790_info },
-       { "rcar-du-r8a7791", (kernel_ulong_t)&rcar_du_r8a7791_info },
-       { }
-};
-
-MODULE_DEVICE_TABLE(platform, rcar_du_id_table);
-
 static struct platform_driver rcar_du_platform_driver = {
        .probe          = rcar_du_probe,
        .remove         = rcar_du_remove,
@@ -309,6 +332,7 @@ static struct platform_driver rcar_du_platform_driver = {
                .owner  = THIS_MODULE,
                .name   = "rcar-du",
                .pm     = &rcar_du_pm_ops,
+               .of_match_table = rcar_du_of_table,
        },
        .id_table       = rcar_du_id_table,
 };
index e31b735..8e49463 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * rcar_du_drv.h  --  R-Car Display Unit DRM driver
  *
- * Copyright (C) 2013 Renesas Corporation
+ * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
@@ -37,6 +37,7 @@ struct rcar_du_lvdsenc;
  * struct rcar_du_output_routing - Output routing specification
  * @possible_crtcs: bitmask of possible CRTCs for the output
  * @encoder_type: DRM type of the internal encoder associated with the output
+ * @port: device tree port number corresponding to this output route
  *
  * The DU has 5 possible outputs (DPAD0/1, LVDS0/1, TCON). Output routing data
  * specify the valid SoC outputs, which CRTCs can drive the output, and the type
@@ -45,6 +46,7 @@ struct rcar_du_lvdsenc;
 struct rcar_du_output_routing {
        unsigned int possible_crtcs;
        unsigned int encoder_type;
+       unsigned int port;
 };
 
 /*
index 3daa7a1..7c0ec95 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * rcar_du_encoder.c  --  R-Car Display Unit Encoder
  *
- * Copyright (C) 2013 Renesas Corporation
+ * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
@@ -142,7 +142,8 @@ static const struct drm_encoder_funcs encoder_funcs = {
 int rcar_du_encoder_init(struct rcar_du_device *rcdu,
                         enum rcar_du_encoder_type type,
                         enum rcar_du_output output,
-                        const struct rcar_du_encoder_data *data)
+                        const struct rcar_du_encoder_data *data,
+                        struct device_node *np)
 {
        struct rcar_du_encoder *renc;
        unsigned int encoder_type;
@@ -189,9 +190,11 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu,
        drm_encoder_helper_add(&renc->encoder, &encoder_helper_funcs);
 
        switch (encoder_type) {
-       case DRM_MODE_ENCODER_LVDS:
-               return rcar_du_lvds_connector_init(rcdu, renc,
-                                                  &data->connector.lvds.panel);
+       case DRM_MODE_ENCODER_LVDS: {
+               const struct rcar_du_panel_data *pdata =
+                       data ? &data->connector.lvds.panel : NULL;
+               return rcar_du_lvds_connector_init(rcdu, renc, pdata, np);
+       }
 
        case DRM_MODE_ENCODER_DAC:
                return rcar_du_vga_connector_init(rcdu, renc);
index 0e5a65e..bd62413 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * rcar_du_encoder.h  --  R-Car Display Unit Encoder
  *
- * Copyright (C) 2013 Renesas Corporation
+ * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
@@ -44,6 +44,7 @@ rcar_du_connector_best_encoder(struct drm_connector *connector);
 int rcar_du_encoder_init(struct rcar_du_device *rcdu,
                         enum rcar_du_encoder_type type,
                         enum rcar_du_output output,
-                        const struct rcar_du_encoder_data *data);
+                        const struct rcar_du_encoder_data *data,
+                        struct device_node *np);
 
 #endif /* __RCAR_DU_ENCODER_H__ */
index eb53cd9..4e7614b 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * rcar_du_group.c  --  R-Car Display Unit Channels Pair
  *
- * Copyright (C) 2013 Renesas Corporation
+ * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
index 5025930..0c38cdc 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * rcar_du_group.c  --  R-Car Display Unit Planes and CRTCs Group
  *
- * Copyright (C) 2013 Renesas Corporation
+ * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
index 7602610..6c24ad7 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * rcar_du_kms.c  --  R-Car Display Unit Mode Setting
  *
- * Copyright (C) 2013 Renesas Corporation
+ * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
@@ -17,6 +17,8 @@
 #include <drm/drm_fb_cma_helper.h>
 #include <drm/drm_gem_cma_helper.h>
 
+#include <linux/of_graph.h>
+
 #include "rcar_du_crtc.h"
 #include "rcar_du_drv.h"
 #include "rcar_du_encoder.h"
@@ -188,6 +190,205 @@ static const struct drm_mode_config_funcs rcar_du_mode_config_funcs = {
        .output_poll_changed = rcar_du_output_poll_changed,
 };
 
+static int rcar_du_encoders_init_pdata(struct rcar_du_device *rcdu)
+{
+       unsigned int num_encoders = 0;
+       unsigned int i;
+       int ret;
+
+       for (i = 0; i < rcdu->pdata->num_encoders; ++i) {
+               const struct rcar_du_encoder_data *pdata =
+                       &rcdu->pdata->encoders[i];
+               const struct rcar_du_output_routing *route =
+                       &rcdu->info->routes[pdata->output];
+
+               if (pdata->type == RCAR_DU_ENCODER_UNUSED)
+                       continue;
+
+               if (pdata->output >= RCAR_DU_OUTPUT_MAX ||
+                   route->possible_crtcs == 0) {
+                       dev_warn(rcdu->dev,
+                                "encoder %u references unexisting output %u, skipping\n",
+                                i, pdata->output);
+                       continue;
+               }
+
+               ret = rcar_du_encoder_init(rcdu, pdata->type, pdata->output,
+                                          pdata, NULL);
+               if (ret < 0)
+                       return ret;
+
+               num_encoders++;
+       }
+
+       return num_encoders;
+}
+
+static int rcar_du_encoders_init_dt_one(struct rcar_du_device *rcdu,
+                                       enum rcar_du_output output,
+                                       struct of_endpoint *ep)
+{
+       static const struct {
+               const char *compatible;
+               enum rcar_du_encoder_type type;
+       } encoders[] = {
+               { "adi,adv7123", RCAR_DU_ENCODER_VGA },
+               { "thine,thc63lvdm83d", RCAR_DU_ENCODER_LVDS },
+       };
+
+       enum rcar_du_encoder_type enc_type = RCAR_DU_ENCODER_NONE;
+       struct device_node *connector = NULL;
+       struct device_node *encoder = NULL;
+       struct device_node *prev = NULL;
+       struct device_node *entity_ep_node;
+       struct device_node *entity;
+       int ret;
+
+       /*
+        * Locate the connected entity and infer its type from the number of
+        * endpoints.
+        */
+       entity = of_graph_get_remote_port_parent(ep->local_node);
+       if (!entity) {
+               dev_dbg(rcdu->dev, "unconnected endpoint %s, skipping\n",
+                       ep->local_node->full_name);
+               return 0;
+       }
+
+       entity_ep_node = of_parse_phandle(ep->local_node, "remote-endpoint", 0);
+
+       while (1) {
+               struct device_node *ep_node;
+
+               ep_node = of_graph_get_next_endpoint(entity, prev);
+               of_node_put(prev);
+               prev = ep_node;
+
+               if (!ep_node)
+                       break;
+
+               if (ep_node == entity_ep_node)
+                       continue;
+
+               /*
+                * We've found one endpoint other than the input, this must
+                * be an encoder. Locate the connector.
+                */
+               encoder = entity;
+               connector = of_graph_get_remote_port_parent(ep_node);
+               of_node_put(ep_node);
+
+               if (!connector) {
+                       dev_warn(rcdu->dev,
+                                "no connector for encoder %s, skipping\n",
+                                encoder->full_name);
+                       of_node_put(entity_ep_node);
+                       of_node_put(encoder);
+                       return 0;
+               }
+
+               break;
+       }
+
+       of_node_put(entity_ep_node);
+
+       if (encoder) {
+               /*
+                * If an encoder has been found, get its type based on its
+                * compatible string.
+                */
+               unsigned int i;
+
+               for (i = 0; i < ARRAY_SIZE(encoders); ++i) {
+                       if (of_device_is_compatible(encoder,
+                                                   encoders[i].compatible)) {
+                               enc_type = encoders[i].type;
+                               break;
+                       }
+               }
+
+               if (i == ARRAY_SIZE(encoders)) {
+                       dev_warn(rcdu->dev,
+                                "unknown encoder type for %s, skipping\n",
+                                encoder->full_name);
+                       of_node_put(encoder);
+                       of_node_put(connector);
+                       return 0;
+               }
+       } else {
+               /*
+                * If no encoder has been found the entity must be the
+                * connector.
+                */
+               connector = entity;
+       }
+
+       ret = rcar_du_encoder_init(rcdu, enc_type, output, NULL, connector);
+       of_node_put(encoder);
+       of_node_put(connector);
+
+       return ret < 0 ? ret : 1;
+}
+
+static int rcar_du_encoders_init_dt(struct rcar_du_device *rcdu)
+{
+       struct device_node *np = rcdu->dev->of_node;
+       struct device_node *prev = NULL;
+       unsigned int num_encoders = 0;
+
+       /*
+        * Iterate over the endpoints and create one encoder for each output
+        * pipeline.
+        */
+       while (1) {
+               struct device_node *ep_node;
+               enum rcar_du_output output;
+               struct of_endpoint ep;
+               unsigned int i;
+               int ret;
+
+               ep_node = of_graph_get_next_endpoint(np, prev);
+               of_node_put(prev);
+               prev = ep_node;
+
+               if (ep_node == NULL)
+                       break;
+
+               ret = of_graph_parse_endpoint(ep_node, &ep);
+               if (ret < 0) {
+                       of_node_put(ep_node);
+                       return ret;
+               }
+
+               /* Find the output route corresponding to the port number. */
+               for (i = 0; i < RCAR_DU_OUTPUT_MAX; ++i) {
+                       if (rcdu->info->routes[i].possible_crtcs &&
+                           rcdu->info->routes[i].port == ep.port) {
+                               output = i;
+                               break;
+                       }
+               }
+
+               if (i == RCAR_DU_OUTPUT_MAX) {
+                       dev_warn(rcdu->dev,
+                                "port %u references unexisting output, skipping\n",
+                                ep.port);
+                       continue;
+               }
+
+               /* Process the output pipeline. */
+               ret = rcar_du_encoders_init_dt_one(rcdu, output, &ep);
+               if (ret < 0) {
+                       of_node_put(ep_node);
+                       return ret;
+               }
+
+               num_encoders += ret;
+       }
+
+       return num_encoders;
+}
+
 int rcar_du_modeset_init(struct rcar_du_device *rcdu)
 {
        static const unsigned int mmio_offsets[] = {
@@ -197,6 +398,7 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
        struct drm_device *dev = rcdu->ddev;
        struct drm_encoder *encoder;
        struct drm_fbdev_cma *fbdev;
+       unsigned int num_encoders;
        unsigned int num_groups;
        unsigned int i;
        int ret;
@@ -240,28 +442,15 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
        if (ret < 0)
                return ret;
 
-       for (i = 0; i < rcdu->pdata->num_encoders; ++i) {
-               const struct rcar_du_encoder_data *pdata =
-                       &rcdu->pdata->encoders[i];
-               const struct rcar_du_output_routing *route =
-                       &rcdu->info->routes[pdata->output];
-
-               if (pdata->type == RCAR_DU_ENCODER_UNUSED)
-                       continue;
+       if (rcdu->pdata)
+               ret = rcar_du_encoders_init_pdata(rcdu);
+       else
+               ret = rcar_du_encoders_init_dt(rcdu);
 
-               if (pdata->output >= RCAR_DU_OUTPUT_MAX ||
-                   route->possible_crtcs == 0) {
-                       dev_warn(rcdu->dev,
-                                "encoder %u references unexisting output %u, skipping\n",
-                                i, pdata->output);
-                       continue;
-               }
+       if (ret < 0)
+               return ret;
 
-               ret = rcar_du_encoder_init(rcdu, pdata->type, pdata->output,
-                                          pdata);
-               if (ret < 0)
-                       return ret;
-       }
+       num_encoders = ret;
 
        /* Set the possible CRTCs and possible clones. There's always at least
         * one way for all encoders to clone each other, set all bits in the
@@ -273,7 +462,7 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
                        &rcdu->info->routes[renc->output];
 
                encoder->possible_crtcs = route->possible_crtcs;
-               encoder->possible_clones = (1 << rcdu->pdata->num_encoders) - 1;
+               encoder->possible_clones = (1 << num_encoders) - 1;
        }
 
        /* Now that the CRTCs have been initialized register the planes. */
index 5750e6a..07951d5 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * rcar_du_kms.h  --  R-Car Display Unit Mode Setting
  *
- * Copyright (C) 2013 Renesas Corporation
+ * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
index 4f3ba93..e3e3513 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * rcar_du_lvdscon.c  --  R-Car Display Unit LVDS Connector
  *
- * Copyright (C) 2013 Renesas Corporation
+ * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
 #include <drm/drm_crtc.h>
 #include <drm/drm_crtc_helper.h>
 
+#include <video/display_timing.h>
+#include <video/of_display_timing.h>
+#include <video/videomode.h>
+
 #include "rcar_du_drv.h"
 #include "rcar_du_encoder.h"
 #include "rcar_du_kms.h"
@@ -23,7 +27,7 @@
 struct rcar_du_lvds_connector {
        struct rcar_du_connector connector;
 
-       const struct rcar_du_panel_data *panel;
+       struct rcar_du_panel_data panel;
 };
 
 #define to_rcar_lvds_connector(c) \
@@ -40,18 +44,9 @@ static int rcar_du_lvds_connector_get_modes(struct drm_connector *connector)
                return 0;
 
        mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER;
-       mode->clock = lvdscon->panel->mode.clock;
-       mode->hdisplay = lvdscon->panel->mode.hdisplay;
-       mode->hsync_start = lvdscon->panel->mode.hsync_start;
-       mode->hsync_end = lvdscon->panel->mode.hsync_end;
-       mode->htotal = lvdscon->panel->mode.htotal;
-       mode->vdisplay = lvdscon->panel->mode.vdisplay;
-       mode->vsync_start = lvdscon->panel->mode.vsync_start;
-       mode->vsync_end = lvdscon->panel->mode.vsync_end;
-       mode->vtotal = lvdscon->panel->mode.vtotal;
-       mode->flags = lvdscon->panel->mode.flags;
-
-       drm_mode_set_name(mode);
+
+       drm_display_mode_from_videomode(&lvdscon->panel.mode, mode);
+
        drm_mode_probed_add(connector, mode);
 
        return 1;
@@ -90,7 +85,8 @@ static const struct drm_connector_funcs connector_funcs = {
 
 int rcar_du_lvds_connector_init(struct rcar_du_device *rcdu,
                                struct rcar_du_encoder *renc,
-                               const struct rcar_du_panel_data *panel)
+                               const struct rcar_du_panel_data *panel,
+                               /* TODO const */ struct device_node *np)
 {
        struct rcar_du_lvds_connector *lvdscon;
        struct drm_connector *connector;
@@ -100,11 +96,24 @@ int rcar_du_lvds_connector_init(struct rcar_du_device *rcdu,
        if (lvdscon == NULL)
                return -ENOMEM;
 
-       lvdscon->panel = panel;
+       if (panel) {
+               lvdscon->panel = *panel;
+       } else {
+               struct display_timing timing;
+
+               ret = of_get_display_timing(np, "panel-timing", &timing);
+               if (ret < 0)
+                       return ret;
+
+               videomode_from_timing(&timing, &lvdscon->panel.mode);
+
+               of_property_read_u32(np, "width-mm", &lvdscon->panel.width_mm);
+               of_property_read_u32(np, "height-mm", &lvdscon->panel.height_mm);
+       }
 
        connector = &lvdscon->connector.connector;
-       connector->display_info.width_mm = panel->width_mm;
-       connector->display_info.height_mm = panel->height_mm;
+       connector->display_info.width_mm = lvdscon->panel.width_mm;
+       connector->display_info.height_mm = lvdscon->panel.height_mm;
 
        ret = drm_connector_init(rcdu->ddev, connector, &connector_funcs,
                                 DRM_MODE_CONNECTOR_LVDS);
index bff8683..d11424d 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * rcar_du_lvdscon.h  --  R-Car Display Unit LVDS Connector
  *
- * Copyright (C) 2013 Renesas Corporation
+ * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
@@ -20,6 +20,7 @@ struct rcar_du_panel_data;
 
 int rcar_du_lvds_connector_init(struct rcar_du_device *rcdu,
                                struct rcar_du_encoder *renc,
-                               const struct rcar_du_panel_data *panel);
+                               const struct rcar_du_panel_data *panel,
+                               struct device_node *np);
 
 #endif /* __RCAR_DU_LVDSCON_H__ */
index df30a07..7cfb48c 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * rcar_du_lvdsenc.c  --  R-Car Display Unit LVDS Encoder
  *
- * Copyright (C) 2013 Renesas Corporation
+ * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
index 7051c6d..3303a55 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * rcar_du_lvdsenc.h  --  R-Car Display Unit LVDS Encoder
  *
- * Copyright (C) 2013 Renesas Corporation
+ * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
index 3fb69d9..72a7cb4 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * rcar_du_plane.c  --  R-Car Display Unit Planes
  *
- * Copyright (C) 2013 Renesas Corporation
+ * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
index f94f9ce..3021288 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * rcar_du_plane.h  --  R-Car Display Unit Planes
  *
- * Copyright (C) 2013 Renesas Corporation
+ * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
index 41d563a..3bcbf58 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * rcar_du_vgacon.c  --  R-Car Display Unit VGA Connector
  *
- * Copyright (C) 2013 Renesas Corporation
+ * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
index b12b0cf..112f503 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * rcar_du_vgacon.h  --  R-Car Display Unit VGA Connector
  *
- * Copyright (C) 2013 Renesas Corporation
+ * Copyright (C) 2013-2014 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  *
index 65ef966..899bede 100644 (file)
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-    MA 02110-1301 USA.
  * ------------------------------------------------------------------------- */
 
 /* With some changes from Frodo Looijaard <frodol@dds.nl>, Kyösti Mälkki
index 8b10f88..580dbf0 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- *  MA 02110-1301 USA.
  */
 
 #include <linux/kernel.h>
index 3437009..270d84b 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- *  MA 02110-1301 USA.
- *
  * With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and
  * Frodo Looijaard <frodol@dds.nl>, and also from Martin Bailey
  * <mbailey@littlefeet-inc.com>
index 1ec703e..262ee80 100644 (file)
     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-    MA 02110-1301 USA.                                                 */
+    GNU General Public License for more details.                       */
 /* --------------------------------------------------------------------        */
 
 /* With some changes from Frodo Looijaard <frodol@dds.nl> */
index 451e305..4f2d788 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
 /*
index 2fa21ce..45c5c48 100644 (file)
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
 /*
index 41fc683..65e3240 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
  
 /*
index a16f728..6c7113d 100644 (file)
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
 /*
index 8762458..6f8c075 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #include <linux/delay.h>
index f3b89a4..5bdbc71 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/kernel.h>
index af0b583..e2d9639 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  * ----------------------------------------------------------------------------
  *
  */
index d95b930..eb8736a 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  * ----------------------------------------------------------------------------
  *
  */
index e8a7565..139677f 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  * ----------------------------------------------------------------------------
  *
  */
index 1d3b4eb..1932468 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  * ----------------------------------------------------------------------------
  *
  */
index d0bdac0..9c6cc51 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  * ----------------------------------------------------------------------------
  *
  */
index a44ea13..76e699f 100644 (file)
@@ -9,10 +9,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #include <linux/module.h>
index 4854970..92e8c0c 100644 (file)
     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.               */
+    GNU General Public License for more details.                            */
 /* ------------------------------------------------------------------------- */
 
 /* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
index 14d2b76..b7864cf 100644 (file)
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
 #include <linux/kernel.h>
index 10467a3..9a50a4f 100644 (file)
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
 /*
index 584e002..2e83a4a 100644 (file)
  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *     GNU General Public License for more details.
  *
- *     You should have received a copy of the GNU General Public License
- *     along with this program; if not, write to the Free Software
- *     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
- *     USA.
- *
  * Author:
  *     Darius Augulis, Teltonika Inc.
  *
index 097e270..2d6929c 100644 (file)
     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                */
+    GNU General Public License for more details.                            */
 /* ------------------------------------------------------------------------- */
 
 
index cf99dbf..113293d 100644 (file)
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
 /*
index d9ee43c..acd32d1 100644 (file)
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  * The full GNU General Public License is included in this distribution
  * in the file called LICENSE.GPL.
  *
index b170bdf..88eda09 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 /*
index ee3a76c..70b3c91 100644 (file)
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
 /*
index fe9ee69..5c6edbc 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
index 62f55fe..d1f625f 100644 (file)
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  * ------------------------------------------------------------------------ */
 
 #include <linux/kernel.h>
index a27aae2..a1fac5a 100644 (file)
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  * ------------------------------------------------------------------------ */
 
 #include <linux/kernel.h>
index e572f3a..4e12945 100644 (file)
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  * ------------------------------------------------------------------------ */
 
 #define PORT_DATA      0
index 7a9dce4..df1dbc9 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
 #include <linux/module.h>
index 323f061..e0eb4ca 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/kernel.h>
index a6f54ba..67cbec6 100644 (file)
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
 /*
index 8564768..177834e 100644 (file)
  *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/kernel.h>
index 01e9677..60a53c1 100644 (file)
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
 
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 
 #include <linux/module.h>
index e506fcd..d826e82 100644 (file)
@@ -195,7 +195,7 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv,
         */
        rate = clk_get_rate(priv->clk);
        cdf = rate / 20000000;
-       if (cdf >= 1 << cdf_width) {
+       if (cdf >= 1U << cdf_width) {
                dev_err(dev, "Input clock %lu too high\n", rate);
                return -EIO;
        }
@@ -245,7 +245,7 @@ scgd_find:
        return 0;
 }
 
-static int rcar_i2c_prepare_msg(struct rcar_i2c_priv *priv)
+static void rcar_i2c_prepare_msg(struct rcar_i2c_priv *priv)
 {
        int read = !!rcar_i2c_is_recv(priv);
 
@@ -253,8 +253,6 @@ static int rcar_i2c_prepare_msg(struct rcar_i2c_priv *priv)
        rcar_i2c_write(priv, ICMSR, 0);
        rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_START);
        rcar_i2c_write(priv, ICMIER, read ? RCAR_IRQ_RECV : RCAR_IRQ_SEND);
-
-       return 0;
 }
 
 /*
@@ -365,6 +363,7 @@ static int rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr)
 static irqreturn_t rcar_i2c_irq(int irq, void *ptr)
 {
        struct rcar_i2c_priv *priv = ptr;
+       irqreturn_t result = IRQ_HANDLED;
        u32 msr;
 
        /*-------------- spin lock -----------------*/
@@ -374,6 +373,10 @@ static irqreturn_t rcar_i2c_irq(int irq, void *ptr)
 
        /* Only handle interrupts that are currently enabled */
        msr &= rcar_i2c_read(priv, ICMIER);
+       if (!msr) {
+               result = IRQ_NONE;
+               goto exit;
+       }
 
        /* Arbitration lost */
        if (msr & MAL) {
@@ -408,10 +411,11 @@ out:
                wake_up(&priv->wait);
        }
 
+exit:
        spin_unlock(&priv->lock);
        /*-------------- spin unlock -----------------*/
 
-       return IRQ_HANDLED;
+       return result;
 }
 
 static int rcar_i2c_master_xfer(struct i2c_adapter *adap,
@@ -453,17 +457,14 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap,
                priv->msg       = &msgs[i];
                priv->pos       = 0;
                priv->flags     = 0;
-               if (priv->msg == &msgs[num - 1])
+               if (i == num - 1)
                        rcar_i2c_flags_set(priv, ID_LAST_MSG);
 
-               ret = rcar_i2c_prepare_msg(priv);
+               rcar_i2c_prepare_msg(priv);
 
                spin_unlock_irqrestore(&priv->lock, flags);
                /*-------------- spin unlock -----------------*/
 
-               if (ret < 0)
-                       break;
-
                timeout = wait_event_timeout(priv->wait,
                                             rcar_i2c_flags_has(priv, ID_DONE),
                                             5 * HZ);
index 5e74249..27303c7 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 
 #include <linux/kernel.h>
index 8b5e79c..4855188 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 #include <linux/kernel.h>
index 0fe505d..2b6219d 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 #include <linux/kernel.h>
index 964e5c6..15ac839 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 
 #include <linux/kernel.h>
index ac9bc33..7d58a40 100644 (file)
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
 /* Note: we assume there can only be one SIS5595 with one SMBus interface */
index c636673..1e6805b 100644 (file)
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
 /*
index 8dc2fc5..44b9044 100644 (file)
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
 /*
index 0576026..13c8301 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #include <linux/delay.h>
index f4a1ed7..59b1d23 100644 (file)
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
 #include <linux/kernel.h>
index 6841200..0ee2646 100644 (file)
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
 /*
index 2810750..63c0a2f 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  *
  * This code was implemented by Mocean Laboratories AB when porting linux
  * to the automotive development board Russellville. The copyright holder
index ff3f574..5153354 100644 (file)
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index f24cc64..90e3229 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301 USA.
  */
 
 #include <linux/kernel.h>
index 98a5fd9..f08e7db 100644 (file)
     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-    MA 02110-1301 USA.                                                      */
+    GNU General Public License for more details.                            */
 /* ------------------------------------------------------------------------- */
 
 /* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi>.
index 18a8fd2..17700bf 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301 USA.
  */
 
 #include <linux/rwsem.h>
index 80b47e8..71c7a39 100644 (file)
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-    MA 02110-1301 USA.
 */
 
 /* Note that this is a complete rewrite of Simon Vogl's i2c-dev module.
index fc99f0d..9ebf9cb 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301 USA.
  */
 
 #include <linux/kernel.h>
index 77e4849..b58c328 100644 (file)
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
 #define DEBUG 1
index ea6203e..23467a2 100644 (file)
@@ -2425,6 +2425,8 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file,
        attr.grh.sgid_index    = cmd.attr.grh.sgid_index;
        attr.grh.hop_limit     = cmd.attr.grh.hop_limit;
        attr.grh.traffic_class = cmd.attr.grh.traffic_class;
+       attr.vlan_id           = 0;
+       memset(&attr.dmac, 0, sizeof(attr.dmac));
        memcpy(attr.grh.dgid.raw, cmd.attr.grh.dgid, 16);
 
        ah = ib_create_ah(pd, &attr);
index c5c194c..a96cfc3 100644 (file)
@@ -112,9 +112,12 @@ isert_conn_setup_qp(struct isert_conn *isert_conn, struct rdma_cm_id *cma_id)
        attr.cap.max_recv_wr = ISERT_QP_MAX_RECV_DTOS;
        /*
         * FIXME: Use devattr.max_sge - 2 for max_send_sge as
-        * work-around for RDMA_READ..
+        * work-around for RDMA_READs with ConnectX-2.
+        *
+        * Also, still make sure to have at least two SGEs for
+        * outgoing control PDU responses.
         */
-       attr.cap.max_send_sge = device->dev_attr.max_sge - 2;
+       attr.cap.max_send_sge = max(2, device->dev_attr.max_sge - 2);
        isert_conn->max_sge = attr.cap.max_send_sge;
 
        attr.cap.max_recv_sge = 1;
@@ -220,12 +223,16 @@ isert_create_device_ib_res(struct isert_device *device)
        struct isert_cq_desc *cq_desc;
        struct ib_device_attr *dev_attr;
        int ret = 0, i, j;
+       int max_rx_cqe, max_tx_cqe;
 
        dev_attr = &device->dev_attr;
        ret = isert_query_device(ib_dev, dev_attr);
        if (ret)
                return ret;
 
+       max_rx_cqe = min(ISER_MAX_RX_CQ_LEN, dev_attr->max_cqe);
+       max_tx_cqe = min(ISER_MAX_TX_CQ_LEN, dev_attr->max_cqe);
+
        /* asign function handlers */
        if (dev_attr->device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS) {
                device->use_fastreg = 1;
@@ -261,7 +268,7 @@ isert_create_device_ib_res(struct isert_device *device)
                                                isert_cq_rx_callback,
                                                isert_cq_event_callback,
                                                (void *)&cq_desc[i],
-                                               ISER_MAX_RX_CQ_LEN, i);
+                                               max_rx_cqe, i);
                if (IS_ERR(device->dev_rx_cq[i])) {
                        ret = PTR_ERR(device->dev_rx_cq[i]);
                        device->dev_rx_cq[i] = NULL;
@@ -273,7 +280,7 @@ isert_create_device_ib_res(struct isert_device *device)
                                                isert_cq_tx_callback,
                                                isert_cq_event_callback,
                                                (void *)&cq_desc[i],
-                                               ISER_MAX_TX_CQ_LEN, i);
+                                               max_tx_cqe, i);
                if (IS_ERR(device->dev_tx_cq[i])) {
                        ret = PTR_ERR(device->dev_tx_cq[i]);
                        device->dev_tx_cq[i] = NULL;
@@ -718,14 +725,25 @@ wake_up:
        complete(&isert_conn->conn_wait);
 }
 
-static void
+static int
 isert_disconnected_handler(struct rdma_cm_id *cma_id, bool disconnect)
 {
-       struct isert_conn *isert_conn = (struct isert_conn *)cma_id->context;
+       struct isert_conn *isert_conn;
+
+       if (!cma_id->qp) {
+               struct isert_np *isert_np = cma_id->context;
+
+               isert_np->np_cm_id = NULL;
+               return -1;
+       }
+
+       isert_conn = (struct isert_conn *)cma_id->context;
 
        isert_conn->disconnect = disconnect;
        INIT_WORK(&isert_conn->conn_logout_work, isert_disconnect_work);
        schedule_work(&isert_conn->conn_logout_work);
+
+       return 0;
 }
 
 static int
@@ -740,6 +758,9 @@ isert_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)
        switch (event->event) {
        case RDMA_CM_EVENT_CONNECT_REQUEST:
                ret = isert_connect_request(cma_id, event);
+               if (ret)
+                       pr_err("isert_cma_handler failed RDMA_CM_EVENT: 0x%08x %d\n",
+                               event->event, ret);
                break;
        case RDMA_CM_EVENT_ESTABLISHED:
                isert_connected_handler(cma_id);
@@ -749,7 +770,7 @@ isert_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)
        case RDMA_CM_EVENT_DEVICE_REMOVAL: /* FALLTHRU */
                disconnect = true;
        case RDMA_CM_EVENT_TIMEWAIT_EXIT:  /* FALLTHRU */
-               isert_disconnected_handler(cma_id, disconnect);
+               ret = isert_disconnected_handler(cma_id, disconnect);
                break;
        case RDMA_CM_EVENT_CONNECT_ERROR:
        default:
@@ -757,12 +778,6 @@ isert_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)
                break;
        }
 
-       if (ret != 0) {
-               pr_err("isert_cma_handler failed RDMA_CM_EVENT: 0x%08x %d\n",
-                      event->event, ret);
-               dump_stack();
-       }
-
        return ret;
 }
 
@@ -970,7 +985,8 @@ isert_put_login_tx(struct iscsi_conn *conn, struct iscsi_login *login,
        }
        if (!login->login_failed) {
                if (login->login_complete) {
-                       if (isert_conn->conn_device->use_fastreg) {
+                       if (!conn->sess->sess_ops->SessionType &&
+                           isert_conn->conn_device->use_fastreg) {
                                ret = isert_conn_create_fastreg_pool(isert_conn);
                                if (ret) {
                                        pr_err("Conn: %p failed to create"
@@ -1937,7 +1953,7 @@ isert_put_response(struct iscsi_conn *conn, struct iscsi_cmd *cmd)
                isert_cmd->tx_desc.num_sge = 2;
        }
 
-       isert_init_send_wr(isert_conn, isert_cmd, send_wr, true);
+       isert_init_send_wr(isert_conn, isert_cmd, send_wr, false);
 
        pr_debug("Posting SCSI Response IB_WR_SEND >>>>>>>>>>>>>>>>>>>>>>\n");
 
@@ -2456,7 +2472,7 @@ isert_put_datain(struct iscsi_conn *conn, struct iscsi_cmd *cmd)
                             &isert_cmd->tx_desc.iscsi_header);
        isert_init_tx_hdrs(isert_conn, &isert_cmd->tx_desc);
        isert_init_send_wr(isert_conn, isert_cmd,
-                          &isert_cmd->tx_desc.send_wr, true);
+                          &isert_cmd->tx_desc.send_wr, false);
 
        atomic_add(wr->send_wr_num + 1, &isert_conn->post_send_buf_count);
 
@@ -2768,7 +2784,8 @@ isert_free_np(struct iscsi_np *np)
 {
        struct isert_np *isert_np = (struct isert_np *)np->np_context;
 
-       rdma_destroy_id(isert_np->np_cm_id);
+       if (isert_np->np_cm_id)
+               rdma_destroy_id(isert_np->np_cm_id);
 
        np->np_context = NULL;
        kfree(isert_np);
index d1078ce..0097b8d 100644 (file)
@@ -2091,6 +2091,7 @@ static int srpt_create_ch_ib(struct srpt_rdma_ch *ch)
        if (!qp_init)
                goto out;
 
+retry:
        ch->cq = ib_create_cq(sdev->device, srpt_completion, NULL, ch,
                              ch->rq_size + srp_sq_size, 0);
        if (IS_ERR(ch->cq)) {
@@ -2114,6 +2115,13 @@ static int srpt_create_ch_ib(struct srpt_rdma_ch *ch)
        ch->qp = ib_create_qp(sdev->pd, qp_init);
        if (IS_ERR(ch->qp)) {
                ret = PTR_ERR(ch->qp);
+               if (ret == -ENOMEM) {
+                       srp_sq_size /= 2;
+                       if (srp_sq_size >= MIN_SRPT_SQ_SIZE) {
+                               ib_destroy_cq(ch->cq);
+                               goto retry;
+                       }
+               }
                printk(KERN_ERR "failed to create_qp ret= %d\n", ret);
                goto err_destroy_cq;
        }
index 603fe0d..517829f 100644 (file)
@@ -1003,9 +1003,19 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
                }
 
                ep_irq_in = &intf->cur_altsetting->endpoint[1].desc;
-               usb_fill_bulk_urb(xpad->bulk_out, udev,
-                               usb_sndbulkpipe(udev, ep_irq_in->bEndpointAddress),
-                               xpad->bdata, XPAD_PKT_LEN, xpad_bulk_out, xpad);
+               if (usb_endpoint_is_bulk_out(ep_irq_in)) {
+                       usb_fill_bulk_urb(xpad->bulk_out, udev,
+                                         usb_sndbulkpipe(udev,
+                                                         ep_irq_in->bEndpointAddress),
+                                         xpad->bdata, XPAD_PKT_LEN,
+                                         xpad_bulk_out, xpad);
+               } else {
+                       usb_fill_int_urb(xpad->bulk_out, udev,
+                                        usb_sndintpipe(udev,
+                                                       ep_irq_in->bEndpointAddress),
+                                        xpad->bdata, XPAD_PKT_LEN,
+                                        xpad_bulk_out, xpad, 0);
+               }
 
                /*
                 * Submit the int URB immediately rather than waiting for open
index fb15c64..4979b00 100644 (file)
@@ -1047,7 +1047,13 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
 {
        struct alps_data *priv = psmouse->private;
 
-       if ((psmouse->packet[0] & 0xc8) == 0x08) { /* PS/2 packet */
+       /*
+        * Check if we are dealing with a bare PS/2 packet, presumably from
+        * a device connected to the external PS/2 port. Because bare PS/2
+        * protocol does not have enough constant bits to self-synchronize
+        * properly we only do this if the device is fully synchronized.
+        */
+       if (!psmouse->out_of_sync_cnt && (psmouse->packet[0] & 0xc8) == 0x08) {
                if (psmouse->pktcnt == 3) {
                        alps_report_bare_ps2_packet(psmouse, psmouse->packet,
                                                    true);
@@ -1071,12 +1077,27 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
        }
 
        /* Bytes 2 - pktsize should have 0 in the highest bit */
-       if ((priv->proto_version < ALPS_PROTO_V5) &&
+       if (priv->proto_version < ALPS_PROTO_V5 &&
            psmouse->pktcnt >= 2 && psmouse->pktcnt <= psmouse->pktsize &&
            (psmouse->packet[psmouse->pktcnt - 1] & 0x80)) {
                psmouse_dbg(psmouse, "refusing packet[%i] = %x\n",
                            psmouse->pktcnt - 1,
                            psmouse->packet[psmouse->pktcnt - 1]);
+
+               if (priv->proto_version == ALPS_PROTO_V3 &&
+                   psmouse->pktcnt == psmouse->pktsize) {
+                       /*
+                        * Some Dell boxes, such as Latitude E6440 or E7440
+                        * with closed lid, quite often smash last byte of
+                        * otherwise valid packet with 0xff. Given that the
+                        * next packet is very likely to be valid let's
+                        * report PSMOUSE_FULL_PACKET but not process data,
+                        * rather than reporting PSMOUSE_BAD_DATA and
+                        * filling the logs.
+                        */
+                       return PSMOUSE_FULL_PACKET;
+               }
+
                return PSMOUSE_BAD_DATA;
        }
 
@@ -2148,6 +2169,9 @@ int alps_init(struct psmouse *psmouse)
        /* We are having trouble resyncing ALPS touchpads so disable it for now */
        psmouse->resync_time = 0;
 
+       /* Allow 2 invalid packets without resetting device */
+       psmouse->resetafter = psmouse->pktsize * 2;
+
        return 0;
 
 init_fail:
index a50a2a7..a3769cf 100644 (file)
@@ -132,14 +132,18 @@ static const struct min_max_quirk min_max_pnpid_table[] = {
                1232, 5710, 1156, 4696
        },
        {
-               (const char * const []){"LEN0034", "LEN0036", "LEN2002",
-                                       "LEN2004", NULL},
+               (const char * const []){"LEN0034", "LEN0036", "LEN0039",
+                                       "LEN2002", "LEN2004", NULL},
                1024, 5112, 2024, 4832
        },
        {
                (const char * const []){"LEN2001", NULL},
                1024, 5022, 2508, 4832
        },
+       {
+               (const char * const []){"LEN2006", NULL},
+               1264, 5675, 1171, 4688
+       },
        { }
 };
 
@@ -160,6 +164,7 @@ static const char * const topbuttonpad_pnp_ids[] = {
        "LEN0036", /* T440 */
        "LEN0037",
        "LEN0038",
+       "LEN0039", /* T440s */
        "LEN0041",
        "LEN0042", /* Yoga */
        "LEN0045",
index 3ee78f0..542e850 100644 (file)
@@ -17,6 +17,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <linux/clk.h>
 #include <linux/init.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
@@ -30,6 +31,7 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/platform_data/irq-renesas-intc-irqpin.h>
+#include <linux/pm_runtime.h>
 
 #define INTC_IRQPIN_MAX 8 /* maximum 8 interrupts per driver instance */
 
@@ -75,6 +77,7 @@ struct intc_irqpin_priv {
        struct platform_device *pdev;
        struct irq_chip irq_chip;
        struct irq_domain *irq_domain;
+       struct clk *clk;
        bool shared_irqs;
        u8 shared_irq_mask;
 };
@@ -270,6 +273,21 @@ static int intc_irqpin_irq_set_type(struct irq_data *d, unsigned int type)
                                     value ^ INTC_IRQ_SENSE_VALID);
 }
 
+static int intc_irqpin_irq_set_wake(struct irq_data *d, unsigned int on)
+{
+       struct intc_irqpin_priv *p = irq_data_get_irq_chip_data(d);
+
+       if (!p->clk)
+               return 0;
+
+       if (on)
+               clk_enable(p->clk);
+       else
+               clk_disable(p->clk);
+
+       return 0;
+}
+
 static irqreturn_t intc_irqpin_irq_handler(int irq, void *dev_id)
 {
        struct intc_irqpin_irq *i = dev_id;
@@ -329,7 +347,8 @@ static struct irq_domain_ops intc_irqpin_irq_domain_ops = {
 
 static int intc_irqpin_probe(struct platform_device *pdev)
 {
-       struct renesas_intc_irqpin_config *pdata = pdev->dev.platform_data;
+       struct device *dev = &pdev->dev;
+       struct renesas_intc_irqpin_config *pdata = dev->platform_data;
        struct intc_irqpin_priv *p;
        struct intc_irqpin_iomem *i;
        struct resource *io[INTC_IRQPIN_REG_NR];
@@ -337,25 +356,24 @@ static int intc_irqpin_probe(struct platform_device *pdev)
        struct irq_chip *irq_chip;
        void (*enable_fn)(struct irq_data *d);
        void (*disable_fn)(struct irq_data *d);
-       const char *name = dev_name(&pdev->dev);
+       const char *name = dev_name(dev);
        int ref_irq;
        int ret;
        int k;
 
-       p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL);
+       p = devm_kzalloc(dev, sizeof(*p), GFP_KERNEL);
        if (!p) {
-               dev_err(&pdev->dev, "failed to allocate driver data\n");
-               ret = -ENOMEM;
-               goto err0;
+               dev_err(dev, "failed to allocate driver data\n");
+               return -ENOMEM;
        }
 
        /* deal with driver instance configuration */
        if (pdata) {
                memcpy(&p->config, pdata, sizeof(*pdata));
        } else {
-               of_property_read_u32(pdev->dev.of_node, "sense-bitfield-width",
+               of_property_read_u32(dev->of_node, "sense-bitfield-width",
                                     &p->config.sense_bitfield_width);
-               p->config.control_parent = of_property_read_bool(pdev->dev.of_node,
+               p->config.control_parent = of_property_read_bool(dev->of_node,
                                                                 "control-parent");
        }
        if (!p->config.sense_bitfield_width)
@@ -364,11 +382,20 @@ static int intc_irqpin_probe(struct platform_device *pdev)
        p->pdev = pdev;
        platform_set_drvdata(pdev, p);
 
+       p->clk = devm_clk_get(dev, NULL);
+       if (IS_ERR(p->clk)) {
+               dev_warn(dev, "unable to get clock\n");
+               p->clk = NULL;
+       }
+
+       pm_runtime_enable(dev);
+       pm_runtime_get_sync(dev);
+
        /* get hold of manadatory IOMEM */
        for (k = 0; k < INTC_IRQPIN_REG_NR; k++) {
                io[k] = platform_get_resource(pdev, IORESOURCE_MEM, k);
                if (!io[k]) {
-                       dev_err(&pdev->dev, "not enough IOMEM resources\n");
+                       dev_err(dev, "not enough IOMEM resources\n");
                        ret = -EINVAL;
                        goto err0;
                }
@@ -386,7 +413,7 @@ static int intc_irqpin_probe(struct platform_device *pdev)
 
        p->number_of_irqs = k;
        if (p->number_of_irqs < 1) {
-               dev_err(&pdev->dev, "not enough IRQ resources\n");
+               dev_err(dev, "not enough IRQ resources\n");
                ret = -EINVAL;
                goto err0;
        }
@@ -407,15 +434,15 @@ static int intc_irqpin_probe(struct platform_device *pdev)
                        i->write = intc_irqpin_write32;
                        break;
                default:
-                       dev_err(&pdev->dev, "IOMEM size mismatch\n");
+                       dev_err(dev, "IOMEM size mismatch\n");
                        ret = -EINVAL;
                        goto err0;
                }
 
-               i->iomem = devm_ioremap_nocache(&pdev->dev, io[k]->start,
+               i->iomem = devm_ioremap_nocache(dev, io[k]->start,
                                                resource_size(io[k]));
                if (!i->iomem) {
-                       dev_err(&pdev->dev, "failed to remap IOMEM\n");
+                       dev_err(dev, "failed to remap IOMEM\n");
                        ret = -ENXIO;
                        goto err0;
                }
@@ -454,39 +481,36 @@ static int intc_irqpin_probe(struct platform_device *pdev)
        irq_chip->name = name;
        irq_chip->irq_mask = disable_fn;
        irq_chip->irq_unmask = enable_fn;
-       irq_chip->irq_enable = enable_fn;
-       irq_chip->irq_disable = disable_fn;
        irq_chip->irq_set_type = intc_irqpin_irq_set_type;
-       irq_chip->flags = IRQCHIP_SKIP_SET_WAKE;
+       irq_chip->irq_set_wake = intc_irqpin_irq_set_wake;
+       irq_chip->flags = IRQCHIP_MASK_ON_SUSPEND;
 
-       p->irq_domain = irq_domain_add_simple(pdev->dev.of_node,
+       p->irq_domain = irq_domain_add_simple(dev->of_node,
                                              p->number_of_irqs,
                                              p->config.irq_base,
                                              &intc_irqpin_irq_domain_ops, p);
        if (!p->irq_domain) {
                ret = -ENXIO;
-               dev_err(&pdev->dev, "cannot initialize irq domain\n");
+               dev_err(dev, "cannot initialize irq domain\n");
                goto err0;
        }
 
        if (p->shared_irqs) {
                /* request one shared interrupt */
-               if (devm_request_irq(&pdev->dev, p->irq[0].requested_irq,
+               if (devm_request_irq(dev, p->irq[0].requested_irq,
                                intc_irqpin_shared_irq_handler,
                                IRQF_SHARED, name, p)) {
-                       dev_err(&pdev->dev, "failed to request low IRQ\n");
+                       dev_err(dev, "failed to request low IRQ\n");
                        ret = -ENOENT;
                        goto err1;
                }
        } else {
                /* request interrupts one by one */
                for (k = 0; k < p->number_of_irqs; k++) {
-                       if (devm_request_irq(&pdev->dev,
-                                       p->irq[k].requested_irq,
-                                       intc_irqpin_irq_handler,
-                                       0, name, &p->irq[k])) {
-                               dev_err(&pdev->dev,
-                                       "failed to request low IRQ\n");
+                       if (devm_request_irq(dev, p->irq[k].requested_irq,
+                                            intc_irqpin_irq_handler, 0, name,
+                                            &p->irq[k])) {
+                               dev_err(dev, "failed to request low IRQ\n");
                                ret = -ENOENT;
                                goto err1;
                        }
@@ -497,12 +521,12 @@ static int intc_irqpin_probe(struct platform_device *pdev)
        for (k = 0; k < p->number_of_irqs; k++)
                intc_irqpin_mask_unmask_prio(p, k, 0);
 
-       dev_info(&pdev->dev, "driving %d irqs\n", p->number_of_irqs);
+       dev_info(dev, "driving %d irqs\n", p->number_of_irqs);
 
        /* warn in case of mismatch if irq base is specified */
        if (p->config.irq_base) {
                if (p->config.irq_base != p->irq[0].domain_irq)
-                       dev_warn(&pdev->dev, "irq base mismatch (%d/%d)\n",
+                       dev_warn(dev, "irq base mismatch (%d/%d)\n",
                                 p->config.irq_base, p->irq[0].domain_irq);
        }
 
@@ -511,6 +535,8 @@ static int intc_irqpin_probe(struct platform_device *pdev)
 err1:
        irq_domain_remove(p->irq_domain);
 err0:
+       pm_runtime_put(dev);
+       pm_runtime_disable(dev);
        return ret;
 }
 
@@ -519,7 +545,8 @@ static int intc_irqpin_remove(struct platform_device *pdev)
        struct intc_irqpin_priv *p = platform_get_drvdata(pdev);
 
        irq_domain_remove(p->irq_domain);
-
+       pm_runtime_put(&pdev->dev);
+       pm_runtime_disable(&pdev->dev);
        return 0;
 }
 
index ca1621b..a1cebf7 100644 (file)
@@ -1448,9 +1448,9 @@ static void drop_buffers(struct dm_bufio_client *c)
 
 /*
  * Test if the buffer is unused and too old, and commit it.
- * At if noio is set, we must not do any I/O because we hold
- * dm_bufio_clients_lock and we would risk deadlock if the I/O gets rerouted to
- * different bufio client.
+ * And if GFP_NOFS is used, we must not do any I/O because we hold
+ * dm_bufio_clients_lock and we would risk deadlock if the I/O gets
+ * rerouted to different bufio client.
  */
 static int __cleanup_old_buffer(struct dm_buffer *b, gfp_t gfp,
                                unsigned long max_jiffies)
@@ -1458,7 +1458,7 @@ static int __cleanup_old_buffer(struct dm_buffer *b, gfp_t gfp,
        if (jiffies - b->last_accessed < max_jiffies)
                return 0;
 
-       if (!(gfp & __GFP_IO)) {
+       if (!(gfp & __GFP_FS)) {
                if (test_bit(B_READING, &b->state) ||
                    test_bit(B_WRITING, &b->state) ||
                    test_bit(B_DIRTY, &b->state))
@@ -1500,7 +1500,7 @@ dm_bufio_shrink_scan(struct shrinker *shrink, struct shrink_control *sc)
        unsigned long freed;
 
        c = container_of(shrink, struct dm_bufio_client, shrinker);
-       if (sc->gfp_mask & __GFP_IO)
+       if (sc->gfp_mask & __GFP_FS)
                dm_bufio_lock(c);
        else if (!dm_bufio_trylock(c))
                return SHRINK_STOP;
@@ -1517,7 +1517,7 @@ dm_bufio_shrink_count(struct shrinker *shrink, struct shrink_control *sc)
        unsigned long count;
 
        c = container_of(shrink, struct dm_bufio_client, shrinker);
-       if (sc->gfp_mask & __GFP_IO)
+       if (sc->gfp_mask & __GFP_FS)
                dm_bufio_lock(c);
        else if (!dm_bufio_trylock(c))
                return 0;
index 4880b69..5971538 100644 (file)
@@ -785,8 +785,7 @@ struct dm_raid_superblock {
        __le32 layout;
        __le32 stripe_sectors;
 
-       __u8 pad[452];          /* Round struct to 512 bytes. */
-                               /* Always set to 0 when writing. */
+       /* Remainder of a logical block is zero-filled when writing (see super_sync()). */
 } __packed;
 
 static int read_disk_sb(struct md_rdev *rdev, int size)
@@ -823,7 +822,7 @@ static void super_sync(struct mddev *mddev, struct md_rdev *rdev)
                    test_bit(Faulty, &(rs->dev[i].rdev.flags)))
                        failed_devices |= (1ULL << i);
 
-       memset(sb, 0, sizeof(*sb));
+       memset(sb + 1, 0, rdev->sb_size - sizeof(*sb));
 
        sb->magic = cpu_to_le32(DM_RAID_MAGIC);
        sb->features = cpu_to_le32(0);  /* No features yet */
@@ -858,7 +857,11 @@ static int super_load(struct md_rdev *rdev, struct md_rdev *refdev)
        uint64_t events_sb, events_refsb;
 
        rdev->sb_start = 0;
-       rdev->sb_size = sizeof(*sb);
+       rdev->sb_size = bdev_logical_block_size(rdev->meta_bdev);
+       if (rdev->sb_size < sizeof(*sb) || rdev->sb_size > PAGE_SIZE) {
+               DMERR("superblock size of a logical block is no longer valid");
+               return -EINVAL;
+       }
 
        ret = read_disk_sb(rdev, rdev->sb_size);
        if (ret)
index 359af3a..37f2648 100644 (file)
@@ -1704,6 +1704,14 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio)
                return DM_MAPIO_SUBMITTED;
        }
 
+       /*
+        * We must hold the virtual cell before doing the lookup, otherwise
+        * there's a race with discard.
+        */
+       build_virtual_key(tc->td, block, &key);
+       if (dm_bio_detain(tc->pool->prison, &key, bio, &cell1, &cell_result))
+               return DM_MAPIO_SUBMITTED;
+
        r = dm_thin_find_block(td, block, 0, &result);
 
        /*
@@ -1727,13 +1735,10 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio)
                         * shared flag will be set in their case.
                         */
                        thin_defer_bio(tc, bio);
+                       cell_defer_no_holder_no_free(tc, &cell1);
                        return DM_MAPIO_SUBMITTED;
                }
 
-               build_virtual_key(tc->td, block, &key);
-               if (dm_bio_detain(tc->pool->prison, &key, bio, &cell1, &cell_result))
-                       return DM_MAPIO_SUBMITTED;
-
                build_data_key(tc->td, result.block, &key);
                if (dm_bio_detain(tc->pool->prison, &key, bio, &cell2, &cell_result)) {
                        cell_defer_no_holder_no_free(tc, &cell1);
@@ -1754,6 +1759,7 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio)
                         * of doing so.
                         */
                        handle_unserviceable_bio(tc->pool, bio);
+                       cell_defer_no_holder_no_free(tc, &cell1);
                        return DM_MAPIO_SUBMITTED;
                }
                /* fall through */
@@ -1764,6 +1770,7 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio)
                 * provide the hint to load the metadata into cache.
                 */
                thin_defer_bio(tc, bio);
+               cell_defer_no_holder_no_free(tc, &cell1);
                return DM_MAPIO_SUBMITTED;
 
        default:
@@ -1773,6 +1780,7 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio)
                 * pool is switched to fail-io mode.
                 */
                bio_io_error(bio);
+               cell_defer_no_holder_no_free(tc, &cell1);
                return DM_MAPIO_SUBMITTED;
        }
 }
index 73aedcb..40959ee 100644 (file)
@@ -5333,6 +5333,7 @@ static int md_set_readonly(struct mddev *mddev, struct block_device *bdev)
                printk("md: %s still in use.\n",mdname(mddev));
                if (did_freeze) {
                        clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
+                       set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
                        md_wakeup_thread(mddev->thread);
                }
                err = -EBUSY;
@@ -5347,6 +5348,8 @@ static int md_set_readonly(struct mddev *mddev, struct block_device *bdev)
                mddev->ro = 1;
                set_disk_ro(mddev->gendisk, 1);
                clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
+               set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+               md_wakeup_thread(mddev->thread);
                sysfs_notify_dirent_safe(mddev->sysfs_state);
                err = 0;
        }
@@ -5390,6 +5393,7 @@ static int do_md_stop(struct mddev * mddev, int mode,
                mutex_unlock(&mddev->open_mutex);
                if (did_freeze) {
                        clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
+                       set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
                        md_wakeup_thread(mddev->thread);
                }
                return -EBUSY;
index 37d367b..bf2b80d 100644 (file)
@@ -42,6 +42,12 @@ struct btree_node {
 } __packed;
 
 
+/*
+ * Locks a block using the btree node validator.
+ */
+int bn_read_lock(struct dm_btree_info *info, dm_block_t b,
+                struct dm_block **result);
+
 void inc_children(struct dm_transaction_manager *tm, struct btree_node *n,
                  struct dm_btree_value_type *vt);
 
index cf9fd67..1b5e13e 100644 (file)
@@ -92,7 +92,7 @@ struct dm_block_validator btree_node_validator = {
 
 /*----------------------------------------------------------------*/
 
-static int bn_read_lock(struct dm_btree_info *info, dm_block_t b,
+int bn_read_lock(struct dm_btree_info *info, dm_block_t b,
                 struct dm_block **result)
 {
        return dm_tm_read_lock(info->tm, b, &btree_node_validator, result);
index 416060c..200ac12 100644 (file)
@@ -847,22 +847,26 @@ EXPORT_SYMBOL_GPL(dm_btree_find_lowest_key);
  * FIXME: We shouldn't use a recursive algorithm when we have limited stack
  * space.  Also this only works for single level trees.
  */
-static int walk_node(struct ro_spine *s, dm_block_t block,
+static int walk_node(struct dm_btree_info *info, dm_block_t block,
                     int (*fn)(void *context, uint64_t *keys, void *leaf),
                     void *context)
 {
        int r;
        unsigned i, nr;
+       struct dm_block *node;
        struct btree_node *n;
        uint64_t keys;
 
-       r = ro_step(s, block);
-       n = ro_node(s);
+       r = bn_read_lock(info, block, &node);
+       if (r)
+               return r;
+
+       n = dm_block_data(node);
 
        nr = le32_to_cpu(n->header.nr_entries);
        for (i = 0; i < nr; i++) {
                if (le32_to_cpu(n->header.flags) & INTERNAL_NODE) {
-                       r = walk_node(s, value64(n, i), fn, context);
+                       r = walk_node(info, value64(n, i), fn, context);
                        if (r)
                                goto out;
                } else {
@@ -874,7 +878,7 @@ static int walk_node(struct ro_spine *s, dm_block_t block,
        }
 
 out:
-       ro_pop(s);
+       dm_tm_unlock(info->tm, node);
        return r;
 }
 
@@ -882,15 +886,7 @@ int dm_btree_walk(struct dm_btree_info *info, dm_block_t root,
                  int (*fn)(void *context, uint64_t *keys, void *leaf),
                  void *context)
 {
-       int r;
-       struct ro_spine spine;
-
        BUG_ON(info->levels > 1);
-
-       init_ro_spine(&spine, info);
-       r = walk_node(&spine, root, fn, context);
-       exit_ro_spine(&spine);
-
-       return r;
+       return walk_node(info, root, fn, context);
 }
 EXPORT_SYMBOL_GPL(dm_btree_walk);
index d0f82da..04d6ecd 100644 (file)
@@ -469,10 +469,10 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd,
                return 0;
 
        v4l2_of_parse_endpoint(ep, &endpoint);
-       if (WARN_ON(endpoint.port == 0) || index >= FIMC_MAX_SENSORS)
+       if (WARN_ON(endpoint.base.port == 0) || index >= FIMC_MAX_SENSORS)
                return -EINVAL;
 
-       pd->mux_id = (endpoint.port - 1) & 0x1;
+       pd->mux_id = (endpoint.base.port - 1) & 0x1;
 
        rem = of_graph_get_remote_port_parent(ep);
        of_node_put(ep);
@@ -494,13 +494,13 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd,
                return -EINVAL;
        }
 
-       if (fimc_input_is_parallel(endpoint.port)) {
+       if (fimc_input_is_parallel(endpoint.base.port)) {
                if (endpoint.bus_type == V4L2_MBUS_PARALLEL)
                        pd->sensor_bus_type = FIMC_BUS_TYPE_ITU_601;
                else
                        pd->sensor_bus_type = FIMC_BUS_TYPE_ITU_656;
                pd->flags = endpoint.bus.parallel.flags;
-       } else if (fimc_input_is_mipi_csi(endpoint.port)) {
+       } else if (fimc_input_is_mipi_csi(endpoint.base.port)) {
                /*
                 * MIPI CSI-2: only input mux selection and
                 * the sensor's clock frequency is needed.
@@ -508,7 +508,7 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd,
                pd->sensor_bus_type = FIMC_BUS_TYPE_MIPI_CSI2;
        } else {
                v4l2_err(&fmd->v4l2_dev, "Wrong port id (%u) at node %s\n",
-                        endpoint.port, rem->full_name);
+                        endpoint.base.port, rem->full_name);
        }
        /*
         * For FIMC-IS handled sensors, that are placed under i2c-isp device
index fd1ae65..3678ba5 100644 (file)
@@ -772,7 +772,7 @@ static int s5pcsis_parse_dt(struct platform_device *pdev,
        /* Get port node and validate MIPI-CSI channel id. */
        v4l2_of_parse_endpoint(node, &endpoint);
 
-       state->index = endpoint.port - FIMC_INPUT_MIPI_CSI2_0;
+       state->index = endpoint.base.port - FIMC_INPUT_MIPI_CSI2_0;
        if (state->index < 0 || state->index >= CSIS_MAX_ENTITIES)
                return -ENXIO;
 
index 5c45c9d..9c29552 100644 (file)
@@ -156,6 +156,9 @@ static int ttusbdecfe_dvbs_diseqc_send_master_cmd(struct dvb_frontend* fe, struc
                   0x00, 0x00, 0x00, 0x00,
                   0x00, 0x00 };
 
+       if (cmd->msg_len > sizeof(b) - 4)
+               return -EINVAL;
+
        memcpy(&b[4], cmd->msg, cmd->msg_len);
 
        state->config->send_command(fe, 0x72,
index f919db3..b4ed9a9 100644 (file)
@@ -127,17 +127,9 @@ static void v4l2_of_parse_parallel_bus(const struct device_node *node,
 int v4l2_of_parse_endpoint(const struct device_node *node,
                           struct v4l2_of_endpoint *endpoint)
 {
-       struct device_node *port_node = of_get_parent(node);
-
-       memset(endpoint, 0, offsetof(struct v4l2_of_endpoint, head));
-
-       endpoint->local_node = node;
-       /*
-        * It doesn't matter whether the two calls below succeed.
-        * If they don't then the default value 0 is used.
-        */
-       of_property_read_u32(port_node, "reg", &endpoint->port);
-       of_property_read_u32(node, "reg", &endpoint->id);
+       of_graph_parse_endpoint(node, &endpoint->base);
+       endpoint->bus_type = 0;
+       memset(&endpoint->bus, 0, sizeof(endpoint->bus));
 
        v4l2_of_parse_csi_bus(node, endpoint);
        /*
@@ -147,8 +139,6 @@ int v4l2_of_parse_endpoint(const struct device_node *node,
        if (endpoint->bus.mipi_csi2.flags == 0)
                v4l2_of_parse_parallel_bus(node, endpoint);
 
-       of_node_put(port_node);
-
        return 0;
 }
 EXPORT_SYMBOL(v4l2_of_parse_endpoint);
index caf8dcf..b4d920c 100644 (file)
@@ -296,73 +296,73 @@ static struct resource da9055_ld05_6_resource = {
 
 static const struct mfd_cell da9055_devs[] = {
        {
-               .of_compatible = "dialog,da9055-gpio",
+               .of_compatible = "dlg,da9055-gpio",
                .name = "da9055-gpio",
        },
        {
-               .of_compatible = "dialog,da9055-regulator",
+               .of_compatible = "dlg,da9055-regulator",
                .name = "da9055-regulator",
                .id = 1,
        },
        {
-               .of_compatible = "dialog,da9055-regulator",
+               .of_compatible = "dlg,da9055-regulator",
                .name = "da9055-regulator",
                .id = 2,
        },
        {
-               .of_compatible = "dialog,da9055-regulator",
+               .of_compatible = "dlg,da9055-regulator",
                .name = "da9055-regulator",
                .id = 3,
        },
        {
-               .of_compatible = "dialog,da9055-regulator",
+               .of_compatible = "dlg,da9055-regulator",
                .name = "da9055-regulator",
                .id = 4,
        },
        {
-               .of_compatible = "dialog,da9055-regulator",
+               .of_compatible = "dlg,da9055-regulator",
                .name = "da9055-regulator",
                .id = 5,
        },
        {
-               .of_compatible = "dialog,da9055-regulator",
+               .of_compatible = "dlg,da9055-regulator",
                .name = "da9055-regulator",
                .id = 6,
        },
        {
-               .of_compatible = "dialog,da9055-regulator",
+               .of_compatible = "dlg,da9055-regulator",
                .name = "da9055-regulator",
                .id = 7,
                .resources = &da9055_ld05_6_resource,
                .num_resources = 1,
        },
        {
-               .of_compatible = "dialog,da9055-regulator",
+               .of_compatible = "dlg,da9055-regulator",
                .name = "da9055-regulator",
                .resources = &da9055_ld05_6_resource,
                .num_resources = 1,
                .id = 8,
        },
        {
-               .of_compatible = "dialog,da9055-onkey",
+               .of_compatible = "dlg,da9055-onkey",
                .name = "da9055-onkey",
                .resources = &da9055_onkey_resource,
                .num_resources = 1,
        },
        {
-               .of_compatible = "dialog,da9055-rtc",
+               .of_compatible = "dlg,da9055-rtc",
                .name = "da9055-rtc",
                .resources = da9055_rtc_resource,
                .num_resources = ARRAY_SIZE(da9055_rtc_resource),
        },
        {
-               .of_compatible = "dialog,da9055-hwmon",
+               .of_compatible = "dlg,da9055-hwmon",
                .name = "da9055-hwmon",
                .resources = &da9055_hwmon_resource,
                .num_resources = 1,
        },
        {
-               .of_compatible = "dialog,da9055-watchdog",
+               .of_compatible = "dlg,da9055-watchdog",
                .name = "da9055-watchdog",
        },
 };
index 7b5424f..3a24edd 100644 (file)
@@ -1359,6 +1359,16 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
                if (card->host->caps2 & MMC_CAP2_NO_MULTI_READ &&
                    rq_data_dir(req) == READ)
                        brq->data.blocks = 1;
+
+               /*
+                * Some controllers have HW issues while operating
+                * in multiple I/O mode
+                */
+               if (card->host->ops->multi_io_quirk)
+                       brq->data.blocks = card->host->ops->multi_io_quirk(card,
+                                               (rq_data_dir(req) == READ) ?
+                                               MMC_DATA_READ : MMC_DATA_WRITE,
+                                               brq->data.blocks);
        }
 
        if (brq->data.blocks > 1 || do_rel_wr) {
index 91058da..5e76502 100644 (file)
@@ -39,6 +39,7 @@ struct sh_mobile_sdhi_of_data {
        unsigned long tmio_flags;
        unsigned long capabilities;
        unsigned long capabilities2;
+       dma_addr_t dma_rx_offset;
 };
 
 static const struct sh_mobile_sdhi_of_data sh_mobile_sdhi_of_cfg[] = {
@@ -48,14 +49,16 @@ static const struct sh_mobile_sdhi_of_data sh_mobile_sdhi_of_cfg[] = {
 };
 
 static const struct sh_mobile_sdhi_of_data of_rcar_gen1_compatible = {
-       .tmio_flags     = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_WRPROTECT_DISABLE,
+       .tmio_flags     = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_WRPROTECT_DISABLE |
+                         TMIO_MMC_CLK_ACTUAL,
        .capabilities   = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ,
 };
 
 static const struct sh_mobile_sdhi_of_data of_rcar_gen2_compatible = {
-       .tmio_flags     = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_WRPROTECT_DISABLE,
+       .tmio_flags     = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_WRPROTECT_DISABLE |
+                         TMIO_MMC_CLK_ACTUAL,
        .capabilities   = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ,
-       .capabilities2  = MMC_CAP2_NO_MULTI_READ,
+       .dma_rx_offset  = 0x2000,
 };
 
 static const struct of_device_id sh_mobile_sdhi_of_match[] = {
@@ -68,6 +71,9 @@ static const struct of_device_id sh_mobile_sdhi_of_match[] = {
        { .compatible = "renesas,sdhi-r8a7779", .data = &of_rcar_gen1_compatible, },
        { .compatible = "renesas,sdhi-r8a7790", .data = &of_rcar_gen2_compatible, },
        { .compatible = "renesas,sdhi-r8a7791", .data = &of_rcar_gen2_compatible, },
+       { .compatible = "renesas,sdhi-r8a7792", .data = &of_rcar_gen2_compatible, },
+       { .compatible = "renesas,sdhi-r8a7793", .data = &of_rcar_gen2_compatible, },
+       { .compatible = "renesas,sdhi-r8a7794", .data = &of_rcar_gen2_compatible, },
        {},
 };
 MODULE_DEVICE_TABLE(of, sh_mobile_sdhi_of_match);
@@ -132,6 +138,24 @@ static int sh_mobile_sdhi_write16_hook(struct tmio_mmc_host *host, int addr)
        return 0;
 }
 
+static int sh_mobile_sdhi_multi_io_quirk(struct mmc_card *card,
+                                        unsigned int direction, int blk_size)
+{
+       /*
+        * In Renesas controllers, when performing a
+        * multiple block read of one or two blocks,
+        * depending on the timing with which the
+        * response register is read, the response
+        * value may not be read properly.
+        * Use single block read for this HW bug
+        */
+       if ((direction == MMC_DATA_READ) &&
+           blk_size == 2)
+               return 1;
+
+       return blk_size;
+}
+
 static void sh_mobile_sdhi_cd_wakeup(const struct platform_device *pdev)
 {
        mmc_detect_change(platform_get_drvdata(pdev), msecs_to_jiffies(100));
@@ -187,6 +211,7 @@ static int sh_mobile_sdhi_probe(struct platform_device *pdev)
        mmc_data->clk_disable = sh_mobile_sdhi_clk_disable;
        mmc_data->capabilities = MMC_CAP_MMC_HIGHSPEED;
        mmc_data->write16_hook = sh_mobile_sdhi_write16_hook;
+       mmc_data->multi_io_quirk = sh_mobile_sdhi_multi_io_quirk;
        if (p) {
                mmc_data->flags = p->tmio_flags;
                mmc_data->ocr_mask = p->tmio_ocr_mask;
@@ -223,11 +248,27 @@ static int sh_mobile_sdhi_probe(struct platform_device *pdev)
         */
        mmc_data->flags |= TMIO_MMC_SDIO_IRQ;
 
+       /*
+        * All SDHI have CMD12 controll bit
+        */
+       mmc_data->flags |= TMIO_MMC_HAVE_CMD12_CTRL;
+
+       /*
+        * All SDHI need SDIO_INFO1 reserved bit
+        */
+       mmc_data->flags |= TMIO_MMC_SDIO_STATUS_QUIRK;
+
+       /*
+        * All SDHI have DMA control register
+        */
+       mmc_data->flags |= TMIO_MMC_HAVE_CTL_DMA_REG;
+
        if (of_id && of_id->data) {
                const struct sh_mobile_sdhi_of_data *of_data = of_id->data;
                mmc_data->flags |= of_data->tmio_flags;
                mmc_data->capabilities |= of_data->capabilities;
                mmc_data->capabilities2 |= of_data->capabilities2;
+               dma_priv->dma_rx_offset = of_data->dma_rx_offset;
        }
 
        /* SD control register space size is 0x100, 0x200 for bus_shift=1 */
@@ -332,8 +373,9 @@ static int sh_mobile_sdhi_remove(struct platform_device *pdev)
 }
 
 static const struct dev_pm_ops tmio_mmc_dev_pm_ops = {
-       SET_SYSTEM_SLEEP_PM_OPS(tmio_mmc_host_suspend, tmio_mmc_host_resume)
-       SET_RUNTIME_PM_OPS(tmio_mmc_host_runtime_suspend,
+       SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+                       pm_runtime_force_resume)
+       SET_PM_RUNTIME_PM_OPS(tmio_mmc_host_runtime_suspend,
                        tmio_mmc_host_runtime_resume,
                        NULL)
 };
index cfad844..659028d 100644 (file)
@@ -30,7 +30,7 @@ static int tmio_mmc_suspend(struct device *dev)
        const struct mfd_cell *cell = mfd_get_cell(pdev);
        int ret;
 
-       ret = tmio_mmc_host_suspend(dev);
+       ret = pm_runtime_force_suspend(dev);
 
        /* Tell MFD core it can disable us now.*/
        if (!ret && cell->disable)
@@ -50,7 +50,7 @@ static int tmio_mmc_resume(struct device *dev)
                ret = cell->resume(pdev);
 
        if (!ret)
-               ret = tmio_mmc_host_resume(dev);
+               ret = pm_runtime_force_resume(dev);
 
        return ret;
 }
@@ -135,6 +135,9 @@ static int tmio_mmc_remove(struct platform_device *pdev)
 
 static const struct dev_pm_ops tmio_mmc_dev_pm_ops = {
        SET_SYSTEM_SLEEP_PM_OPS(tmio_mmc_suspend, tmio_mmc_resume)
+       SET_PM_RUNTIME_PM_OPS(tmio_mmc_host_runtime_suspend,
+                       tmio_mmc_host_runtime_resume,
+                       NULL)
 };
 
 static struct platform_driver tmio_mmc_driver = {
index 100ffe0..a34ecbe 100644 (file)
 
 struct tmio_mmc_data;
 
-/*
- * We differentiate between the following 3 power states:
- * 1. card slot powered off, controller stopped. This is used, when either there
- *    is no card in the slot, or the card really has to be powered down.
- * 2. card slot powered on, controller stopped. This is used, when a card is in
- *    the slot, but no activity is currently taking place. This is a power-
- *    saving mode with card-state preserved. This state can be entered, e.g.
- *    when MMC clock-gating is used.
- * 3. card slot powered on, controller running. This is the actual active state.
- */
-enum tmio_mmc_power {
-       TMIO_MMC_OFF_STOP,      /* card power off, controller stopped */
-       TMIO_MMC_ON_STOP,       /* card power on, controller stopped */
-       TMIO_MMC_ON_RUN,        /* card power on, controller running */
-};
-
 struct tmio_mmc_host {
        void __iomem *ctl;
        struct mmc_command      *cmd;
@@ -63,9 +47,6 @@ struct tmio_mmc_host {
        struct mmc_data         *data;
        struct mmc_host         *mmc;
 
-       /* Controller and card power state */
-       enum tmio_mmc_power     power;
-
        /* Callbacks for clock / power control */
        void (*set_pwr)(struct platform_device *host, int state);
        void (*set_clk_div)(struct platform_device *host, int state);
@@ -92,15 +73,16 @@ struct tmio_mmc_host {
        struct delayed_work     delayed_reset_work;
        struct work_struct      done;
 
-       /* Cache IRQ mask */
+       /* Cache */
        u32                     sdcard_irq_mask;
        u32                     sdio_irq_mask;
+       unsigned int            clk_cache;
 
        spinlock_t              lock;           /* protect host private data */
        unsigned long           last_req_ts;
        struct mutex            ios_lock;       /* protect set_ios() context */
        bool                    native_hotplug;
-       bool                    resuming;
+       bool                    sdio_irq_enabled;
 };
 
 int tmio_mmc_host_probe(struct tmio_mmc_host **host,
@@ -162,12 +144,7 @@ static inline void tmio_mmc_abort_dma(struct tmio_mmc_host *host)
 }
 #endif
 
-#ifdef CONFIG_PM_SLEEP
-int tmio_mmc_host_suspend(struct device *dev);
-int tmio_mmc_host_resume(struct device *dev);
-#endif
-
-#ifdef CONFIG_PM_RUNTIME
+#ifdef CONFIG_PM
 int tmio_mmc_host_runtime_suspend(struct device *dev);
 int tmio_mmc_host_runtime_resume(struct device *dev);
 #endif
index eb8f1d5..7d07738 100644 (file)
@@ -28,10 +28,8 @@ void tmio_mmc_enable_dma(struct tmio_mmc_host *host, bool enable)
        if (!host->chan_tx || !host->chan_rx)
                return;
 
-#if defined(CONFIG_SUPERH) || defined(CONFIG_ARCH_SHMOBILE)
-       /* Switch DMA mode on or off - SuperH specific? */
-       sd_ctrl_write16(host, CTL_DMA_ENABLE, enable ? 2 : 0);
-#endif
+       if (host->pdata->flags & TMIO_MMC_HAVE_CTL_DMA_REG)
+               sd_ctrl_write16(host, CTL_DMA_ENABLE, enable ? 2 : 0);
 }
 
 void tmio_mmc_abort_dma(struct tmio_mmc_host *host)
@@ -312,7 +310,7 @@ void tmio_mmc_request_dma(struct tmio_mmc_host *host, struct tmio_mmc_data *pdat
                if (pdata->dma->chan_priv_rx)
                        cfg.slave_id = pdata->dma->slave_id_rx;
                cfg.direction = DMA_DEV_TO_MEM;
-               cfg.src_addr = cfg.dst_addr;
+               cfg.src_addr = cfg.dst_addr + pdata->dma->dma_rx_offset;
                cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
                cfg.dst_addr = 0;
                ret = dmaengine_slave_config(host->chan_rx, &cfg);
index faf0924..e487ba4 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/pm_qos.h>
 #include <linux/pm_runtime.h>
 #include <linux/regulator/consumer.h>
+#include <linux/mmc/sdio.h>
 #include <linux/scatterlist.h>
 #include <linux/spinlock.h>
 #include <linux/workqueue.h>
@@ -129,19 +130,28 @@ static void tmio_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
 {
        struct tmio_mmc_host *host = mmc_priv(mmc);
 
-       if (enable) {
+       if (enable && !host->sdio_irq_enabled) {
+               /* Keep device active while SDIO irq is enabled */
+               pm_runtime_get_sync(mmc_dev(mmc));
+               host->sdio_irq_enabled = true;
+
                host->sdio_irq_mask = TMIO_SDIO_MASK_ALL &
                                        ~TMIO_SDIO_STAT_IOIRQ;
                sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0001);
                sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, host->sdio_irq_mask);
-       } else {
+       } else if (!enable && host->sdio_irq_enabled) {
                host->sdio_irq_mask = TMIO_SDIO_MASK_ALL;
                sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, host->sdio_irq_mask);
                sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0000);
+
+               host->sdio_irq_enabled = false;
+               pm_runtime_mark_last_busy(mmc_dev(mmc));
+               pm_runtime_put_autosuspend(mmc_dev(mmc));
        }
 }
 
-static void tmio_mmc_set_clock(struct tmio_mmc_host *host, int new_clock)
+static void tmio_mmc_set_clock(struct tmio_mmc_host *host,
+                               unsigned int new_clock)
 {
        u32 clk = 0, clock;
 
@@ -149,7 +159,11 @@ static void tmio_mmc_set_clock(struct tmio_mmc_host *host, int new_clock)
                for (clock = host->mmc->f_min, clk = 0x80000080;
                        new_clock >= (clock<<1); clk >>= 1)
                        clock <<= 1;
-               clk |= 0x100;
+
+               /* 1/1 clock is option */
+               if ((host->pdata->flags & TMIO_MMC_CLK_ACTUAL) &&
+                   ((clk >> 22) & 0x1))
+                       clk |= 0xff;
        }
 
        if (host->set_clk_div)
@@ -245,6 +259,9 @@ static void tmio_mmc_reset_work(struct work_struct *work)
 
        tmio_mmc_abort_dma(host);
        mmc_request_done(host->mmc, mrq);
+
+       pm_runtime_mark_last_busy(mmc_dev(host->mmc));
+       pm_runtime_put_autosuspend(mmc_dev(host->mmc));
 }
 
 /* called with host->lock held, interrupts disabled */
@@ -274,6 +291,9 @@ static void tmio_mmc_finish_request(struct tmio_mmc_host *host)
                tmio_mmc_abort_dma(host);
 
        mmc_request_done(host->mmc, mrq);
+
+       pm_runtime_mark_last_busy(mmc_dev(host->mmc));
+       pm_runtime_put_autosuspend(mmc_dev(host->mmc));
 }
 
 static void tmio_mmc_done_work(struct work_struct *work)
@@ -295,6 +315,7 @@ static void tmio_mmc_done_work(struct work_struct *work)
 #define TRANSFER_READ  0x1000
 #define TRANSFER_MULTI 0x2000
 #define SECURITY_CMD   0x4000
+#define NO_CMD12_ISSUE 0x4000 /* TMIO_MMC_HAVE_CMD12_CTRL */
 
 static int tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command *cmd)
 {
@@ -331,6 +352,14 @@ static int tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command
                if (data->blocks > 1) {
                        sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, 0x100);
                        c |= TRANSFER_MULTI;
+
+                       /*
+                        * Disable auto CMD12 at IO_RW_EXTENDED when
+                        * multiple block transfer
+                        */
+                       if ((host->pdata->flags & TMIO_MMC_HAVE_CMD12_CTRL) &&
+                           (cmd->opcode == SD_IO_RW_EXTENDED))
+                               c |= NO_CMD12_ISSUE;
                }
                if (data->flags & MMC_DATA_READ)
                        c |= TRANSFER_READ;
@@ -347,6 +376,40 @@ static int tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command
        return 0;
 }
 
+static void tmio_mmc_transfer_data(struct tmio_mmc_host *host,
+                                  unsigned short *buf,
+                                  unsigned int count)
+{
+       int is_read = host->data->flags & MMC_DATA_READ;
+       u8  *buf8;
+
+       /*
+        * Transfer the data
+        */
+       if (is_read)
+               sd_ctrl_read16_rep(host, CTL_SD_DATA_PORT, buf, count >> 1);
+       else
+               sd_ctrl_write16_rep(host, CTL_SD_DATA_PORT, buf, count >> 1);
+
+       /* if count was even number */
+       if (!(count & 0x1))
+               return;
+
+       /* if count was odd number */
+       buf8 = (u8 *)(buf + (count >> 1));
+
+       /*
+        * FIXME
+        *
+        * driver and this function are assuming that
+        * it is used as little endian
+        */
+       if (is_read)
+               *buf8 = sd_ctrl_read16(host, CTL_SD_DATA_PORT) & 0xff;
+       else
+               sd_ctrl_write16(host, CTL_SD_DATA_PORT, *buf8);
+}
+
 /*
  * This chip always returns (at least?) as much data as you ask for.
  * I'm unsure what happens if you ask for less than a block. This should be
@@ -379,10 +442,7 @@ static void tmio_mmc_pio_irq(struct tmio_mmc_host *host)
                 count, host->sg_off, data->flags);
 
        /* Transfer the data */
-       if (data->flags & MMC_DATA_READ)
-               sd_ctrl_read16_rep(host, CTL_SD_DATA_PORT, buf, count >> 1);
-       else
-               sd_ctrl_write16_rep(host, CTL_SD_DATA_PORT, buf, count >> 1);
+       tmio_mmc_transfer_data(host, buf, count);
 
        host->sg_off += count;
 
@@ -465,6 +525,9 @@ static void tmio_mmc_data_irq(struct tmio_mmc_host *host)
                goto out;
 
        if (host->chan_tx && (data->flags & MMC_DATA_WRITE) && !host->force_pio) {
+               u32 status = sd_ctrl_read32(host, CTL_STATUS);
+               bool done = false;
+
                /*
                 * Has all data been written out yet? Testing on SuperH showed,
                 * that in most cases the first interrupt comes already with the
@@ -473,7 +536,15 @@ static void tmio_mmc_data_irq(struct tmio_mmc_host *host)
                 * DATAEND interrupt with the BUSY bit set, in this cases
                 * waiting for one more interrupt fixes the problem.
                 */
-               if (!(sd_ctrl_read32(host, CTL_STATUS) & TMIO_STAT_CMD_BUSY)) {
+               if (host->pdata->flags & TMIO_MMC_HAS_IDLE_WAIT) {
+                       if (status & TMIO_STAT_ILL_FUNC)
+                               done = true;
+               } else {
+                       if (!(status & TMIO_STAT_CMD_BUSY))
+                               done = true;
+               }
+
+               if (done) {
                        tmio_mmc_disable_mmc_irqs(host, TMIO_STAT_DATAEND);
                        tasklet_schedule(&host->dma_complete);
                }
@@ -557,6 +628,9 @@ static void tmio_mmc_card_irq_status(struct tmio_mmc_host *host,
 
        pr_debug_status(*status);
        pr_debug_status(*ireg);
+
+       /* Clear the status except the interrupt status */
+       sd_ctrl_write32(host, CTL_STATUS, TMIO_MASK_IRQ);
 }
 
 static bool __tmio_mmc_card_detect_irq(struct tmio_mmc_host *host,
@@ -637,6 +711,7 @@ irqreturn_t tmio_mmc_sdio_irq(int irq, void *devid)
        struct mmc_host *mmc = host->mmc;
        struct tmio_mmc_data *pdata = host->pdata;
        unsigned int ireg, status;
+       unsigned int sdio_status;
 
        if (!(pdata->flags & TMIO_MMC_SDIO_IRQ))
                return IRQ_HANDLED;
@@ -644,7 +719,11 @@ irqreturn_t tmio_mmc_sdio_irq(int irq, void *devid)
        status = sd_ctrl_read16(host, CTL_SDIO_STATUS);
        ireg = status & TMIO_SDIO_MASK_ALL & ~host->sdcard_irq_mask;
 
-       sd_ctrl_write16(host, CTL_SDIO_STATUS, status & ~TMIO_SDIO_MASK_ALL);
+       sdio_status = status & ~TMIO_SDIO_MASK_ALL;
+       if (pdata->flags & TMIO_MMC_SDIO_STATUS_QUIRK)
+               sdio_status |= 6;
+
+       sd_ctrl_write16(host, CTL_SDIO_STATUS, sdio_status);
 
        if (mmc->caps & MMC_CAP_SDIO_IRQ && ireg & TMIO_SDIO_STAT_IOIRQ)
                mmc_signal_sdio_irq(mmc);
@@ -728,6 +807,8 @@ static void tmio_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
 
        spin_unlock_irqrestore(&host->lock, flags);
 
+       pm_runtime_get_sync(mmc_dev(mmc));
+
        if (mrq->data) {
                ret = tmio_mmc_start_data(host, mrq->data);
                if (ret)
@@ -746,11 +827,14 @@ fail:
        host->mrq = NULL;
        mrq->cmd->error = ret;
        mmc_request_done(mmc, mrq);
+
+       pm_runtime_mark_last_busy(mmc_dev(mmc));
+       pm_runtime_put_autosuspend(mmc_dev(mmc));
 }
 
-static int tmio_mmc_clk_update(struct mmc_host *mmc)
+static int tmio_mmc_clk_update(struct tmio_mmc_host *host)
 {
-       struct tmio_mmc_host *host = mmc_priv(mmc);
+       struct mmc_host *mmc = host->mmc;
        struct tmio_mmc_data *pdata = host->pdata;
        int ret;
 
@@ -812,6 +896,19 @@ static void tmio_mmc_power_off(struct tmio_mmc_host *host)
                host->set_pwr(host->pdev, 0);
 }
 
+static void tmio_mmc_set_bus_width(struct tmio_mmc_host *host,
+                               unsigned char bus_width)
+{
+       switch (bus_width) {
+       case MMC_BUS_WIDTH_1:
+               sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x80e0);
+               break;
+       case MMC_BUS_WIDTH_4:
+               sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x00e0);
+               break;
+       }
+}
+
 /* Set MMC clock / power.
  * Note: This controller uses a simple divider scheme therefore it cannot
  * run a MMC card at full speed (20MHz). The max clock is 24MHz on SD, but as
@@ -824,6 +921,8 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
        struct device *dev = &host->pdev->dev;
        unsigned long flags;
 
+       pm_runtime_get_sync(mmc_dev(mmc));
+
        mutex_lock(&host->ios_lock);
 
        spin_lock_irqsave(&host->lock, flags);
@@ -850,60 +949,22 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 
        spin_unlock_irqrestore(&host->lock, flags);
 
-       /*
-        * host->power toggles between false and true in both cases - either
-        * or not the controller can be runtime-suspended during inactivity.
-        * But if the controller has to be kept on, the runtime-pm usage_count
-        * is kept positive, so no suspending actually takes place.
-        */
-       if (ios->power_mode == MMC_POWER_ON && ios->clock) {
-               if (host->power != TMIO_MMC_ON_RUN) {
-                       tmio_mmc_clk_update(mmc);
-                       pm_runtime_get_sync(dev);
-                       if (host->resuming) {
-                               tmio_mmc_reset(host);
-                               host->resuming = false;
-                       }
-               }
-               if (host->power == TMIO_MMC_OFF_STOP)
-                       tmio_mmc_reset(host);
+       switch (ios->power_mode) {
+       case MMC_POWER_OFF:
+               tmio_mmc_power_off(host);
+               tmio_mmc_clk_stop(host);
+               break;
+       case MMC_POWER_UP:
                tmio_mmc_set_clock(host, ios->clock);
-               if (host->power == TMIO_MMC_OFF_STOP)
-                       /* power up SD card and the bus */
-                       tmio_mmc_power_on(host, ios->vdd);
-               host->power = TMIO_MMC_ON_RUN;
-               /* start bus clock */
+               tmio_mmc_power_on(host, ios->vdd);
                tmio_mmc_clk_start(host);
-       } else if (ios->power_mode != MMC_POWER_UP) {
-               struct tmio_mmc_data *pdata = host->pdata;
-               unsigned int old_power = host->power;
-
-               if (old_power != TMIO_MMC_OFF_STOP) {
-                       if (ios->power_mode == MMC_POWER_OFF) {
-                               tmio_mmc_power_off(host);
-                               host->power = TMIO_MMC_OFF_STOP;
-                       } else {
-                               host->power = TMIO_MMC_ON_STOP;
-                       }
-               }
-
-               if (old_power == TMIO_MMC_ON_RUN) {
-                       tmio_mmc_clk_stop(host);
-                       pm_runtime_put(dev);
-                       if (pdata->clk_disable)
-                               pdata->clk_disable(host->pdev);
-               }
-       }
-
-       if (host->power != TMIO_MMC_OFF_STOP) {
-               switch (ios->bus_width) {
-               case MMC_BUS_WIDTH_1:
-                       sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x80e0);
+               tmio_mmc_set_bus_width(host, ios->bus_width);
                break;
-               case MMC_BUS_WIDTH_4:
-                       sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x00e0);
+       case MMC_POWER_ON:
+               tmio_mmc_set_clock(host, ios->clock);
+               tmio_mmc_clk_start(host);
+               tmio_mmc_set_bus_width(host, ios->bus_width);
                break;
-               }
        }
 
        /* Let things settle. delay taken from winCE driver */
@@ -915,7 +976,12 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
                        ios->clock, ios->power_mode);
        host->mrq = NULL;
 
+       host->clk_cache = ios->clock;
+
        mutex_unlock(&host->ios_lock);
+
+       pm_runtime_mark_last_busy(mmc_dev(mmc));
+       pm_runtime_put_autosuspend(mmc_dev(mmc));
 }
 
 static int tmio_mmc_get_ro(struct mmc_host *mmc)
@@ -926,8 +992,25 @@ static int tmio_mmc_get_ro(struct mmc_host *mmc)
        if (ret >= 0)
                return ret;
 
-       return !((pdata->flags & TMIO_MMC_WRPROTECT_DISABLE) ||
-                (sd_ctrl_read32(host, CTL_STATUS) & TMIO_STAT_WRPROTECT));
+       pm_runtime_get_sync(mmc_dev(mmc));
+       ret = !((pdata->flags & TMIO_MMC_WRPROTECT_DISABLE) ||
+               (sd_ctrl_read32(host, CTL_STATUS) & TMIO_STAT_WRPROTECT));
+       pm_runtime_mark_last_busy(mmc_dev(mmc));
+       pm_runtime_put_autosuspend(mmc_dev(mmc));
+
+       return ret;
+}
+
+static int tmio_multi_io_quirk(struct mmc_card *card,
+                              unsigned int direction, int blk_size)
+{
+       struct tmio_mmc_host *host = mmc_priv(card->host);
+       struct tmio_mmc_data *pdata = host->pdata;
+
+       if (pdata->multi_io_quirk)
+               return pdata->multi_io_quirk(card, direction, blk_size);
+
+       return blk_size;
 }
 
 static const struct mmc_host_ops tmio_mmc_ops = {
@@ -936,6 +1019,7 @@ static const struct mmc_host_ops tmio_mmc_ops = {
        .get_ro         = tmio_mmc_get_ro,
        .get_cd         = mmc_gpio_get_cd,
        .enable_sdio_irq = tmio_mmc_enable_sdio_irq,
+       .multi_io_quirk = tmio_multi_io_quirk,
 };
 
 static int tmio_mmc_init_ocr(struct tmio_mmc_host *host)
@@ -1032,28 +1116,23 @@ int tmio_mmc_host_probe(struct tmio_mmc_host **host,
                                  mmc->caps & MMC_CAP_NONREMOVABLE ||
                                  mmc->slot.cd_irq >= 0);
 
-       _host->power = TMIO_MMC_OFF_STOP;
-       pm_runtime_enable(&pdev->dev);
-       ret = pm_runtime_resume(&pdev->dev);
-       if (ret < 0)
-               goto pm_disable;
-
-       if (tmio_mmc_clk_update(mmc) < 0) {
+       if (tmio_mmc_clk_update(_host) < 0) {
                mmc->f_max = pdata->hclk;
                mmc->f_min = mmc->f_max / 512;
        }
 
        /*
-        * There are 4 different scenarios for the card detection:
-        *  1) an external gpio irq handles the cd (best for power savings)
-        *  2) internal sdhi irq handles the cd
-        *  3) a worker thread polls the sdhi - indicated by MMC_CAP_NEEDS_POLL
-        *  4) the medium is non-removable - indicated by MMC_CAP_NONREMOVABLE
-        *
-        *  While we increment the runtime PM counter for all scenarios when
-        *  the mmc core activates us by calling an appropriate set_ios(), we
-        *  must additionally ensure that in case 2) the tmio mmc hardware stays
-        *  powered on during runtime for the card detection to work.
+        * Check the sanity of mmc->f_min to prevent tmio_mmc_set_clock() from
+        * looping forever...
+        */
+       if (mmc->f_min == 0) {
+               ret = -EINVAL;
+               goto host_free;
+       }
+
+       /*
+        * While using internal tmio hardware logic for card detection, we need
+        * to ensure it stays powered for it to work.
         */
        if (_host->native_hotplug)
                pm_runtime_get_noresume(&pdev->dev);
@@ -1074,8 +1153,12 @@ int tmio_mmc_host_probe(struct tmio_mmc_host **host,
 
        _host->sdcard_irq_mask &= ~irq_mask;
 
-       if (pdata->flags & TMIO_MMC_SDIO_IRQ)
-               tmio_mmc_enable_sdio_irq(mmc, 0);
+       _host->sdio_irq_enabled = false;
+       if (pdata->flags & TMIO_MMC_SDIO_IRQ) {
+               _host->sdio_irq_mask = TMIO_SDIO_MASK_ALL;
+               sd_ctrl_write16(_host, CTL_SDIO_IRQ_MASK, _host->sdio_irq_mask);
+               sd_ctrl_write16(_host, CTL_TRANSACTION_CTL, 0x0000);
+       }
 
        spin_lock_init(&_host->lock);
        mutex_init(&_host->ios_lock);
@@ -1087,9 +1170,12 @@ int tmio_mmc_host_probe(struct tmio_mmc_host **host,
        /* See if we also get DMA */
        tmio_mmc_request_dma(_host, pdata);
 
+       pm_runtime_set_active(&pdev->dev);
+       pm_runtime_set_autosuspend_delay(&pdev->dev, 50);
+       pm_runtime_use_autosuspend(&pdev->dev);
+       pm_runtime_enable(&pdev->dev);
+
        ret = mmc_add_host(mmc);
-       if (pdata->clk_disable)
-               pdata->clk_disable(pdev);
        if (ret < 0) {
                tmio_mmc_host_remove(_host);
                return ret;
@@ -1109,9 +1195,6 @@ int tmio_mmc_host_probe(struct tmio_mmc_host **host,
 
        return 0;
 
-pm_disable:
-       pm_runtime_disable(&pdev->dev);
-       iounmap(_host->ctl);
 host_free:
        mmc_free_host(mmc);
 
@@ -1142,34 +1225,20 @@ void tmio_mmc_host_remove(struct tmio_mmc_host *host)
 }
 EXPORT_SYMBOL(tmio_mmc_host_remove);
 
-#ifdef CONFIG_PM_SLEEP
-int tmio_mmc_host_suspend(struct device *dev)
+#ifdef CONFIG_PM
+int tmio_mmc_host_runtime_suspend(struct device *dev)
 {
        struct mmc_host *mmc = dev_get_drvdata(dev);
        struct tmio_mmc_host *host = mmc_priv(mmc);
 
        tmio_mmc_disable_mmc_irqs(host, TMIO_MASK_ALL);
-       return 0;
-}
-EXPORT_SYMBOL(tmio_mmc_host_suspend);
-
-int tmio_mmc_host_resume(struct device *dev)
-{
-       struct mmc_host *mmc = dev_get_drvdata(dev);
-       struct tmio_mmc_host *host = mmc_priv(mmc);
 
-       tmio_mmc_enable_dma(host, true);
+       if (host->clk_cache)
+               tmio_mmc_clk_stop(host);
 
-       /* The MMC core will perform the complete set up */
-       host->resuming = true;
-       return 0;
-}
-EXPORT_SYMBOL(tmio_mmc_host_resume);
-#endif
+       if (host->pdata->clk_disable)
+               host->pdata->clk_disable(host->pdev);
 
-#ifdef CONFIG_PM_RUNTIME
-int tmio_mmc_host_runtime_suspend(struct device *dev)
-{
        return 0;
 }
 EXPORT_SYMBOL(tmio_mmc_host_runtime_suspend);
@@ -1179,6 +1248,14 @@ int tmio_mmc_host_runtime_resume(struct device *dev)
        struct mmc_host *mmc = dev_get_drvdata(dev);
        struct tmio_mmc_host *host = mmc_priv(mmc);
 
+       tmio_mmc_reset(host);
+       tmio_mmc_clk_update(host);
+
+       if (host->clk_cache) {
+               tmio_mmc_set_clock(host, host->clk_cache);
+               tmio_mmc_clk_start(host);
+       }
+
        tmio_mmc_enable_dma(host, true);
 
        return 0;
index cc38948..1537982 100644 (file)
@@ -2450,9 +2450,9 @@ static void bond_loadbalance_arp_mon(struct work_struct *work)
                if (!rtnl_trylock())
                        goto re_arm;
 
-               if (slave_state_changed) {
+               if (slave_state_changed)
                        bond_slave_state_change(bond);
-               } else if (do_failover) {
+               if (do_failover) {
                        /* the bond_select_active_slave must hold RTNL
                         * and curr_slave_lock for write.
                         */
index fc59bc6..cc11f7f 100644 (file)
@@ -384,7 +384,7 @@ void can_free_echo_skb(struct net_device *dev, unsigned int idx)
        BUG_ON(idx >= priv->echo_skb_max);
 
        if (priv->echo_skb[idx]) {
-               kfree_skb(priv->echo_skb[idx]);
+               dev_kfree_skb_any(priv->echo_skb[idx]);
                priv->echo_skb[idx] = NULL;
        }
 }
index 7fbe859..f34f7fa 100644 (file)
@@ -1141,6 +1141,7 @@ static void esd_usb2_disconnect(struct usb_interface *intf)
                        }
                }
                unlink_all_urbs(dev);
+               kfree(dev);
        }
 }
 
index 6382b7c..e10f5ed 100644 (file)
@@ -1341,6 +1341,42 @@ static void smsc911x_rx_multicast_update_workaround(struct smsc911x_data *pdata)
        spin_unlock(&pdata->mac_lock);
 }
 
+static int smsc911x_phy_general_power_up(struct smsc911x_data *pdata)
+{
+       int rc = 0;
+
+       if (!pdata->phy_dev)
+               return rc;
+
+       /* If the internal PHY is in General Power-Down mode, all, except the
+        * management interface, is powered-down and stays in that condition as
+        * long as Phy register bit 0.11 is HIGH.
+        *
+        * In that case, clear the bit 0.11, so the PHY powers up and we can
+        * access to the phy registers.
+        */
+       rc = phy_read(pdata->phy_dev, MII_BMCR);
+       if (rc < 0) {
+               SMSC_WARN(pdata, drv, "Failed reading PHY control reg");
+               return rc;
+       }
+
+       /* If the PHY general power-down bit is not set is not necessary to
+        * disable the general power down-mode.
+        */
+       if (rc & BMCR_PDOWN) {
+               rc = phy_write(pdata->phy_dev, MII_BMCR, rc & ~BMCR_PDOWN);
+               if (rc < 0) {
+                       SMSC_WARN(pdata, drv, "Failed writing PHY control reg");
+                       return rc;
+               }
+
+               usleep_range(1000, 1500);
+       }
+
+       return 0;
+}
+
 static int smsc911x_phy_disable_energy_detect(struct smsc911x_data *pdata)
 {
        int rc = 0;
@@ -1414,6 +1450,16 @@ static int smsc911x_soft_reset(struct smsc911x_data *pdata)
        int ret;
 
        /*
+        * Make sure to power-up the PHY chip before doing a reset, otherwise
+        * the reset fails.
+        */
+       ret = smsc911x_phy_general_power_up(pdata);
+       if (ret) {
+               SMSC_WARN(pdata, drv, "Failed to power-up the PHY chip");
+               return ret;
+       }
+
+       /*
         * LAN9210/LAN9211/LAN9220/LAN9221 chips have an internal PHY that
         * are initialized in a Energy Detect Power-Down mode that prevents
         * the MAC chip to be software reseted. So we have to wakeup the PHY
index fd411d6..03ae9de 100644 (file)
@@ -656,7 +656,7 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
        spin_lock_irqsave(&port->vio.lock, flags);
 
        dr = &port->vio.drings[VIO_DRIVER_TX_RING];
-       if (unlikely(vnet_tx_dring_avail(dr) < 2)) {
+       if (unlikely(vnet_tx_dring_avail(dr) < 1)) {
                if (!netif_queue_stopped(dev)) {
                        netif_stop_queue(dev);
 
@@ -704,7 +704,7 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
        dev->stats.tx_bytes += skb->len;
 
        dr->prod = (dr->prod + 1) & (VNET_TX_RING_SIZE - 1);
-       if (unlikely(vnet_tx_dring_avail(dr) < 2)) {
+       if (unlikely(vnet_tx_dring_avail(dr) < 1)) {
                netif_stop_queue(dev);
                if (vnet_tx_dring_avail(dr) > VNET_TX_WAKEUP_THRESH(dr))
                        netif_wake_queue(dev);
index bf0d55e..6adbef8 100644 (file)
@@ -376,17 +376,20 @@ static int ieee802154fake_probe(struct platform_device *pdev)
 
        err = wpan_phy_register(phy);
        if (err)
-               goto out;
+               goto err_phy_reg;
 
        err = register_netdev(dev);
-       if (err < 0)
-               goto out;
+       if (err)
+               goto err_netdev_reg;
 
        dev_info(&pdev->dev, "Added ieee802154 HardMAC hardware\n");
        return 0;
 
-out:
-       unregister_netdev(dev);
+err_netdev_reg:
+       wpan_phy_unregister(phy);
+err_phy_reg:
+       free_netdev(dev);
+       wpan_phy_free(phy);
        return err;
 }
 
index f30ceb1..07c942b 100644 (file)
@@ -66,7 +66,7 @@ static struct cdev macvtap_cdev;
 static const struct proto_ops macvtap_socket_ops;
 
 #define TUN_OFFLOADS (NETIF_F_HW_CSUM | NETIF_F_TSO_ECN | NETIF_F_TSO | \
-                     NETIF_F_TSO6)
+                     NETIF_F_TSO6 | NETIF_F_UFO)
 #define RX_OFFLOADS (NETIF_F_GRO | NETIF_F_LRO)
 #define TAP_FEATURES (NETIF_F_GSO | NETIF_F_SG)
 
@@ -570,8 +570,6 @@ static int macvtap_skb_from_vnet_hdr(struct sk_buff *skb,
                        gso_type = SKB_GSO_TCPV6;
                        break;
                case VIRTIO_NET_HDR_GSO_UDP:
-                       pr_warn_once("macvtap: %s: using disabled UFO feature; please fix this program\n",
-                                    current->comm);
                        gso_type = SKB_GSO_UDP;
                        if (skb->protocol == htons(ETH_P_IPV6))
                                ipv6_proxy_select_ident(skb);
@@ -619,6 +617,8 @@ static void macvtap_skb_to_vnet_hdr(const struct sk_buff *skb,
                        vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
                else if (sinfo->gso_type & SKB_GSO_TCPV6)
                        vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
+               else if (sinfo->gso_type & SKB_GSO_UDP)
+                       vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_UDP;
                else
                        BUG();
                if (sinfo->gso_type & SKB_GSO_TCP_ECN)
@@ -629,6 +629,8 @@ static void macvtap_skb_to_vnet_hdr(const struct sk_buff *skb,
        if (skb->ip_summed == CHECKSUM_PARTIAL) {
                vnet_hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
                vnet_hdr->csum_start = skb_checksum_start_offset(skb);
+               if (vlan_tx_tag_present(skb))
+                       vnet_hdr->csum_start += VLAN_HLEN;
                vnet_hdr->csum_offset = skb->csum_offset;
        } else if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
                vnet_hdr->flags = VIRTIO_NET_HDR_F_DATA_VALID;
@@ -953,6 +955,9 @@ static int set_offload(struct macvtap_queue *q, unsigned long arg)
                        if (arg & TUN_F_TSO6)
                                feature_mask |= NETIF_F_TSO6;
                }
+
+               if (arg & TUN_F_UFO)
+                       feature_mask |= NETIF_F_UFO;
        }
 
        /* tun/tap driver inverts the usage for TSO offloads, where
@@ -963,7 +968,7 @@ static int set_offload(struct macvtap_queue *q, unsigned long arg)
         * When user space turns off TSO, we turn off GSO/LRO so that
         * user-space will not receive TSO frames.
         */
-       if (feature_mask & (NETIF_F_TSO | NETIF_F_TSO6))
+       if (feature_mask & (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_UFO))
                features |= RX_OFFLOADS;
        else
                features &= ~RX_OFFLOADS;
@@ -1064,7 +1069,7 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd,
        case TUNSETOFFLOAD:
                /* let the user check for future flags */
                if (arg & ~(TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 |
-                           TUN_F_TSO_ECN))
+                           TUN_F_TSO_ECN | TUN_F_UFO))
                        return -EINVAL;
 
                rtnl_lock();
index 1aff970..1dc628f 100644 (file)
@@ -506,7 +506,9 @@ static int pptp_getname(struct socket *sock, struct sockaddr *uaddr,
        int len = sizeof(struct sockaddr_pppox);
        struct sockaddr_pppox sp;
 
-       sp.sa_family      = AF_PPPOX;
+       memset(&sp.sa_addr, 0, sizeof(sp.sa_addr));
+
+       sp.sa_family    = AF_PPPOX;
        sp.sa_protocol  = PX_PROTO_PPTP;
        sp.sa_addr.pptp = pppox_sk(sock->sk)->proto.pptp.src_addr;
 
index 2c8b1c2..ec63314 100644 (file)
@@ -175,7 +175,7 @@ struct tun_struct {
        struct net_device       *dev;
        netdev_features_t       set_features;
 #define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \
-                         NETIF_F_TSO6)
+                         NETIF_F_TSO6|NETIF_F_UFO)
 
        int                     vnet_hdr_sz;
        int                     sndbuf;
@@ -1153,20 +1153,10 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
                        skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
                        break;
                case VIRTIO_NET_HDR_GSO_UDP:
-               {
-                       static bool warned;
-
-                       if (!warned) {
-                               warned = true;
-                               netdev_warn(tun->dev,
-                                           "%s: using disabled UFO feature; please fix this program\n",
-                                           current->comm);
-                       }
                        skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
                        if (skb->protocol == htons(ETH_P_IPV6))
                                ipv6_proxy_select_ident(skb);
                        break;
-               }
                default:
                        tun->dev->stats.rx_frame_errors++;
                        kfree_skb(skb);
@@ -1236,6 +1226,10 @@ static ssize_t tun_put_user(struct tun_struct *tun,
        struct tun_pi pi = { 0, skb->protocol };
        ssize_t total = 0;
        int vlan_offset = 0, copied;
+       int vlan_hlen = 0;
+
+       if (vlan_tx_tag_present(skb))
+               vlan_hlen = VLAN_HLEN;
 
        if (!(tun->flags & TUN_NO_PI)) {
                if ((len -= sizeof(pi)) < 0)
@@ -1266,6 +1260,8 @@ static ssize_t tun_put_user(struct tun_struct *tun,
                                gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
                        else if (sinfo->gso_type & SKB_GSO_TCPV6)
                                gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
+                       else if (sinfo->gso_type & SKB_GSO_UDP)
+                               gso.gso_type = VIRTIO_NET_HDR_GSO_UDP;
                        else {
                                pr_err("unexpected GSO type: "
                                       "0x%x, gso_size %d, hdr_len %d\n",
@@ -1285,7 +1281,8 @@ static ssize_t tun_put_user(struct tun_struct *tun,
 
                if (skb->ip_summed == CHECKSUM_PARTIAL) {
                        gso.flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
-                       gso.csum_start = skb_checksum_start_offset(skb);
+                       gso.csum_start = skb_checksum_start_offset(skb) +
+                                        vlan_hlen;
                        gso.csum_offset = skb->csum_offset;
                } else if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
                        gso.flags = VIRTIO_NET_HDR_F_DATA_VALID;
@@ -1298,10 +1295,9 @@ static ssize_t tun_put_user(struct tun_struct *tun,
        }
 
        copied = total;
-       total += skb->len;
-       if (!vlan_tx_tag_present(skb)) {
-               len = min_t(int, skb->len, len);
-       } else {
+       len = min_t(int, skb->len + vlan_hlen, len);
+       total += skb->len + vlan_hlen;
+       if (vlan_hlen) {
                int copy, ret;
                struct {
                        __be16 h_vlan_proto;
@@ -1312,8 +1308,6 @@ static ssize_t tun_put_user(struct tun_struct *tun,
                veth.h_vlan_TCI = htons(vlan_tx_tag_get(skb));
 
                vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto);
-               len = min_t(int, skb->len + VLAN_HLEN, len);
-               total += VLAN_HLEN;
 
                copy = min_t(int, vlan_offset, len);
                ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy);
@@ -1795,6 +1789,11 @@ static int set_offload(struct tun_struct *tun, unsigned long arg)
                                features |= NETIF_F_TSO6;
                        arg &= ~(TUN_F_TSO4|TUN_F_TSO6);
                }
+
+               if (arg & TUN_F_UFO) {
+                       features |= NETIF_F_UFO;
+                       arg &= ~TUN_F_UFO;
+               }
        }
 
        /* This gives the user a way to test for new features in future by
index d510f1d..db21af8 100644 (file)
@@ -769,6 +769,7 @@ static const struct usb_device_id products[] = {
        {QMI_FIXED_INTF(0x413c, 0x81a4, 8)},    /* Dell Wireless 5570e HSPA+ (42Mbps) Mobile Broadband Card */
        {QMI_FIXED_INTF(0x413c, 0x81a8, 8)},    /* Dell Wireless 5808 Gobi(TM) 4G LTE Mobile Broadband Card */
        {QMI_FIXED_INTF(0x413c, 0x81a9, 8)},    /* Dell Wireless 5808e Gobi(TM) 4G LTE Mobile Broadband Card */
+       {QMI_FIXED_INTF(0x03f0, 0x581d, 4)},    /* HP lt4112 LTE/HSPA+ Gobi 4G Module (Huawei me906e) */
 
        /* 4. Gobi 1000 devices */
        {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)},    /* Acer Gobi Modem Device */
index 07a3255..841b608 100644 (file)
@@ -496,17 +496,8 @@ static void receive_buf(struct receive_queue *rq, void *buf, unsigned int len)
                        skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
                        break;
                case VIRTIO_NET_HDR_GSO_UDP:
-               {
-                       static bool warned;
-
-                       if (!warned) {
-                               warned = true;
-                               netdev_warn(dev,
-                                           "host using disabled UFO feature; please fix it\n");
-                       }
                        skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
                        break;
-               }
                case VIRTIO_NET_HDR_GSO_TCPV6:
                        skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
                        break;
@@ -845,6 +836,8 @@ static int xmit_skb(struct send_queue *sq, struct sk_buff *skb)
                        hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
                else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
                        hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
+               else if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP)
+                       hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_UDP;
                else
                        BUG();
                if (skb_shinfo(skb)->gso_type & SKB_GSO_TCP_ECN)
@@ -1664,7 +1657,7 @@ static int virtnet_probe(struct virtio_device *vdev)
                        dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST;
 
                if (virtio_has_feature(vdev, VIRTIO_NET_F_GSO)) {
-                       dev->hw_features |= NETIF_F_TSO
+                       dev->hw_features |= NETIF_F_TSO | NETIF_F_UFO
                                | NETIF_F_TSO_ECN | NETIF_F_TSO6;
                }
                /* Individual feature bits: what can host handle? */
@@ -1674,9 +1667,11 @@ static int virtnet_probe(struct virtio_device *vdev)
                        dev->hw_features |= NETIF_F_TSO6;
                if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_ECN))
                        dev->hw_features |= NETIF_F_TSO_ECN;
+               if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_UFO))
+                       dev->hw_features |= NETIF_F_UFO;
 
                if (gso)
-                       dev->features |= dev->hw_features & NETIF_F_ALL_TSO;
+                       dev->features |= dev->hw_features & (NETIF_F_ALL_TSO|NETIF_F_UFO);
                /* (!csum && gso) case will be fixed by register_netdev() */
        }
        if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_CSUM))
@@ -1716,7 +1711,8 @@ static int virtnet_probe(struct virtio_device *vdev)
        /* If we can receive ANY GSO packets, we must allocate large ones. */
        if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) ||
            virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6) ||
-           virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN))
+           virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN) ||
+           virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_UFO))
                vi->big_packets = true;
 
        if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF))
@@ -1907,9 +1903,9 @@ static struct virtio_device_id id_table[] = {
 static unsigned int features[] = {
        VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GUEST_CSUM,
        VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC,
-       VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_TSO6,
+       VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6,
        VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6,
-       VIRTIO_NET_F_GUEST_ECN,
+       VIRTIO_NET_F_GUEST_ECN, VIRTIO_NET_F_GUEST_UFO,
        VIRTIO_NET_F_MRG_RXBUF, VIRTIO_NET_F_STATUS, VIRTIO_NET_F_CTRL_VQ,
        VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN,
        VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_MQ,
index 0704a04..5441b49 100644 (file)
@@ -279,13 +279,15 @@ static inline struct vxlan_rdst *first_remote_rtnl(struct vxlan_fdb *fdb)
        return list_first_entry(&fdb->remotes, struct vxlan_rdst, list);
 }
 
-/* Find VXLAN socket based on network namespace and UDP port */
-static struct vxlan_sock *vxlan_find_sock(struct net *net, __be16 port)
+/* Find VXLAN socket based on network namespace, address family and UDP port */
+static struct vxlan_sock *vxlan_find_sock(struct net *net,
+                                         sa_family_t family, __be16 port)
 {
        struct vxlan_sock *vs;
 
        hlist_for_each_entry_rcu(vs, vs_head(net, port), hlist) {
-               if (inet_sk(vs->sock->sk)->inet_sport == port)
+               if (inet_sk(vs->sock->sk)->inet_sport == port &&
+                   inet_sk(vs->sock->sk)->sk.sk_family == family)
                        return vs;
        }
        return NULL;
@@ -304,11 +306,12 @@ static struct vxlan_dev *vxlan_vs_find_vni(struct vxlan_sock *vs, u32 id)
 }
 
 /* Look up VNI in a per net namespace table */
-static struct vxlan_dev *vxlan_find_vni(struct net *net, u32 id, __be16 port)
+static struct vxlan_dev *vxlan_find_vni(struct net *net, u32 id,
+                                       sa_family_t family, __be16 port)
 {
        struct vxlan_sock *vs;
 
-       vs = vxlan_find_sock(net, port);
+       vs = vxlan_find_sock(net, family, port);
        if (!vs)
                return NULL;
 
@@ -1872,7 +1875,8 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
                        struct vxlan_dev *dst_vxlan;
 
                        ip_rt_put(rt);
-                       dst_vxlan = vxlan_find_vni(dev_net(dev), vni, dst_port);
+                       dst_vxlan = vxlan_find_vni(dev_net(dev), vni,
+                                                  dst->sa.sa_family, dst_port);
                        if (!dst_vxlan)
                                goto tx_error;
                        vxlan_encap_bypass(skb, vxlan, dst_vxlan);
@@ -1925,7 +1929,8 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
                        struct vxlan_dev *dst_vxlan;
 
                        dst_release(ndst);
-                       dst_vxlan = vxlan_find_vni(dev_net(dev), vni, dst_port);
+                       dst_vxlan = vxlan_find_vni(dev_net(dev), vni,
+                                                  dst->sa.sa_family, dst_port);
                        if (!dst_vxlan)
                                goto tx_error;
                        vxlan_encap_bypass(skb, vxlan, dst_vxlan);
@@ -2083,6 +2088,7 @@ static int vxlan_init(struct net_device *dev)
 {
        struct vxlan_dev *vxlan = netdev_priv(dev);
        struct vxlan_net *vn = net_generic(dev_net(dev), vxlan_net_id);
+       bool ipv6 = vxlan->flags & VXLAN_F_IPV6;
        struct vxlan_sock *vs;
        int i;
 
@@ -2098,7 +2104,8 @@ static int vxlan_init(struct net_device *dev)
 
 
        spin_lock(&vn->sock_lock);
-       vs = vxlan_find_sock(dev_net(dev), vxlan->dst_port);
+       vs = vxlan_find_sock(dev_net(dev), ipv6 ? AF_INET6 : AF_INET,
+                            vxlan->dst_port);
        if (vs) {
                /* If we have a socket with same port already, reuse it */
                atomic_inc(&vs->refcnt);
@@ -2566,7 +2573,7 @@ struct vxlan_sock *vxlan_sock_add(struct net *net, __be16 port,
                return vs;
 
        spin_lock(&vn->sock_lock);
-       vs = vxlan_find_sock(net, port);
+       vs = vxlan_find_sock(net, ipv6 ? AF_INET6 : AF_INET, port);
        if (vs) {
                if (vs->rcv == rcv)
                        atomic_inc(&vs->refcnt);
@@ -2712,7 +2719,8 @@ static int vxlan_newlink(struct net *net, struct net_device *dev,
        if (data[IFLA_VXLAN_PORT])
                vxlan->dst_port = nla_get_be16(data[IFLA_VXLAN_PORT]);
 
-       if (vxlan_find_vni(net, vni, vxlan->dst_port)) {
+       if (vxlan_find_vni(net, vni, use_ipv6 ? AF_INET6 : AF_INET,
+                          vxlan->dst_port)) {
                pr_info("duplicate VNI %u\n", vni);
                return -EEXIST;
        }
index 992bc02..692184d 100644 (file)
@@ -1,5 +1 @@
-
 obj-$(CONFIG_WIMAX_I2400M)     += i2400m/
-
-# (from Sam Ravnborg) force kbuild to create built-in.o
-obj- := dummy.o
index 09facba..390c2de 100644 (file)
@@ -647,6 +647,19 @@ static void ar9003_hw_override_ini(struct ath_hw *ah)
                ah->enabled_cals |= TX_CL_CAL;
        else
                ah->enabled_cals &= ~TX_CL_CAL;
+
+       if (AR_SREV_9340(ah) || AR_SREV_9531(ah) || AR_SREV_9550(ah)) {
+               if (ah->is_clk_25mhz) {
+                       REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x17c << 1);
+                       REG_WRITE(ah, AR_SLP32_MODE, 0x0010f3d7);
+                       REG_WRITE(ah, AR_SLP32_INC, 0x0001e7ae);
+               } else {
+                       REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x261 << 1);
+                       REG_WRITE(ah, AR_SLP32_MODE, 0x0010f400);
+                       REG_WRITE(ah, AR_SLP32_INC, 0x0001e800);
+               }
+               udelay(100);
+       }
 }
 
 static void ar9003_hw_prog_ini(struct ath_hw *ah,
index 9078a6c..dcc1494 100644 (file)
@@ -858,19 +858,6 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
        udelay(RTC_PLL_SETTLE_DELAY);
 
        REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK);
-
-       if (AR_SREV_9340(ah) || AR_SREV_9550(ah)) {
-               if (ah->is_clk_25mhz) {
-                       REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x17c << 1);
-                       REG_WRITE(ah, AR_SLP32_MODE, 0x0010f3d7);
-                       REG_WRITE(ah,  AR_SLP32_INC, 0x0001e7ae);
-               } else {
-                       REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x261 << 1);
-                       REG_WRITE(ah, AR_SLP32_MODE, 0x0010f400);
-                       REG_WRITE(ah,  AR_SLP32_INC, 0x0001e800);
-               }
-               udelay(100);
-       }
 }
 
 static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
index 1f065cf..d090ed7 100644 (file)
@@ -514,6 +514,7 @@ enum iwl_trans_state {
  *     Set during transport allocation.
  * @hw_id_str: a string with info about HW ID. Set during transport allocation.
  * @pm_support: set to true in start_hw if link pm is supported
+ * @ltr_enabled: set to true if the LTR is enabled
  * @dev_cmd_pool: pool for Tx cmd allocation - for internal use only.
  *     The user should use iwl_trans_{alloc,free}_tx_cmd.
  * @dev_cmd_headroom: room needed for the transport's private use before the
@@ -539,6 +540,7 @@ struct iwl_trans {
        u8 rx_mpdu_cmd, rx_mpdu_cmd_hdr_size;
 
        bool pm_support;
+       bool ltr_enabled;
 
        /* The following fields are internal only */
        struct kmem_cache *dev_cmd_pool;
index 884c087..fa66471 100644 (file)
 
 /* Power Management Commands, Responses, Notifications */
 
+/**
+ * enum iwl_ltr_config_flags - masks for LTR config command flags
+ * @LTR_CFG_FLAG_FEATURE_ENABLE: Feature operational status
+ * @LTR_CFG_FLAG_HW_DIS_ON_SHADOW_REG_ACCESS: allow LTR change on shadow
+ *     memory access
+ * @LTR_CFG_FLAG_HW_EN_SHRT_WR_THROUGH: allow LTR msg send on ANY LTR
+ *     reg change
+ * @LTR_CFG_FLAG_HW_DIS_ON_D0_2_D3: allow LTR msg send on transition from
+ *     D0 to D3
+ * @LTR_CFG_FLAG_SW_SET_SHORT: fixed static short LTR register
+ * @LTR_CFG_FLAG_SW_SET_LONG: fixed static short LONG register
+ * @LTR_CFG_FLAG_DENIE_C10_ON_PD: allow going into C10 on PD
+ */
+enum iwl_ltr_config_flags {
+       LTR_CFG_FLAG_FEATURE_ENABLE = BIT(0),
+       LTR_CFG_FLAG_HW_DIS_ON_SHADOW_REG_ACCESS = BIT(1),
+       LTR_CFG_FLAG_HW_EN_SHRT_WR_THROUGH = BIT(2),
+       LTR_CFG_FLAG_HW_DIS_ON_D0_2_D3 = BIT(3),
+       LTR_CFG_FLAG_SW_SET_SHORT = BIT(4),
+       LTR_CFG_FLAG_SW_SET_LONG = BIT(5),
+       LTR_CFG_FLAG_DENIE_C10_ON_PD = BIT(6),
+};
+
+/**
+ * struct iwl_ltr_config_cmd - configures the LTR
+ * @flags: See %enum iwl_ltr_config_flags
+ */
+struct iwl_ltr_config_cmd {
+       __le32 flags;
+       __le32 static_long;
+       __le32 static_short;
+} __packed;
+
 /* Radio LP RX Energy Threshold measured in dBm */
 #define POWER_LPRX_RSSI_THRESHOLD      75
 #define POWER_LPRX_RSSI_THRESHOLD_MAX  94
 #define POWER_LPRX_RSSI_THRESHOLD_MIN  30
 
 /**
- * enum iwl_scan_flags - masks for power table command flags
+ * enum iwl_power_flags - masks for power table command flags
  * @POWER_FLAGS_POWER_SAVE_ENA_MSK: '1' Allow to save power by turning off
  *             receiver and transmitter. '0' - does not allow.
  * @POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK: '0' Driver disables power management,
index d0a0477..d8948aa 100644 (file)
@@ -142,6 +142,7 @@ enum {
        /* Power - legacy power table command */
        POWER_TABLE_CMD = 0x77,
        PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION = 0x78,
+       LTR_CONFIG = 0xee,
 
        /* Thermal Throttling*/
        REPLY_THERMAL_MNG_BACKOFF = 0x7e,
index c03d395..2ef344f 100644 (file)
@@ -439,6 +439,15 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
                        goto error;
        }
 
+       if (mvm->trans->ltr_enabled) {
+               struct iwl_ltr_config_cmd cmd = {
+                       .flags = cpu_to_le32(LTR_CFG_FLAG_FEATURE_ENABLE),
+               };
+
+               WARN_ON(iwl_mvm_send_cmd_pdu(mvm, LTR_CONFIG, 0,
+                                            sizeof(cmd), &cmd));
+       }
+
        ret = iwl_mvm_power_update_device_mode(mvm);
        if (ret)
                goto error;
index a3d43de..dbff7f0 100644 (file)
@@ -313,6 +313,7 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {
        CMD(REPLY_BEACON_FILTERING_CMD),
        CMD(REPLY_THERMAL_MNG_BACKOFF),
        CMD(MAC_PM_POWER_TABLE),
+       CMD(LTR_CONFIG),
        CMD(BT_COEX_CI),
        CMD(PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION),
 };
index 16be0c0..fb62927 100644 (file)
@@ -94,6 +94,7 @@ static void iwl_pcie_apm_config(struct iwl_trans *trans)
 {
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
        u16 lctl;
+       u16 cap;
 
        /*
         * HW bug W/A for instability in PCIe bus L0S->L1 transition.
@@ -104,16 +105,17 @@ static void iwl_pcie_apm_config(struct iwl_trans *trans)
         *    power savings, even without L1.
         */
        pcie_capability_read_word(trans_pcie->pci_dev, PCI_EXP_LNKCTL, &lctl);
-       if (lctl & PCI_EXP_LNKCTL_ASPM_L1) {
-               /* L1-ASPM enabled; disable(!) L0S */
+       if (lctl & PCI_EXP_LNKCTL_ASPM_L1)
                iwl_set_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
-               dev_info(trans->dev, "L1 Enabled; Disabling L0S\n");
-       } else {
-               /* L1-ASPM disabled; enable(!) L0S */
+       else
                iwl_clear_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
-               dev_info(trans->dev, "L1 Disabled; Enabling L0S\n");
-       }
        trans->pm_support = !(lctl & PCI_EXP_LNKCTL_ASPM_L0S);
+
+       pcie_capability_read_word(trans_pcie->pci_dev, PCI_EXP_DEVCTL2, &cap);
+       trans->ltr_enabled = cap & PCI_EXP_DEVCTL2_LTR_EN;
+       dev_info(trans->dev, "L1 %sabled - LTR %sabled\n",
+                (lctl & PCI_EXP_LNKCTL_ASPM_L1) ? "En" : "Dis",
+                trans->ltr_enabled ? "En" : "Dis");
 }
 
 /*
index 69d4c31..505ff60 100644 (file)
@@ -1974,7 +1974,7 @@ static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2,
        if (err != 0) {
                printk(KERN_DEBUG "mac80211_hwsim: device_bind_driver failed (%d)\n",
                       err);
-               goto failed_hw;
+               goto failed_bind;
        }
 
        skb_queue_head_init(&data->pending);
@@ -2157,6 +2157,8 @@ static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2,
        return idx;
 
 failed_hw:
+       device_release_driver(data->dev);
+failed_bind:
        device_unregister(data->dev);
 failed_drvdata:
        ieee80211_free_hw(hw);
index 5642ccc..22d49d5 100644 (file)
@@ -158,55 +158,29 @@ void rt2x00queue_align_frame(struct sk_buff *skb)
        skb_trim(skb, frame_length);
 }
 
-void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length)
+/*
+ * H/W needs L2 padding between the header and the paylod if header size
+ * is not 4 bytes aligned.
+ */
+void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int hdr_len)
 {
-       unsigned int payload_length = skb->len - header_length;
-       unsigned int header_align = ALIGN_SIZE(skb, 0);
-       unsigned int payload_align = ALIGN_SIZE(skb, header_length);
-       unsigned int l2pad = payload_length ? L2PAD_SIZE(header_length) : 0;
+       unsigned int l2pad = (skb->len > hdr_len) ? L2PAD_SIZE(hdr_len) : 0;
 
-       /*
-        * Adjust the header alignment if the payload needs to be moved more
-        * than the header.
-        */
-       if (payload_align > header_align)
-               header_align += 4;
-
-       /* There is nothing to do if no alignment is needed */
-       if (!header_align)
+       if (!l2pad)
                return;
 
-       /* Reserve the amount of space needed in front of the frame */
-       skb_push(skb, header_align);
-
-       /*
-        * Move the header.
-        */
-       memmove(skb->data, skb->data + header_align, header_length);
-
-       /* Move the payload, if present and if required */
-       if (payload_length && payload_align)
-               memmove(skb->data + header_length + l2pad,
-                       skb->data + header_length + l2pad + payload_align,
-                       payload_length);
-
-       /* Trim the skb to the correct size */
-       skb_trim(skb, header_length + l2pad + payload_length);
+       skb_push(skb, l2pad);
+       memmove(skb->data, skb->data + l2pad, hdr_len);
 }
 
-void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int header_length)
+void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int hdr_len)
 {
-       /*
-        * L2 padding is only present if the skb contains more than just the
-        * IEEE 802.11 header.
-        */
-       unsigned int l2pad = (skb->len > header_length) ?
-                               L2PAD_SIZE(header_length) : 0;
+       unsigned int l2pad = (skb->len > hdr_len) ? L2PAD_SIZE(hdr_len) : 0;
 
        if (!l2pad)
                return;
 
-       memmove(skb->data + l2pad, skb->data, header_length);
+       memmove(skb->data + l2pad, skb->data, hdr_len);
        skb_pull(skb, l2pad);
 }
 
index 1a54f1f..005c657 100644 (file)
@@ -401,6 +401,21 @@ static struct of_bus *of_match_bus(struct device_node *np)
        return NULL;
 }
 
+static int of_empty_ranges_quirk(void)
+{
+       if (IS_ENABLED(CONFIG_PPC)) {
+               /* To save cycles, we cache the result */
+               static int quirk_state = -1;
+
+               if (quirk_state < 0)
+                       quirk_state =
+                               of_machine_is_compatible("Power Macintosh") ||
+                               of_machine_is_compatible("MacRISC");
+               return quirk_state;
+       }
+       return false;
+}
+
 static int of_translate_one(struct device_node *parent, struct of_bus *bus,
                            struct of_bus *pbus, __be32 *addr,
                            int na, int ns, int pna, const char *rprop)
@@ -426,12 +441,10 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
         * This code is only enabled on powerpc. --gcl
         */
        ranges = of_get_property(parent, rprop, &rlen);
-#if !defined(CONFIG_PPC)
-       if (ranges == NULL) {
+       if (ranges == NULL && !of_empty_ranges_quirk()) {
                pr_err("OF: no ranges; cannot translate\n");
                return 1;
        }
-#endif /* !defined(CONFIG_PPC) */
        if (ranges == NULL || rlen == 0) {
                offset = of_read_number(addr, na);
                memset(addr, 0, pna * 4);
index d43b18e..c04d2e0 100644 (file)
@@ -17,6 +17,7 @@
  *      as published by the Free Software Foundation; either version
  *      2 of the License, or (at your option) any later version.
  */
+#include <linux/console.h>
 #include <linux/ctype.h>
 #include <linux/cpu.h>
 #include <linux/module.h>
@@ -1808,9 +1809,9 @@ void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align))
                of_chosen = of_find_node_by_path("/chosen@0");
 
        if (of_chosen) {
-               const char *name;
-
-               name = of_get_property(of_chosen, "linux,stdout-path", NULL);
+               const char *name = of_get_property(of_chosen, "stdout-path", NULL);
+               if (!name)
+                       name = of_get_property(of_chosen, "linux,stdout-path", NULL);
                if (name)
                        of_stdout = of_find_node_by_path(name);
        }
@@ -1926,20 +1927,22 @@ const char *of_prop_next_string(struct property *prop, const char *cur)
 EXPORT_SYMBOL_GPL(of_prop_next_string);
 
 /**
- * of_device_is_stdout_path - check if a device node matches the
- *                            linux,stdout-path property
- *
- * Check if this device node matches the linux,stdout-path property
- * in the chosen node. return true if yes, false otherwise.
+ * of_console_check() - Test and setup console for DT setup
+ * @dn - Pointer to device node
+ * @name - Name to use for preferred console without index. ex. "ttyS"
+ * @index - Index to use for preferred console.
+ *
+ * Check if the given device node matches the stdout-path property in the
+ * /chosen node. If it does then register it as the preferred console and return
+ * TRUE. Otherwise return FALSE.
  */
-int of_device_is_stdout_path(struct device_node *dn)
+bool of_console_check(struct device_node *dn, char *name, int index)
 {
-       if (!of_stdout)
+       if (!dn || dn != of_stdout || console_set_on_cmdline)
                return false;
-
-       return of_stdout == dn;
+       return !add_preferred_console(name, index, NULL);
 }
-EXPORT_SYMBOL_GPL(of_device_is_stdout_path);
+EXPORT_SYMBOL_GPL(of_console_check);
 
 /**
  *     of_find_next_cache_node - Find a node's subsidiary cache
@@ -1973,6 +1976,34 @@ struct device_node *of_find_next_cache_node(const struct device_node *np)
 }
 
 /**
+ * of_graph_parse_endpoint() - parse common endpoint node properties
+ * @node: pointer to endpoint device_node
+ * @endpoint: pointer to the OF endpoint data structure
+ *
+ * The caller should hold a reference to @node.
+ */
+int of_graph_parse_endpoint(const struct device_node *node,
+                           struct of_endpoint *endpoint)
+{
+       struct device_node *port_node = of_get_parent(node);
+
+       memset(endpoint, 0, sizeof(*endpoint));
+
+       endpoint->local_node = node;
+       /*
+        * It doesn't matter whether the two calls below succeed.
+        * If they don't then the default value 0 is used.
+        */
+       of_property_read_u32(port_node, "reg", &endpoint->port);
+       of_property_read_u32(node, "reg", &endpoint->id);
+
+       of_node_put(port_node);
+
+       return 0;
+}
+EXPORT_SYMBOL(of_graph_parse_endpoint);
+
+/**
  * of_graph_get_next_endpoint() - get next endpoint node
  * @parent: pointer to the parent device node
  * @prev: previous endpoint node, or NULL to get first
index ceec147..3ef854f 100644 (file)
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/of_pci.h>
 #include <linux/pci.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/sizes.h>
 #include <linux/slab.h>
 
 /* AHB-PCI Bridge PCI communication registers */
 
 #define RCAR_PCI_INT_ENABLE_REG                (RCAR_AHBPCI_PCICOM_OFFSET + 0x20)
 #define RCAR_PCI_INT_STATUS_REG                (RCAR_AHBPCI_PCICOM_OFFSET + 0x24)
+#define RCAR_PCI_INT_SIGTABORT         (1 << 0)
+#define RCAR_PCI_INT_SIGRETABORT       (1 << 1)
+#define RCAR_PCI_INT_REMABORT          (1 << 2)
+#define RCAR_PCI_INT_PERR              (1 << 3)
+#define RCAR_PCI_INT_SIGSERR           (1 << 4)
+#define RCAR_PCI_INT_RESERR            (1 << 5)
+#define RCAR_PCI_INT_WIN1ERR           (1 << 12)
+#define RCAR_PCI_INT_WIN2ERR           (1 << 13)
 #define RCAR_PCI_INT_A                 (1 << 16)
 #define RCAR_PCI_INT_B                 (1 << 17)
 #define RCAR_PCI_INT_PME               (1 << 19)
+#define RCAR_PCI_INT_ALLERRORS (RCAR_PCI_INT_SIGTABORT         | \
+                               RCAR_PCI_INT_SIGRETABORT        | \
+                               RCAR_PCI_INT_SIGRETABORT        | \
+                               RCAR_PCI_INT_REMABORT           | \
+                               RCAR_PCI_INT_PERR               | \
+                               RCAR_PCI_INT_SIGSERR            | \
+                               RCAR_PCI_INT_RESERR             | \
+                               RCAR_PCI_INT_WIN1ERR            | \
+                               RCAR_PCI_INT_WIN2ERR)
 
 #define RCAR_AHB_BUS_CTR_REG           (RCAR_AHBPCI_PCICOM_OFFSET + 0x30)
 #define RCAR_AHB_BUS_MMODE_HTRANS      (1 << 0)
 
 #define RCAR_PCI_UNIT_REV_REG          (RCAR_AHBPCI_PCICOM_OFFSET + 0x48)
 
-/* Number of internal PCI controllers */
-#define RCAR_PCI_NR_CONTROLLERS                3
-
 struct rcar_pci_priv {
        struct device *dev;
        void __iomem *reg;
        struct resource io_res;
        struct resource mem_res;
        struct resource *cfg_res;
+       unsigned busnr;
        int irq;
+       unsigned long window_size;
 };
 
 /* PCI configuration space operations */
@@ -102,6 +120,10 @@ static void __iomem *rcar_pci_cfg_base(struct pci_bus *bus, unsigned int devfn,
        if (slot > 2)
                return NULL;
 
+       /* bridge logic only has registers to 0x40 */
+       if (slot == 0x0 && where >= 0x40)
+               return NULL;
+
        val = slot ? RCAR_AHBPCI_WIN1_DEVICE | RCAR_AHBPCI_WIN_CTR_CFG :
                     RCAR_AHBPCI_WIN1_HOST | RCAR_AHBPCI_WIN_CTR_CFG;
 
@@ -156,16 +178,61 @@ static int rcar_pci_write_config(struct pci_bus *bus, unsigned int devfn,
 }
 
 /* PCI interrupt mapping */
-static int __init rcar_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+static int rcar_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
        struct pci_sys_data *sys = dev->bus->sysdata;
        struct rcar_pci_priv *priv = sys->private_data;
+       int irq;
+
+       irq = of_irq_parse_and_map_pci(dev, slot, pin);
+       if (!irq)
+               irq = priv->irq;
+
+       return irq;
+}
+
+#ifdef CONFIG_PCI_DEBUG
+/* if debug enabled, then attach an error handler irq to the bridge */
+
+static irqreturn_t rcar_pci_err_irq(int irq, void *pw)
+{
+       struct rcar_pci_priv *priv = pw;
+       u32 status = ioread32(priv->reg + RCAR_PCI_INT_STATUS_REG);
+
+       if (status & RCAR_PCI_INT_ALLERRORS) {
+               dev_err(priv->dev, "error irq: status %08x\n", status);
+
+               /* clear the error(s) */
+               iowrite32(status & RCAR_PCI_INT_ALLERRORS,
+                         priv->reg + RCAR_PCI_INT_STATUS_REG);
+               return IRQ_HANDLED;
+       }
+
+       return IRQ_NONE;
+}
 
-       return priv->irq;
+static void rcar_pci_setup_errirq(struct rcar_pci_priv *priv)
+{
+       int ret;
+       u32 val;
+
+       ret = devm_request_irq(priv->dev, priv->irq, rcar_pci_err_irq,
+                              IRQF_SHARED, "error irq", priv);
+       if (ret) {
+               dev_err(priv->dev, "cannot claim IRQ for error handling\n");
+               return;
+       }
+
+       val = ioread32(priv->reg + RCAR_PCI_INT_ENABLE_REG);
+       val |= RCAR_PCI_INT_ALLERRORS;
+       iowrite32(val, priv->reg + RCAR_PCI_INT_ENABLE_REG);
 }
+#else
+static inline void rcar_pci_setup_errirq(struct rcar_pci_priv *priv) { }
+#endif
 
 /* PCI host controller setup */
-static int __init rcar_pci_setup(int nr, struct pci_sys_data *sys)
+static int rcar_pci_setup(int nr, struct pci_sys_data *sys)
 {
        struct rcar_pci_priv *priv = sys->private_data;
        void __iomem *reg = priv->reg;
@@ -183,10 +250,31 @@ static int __init rcar_pci_setup(int nr, struct pci_sys_data *sys)
        iowrite32(val, reg + RCAR_USBCTR_REG);
        udelay(4);
 
-       /* De-assert reset and set PCIAHB window1 size to 1GB */
+       /* De-assert reset and reset PCIAHB window1 size */
        val &= ~(RCAR_USBCTR_PCIAHB_WIN1_MASK | RCAR_USBCTR_PCICLK_MASK |
                 RCAR_USBCTR_USBH_RST | RCAR_USBCTR_PLL_RST);
-       iowrite32(val | RCAR_USBCTR_PCIAHB_WIN1_1G, reg + RCAR_USBCTR_REG);
+
+       /* Setup PCIAHB window1 size */
+       switch (priv->window_size) {
+       case SZ_2G:
+               val |= RCAR_USBCTR_PCIAHB_WIN1_2G;
+               break;
+       case SZ_1G:
+               val |= RCAR_USBCTR_PCIAHB_WIN1_1G;
+               break;
+       case SZ_512M:
+               val |= RCAR_USBCTR_PCIAHB_WIN1_512M;
+               break;
+       default:
+               pr_warn("unknown window size %ld - defaulting to 256M\n",
+                       priv->window_size);
+               priv->window_size = SZ_256M;
+               /* fall-through */
+       case SZ_256M:
+               val |= RCAR_USBCTR_PCIAHB_WIN1_256M;
+               break;
+       }
+       iowrite32(val, reg + RCAR_USBCTR_REG);
 
        /* Configure AHB master and slave modes */
        iowrite32(RCAR_AHB_BUS_MODE, reg + RCAR_AHB_BUS_CTR_REG);
@@ -197,7 +285,7 @@ static int __init rcar_pci_setup(int nr, struct pci_sys_data *sys)
               RCAR_PCI_ARBITER_PCIBP_MODE;
        iowrite32(val, reg + RCAR_PCI_ARBITER_CTR_REG);
 
-       /* PCI-AHB mapping: 0x40000000-0x80000000 */
+       /* PCI-AHB mapping: 0x40000000 base */
        iowrite32(0x40000000 | RCAR_PCIAHB_PREFETCH16,
                  reg + RCAR_PCIAHB_WIN1_CTR_REG);
 
@@ -224,10 +312,15 @@ static int __init rcar_pci_setup(int nr, struct pci_sys_data *sys)
        iowrite32(RCAR_PCI_INT_A | RCAR_PCI_INT_B | RCAR_PCI_INT_PME,
                  reg + RCAR_PCI_INT_ENABLE_REG);
 
+       if (priv->irq > 0)
+               rcar_pci_setup_errirq(priv);
+
        /* Add PCI resources */
        pci_add_resource(&sys->resources, &priv->io_res);
        pci_add_resource(&sys->resources, &priv->mem_res);
 
+       /* Setup bus number based on platform device id / of bus-range */
+       sys->busnr = priv->busnr;
        return 1;
 }
 
@@ -236,48 +329,13 @@ static struct pci_ops rcar_pci_ops = {
        .write  = rcar_pci_write_config,
 };
 
-static struct hw_pci rcar_hw_pci __initdata = {
-       .map_irq        = rcar_pci_map_irq,
-       .ops            = &rcar_pci_ops,
-       .setup          = rcar_pci_setup,
-};
-
-static int rcar_pci_count __initdata;
-
-static int __init rcar_pci_add_controller(struct rcar_pci_priv *priv)
-{
-       void **private_data;
-       int count;
-
-       if (rcar_hw_pci.nr_controllers < rcar_pci_count)
-               goto add_priv;
-
-       /* (Re)allocate private data pointer array if needed */
-       count = rcar_pci_count + RCAR_PCI_NR_CONTROLLERS;
-       private_data = kzalloc(count * sizeof(void *), GFP_KERNEL);
-       if (!private_data)
-               return -ENOMEM;
-
-       rcar_pci_count = count;
-       if (rcar_hw_pci.private_data) {
-               memcpy(private_data, rcar_hw_pci.private_data,
-                      rcar_hw_pci.nr_controllers * sizeof(void *));
-               kfree(rcar_hw_pci.private_data);
-       }
-
-       rcar_hw_pci.private_data = private_data;
-
-add_priv:
-       /* Add private data pointer to the array */
-       rcar_hw_pci.private_data[rcar_hw_pci.nr_controllers++] = priv;
-       return 0;
-}
-
-static int __init rcar_pci_probe(struct platform_device *pdev)
+static int rcar_pci_probe(struct platform_device *pdev)
 {
        struct resource *cfg_res, *mem_res;
        struct rcar_pci_priv *priv;
        void __iomem *reg;
+       struct hw_pci hw;
+       void *hw_private[1];
 
        cfg_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        reg = devm_ioremap_resource(&pdev->dev, cfg_res);
@@ -308,31 +366,60 @@ static int __init rcar_pci_probe(struct platform_device *pdev)
        priv->reg = reg;
        priv->dev = &pdev->dev;
 
-       return rcar_pci_add_controller(priv);
+       if (priv->irq < 0) {
+               dev_err(&pdev->dev, "no valid irq found\n");
+               return priv->irq;
+       }
+
+       priv->window_size = SZ_1G;
+
+       if (pdev->dev.of_node) {
+               struct resource busnr;
+               int ret;
+
+               ret = of_pci_parse_bus_range(pdev->dev.of_node, &busnr);
+               if (ret < 0) {
+                       dev_err(&pdev->dev, "failed to parse bus-range\n");
+                       return ret;
+               }
+
+               priv->busnr = busnr.start;
+               if (busnr.end != busnr.start)
+                       dev_warn(&pdev->dev, "only one bus number supported\n");
+       } else {
+               priv->busnr = pdev->id;
+       }
+
+       hw_private[0] = priv;
+       memset(&hw, 0, sizeof(hw));
+       hw.nr_controllers = ARRAY_SIZE(hw_private);
+       hw.private_data = hw_private;
+       hw.map_irq = rcar_pci_map_irq;
+       hw.ops = &rcar_pci_ops;
+       hw.setup = rcar_pci_setup;
+       pci_common_init_dev(&pdev->dev, &hw);
+       return 0;
 }
 
+static struct of_device_id rcar_pci_of_match[] = {
+       { .compatible = "renesas,pci-r8a7790", },
+       { .compatible = "renesas,pci-r8a7791", },
+       { },
+};
+
+MODULE_DEVICE_TABLE(of, rcar_pci_of_match);
+
 static struct platform_driver rcar_pci_driver = {
        .driver = {
                .name = "pci-rcar-gen2",
+               .owner = THIS_MODULE,
+               .suppress_bind_attrs = true,
+               .of_match_table = rcar_pci_of_match,
        },
+       .probe = rcar_pci_probe,
 };
 
-static int __init rcar_pci_init(void)
-{
-       int retval;
-
-       retval = platform_driver_probe(&rcar_pci_driver, rcar_pci_probe);
-       if (!retval)
-               pci_common_init(&rcar_hw_pci);
-
-       /* Private data pointer array is not needed any more */
-       kfree(rcar_hw_pci.private_data);
-       rcar_hw_pci.private_data = NULL;
-
-       return retval;
-}
-
-subsys_initcall(rcar_pci_init);
+module_platform_driver(rcar_pci_driver);
 
 MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("Renesas R-Car Gen2 internal PCI");
index fb02fc2..ced17f2 100644 (file)
@@ -599,6 +599,20 @@ error_attrs:
        return ret;
 }
 
+static int msi_verify_entries(struct pci_dev *dev)
+{
+       struct msi_desc *entry;
+
+       list_for_each_entry(entry, &dev->msi_list, list) {
+               if (!dev->no_64bit_msi || !entry->msg.address_hi)
+                       continue;
+               dev_err(&dev->dev, "Device has broken 64-bit MSI but arch"
+                       " tried to assign one above 4G\n");
+               return -EIO;
+       }
+       return 0;
+}
+
 /**
  * msi_capability_init - configure device's MSI capability structure
  * @dev: pointer to the pci_dev data structure of MSI device function
@@ -652,6 +666,13 @@ static int msi_capability_init(struct pci_dev *dev, int nvec)
                return ret;
        }
 
+       ret = msi_verify_entries(dev);
+       if (ret) {
+               msi_mask_irq(entry, mask, ~mask);
+               free_msi_irqs(dev);
+               return ret;
+       }
+
        ret = populate_msi_sysfs(dev);
        if (ret) {
                msi_mask_irq(entry, mask, ~mask);
@@ -767,6 +788,11 @@ static int msix_capability_init(struct pci_dev *dev,
        if (ret)
                goto out_avail;
 
+       /* Check if all MSI entries honor device restrictions */
+       ret = msi_verify_entries(dev);
+       if (ret)
+               goto out_free;
+
        /*
         * Some devices require MSI-X to be enabled before we can touch the
         * MSI-X registers.  We need to mask all the vectors to prevent
index 6e34498..34dff3a 100644 (file)
@@ -395,15 +395,16 @@ static void pci_read_bridge_mmio_pref(struct pci_bus *child)
 {
        struct pci_dev *dev = child->self;
        u16 mem_base_lo, mem_limit_lo;
-       unsigned long base, limit;
+       u64 base64, limit64;
+       dma_addr_t base, limit;
        struct pci_bus_region region;
        struct resource *res;
 
        res = child->resource[2];
        pci_read_config_word(dev, PCI_PREF_MEMORY_BASE, &mem_base_lo);
        pci_read_config_word(dev, PCI_PREF_MEMORY_LIMIT, &mem_limit_lo);
-       base = ((unsigned long) mem_base_lo & PCI_PREF_RANGE_MASK) << 16;
-       limit = ((unsigned long) mem_limit_lo & PCI_PREF_RANGE_MASK) << 16;
+       base64 = (mem_base_lo & PCI_PREF_RANGE_MASK) << 16;
+       limit64 = (mem_limit_lo & PCI_PREF_RANGE_MASK) << 16;
 
        if ((mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) {
                u32 mem_base_hi, mem_limit_hi;
@@ -417,18 +418,20 @@ static void pci_read_bridge_mmio_pref(struct pci_bus *child)
                 * this, just assume they are not being used.
                 */
                if (mem_base_hi <= mem_limit_hi) {
-#if BITS_PER_LONG == 64
-                       base |= ((unsigned long) mem_base_hi) << 32;
-                       limit |= ((unsigned long) mem_limit_hi) << 32;
-#else
-                       if (mem_base_hi || mem_limit_hi) {
-                               dev_err(&dev->dev, "can't handle 64-bit "
-                                       "address space for bridge\n");
-                               return;
-                       }
-#endif
+                       base64 |= (u64) mem_base_hi << 32;
+                       limit64 |= (u64) mem_limit_hi << 32;
                }
        }
+
+       base = (dma_addr_t) base64;
+       limit = (dma_addr_t) limit64;
+
+       if (base != base64) {
+               dev_err(&dev->dev, "can't handle bridge window above 4GB (bus address %#010llx)\n",
+                       (unsigned long long) base64);
+               return;
+       }
+
        if (base <= limit) {
                res->flags = (mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) |
                                         IORESOURCE_MEM | IORESOURCE_PREFETCH;
index c7a551c..1d75902 100644 (file)
@@ -28,6 +28,13 @@ config PHY_MVEBU_SATA
        depends on OF
        select GENERIC_PHY
 
+config PHY_RCAR_GEN2
+       tristate "Renesas R-Car generation 2 USB PHY driver"
+       depends on ARCH_SHMOBILE
+       depends on GENERIC_PHY
+       help
+         Support for USB PHY found on Renesas R-Car generation 2 SoCs.
+
 config OMAP_USB2
        tristate "OMAP USB2 PHY Driver"
        depends on ARCH_OMAP2PLUS
index b57c253..c6c34db 100644 (file)
@@ -7,5 +7,6 @@ obj-$(CONFIG_BCM_KONA_USB2_PHY)         += phy-bcm-kona-usb2.o
 obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO)      += phy-exynos-dp-video.o
 obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO)    += phy-exynos-mipi-video.o
 obj-$(CONFIG_PHY_MVEBU_SATA)           += phy-mvebu-sata.o
+obj-$(CONFIG_PHY_RCAR_GEN2)            += phy-rcar-gen2.o
 obj-$(CONFIG_OMAP_USB2)                        += phy-omap-usb2.o
 obj-$(CONFIG_TWL4030_USB)              += phy-twl4030-usb.o
index efc5c1a..f90ce8c 100644 (file)
@@ -117,7 +117,7 @@ static int bcm_kona_usb2_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, phy);
 
-       gphy = devm_phy_create(dev, &ops, NULL);
+       gphy = devm_phy_create(dev, NULL, &ops, NULL);
        if (IS_ERR(gphy))
                return PTR_ERR(gphy);
 
index 34d56f7..176c443 100644 (file)
@@ -64,6 +64,9 @@ static struct phy *phy_lookup(struct device *device, const char *port)
        class_dev_iter_init(&iter, phy_class, NULL, NULL);
        while ((dev = class_dev_iter_next(&iter))) {
                phy = to_phy(dev);
+
+               if (!phy->init_data)
+                       continue;
                count = phy->init_data->num_consumers;
                consumers = phy->init_data->consumers;
                while (count--) {
@@ -83,10 +86,15 @@ static struct phy *phy_lookup(struct device *device, const char *port)
 static struct phy_provider *of_phy_provider_lookup(struct device_node *node)
 {
        struct phy_provider *phy_provider;
+       struct device_node *child;
 
        list_for_each_entry(phy_provider, &phy_provider_list, list) {
                if (phy_provider->dev->of_node == node)
                        return phy_provider;
+
+               for_each_child_of_node(phy_provider->dev->of_node, child)
+                       if (child == node)
+                               return phy_provider;
        }
 
        return ERR_PTR(-EPROBE_DEFER);
@@ -368,13 +376,20 @@ struct phy *of_phy_simple_xlate(struct device *dev, struct of_phandle_args
        struct phy *phy;
        struct class_dev_iter iter;
        struct device_node *node = dev->of_node;
+       struct device_node *child;
 
        class_dev_iter_init(&iter, phy_class, NULL, NULL);
        while ((dev = class_dev_iter_next(&iter))) {
                phy = to_phy(dev);
-               if (node != phy->dev.of_node)
+               if (node != phy->dev.of_node) {
+                       for_each_child_of_node(node, child) {
+                               if (child == phy->dev.of_node)
+                                       goto phy_found;
+                       }
                        continue;
+               }
 
+phy_found:
                class_dev_iter_exit(&iter);
                return phy;
        }
@@ -501,13 +516,15 @@ EXPORT_SYMBOL_GPL(devm_phy_optional_get);
 /**
  * phy_create() - create a new phy
  * @dev: device that is creating the new phy
+ * @node: device node of the phy
  * @ops: function pointers for performing phy operations
  * @init_data: contains the list of PHY consumers or NULL
  *
  * Called to create a phy using phy framework.
  */
-struct phy *phy_create(struct device *dev, const struct phy_ops *ops,
-       struct phy_init_data *init_data)
+struct phy *phy_create(struct device *dev, struct device_node *node,
+                      const struct phy_ops *ops,
+                      struct phy_init_data *init_data)
 {
        int ret;
        int id;
@@ -532,7 +549,7 @@ struct phy *phy_create(struct device *dev, const struct phy_ops *ops,
 
        phy->dev.class = phy_class;
        phy->dev.parent = dev;
-       phy->dev.of_node = dev->of_node;
+       phy->dev.of_node = node ?: dev->of_node;
        phy->id = id;
        phy->ops = ops;
        phy->init_data = init_data;
@@ -565,6 +582,7 @@ EXPORT_SYMBOL_GPL(phy_create);
 /**
  * devm_phy_create() - create a new phy
  * @dev: device that is creating the new phy
+ * @node: device node of the phy
  * @ops: function pointers for performing phy operations
  * @init_data: contains the list of PHY consumers or NULL
  *
@@ -573,8 +591,9 @@ EXPORT_SYMBOL_GPL(phy_create);
  * On driver detach, release function is invoked on the devres data,
  * then, devres data is freed.
  */
-struct phy *devm_phy_create(struct device *dev, const struct phy_ops *ops,
-       struct phy_init_data *init_data)
+struct phy *devm_phy_create(struct device *dev, struct device_node *node,
+                           const struct phy_ops *ops,
+                           struct phy_init_data *init_data)
 {
        struct phy **ptr, *phy;
 
@@ -582,7 +601,7 @@ struct phy *devm_phy_create(struct device *dev, const struct phy_ops *ops,
        if (!ptr)
                return ERR_PTR(-ENOMEM);
 
-       phy = phy_create(dev, ops, init_data);
+       phy = phy_create(dev, node, ops, init_data);
        if (!IS_ERR(phy)) {
                *ptr = phy;
                devres_add(dev, ptr);
index 0786fef..94fc0d1 100644 (file)
@@ -76,7 +76,7 @@ static int exynos_dp_video_phy_probe(struct platform_device *pdev)
        if (IS_ERR(state->regs))
                return PTR_ERR(state->regs);
 
-       phy = devm_phy_create(dev, &exynos_dp_video_phy_ops, NULL);
+       phy = devm_phy_create(dev, NULL, &exynos_dp_video_phy_ops, NULL);
        if (IS_ERR(phy)) {
                dev_err(dev, "failed to create Display Port PHY\n");
                return PTR_ERR(phy);
index ff02668..e29a100 100644 (file)
@@ -135,7 +135,7 @@ static int exynos_mipi_video_phy_probe(struct platform_device *pdev)
        spin_lock_init(&state->slock);
 
        for (i = 0; i < EXYNOS_MIPI_PHYS_NUM; i++) {
-               struct phy *phy = devm_phy_create(dev,
+               struct phy *phy = devm_phy_create(dev, NULL,
                                        &exynos_mipi_video_phy_ops, NULL);
                if (IS_ERR(phy)) {
                        dev_err(dev, "failed to create PHY %d\n", i);
index d70ecd6..cc3c0e1 100644 (file)
@@ -99,7 +99,7 @@ static int phy_mvebu_sata_probe(struct platform_device *pdev)
        if (IS_ERR(priv->clk))
                return PTR_ERR(priv->clk);
 
-       phy = devm_phy_create(&pdev->dev, &phy_mvebu_sata_ops, NULL);
+       phy = devm_phy_create(&pdev->dev, NULL, &phy_mvebu_sata_ops, NULL);
        if (IS_ERR(phy))
                return PTR_ERR(phy);
 
index 7699752..b1685bf 100644 (file)
@@ -203,7 +203,7 @@ static int omap_usb2_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, phy);
        pm_runtime_enable(phy->dev);
 
-       generic_phy = devm_phy_create(phy->dev, &ops, NULL);
+       generic_phy = devm_phy_create(phy->dev, NULL, &ops, NULL);
        if (IS_ERR(generic_phy))
                return PTR_ERR(generic_phy);
 
diff --git a/drivers/phy/phy-rcar-gen2.c b/drivers/phy/phy-rcar-gen2.c
new file mode 100644 (file)
index 0000000..2793af1
--- /dev/null
@@ -0,0 +1,341 @@
+/*
+ * Renesas R-Car Gen2 PHY driver
+ *
+ * Copyright (C) 2014 Renesas Solutions Corp.
+ * Copyright (C) 2014 Cogent Embedded, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+
+#include <asm/cmpxchg.h>
+
+#define USBHS_LPSTS                    0x02
+#define USBHS_UGCTRL                   0x80
+#define USBHS_UGCTRL2                  0x84
+#define USBHS_UGSTS                    0x88    /* The manuals have 0x90 */
+
+/* Low Power Status register (LPSTS) */
+#define USBHS_LPSTS_SUSPM              0x4000
+
+/* USB General control register (UGCTRL) */
+#define USBHS_UGCTRL_CONNECT           0x00000004
+#define USBHS_UGCTRL_PLLRESET          0x00000001
+
+/* USB General control register 2 (UGCTRL2) */
+#define USBHS_UGCTRL2_USB2SEL          0x80000000
+#define USBHS_UGCTRL2_USB2SEL_PCI      0x00000000
+#define USBHS_UGCTRL2_USB2SEL_USB30    0x80000000
+#define USBHS_UGCTRL2_USB0SEL          0x00000030
+#define USBHS_UGCTRL2_USB0SEL_PCI      0x00000010
+#define USBHS_UGCTRL2_USB0SEL_HS_USB   0x00000030
+
+/* USB General status register (UGSTS) */
+#define USBHS_UGSTS_LOCK               0x00000300 /* The manuals have 0x3 */
+
+#define PHYS_PER_CHANNEL       2
+
+struct rcar_gen2_phy {
+       struct phy *phy;
+       struct rcar_gen2_channel *channel;
+       int number;
+       u32 select_value;
+};
+
+struct rcar_gen2_channel {
+       struct device_node *of_node;
+       struct rcar_gen2_phy_driver *drv;
+       struct rcar_gen2_phy phys[PHYS_PER_CHANNEL];
+       int selected_phy;
+       u32 select_mask;
+};
+
+struct rcar_gen2_phy_driver {
+       void __iomem *base;
+       struct clk *clk;
+       spinlock_t lock;
+       int num_channels;
+       struct rcar_gen2_channel *channels;
+};
+
+static int rcar_gen2_phy_init(struct phy *p)
+{
+       struct rcar_gen2_phy *phy = phy_get_drvdata(p);
+       struct rcar_gen2_channel *channel = phy->channel;
+       struct rcar_gen2_phy_driver *drv = channel->drv;
+       unsigned long flags;
+       u32 ugctrl2;
+
+       /*
+        * Try to acquire exclusive access to PHY.  The first driver calling
+        * phy_init()  on a given channel wins, and all attempts  to use another
+        * PHY on this channel will fail until phy_exit() is called by the first
+        * driver.   Achieving this with cmpxcgh() should be SMP-safe.
+        */
+       if (cmpxchg(&channel->selected_phy, -1, phy->number) != -1)
+               return -EBUSY;
+
+       clk_prepare_enable(drv->clk);
+
+       spin_lock_irqsave(&drv->lock, flags);
+       ugctrl2 = readl(drv->base + USBHS_UGCTRL2);
+       ugctrl2 &= ~channel->select_mask;
+       ugctrl2 |= phy->select_value;
+       writel(ugctrl2, drv->base + USBHS_UGCTRL2);
+       spin_unlock_irqrestore(&drv->lock, flags);
+       return 0;
+}
+
+static int rcar_gen2_phy_exit(struct phy *p)
+{
+       struct rcar_gen2_phy *phy = phy_get_drvdata(p);
+       struct rcar_gen2_channel *channel = phy->channel;
+
+       clk_disable_unprepare(channel->drv->clk);
+
+       channel->selected_phy = -1;
+
+       return 0;
+}
+
+static int rcar_gen2_phy_power_on(struct phy *p)
+{
+       struct rcar_gen2_phy *phy = phy_get_drvdata(p);
+       struct rcar_gen2_phy_driver *drv = phy->channel->drv;
+       void __iomem *base = drv->base;
+       unsigned long flags;
+       u32 value;
+       int err = 0, i;
+
+       /* Skip if it's not USBHS */
+       if (phy->select_value != USBHS_UGCTRL2_USB0SEL_HS_USB)
+               return 0;
+
+       spin_lock_irqsave(&drv->lock, flags);
+
+       /* Power on USBHS PHY */
+       value = readl(base + USBHS_UGCTRL);
+       value &= ~USBHS_UGCTRL_PLLRESET;
+       writel(value, base + USBHS_UGCTRL);
+
+       value = readw(base + USBHS_LPSTS);
+       value |= USBHS_LPSTS_SUSPM;
+       writew(value, base + USBHS_LPSTS);
+
+       for (i = 0; i < 20; i++) {
+               value = readl(base + USBHS_UGSTS);
+               if ((value & USBHS_UGSTS_LOCK) == USBHS_UGSTS_LOCK) {
+                       value = readl(base + USBHS_UGCTRL);
+                       value |= USBHS_UGCTRL_CONNECT;
+                       writel(value, base + USBHS_UGCTRL);
+                       goto out;
+               }
+               udelay(1);
+       }
+
+       /* Timed out waiting for the PLL lock */
+       err = -ETIMEDOUT;
+
+out:
+       spin_unlock_irqrestore(&drv->lock, flags);
+
+       return err;
+}
+
+static int rcar_gen2_phy_power_off(struct phy *p)
+{
+       struct rcar_gen2_phy *phy = phy_get_drvdata(p);
+       struct rcar_gen2_phy_driver *drv = phy->channel->drv;
+       void __iomem *base = drv->base;
+       unsigned long flags;
+       u32 value;
+
+       /* Skip if it's not USBHS */
+       if (phy->select_value != USBHS_UGCTRL2_USB0SEL_HS_USB)
+               return 0;
+
+       spin_lock_irqsave(&drv->lock, flags);
+
+       /* Power off USBHS PHY */
+       value = readl(base + USBHS_UGCTRL);
+       value &= ~USBHS_UGCTRL_CONNECT;
+       writel(value, base + USBHS_UGCTRL);
+
+       value = readw(base + USBHS_LPSTS);
+       value &= ~USBHS_LPSTS_SUSPM;
+       writew(value, base + USBHS_LPSTS);
+
+       value = readl(base + USBHS_UGCTRL);
+       value |= USBHS_UGCTRL_PLLRESET;
+       writel(value, base + USBHS_UGCTRL);
+
+       spin_unlock_irqrestore(&drv->lock, flags);
+
+       return 0;
+}
+
+static struct phy_ops rcar_gen2_phy_ops = {
+       .init           = rcar_gen2_phy_init,
+       .exit           = rcar_gen2_phy_exit,
+       .power_on       = rcar_gen2_phy_power_on,
+       .power_off      = rcar_gen2_phy_power_off,
+       .owner          = THIS_MODULE,
+};
+
+static const struct of_device_id rcar_gen2_phy_match_table[] = {
+       { .compatible = "renesas,usb-phy-r8a7790" },
+       { .compatible = "renesas,usb-phy-r8a7791" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, rcar_gen2_phy_match_table);
+
+static struct phy *rcar_gen2_phy_xlate(struct device *dev,
+                                      struct of_phandle_args *args)
+{
+       struct rcar_gen2_phy_driver *drv;
+       struct device_node *np = args->np;
+       int i;
+
+       if (!of_device_is_available(np)) {
+               dev_warn(dev, "Requested PHY is disabled\n");
+               return ERR_PTR(-ENODEV);
+       }
+
+       drv = dev_get_drvdata(dev);
+       if (!drv)
+               return ERR_PTR(-EINVAL);
+
+       for (i = 0; i < drv->num_channels; i++) {
+               if (np == drv->channels[i].of_node)
+                       break;
+       }
+
+       if (i >= drv->num_channels || args->args[0] >= 2)
+               return ERR_PTR(-ENODEV);
+
+       return drv->channels[i].phys[args->args[0]].phy;
+}
+
+static const u32 select_mask[] = {
+       [0]     = USBHS_UGCTRL2_USB0SEL,
+       [2]     = USBHS_UGCTRL2_USB2SEL,
+};
+
+static const u32 select_value[][PHYS_PER_CHANNEL] = {
+       [0]     = { USBHS_UGCTRL2_USB0SEL_PCI, USBHS_UGCTRL2_USB0SEL_HS_USB },
+       [2]     = { USBHS_UGCTRL2_USB2SEL_PCI, USBHS_UGCTRL2_USB2SEL_USB30 },
+};
+
+static int rcar_gen2_phy_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct rcar_gen2_phy_driver *drv;
+       struct phy_provider *provider;
+       struct device_node *np;
+       struct resource *res;
+       void __iomem *base;
+       struct clk *clk;
+       int i = 0;
+
+       if (!dev->of_node) {
+               dev_err(dev,
+                       "This driver is required to be instantiated from device tree\n");
+               return -EINVAL;
+       }
+
+       clk = devm_clk_get(dev, "usbhs");
+       if (IS_ERR(clk)) {
+               dev_err(dev, "Can't get USBHS clock\n");
+               return PTR_ERR(clk);
+       }
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       base = devm_ioremap_resource(dev, res);
+       if (IS_ERR(base))
+               return PTR_ERR(base);
+
+       drv = devm_kzalloc(dev, sizeof(*drv), GFP_KERNEL);
+       if (!drv)
+               return -ENOMEM;
+
+       spin_lock_init(&drv->lock);
+
+       drv->clk = clk;
+       drv->base = base;
+
+       drv->num_channels = of_get_child_count(dev->of_node);
+       drv->channels = devm_kcalloc(dev, drv->num_channels,
+                                    sizeof(struct rcar_gen2_channel),
+                                    GFP_KERNEL);
+       if (!drv->channels)
+               return -ENOMEM;
+
+       for_each_child_of_node(dev->of_node, np) {
+               struct rcar_gen2_channel *channel = drv->channels + i;
+               u32 channel_num;
+               int error, n;
+
+               channel->of_node = np;
+               channel->drv = drv;
+               channel->selected_phy = -1;
+
+               error = of_property_read_u32(np, "reg", &channel_num);
+               if (error || channel_num > 2) {
+                       dev_err(dev, "Invalid \"reg\" property\n");
+                       return error;
+               }
+               channel->select_mask = select_mask[channel_num];
+
+               for (n = 0; n < PHYS_PER_CHANNEL; n++) {
+                       struct rcar_gen2_phy *phy = &channel->phys[n];
+
+                       phy->channel = channel;
+                       phy->number = n;
+                       phy->select_value = select_value[channel_num][n];
+
+                       phy->phy = devm_phy_create(dev, NULL,
+                                                  &rcar_gen2_phy_ops, NULL);
+                       if (IS_ERR(phy->phy)) {
+                               dev_err(dev, "Failed to create PHY\n");
+                               return PTR_ERR(phy->phy);
+                       }
+                       phy_set_drvdata(phy->phy, phy);
+               }
+
+               i++;
+       }
+
+       provider = devm_of_phy_provider_register(dev, rcar_gen2_phy_xlate);
+       if (IS_ERR(provider)) {
+               dev_err(dev, "Failed to register PHY provider\n");
+               return PTR_ERR(provider);
+       }
+
+       dev_set_drvdata(dev, drv);
+
+       return 0;
+}
+
+static struct platform_driver rcar_gen2_phy_driver = {
+       .driver = {
+               .name           = "phy_rcar_gen2",
+               .of_match_table = rcar_gen2_phy_match_table,
+       },
+       .probe  = rcar_gen2_phy_probe,
+};
+
+module_platform_driver(rcar_gen2_phy_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Renesas R-Car Gen2 PHY");
+MODULE_AUTHOR("Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>");
index aaac359..d142ca0 100644 (file)
@@ -711,7 +711,7 @@ static int twl4030_usb_probe(struct platform_device *pdev)
        otg->set_host           = twl4030_set_host;
        otg->set_peripheral     = twl4030_set_peripheral;
 
-       phy = devm_phy_create(twl->dev, &ops, init_data);
+       phy = devm_phy_create(twl->dev, NULL, &ops, init_data);
        if (IS_ERR(phy)) {
                dev_dbg(&pdev->dev, "Failed to create PHY\n");
                return PTR_ERR(phy);
index b9b464d..6572c23 100644 (file)
@@ -542,7 +542,7 @@ static int sh_pfc_probe(struct platform_device *pdev)
         */
        ret = sh_pfc_register_pinctrl(pfc);
        if (unlikely(ret != 0))
-               goto error;
+               return ret;
 
 #ifdef CONFIG_GPIO_SH_PFC
        /*
@@ -564,11 +564,6 @@ static int sh_pfc_probe(struct platform_device *pdev)
        dev_info(pfc->dev, "%s support registered\n", info->name);
 
        return 0;
-
-error:
-       if (info->ops && info->ops->exit)
-               info->ops->exit(pfc);
-       return ret;
 }
 
 static int sh_pfc_remove(struct platform_device *pdev)
@@ -580,9 +575,6 @@ static int sh_pfc_remove(struct platform_device *pdev)
 #endif
        sh_pfc_unregister_pinctrl(pfc);
 
-       if (pfc->info->ops && pfc->info->ops->exit)
-               pfc->info->ops->exit(pfc);
-
        return 0;
 }
 
index b7b0e6c..3daaa52 100644 (file)
@@ -33,7 +33,6 @@ struct sh_pfc_pin_range {
 struct sh_pfc {
        struct device *dev;
        const struct sh_pfc_soc_info *info;
-       void *soc_data;
        spinlock_t lock;
 
        unsigned int num_windows;
index ce9fb7a..280a56f 100644 (file)
@@ -2717,14 +2717,14 @@ static void r8a73a4_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin,
        iowrite8(value, addr);
 }
 
-static const struct sh_pfc_soc_operations r8a73a4_pinmux_ops = {
+static const struct sh_pfc_soc_operations r8a73a4_pfc_ops = {
        .get_bias = r8a73a4_pinmux_get_bias,
        .set_bias = r8a73a4_pinmux_set_bias,
 };
 
 const struct sh_pfc_soc_info r8a73a4_pinmux_info = {
        .name           = "r8a73a4_pfc",
-       .ops            = &r8a73a4_pinmux_ops,
+       .ops            = &r8a73a4_pfc_ops,
 
        .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END },
        .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END },
index e4c1ef4..b486e9d 100644 (file)
@@ -3752,14 +3752,14 @@ static void r8a7740_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin,
        iowrite8(value, addr);
 }
 
-static const struct sh_pfc_soc_operations r8a7740_pinmux_ops = {
+static const struct sh_pfc_soc_operations r8a7740_pfc_ops = {
        .get_bias = r8a7740_pinmux_get_bias,
        .set_bias = r8a7740_pinmux_set_bias,
 };
 
 const struct sh_pfc_soc_info r8a7740_pinmux_info = {
        .name           = "r8a7740_pfc",
-       .ops            = &r8a7740_pinmux_ops,
+       .ops            = &r8a7740_pfc_ops,
 
        .input          = { PINMUX_INPUT_BEGIN,
                            PINMUX_INPUT_END },
index d9158b3..8211f66 100644 (file)
@@ -2614,14 +2614,14 @@ static void sh7372_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin,
        iowrite8(value, addr);
 }
 
-static const struct sh_pfc_soc_operations sh7372_pinmux_ops = {
+static const struct sh_pfc_soc_operations sh7372_pfc_ops = {
        .get_bias = sh7372_pinmux_get_bias,
        .set_bias = sh7372_pinmux_set_bias,
 };
 
 const struct sh_pfc_soc_info sh7372_pinmux_info = {
        .name = "sh7372_pfc",
-       .ops = &sh7372_pinmux_ops,
+       .ops = &sh7372_pfc_ops,
 
        .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END },
        .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END },
index 0bd8f44..d2efbfb 100644 (file)
@@ -3824,39 +3824,28 @@ static void sh73a0_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin,
  * SoC information
  */
 
-struct sh73a0_pinmux_data {
-       struct regulator_dev *vccq_mc0;
-};
-
 static int sh73a0_pinmux_soc_init(struct sh_pfc *pfc)
 {
-       struct sh73a0_pinmux_data *data;
        struct regulator_config cfg = { };
+       struct regulator_dev *vccq;
        int ret;
 
-       data = devm_kzalloc(pfc->dev, sizeof(*data), GFP_KERNEL);
-       if (data == NULL)
-               return -ENOMEM;
-
        cfg.dev = pfc->dev;
        cfg.init_data = &sh73a0_vccq_mc0_init_data;
        cfg.driver_data = pfc;
 
-       data->vccq_mc0 = devm_regulator_register(pfc->dev,
-                                                &sh73a0_vccq_mc0_desc, &cfg);
-       if (IS_ERR(data->vccq_mc0)) {
-               ret = PTR_ERR(data->vccq_mc0);
+       vccq = devm_regulator_register(pfc->dev, &sh73a0_vccq_mc0_desc, &cfg);
+       if (IS_ERR(vccq)) {
+               ret = PTR_ERR(vccq);
                dev_err(pfc->dev, "Failed to register VCCQ MC0 regulator: %d\n",
                        ret);
                return ret;
        }
 
-       pfc->soc_data = data;
-
        return 0;
 }
 
-static const struct sh_pfc_soc_operations sh73a0_pinmux_ops = {
+static const struct sh_pfc_soc_operations sh73a0_pfc_ops = {
        .init = sh73a0_pinmux_soc_init,
        .get_bias = sh73a0_pinmux_get_bias,
        .set_bias = sh73a0_pinmux_set_bias,
@@ -3864,7 +3853,7 @@ static const struct sh_pfc_soc_operations sh73a0_pinmux_ops = {
 
 const struct sh_pfc_soc_info sh73a0_pinmux_info = {
        .name = "sh73a0_pfc",
-       .ops = &sh73a0_pinmux_ops,
+       .ops = &sh73a0_pfc_ops,
 
        .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END },
        .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END },
index d482c40..5b72831 100644 (file)
@@ -116,7 +116,6 @@ struct sh_pfc;
 
 struct sh_pfc_soc_operations {
        int (*init)(struct sh_pfc *pfc);
-       void (*exit)(struct sh_pfc *pfc);
        unsigned int (*get_bias)(struct sh_pfc *pfc, unsigned int pin);
        void (*set_bias)(struct sh_pfc *pfc, unsigned int pin,
                         unsigned int bias);
index 390e8e3..25721bf 100644 (file)
@@ -163,18 +163,24 @@ static void dell_wmi_notify(u32 value, void *context)
                const struct key_entry *key;
                int reported_key;
                u16 *buffer_entry = (u16 *)obj->buffer.pointer;
+               int buffer_size = obj->buffer.length/2;
 
-               if (dell_new_hk_type && (buffer_entry[1] != 0x10)) {
+               if (buffer_size >= 2 && dell_new_hk_type && buffer_entry[1] != 0x10) {
                        pr_info("Received unknown WMI event (0x%x)\n",
                                buffer_entry[1]);
                        kfree(obj);
                        return;
                }
 
-               if (dell_new_hk_type || buffer_entry[1] == 0x0)
+               if (buffer_size >= 3 && (dell_new_hk_type || buffer_entry[1] == 0x0))
                        reported_key = (int)buffer_entry[2];
-               else
+               else if (buffer_size >= 2)
                        reported_key = (int)buffer_entry[1] & 0xffff;
+               else {
+                       pr_info("Received unknown WMI event\n");
+                       kfree(obj);
+                       return;
+               }
 
                key = sparse_keymap_entry_from_scancode(dell_wmi_input_dev,
                                                        reported_key);
index e384844..1f49986 100644 (file)
@@ -1579,8 +1579,15 @@ static int bq2415x_probe(struct i2c_client *client,
        if (np) {
                bq->notify_psy = power_supply_get_by_phandle(np, "ti,usb-charger-detection");
 
-               if (!bq->notify_psy)
-                       return -EPROBE_DEFER;
+               if (IS_ERR(bq->notify_psy)) {
+                       dev_info(&client->dev,
+                               "no 'ti,usb-charger-detection' property (err=%ld)\n",
+                               PTR_ERR(bq->notify_psy));
+                       bq->notify_psy = NULL;
+               } else if (!bq->notify_psy) {
+                       ret = -EPROBE_DEFER;
+                       goto error_2;
+               }
        }
        else if (pdata->notify_device)
                bq->notify_psy = power_supply_get_by_name(pdata->notify_device);
@@ -1602,27 +1609,27 @@ static int bq2415x_probe(struct i2c_client *client,
                ret = of_property_read_u32(np, "ti,current-limit",
                                &bq->init_data.current_limit);
                if (ret)
-                       return ret;
+                       goto error_2;
                ret = of_property_read_u32(np, "ti,weak-battery-voltage",
                                &bq->init_data.weak_battery_voltage);
                if (ret)
-                       return ret;
+                       goto error_2;
                ret = of_property_read_u32(np, "ti,battery-regulation-voltage",
                                &bq->init_data.battery_regulation_voltage);
                if (ret)
-                       return ret;
+                       goto error_2;
                ret = of_property_read_u32(np, "ti,charge-current",
                                &bq->init_data.charge_current);
                if (ret)
-                       return ret;
+                       goto error_2;
                ret = of_property_read_u32(np, "ti,termination-current",
                                &bq->init_data.termination_current);
                if (ret)
-                       return ret;
+                       goto error_2;
                ret = of_property_read_u32(np, "ti,resistor-sense",
                                &bq->init_data.resistor_sense);
                if (ret)
-                       return ret;
+                       goto error_2;
        } else {
                memcpy(&bq->init_data, pdata, sizeof(bq->init_data));
        }
index ef1f4c9..03bfac3 100644 (file)
@@ -97,6 +97,7 @@ static struct charger_global_desc *g_desc; /* init with setup_charger_manager */
 static bool is_batt_present(struct charger_manager *cm)
 {
        union power_supply_propval val;
+       struct power_supply *psy;
        bool present = false;
        int i, ret;
 
@@ -107,16 +108,27 @@ static bool is_batt_present(struct charger_manager *cm)
        case CM_NO_BATTERY:
                break;
        case CM_FUEL_GAUGE:
-               ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
+               psy = power_supply_get_by_name(cm->desc->psy_fuel_gauge);
+               if (!psy)
+                       break;
+
+               ret = psy->get_property(psy,
                                POWER_SUPPLY_PROP_PRESENT, &val);
                if (ret == 0 && val.intval)
                        present = true;
                break;
        case CM_CHARGER_STAT:
-               for (i = 0; cm->charger_stat[i]; i++) {
-                       ret = cm->charger_stat[i]->get_property(
-                                       cm->charger_stat[i],
-                                       POWER_SUPPLY_PROP_PRESENT, &val);
+               for (i = 0; cm->desc->psy_charger_stat[i]; i++) {
+                       psy = power_supply_get_by_name(
+                                       cm->desc->psy_charger_stat[i]);
+                       if (!psy) {
+                               dev_err(cm->dev, "Cannot find power supply \"%s\"\n",
+                                       cm->desc->psy_charger_stat[i]);
+                               continue;
+                       }
+
+                       ret = psy->get_property(psy, POWER_SUPPLY_PROP_PRESENT,
+                                       &val);
                        if (ret == 0 && val.intval) {
                                present = true;
                                break;
@@ -139,14 +151,20 @@ static bool is_batt_present(struct charger_manager *cm)
 static bool is_ext_pwr_online(struct charger_manager *cm)
 {
        union power_supply_propval val;
+       struct power_supply *psy;
        bool online = false;
        int i, ret;
 
        /* If at least one of them has one, it's yes. */
-       for (i = 0; cm->charger_stat[i]; i++) {
-               ret = cm->charger_stat[i]->get_property(
-                               cm->charger_stat[i],
-                               POWER_SUPPLY_PROP_ONLINE, &val);
+       for (i = 0; cm->desc->psy_charger_stat[i]; i++) {
+               psy = power_supply_get_by_name(cm->desc->psy_charger_stat[i]);
+               if (!psy) {
+                       dev_err(cm->dev, "Cannot find power supply \"%s\"\n",
+                                       cm->desc->psy_charger_stat[i]);
+                       continue;
+               }
+
+               ret = psy->get_property(psy, POWER_SUPPLY_PROP_ONLINE, &val);
                if (ret == 0 && val.intval) {
                        online = true;
                        break;
@@ -167,12 +185,14 @@ static bool is_ext_pwr_online(struct charger_manager *cm)
 static int get_batt_uV(struct charger_manager *cm, int *uV)
 {
        union power_supply_propval val;
+       struct power_supply *fuel_gauge;
        int ret;
 
-       if (!cm->fuel_gauge)
+       fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge);
+       if (!fuel_gauge)
                return -ENODEV;
 
-       ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
+       ret = fuel_gauge->get_property(fuel_gauge,
                                POWER_SUPPLY_PROP_VOLTAGE_NOW, &val);
        if (ret)
                return ret;
@@ -189,6 +209,7 @@ static bool is_charging(struct charger_manager *cm)
 {
        int i, ret;
        bool charging = false;
+       struct power_supply *psy;
        union power_supply_propval val;
 
        /* If there is no battery, it cannot be charged */
@@ -196,17 +217,22 @@ static bool is_charging(struct charger_manager *cm)
                return false;
 
        /* If at least one of the charger is charging, return yes */
-       for (i = 0; cm->charger_stat[i]; i++) {
+       for (i = 0; cm->desc->psy_charger_stat[i]; i++) {
                /* 1. The charger sholuld not be DISABLED */
                if (cm->emergency_stop)
                        continue;
                if (!cm->charger_enabled)
                        continue;
 
+               psy = power_supply_get_by_name(cm->desc->psy_charger_stat[i]);
+               if (!psy) {
+                       dev_err(cm->dev, "Cannot find power supply \"%s\"\n",
+                                       cm->desc->psy_charger_stat[i]);
+                       continue;
+               }
+
                /* 2. The charger should be online (ext-power) */
-               ret = cm->charger_stat[i]->get_property(
-                               cm->charger_stat[i],
-                               POWER_SUPPLY_PROP_ONLINE, &val);
+               ret = psy->get_property(psy, POWER_SUPPLY_PROP_ONLINE, &val);
                if (ret) {
                        dev_warn(cm->dev, "Cannot read ONLINE value from %s\n",
                                 cm->desc->psy_charger_stat[i]);
@@ -219,9 +245,7 @@ static bool is_charging(struct charger_manager *cm)
                 * 3. The charger should not be FULL, DISCHARGING,
                 * or NOT_CHARGING.
                 */
-               ret = cm->charger_stat[i]->get_property(
-                               cm->charger_stat[i],
-                               POWER_SUPPLY_PROP_STATUS, &val);
+               ret = psy->get_property(psy, POWER_SUPPLY_PROP_STATUS, &val);
                if (ret) {
                        dev_warn(cm->dev, "Cannot read STATUS value from %s\n",
                                 cm->desc->psy_charger_stat[i]);
@@ -248,6 +272,7 @@ static bool is_full_charged(struct charger_manager *cm)
 {
        struct charger_desc *desc = cm->desc;
        union power_supply_propval val;
+       struct power_supply *fuel_gauge;
        int ret = 0;
        int uV;
 
@@ -255,11 +280,15 @@ static bool is_full_charged(struct charger_manager *cm)
        if (!is_batt_present(cm))
                return false;
 
-       if (cm->fuel_gauge && desc->fullbatt_full_capacity > 0) {
+       fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge);
+       if (!fuel_gauge)
+               return false;
+
+       if (desc->fullbatt_full_capacity > 0) {
                val.intval = 0;
 
                /* Not full if capacity of fuel gauge isn't full */
-               ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
+               ret = fuel_gauge->get_property(fuel_gauge,
                                POWER_SUPPLY_PROP_CHARGE_FULL, &val);
                if (!ret && val.intval > desc->fullbatt_full_capacity)
                        return true;
@@ -273,10 +302,10 @@ static bool is_full_charged(struct charger_manager *cm)
        }
 
        /* Full, if the capacity is more than fullbatt_soc */
-       if (cm->fuel_gauge && desc->fullbatt_soc > 0) {
+       if (desc->fullbatt_soc > 0) {
                val.intval = 0;
 
-               ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
+               ret = fuel_gauge->get_property(fuel_gauge,
                                POWER_SUPPLY_PROP_CAPACITY, &val);
                if (!ret && val.intval >= desc->fullbatt_soc)
                        return true;
@@ -551,6 +580,20 @@ static int check_charging_duration(struct charger_manager *cm)
        return ret;
 }
 
+static int cm_get_battery_temperature_by_psy(struct charger_manager *cm,
+                                       int *temp)
+{
+       struct power_supply *fuel_gauge;
+
+       fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge);
+       if (!fuel_gauge)
+               return -ENODEV;
+
+       return fuel_gauge->get_property(fuel_gauge,
+                               POWER_SUPPLY_PROP_TEMP,
+                               (union power_supply_propval *)temp);
+}
+
 static int cm_get_battery_temperature(struct charger_manager *cm,
                                        int *temp)
 {
@@ -560,15 +603,18 @@ static int cm_get_battery_temperature(struct charger_manager *cm,
                return -ENODEV;
 
 #ifdef CONFIG_THERMAL
-       ret = thermal_zone_get_temp(cm->tzd_batt, (unsigned long *)temp);
-       if (!ret)
-               /* Calibrate temperature unit */
-               *temp /= 100;
-#else
-       ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
-                               POWER_SUPPLY_PROP_TEMP,
-                               (union power_supply_propval *)temp);
+       if (cm->tzd_batt) {
+               ret = thermal_zone_get_temp(cm->tzd_batt, (unsigned long *)temp);
+               if (!ret)
+                       /* Calibrate temperature unit */
+                       *temp /= 100;
+       } else
 #endif
+       {
+               /* if-else continued from CONFIG_THERMAL */
+               ret = cm_get_battery_temperature_by_psy(cm, temp);
+       }
+
        return ret;
 }
 
@@ -827,6 +873,7 @@ static int charger_get_property(struct power_supply *psy,
        struct charger_manager *cm = container_of(psy,
                        struct charger_manager, charger_psy);
        struct charger_desc *desc = cm->desc;
+       struct power_supply *fuel_gauge;
        int ret = 0;
        int uV;
 
@@ -857,14 +904,20 @@ static int charger_get_property(struct power_supply *psy,
                ret = get_batt_uV(cm, &val->intval);
                break;
        case POWER_SUPPLY_PROP_CURRENT_NOW:
-               ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
+               fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge);
+               if (!fuel_gauge) {
+                       ret = -ENODEV;
+                       break;
+               }
+               ret = fuel_gauge->get_property(fuel_gauge,
                                POWER_SUPPLY_PROP_CURRENT_NOW, val);
                break;
        case POWER_SUPPLY_PROP_TEMP:
        case POWER_SUPPLY_PROP_TEMP_AMBIENT:
                return cm_get_battery_temperature(cm, &val->intval);
        case POWER_SUPPLY_PROP_CAPACITY:
-               if (!cm->fuel_gauge) {
+               fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge);
+               if (!fuel_gauge) {
                        ret = -ENODEV;
                        break;
                }
@@ -875,7 +928,7 @@ static int charger_get_property(struct power_supply *psy,
                        break;
                }
 
-               ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
+               ret = fuel_gauge->get_property(fuel_gauge,
                                        POWER_SUPPLY_PROP_CAPACITY, val);
                if (ret)
                        break;
@@ -924,7 +977,14 @@ static int charger_get_property(struct power_supply *psy,
                break;
        case POWER_SUPPLY_PROP_CHARGE_NOW:
                if (is_charging(cm)) {
-                       ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
+                       fuel_gauge = power_supply_get_by_name(
+                                       cm->desc->psy_fuel_gauge);
+                       if (!fuel_gauge) {
+                               ret = -ENODEV;
+                               break;
+                       }
+
+                       ret = fuel_gauge->get_property(fuel_gauge,
                                                POWER_SUPPLY_PROP_CHARGE_NOW,
                                                val);
                        if (ret) {
@@ -1485,14 +1545,15 @@ err:
        return ret;
 }
 
-static int cm_init_thermal_data(struct charger_manager *cm)
+static int cm_init_thermal_data(struct charger_manager *cm,
+               struct power_supply *fuel_gauge)
 {
        struct charger_desc *desc = cm->desc;
        union power_supply_propval val;
        int ret;
 
        /* Verify whether fuel gauge provides battery temperature */
-       ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
+       ret = fuel_gauge->get_property(fuel_gauge,
                                        POWER_SUPPLY_PROP_TEMP, &val);
 
        if (!ret) {
@@ -1502,8 +1563,6 @@ static int cm_init_thermal_data(struct charger_manager *cm)
                cm->desc->measure_battery_temp = true;
        }
 #ifdef CONFIG_THERMAL
-       cm->tzd_batt = cm->fuel_gauge->tzd;
-
        if (ret && desc->thermal_zone) {
                cm->tzd_batt =
                        thermal_zone_get_zone_by_name(desc->thermal_zone);
@@ -1666,6 +1725,7 @@ static int charger_manager_probe(struct platform_device *pdev)
        int ret = 0, i = 0;
        int j = 0;
        union power_supply_propval val;
+       struct power_supply *fuel_gauge;
 
        if (g_desc && !rtc_dev && g_desc->rtc_name) {
                rtc_dev = rtc_class_open(g_desc->rtc_name);
@@ -1729,23 +1789,20 @@ static int charger_manager_probe(struct platform_device *pdev)
        while (desc->psy_charger_stat[i])
                i++;
 
-       cm->charger_stat = devm_kzalloc(&pdev->dev,
-                               sizeof(struct power_supply *) * i, GFP_KERNEL);
-       if (!cm->charger_stat)
-               return -ENOMEM;
-
+       /* Check if charger's supplies are present at probe */
        for (i = 0; desc->psy_charger_stat[i]; i++) {
-               cm->charger_stat[i] = power_supply_get_by_name(
-                                       desc->psy_charger_stat[i]);
-               if (!cm->charger_stat[i]) {
+               struct power_supply *psy;
+
+               psy = power_supply_get_by_name(desc->psy_charger_stat[i]);
+               if (!psy) {
                        dev_err(&pdev->dev, "Cannot find power supply \"%s\"\n",
                                desc->psy_charger_stat[i]);
                        return -ENODEV;
                }
        }
 
-       cm->fuel_gauge = power_supply_get_by_name(desc->psy_fuel_gauge);
-       if (!cm->fuel_gauge) {
+       fuel_gauge = power_supply_get_by_name(desc->psy_fuel_gauge);
+       if (!fuel_gauge) {
                dev_err(&pdev->dev, "Cannot find power supply \"%s\"\n",
                        desc->psy_fuel_gauge);
                return -ENODEV;
@@ -1788,13 +1845,13 @@ static int charger_manager_probe(struct platform_device *pdev)
        cm->charger_psy.num_properties = psy_default.num_properties;
 
        /* Find which optional psy-properties are available */
-       if (!cm->fuel_gauge->get_property(cm->fuel_gauge,
+       if (!fuel_gauge->get_property(fuel_gauge,
                                          POWER_SUPPLY_PROP_CHARGE_NOW, &val)) {
                cm->charger_psy.properties[cm->charger_psy.num_properties] =
                                POWER_SUPPLY_PROP_CHARGE_NOW;
                cm->charger_psy.num_properties++;
        }
-       if (!cm->fuel_gauge->get_property(cm->fuel_gauge,
+       if (!fuel_gauge->get_property(fuel_gauge,
                                          POWER_SUPPLY_PROP_CURRENT_NOW,
                                          &val)) {
                cm->charger_psy.properties[cm->charger_psy.num_properties] =
@@ -1802,7 +1859,7 @@ static int charger_manager_probe(struct platform_device *pdev)
                cm->charger_psy.num_properties++;
        }
 
-       ret = cm_init_thermal_data(cm);
+       ret = cm_init_thermal_data(cm, fuel_gauge);
        if (ret) {
                dev_err(&pdev->dev, "Failed to initialize thermal data\n");
                cm->desc->measure_battery_temp = false;
@@ -2059,8 +2116,8 @@ static bool find_power_supply(struct charger_manager *cm,
        int i;
        bool found = false;
 
-       for (i = 0; cm->charger_stat[i]; i++) {
-               if (psy == cm->charger_stat[i]) {
+       for (i = 0; cm->desc->psy_charger_stat[i]; i++) {
+               if (!strcmp(psy->name, cm->desc->psy_charger_stat[i])) {
                        found = true;
                        break;
                }
index 9b94850..cc6b13b 100644 (file)
@@ -411,6 +411,7 @@ static int bnx2fc_rcv(struct sk_buff *skb, struct net_device *dev,
        struct fc_frame_header *fh;
        struct fcoe_rcv_info *fr;
        struct fcoe_percpu_s *bg;
+       struct sk_buff *tmp_skb;
        unsigned short oxid;
 
        interface = container_of(ptype, struct bnx2fc_interface,
@@ -423,6 +424,12 @@ static int bnx2fc_rcv(struct sk_buff *skb, struct net_device *dev,
                goto err;
        }
 
+       tmp_skb = skb_share_check(skb, GFP_ATOMIC);
+       if (!tmp_skb)
+               goto err;
+
+       skb = tmp_skb;
+
        if (unlikely(eth_hdr(skb)->h_proto != htons(ETH_P_FCOE))) {
                printk(KERN_ERR PFX "bnx2fc_rcv: Wrong FC type frame\n");
                goto err;
index 49014a1..c1d04d4 100644 (file)
@@ -202,6 +202,7 @@ static struct {
        {"IOMEGA", "Io20S         *F", NULL, BLIST_KEY},
        {"INSITE", "Floptical   F*8I", NULL, BLIST_KEY},
        {"INSITE", "I325VM", NULL, BLIST_KEY},
+       {"Intel", "Multi-Flex", NULL, BLIST_NO_RSOC},
        {"iRiver", "iFP Mass Driver", NULL, BLIST_NOT_LOCKABLE | BLIST_INQUIRY_36},
        {"LASOUND", "CDX7405", "3.10", BLIST_MAX5LUN | BLIST_SINGLELUN},
        {"MATSHITA", "PD-1", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
index edb4d46..96b6664 100644 (file)
@@ -1984,8 +1984,10 @@ static void scsi_restart_operations(struct Scsi_Host *shost)
         * is no point trying to lock the door of an off-line device.
         */
        shost_for_each_device(sdev, shost) {
-               if (scsi_device_online(sdev) && sdev->locked)
+               if (scsi_device_online(sdev) && sdev->was_reset && sdev->locked) {
                        scsi_eh_lock_door(sdev);
+                       sdev->was_reset = 0;
+               }
        }
 
        /*
index 72f6381..fe2c2d5 100644 (file)
@@ -75,8 +75,6 @@ static struct pm_clk_notifier_block platform_bus_notifier = {
        .con_ids = { NULL, },
 };
 
-static bool default_pm_on;
-
 static int __init sh_pm_runtime_init(void)
 {
        if (IS_ENABLED(CONFIG_ARCH_SHMOBILE_MULTI)) {
@@ -96,16 +94,7 @@ static int __init sh_pm_runtime_init(void)
                        return 0;
        }
 
-       default_pm_on = true;
        pm_clk_add_notifier(&platform_bus_type, &platform_bus_notifier);
        return 0;
 }
 core_initcall(sh_pm_runtime_init);
-
-static int __init sh_pm_runtime_late_init(void)
-{
-       if (default_pm_on)
-               pm_genpd_poweroff_unused();
-       return 0;
-}
-late_initcall(sh_pm_runtime_late_init);
index e63d270..e543b80 100644 (file)
@@ -394,9 +394,6 @@ static void pump_transfers(unsigned long data)
        chip = dws->cur_chip;
        spi = message->spi;
 
-       if (unlikely(!chip->clk_div))
-               chip->clk_div = dws->max_freq / chip->speed_hz;
-
        if (message->state == ERROR_STATE) {
                message->status = -EIO;
                goto early_exit;
@@ -437,7 +434,7 @@ static void pump_transfers(unsigned long data)
        if (transfer->speed_hz) {
                speed = chip->speed_hz;
 
-               if (transfer->speed_hz != speed) {
+               if ((transfer->speed_hz != speed) || (!chip->clk_div)) {
                        speed = transfer->speed_hz;
                        if (speed > dws->max_freq) {
                                printk(KERN_ERR "MRST SPI0: unsupported"
@@ -659,7 +656,6 @@ static int dw_spi_setup(struct spi_device *spi)
                dev_err(&spi->dev, "No max speed HZ parameter\n");
                return -EINVAL;
        }
-       chip->speed_hz = spi->max_speed_hz;
 
        chip->tmode = 0; /* Tx & Rx */
        /* Default SPI mode is SCPOL = 0, SCPH = 0 */
index ad87a98..54bb0fa 100644 (file)
@@ -87,7 +87,7 @@
 /* RSPI on SH only */
 #define SPCR_TXMD              0x02    /* TX Only Mode (vs. Full Duplex) */
 #define SPCR_SPMS              0x01    /* 3-wire Mode (vs. 4-wire) */
-/* QSPI on R-Car M2 only */
+/* QSPI on R-Car Gen2 only */
 #define SPCR_WSWAP             0x02    /* Word Swap of read-data for DMAC */
 #define SPCR_BSWAP             0x01    /* Byte Swap of read-data for DMAC */
 
@@ -909,20 +909,24 @@ static struct dma_chan *rspi_request_dma_chan(struct device *dev,
        dma_cap_zero(mask);
        dma_cap_set(DMA_SLAVE, mask);
 
-       chan = dma_request_channel(mask, shdma_chan_filter,
-                                  (void *)(unsigned long)id);
+       chan = dma_request_slave_channel_compat(mask, shdma_chan_filter,
+                               (void *)(unsigned long)id, dev,
+                               dir == DMA_MEM_TO_DEV ? "tx" : "rx");
        if (!chan) {
-               dev_warn(dev, "dma_request_channel failed\n");
+               dev_warn(dev, "dma_request_slave_channel_compat failed\n");
                return NULL;
        }
 
        memset(&cfg, 0, sizeof(cfg));
        cfg.slave_id = id;
        cfg.direction = dir;
-       if (dir == DMA_MEM_TO_DEV)
+       if (dir == DMA_MEM_TO_DEV) {
                cfg.dst_addr = port_addr;
-       else
+               cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+       } else {
                cfg.src_addr = port_addr;
+               cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+       }
 
        ret = dmaengine_slave_config(chan, &cfg);
        if (ret) {
@@ -938,22 +942,30 @@ static int rspi_request_dma(struct device *dev, struct spi_master *master,
                            const struct resource *res)
 {
        const struct rspi_plat_data *rspi_pd = dev_get_platdata(dev);
+       unsigned int dma_tx_id, dma_rx_id;
+
+       if (dev->of_node) {
+               /* In the OF case we will get the slave IDs from the DT */
+               dma_tx_id = 0;
+               dma_rx_id = 0;
+       } else if (rspi_pd && rspi_pd->dma_tx_id && rspi_pd->dma_rx_id) {
+               dma_tx_id = rspi_pd->dma_tx_id;
+               dma_rx_id = rspi_pd->dma_rx_id;
+       } else {
+               /* The driver assumes no error. */
+               return 0;
+       }
 
-       if (!rspi_pd || !rspi_pd->dma_rx_id || !rspi_pd->dma_tx_id)
-               return 0;       /* The driver assumes no error. */
-
-       master->dma_rx = rspi_request_dma_chan(dev, DMA_DEV_TO_MEM,
-                                              rspi_pd->dma_rx_id,
+       master->dma_tx = rspi_request_dma_chan(dev, DMA_MEM_TO_DEV, dma_tx_id,
                                               res->start + RSPI_SPDR);
-       if (!master->dma_rx)
+       if (!master->dma_tx)
                return -ENODEV;
 
-       master->dma_tx = rspi_request_dma_chan(dev, DMA_MEM_TO_DEV,
-                                              rspi_pd->dma_tx_id,
+       master->dma_rx = rspi_request_dma_chan(dev, DMA_DEV_TO_MEM, dma_rx_id,
                                               res->start + RSPI_SPDR);
-       if (!master->dma_tx) {
-               dma_release_channel(master->dma_rx);
-               master->dma_rx = NULL;
+       if (!master->dma_rx) {
+               dma_release_channel(master->dma_tx);
+               master->dma_tx = NULL;
                return -ENODEV;
        }
 
@@ -1046,12 +1058,11 @@ static int rspi_request_irq(struct device *dev, unsigned int irq,
                            irq_handler_t handler, const char *suffix,
                            void *dev_id)
 {
-       const char *base = dev_name(dev);
-       size_t len = strlen(base) + strlen(suffix) + 2;
-       char *name = devm_kzalloc(dev, len, GFP_KERNEL);
+       const char *name = devm_kasprintf(dev, GFP_KERNEL, "%s:%s",
+                                         dev_name(dev), suffix);
        if (!name)
                return -ENOMEM;
-       snprintf(name, len, "%s:%s", base, suffix);
+
        return devm_request_irq(dev, irq, handler, 0, name, dev_id);
 }
 
@@ -1084,7 +1095,7 @@ static int rspi_probe(struct platform_device *pdev)
                        master->num_chipselect = rspi_pd->num_chipselect;
                else
                        master->num_chipselect = 2; /* default */
-       };
+       }
 
        /* ops parameter check */
        if (!ops->set_config_register) {
index 543075b..3f36540 100644 (file)
@@ -642,18 +642,14 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
                desc_rx = dmaengine_prep_slave_single(p->master->dma_rx,
                                        p->rx_dma_addr, len, DMA_FROM_DEVICE,
                                        DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
-               if (!desc_rx) {
-                       ret = -EAGAIN;
-                       goto no_dma_rx;
-               }
+               if (!desc_rx)
+                       return -EAGAIN;
 
                desc_rx->callback = sh_msiof_dma_complete;
                desc_rx->callback_param = p;
                cookie = dmaengine_submit(desc_rx);
-               if (dma_submit_error(cookie)) {
-                       ret = cookie;
-                       goto no_dma_rx;
-               }
+               if (dma_submit_error(cookie))
+                       return cookie;
        }
 
        if (tx) {
@@ -738,7 +734,6 @@ no_dma_tx:
        if (rx)
                dmaengine_terminate_all(p->master->dma_rx);
        sh_msiof_write(p, IER, 0);
-no_dma_rx:
        return ret;
 }
 
@@ -933,6 +928,9 @@ static const struct of_device_id sh_msiof_match[] = {
        { .compatible = "renesas,sh-mobile-msiof", .data = &sh_data },
        { .compatible = "renesas,msiof-r8a7790",   .data = &r8a779x_data },
        { .compatible = "renesas,msiof-r8a7791",   .data = &r8a779x_data },
+       { .compatible = "renesas,msiof-r8a7792",   .data = &r8a779x_data },
+       { .compatible = "renesas,msiof-r8a7793",   .data = &r8a779x_data },
+       { .compatible = "renesas,msiof-r8a7794",   .data = &r8a779x_data },
        {},
 };
 MODULE_DEVICE_TABLE(of, sh_msiof_match);
@@ -977,20 +975,24 @@ static struct dma_chan *sh_msiof_request_dma_chan(struct device *dev,
        dma_cap_zero(mask);
        dma_cap_set(DMA_SLAVE, mask);
 
-       chan = dma_request_channel(mask, shdma_chan_filter,
-                                 (void *)(unsigned long)id);
+       chan = dma_request_slave_channel_compat(mask, shdma_chan_filter,
+                               (void *)(unsigned long)id, dev,
+                               dir == DMA_MEM_TO_DEV ? "tx" : "rx");
        if (!chan) {
-               dev_warn(dev, "dma_request_channel failed\n");
+               dev_warn(dev, "dma_request_slave_channel_compat failed\n");
                return NULL;
        }
 
        memset(&cfg, 0, sizeof(cfg));
        cfg.slave_id = id;
        cfg.direction = dir;
-       if (dir == DMA_MEM_TO_DEV)
+       if (dir == DMA_MEM_TO_DEV) {
                cfg.dst_addr = port_addr;
-       else
+               cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+       } else {
                cfg.src_addr = port_addr;
+               cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+       }
 
        ret = dmaengine_slave_config(chan, &cfg);
        if (ret) {
@@ -1007,12 +1009,22 @@ static int sh_msiof_request_dma(struct sh_msiof_spi_priv *p)
        struct platform_device *pdev = p->pdev;
        struct device *dev = &pdev->dev;
        const struct sh_msiof_spi_info *info = dev_get_platdata(dev);
+       unsigned int dma_tx_id, dma_rx_id;
        const struct resource *res;
        struct spi_master *master;
        struct device *tx_dev, *rx_dev;
 
-       if (!info || !info->dma_tx_id || !info->dma_rx_id)
-               return 0;       /* The driver assumes no error */
+       if (dev->of_node) {
+               /* In the OF case we will get the slave IDs from the DT */
+               dma_tx_id = 0;
+               dma_rx_id = 0;
+       } else if (info && info->dma_tx_id && info->dma_rx_id) {
+               dma_tx_id = info->dma_tx_id;
+               dma_rx_id = info->dma_rx_id;
+       } else {
+               /* The driver assumes no error */
+               return 0;
+       }
 
        /* The DMA engine uses the second register set, if present */
        res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
@@ -1021,13 +1033,13 @@ static int sh_msiof_request_dma(struct sh_msiof_spi_priv *p)
 
        master = p->master;
        master->dma_tx = sh_msiof_request_dma_chan(dev, DMA_MEM_TO_DEV,
-                                                  info->dma_tx_id,
+                                                  dma_tx_id,
                                                   res->start + TFDR);
        if (!master->dma_tx)
                return -ENODEV;
 
        master->dma_rx = sh_msiof_request_dma_chan(dev, DMA_DEV_TO_MEM,
-                                                  info->dma_rx_id,
+                                                  dma_rx_id,
                                                   res->start + RFDR);
        if (!master->dma_rx)
                goto free_tx_chan;
@@ -1210,6 +1222,9 @@ static struct platform_device_id spi_driver_ids[] = {
        { "spi_sh_msiof",       (kernel_ulong_t)&sh_data },
        { "spi_r8a7790_msiof",  (kernel_ulong_t)&r8a779x_data },
        { "spi_r8a7791_msiof",  (kernel_ulong_t)&r8a779x_data },
+       { "spi_r8a7792_msiof",  (kernel_ulong_t)&r8a779x_data },
+       { "spi_r8a7793_msiof",  (kernel_ulong_t)&r8a779x_data },
+       { "spi_r8a7794_msiof",  (kernel_ulong_t)&r8a779x_data },
        {},
 };
 MODULE_DEVICE_TABLE(platform, spi_driver_ids);
index fed699f..2185a71 100644 (file)
@@ -57,6 +57,7 @@ static struct usb_device_id rtw_usb_id_tbl[] = {
        {USB_DEVICE(0x07b8, 0x8179)}, /* Abocom - Abocom */
        {USB_DEVICE(0x2001, 0x330F)}, /* DLink DWA-125 REV D1 */
        {USB_DEVICE(0x2001, 0x3310)}, /* Dlink DWA-123 REV D1 */
+       {USB_DEVICE(0x2001, 0x3311)}, /* DLink GO-USB-N150 REV B1 */
        {USB_DEVICE(0x0df6, 0x0076)}, /* Sitecom N150 v2 */
        {}      /* Terminating entry */
 };
index 9232c77..e6463ef 100644 (file)
@@ -2230,7 +2230,7 @@ transport_generic_new_cmd(struct se_cmd *cmd)
         * and let it call back once the write buffers are ready.
         */
        target_add_to_state_list(cmd);
-       if (cmd->data_direction != DMA_TO_DEVICE) {
+       if (cmd->data_direction != DMA_TO_DEVICE || cmd->data_length == 0) {
                target_execute_cmd(cmd);
                return 0;
        }
index 27b5554..8c7ed09 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/console.h>
+#include <linux/of.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/device.h>
@@ -2607,6 +2608,8 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport)
                spin_lock_init(&uport->lock);
                lockdep_set_class(&uport->lock, &port_lock_key);
        }
+       if (uport->cons && uport->dev)
+               of_console_check(uport->dev->of_node, uport->cons->name, uport->line);
 
        uart_configure_port(drv, state, uport);
 
index d879c0c..2888efb 100644 (file)
@@ -1403,7 +1403,7 @@ static void work_fn_rx(struct work_struct *work)
                unsigned long flags;
                int count;
 
-               chan->device->device_control(chan, DMA_TERMINATE_ALL, 0);
+               dmaengine_terminate_all(chan);
                dev_dbg(port->dev, "Read %zu bytes with cookie %d\n",
                        sh_desc->partial, sh_desc->cookie);
 
index 33f22bc..7203b1d 100644 (file)
@@ -410,6 +410,10 @@ static int ci_get_platdata(struct device *dev,
                                PTR_ERR(platdata->reg_vbus));
                        return PTR_ERR(platdata->reg_vbus);
                }
+               /* Get TPL support */
+               if (!platdata->tpl_support)
+                       platdata->tpl_support =
+                               of_usb_host_tpl_support(dev->of_node);
        }
 
        return 0;
index a8ac6c1..c693905 100644 (file)
@@ -59,7 +59,8 @@ static int host_start(struct ci_hdrc *ci)
        hcd->has_tt = 1;
 
        hcd->power_budget = ci->platdata->power_budget;
-       hcd->phy = ci->transceiver;
+       hcd->usb_phy = ci->transceiver;
+       hcd->tpl_support = ci->platdata->tpl_support;
 
        ehci = hcd_to_ehci(hcd);
        ehci->caps = ci->hw_bank.cap;
index ef6ec13..7b2c9a0 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/types.h>
 
+#include <linux/phy/phy.h>
 #include <linux/usb.h>
 #include <linux/usb/hcd.h>
 #include <linux/usb/phy.h>
@@ -2590,7 +2591,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
        int retval;
        struct usb_device *rhdev;
 
-       if (IS_ENABLED(CONFIG_USB_PHY) && !hcd->phy) {
+       if (IS_ENABLED(CONFIG_USB_PHY) && !hcd->usb_phy) {
                struct usb_phy *phy = usb_get_phy_dev(hcd->self.controller, 0);
 
                if (IS_ERR(phy)) {
@@ -2603,11 +2604,34 @@ int usb_add_hcd(struct usb_hcd *hcd,
                                usb_put_phy(phy);
                                return retval;
                        }
-                       hcd->phy = phy;
+                       hcd->usb_phy = phy;
                        hcd->remove_phy = 1;
                }
        }
 
+       if (IS_ENABLED(CONFIG_GENERIC_PHY)) {
+               struct phy *phy = phy_get(hcd->self.controller, "usb");
+
+               if (IS_ERR(phy)) {
+                       retval = PTR_ERR(phy);
+                       if (retval == -EPROBE_DEFER)
+                               goto err_phy;
+               } else {
+                       retval = phy_init(phy);
+                       if (retval) {
+                               phy_put(phy);
+                               goto err_phy;
+                       }
+                       retval = phy_power_on(phy);
+                       if (retval) {
+                               phy_exit(phy);
+                               phy_put(phy);
+                               goto err_phy;
+                       }
+                       hcd->phy = phy;
+               }
+       }
+
        dev_info(hcd->self.controller, "%s\n", hcd->product_desc);
 
        /* Keep old behaviour if authorized_default is not in [0, 1]. */
@@ -2623,7 +2647,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
         */
        if ((retval = hcd_buffer_create(hcd)) != 0) {
                dev_dbg(hcd->self.controller, "pool alloc failed\n");
-               goto err_remove_phy;
+               goto err_create_buf;
        }
 
        if ((retval = usb_register_bus(&hcd->self)) < 0)
@@ -2748,12 +2772,19 @@ err_allocate_root_hub:
        usb_deregister_bus(&hcd->self);
 err_register_bus:
        hcd_buffer_destroy(hcd);
-err_remove_phy:
-       if (hcd->remove_phy && hcd->phy) {
-               usb_phy_shutdown(hcd->phy);
-               usb_put_phy(hcd->phy);
+err_create_buf:
+       if (IS_ENABLED(CONFIG_GENERIC_PHY) && hcd->phy) {
+               phy_power_off(hcd->phy);
+               phy_exit(hcd->phy);
+               phy_put(hcd->phy);
                hcd->phy = NULL;
        }
+err_phy:
+       if (hcd->remove_phy && hcd->usb_phy) {
+               usb_phy_shutdown(hcd->usb_phy);
+               usb_put_phy(hcd->usb_phy);
+               hcd->usb_phy = NULL;
+       }
        return retval;
 }
 EXPORT_SYMBOL_GPL(usb_add_hcd);
@@ -2826,11 +2857,18 @@ void usb_remove_hcd(struct usb_hcd *hcd)
        usb_put_dev(hcd->self.root_hub);
        usb_deregister_bus(&hcd->self);
        hcd_buffer_destroy(hcd);
-       if (hcd->remove_phy && hcd->phy) {
-               usb_phy_shutdown(hcd->phy);
-               usb_put_phy(hcd->phy);
+
+       if (IS_ENABLED(CONFIG_GENERIC_PHY) && hcd->phy) {
+               phy_power_off(hcd->phy);
+               phy_exit(hcd->phy);
+               phy_put(hcd->phy);
                hcd->phy = NULL;
        }
+       if (hcd->remove_phy && hcd->usb_phy) {
+               usb_phy_shutdown(hcd->usb_phy);
+               usb_put_phy(hcd->usb_phy);
+               hcd->usb_phy = NULL;
+       }
 }
 EXPORT_SYMBOL_GPL(usb_remove_hcd);
 
index d2bd9d7..adcbe18 100644 (file)
@@ -404,30 +404,35 @@ static int set_port_feature(struct usb_device *hdev, int port1, int feature)
                NULL, 0, 1000);
 }
 
+static char *to_led_name(int selector)
+{
+       switch (selector) {
+       case HUB_LED_AMBER:
+               return "amber";
+       case HUB_LED_GREEN:
+               return "green";
+       case HUB_LED_OFF:
+               return "off";
+       case HUB_LED_AUTO:
+               return "auto";
+       default:
+               return "??";
+       }
+}
+
 /*
  * USB 2.0 spec Section 11.24.2.7.1.10 and table 11-7
  * for info about using port indicators
  */
-static void set_port_led(
-       struct usb_hub *hub,
-       int port1,
-       int selector
-)
+static void set_port_led(struct usb_hub *hub, int port1, int selector)
 {
-       int status = set_port_feature(hub->hdev, (selector << 8) | port1,
+       struct usb_port *port_dev = hub->ports[port1 - 1];
+       int status;
+
+       status = set_port_feature(hub->hdev, (selector << 8) | port1,
                        USB_PORT_FEAT_INDICATOR);
-       if (status < 0)
-               dev_dbg (hub->intfdev,
-                       "port %d indicator %s status %d\n",
-                       port1,
-                       ({ char *s; switch (selector) {
-                       case HUB_LED_AMBER: s = "amber"; break;
-                       case HUB_LED_GREEN: s = "green"; break;
-                       case HUB_LED_OFF: s = "off"; break;
-                       case HUB_LED_AUTO: s = "auto"; break;
-                       default: s = "??"; break;
-                       } s; }),
-                       status);
+       dev_dbg(&port_dev->dev, "indicator %s status %d\n",
+               to_led_name(selector), status);
 }
 
 #define        LED_CYCLE_PERIOD        ((2*HZ)/3)
@@ -809,8 +814,6 @@ static unsigned hub_power_on(struct usb_hub *hub, bool do_delay)
        int port1;
        unsigned pgood_delay = hub->descriptor->bPwrOn2PwrGood * 2;
        unsigned delay;
-       u16 wHubCharacteristics =
-                       le16_to_cpu(hub->descriptor->wHubCharacteristics);
 
        /* Enable power on each port.  Some hubs have reserved values
         * of LPSM (> 2) in their descriptors, even though they are
@@ -818,7 +821,7 @@ static unsigned hub_power_on(struct usb_hub *hub, bool do_delay)
         * but only emulate it.  In all cases, the ports won't work
         * unless we send these messages to the hub.
         */
-       if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2)
+       if (hub_is_port_power_switchable(hub))
                dev_dbg(hub->intfdev, "enabling power on all ports\n");
        else
                dev_dbg(hub->intfdev, "trying to enable port power on "
@@ -921,20 +924,20 @@ static int hub_usb3_port_disable(struct usb_hub *hub, int port1)
                msleep(HUB_DEBOUNCE_STEP);
        }
        if (total_time >= HUB_DEBOUNCE_TIMEOUT)
-               dev_warn(hub->intfdev, "Could not disable port %d after %d ms\n",
-                               port1, total_time);
+               dev_warn(&hub->ports[port1 - 1]->dev,
+                               "Could not disable after %d ms\n", total_time);
 
        return hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_RX_DETECT);
 }
 
 static int hub_port_disable(struct usb_hub *hub, int port1, int set_state)
 {
+       struct usb_port *port_dev = hub->ports[port1 - 1];
        struct usb_device *hdev = hub->hdev;
        int ret = 0;
 
-       if (hub->ports[port1 - 1]->child && set_state)
-               usb_set_device_state(hub->ports[port1 - 1]->child,
-                               USB_STATE_NOTATTACHED);
+       if (port_dev->child && set_state)
+               usb_set_device_state(port_dev->child, USB_STATE_NOTATTACHED);
        if (!hub->error) {
                if (hub_is_superspeed(hub->hdev))
                        ret = hub_usb3_port_disable(hub, port1);
@@ -943,8 +946,7 @@ static int hub_port_disable(struct usb_hub *hub, int port1, int set_state)
                                        USB_PORT_FEAT_ENABLE);
        }
        if (ret && ret != -ENODEV)
-               dev_err(hub->intfdev, "cannot disable port %d (err = %d)\n",
-                               port1, ret);
+               dev_err(&port_dev->dev, "cannot disable (err = %d)\n", ret);
        return ret;
 }
 
@@ -955,7 +957,7 @@ static int hub_port_disable(struct usb_hub *hub, int port1, int set_state)
  */
 static void hub_port_logical_disconnect(struct usb_hub *hub, int port1)
 {
-       dev_dbg(hub->intfdev, "logical disconnect on port %d\n", port1);
+       dev_dbg(&hub->ports[port1 - 1]->dev, "logical disconnect\n");
        hub_port_disable(hub, port1, 1);
 
        /* FIXME let caller ask to power down the port:
@@ -1092,21 +1094,23 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
        }
  init2:
 
-       /* Check each port and set hub->change_bits to let khubd know
+       /*
+        * Check each port and set hub->change_bits to let khubd know
         * which ports need attention.
         */
        for (port1 = 1; port1 <= hdev->maxchild; ++port1) {
-               struct usb_device *udev = hub->ports[port1 - 1]->child;
+               struct usb_port *port_dev = hub->ports[port1 - 1];
+               struct usb_device *udev = port_dev->child;
                u16 portstatus, portchange;
 
                portstatus = portchange = 0;
                status = hub_port_status(hub, port1, &portstatus, &portchange);
                if (udev || (portstatus & USB_PORT_STAT_CONNECTION))
-                       dev_dbg(hub->intfdev,
-                                       "port %d: status %04x change %04x\n",
-                                       port1, portstatus, portchange);
+                       dev_dbg(&port_dev->dev, "status %04x change %04x\n",
+                                       portstatus, portchange);
 
-               /* After anything other than HUB_RESUME (i.e., initialization
+               /*
+                * After anything other than HUB_RESUME (i.e., initialization
                 * or any sort of reset), every port should be disabled.
                 * Unconnected ports should likewise be disabled (paranoia),
                 * and so should ports for which we have no usb_device.
@@ -2585,9 +2589,9 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1,
                if (delay_time >= 2 * HUB_SHORT_RESET_TIME)
                        delay = HUB_LONG_RESET_TIME;
 
-               dev_dbg (hub->intfdev,
-                       "port %d not %sreset yet, waiting %dms\n",
-                       port1, warm ? "warm " : "", delay);
+               dev_dbg(&hub->ports[port1 - 1]->dev,
+                               "not %sreset yet, waiting %dms\n",
+                               warm ? "warm " : "", delay);
        }
 
        if ((portstatus & USB_PORT_STAT_RESET))
@@ -2671,6 +2675,7 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
 {
        int i, status;
        u16 portchange, portstatus;
+       struct usb_port *port_dev = hub->ports[port1 - 1];
 
        if (!hub_is_superspeed(hub->hdev)) {
                if (warm) {
@@ -2704,9 +2709,9 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
                if (status == -ENODEV) {
                        ;       /* The hub is gone */
                } else if (status) {
-                       dev_err(hub->intfdev,
-                                       "cannot %sreset port %d (err = %d)\n",
-                                       warm ? "warm " : "", port1, status);
+                       dev_err(&port_dev->dev,
+                                       "cannot %sreset (err = %d)\n",
+                                       warm ? "warm " : "", status);
                } else {
                        status = hub_port_wait_reset(hub, port1, udev, delay,
                                                                warm);
@@ -2739,21 +2744,19 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
                         * hot or warm reset failed.  Try another warm reset.
                         */
                        if (!warm) {
-                               dev_dbg(hub->intfdev, "hot reset failed, warm reset port %d\n",
-                                               port1);
+                               dev_dbg(&port_dev->dev,
+                                               "hot reset failed, warm reset\n");
                                warm = true;
                        }
                }
 
-               dev_dbg (hub->intfdev,
-                       "port %d not enabled, trying %sreset again...\n",
-                       port1, warm ? "warm " : "");
+               dev_dbg(&port_dev->dev,
+                               "not enabled, trying %sreset again...\n",
+                               warm ? "warm " : "");
                delay = HUB_LONG_RESET_TIME;
        }
 
-       dev_err (hub->intfdev,
-               "Cannot enable port %i.  Maybe the USB cable is bad?\n",
-               port1);
+       dev_err(&port_dev->dev, "Cannot enable. Maybe the USB cable is bad?\n");
 
 done:
        if (!hub_is_superspeed(hub->hdev))
@@ -2804,6 +2807,8 @@ static int check_port_resume_type(struct usb_device *udev,
                struct usb_hub *hub, int port1,
                int status, unsigned portchange, unsigned portstatus)
 {
+       struct usb_port *port_dev = hub->ports[port1 - 1];
+
        /* Is the device still present? */
        if (status || port_is_suspended(hub, portstatus) ||
                        !port_is_power_on(hub, portstatus) ||
@@ -2823,9 +2828,8 @@ static int check_port_resume_type(struct usb_device *udev,
        }
 
        if (status) {
-               dev_dbg(hub->intfdev,
-                               "port %d status %04x.%04x after resume, %d\n",
-                               port1, portchange, portstatus, status);
+               dev_dbg(&port_dev->dev, "status %04x.%04x after resume, %d\n",
+                               portchange, portstatus, status);
        } else if (udev->reset_resume) {
 
                /* Late port handoff can set status-change bits */
@@ -3056,8 +3060,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
                status = 0;
        }
        if (status) {
-               dev_dbg(hub->intfdev, "can't suspend port %d, status %d\n",
-                               port1, status);
+               dev_dbg(&port_dev->dev, "can't suspend, status %d\n", status);
 
                /* Try to enable USB3 LPM and LTM again */
                usb_unlocked_enable_lpm(udev);
@@ -3275,8 +3278,6 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg)
        if (status == 0 && !port_is_suspended(hub, portstatus))
                goto SuspendCleared;
 
-       /* dev_dbg(hub->intfdev, "resume port %d\n", port1); */
-
        set_bit(port1, hub->busy_bits);
 
        /* see 7.1.7.7; affects power usage, but not budgeting */
@@ -3286,8 +3287,7 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg)
                status = usb_clear_port_feature(hub->hdev,
                                port1, USB_PORT_FEAT_SUSPEND);
        if (status) {
-               dev_dbg(hub->intfdev, "can't resume port %d, status %d\n",
-                               port1, status);
+               dev_dbg(&port_dev->dev, "can't resume, status %d\n", status);
        } else {
                /* drive resume for at least 20 msec */
                dev_dbg(&udev->dev, "usb %sresume\n",
@@ -3392,12 +3392,11 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
         */
        hub->wakeup_enabled_descendants = 0;
        for (port1 = 1; port1 <= hdev->maxchild; port1++) {
-               struct usb_device       *udev;
+               struct usb_port *port_dev = hub->ports[port1 - 1];
+               struct usb_device *udev = port_dev->child;
 
-               udev = hub->ports[port1 - 1]->child;
                if (udev && udev->can_submit) {
-                       dev_warn(&intf->dev, "port %d not suspended yet\n",
-                                       port1);
+                       dev_warn(&port_dev->dev, "not suspended yet\n");
                        if (PMSG_IS_AUTO(msg))
                                return -EBUSY;
                }
@@ -3937,9 +3936,10 @@ EXPORT_SYMBOL_GPL(usb_enable_ltm);
 int hub_port_debounce(struct usb_hub *hub, int port1, bool must_be_connected)
 {
        int ret;
-       int total_time, stable_time = 0;
        u16 portchange, portstatus;
        unsigned connection = 0xffff;
+       int total_time, stable_time = 0;
+       struct usb_port *port_dev = hub->ports[port1 - 1];
 
        for (total_time = 0; ; total_time += HUB_DEBOUNCE_STEP) {
                ret = hub_port_status(hub, port1, &portstatus, &portchange);
@@ -3968,9 +3968,8 @@ int hub_port_debounce(struct usb_hub *hub, int port1, bool must_be_connected)
                msleep(HUB_DEBOUNCE_STEP);
        }
 
-       dev_dbg (hub->intfdev,
-               "debounce: port %d: total %dms stable %dms status 0x%x\n",
-               port1, total_time, stable_time, portstatus);
+       dev_dbg(&port_dev->dev, "debounce total %dms stable %dms status 0x%x\n",
+                       total_time, stable_time, portstatus);
 
        if (stable_time < HUB_DEBOUNCE_STABLE)
                return -ETIMEDOUT;
@@ -4029,13 +4028,14 @@ static int hub_set_address(struct usb_device *udev, int devnum)
  */
 static void hub_set_initial_usb2_lpm_policy(struct usb_device *udev)
 {
-       int connect_type;
+       struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent);
+       int connect_type = USB_PORT_CONNECT_TYPE_UNKNOWN;
 
        if (!udev->usb2_hw_lpm_capable)
                return;
 
-       connect_type = usb_get_hub_port_connect_type(udev->parent,
-                       udev->portnum);
+       if (hub)
+               connect_type = hub->ports[udev->portnum - 1]->connect_type;
 
        if ((udev->bos->ext_cap->bmAttributes & USB_BESL_SUPPORT) ||
                        connect_type == USB_PORT_CONNECT_TYPE_HARD_WIRED) {
@@ -4301,8 +4301,8 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
        if (retval)
                goto fail;
 
-       if (hcd->phy && !hdev->parent)
-               usb_phy_notify_connect(hcd->phy, udev->speed);
+       if (hcd->usb_phy && !hdev->parent)
+               usb_phy_notify_connect(hcd->usb_phy, udev->speed);
 
        /*
         * Some superspeed devices have finished the link training process
@@ -4411,9 +4411,10 @@ hub_power_remaining (struct usb_hub *hub)
 
        remaining = hdev->bus_mA - hub->descriptor->bHubContrCurrent;
        for (port1 = 1; port1 <= hdev->maxchild; ++port1) {
-               struct usb_device       *udev = hub->ports[port1 - 1]->child;
-               int                     delta;
-               unsigned                unit_load;
+               struct usb_port *port_dev = hub->ports[port1 - 1];
+               struct usb_device *udev = port_dev->child;
+               unsigned unit_load;
+               int delta;
 
                if (!udev)
                        continue;
@@ -4433,9 +4434,8 @@ hub_power_remaining (struct usb_hub *hub)
                else
                        delta = 8;
                if (delta > hub->mA_per_port)
-                       dev_warn(&udev->dev,
-                                "%dmA is over %umA budget for port %d!\n",
-                                delta, hub->mA_per_port, port1);
+                       dev_warn(&port_dev->dev, "%dmA is over %umA budget!\n",
+                                       delta, hub->mA_per_port);
                remaining -= delta;
        }
        if (remaining < 0) {
@@ -4458,17 +4458,14 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
                                        u16 portstatus, u16 portchange)
 {
        struct usb_device *hdev = hub->hdev;
-       struct device *hub_dev = hub->intfdev;
        struct usb_hcd *hcd = bus_to_hcd(hdev->bus);
-       unsigned wHubCharacteristics =
-                       le16_to_cpu(hub->descriptor->wHubCharacteristics);
+       struct usb_port *port_dev = hub->ports[port1 - 1];
        struct usb_device *udev;
        int status, i;
        unsigned unit_load;
 
-       dev_dbg (hub_dev,
-               "port %d, status %04x, change %04x, %s\n",
-               port1, portstatus, portchange, portspeed(hub, portstatus));
+       dev_dbg(&port_dev->dev, "status %04x, change %04x, %s\n",
+                       portstatus, portchange, portspeed(hub, portstatus));
 
        if (hub->has_indicators) {
                set_port_led(hub, port1, HUB_LED_AUTO);
@@ -4483,7 +4480,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
 #endif
 
        /* Try to resuscitate an existing device */
-       udev = hub->ports[port1 - 1]->child;
+       udev = port_dev->child;
        if ((portstatus & USB_PORT_STAT_CONNECTION) && udev &&
                        udev->state != USB_STATE_NOTATTACHED) {
                usb_lock_device(udev);
@@ -4512,10 +4509,10 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
 
        /* Disconnect any existing devices under this port */
        if (udev) {
-               if (hcd->phy && !hdev->parent &&
+               if (hcd->usb_phy && !hdev->parent &&
                                !(portstatus & USB_PORT_STAT_CONNECTION))
-                       usb_phy_notify_disconnect(hcd->phy, udev->speed);
-               usb_disconnect(&hub->ports[port1 - 1]->child);
+                       usb_phy_notify_disconnect(hcd->usb_phy, udev->speed);
+               usb_disconnect(&port_dev->child);
        }
        clear_bit(port1, hub->change_bits);
 
@@ -4531,8 +4528,8 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
                status = hub_port_debounce_be_stable(hub, port1);
                if (status < 0) {
                        if (status != -ENODEV && printk_ratelimit())
-                               dev_err(hub_dev, "connect-debounce failed, "
-                                               "port %d disabled\n", port1);
+                               dev_err(&port_dev->dev,
+                                               "connect-debounce failed\n");
                        portstatus &= ~USB_PORT_STAT_CONNECTION;
                } else {
                        portstatus = status;
@@ -4546,7 +4543,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
                        test_bit(port1, hub->removed_bits)) {
 
                /* maybe switch power back on (e.g. root hub was reset) */
-               if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2
+               if (hub_is_port_power_switchable(hub)
                                && !port_is_power_on(hub, portstatus))
                        set_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
 
@@ -4567,9 +4564,8 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
                 */
                udev = usb_alloc_dev(hdev, hdev->bus, port1);
                if (!udev) {
-                       dev_err (hub_dev,
-                               "couldn't allocate port %d usb_device\n",
-                               port1);
+                       dev_err(&port_dev->dev,
+                                       "couldn't allocate usb_device\n");
                        goto done;
                }
 
@@ -4649,7 +4645,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
                if (hdev->state == USB_STATE_NOTATTACHED)
                        status = -ENOTCONN;
                else
-                       hub->ports[port1 - 1]->child = udev;
+                       port_dev->child = udev;
                spin_unlock_irq(&device_state_lock);
 
                /* Run it through the hoops (find a driver, etc) */
@@ -4657,7 +4653,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
                        status = usb_new_device(udev);
                        if (status) {
                                spin_lock_irq(&device_state_lock);
-                               hub->ports[port1 - 1]->child = NULL;
+                               port_dev->child = NULL;
                                spin_unlock_irq(&device_state_lock);
                        }
                }
@@ -4667,7 +4663,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
 
                status = hub_power_remaining(hub);
                if (status)
-                       dev_dbg(hub_dev, "%dmA power budget left\n", status);
+                       dev_dbg(hub->intfdev, "%dmA power budget left\n", status);
 
                return;
 
@@ -4685,8 +4681,8 @@ loop:
                        !hcd->driver->port_handed_over ||
                        !(hcd->driver->port_handed_over)(hcd, port1)) {
                if (status != -ENOTCONN && status != -ENODEV)
-                       dev_err(hub_dev, "unable to enumerate USB device on port %d\n",
-                                       port1);
+                       dev_err(&port_dev->dev,
+                                       "unable to enumerate USB device\n");
        }
 
 done:
@@ -4699,13 +4695,14 @@ done:
 static int hub_handle_remote_wakeup(struct usb_hub *hub, unsigned int port,
                u16 portstatus, u16 portchange)
 {
+       struct usb_port *port_dev = hub->ports[port - 1];
        struct usb_device *hdev;
        struct usb_device *udev;
        int connect_change = 0;
        int ret;
 
        hdev = hub->hdev;
-       udev = hub->ports[port - 1]->child;
+       udev = port_dev->child;
        if (!hub_is_superspeed(hdev)) {
                if (!(portchange & USB_PORT_STAT_C_SUSPEND))
                        return 0;
@@ -4730,8 +4727,7 @@ static int hub_handle_remote_wakeup(struct usb_hub *hub, unsigned int port,
                ret = -ENODEV;
                hub_port_disable(hub, port, 1);
        }
-       dev_dbg(hub->intfdev, "resume on port %d, status %d\n",
-                       port, ret);
+       dev_dbg(&port_dev->dev, "resume, status %d\n", ret);
        return connect_change;
 }
 
@@ -4822,6 +4818,9 @@ static void hub_events(void)
 
                /* deal with port status changes */
                for (i = 1; i <= hdev->maxchild; i++) {
+                       struct usb_port *port_dev = hub->ports[i - 1];
+                       struct usb_device *udev = port_dev->child;
+
                        if (test_bit(i, hub->busy_bits))
                                continue;
                        connect_change = test_bit(i, hub->change_bits);
@@ -4843,10 +4842,9 @@ static void hub_events(void)
 
                        if (portchange & USB_PORT_STAT_C_ENABLE) {
                                if (!connect_change)
-                                       dev_dbg (hub_dev,
-                                               "port %d enable change, "
-                                               "status %08x\n",
-                                               i, portstatus);
+                                       dev_dbg(&port_dev->dev,
+                                                       "enable change, status %08x\n",
+                                                        portstatus);
                                usb_clear_port_feature(hdev, i,
                                        USB_PORT_FEAT_C_ENABLE);
 
@@ -4857,13 +4855,9 @@ static void hub_events(void)
                                 * Works at least with mouse driver.
                                 */
                                if (!(portstatus & USB_PORT_STAT_ENABLE)
-                                   && !connect_change
-                                   && hub->ports[i - 1]->child) {
-                                       dev_err (hub_dev,
-                                           "port %i "
-                                           "disabled by hub (EMI?), "
-                                           "re-enabling...\n",
-                                               i);
+                                   && !connect_change && udev) {
+                                       dev_err(&port_dev->dev,
+                                                       "disabled by hub (EMI?), re-enabling...\n");
                                        connect_change = 1;
                                }
                        }
@@ -4876,30 +4870,25 @@ static void hub_events(void)
                                u16 status = 0;
                                u16 unused;
 
-                               dev_dbg(hub_dev, "over-current change on port "
-                                       "%d\n", i);
+                               dev_dbg(&port_dev->dev, "over-current change\n");
                                usb_clear_port_feature(hdev, i,
                                        USB_PORT_FEAT_C_OVER_CURRENT);
                                msleep(100);    /* Cool down */
                                hub_power_on(hub, true);
                                hub_port_status(hub, i, &status, &unused);
                                if (status & USB_PORT_STAT_OVERCURRENT)
-                                       dev_err(hub_dev, "over-current "
-                                               "condition on port %d\n", i);
+                                       dev_err(&port_dev->dev,
+                                                       "over-current condition\n");
                        }
 
                        if (portchange & USB_PORT_STAT_C_RESET) {
-                               dev_dbg (hub_dev,
-                                       "reset change on port %d\n",
-                                       i);
+                               dev_dbg(&port_dev->dev, "reset change\n");
                                usb_clear_port_feature(hdev, i,
                                        USB_PORT_FEAT_C_RESET);
                        }
                        if ((portchange & USB_PORT_STAT_C_BH_RESET) &&
                                        hub_is_superspeed(hub->hdev)) {
-                               dev_dbg(hub_dev,
-                                       "warm reset change on port %d\n",
-                                       i);
+                               dev_dbg(&port_dev->dev, "warm reset change\n");
                                usb_clear_port_feature(hdev, i,
                                        USB_PORT_FEAT_C_BH_PORT_RESET);
                        }
@@ -4908,9 +4897,7 @@ static void hub_events(void)
                                                USB_PORT_FEAT_C_PORT_LINK_STATE);
                        }
                        if (portchange & USB_PORT_STAT_C_CONFIG_ERROR) {
-                               dev_warn(hub_dev,
-                                       "config error on port %d\n",
-                                       i);
+                               dev_warn(&port_dev->dev, "config error\n");
                                usb_clear_port_feature(hub->hdev, i,
                                                USB_PORT_FEAT_C_PORT_CONFIG_ERROR);
                        }
@@ -4920,10 +4907,8 @@ static void hub_events(void)
                         */
                        if (hub_port_warm_reset_required(hub, portstatus)) {
                                int status;
-                               struct usb_device *udev =
-                                       hub->ports[i - 1]->child;
 
-                               dev_dbg(hub_dev, "warm reset port %d\n", i);
+                               dev_dbg(&port_dev->dev, "warm reset\n");
                                if (!udev ||
                                    !(portstatus & USB_PORT_STAT_CONNECTION) ||
                                    udev->state == USB_STATE_NOTATTACHED) {
@@ -4938,6 +4923,24 @@ static void hub_events(void)
                                        usb_unlock_device(udev);
                                        connect_change = 0;
                                }
+                       /*
+                        * On disconnect USB3 protocol ports transit from U0 to
+                        * SS.Inactive to Rx.Detect. If this happens a warm-
+                        * reset is not needed, but a (re)connect may happen
+                        * before khubd runs and sees the disconnect, and the
+                        * device may be an unknown state.
+                        *
+                        * If the port went through SS.Inactive without khubd
+                        * seeing it the C_LINK_STATE change flag will be set,
+                        * and we reset the dev to put it in a known state.
+                        */
+                       } else if (udev && hub_is_superspeed(hub->hdev) &&
+                                  (portchange & USB_PORT_STAT_C_LINK_STATE) &&
+                                  (portstatus & USB_PORT_STAT_CONNECTION)) {
+                               usb_lock_device(udev);
+                               usb_reset_device(udev);
+                               usb_unlock_device(udev);
+                               connect_change = 0;
                        }
 
                        if (connect_change)
@@ -5504,56 +5507,26 @@ struct usb_device *usb_hub_find_child(struct usb_device *hdev,
 }
 EXPORT_SYMBOL_GPL(usb_hub_find_child);
 
-/**
- * usb_set_hub_port_connect_type - set hub port connect type.
- * @hdev: USB device belonging to the usb hub
- * @port1: port num of the port
- * @type: connect type of the port
- */
-void usb_set_hub_port_connect_type(struct usb_device *hdev, int port1,
-       enum usb_port_connect_type type)
-{
-       struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
-
-       if (hub)
-               hub->ports[port1 - 1]->connect_type = type;
-}
-
-/**
- * usb_get_hub_port_connect_type - Get the port's connect type
- * @hdev: USB device belonging to the usb hub
- * @port1: port num of the port
- *
- * Return: The connect type of the port if successful. Or
- * USB_PORT_CONNECT_TYPE_UNKNOWN if input params are invalid.
- */
-enum usb_port_connect_type
-usb_get_hub_port_connect_type(struct usb_device *hdev, int port1)
-{
-       struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
-
-       if (!hub)
-               return USB_PORT_CONNECT_TYPE_UNKNOWN;
-
-       return hub->ports[port1 - 1]->connect_type;
-}
-
 void usb_hub_adjust_deviceremovable(struct usb_device *hdev,
                struct usb_hub_descriptor *desc)
 {
+       struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
        enum usb_port_connect_type connect_type;
        int i;
 
+       if (!hub)
+               return;
+
        if (!hub_is_superspeed(hdev)) {
                for (i = 1; i <= hdev->maxchild; i++) {
-                       connect_type = usb_get_hub_port_connect_type(hdev, i);
+                       struct usb_port *port_dev = hub->ports[i - 1];
 
+                       connect_type = port_dev->connect_type;
                        if (connect_type == USB_PORT_CONNECT_TYPE_HARD_WIRED) {
                                u8 mask = 1 << (i%8);
 
                                if (!(desc->u.hs.DeviceRemovable[i/8] & mask)) {
-                                       dev_dbg(&hdev->dev, "usb port%d's DeviceRemovable is changed to 1 according to platform information.\n",
-                                               i);
+                                       dev_dbg(&port_dev->dev, "DeviceRemovable is changed to 1 according to platform information.\n");
                                        desc->u.hs.DeviceRemovable[i/8] |= mask;
                                }
                        }
@@ -5562,14 +5535,14 @@ void usb_hub_adjust_deviceremovable(struct usb_device *hdev,
                u16 port_removable = le16_to_cpu(desc->u.ss.DeviceRemovable);
 
                for (i = 1; i <= hdev->maxchild; i++) {
-                       connect_type = usb_get_hub_port_connect_type(hdev, i);
+                       struct usb_port *port_dev = hub->ports[i - 1];
 
+                       connect_type = port_dev->connect_type;
                        if (connect_type == USB_PORT_CONNECT_TYPE_HARD_WIRED) {
                                u16 mask = 1 << i;
 
                                if (!(port_removable & mask)) {
-                                       dev_dbg(&hdev->dev, "usb port%d's DeviceRemovable is changed to 1 according to platform information.\n",
-                                               i);
+                                       dev_dbg(&port_dev->dev, "DeviceRemovable is changed to 1 according to platform information.\n");
                                        port_removable |= mask;
                                }
                        }
index df629a3..baf5b48 100644 (file)
@@ -111,6 +111,16 @@ extern int hub_port_debounce(struct usb_hub *hub, int port1,
 extern int usb_clear_port_feature(struct usb_device *hdev,
                int port1, int feature);
 
+static inline bool hub_is_port_power_switchable(struct usb_hub *hub)
+{
+       __le16 hcs;
+
+       if (!hub)
+               return false;
+       hcs = hub->descriptor->wHubCharacteristics;
+       return (le16_to_cpu(hcs) & HUB_CHAR_LPSM) < HUB_CHAR_NO_LPSM;
+}
+
 static inline int hub_port_debounce_be_connected(struct usb_hub *hub,
                int port1)
 {
index 51542f8..531a591 100644 (file)
@@ -146,6 +146,11 @@ struct device_type usb_port_device_type = {
        .pm =           &usb_port_pm_ops,
 };
 
+static struct device_driver usb_port_driver = {
+       .name = "usb",
+       .owner = THIS_MODULE,
+};
+
 int usb_hub_create_port_device(struct usb_hub *hub, int port1)
 {
        struct usb_port *port_dev = NULL;
@@ -163,20 +168,24 @@ int usb_hub_create_port_device(struct usb_hub *hub, int port1)
        port_dev->dev.parent = hub->intfdev;
        port_dev->dev.groups = port_dev_group;
        port_dev->dev.type = &usb_port_device_type;
-       dev_set_name(&port_dev->dev, "port%d", port1);
-
+       port_dev->dev.driver = &usb_port_driver;
+       dev_set_name(&port_dev->dev, "%s-port%d", dev_name(&hub->hdev->dev),
+                       port1);
        retval = device_register(&port_dev->dev);
        if (retval)
                goto error_register;
 
        pm_runtime_set_active(&port_dev->dev);
 
-       /* It would be dangerous if user space couldn't
-        * prevent usb device from being powered off. So don't
-        * enable port runtime pm if failed to expose port's pm qos.
+       /*
+        * Do not enable port runtime pm if the hub does not support
+        * power switching.  Also, userspace must have final say of
+        * whether a port is permitted to power-off.  Do not enable
+        * runtime pm if we fail to expose pm_qos_no_power_off.
         */
-       if (!dev_pm_qos_expose_flags(&port_dev->dev,
-                       PM_QOS_FLAG_NO_POWER_OFF))
+       if (hub_is_port_power_switchable(hub)
+                       && dev_pm_qos_expose_flags(&port_dev->dev,
+                       PM_QOS_FLAG_NO_POWER_OFF) == 0)
                pm_runtime_enable(&port_dev->dev);
 
        device_enable_async_suspend(&port_dev->dev);
index c854593..b195fdb 100644 (file)
@@ -44,6 +44,9 @@ static const struct usb_device_id usb_quirk_list[] = {
        /* Creative SB Audigy 2 NX */
        { USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME },
 
+       /* Microsoft Wireless Laser Mouse 6000 Receiver */
+       { USB_DEVICE(0x045e, 0x00e1), .driver_info = USB_QUIRK_RESET_RESUME },
+
        /* Microsoft LifeCam-VX700 v2.0 */
        { USB_DEVICE(0x045e, 0x0770), .driver_info = USB_QUIRK_RESET_RESUME },
 
index 5ca4070..f91ef02 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/pci.h>
 #include <linux/usb/hcd.h>
 
-#include "usb.h"
+#include "hub.h"
 
 /**
  * usb_acpi_power_manageable - check whether usb port has
@@ -55,13 +55,18 @@ EXPORT_SYMBOL_GPL(usb_acpi_power_manageable);
  */
 int usb_acpi_set_power_state(struct usb_device *hdev, int index, bool enable)
 {
+       struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
+       struct usb_port *port_dev;
        acpi_handle port_handle;
        unsigned char state;
        int port1 = index + 1;
        int error = -EINVAL;
 
-       port_handle = (acpi_handle)usb_get_hub_port_acpi_handle(hdev,
-               port1);
+       if (!hub)
+               return -ENODEV;
+       port_dev = hub->ports[port1 - 1];
+
+       port_handle = (acpi_handle) usb_get_hub_port_acpi_handle(hdev, port1);
        if (!port_handle)
                return error;
 
@@ -72,10 +77,9 @@ int usb_acpi_set_power_state(struct usb_device *hdev, int index, bool enable)
 
        error = acpi_bus_set_power(port_handle, state);
        if (!error)
-               dev_dbg(&hdev->dev, "The power of hub port %d was set to %d\n",
-                       port1, enable);
+               dev_dbg(&port_dev->dev, "acpi: power was set to %d\n", enable);
        else
-               dev_dbg(&hdev->dev, "The power of hub port failed to be set\n");
+               dev_dbg(&port_dev->dev, "acpi: power failed to be set\n");
 
        return error;
 }
@@ -84,12 +88,17 @@ EXPORT_SYMBOL_GPL(usb_acpi_set_power_state);
 static int usb_acpi_check_port_connect_type(struct usb_device *hdev,
        acpi_handle handle, int port1)
 {
-       acpi_status status;
+       enum usb_port_connect_type connect_type = USB_PORT_CONNECT_TYPE_UNKNOWN;
        struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
-       union acpi_object *upc;
+       struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
        struct acpi_pld_info *pld;
+       union acpi_object *upc;
+       acpi_status status;
        int ret = 0;
 
+       if (!hub)
+               return 0;
+
        /*
         * According to ACPI Spec 9.13. PLD indicates whether usb port is
         * user visible and _UPC indicates whether it is connectable. If
@@ -112,13 +121,12 @@ static int usb_acpi_check_port_connect_type(struct usb_device *hdev,
 
        if (upc->package.elements[0].integer.value)
                if (pld->user_visible)
-                       usb_set_hub_port_connect_type(hdev, port1,
-                               USB_PORT_CONNECT_TYPE_HOT_PLUG);
+                       connect_type = USB_PORT_CONNECT_TYPE_HOT_PLUG;
                else
-                       usb_set_hub_port_connect_type(hdev, port1,
-                               USB_PORT_CONNECT_TYPE_HARD_WIRED);
+                       connect_type = USB_PORT_CONNECT_TYPE_HARD_WIRED;
        else if (!pld->user_visible)
-               usb_set_hub_port_connect_type(hdev, port1, USB_PORT_NOT_USED);
+               connect_type = USB_PORT_NOT_USED;
+       hub->ports[port1 - 1]->connect_type = connect_type;
 
 out:
        ACPI_FREE(pld);
@@ -128,9 +136,9 @@ out:
 
 static struct acpi_device *usb_acpi_find_companion(struct device *dev)
 {
+       int port1;
        struct usb_device *udev;
        acpi_handle *parent_handle;
-       int port_num;
 
        /*
         * In the ACPI DSDT table, only usb root hub and usb ports are
@@ -147,16 +155,16 @@ static struct acpi_device *usb_acpi_find_companion(struct device *dev)
         */
        if (is_usb_device(dev)) {
                udev = to_usb_device(dev);
+               port1 = udev->portnum;
                if (udev->parent) {
-                       enum usb_port_connect_type type;
+                       struct usb_hub *hub;
 
+                       hub = usb_hub_to_struct_hub(udev->parent);
                        /*
                         * According usb port's connect type to set usb device's
                         * removability.
                         */
-                       type = usb_get_hub_port_connect_type(udev->parent,
-                               udev->portnum);
-                       switch (type) {
+                       switch (hub->ports[port1 - 1]->connect_type) {
                        case USB_PORT_CONNECT_TYPE_HOT_PLUG:
                                udev->removable = USB_DEVICE_REMOVABLE;
                                break;
@@ -173,13 +181,14 @@ static struct acpi_device *usb_acpi_find_companion(struct device *dev)
 
                /* root hub's parent is the usb hcd. */
                return acpi_find_child_device(ACPI_COMPANION(dev->parent),
-                                             udev->portnum, false);
+                               port1, false);
        } else if (is_usb_port(dev)) {
+               struct usb_port *port_dev = to_usb_port(dev);
                struct acpi_device *adev = NULL;
 
-               sscanf(dev_name(dev), "port%d", &port_num);
                /* Get the struct usb_device point of port's hub */
                udev = to_usb_device(dev->parent->parent);
+               port1 = port_dev->portnum;
 
                /*
                 * The root hub ports' parent is the root hub. The non-root-hub
@@ -188,12 +197,11 @@ static struct acpi_device *usb_acpi_find_companion(struct device *dev)
                 */
                if (!udev->parent) {
                        struct usb_hcd *hcd = bus_to_hcd(udev->bus);
-                       int raw_port_num;
+                       int raw;
 
-                       raw_port_num = usb_hcd_find_raw_port_number(hcd,
-                               port_num);
+                       raw = usb_hcd_find_raw_port_number(hcd, port1);
                        adev = acpi_find_child_device(ACPI_COMPANION(&udev->dev),
-                                                     raw_port_num, false);
+                                       raw, false);
                        if (!adev)
                                return NULL;
                } else {
@@ -204,11 +212,11 @@ static struct acpi_device *usb_acpi_find_companion(struct device *dev)
                                return NULL;
 
                        acpi_bus_get_device(parent_handle, &adev);
-                       adev = acpi_find_child_device(adev, port_num, false);
+                       adev = acpi_find_child_device(adev, port1, false);
                        if (!adev)
                                return NULL;
                }
-               usb_acpi_check_port_connect_type(udev, adev->handle, port_num);
+               usb_acpi_check_port_connect_type(udev, adev->handle, port1);
                return adev;
        }
 
index 0923add..981d340 100644 (file)
@@ -179,10 +179,6 @@ extern void usb_notify_add_device(struct usb_device *udev);
 extern void usb_notify_remove_device(struct usb_device *udev);
 extern void usb_notify_add_bus(struct usb_bus *ubus);
 extern void usb_notify_remove_bus(struct usb_bus *ubus);
-extern enum usb_port_connect_type
-       usb_get_hub_port_connect_type(struct usb_device *hdev, int port1);
-extern void usb_set_hub_port_connect_type(struct usb_device *hdev, int port1,
-       enum usb_port_connect_type type);
 extern void usb_hub_adjust_deviceremovable(struct usb_device *hdev,
                struct usb_hub_descriptor *desc);
 
index cf2734b..4bdcd34 100644 (file)
@@ -136,15 +136,15 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver,
        if (pdata->operating_mode == FSL_USB2_DR_OTG) {
                struct ehci_hcd *ehci = hcd_to_ehci(hcd);
 
-               hcd->phy = usb_get_phy(USB_PHY_TYPE_USB2);
+               hcd->usb_phy = usb_get_phy(USB_PHY_TYPE_USB2);
                dev_dbg(&pdev->dev, "hcd=0x%p  ehci=0x%p, phy=0x%p\n",
-                       hcd, ehci, hcd->phy);
+                       hcd, ehci, hcd->usb_phy);
 
-               if (!IS_ERR_OR_NULL(hcd->phy)) {
-                       retval = otg_set_host(hcd->phy->otg,
+               if (!IS_ERR_OR_NULL(hcd->usb_phy)) {
+                       retval = otg_set_host(hcd->usb_phy->otg,
                                              &ehci_to_hcd(ehci)->self);
                        if (retval) {
-                               usb_put_phy(hcd->phy);
+                               usb_put_phy(hcd->usb_phy);
                                goto err2;
                        }
                } else {
@@ -181,9 +181,9 @@ static void usb_hcd_fsl_remove(struct usb_hcd *hcd,
 {
        struct fsl_usb2_platform_data *pdata = dev_get_platdata(&pdev->dev);
 
-       if (!IS_ERR_OR_NULL(hcd->phy)) {
-               otg_set_host(hcd->phy->otg, NULL);
-               usb_put_phy(hcd->phy);
+       if (!IS_ERR_OR_NULL(hcd->usb_phy)) {
+               otg_set_host(hcd->usb_phy->otg, NULL);
+               usb_put_phy(hcd->usb_phy);
        }
 
        usb_remove_hcd(hcd);
index 7d6f64c..28a5b48 100644 (file)
@@ -931,7 +931,7 @@ static int ehci_hub_control (
 #ifdef CONFIG_USB_OTG
                        if ((hcd->self.otg_port == (wIndex + 1))
                            && hcd->self.b_hnp_enable) {
-                               otg_start_hnp(hcd->phy->otg);
+                               otg_start_hnp(hcd->usb_phy->otg);
                                break;
                        }
 #endif
index f341651..fea9b15 100644 (file)
@@ -125,7 +125,7 @@ static int ehci_msm_probe(struct platform_device *pdev)
                goto put_hcd;
        }
 
-       hcd->phy = phy;
+       hcd->usb_phy = phy;
        device_init_wakeup(&pdev->dev, 1);
        /*
         * OTG device parent of HCD takes care of putting
@@ -152,7 +152,7 @@ static int ehci_msm_remove(struct platform_device *pdev)
        pm_runtime_disable(&pdev->dev);
        pm_runtime_set_suspended(&pdev->dev);
 
-       otg_set_host(hcd->phy->otg, NULL);
+       otg_set_host(hcd->usb_phy->otg, NULL);
 
        /* FIXME: need to call usb_remove_hcd() here? */
 
index 633dbea..7cc7357 100644 (file)
@@ -158,7 +158,7 @@ static int tegra_ehci_hub_control(
                if (tegra->port_resuming && !(temp & PORT_SUSPEND)) {
                        /* Resume completed, re-enable disconnect detection */
                        tegra->port_resuming = 0;
-                       tegra_usb_phy_postresume(hcd->phy);
+                       tegra_usb_phy_postresume(hcd->usb_phy);
                }
        }
 
@@ -211,7 +211,7 @@ static int tegra_ehci_hub_control(
                        goto done;
 
                /* Disable disconnect detection during port resume */
-               tegra_usb_phy_preresume(hcd->phy);
+               tegra_usb_phy_preresume(hcd->usb_phy);
 
                ehci->reset_done[wIndex-1] = jiffies + msecs_to_jiffies(25);
 
@@ -406,7 +406,7 @@ static int tegra_ehci_probe(struct platform_device *pdev)
                err = PTR_ERR(u_phy);
                goto cleanup_clk_en;
        }
-       hcd->phy = u_phy;
+       hcd->usb_phy = u_phy;
 
        tegra->needs_double_reset = of_property_read_bool(pdev->dev.of_node,
                "nvidia,needs-double-reset");
@@ -428,7 +428,7 @@ static int tegra_ehci_probe(struct platform_device *pdev)
        ehci->caps = hcd->regs + 0x100;
        ehci->has_hostpc = soc_config->has_hostpc;
 
-       err = usb_phy_init(hcd->phy);
+       err = usb_phy_init(hcd->usb_phy);
        if (err) {
                dev_err(&pdev->dev, "Failed to initialize phy\n");
                goto cleanup_clk_en;
@@ -443,7 +443,7 @@ static int tegra_ehci_probe(struct platform_device *pdev)
        }
        u_phy->otg->host = hcd_to_bus(hcd);
 
-       err = usb_phy_set_suspend(hcd->phy, 0);
+       err = usb_phy_set_suspend(hcd->usb_phy, 0);
        if (err) {
                dev_err(&pdev->dev, "Failed to power on the phy\n");
                goto cleanup_phy;
@@ -470,7 +470,7 @@ static int tegra_ehci_probe(struct platform_device *pdev)
 cleanup_otg_set_host:
        otg_set_host(u_phy->otg, NULL);
 cleanup_phy:
-       usb_phy_shutdown(hcd->phy);
+       usb_phy_shutdown(hcd->usb_phy);
 cleanup_clk_en:
        clk_disable_unprepare(tegra->clk);
 cleanup_hcd_create:
@@ -484,9 +484,9 @@ static int tegra_ehci_remove(struct platform_device *pdev)
        struct tegra_ehci_hcd *tegra =
                (struct tegra_ehci_hcd *)hcd_to_ehci(hcd)->priv;
 
-       otg_set_host(hcd->phy->otg, NULL);
+       otg_set_host(hcd->usb_phy->otg, NULL);
 
-       usb_phy_shutdown(hcd->phy);
+       usb_phy_shutdown(hcd->usb_phy);
        usb_remove_hcd(hcd);
        usb_put_hcd(hcd);
 
index c923caf..bf8e3e9 100644 (file)
@@ -180,10 +180,10 @@ static void start_hnp(struct ohci_hcd *ohci)
        unsigned long   flags;
        u32 l;
 
-       otg_start_hnp(hcd->phy->otg);
+       otg_start_hnp(hcd->usb_phy->otg);
 
        local_irq_save(flags);
-       hcd->phy->state = OTG_STATE_A_SUSPEND;
+       hcd->usb_phy->state = OTG_STATE_A_SUSPEND;
        writel (RH_PS_PSS, &ohci->regs->roothub.portstatus [port]);
        l = omap_readl(OTG_CTRL);
        l &= ~OTG_A_BUSREQ;
@@ -220,14 +220,14 @@ static int ohci_omap_reset(struct usb_hcd *hcd)
 
 #ifdef CONFIG_USB_OTG
        if (need_transceiver) {
-               hcd->phy = usb_get_phy(USB_PHY_TYPE_USB2);
-               if (!IS_ERR_OR_NULL(hcd->phy)) {
-                       int     status = otg_set_host(hcd->phy->otg,
+               hcd->usb_phy = usb_get_phy(USB_PHY_TYPE_USB2);
+               if (!IS_ERR_OR_NULL(hcd->usb_phy)) {
+                       int     status = otg_set_host(hcd->usb_phy->otg,
                                                &ohci_to_hcd(ohci)->self);
                        dev_dbg(hcd->self.controller, "init %s phy, status %d\n",
-                                       hcd->phy->label, status);
+                                       hcd->usb_phy->label, status);
                        if (status) {
-                               usb_put_phy(hcd->phy);
+                               usb_put_phy(hcd->usb_phy);
                                return status;
                        }
                } else {
@@ -399,9 +399,9 @@ usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)
        dev_dbg(hcd->self.controller, "stopping USB Controller\n");
        usb_remove_hcd(hcd);
        omap_ohci_clock_power(0);
-       if (!IS_ERR_OR_NULL(hcd->phy)) {
-               (void) otg_set_host(hcd->phy->otg, 0);
-               usb_put_phy(hcd->phy);
+       if (!IS_ERR_OR_NULL(hcd->usb_phy)) {
+               (void) otg_set_host(hcd->usb_phy->otg, 0);
+               usb_put_phy(hcd->usb_phy);
        }
        if (machine_is_omap_osk())
                gpio_free(9);
index 75cb1ff..309fe45 100644 (file)
@@ -40,6 +40,8 @@
 
 static const char hcd_name[] = "xhci_hcd";
 
+static struct hc_driver __read_mostly xhci_pci_hc_driver;
+
 /* called after powerup, by probe or system-pm "wakeup" */
 static int xhci_pci_reinit(struct xhci_hcd *xhci, struct pci_dev *pdev)
 {
@@ -281,7 +283,7 @@ static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
        if (xhci_compliance_mode_recovery_timer_quirk_check())
                pdev->no_d3cold = true;
 
-       return xhci_suspend(xhci);
+       return xhci_suspend(xhci, do_wakeup);
 }
 
 static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated)
@@ -316,68 +318,6 @@ static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated)
 }
 #endif /* CONFIG_PM */
 
-static const struct hc_driver xhci_pci_hc_driver = {
-       .description =          hcd_name,
-       .product_desc =         "xHCI Host Controller",
-       .hcd_priv_size =        sizeof(struct xhci_hcd *),
-
-       /*
-        * generic hardware linkage
-        */
-       .irq =                  xhci_irq,
-       .flags =                HCD_MEMORY | HCD_USB3 | HCD_SHARED,
-
-       /*
-        * basic lifecycle operations
-        */
-       .reset =                xhci_pci_setup,
-       .start =                xhci_run,
-#ifdef CONFIG_PM
-       .pci_suspend =          xhci_pci_suspend,
-       .pci_resume =           xhci_pci_resume,
-#endif
-       .stop =                 xhci_stop,
-       .shutdown =             xhci_shutdown,
-
-       /*
-        * managing i/o requests and associated device resources
-        */
-       .urb_enqueue =          xhci_urb_enqueue,
-       .urb_dequeue =          xhci_urb_dequeue,
-       .alloc_dev =            xhci_alloc_dev,
-       .free_dev =             xhci_free_dev,
-       .alloc_streams =        xhci_alloc_streams,
-       .free_streams =         xhci_free_streams,
-       .add_endpoint =         xhci_add_endpoint,
-       .drop_endpoint =        xhci_drop_endpoint,
-       .endpoint_reset =       xhci_endpoint_reset,
-       .check_bandwidth =      xhci_check_bandwidth,
-       .reset_bandwidth =      xhci_reset_bandwidth,
-       .address_device =       xhci_address_device,
-       .enable_device =        xhci_enable_device,
-       .update_hub_device =    xhci_update_hub_device,
-       .reset_device =         xhci_discover_or_reset_device,
-
-       /*
-        * scheduling support
-        */
-       .get_frame_number =     xhci_get_frame,
-
-       /* Root hub support */
-       .hub_control =          xhci_hub_control,
-       .hub_status_data =      xhci_hub_status_data,
-       .bus_suspend =          xhci_bus_suspend,
-       .bus_resume =           xhci_bus_resume,
-       /*
-        * call back when device connected and addressed
-        */
-       .update_device =        xhci_update_device,
-       .set_usb2_hw_lpm =      xhci_set_usb2_hardware_lpm,
-       .enable_usb3_lpm_timeout =      xhci_enable_usb3_lpm_timeout,
-       .disable_usb3_lpm_timeout =     xhci_disable_usb3_lpm_timeout,
-       .find_raw_port_number = xhci_find_raw_port_number,
-};
-
 /*-------------------------------------------------------------------------*/
 
 /* PCI driver selection metadata; PCI hotplugging uses this */
@@ -409,6 +349,11 @@ static struct pci_driver xhci_pci_driver = {
 
 int __init xhci_register_pci(void)
 {
+       xhci_init_driver(&xhci_pci_hc_driver, xhci_pci_setup);
+#ifdef CONFIG_PM
+       xhci_pci_hc_driver.pci_suspend = xhci_pci_suspend;
+       xhci_pci_hc_driver.pci_resume = xhci_pci_resume;
+#endif
        return pci_register_driver(&xhci_pci_driver);
 }
 
index d1dda33..bf09ffb 100644 (file)
@@ -23,6 +23,8 @@
 #include "xhci-mvebu.h"
 #include "xhci-rcar.h"
 
+static struct hc_driver __read_mostly xhci_plat_hc_driver;
+
 static void xhci_plat_quirks(struct device *dev, struct xhci_hcd *xhci)
 {
        /*
@@ -60,59 +62,6 @@ static int xhci_plat_start(struct usb_hcd *hcd)
        return xhci_run(hcd);
 }
 
-static const struct hc_driver xhci_plat_xhci_driver = {
-       .description =          "xhci-hcd",
-       .product_desc =         "xHCI Host Controller",
-       .hcd_priv_size =        sizeof(struct xhci_hcd *),
-
-       /*
-        * generic hardware linkage
-        */
-       .irq =                  xhci_irq,
-       .flags =                HCD_MEMORY | HCD_USB3 | HCD_SHARED,
-
-       /*
-        * basic lifecycle operations
-        */
-       .reset =                xhci_plat_setup,
-       .start =                xhci_plat_start,
-       .stop =                 xhci_stop,
-       .shutdown =             xhci_shutdown,
-
-       /*
-        * managing i/o requests and associated device resources
-        */
-       .urb_enqueue =          xhci_urb_enqueue,
-       .urb_dequeue =          xhci_urb_dequeue,
-       .alloc_dev =            xhci_alloc_dev,
-       .free_dev =             xhci_free_dev,
-       .alloc_streams =        xhci_alloc_streams,
-       .free_streams =         xhci_free_streams,
-       .add_endpoint =         xhci_add_endpoint,
-       .drop_endpoint =        xhci_drop_endpoint,
-       .endpoint_reset =       xhci_endpoint_reset,
-       .check_bandwidth =      xhci_check_bandwidth,
-       .reset_bandwidth =      xhci_reset_bandwidth,
-       .address_device =       xhci_address_device,
-       .enable_device =        xhci_enable_device,
-       .update_hub_device =    xhci_update_hub_device,
-       .reset_device =         xhci_discover_or_reset_device,
-
-       /*
-        * scheduling support
-        */
-       .get_frame_number =     xhci_get_frame,
-
-       /* Root hub support */
-       .hub_control =          xhci_hub_control,
-       .hub_status_data =      xhci_hub_status_data,
-       .bus_suspend =          xhci_bus_suspend,
-       .bus_resume =           xhci_bus_resume,
-
-       .enable_usb3_lpm_timeout =      xhci_enable_usb3_lpm_timeout,
-       .disable_usb3_lpm_timeout =     xhci_disable_usb3_lpm_timeout,
-};
-
 static int xhci_plat_probe(struct platform_device *pdev)
 {
        struct device_node      *node = pdev->dev.of_node;
@@ -128,7 +77,7 @@ static int xhci_plat_probe(struct platform_device *pdev)
        if (usb_disabled())
                return -ENODEV;
 
-       driver = &xhci_plat_xhci_driver;
+       driver = &xhci_plat_hc_driver;
 
        irq = platform_get_irq(pdev, 0);
        if (irq < 0)
@@ -252,7 +201,15 @@ static int xhci_plat_suspend(struct device *dev)
        struct usb_hcd  *hcd = dev_get_drvdata(dev);
        struct xhci_hcd *xhci = hcd_to_xhci(hcd);
 
-       return xhci_suspend(xhci);
+       /*
+        * xhci_suspend() needs `do_wakeup` to know whether host is allowed
+        * to do wakeup during suspend. Since xhci_plat_suspend is currently
+        * only designed for system suspend, device_may_wakeup() is enough
+        * to dertermine whether host is allowed to do wakeup. Need to
+        * reconsider this when xhci_plat_suspend enlarges its scope, e.g.,
+        * also applies to runtime suspend.
+        */
+       return xhci_suspend(xhci, device_may_wakeup(dev));
 }
 
 static int xhci_plat_resume(struct device *dev)
@@ -297,6 +254,8 @@ MODULE_ALIAS("platform:xhci-hcd");
 
 int xhci_register_plat(void)
 {
+       xhci_init_driver(&xhci_plat_hc_driver, xhci_plat_setup);
+       xhci_plat_hc_driver.start = xhci_plat_start;
        return platform_driver_register(&usb_xhci_driver);
 }
 
index 0e6665a..1710a86 100644 (file)
@@ -1180,9 +1180,8 @@ static void xhci_handle_cmd_reset_ep(struct xhci_hcd *xhci, int slot_id,
                                false);
                xhci_ring_cmd_db(xhci);
        } else {
-               /* Clear our internal halted state and restart the ring(s) */
+               /* Clear our internal halted state */
                xhci->devs[slot_id]->eps[ep_index].ep_state &= ~EP_HALTED;
-               ring_doorbell_for_active_rings(xhci, slot_id, ep_index);
        }
 }
 
index 82b563f..58f420d 100644 (file)
@@ -35,6 +35,8 @@
 #define DRIVER_AUTHOR "Sarah Sharp"
 #define DRIVER_DESC "'eXtensible' Host Controller (xHC) Driver"
 
+#define        PORT_WAKE_BITS  (PORT_WKOC_E | PORT_WKDISC_E | PORT_WKCONN_E)
+
 /* Some 0.95 hardware can't handle the chain bit on a Link TRB being cleared */
 static int link_quirk;
 module_param(link_quirk, int, S_IRUGO | S_IWUSR);
@@ -842,13 +844,47 @@ static void xhci_clear_command_ring(struct xhci_hcd *xhci)
        xhci_set_cmd_ring_deq(xhci);
 }
 
+static void xhci_disable_port_wake_on_bits(struct xhci_hcd *xhci)
+{
+       int port_index;
+       __le32 __iomem **port_array;
+       unsigned long flags;
+       u32 t1, t2;
+
+       spin_lock_irqsave(&xhci->lock, flags);
+
+       /* disble usb3 ports Wake bits*/
+       port_index = xhci->num_usb3_ports;
+       port_array = xhci->usb3_ports;
+       while (port_index--) {
+               t1 = readl(port_array[port_index]);
+               t1 = xhci_port_state_to_neutral(t1);
+               t2 = t1 & ~PORT_WAKE_BITS;
+               if (t1 != t2)
+                       writel(t2, port_array[port_index]);
+       }
+
+       /* disble usb2 ports Wake bits*/
+       port_index = xhci->num_usb2_ports;
+       port_array = xhci->usb2_ports;
+       while (port_index--) {
+               t1 = readl(port_array[port_index]);
+               t1 = xhci_port_state_to_neutral(t1);
+               t2 = t1 & ~PORT_WAKE_BITS;
+               if (t1 != t2)
+                       writel(t2, port_array[port_index]);
+       }
+
+       spin_unlock_irqrestore(&xhci->lock, flags);
+}
+
 /*
  * Stop HC (not bus-specific)
  *
  * This is called when the machine transition into S3/S4 mode.
  *
  */
-int xhci_suspend(struct xhci_hcd *xhci)
+int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup)
 {
        int                     rc = 0;
        unsigned int            delay = XHCI_MAX_HALT_USEC;
@@ -859,6 +895,10 @@ int xhci_suspend(struct xhci_hcd *xhci)
                        xhci->shared_hcd->state != HC_STATE_SUSPENDED)
                return -EINVAL;
 
+       /* Clear root port wake on bits if wakeup not allowed. */
+       if (!do_wakeup)
+               xhci_disable_port_wake_on_bits(xhci);
+
        /* Don't poll the roothubs on bus suspend. */
        xhci_dbg(xhci, "%s: stopping port polling.\n", __func__);
        clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
@@ -4831,6 +4871,75 @@ error:
        return retval;
 }
 
+static const struct hc_driver xhci_hc_driver = {
+       .description =          "xhci-hcd",
+       .product_desc =         "xHCI Host Controller",
+       .hcd_priv_size =        sizeof(struct xhci_hcd *),
+
+       /*
+        * generic hardware linkage
+        */
+       .irq =                  xhci_irq,
+       .flags =                HCD_MEMORY | HCD_USB3 | HCD_SHARED,
+
+       /*
+        * basic lifecycle operations
+        */
+       .reset =                NULL, /* set in xhci_init_driver() */
+       .start =                xhci_run,
+       .stop =                 xhci_stop,
+       .shutdown =             xhci_shutdown,
+
+       /*
+        * managing i/o requests and associated device resources
+        */
+       .urb_enqueue =          xhci_urb_enqueue,
+       .urb_dequeue =          xhci_urb_dequeue,
+       .alloc_dev =            xhci_alloc_dev,
+       .free_dev =             xhci_free_dev,
+       .alloc_streams =        xhci_alloc_streams,
+       .free_streams =         xhci_free_streams,
+       .add_endpoint =         xhci_add_endpoint,
+       .drop_endpoint =        xhci_drop_endpoint,
+       .endpoint_reset =       xhci_endpoint_reset,
+       .check_bandwidth =      xhci_check_bandwidth,
+       .reset_bandwidth =      xhci_reset_bandwidth,
+       .address_device =       xhci_address_device,
+       .enable_device =        xhci_enable_device,
+       .update_hub_device =    xhci_update_hub_device,
+       .reset_device =         xhci_discover_or_reset_device,
+
+       /*
+        * scheduling support
+        */
+       .get_frame_number =     xhci_get_frame,
+
+       /*
+        * root hub support
+        */
+       .hub_control =          xhci_hub_control,
+       .hub_status_data =      xhci_hub_status_data,
+       .bus_suspend =          xhci_bus_suspend,
+       .bus_resume =           xhci_bus_resume,
+
+       /*
+        * call back when device connected and addressed
+        */
+       .update_device =        xhci_update_device,
+       .set_usb2_hw_lpm =      xhci_set_usb2_hardware_lpm,
+       .enable_usb3_lpm_timeout =      xhci_enable_usb3_lpm_timeout,
+       .disable_usb3_lpm_timeout =     xhci_disable_usb3_lpm_timeout,
+       .find_raw_port_number = xhci_find_raw_port_number,
+};
+
+void xhci_init_driver(struct hc_driver *drv, int (*setup_fn)(struct usb_hcd *))
+{
+       BUG_ON(!setup_fn);
+       *drv = xhci_hc_driver;
+       drv->reset = setup_fn;
+}
+EXPORT_SYMBOL_GPL(xhci_init_driver);
+
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_LICENSE("GPL");
index 1e60ab8..2c8c598 100644 (file)
@@ -1760,9 +1760,10 @@ int xhci_run(struct usb_hcd *hcd);
 void xhci_stop(struct usb_hcd *hcd);
 void xhci_shutdown(struct usb_hcd *hcd);
 int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks);
+void xhci_init_driver(struct hc_driver *drv, int (*setup_fn)(struct usb_hcd *));
 
 #ifdef CONFIG_PM
-int xhci_suspend(struct xhci_hcd *xhci);
+int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup);
 int xhci_resume(struct xhci_hcd *xhci, bool hibernated);
 #else
 #define        xhci_suspend    NULL
index 551e0a6..388d89f 100644 (file)
@@ -177,15 +177,15 @@ static int rcar_gen2_usb_phy_probe(struct platform_device *pdev)
        struct clk *clk;
        int retval;
 
-       pdata = dev_get_platdata(&pdev->dev);
+       pdata = dev_get_platdata(dev);
        if (!pdata) {
                dev_err(dev, "No platform data\n");
                return -EINVAL;
        }
 
-       clk = devm_clk_get(&pdev->dev, "usbhs");
+       clk = devm_clk_get(dev, "usbhs");
        if (IS_ERR(clk)) {
-               dev_err(&pdev->dev, "Can't get the clock\n");
+               dev_err(dev, "Can't get the clock\n");
                return PTR_ERR(clk);
        }
 
index 1c4195a..de83b9d 100644 (file)
@@ -5,6 +5,7 @@
 config USB_RENESAS_USBHS
        tristate 'Renesas USBHS controller'
        depends on USB_GADGET
+       depends on ARCH_SHMOBILE || SUPERH || COMPILE_TEST
        default n
        help
          Renesas USBHS is a discrete USB host and peripheral controller chip
index 1b9bf8d..b3b6813 100644 (file)
@@ -18,6 +18,8 @@
 #include <linux/gpio.h>
 #include <linux/io.h>
 #include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
 #include <linux/pm_runtime.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
@@ -438,6 +440,43 @@ static int usbhsc_drvcllbck_notify_hotplug(struct platform_device *pdev)
 /*
  *             platform functions
  */
+static const struct of_device_id usbhs_of_match[] = {
+       {
+               .compatible = "renesas,usbhs-r8a7790",
+               .data = (void *)USBHS_TYPE_R8A7790,
+       },
+       {
+               .compatible = "renesas,usbhs-r8a7791",
+               .data = (void *)USBHS_TYPE_R8A7791,
+       },
+       { },
+};
+MODULE_DEVICE_TABLE(of, usbhs_of_match);
+
+static struct renesas_usbhs_platform_info *usbhs_parse_dt(struct device *dev)
+{
+       struct renesas_usbhs_platform_info *info;
+       struct renesas_usbhs_driver_param *dparam;
+       const struct of_device_id *of_id = of_match_device(usbhs_of_match, dev);
+       u32 tmp;
+       int gpio;
+
+       info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
+       if (!info)
+               return NULL;
+
+       dparam = &info->driver_param;
+       dparam->type = of_id ? (u32)of_id->data : 0;
+       if (!of_property_read_u32(dev->of_node, "renesas,buswait", &tmp))
+               dparam->buswait_bwait = tmp;
+       gpio = of_get_named_gpio_flags(dev->of_node, "renesas,enable-gpio", 0,
+                                      NULL);
+       if (gpio > 0)
+               dparam->enable_gpio = gpio;
+
+       return info;
+}
+
 static int usbhs_probe(struct platform_device *pdev)
 {
        struct renesas_usbhs_platform_info *info = dev_get_platdata(&pdev->dev);
@@ -446,6 +485,10 @@ static int usbhs_probe(struct platform_device *pdev)
        struct resource *res, *irq_res;
        int ret;
 
+       /* check device node */
+       if (pdev->dev.of_node)
+               info = pdev->dev.platform_data = usbhs_parse_dt(&pdev->dev);
+
        /* check platform information */
        if (!info) {
                dev_err(&pdev->dev, "no platform information\n");
@@ -689,6 +732,7 @@ static struct platform_driver renesas_usbhs_driver = {
        .driver         = {
                .name   = "renesas_usbhs",
                .pm     = &usbhsc_pm_ops,
+               .of_match_table = of_match_ptr(usbhs_of_match),
        },
        .probe          = usbhs_probe,
        .remove         = usbhs_remove,
index 3beae72..5741e94 100644 (file)
@@ -120,6 +120,7 @@ static const struct usb_device_id id_table[] = {
        { USB_DEVICE(0x10C4, 0x85F8) }, /* Virtenio Preon32 */
        { USB_DEVICE(0x10C4, 0x8664) }, /* AC-Services CAN-IF */
        { USB_DEVICE(0x10C4, 0x8665) }, /* AC-Services OBD-IF */
+       { USB_DEVICE(0x10C4, 0x8875) }, /* CEL MeshConnect USB Stick */
        { USB_DEVICE(0x10C4, 0x88A4) }, /* MMB Networks ZigBee USB Device */
        { USB_DEVICE(0x10C4, 0x88A5) }, /* Planet Innovation Ingeni ZigBee USB Device */
        { USB_DEVICE(0x10C4, 0x8946) }, /* Ketra N1 Wireless Interface */
index a523ada..debcdef 100644 (file)
@@ -483,6 +483,39 @@ static const struct usb_device_id id_table_combined[] = {
        { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FD_PID) },
        { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FE_PID) },
        { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FF_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_4701_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9300_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9301_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9302_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9303_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9304_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9305_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9306_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9307_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9308_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9309_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_930A_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_930B_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_930C_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_930D_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_930E_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_930F_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9310_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9311_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9312_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9313_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9314_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9315_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9316_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9317_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9318_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_9319_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_931A_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_931B_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_931C_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_931D_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_931E_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_931F_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_TNC_X_PID) },
index 6786b70..e52409c 100644 (file)
 #define BAYER_CONTOUR_CABLE_PID        0x6001
 
 /*
- * The following are the values for the Matrix Orbital FTDI Range
- * Anything in this range will use an FT232RL.
+ * Matrix Orbital Intelligent USB displays.
+ * http://www.matrixorbital.com
  */
 #define MTXORB_VID                     0x1B3D
 #define MTXORB_FTDI_RANGE_0100_PID     0x0100
 #define MTXORB_FTDI_RANGE_01FD_PID     0x01FD
 #define MTXORB_FTDI_RANGE_01FE_PID     0x01FE
 #define MTXORB_FTDI_RANGE_01FF_PID     0x01FF
-
-
+#define MTXORB_FTDI_RANGE_4701_PID     0x4701
+#define MTXORB_FTDI_RANGE_9300_PID     0x9300
+#define MTXORB_FTDI_RANGE_9301_PID     0x9301
+#define MTXORB_FTDI_RANGE_9302_PID     0x9302
+#define MTXORB_FTDI_RANGE_9303_PID     0x9303
+#define MTXORB_FTDI_RANGE_9304_PID     0x9304
+#define MTXORB_FTDI_RANGE_9305_PID     0x9305
+#define MTXORB_FTDI_RANGE_9306_PID     0x9306
+#define MTXORB_FTDI_RANGE_9307_PID     0x9307
+#define MTXORB_FTDI_RANGE_9308_PID     0x9308
+#define MTXORB_FTDI_RANGE_9309_PID     0x9309
+#define MTXORB_FTDI_RANGE_930A_PID     0x930A
+#define MTXORB_FTDI_RANGE_930B_PID     0x930B
+#define MTXORB_FTDI_RANGE_930C_PID     0x930C
+#define MTXORB_FTDI_RANGE_930D_PID     0x930D
+#define MTXORB_FTDI_RANGE_930E_PID     0x930E
+#define MTXORB_FTDI_RANGE_930F_PID     0x930F
+#define MTXORB_FTDI_RANGE_9310_PID     0x9310
+#define MTXORB_FTDI_RANGE_9311_PID     0x9311
+#define MTXORB_FTDI_RANGE_9312_PID     0x9312
+#define MTXORB_FTDI_RANGE_9313_PID     0x9313
+#define MTXORB_FTDI_RANGE_9314_PID     0x9314
+#define MTXORB_FTDI_RANGE_9315_PID     0x9315
+#define MTXORB_FTDI_RANGE_9316_PID     0x9316
+#define MTXORB_FTDI_RANGE_9317_PID     0x9317
+#define MTXORB_FTDI_RANGE_9318_PID     0x9318
+#define MTXORB_FTDI_RANGE_9319_PID     0x9319
+#define MTXORB_FTDI_RANGE_931A_PID     0x931A
+#define MTXORB_FTDI_RANGE_931B_PID     0x931B
+#define MTXORB_FTDI_RANGE_931C_PID     0x931C
+#define MTXORB_FTDI_RANGE_931D_PID     0x931D
+#define MTXORB_FTDI_RANGE_931E_PID     0x931E
+#define MTXORB_FTDI_RANGE_931F_PID     0x931F
 
 /*
  * The Mobility Lab (TML)
index 265c677..49101fe 100644 (file)
@@ -311,24 +311,30 @@ static void       usa26_indat_callback(struct urb *urb)
                if ((data[0] & 0x80) == 0) {
                        /* no errors on individual bytes, only
                           possible overrun err */
-                       if (data[0] & RXERROR_OVERRUN)
-                               err = TTY_OVERRUN;
-                       else
-                               err = 0;
+                       if (data[0] & RXERROR_OVERRUN) {
+                               tty_insert_flip_char(&port->port, 0,
+                                                               TTY_OVERRUN);
+                       }
                        for (i = 1; i < urb->actual_length ; ++i)
-                               tty_insert_flip_char(&port->port, data[i], err);
+                               tty_insert_flip_char(&port->port, data[i],
+                                                               TTY_NORMAL);
                } else {
                        /* some bytes had errors, every byte has status */
                        dev_dbg(&port->dev, "%s - RX error!!!!\n", __func__);
                        for (i = 0; i + 1 < urb->actual_length; i += 2) {
-                               int stat = data[i], flag = 0;
-                               if (stat & RXERROR_OVERRUN)
-                                       flag |= TTY_OVERRUN;
-                               if (stat & RXERROR_FRAMING)
-                                       flag |= TTY_FRAME;
-                               if (stat & RXERROR_PARITY)
-                                       flag |= TTY_PARITY;
+                               int stat = data[i];
+                               int flag = TTY_NORMAL;
+
+                               if (stat & RXERROR_OVERRUN) {
+                                       tty_insert_flip_char(&port->port, 0,
+                                                               TTY_OVERRUN);
+                               }
                                /* XXX should handle break (0x10) */
+                               if (stat & RXERROR_PARITY)
+                                       flag = TTY_PARITY;
+                               else if (stat & RXERROR_FRAMING)
+                                       flag = TTY_FRAME;
+
                                tty_insert_flip_char(&port->port, data[i+1],
                                                flag);
                        }
@@ -666,14 +672,19 @@ static void       usa49_indat_callback(struct urb *urb)
                } else {
                        /* some bytes had errors, every byte has status */
                        for (i = 0; i + 1 < urb->actual_length; i += 2) {
-                               int stat = data[i], flag = 0;
-                               if (stat & RXERROR_OVERRUN)
-                                       flag |= TTY_OVERRUN;
-                               if (stat & RXERROR_FRAMING)
-                                       flag |= TTY_FRAME;
-                               if (stat & RXERROR_PARITY)
-                                       flag |= TTY_PARITY;
+                               int stat = data[i];
+                               int flag = TTY_NORMAL;
+
+                               if (stat & RXERROR_OVERRUN) {
+                                       tty_insert_flip_char(&port->port, 0,
+                                                               TTY_OVERRUN);
+                               }
                                /* XXX should handle break (0x10) */
+                               if (stat & RXERROR_PARITY)
+                                       flag = TTY_PARITY;
+                               else if (stat & RXERROR_FRAMING)
+                                       flag = TTY_FRAME;
+
                                tty_insert_flip_char(&port->port, data[i+1],
                                                flag);
                        }
@@ -730,15 +741,19 @@ static void usa49wg_indat_callback(struct urb *urb)
                         */
                        for (x = 0; x + 1 < len &&
                                    i + 1 < urb->actual_length; x += 2) {
-                               int stat = data[i], flag = 0;
+                               int stat = data[i];
+                               int flag = TTY_NORMAL;
 
-                               if (stat & RXERROR_OVERRUN)
-                                       flag |= TTY_OVERRUN;
-                               if (stat & RXERROR_FRAMING)
-                                       flag |= TTY_FRAME;
-                               if (stat & RXERROR_PARITY)
-                                       flag |= TTY_PARITY;
+                               if (stat & RXERROR_OVERRUN) {
+                                       tty_insert_flip_char(&port->port, 0,
+                                                               TTY_OVERRUN);
+                               }
                                /* XXX should handle break (0x10) */
+                               if (stat & RXERROR_PARITY)
+                                       flag = TTY_PARITY;
+                               else if (stat & RXERROR_FRAMING)
+                                       flag = TTY_FRAME;
+
                                tty_insert_flip_char(&port->port, data[i+1],
                                                     flag);
                                i += 2;
@@ -790,25 +805,31 @@ static void usa90_indat_callback(struct urb *urb)
                        if ((data[0] & 0x80) == 0) {
                                /* no errors on individual bytes, only
                                   possible overrun err*/
-                               if (data[0] & RXERROR_OVERRUN)
-                                       err = TTY_OVERRUN;
-                               else
-                                       err = 0;
+                               if (data[0] & RXERROR_OVERRUN) {
+                                       tty_insert_flip_char(&port->port, 0,
+                                                               TTY_OVERRUN);
+                               }
                                for (i = 1; i < urb->actual_length ; ++i)
                                        tty_insert_flip_char(&port->port,
-                                                       data[i], err);
+                                                       data[i], TTY_NORMAL);
                        }  else {
                        /* some bytes had errors, every byte has status */
                                dev_dbg(&port->dev, "%s - RX error!!!!\n", __func__);
                                for (i = 0; i + 1 < urb->actual_length; i += 2) {
-                                       int stat = data[i], flag = 0;
-                                       if (stat & RXERROR_OVERRUN)
-                                               flag |= TTY_OVERRUN;
-                                       if (stat & RXERROR_FRAMING)
-                                               flag |= TTY_FRAME;
-                                       if (stat & RXERROR_PARITY)
-                                               flag |= TTY_PARITY;
+                                       int stat = data[i];
+                                       int flag = TTY_NORMAL;
+
+                                       if (stat & RXERROR_OVERRUN) {
+                                               tty_insert_flip_char(
+                                                               &port->port, 0,
+                                                               TTY_OVERRUN);
+                                       }
                                        /* XXX should handle break (0x10) */
+                                       if (stat & RXERROR_PARITY)
+                                               flag = TTY_PARITY;
+                                       else if (stat & RXERROR_FRAMING)
+                                               flag = TTY_FRAME;
+
                                        tty_insert_flip_char(&port->port,
                                                        data[i+1], flag);
                                }
index a7fe664..70a098d 100644 (file)
@@ -490,10 +490,9 @@ static void ssu100_update_lsr(struct usb_serial_port *port, u8 lsr,
                        if (*tty_flag == TTY_NORMAL)
                                *tty_flag = TTY_FRAME;
                }
-               if (lsr & UART_LSR_OE){
+               if (lsr & UART_LSR_OE) {
                        port->icount.overrun++;
-                       if (*tty_flag == TTY_NORMAL)
-                               *tty_flag = TTY_OVERRUN;
+                       tty_insert_flip_char(&port->port, 0, TTY_OVERRUN);
                }
        }
 
@@ -511,12 +510,8 @@ static void ssu100_process_read_urb(struct urb *urb)
        if ((len >= 4) &&
            (packet[0] == 0x1b) && (packet[1] == 0x1b) &&
            ((packet[2] == 0x00) || (packet[2] == 0x01))) {
-               if (packet[2] == 0x00) {
+               if (packet[2] == 0x00)
                        ssu100_update_lsr(port, packet[3], &flag);
-                       if (flag == TTY_OVERRUN)
-                               tty_insert_flip_char(&port->port, 0,
-                                               TTY_OVERRUN);
-               }
                if (packet[2] == 0x01)
                        ssu100_update_msr(port, packet[3]);
 
index e48d4a6..5d0b7b8 100644 (file)
@@ -1200,6 +1200,7 @@ static int
 vhost_scsi_set_endpoint(struct vhost_scsi *vs,
                        struct vhost_scsi_target *t)
 {
+       struct se_portal_group *se_tpg;
        struct tcm_vhost_tport *tv_tport;
        struct tcm_vhost_tpg *tpg;
        struct tcm_vhost_tpg **vs_tpg;
@@ -1247,6 +1248,21 @@ vhost_scsi_set_endpoint(struct vhost_scsi *vs,
                                ret = -EEXIST;
                                goto out;
                        }
+                       /*
+                        * In order to ensure individual vhost-scsi configfs
+                        * groups cannot be removed while in use by vhost ioctl,
+                        * go ahead and take an explicit se_tpg->tpg_group.cg_item
+                        * dependency now.
+                        */
+                       se_tpg = &tpg->se_tpg;
+                       ret = configfs_depend_item(se_tpg->se_tpg_tfo->tf_subsys,
+                                                  &se_tpg->tpg_group.cg_item);
+                       if (ret) {
+                               pr_warn("configfs_depend_item() failed: %d\n", ret);
+                               kfree(vs_tpg);
+                               mutex_unlock(&tpg->tv_tpg_mutex);
+                               goto out;
+                       }
                        tpg->tv_tpg_vhost_count++;
                        tpg->vhost_scsi = vs;
                        vs_tpg[tpg->tport_tpgt] = tpg;
@@ -1289,6 +1305,7 @@ static int
 vhost_scsi_clear_endpoint(struct vhost_scsi *vs,
                          struct vhost_scsi_target *t)
 {
+       struct se_portal_group *se_tpg;
        struct tcm_vhost_tport *tv_tport;
        struct tcm_vhost_tpg *tpg;
        struct vhost_virtqueue *vq;
@@ -1337,6 +1354,13 @@ vhost_scsi_clear_endpoint(struct vhost_scsi *vs,
                vs->vs_tpg[target] = NULL;
                match = true;
                mutex_unlock(&tpg->tv_tpg_mutex);
+               /*
+                * Release se_tpg->tpg_group.cg_item configfs dependency now
+                * to allow vhost-scsi WWPN se_tpg->tpg_group shutdown to occur.
+                */
+               se_tpg = &tpg->se_tpg;
+               configfs_undepend_item(se_tpg->se_tpg_tfo->tf_subsys,
+                                      &se_tpg->tpg_group.cg_item);
        }
        if (match) {
                for (i = 0; i < VHOST_SCSI_MAX_VQ; i++) {
index f45ddaa..2f7e8c2 100644 (file)
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -165,6 +165,15 @@ static struct vfsmount *aio_mnt;
 static const struct file_operations aio_ring_fops;
 static const struct address_space_operations aio_ctx_aops;
 
+/* Backing dev info for aio fs.
+ * -no dirty page accounting or writeback happens
+ */
+static struct backing_dev_info aio_fs_backing_dev_info = {
+       .name           = "aiofs",
+       .state          = 0,
+       .capabilities   = BDI_CAP_NO_ACCT_AND_WRITEBACK | BDI_CAP_MAP_COPY,
+};
+
 static struct file *aio_private_file(struct kioctx *ctx, loff_t nr_pages)
 {
        struct qstr this = QSTR_INIT("[aio]", 5);
@@ -176,6 +185,7 @@ static struct file *aio_private_file(struct kioctx *ctx, loff_t nr_pages)
 
        inode->i_mapping->a_ops = &aio_ctx_aops;
        inode->i_mapping->private_data = ctx;
+       inode->i_mapping->backing_dev_info = &aio_fs_backing_dev_info;
        inode->i_size = PAGE_SIZE * nr_pages;
 
        path.dentry = d_alloc_pseudo(aio_mnt->mnt_sb, &this);
@@ -221,6 +231,9 @@ static int __init aio_setup(void)
        if (IS_ERR(aio_mnt))
                panic("Failed to create aio fs mount.");
 
+       if (bdi_init(&aio_fs_backing_dev_info))
+               panic("Failed to init aio fs backing dev info.");
+
        kiocb_cachep = KMEM_CACHE(kiocb, SLAB_HWCACHE_ALIGN|SLAB_PANIC);
        kioctx_cachep = KMEM_CACHE(kioctx,SLAB_HWCACHE_ALIGN|SLAB_PANIC);
 
@@ -282,11 +295,6 @@ static const struct file_operations aio_ring_fops = {
        .mmap = aio_ring_mmap,
 };
 
-static int aio_set_page_dirty(struct page *page)
-{
-       return 0;
-}
-
 #if IS_ENABLED(CONFIG_MIGRATION)
 static int aio_migratepage(struct address_space *mapping, struct page *new,
                        struct page *old, enum migrate_mode mode)
@@ -358,7 +366,7 @@ out:
 #endif
 
 static const struct address_space_operations aio_ctx_aops = {
-       .set_page_dirty = aio_set_page_dirty,
+       .set_page_dirty = __set_page_dirty_no_writeback,
 #if IS_ENABLED(CONFIG_MIGRATION)
        .migratepage    = aio_migratepage,
 #endif
@@ -413,7 +421,6 @@ static int aio_setup_ring(struct kioctx *ctx)
                pr_debug("pid(%d) page[%d]->count=%d\n",
                         current->pid, i, page_count(page));
                SetPageUptodate(page);
-               SetPageDirty(page);
                unlock_page(page);
 
                ctx->ring_pages[i] = page;
index b01fb6c..d43c544 100644 (file)
@@ -472,7 +472,7 @@ static noinline int add_ra_bio_pages(struct inode *inode,
                rcu_read_lock();
                page = radix_tree_lookup(&mapping->page_tree, pg_index);
                rcu_read_unlock();
-               if (page) {
+               if (page && !radix_tree_exceptional_entry(page)) {
                        misses++;
                        if (misses > 4)
                                break;
index a9a881e..f6d00df 100644 (file)
@@ -425,13 +425,8 @@ static noinline int btrfs_copy_from_user(loff_t pos, int num_pages,
                struct page *page = prepared_pages[pg];
                /*
                 * Copy data from userspace to the current page
-                *
-                * Disable pagefault to avoid recursive lock since
-                * the pages are already locked
                 */
-               pagefault_disable();
                copied = iov_iter_copy_from_user_atomic(page, i, offset, count);
-               pagefault_enable();
 
                /* Flush processor's dcache for this page */
                flush_dcache_page(page);
index 06610cf..a1f801c 100644 (file)
@@ -195,8 +195,7 @@ static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned i
                struct page *page = NULL;
 
                if (blocknr + i < devsize) {
-                       page = read_mapping_page_async(mapping, blocknr + i,
-                                                                       NULL);
+                       page = read_mapping_page(mapping, blocknr + i, NULL);
                        /* synchronous error? */
                        if (IS_ERR(page))
                                page = NULL;
index 77bcc30..a91d3b4 100644 (file)
@@ -1003,9 +1003,7 @@ static ssize_t fuse_fill_write_pages(struct fuse_req *req,
                if (mapping_writably_mapped(mapping))
                        flush_dcache_page(page);
 
-               pagefault_disable();
                tmp = iov_iter_copy_from_user_atomic(page, ii, offset, bytes);
-               pagefault_enable();
                flush_dcache_page(page);
 
                mark_page_accessed(page);
index c7f2469..b82a9c9 100644 (file)
@@ -97,6 +97,11 @@ const struct address_space_operations gfs2_meta_aops = {
        .releasepage = gfs2_releasepage,
 };
 
+const struct address_space_operations gfs2_rgrp_aops = {
+       .writepage = gfs2_aspace_writepage,
+       .releasepage = gfs2_releasepage,
+};
+
 /**
  * gfs2_getbuf - Get a buffer with a given address space
  * @gl: the glock
index 4823b93..ac5d802 100644 (file)
@@ -38,12 +38,15 @@ static inline void gfs2_buffer_copy_tail(struct buffer_head *to_bh,
 }
 
 extern const struct address_space_operations gfs2_meta_aops;
+extern const struct address_space_operations gfs2_rgrp_aops;
 
 static inline struct gfs2_sbd *gfs2_mapping2sbd(struct address_space *mapping)
 {
        struct inode *inode = mapping->host;
        if (mapping->a_ops == &gfs2_meta_aops)
                return (((struct gfs2_glock *)mapping) - 1)->gl_sbd;
+       else if (mapping->a_ops == &gfs2_rgrp_aops)
+               return container_of(mapping, struct gfs2_sbd, sd_aspace);
        else
                return inode->i_sb->s_fs_info;
 }
index c6872d0..f6c9d83 100644 (file)
@@ -104,7 +104,7 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb)
        mapping = &sdp->sd_aspace;
 
        address_space_init_once(mapping);
-       mapping->a_ops = &gfs2_meta_aops;
+       mapping->a_ops = &gfs2_rgrp_aops;
        mapping->host = sb->s_bdev->bd_inode;
        mapping->flags = 0;
        mapping_set_gfp_mask(mapping, GFP_NOFS);
index e50170c..31666c9 100644 (file)
@@ -157,14 +157,16 @@ out:
 
 int ioprio_best(unsigned short aprio, unsigned short bprio)
 {
-       unsigned short aclass = IOPRIO_PRIO_CLASS(aprio);
-       unsigned short bclass = IOPRIO_PRIO_CLASS(bprio);
+       unsigned short aclass;
+       unsigned short bclass;
 
-       if (aclass == IOPRIO_CLASS_NONE)
-               aclass = IOPRIO_CLASS_BE;
-       if (bclass == IOPRIO_CLASS_NONE)
-               bclass = IOPRIO_CLASS_BE;
+       if (!ioprio_valid(aprio))
+               aprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, IOPRIO_NORM);
+       if (!ioprio_valid(bprio))
+               bprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, IOPRIO_NORM);
 
+       aclass = IOPRIO_PRIO_CLASS(aprio);
+       bclass = IOPRIO_PRIO_CLASS(bprio);
        if (aclass == bclass)
                return min(aprio, bprio);
        if (aclass > bclass)
index a69e426..5b234db 100644 (file)
@@ -687,7 +687,7 @@ unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c,
        struct inode *inode = OFNI_EDONI_2SFFJ(f);
        struct page *pg;
 
-       pg = read_cache_page_async(inode->i_mapping, offset >> PAGE_CACHE_SHIFT,
+       pg = read_cache_page(inode->i_mapping, offset >> PAGE_CACHE_SHIFT,
                             (void *)jffs2_do_readpage_unlock, inode);
        if (IS_ERR(pg))
                return (void *)pg;
index 4dd39b9..2c61c4e 100644 (file)
@@ -2235,16 +2235,28 @@ void locks_remove_flock(struct file *filp)
 
        while ((fl = *before) != NULL) {
                if (fl->fl_file == filp) {
-                       if (IS_FLOCK(fl)) {
-                               locks_delete_lock(before);
-                               continue;
-                       }
                        if (IS_LEASE(fl)) {
                                lease_modify(before, F_UNLCK);
                                continue;
                        }
-                       /* What? */
-                       BUG();
+
+                       /*
+                        * There's a leftover lock on the list of a type that
+                        * we didn't expect to see. Most likely a classic
+                        * POSIX lock that ended up not getting released
+                        * properly, or that raced onto the list somehow. Log
+                        * some info about it and then just remove it from
+                        * the list.
+                        */
+                       WARN(!IS_FLOCK(fl),
+                               "leftover lock: dev=%u:%u ino=%lu type=%hhd flags=0x%x start=%lld end=%lld\n",
+                               MAJOR(inode->i_sb->s_dev),
+                               MINOR(inode->i_sb->s_dev), inode->i_ino,
+                               fl->fl_type, fl->fl_flags,
+                               fl->fl_start, fl->fl_end);
+
+                       locks_delete_lock(before);
+                       continue;
                }
                before = &fl->fl_next;
        }
index 56ff823..65d849b 100644 (file)
@@ -1213,7 +1213,7 @@ static u64 pnfs_num_cont_bytes(struct inode *inode, pgoff_t idx)
        end = DIV_ROUND_UP(i_size_read(inode), PAGE_CACHE_SIZE);
        if (end != NFS_I(inode)->npages) {
                rcu_read_lock();
-               end = radix_tree_next_hole(&mapping->page_tree, idx + 1, ULONG_MAX);
+               end = page_cache_next_hole(mapping, idx + 1, ULONG_MAX);
                rcu_read_unlock();
        }
 
index 5d8ccec..3ed1be9 100644 (file)
@@ -109,6 +109,8 @@ again:
                        continue;
                if (!test_bit(NFS_DELEGATED_STATE, &state->flags))
                        continue;
+               if (!nfs4_valid_open_stateid(state))
+                       continue;
                if (!nfs4_stateid_match(&state->stateid, stateid))
                        continue;
                get_nfs_open_context(ctx);
@@ -177,7 +179,11 @@ static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation *
 {
        int res = 0;
 
-       res = nfs4_proc_delegreturn(inode, delegation->cred, &delegation->stateid, issync);
+       if (!test_bit(NFS_DELEGATION_REVOKED, &delegation->flags))
+               res = nfs4_proc_delegreturn(inode,
+                               delegation->cred,
+                               &delegation->stateid,
+                               issync);
        nfs_free_delegation(delegation);
        return res;
 }
@@ -364,11 +370,13 @@ static int nfs_end_delegation_return(struct inode *inode, struct nfs_delegation
 {
        struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
        struct nfs_inode *nfsi = NFS_I(inode);
-       int err;
+       int err = 0;
 
        if (delegation == NULL)
                return 0;
        do {
+               if (test_bit(NFS_DELEGATION_REVOKED, &delegation->flags))
+                       break;
                err = nfs_delegation_claim_opens(inode, &delegation->stateid);
                if (!issync || err != -EAGAIN)
                        break;
@@ -589,10 +597,23 @@ static void nfs_client_mark_return_unused_delegation_types(struct nfs_client *cl
        rcu_read_unlock();
 }
 
+static void nfs_revoke_delegation(struct inode *inode)
+{
+       struct nfs_delegation *delegation;
+       rcu_read_lock();
+       delegation = rcu_dereference(NFS_I(inode)->delegation);
+       if (delegation != NULL) {
+               set_bit(NFS_DELEGATION_REVOKED, &delegation->flags);
+               nfs_mark_return_delegation(NFS_SERVER(inode), delegation);
+       }
+       rcu_read_unlock();
+}
+
 void nfs_remove_bad_delegation(struct inode *inode)
 {
        struct nfs_delegation *delegation;
 
+       nfs_revoke_delegation(inode);
        delegation = nfs_inode_detach_delegation(inode);
        if (delegation) {
                nfs_inode_find_state_and_recover(inode, &delegation->stateid);
index 9a79c7a..e02b090 100644 (file)
@@ -31,6 +31,7 @@ enum {
        NFS_DELEGATION_RETURN_IF_CLOSED,
        NFS_DELEGATION_REFERENCED,
        NFS_DELEGATION_RETURNING,
+       NFS_DELEGATION_REVOKED,
 };
 
 int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res);
index b8797ae..de2543d 100644 (file)
@@ -178,6 +178,7 @@ static void nfs_direct_req_free(struct kref *kref)
 {
        struct nfs_direct_req *dreq = container_of(kref, struct nfs_direct_req, kref);
 
+       nfs_free_pnfs_ds_cinfo(&dreq->ds_cinfo);
        if (dreq->l_ctx != NULL)
                nfs_put_lock_context(dreq->l_ctx);
        if (dreq->ctx != NULL)
index 15f9d98..6659ce5 100644 (file)
@@ -592,7 +592,7 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
 {
        struct inode *inode = dentry->d_inode;
        int need_atime = NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATIME;
-       int err;
+       int err = 0;
 
        trace_nfs_getattr_enter(inode);
        /* Flush out writes to the server in order to update c/mtime.  */
index da657b7..bd01803 100644 (file)
@@ -1587,7 +1587,7 @@ static int nfs4_handle_delegation_recall_error(struct nfs_server *server, struct
                        nfs_inode_find_state_and_recover(state->inode,
                                        stateid);
                        nfs4_schedule_stateid_recovery(server, state);
-                       return 0;
+                       return -EAGAIN;
                case -NFS4ERR_DELAY:
                case -NFS4ERR_GRACE:
                        set_bit(NFS_DELEGATED_STATE, &state->flags);
@@ -2034,46 +2034,60 @@ static int nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *sta
        return ret;
 }
 
+static void nfs_finish_clear_delegation_stateid(struct nfs4_state *state)
+{
+       nfs_remove_bad_delegation(state->inode);
+       write_seqlock(&state->seqlock);
+       nfs4_stateid_copy(&state->stateid, &state->open_stateid);
+       write_sequnlock(&state->seqlock);
+       clear_bit(NFS_DELEGATED_STATE, &state->flags);
+}
+
+static void nfs40_clear_delegation_stateid(struct nfs4_state *state)
+{
+       if (rcu_access_pointer(NFS_I(state->inode)->delegation) != NULL)
+               nfs_finish_clear_delegation_stateid(state);
+}
+
+static int nfs40_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *state)
+{
+       /* NFSv4.0 doesn't allow for delegation recovery on open expire */
+       nfs40_clear_delegation_stateid(state);
+       return nfs4_open_expired(sp, state);
+}
+
 #if defined(CONFIG_NFS_V4_1)
-static void nfs41_clear_delegation_stateid(struct nfs4_state *state)
+static void nfs41_check_delegation_stateid(struct nfs4_state *state)
 {
        struct nfs_server *server = NFS_SERVER(state->inode);
-       nfs4_stateid *stateid = &state->stateid;
+       nfs4_stateid stateid;
        struct nfs_delegation *delegation;
-       struct rpc_cred *cred = NULL;
-       int status = -NFS4ERR_BAD_STATEID;
-
-       /* If a state reset has been done, test_stateid is unneeded */
-       if (test_bit(NFS_DELEGATED_STATE, &state->flags) == 0)
-               return;
+       struct rpc_cred *cred;
+       int status;
 
        /* Get the delegation credential for use by test/free_stateid */
        rcu_read_lock();
        delegation = rcu_dereference(NFS_I(state->inode)->delegation);
-       if (delegation != NULL &&
-           nfs4_stateid_match(&delegation->stateid, stateid)) {
-               cred = get_rpccred(delegation->cred);
-               rcu_read_unlock();
-               status = nfs41_test_stateid(server, stateid, cred);
-               trace_nfs4_test_delegation_stateid(state, NULL, status);
-       } else
+       if (delegation == NULL) {
                rcu_read_unlock();
+               return;
+       }
+
+       nfs4_stateid_copy(&stateid, &delegation->stateid);
+       cred = get_rpccred(delegation->cred);
+       rcu_read_unlock();
+       status = nfs41_test_stateid(server, &stateid, cred);
+       trace_nfs4_test_delegation_stateid(state, NULL, status);
 
        if (status != NFS_OK) {
                /* Free the stateid unless the server explicitly
                 * informs us the stateid is unrecognized. */
                if (status != -NFS4ERR_BAD_STATEID)
-                       nfs41_free_stateid(server, stateid, cred);
-               nfs_remove_bad_delegation(state->inode);
-
-               write_seqlock(&state->seqlock);
-               nfs4_stateid_copy(&state->stateid, &state->open_stateid);
-               write_sequnlock(&state->seqlock);
-               clear_bit(NFS_DELEGATED_STATE, &state->flags);
+                       nfs41_free_stateid(server, &stateid, cred);
+               nfs_finish_clear_delegation_stateid(state);
        }
 
-       if (cred != NULL)
-               put_rpccred(cred);
+       put_rpccred(cred);
 }
 
 /**
@@ -2117,7 +2131,7 @@ static int nfs41_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *st
 {
        int status;
 
-       nfs41_clear_delegation_stateid(state);
+       nfs41_check_delegation_stateid(state);
        status = nfs41_check_open_stateid(state);
        if (status != NFS_OK)
                status = nfs4_open_expired(sp, state);
@@ -8255,7 +8269,7 @@ static const struct nfs4_state_recovery_ops nfs41_reboot_recovery_ops = {
 static const struct nfs4_state_recovery_ops nfs40_nograce_recovery_ops = {
        .owner_flag_bit = NFS_OWNER_RECLAIM_NOGRACE,
        .state_flag_bit = NFS_STATE_RECLAIM_NOGRACE,
-       .recover_open   = nfs4_open_expired,
+       .recover_open   = nfs40_open_expired,
        .recover_lock   = nfs4_lock_expired,
        .establish_clid = nfs4_init_clientid,
 };
index 2ffebf2..27d7f27 100644 (file)
@@ -113,7 +113,7 @@ __nfs_iocounter_wait(struct nfs_io_counter *c)
                if (atomic_read(&c->io_count) == 0)
                        break;
                ret = nfs_wait_bit_killable(&c->flags);
-       } while (atomic_read(&c->io_count) != 0);
+       } while (atomic_read(&c->io_count) != 0 && !ret);
        finish_wait(wq, &q.wait);
        return ret;
 }
index cc8c5b3..f42bbe5 100644 (file)
@@ -784,8 +784,12 @@ static bool nfsd41_cb_get_slot(struct nfs4_client *clp, struct rpc_task *task)
 {
        if (test_and_set_bit(0, &clp->cl_cb_slot_busy) != 0) {
                rpc_sleep_on(&clp->cl_cb_waitq, task, NULL);
-               dprintk("%s slot is busy\n", __func__);
-               return false;
+               /* Race breaker */
+               if (test_and_set_bit(0, &clp->cl_cb_slot_busy) != 0) {
+                       dprintk("%s slot is busy\n", __func__);
+                       return false;
+               }
+               rpc_wake_up_queued_task(&clp->cl_cb_waitq, task);
        }
        return true;
 }
index f8f060f..6040da8 100644 (file)
@@ -224,13 +224,6 @@ hash_refile(struct svc_cacherep *rp)
        hlist_add_head(&rp->c_hash, cache_hash + hash_32(rp->c_xid, maskbits));
 }
 
-static inline bool
-nfsd_cache_entry_expired(struct svc_cacherep *rp)
-{
-       return rp->c_state != RC_INPROG &&
-              time_after(jiffies, rp->c_timestamp + RC_EXPIRE);
-}
-
 /*
  * Walk the LRU list and prune off entries that are older than RC_EXPIRE.
  * Also prune the oldest ones when the total exceeds the max number of entries.
@@ -242,8 +235,14 @@ prune_cache_entries(void)
        long freed = 0;
 
        list_for_each_entry_safe(rp, tmp, &lru_head, c_lru) {
-               if (!nfsd_cache_entry_expired(rp) &&
-                   num_drc_entries <= max_drc_entries)
+               /*
+                * Don't free entries attached to calls that are still
+                * in-progress, but do keep scanning the list.
+                */
+               if (rp->c_state == RC_INPROG)
+                       continue;
+               if (num_drc_entries <= max_drc_entries &&
+                   time_before(jiffies, rp->c_timestamp + RC_EXPIRE))
                        break;
                nfsd_reply_cache_free_locked(rp);
                freed++;
index 479eb68..f417fef 100644 (file)
@@ -328,12 +328,15 @@ void              nfsd_lockd_shutdown(void);
        (NFSD4_SUPPORTED_ATTRS_WORD2 | FATTR4_WORD2_SUPPATTR_EXCLCREAT)
 
 #ifdef CONFIG_NFSD_V4_SECURITY_LABEL
-#define NFSD4_2_SUPPORTED_ATTRS_WORD2 \
-       (NFSD4_1_SUPPORTED_ATTRS_WORD2 | FATTR4_WORD2_SECURITY_LABEL)
+#define NFSD4_2_SECURITY_ATTRS         FATTR4_WORD2_SECURITY_LABEL
 #else
-#define NFSD4_2_SUPPORTED_ATTRS_WORD2 0
+#define NFSD4_2_SECURITY_ATTRS         0
 #endif
 
+#define NFSD4_2_SUPPORTED_ATTRS_WORD2 \
+       (NFSD4_1_SUPPORTED_ATTRS_WORD2 | \
+       NFSD4_2_SECURITY_ATTRS)
+
 static inline u32 nfsd_suppattrs0(u32 minorversion)
 {
        return minorversion ? NFSD4_1_SUPPORTED_ATTRS_WORD0
index 88a6bc6..440ef51 100644 (file)
@@ -114,9 +114,14 @@ static unsigned long super_cache_count(struct shrinker *shrink,
 
        sb = container_of(shrink, struct super_block, s_shrink);
 
-       if (!grab_super_passive(sb))
-               return 0;
-
+       /*
+        * Don't call grab_super_passive as it is a potential
+        * scalability bottleneck. The counts could get updated
+        * between super_cache_count and super_cache_scan anyway.
+        * Call to super_cache_count with shrinker_rwsem held
+        * ensures the safety of call to list_lru_count_node() and
+        * s_op->nr_cached_objects().
+        */
        if (sb->s_op && sb->s_op->nr_cached_objects)
                total_objects = sb->s_op->nr_cached_objects(sb,
                                                 sc->nid);
@@ -127,7 +132,6 @@ static unsigned long super_cache_count(struct shrinker *shrink,
                                                 sc->nid);
 
        total_objects = vfs_pressure_ratio(total_objects);
-       drop_super(sb);
        return total_objects;
 }
 
@@ -278,10 +282,8 @@ void deactivate_locked_super(struct super_block *s)
        struct file_system_type *fs = s->s_type;
        if (atomic_dec_and_test(&s->s_active)) {
                cleancache_invalidate_fs(s);
-               fs->kill_sb(s);
-
-               /* caches are now gone, we can safely kill the shrinker now */
                unregister_shrinker(&s->s_shrink);
+               fs->kill_sb(s);
 
                put_filesystem(fs);
                put_super(s);
index a5f56a0..23e3645 100644 (file)
@@ -69,7 +69,7 @@ static inline int gpio_direction_input(unsigned gpio)
 }
 static inline int gpio_direction_output(unsigned gpio, int value)
 {
-       return gpiod_direction_output(gpio_to_desc(gpio), value);
+       return gpiod_direction_output_raw(gpio_to_desc(gpio), value);
 }
 
 static inline int gpio_set_debounce(unsigned gpio, unsigned debounce)
diff --git a/include/dt-bindings/clock/r8a7740-clock.h b/include/dt-bindings/clock/r8a7740-clock.h
new file mode 100644 (file)
index 0000000..476135d
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2014 Ulrich Hecht
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_R8A7740_H__
+#define __DT_BINDINGS_CLOCK_R8A7740_H__
+
+/* CPG */
+#define R8A7740_CLK_SYSTEM     0
+#define R8A7740_CLK_PLLC0      1
+#define R8A7740_CLK_PLLC1      2
+#define R8A7740_CLK_PLLC2      3
+#define R8A7740_CLK_R          4
+#define R8A7740_CLK_USB24S     5
+#define R8A7740_CLK_I          6
+#define R8A7740_CLK_ZG         7
+#define R8A7740_CLK_B          8
+#define R8A7740_CLK_M1         9
+#define R8A7740_CLK_HP         10
+#define R8A7740_CLK_HPP                11
+#define R8A7740_CLK_USBP       12
+#define R8A7740_CLK_S          13
+#define R8A7740_CLK_ZB         14
+#define R8A7740_CLK_M3         15
+#define R8A7740_CLK_CP         16
+
+/* MSTP1 */
+#define R8A7740_CLK_CEU21      28
+#define R8A7740_CLK_CEU20      27
+#define R8A7740_CLK_TMU0       25
+#define R8A7740_CLK_LCDC1      17
+#define R8A7740_CLK_IIC0       16
+#define R8A7740_CLK_TMU1       11
+#define R8A7740_CLK_LCDC0      0
+
+/* MSTP2 */
+#define R8A7740_CLK_SCIFA6     30
+#define R8A7740_CLK_INTCA      29
+#define R8A7740_CLK_SCIFA7     22
+#define R8A7740_CLK_DMAC1      18
+#define R8A7740_CLK_DMAC2      17
+#define R8A7740_CLK_DMAC3      16
+#define R8A7740_CLK_USBDMAC    14
+#define R8A7740_CLK_SCIFA5     7
+#define R8A7740_CLK_SCIFB      6
+#define R8A7740_CLK_SCIFA0     4
+#define R8A7740_CLK_SCIFA1     3
+#define R8A7740_CLK_SCIFA2     2
+#define R8A7740_CLK_SCIFA3     1
+#define R8A7740_CLK_SCIFA4     0
+
+/* MSTP3 */
+#define R8A7740_CLK_CMT1       29
+#define R8A7740_CLK_FSI                28
+#define R8A7740_CLK_IIC1       23
+#define R8A7740_CLK_USBF       20
+#define R8A7740_CLK_SDHI0      14
+#define R8A7740_CLK_SDHI1      13
+#define R8A7740_CLK_MMC                12
+#define R8A7740_CLK_GETHER     9
+#define R8A7740_CLK_TPU0       4
+
+/* MSTP4 */
+#define R8A7740_CLK_USBH       16
+#define R8A7740_CLK_SDHI2      15
+#define R8A7740_CLK_USBFUNC    7
+#define R8A7740_CLK_USBPHY     6
+
+/* SUBCK* */
+#define R8A7740_CLK_SUBCK      9
+#define R8A7740_CLK_SUBCK2     10
+
+#endif /* __DT_BINDINGS_CLOCK_R8A7740_H__ */
index f929a79..c27b3b5 100644 (file)
 #define R8A7790_CLK_MSIOF0             0
 
 /* MSTP1 */
+#define R8A7790_CLK_VCP1               0
+#define R8A7790_CLK_VCP0               1
+#define R8A7790_CLK_VPC1               2
+#define R8A7790_CLK_VPC0               3
+#define R8A7790_CLK_JPU                        6
+#define R8A7790_CLK_SSP1               9
 #define R8A7790_CLK_TMU1               11
+#define R8A7790_CLK_3DG                        12
+#define R8A7790_CLK_2DDMAC             15
+#define R8A7790_CLK_FDP1_2             17
+#define R8A7790_CLK_FDP1_1             18
+#define R8A7790_CLK_FDP1_0             19
 #define R8A7790_CLK_TMU3               21
 #define R8A7790_CLK_TMU2               22
 #define R8A7790_CLK_CMT0               24
@@ -67,6 +78,8 @@
 #define R8A7790_CLK_USBDMAC1           31
 
 /* MSTP5 */
+#define R8A7790_CLK_AUDIO_DMAC1                1
+#define R8A7790_CLK_AUDIO_DMAC0                2
 #define R8A7790_CLK_THERMAL            22
 #define R8A7790_CLK_PWM                        23
 
index f0d4d10..3ea2bbc 100644 (file)
 #define R8A7791_CLK_MSIOF0             0
 
 /* MSTP1 */
+#define R8A7791_CLK_VCP0               1
+#define R8A7791_CLK_VPC0               3
+#define R8A7791_CLK_JPU                        6
+#define R8A7791_CLK_SSP1               9
 #define R8A7791_CLK_TMU1               11
+#define R8A7791_CLK_3DG                        12
+#define R8A7791_CLK_2DDMAC             15
+#define R8A7791_CLK_FDP1_1             18
+#define R8A7791_CLK_FDP1_0             19
 #define R8A7791_CLK_TMU3               21
 #define R8A7791_CLK_TMU2               22
 #define R8A7791_CLK_CMT0               24
@@ -61,6 +69,8 @@
 #define R8A7791_CLK_USBDMAC1           31
 
 /* MSTP5 */
+#define R8A7791_CLK_AUDIO_DMAC1                1
+#define R8A7791_CLK_AUDIO_DMAC0                2
 #define R8A7791_CLK_THERMAL            22
 #define R8A7791_CLK_PWM                        23
 
diff --git a/include/dt-bindings/clock/r8a7794-clock.h b/include/dt-bindings/clock/r8a7794-clock.h
new file mode 100644 (file)
index 0000000..aa9c286
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2014 Renesas Electronics Corporation
+ * Copyright 2013 Ideas On Board SPRL
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_R8A7794_H__
+#define __DT_BINDINGS_CLOCK_R8A7794_H__
+
+/* CPG */
+#define R8A7794_CLK_MAIN               0
+#define R8A7794_CLK_PLL0               1
+#define R8A7794_CLK_PLL1               2
+#define R8A7794_CLK_PLL3               3
+#define R8A7794_CLK_LB                 4
+#define R8A7794_CLK_QSPI               5
+#define R8A7794_CLK_SDH                        6
+#define R8A7794_CLK_SD0                        7
+#define R8A7794_CLK_Z                  8
+
+/* MSTP0 */
+#define R8A7794_CLK_MSIOF0             0
+
+/* MSTP1 */
+#define R8A7794_CLK_VCP0               1
+#define R8A7794_CLK_VPC0               3
+#define R8A7794_CLK_TMU1               11
+#define R8A7794_CLK_3DG                        12
+#define R8A7794_CLK_2DDMAC             15
+#define R8A7794_CLK_FDP1_0             19
+#define R8A7794_CLK_TMU3               21
+#define R8A7794_CLK_TMU2               22
+#define R8A7794_CLK_CMT0               24
+#define R8A7794_CLK_TMU0               25
+#define R8A7794_CLK_VSP1_DU0           28
+#define R8A7794_CLK_VSP1_S             31
+
+/* MSTP2 */
+#define R8A7794_CLK_SCIFA2             2
+#define R8A7794_CLK_SCIFA1             3
+#define R8A7794_CLK_SCIFA0             4
+#define R8A7794_CLK_MSIOF2             5
+#define R8A7794_CLK_SCIFB0             6
+#define R8A7794_CLK_SCIFB1             7
+#define R8A7794_CLK_MSIOF1             8
+#define R8A7794_CLK_SCIFB2             16
+
+/* MSTP3 */
+#define R8A7794_CLK_CMT1               29
+
+/* MSTP5 */
+#define R8A7794_CLK_THERMAL            22
+#define R8A7794_CLK_PWM                        23
+
+/* MSTP7 */
+#define R8A7794_CLK_HSCIF2             13
+#define R8A7794_CLK_SCIF5              14
+#define R8A7794_CLK_SCIF4              15
+#define R8A7794_CLK_HSCIF1             16
+#define R8A7794_CLK_HSCIF0             17
+#define R8A7794_CLK_SCIF3              18
+#define R8A7794_CLK_SCIF2              19
+#define R8A7794_CLK_SCIF1              20
+#define R8A7794_CLK_SCIF0              21
+
+/* MSTP8 */
+#define R8A7794_CLK_VIN1               10
+#define R8A7794_CLK_VIN0               11
+#define R8A7794_CLK_ETHER              13
+
+/* MSTP9 */
+#define R8A7794_CLK_GPIO6              5
+#define R8A7794_CLK_GPIO5              7
+#define R8A7794_CLK_GPIO4              8
+#define R8A7794_CLK_GPIO3              9
+#define R8A7794_CLK_GPIO2              10
+#define R8A7794_CLK_GPIO1              11
+#define R8A7794_CLK_GPIO0              12
+
+/* MSTP11 */
+#define R8A7794_CLK_SCIFA3             6
+#define R8A7794_CLK_SCIFA4             7
+#define R8A7794_CLK_SCIFA5             8
+
+#endif /* __DT_BINDINGS_CLOCK_R8A7794_H__ */
index 3d33794..7448edf 100644 (file)
@@ -40,8 +40,8 @@
 
 /* Active pin states */
 #define PIN_OUTPUT             (0 | PULL_DIS)
-#define PIN_OUTPUT_PULLUP      (PIN_OUTPUT | PULL_ENA | PULL_UP)
-#define PIN_OUTPUT_PULLDOWN    (PIN_OUTPUT | PULL_ENA)
+#define PIN_OUTPUT_PULLUP      (PULL_UP)
+#define PIN_OUTPUT_PULLDOWN    (0)
 #define PIN_INPUT              (INPUT_EN | PULL_DIS)
 #define PIN_INPUT_SLEW         (INPUT_EN | SLEWCONTROL)
 #define PIN_INPUT_PULLUP       (PULL_ENA | INPUT_EN | PULL_UP)
index be5fd38..5d858e0 100644 (file)
  * position @h. For example
  * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
  */
-#define GENMASK(h, l)          (((U32_C(1) << ((h) - (l) + 1)) - 1) << (l))
-#define GENMASK_ULL(h, l)      (((U64_C(1) << ((h) - (l) + 1)) - 1) << (l))
+#define GENMASK(h, l) \
+       (((~0UL) << (l)) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
+
+#define GENMASK_ULL(h, l) \
+       (((~0ULL) << (l)) & (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h))))
 
 extern unsigned int __sw_hweight8(unsigned int w);
 extern unsigned int __sw_hweight16(unsigned int w);
index 67301a4..879065d 100644 (file)
@@ -289,7 +289,7 @@ extern struct clocksource* clocksource_get_next(void);
 extern void clocksource_change_rating(struct clocksource *cs, int rating);
 extern void clocksource_suspend(void);
 extern void clocksource_resume(void);
-extern struct clocksource * __init __weak clocksource_default_clock(void);
+extern struct clocksource * __init clocksource_default_clock(void);
 extern void clocksource_mark_unstable(struct clocksource *cs);
 
 extern u64
index 7e1c76e..01e3132 100644 (file)
@@ -22,7 +22,7 @@ extern int sysctl_extfrag_handler(struct ctl_table *table, int write,
 extern int fragmentation_index(struct zone *zone, unsigned int order);
 extern unsigned long try_to_compact_pages(struct zonelist *zonelist,
                        int order, gfp_t gfp_mask, nodemask_t *mask,
-                       bool sync, bool *contended);
+                       enum migrate_mode mode, bool *contended);
 extern void compact_pgdat(pg_data_t *pgdat, int order);
 extern void reset_isolation_suitable(pg_data_t *pgdat);
 extern unsigned long compaction_suitable(struct zone *zone, int order);
@@ -91,7 +91,7 @@ static inline bool compaction_restarting(struct zone *zone, int order)
 #else
 static inline unsigned long try_to_compact_pages(struct zonelist *zonelist,
                        int order, gfp_t gfp_mask, nodemask_t *nodemask,
-                       bool sync, bool *contended)
+                       enum migrate_mode mode, bool *contended)
 {
        return COMPACT_CONTINUE;
 }
index 7032518..60023e5 100644 (file)
 extern unsigned long long elfcorehdr_addr;
 extern unsigned long long elfcorehdr_size;
 
-extern int __weak elfcorehdr_alloc(unsigned long long *addr,
-                                  unsigned long long *size);
-extern void __weak elfcorehdr_free(unsigned long long addr);
-extern ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos);
-extern ssize_t __weak elfcorehdr_read_notes(char *buf, size_t count, u64 *ppos);
-extern int __weak remap_oldmem_pfn_range(struct vm_area_struct *vma,
-                                        unsigned long from, unsigned long pfn,
-                                        unsigned long size, pgprot_t prot);
+extern int elfcorehdr_alloc(unsigned long long *addr, unsigned long long *size);
+extern void elfcorehdr_free(unsigned long long addr);
+extern ssize_t elfcorehdr_read(char *buf, size_t count, u64 *ppos);
+extern ssize_t elfcorehdr_read_notes(char *buf, size_t count, u64 *ppos);
+extern int remap_oldmem_pfn_range(struct vm_area_struct *vma,
+                                 unsigned long from, unsigned long pfn,
+                                 unsigned long size, pgprot_t prot);
 
 extern ssize_t copy_oldmem_page(unsigned long, char *, size_t,
                                                unsigned long, int);
index 952b010..28f1363 100644 (file)
@@ -609,6 +609,10 @@ extern int devres_release_group(struct device *dev, void *id);
 
 /* managed devm_k.alloc/kfree for device drivers */
 extern void *devm_kmalloc(struct device *dev, size_t size, gfp_t gfp);
+extern char *devm_kvasprintf(struct device *dev, gfp_t gfp, const char *fmt,
+                            va_list ap);
+extern __printf(3, 4)
+char *devm_kasprintf(struct device *dev, gfp_t gfp, const char *fmt, ...);
 static inline void *devm_kzalloc(struct device *dev, size_t size, gfp_t gfp)
 {
        return devm_kmalloc(dev, size, gfp | __GFP_ZERO);
index 7a8144f..b7ce0c6 100644 (file)
@@ -1,11 +1,11 @@
 #ifndef __LINUX_GPIO_CONSUMER_H
 #define __LINUX_GPIO_CONSUMER_H
 
+#include <linux/bug.h>
 #include <linux/err.h>
 #include <linux/kernel.h>
 
 struct device;
-struct gpio_chip;
 
 /**
  * Opaque descriptor for a GPIO. These are obtained using gpiod_get() and are
@@ -18,24 +18,86 @@ struct gpio_desc;
 
 #ifdef CONFIG_GPIOLIB
 
+#define GPIOD_FLAGS_BIT_DIR_SET                BIT(0)
+#define GPIOD_FLAGS_BIT_DIR_OUT                BIT(1)
+#define GPIOD_FLAGS_BIT_DIR_VAL                BIT(2)
+
+/**
+ * Optional flags that can be passed to one of gpiod_* to configure direction
+ * and output value. These values cannot be OR'd.
+ */
+enum gpiod_flags {
+       GPIOD_ASIS      = 0,
+       GPIOD_IN        = GPIOD_FLAGS_BIT_DIR_SET,
+       GPIOD_OUT_LOW   = GPIOD_FLAGS_BIT_DIR_SET | GPIOD_FLAGS_BIT_DIR_OUT,
+       GPIOD_OUT_HIGH  = GPIOD_FLAGS_BIT_DIR_SET | GPIOD_FLAGS_BIT_DIR_OUT |
+                         GPIOD_FLAGS_BIT_DIR_VAL,
+};
+
 /* Acquire and dispose GPIOs */
-struct gpio_desc *__must_check gpiod_get(struct device *dev,
-                                        const char *con_id);
-struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
+struct gpio_desc *__must_check __gpiod_get(struct device *dev,
+                                        const char *con_id,
+                                        enum gpiod_flags flags);
+#define __gpiod_get(dev, con_id, flags, ...) __gpiod_get(dev, con_id, flags)
+#define gpiod_get(varargs...) __gpiod_get(varargs, 0)
+struct gpio_desc *__must_check __gpiod_get_index(struct device *dev,
                                               const char *con_id,
-                                              unsigned int idx);
+                                              unsigned int idx,
+                                              enum gpiod_flags flags);
+#define __gpiod_get_index(dev, con_id, index, flags, ...)              \
+       __gpiod_get_index(dev, con_id, index, flags)
+#define gpiod_get_index(varargs...) __gpiod_get_index(varargs, 0)
+struct gpio_desc *__must_check __gpiod_get_optional(struct device *dev,
+                                                 const char *con_id,
+                                                 enum gpiod_flags flags);
+#define __gpiod_get_optional(dev, con_id, flags, ...)                  \
+       __gpiod_get_optional(dev, con_id, flags)
+#define gpiod_get_optional(varargs...) __gpiod_get_optional(varargs, 0)
+struct gpio_desc *__must_check __gpiod_get_index_optional(struct device *dev,
+                                                       const char *con_id,
+                                                       unsigned int index,
+                                                       enum gpiod_flags flags);
+#define __gpiod_get_index_optional(dev, con_id, index, flags, ...)     \
+       __gpiod_get_index_optional(dev, con_id, index, flags)
+#define gpiod_get_index_optional(varargs...)                           \
+       __gpiod_get_index_optional(varargs, 0)
+
 void gpiod_put(struct gpio_desc *desc);
 
-struct gpio_desc *__must_check devm_gpiod_get(struct device *dev,
-                                             const char *con_id);
-struct gpio_desc *__must_check devm_gpiod_get_index(struct device *dev,
+struct gpio_desc *__must_check __devm_gpiod_get(struct device *dev,
+                                             const char *con_id,
+                                             enum gpiod_flags flags);
+#define __devm_gpiod_get(dev, con_id, flags, ...)                      \
+       __devm_gpiod_get(dev, con_id, flags)
+#define devm_gpiod_get(varargs...) __devm_gpiod_get(varargs, 0)
+struct gpio_desc *__must_check __devm_gpiod_get_index(struct device *dev,
                                                    const char *con_id,
-                                                   unsigned int idx);
+                                                   unsigned int idx,
+                                                   enum gpiod_flags flags);
+#define __devm_gpiod_get_index(dev, con_id, index, flags, ...)         \
+       __devm_gpiod_get_index(dev, con_id, index, flags)
+#define devm_gpiod_get_index(varargs...) __devm_gpiod_get_index(varargs, 0)
+struct gpio_desc *__must_check __devm_gpiod_get_optional(struct device *dev,
+                                                      const char *con_id,
+                                                      enum gpiod_flags flags);
+#define __devm_gpiod_get_optional(dev, con_id, flags, ...)             \
+       __devm_gpiod_get_optional(dev, con_id, flags)
+#define devm_gpiod_get_optional(varargs...)                            \
+       __devm_gpiod_get_optional(varargs, 0)
+struct gpio_desc *__must_check
+__devm_gpiod_get_index_optional(struct device *dev, const char *con_id,
+                             unsigned int index, enum gpiod_flags flags);
+#define __devm_gpiod_get_index_optional(dev, con_id, index, flags, ...)        \
+       __devm_gpiod_get_index_optional(dev, con_id, index, flags)
+#define devm_gpiod_get_index_optional(varargs...)                      \
+       __devm_gpiod_get_index_optional(varargs, 0)
+
 void devm_gpiod_put(struct device *dev, struct gpio_desc *desc);
 
 int gpiod_get_direction(const struct gpio_desc *desc);
 int gpiod_direction_input(struct gpio_desc *desc);
 int gpiod_direction_output(struct gpio_desc *desc, int value);
+int gpiod_direction_output_raw(struct gpio_desc *desc, int value);
 
 /* Value get/set from non-sleeping context */
 int gpiod_get_value(const struct gpio_desc *desc);
@@ -59,7 +121,6 @@ int gpiod_to_irq(const struct gpio_desc *desc);
 /* Convert between the old gpio_ and new gpiod_ interfaces */
 struct gpio_desc *gpio_to_desc(unsigned gpio);
 int desc_to_gpio(const struct gpio_desc *desc);
-struct gpio_chip *gpiod_to_chip(const struct gpio_desc *desc);
 
 #else /* CONFIG_GPIOLIB */
 
@@ -74,6 +135,20 @@ static inline struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
 {
        return ERR_PTR(-ENOSYS);
 }
+
+static inline struct gpio_desc *__must_check
+gpiod_get_optional(struct device *dev, const char *con_id)
+{
+       return ERR_PTR(-ENOSYS);
+}
+
+static inline struct gpio_desc *__must_check
+gpiod_get_index_optional(struct device *dev, const char *con_id,
+                        unsigned int index)
+{
+       return ERR_PTR(-ENOSYS);
+}
+
 static inline void gpiod_put(struct gpio_desc *desc)
 {
        might_sleep();
@@ -94,6 +169,20 @@ struct gpio_desc *__must_check devm_gpiod_get_index(struct device *dev,
 {
        return ERR_PTR(-ENOSYS);
 }
+
+static inline struct gpio_desc *__must_check
+devm_gpiod_get_optional(struct device *dev, const char *con_id)
+{
+       return ERR_PTR(-ENOSYS);
+}
+
+static inline struct gpio_desc *__must_check
+devm_gpiod_get_index_optional(struct device *dev, const char *con_id,
+                             unsigned int index)
+{
+       return ERR_PTR(-ENOSYS);
+}
+
 static inline void devm_gpiod_put(struct device *dev, struct gpio_desc *desc)
 {
        might_sleep();
@@ -121,6 +210,12 @@ static inline int gpiod_direction_output(struct gpio_desc *desc, int value)
        WARN_ON(1);
        return -ENOSYS;
 }
+static inline int gpiod_direction_output_raw(struct gpio_desc *desc, int value)
+{
+       /* GPIO can never have been requested */
+       WARN_ON(1);
+       return -ENOSYS;
+}
 
 
 static inline int gpiod_get_value(const struct gpio_desc *desc)
@@ -207,12 +302,6 @@ static inline int desc_to_gpio(const struct gpio_desc *desc)
        WARN_ON(1);
        return -EINVAL;
 }
-static inline struct gpio_chip *gpiod_to_chip(const struct gpio_desc *desc)
-{
-       /* GPIO can never have been requested */
-       WARN_ON(1);
-       return ERR_PTR(-ENODEV);
-}
 
 
 #endif /* CONFIG_GPIOLIB */
index a3e181e..9fe2836 100644 (file)
@@ -10,6 +10,8 @@ struct of_phandle_args;
 struct device_node;
 struct seq_file;
 
+#ifdef CONFIG_GPIOLIB
+
 /**
  * struct gpio_chip - abstract a GPIO controller
  * @label: for diagnostics
@@ -129,6 +131,11 @@ extern struct gpio_chip *gpiochip_find(void *data,
 int gpiod_lock_as_irq(struct gpio_desc *desc);
 void gpiod_unlock_as_irq(struct gpio_desc *desc);
 
+struct gpio_chip *gpiod_to_chip(const struct gpio_desc *desc);
+
+struct gpio_desc *gpiochip_get_desc(struct gpio_chip *chip,
+                                   u16 hwnum);
+
 enum gpio_lookup_flags {
        GPIO_ACTIVE_HIGH = (0 << 0),
        GPIO_ACTIVE_LOW = (1 << 0),
@@ -183,4 +190,15 @@ struct gpiod_lookup_table {
 
 void gpiod_add_lookup_table(struct gpiod_lookup_table *table);
 
+#else /* CONFIG_GPIOLIB */
+
+static inline struct gpio_chip *gpiod_to_chip(const struct gpio_desc *desc)
+{
+       /* GPIO can never have been requested */
+       WARN_ON(1);
+       return ERR_PTR(-ENODEV);
+}
+
+#endif /* CONFIG_GPIOLIB */
+
 #endif
index 8bbd7bc..03fa332 100644 (file)
@@ -72,7 +72,7 @@ struct iio_event_data {
 
 #define IIO_EVENT_CODE_EXTRACT_TYPE(mask) ((mask >> 56) & 0xFF)
 
-#define IIO_EVENT_CODE_EXTRACT_DIR(mask) ((mask >> 48) & 0xCF)
+#define IIO_EVENT_CODE_EXTRACT_DIR(mask) ((mask >> 48) & 0x7F)
 
 #define IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(mask) ((mask >> 32) & 0xFF)
 
index 0068708..0a21fbe 100644 (file)
@@ -242,7 +242,7 @@ static inline void in_dev_put(struct in_device *idev)
 static __inline__ __be32 inet_make_mask(int logmask)
 {
        if (logmask)
-               return htonl(~((1<<(32-logmask))-1));
+               return htonl(~((1U<<(32-logmask))-1));
        return 0;
 }
 
index 6b06d37..e465bb1 100644 (file)
@@ -283,7 +283,7 @@ struct kgdb_io {
 
 extern struct kgdb_arch                arch_kgdb_ops;
 
-extern unsigned long __weak kgdb_arch_pc(int exception, struct pt_regs *regs);
+extern unsigned long kgdb_arch_pc(int exception, struct pt_regs *regs);
 
 #ifdef CONFIG_SERIAL_KGDB_NMI
 extern int kgdb_register_nmi_console(void);
index bb7384e..8b8d8d1 100644 (file)
@@ -35,7 +35,7 @@ struct memory_block {
 };
 
 int arch_get_memory_phys_device(unsigned long start_pfn);
-unsigned long __weak memory_block_size_bytes(void);
+unsigned long memory_block_size_bytes(void);
 
 /* These states are exposed to userspace as text strings in sysfs */
 #define        MEM_ONLINE              (1<<0) /* exposed to userspace */
index 8f6f2e9..5738817 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/fb.h>
 #include <linux/io.h>
 #include <linux/jiffies.h>
+#include <linux/mmc/card.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 
  */
 #define TMIO_MMC_HAVE_HIGH_REG         (1 << 6)
 
+/*
+ * Some controllers have CMD12 automatically
+ * issue/non-issue register
+ */
+#define TMIO_MMC_HAVE_CMD12_CTRL       (1 << 7)
+
+/*
+ * Some controllers needs to set 1 on SDIO status reserved bits
+ */
+#define TMIO_MMC_SDIO_STATUS_QUIRK     (1 << 8)
+
+/*
+ * Some controllers have DMA enable/disable register
+ */
+#define TMIO_MMC_HAVE_CTL_DMA_REG      (1 << 9)
+
+/*
+ * Some controllers allows to set SDx actual clock
+ */
+#define TMIO_MMC_CLK_ACTUAL            (1 << 10)
+
 int tmio_core_mmc_enable(void __iomem *cnf, int shift, unsigned long base);
 int tmio_core_mmc_resume(void __iomem *cnf, int shift, unsigned long base);
 void tmio_core_mmc_pwr(void __iomem *cnf, int shift, int state);
@@ -96,6 +118,7 @@ struct tmio_mmc_dma {
        int slave_id_tx;
        int slave_id_rx;
        int alignment_shift;
+       dma_addr_t dma_rx_offset;
        bool (*filter)(struct dma_chan *chan, void *arg);
 };
 
@@ -120,6 +143,8 @@ struct tmio_mmc_data {
        /* clock management callbacks */
        int (*clk_enable)(struct platform_device *pdev, unsigned int *f);
        void (*clk_disable)(struct platform_device *pdev);
+       int (*multi_io_quirk)(struct mmc_card *card,
+                             unsigned int direction, int blk_size);
 };
 
 /*
index 84a31ad..a2901c4 100644 (file)
@@ -5,7 +5,9 @@
 #include <linux/mempolicy.h>
 #include <linux/migrate_mode.h>
 
-typedef struct page *new_page_t(struct page *, unsigned long private, int **);
+typedef struct page *new_page_t(struct page *page, unsigned long private,
+                               int **reason);
+typedef void free_page_t(struct page *page, unsigned long private);
 
 /*
  * Return values from addresss_space_operations.migratepage():
@@ -38,7 +40,7 @@ enum migrate_reason {
 extern void putback_movable_pages(struct list_head *l);
 extern int migrate_page(struct address_space *,
                        struct page *, struct page *, enum migrate_mode);
-extern int migrate_pages(struct list_head *l, new_page_t x,
+extern int migrate_pages(struct list_head *l, new_page_t new, free_page_t free,
                unsigned long private, enum migrate_mode mode, int reason);
 
 extern int migrate_prep(void);
@@ -56,8 +58,9 @@ extern int migrate_page_move_mapping(struct address_space *mapping,
 #else
 
 static inline void putback_movable_pages(struct list_head *l) {}
-static inline int migrate_pages(struct list_head *l, new_page_t x,
-               unsigned long private, enum migrate_mode mode, int reason)
+static inline int migrate_pages(struct list_head *l, new_page_t new,
+               free_page_t free, unsigned long private, enum migrate_mode mode,
+               int reason)
        { return -ENOSYS; }
 
 static inline int migrate_prep(void) { return -ENOSYS; }
index 0a0b024..d5039da 100644 (file)
@@ -1041,6 +1041,14 @@ extern void show_free_areas(unsigned int flags);
 extern bool skip_free_areas_node(unsigned int flags, int nid);
 
 int shmem_zero_setup(struct vm_area_struct *);
+#ifdef CONFIG_SHMEM
+bool shmem_mapping(struct address_space *mapping);
+#else
+static inline bool shmem_mapping(struct address_space *mapping)
+{
+       return false;
+}
+#endif
 
 extern int can_do_mlock(void);
 extern int user_shm_lock(size_t, struct user_struct *);
@@ -1848,9 +1856,6 @@ void page_cache_async_readahead(struct address_space *mapping,
                                unsigned long size);
 
 unsigned long max_sane_readahead(unsigned long nr);
-unsigned long ra_submit(struct file_ra_state *ra,
-                       struct address_space *mapping,
-                       struct file *filp);
 
 /* Generic expand stack which grows the stack according to GROWS{UP,DOWN} */
 extern int expand_stack(struct vm_area_struct *vma, unsigned long address);
index 87b1f4f..6cfd7f0 100644 (file)
@@ -140,6 +140,13 @@ struct mmc_host_ops {
        int     (*select_drive_strength)(unsigned int max_dtr, int host_drv, int card_drv);
        void    (*hw_reset)(struct mmc_host *host);
        void    (*card_event)(struct mmc_host *host);
+
+       /*
+        * Optional callback to support controllers with HW issues for multiple
+        * I/O. Returns the number of supported blocks for the request.
+        */
+       int     (*multi_io_quirk)(struct mmc_card *card,
+                                 unsigned int direction, int blk_size);
 };
 
 struct mmc_card;
index e6800f0..1884353 100644 (file)
@@ -361,9 +361,10 @@ struct zone {
        /* Set to true when the PG_migrate_skip bits should be cleared */
        bool                    compact_blockskip_flush;
 
-       /* pfns where compaction scanners should start */
+       /* pfn where compaction free scanner should start */
        unsigned long           compact_cached_free_pfn;
-       unsigned long           compact_cached_migrate_pfn;
+       /* pfn where async and sync compaction migration scanner should start */
+       unsigned long           compact_cached_migrate_pfn[2];
 #endif
 #ifdef CONFIG_MEMORY_HOTPLUG
        /* see spanned/present_pages for more description */
index 5624e4e..53988cb 100644 (file)
@@ -1247,11 +1247,22 @@ struct nfs41_free_stateid_res {
        unsigned int                    status;
 };
 
+static inline void
+nfs_free_pnfs_ds_cinfo(struct pnfs_ds_commit_info *cinfo)
+{
+       kfree(cinfo->buckets);
+}
+
 #else
 
 struct pnfs_ds_commit_info {
 };
 
+static inline void
+nfs_free_pnfs_ds_cinfo(struct pnfs_ds_commit_info *cinfo)
+{
+}
+
 #endif /* CONFIG_NFS_V4_1 */
 
 struct nfs_page;
index ddd1774..622dfc9 100644 (file)
@@ -300,7 +300,7 @@ const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur,
  */
 const char *of_prop_next_string(struct property *prop, const char *cur);
 
-int of_device_is_stdout_path(struct device_node *dn);
+bool of_console_check(struct device_node *dn, char *name, int index);
 
 #else /* CONFIG_OF */
 
@@ -501,9 +501,9 @@ static inline int of_machine_is_compatible(const char *compat)
        return 0;
 }
 
-static inline int of_device_is_stdout_path(struct device_node *dn)
+static inline bool of_console_check(const struct device_node *dn, const char *name, int index)
 {
-       return 0;
+       return false;
 }
 
 static inline const __be32 *of_prop_next_u32(struct property *prop,
index 3bbeb60..2b233db 100644 (file)
 #ifndef __LINUX_OF_GRAPH_H
 #define __LINUX_OF_GRAPH_H
 
+/**
+ * struct of_endpoint - the OF graph endpoint data structure
+ * @port: identifier (value of reg property) of a port this endpoint belongs to
+ * @id: identifier (value of reg property) of this endpoint
+ * @local_node: pointer to device_node of this endpoint
+ */
+struct of_endpoint {
+       unsigned int port;
+       unsigned int id;
+       const struct device_node *local_node;
+};
+
 #ifdef CONFIG_OF
+int of_graph_parse_endpoint(const struct device_node *node,
+                               struct of_endpoint *endpoint);
 struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
                                        struct device_node *previous);
 struct device_node *of_graph_get_remote_port_parent(
@@ -22,6 +36,12 @@ struct device_node *of_graph_get_remote_port_parent(
 struct device_node *of_graph_get_remote_port(const struct device_node *node);
 #else
 
+static inline int of_graph_parse_endpoint(const struct device_node *node,
+                                       struct of_endpoint *endpoint);
+{
+       return -ENOSYS;
+}
+
 static inline struct device_node *of_graph_get_next_endpoint(
                                        const struct device_node *parent,
                                        struct device_node *previous)
index 1710d1b..09c1b03 100644 (file)
@@ -243,12 +243,20 @@ static inline struct page *page_cache_alloc_readahead(struct address_space *x)
 
 typedef int filler_t(void *, struct page *);
 
-extern struct page * find_get_page(struct address_space *mapping,
-                               pgoff_t index);
-extern struct page * find_lock_page(struct address_space *mapping,
-                               pgoff_t index);
-extern struct page * find_or_create_page(struct address_space *mapping,
-                               pgoff_t index, gfp_t gfp_mask);
+pgoff_t page_cache_next_hole(struct address_space *mapping,
+                            pgoff_t index, unsigned long max_scan);
+pgoff_t page_cache_prev_hole(struct address_space *mapping,
+                            pgoff_t index, unsigned long max_scan);
+
+struct page *find_get_entry(struct address_space *mapping, pgoff_t offset);
+struct page *find_get_page(struct address_space *mapping, pgoff_t offset);
+struct page *find_lock_entry(struct address_space *mapping, pgoff_t offset);
+struct page *find_lock_page(struct address_space *mapping, pgoff_t offset);
+struct page *find_or_create_page(struct address_space *mapping, pgoff_t index,
+                                gfp_t gfp_mask);
+unsigned find_get_entries(struct address_space *mapping, pgoff_t start,
+                         unsigned int nr_entries, struct page **entries,
+                         pgoff_t *indices);
 unsigned find_get_pages(struct address_space *mapping, pgoff_t start,
                        unsigned int nr_pages, struct page **pages);
 unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t start,
@@ -270,8 +278,6 @@ static inline struct page *grab_cache_page(struct address_space *mapping,
 
 extern struct page * grab_cache_page_nowait(struct address_space *mapping,
                                pgoff_t index);
-extern struct page * read_cache_page_async(struct address_space *mapping,
-                               pgoff_t index, filler_t *filler, void *data);
 extern struct page * read_cache_page(struct address_space *mapping,
                                pgoff_t index, filler_t *filler, void *data);
 extern struct page * read_cache_page_gfp(struct address_space *mapping,
@@ -279,14 +285,6 @@ extern struct page * read_cache_page_gfp(struct address_space *mapping,
 extern int read_cache_pages(struct address_space *mapping,
                struct list_head *pages, filler_t *filler, void *data);
 
-static inline struct page *read_mapping_page_async(
-                               struct address_space *mapping,
-                               pgoff_t index, void *data)
-{
-       filler_t *filler = (filler_t *)mapping->a_ops->readpage;
-       return read_cache_page_async(mapping, index, filler, data);
-}
-
 static inline struct page *read_mapping_page(struct address_space *mapping,
                                pgoff_t index, void *data)
 {
index e4dbfab..b45d391 100644 (file)
@@ -22,6 +22,11 @@ struct pagevec {
 
 void __pagevec_release(struct pagevec *pvec);
 void __pagevec_lru_add(struct pagevec *pvec);
+unsigned pagevec_lookup_entries(struct pagevec *pvec,
+                               struct address_space *mapping,
+                               pgoff_t start, unsigned nr_entries,
+                               pgoff_t *indices);
+void pagevec_remove_exceptionals(struct pagevec *pvec);
 unsigned pagevec_lookup(struct pagevec *pvec, struct address_space *mapping,
                pgoff_t start, unsigned nr_pages);
 unsigned pagevec_lookup_tag(struct pagevec *pvec,
index 33aa2ca..0e5e16c 100644 (file)
@@ -324,6 +324,7 @@ struct pci_dev {
        unsigned int    is_added:1;
        unsigned int    is_busmaster:1; /* device is busmaster */
        unsigned int    no_msi:1;       /* device may not use msi */
+       unsigned int    no_64bit_msi:1; /* device may only use 32-bit MSIs */
        unsigned int    block_cfg_access:1;     /* config space access is blocked */
        unsigned int    broken_parity_status:1; /* Device generates false positive parity */
        unsigned int    irq_reroute_variant:2;  /* device needs IRQ rerouting variant */
index 3f83459..eab7fdf 100644 (file)
@@ -153,9 +153,10 @@ void phy_put(struct phy *phy);
 void devm_phy_put(struct device *dev, struct phy *phy);
 struct phy *of_phy_simple_xlate(struct device *dev,
        struct of_phandle_args *args);
-struct phy *phy_create(struct device *dev, const struct phy_ops *ops,
-       struct phy_init_data *init_data);
-struct phy *devm_phy_create(struct device *dev,
+struct phy *phy_create(struct device *dev, struct device_node *node,
+                      const struct phy_ops *ops,
+                      struct phy_init_data *init_data);
+struct phy *devm_phy_create(struct device *dev, struct device_node *node,
        const struct phy_ops *ops, struct phy_init_data *init_data);
 void phy_destroy(struct phy *phy);
 void devm_phy_destroy(struct device *dev, struct phy *phy);
@@ -266,13 +267,17 @@ static inline struct phy *of_phy_simple_xlate(struct device *dev,
 }
 
 static inline struct phy *phy_create(struct device *dev,
-       const struct phy_ops *ops, struct phy_init_data *init_data)
+                                    struct device_node *node,
+                                    const struct phy_ops *ops,
+                                    struct phy_init_data *init_data)
 {
        return ERR_PTR(-ENOSYS);
 }
 
 static inline struct phy *devm_phy_create(struct device *dev,
-       const struct phy_ops *ops, struct phy_init_data *init_data)
+                                         struct device_node *node,
+                                         const struct phy_ops *ops,
+                                         struct phy_init_data *init_data)
 {
        return ERR_PTR(-ENOSYS);
 }
index a15f107..d578a60 100644 (file)
@@ -57,7 +57,7 @@
  *     which are then pulled up with an external resistor. Setting this
  *     config will enable open drain mode, the argument is ignored.
  * @PIN_CONFIG_DRIVE_OPEN_SOURCE: the pin will be driven with open source
- *     (open emitter). Setting this config will enable open drain mode, the
+ *     (open emitter). Setting this config will enable open source mode, the
  *     argument is ignored.
  * @PIN_CONFIG_DRIVE_STRENGTH: the pin will sink or source at most the current
  *     passed as argument. The argument is in mA.
index 1a2e990..a5f045e 100644 (file)
@@ -14,7 +14,7 @@
 #ifndef __RCAR_DU_H__
 #define __RCAR_DU_H__
 
-#include <drm/drm_mode.h>
+#include <video/videomode.h>
 
 enum rcar_du_output {
        RCAR_DU_OUTPUT_DPAD0,
@@ -35,7 +35,7 @@ enum rcar_du_encoder_type {
 struct rcar_du_panel_data {
        unsigned int width_mm;          /* Panel width in mm */
        unsigned int height_mm;         /* Panel height in mm */
-       struct drm_mode_modeinfo mode;
+       struct videomode mode;
 };
 
 struct rcar_du_connector_lvds_data {
index 16c9a62..2a5897a 100644 (file)
 #ifdef CONFIG_PM
 extern int pm_generic_runtime_suspend(struct device *dev);
 extern int pm_generic_runtime_resume(struct device *dev);
+extern int pm_runtime_force_suspend(struct device *dev);
+extern int pm_runtime_force_resume(struct device *dev);
 #else
 static inline int pm_generic_runtime_suspend(struct device *dev) { return 0; }
 static inline int pm_generic_runtime_resume(struct device *dev) { return 0; }
+static inline int pm_runtime_force_suspend(struct device *dev) { return 0; }
+static inline int pm_runtime_force_resume(struct device *dev) { return 0; }
 #endif
 
 #ifdef CONFIG_PM_RUNTIME
index 07e7945..e97fc65 100644 (file)
@@ -253,9 +253,6 @@ struct charger_manager {
        struct device *dev;
        struct charger_desc *desc;
 
-       struct power_supply *fuel_gauge;
-       struct power_supply **charger_stat;
-
 #ifdef CONFIG_THERMAL
        struct thermal_zone_device *tzd_batt;
 #endif
index 4039407..e8be53e 100644 (file)
@@ -219,6 +219,7 @@ static inline void radix_tree_replace_slot(void **pslot, void *item)
 int radix_tree_insert(struct radix_tree_root *, unsigned long, void *);
 void *radix_tree_lookup(struct radix_tree_root *, unsigned long);
 void **radix_tree_lookup_slot(struct radix_tree_root *, unsigned long);
+void *radix_tree_delete_item(struct radix_tree_root *, unsigned long, void *);
 void *radix_tree_delete(struct radix_tree_root *, unsigned long);
 unsigned int
 radix_tree_gang_lookup(struct radix_tree_root *root, void **results,
@@ -226,10 +227,6 @@ radix_tree_gang_lookup(struct radix_tree_root *root, void **results,
 unsigned int radix_tree_gang_lookup_slot(struct radix_tree_root *root,
                        void ***results, unsigned long *indices,
                        unsigned long first_index, unsigned int max_items);
-unsigned long radix_tree_next_hole(struct radix_tree_root *root,
-                               unsigned long index, unsigned long max_scan);
-unsigned long radix_tree_prev_hole(struct radix_tree_root *root,
-                               unsigned long index, unsigned long max_scan);
 int radix_tree_preload(gfp_t gfp_mask);
 int radix_tree_maybe_preload(gfp_t gfp_mask);
 void radix_tree_init(void);
index 9d55438..4d1771c 100644 (file)
@@ -51,6 +51,7 @@ extern struct file *shmem_kernel_file_setup(const char *name, loff_t size,
                                            unsigned long flags);
 extern int shmem_zero_setup(struct vm_area_struct *);
 extern int shmem_lock(struct file *file, int lock, struct user_struct *user);
+extern bool shmem_mapping(struct address_space *mapping);
 extern void shmem_unlock_mapping(struct address_space *mapping);
 extern struct page *shmem_read_mapping_page_gfp(struct address_space *mapping,
                                        pgoff_t index, gfp_t gfp_mask);
index 708bd11..a210bac 100644 (file)
@@ -30,6 +30,7 @@ struct ci_hdrc_platform_data {
 #define CI_HDRC_CONTROLLER_STOPPED_EVENT       1
        void    (*notify_event) (struct ci_hdrc *ci, unsigned event);
        struct regulator        *reg_vbus;
+       bool                    tpl_support;
 };
 
 /* Default offset of capability registers */
index efe8d8a..e41feeb 100644 (file)
@@ -106,7 +106,8 @@ struct usb_hcd {
         * OTG and some Host controllers need software interaction with phys;
         * other external phys should be software-transparent
         */
-       struct usb_phy  *phy;
+       struct usb_phy          *usb_phy;
+       struct phy              *phy;
 
        /* Flags that need to be manipulated atomically because they can
         * change while the host controller is running.  Always use
index 3a49735..70fa7b7 100644 (file)
@@ -51,17 +51,13 @@ struct v4l2_of_bus_parallel {
 
 /**
  * struct v4l2_of_endpoint - the endpoint data structure
- * @port: identifier (value of reg property) of a port this endpoint belongs to
- * @id: identifier (value of reg property) of this endpoint
- * @local_node: pointer to device_node of this endpoint
+ * @base: struct of_endpoint containing port, id, and local of_node
  * @bus_type: bus type
  * @bus: bus configuration data structure
  * @head: list head for this structure
  */
 struct v4l2_of_endpoint {
-       unsigned int port;
-       unsigned int id;
-       const struct device_node *local_node;
+       struct of_endpoint base;
        enum v4l2_mbus_type bus_type;
        union {
                struct v4l2_of_bus_parallel parallel;
index a3353f4..ba41e01 100644 (file)
@@ -433,6 +433,11 @@ static inline void sctp_assoc_pending_pmtu(struct sock *sk, struct sctp_associat
        asoc->pmtu_pending = 0;
 }
 
+static inline bool sctp_chunk_pending(const struct sctp_chunk *chunk)
+{
+       return !list_empty(&chunk->list);
+}
+
 /* Walk through a list of TLV parameters.  Don't trust the
  * individual parameter lengths and instead depend on
  * the chunk length to indicate when to stop.  Make sure
index 7f4eeb3..72a31db 100644 (file)
@@ -248,9 +248,9 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *,
                                              int, __be16);
 struct sctp_chunk *sctp_make_asconf_set_prim(struct sctp_association *asoc,
                                             union sctp_addr *addr);
-int sctp_verify_asconf(const struct sctp_association *asoc,
-                      struct sctp_paramhdr *param_hdr, void *chunk_end,
-                      struct sctp_paramhdr **errp);
+bool sctp_verify_asconf(const struct sctp_association *asoc,
+                       struct sctp_chunk *chunk, bool addr_param_needed,
+                       struct sctp_paramhdr **errp);
 struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc,
                                       struct sctp_chunk *asconf);
 int sctp_process_asconf_ack(struct sctp_association *asoc,
index 2883a7a..98f2ade 100644 (file)
@@ -102,6 +102,8 @@ struct snd_soc_dpcm_runtime {
        /* state and update */
        enum snd_soc_dpcm_update runtime_update;
        enum snd_soc_dpcm_state state;
+
+       int trigger_pending; /* trigger cmd + 1 if pending, 0 if not */
 };
 
 /* can this BE stop and free */
index 06f544e..c6814b9 100644 (file)
@@ -5,6 +5,7 @@
 #define _TRACE_COMPACTION_H
 
 #include <linux/types.h>
+#include <linux/list.h>
 #include <linux/tracepoint.h>
 #include <trace/events/gfpflags.h>
 
@@ -47,10 +48,11 @@ DEFINE_EVENT(mm_compaction_isolate_template, mm_compaction_isolate_freepages,
 
 TRACE_EVENT(mm_compaction_migratepages,
 
-       TP_PROTO(unsigned long nr_migrated,
-               unsigned long nr_failed),
+       TP_PROTO(unsigned long nr_all,
+               int migrate_rc,
+               struct list_head *migratepages),
 
-       TP_ARGS(nr_migrated, nr_failed),
+       TP_ARGS(nr_all, migrate_rc, migratepages),
 
        TP_STRUCT__entry(
                __field(unsigned long, nr_migrated)
@@ -58,7 +60,22 @@ TRACE_EVENT(mm_compaction_migratepages,
        ),
 
        TP_fast_assign(
-               __entry->nr_migrated = nr_migrated;
+               unsigned long nr_failed = 0;
+               struct list_head *page_lru;
+
+               /*
+                * migrate_pages() returns either a non-negative number
+                * with the number of pages that failed migration, or an
+                * error code, in which case we need to count the remaining
+                * pages manually
+                */
+               if (migrate_rc >= 0)
+                       nr_failed = migrate_rc;
+               else
+                       list_for_each(page_lru, migratepages)
+                               nr_failed++;
+
+               __entry->nr_migrated = nr_all - nr_failed;
                __entry->nr_failed = nr_failed;
        ),
 
index 5dda450..2ec9fbc 100644 (file)
@@ -6,6 +6,8 @@
 
 #define XT_BPF_MAX_NUM_INSTR   64
 
+struct sk_filter;
+
 struct xt_bpf_info {
        __u16 bpf_program_num_elem;
        struct sock_filter bpf_program[XT_BPF_MAX_NUM_INSTR];
index 1702864..cadddc8 100644 (file)
@@ -123,7 +123,6 @@ static int proc_ipcauto_dointvec_minmax(ctl_table *table, int write,
        void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        struct ctl_table ipc_table;
-       size_t lenp_bef = *lenp;
        int oldval;
        int rc;
 
@@ -133,7 +132,7 @@ static int proc_ipcauto_dointvec_minmax(ctl_table *table, int write,
 
        rc = proc_dointvec_minmax(&ipc_table, write, buffer, lenp, ppos);
 
-       if (write && !rc && lenp_bef == *lenp) {
+       if (write && !rc) {
                int newval = *((int *)(ipc_table.data));
                /*
                 * The file "auto_msgmni" has correctly been set.
index 2c0ecd1..b45b2da 100644 (file)
@@ -687,7 +687,7 @@ static int audit_get_feature(struct sk_buff *skb)
 
        seq = nlmsg_hdr(skb)->nlmsg_seq;
 
-       audit_send_reply(skb, seq, AUDIT_GET, 0, 0, &af, sizeof(af));
+       audit_send_reply(skb, seq, AUDIT_GET_FEATURE, 0, 0, &af, sizeof(af));
 
        return 0;
 }
@@ -702,7 +702,7 @@ static void audit_log_feature_change(int which, u32 old_feature, u32 new_feature
 
        ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_FEATURE_CHANGE);
        audit_log_task_info(ab, current);
-       audit_log_format(ab, "feature=%s old=%u new=%u old_lock=%u new_lock=%u res=%d",
+       audit_log_format(ab, " feature=%s old=%u new=%u old_lock=%u new_lock=%u res=%d",
                         audit_feature_names[which], !!old_feature, !!new_feature,
                         !!old_lock, !!new_lock, res);
        audit_log_end(ab);
index 135944a..a79db03 100644 (file)
@@ -154,6 +154,7 @@ static struct audit_chunk *alloc_chunk(int count)
                chunk->owners[i].index = i;
        }
        fsnotify_init_mark(&chunk->mark, audit_tree_destroy_watch);
+       chunk->mark.mask = FS_IN_IGNORED;
        return chunk;
 }
 
index 4ced342..4bbb27a 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/hw_breakpoint.h>
 #include <linux/mm_types.h>
 #include <linux/cgroup.h>
+#include <linux/compat.h>
 
 #include "internal.h"
 
@@ -3693,6 +3694,26 @@ static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
        return 0;
 }
 
+#ifdef CONFIG_COMPAT
+static long perf_compat_ioctl(struct file *file, unsigned int cmd,
+                               unsigned long arg)
+{
+       switch (_IOC_NR(cmd)) {
+       case _IOC_NR(PERF_EVENT_IOC_SET_FILTER):
+       case _IOC_NR(PERF_EVENT_IOC_ID):
+               /* Fix up pointer size (usually 4 -> 8 in 32-on-64-bit case */
+               if (_IOC_SIZE(cmd) == sizeof(compat_uptr_t)) {
+                       cmd &= ~IOCSIZE_MASK;
+                       cmd |= sizeof(void *) << IOCSIZE_SHIFT;
+               }
+               break;
+       }
+       return perf_ioctl(file, cmd, arg);
+}
+#else
+# define perf_compat_ioctl NULL
+#endif
+
 int perf_event_task_enable(void)
 {
        struct perf_event *event;
@@ -4185,7 +4206,7 @@ static const struct file_operations perf_fops = {
        .read                   = perf_read,
        .poll                   = perf_poll,
        .unlocked_ioctl         = perf_ioctl,
-       .compat_ioctl           = perf_ioctl,
+       .compat_ioctl           = perf_compat_ioctl,
        .mmap                   = perf_mmap,
        .fasync                 = perf_fasync,
 };
index 307d87c..1139b22 100644 (file)
@@ -1621,7 +1621,6 @@ bool uprobe_deny_signal(void)
                if (__fatal_signal_pending(t) || arch_uprobe_xol_was_trapped(t)) {
                        utask->state = UTASK_SSTEP_TRAPPED;
                        set_tsk_thread_flag(t, TIF_UPROBE);
-                       set_tsk_thread_flag(t, TIF_NOTIFY_RESUME);
                }
        }
 
index b3d116c..6705d94 100644 (file)
@@ -1228,6 +1228,22 @@ static int rcu_future_gp_cleanup(struct rcu_state *rsp, struct rcu_node *rnp)
 }
 
 /*
+ * Awaken the grace-period kthread for the specified flavor of RCU.
+ * Don't do a self-awaken, and don't bother awakening when there is
+ * nothing for the grace-period kthread to do (as in several CPUs
+ * raced to awaken, and we lost), and finally don't try to awaken
+ * a kthread that has not yet been created.
+ */
+static void rcu_gp_kthread_wake(struct rcu_state *rsp)
+{
+       if (current == rsp->gp_kthread ||
+           !ACCESS_ONCE(rsp->gp_flags) ||
+           !rsp->gp_kthread)
+               return;
+       wake_up(&rsp->gp_wq);
+}
+
+/*
  * If there is room, assign a ->completed number to any callbacks on
  * this CPU that have not already been assigned.  Also accelerate any
  * callbacks that were previously assigned a ->completed number that has
@@ -1670,7 +1686,7 @@ static void rsp_wakeup(struct irq_work *work)
        struct rcu_state *rsp = container_of(work, struct rcu_state, wakeup_work);
 
        /* Wake up rcu_gp_kthread() to start the grace period. */
-       wake_up(&rsp->gp_wq);
+       rcu_gp_kthread_wake(rsp);
 }
 
 /*
@@ -1746,7 +1762,7 @@ static void rcu_report_qs_rsp(struct rcu_state *rsp, unsigned long flags)
 {
        WARN_ON_ONCE(!rcu_gp_in_progress(rsp));
        raw_spin_unlock_irqrestore(&rcu_get_root(rsp)->lock, flags);
-       wake_up(&rsp->gp_wq);  /* Memory barrier implied by wake_up() path. */
+       rcu_gp_kthread_wake(rsp);
 }
 
 /*
@@ -2322,7 +2338,7 @@ static void force_quiescent_state(struct rcu_state *rsp)
        }
        rsp->gp_flags |= RCU_GP_FLAG_FQS;
        raw_spin_unlock_irqrestore(&rnp_old->lock, flags);
-       wake_up(&rsp->gp_wq);  /* Memory barrier implied by wake_up() path. */
+       rcu_gp_kthread_wake(rsp);
 }
 
 /*
index bd4a8df..7e30d2a 100644 (file)
@@ -946,81 +946,6 @@ next:
 }
 EXPORT_SYMBOL(radix_tree_range_tag_if_tagged);
 
-
-/**
- *     radix_tree_next_hole    -    find the next hole (not-present entry)
- *     @root:          tree root
- *     @index:         index key
- *     @max_scan:      maximum range to search
- *
- *     Search the set [index, min(index+max_scan-1, MAX_INDEX)] for the lowest
- *     indexed hole.
- *
- *     Returns: the index of the hole if found, otherwise returns an index
- *     outside of the set specified (in which case 'return - index >= max_scan'
- *     will be true). In rare cases of index wrap-around, 0 will be returned.
- *
- *     radix_tree_next_hole may be called under rcu_read_lock. However, like
- *     radix_tree_gang_lookup, this will not atomically search a snapshot of
- *     the tree at a single point in time. For example, if a hole is created
- *     at index 5, then subsequently a hole is created at index 10,
- *     radix_tree_next_hole covering both indexes may return 10 if called
- *     under rcu_read_lock.
- */
-unsigned long radix_tree_next_hole(struct radix_tree_root *root,
-                               unsigned long index, unsigned long max_scan)
-{
-       unsigned long i;
-
-       for (i = 0; i < max_scan; i++) {
-               if (!radix_tree_lookup(root, index))
-                       break;
-               index++;
-               if (index == 0)
-                       break;
-       }
-
-       return index;
-}
-EXPORT_SYMBOL(radix_tree_next_hole);
-
-/**
- *     radix_tree_prev_hole    -    find the prev hole (not-present entry)
- *     @root:          tree root
- *     @index:         index key
- *     @max_scan:      maximum range to search
- *
- *     Search backwards in the range [max(index-max_scan+1, 0), index]
- *     for the first hole.
- *
- *     Returns: the index of the hole if found, otherwise returns an index
- *     outside of the set specified (in which case 'index - return >= max_scan'
- *     will be true). In rare cases of wrap-around, ULONG_MAX will be returned.
- *
- *     radix_tree_next_hole may be called under rcu_read_lock. However, like
- *     radix_tree_gang_lookup, this will not atomically search a snapshot of
- *     the tree at a single point in time. For example, if a hole is created
- *     at index 10, then subsequently a hole is created at index 5,
- *     radix_tree_prev_hole covering both indexes may return 5 if called under
- *     rcu_read_lock.
- */
-unsigned long radix_tree_prev_hole(struct radix_tree_root *root,
-                                  unsigned long index, unsigned long max_scan)
-{
-       unsigned long i;
-
-       for (i = 0; i < max_scan; i++) {
-               if (!radix_tree_lookup(root, index))
-                       break;
-               index--;
-               if (index == ULONG_MAX)
-                       break;
-       }
-
-       return index;
-}
-EXPORT_SYMBOL(radix_tree_prev_hole);
-
 /**
  *     radix_tree_gang_lookup - perform multiple lookup on a radix tree
  *     @root:          radix tree root
@@ -1337,15 +1262,18 @@ static inline void radix_tree_shrink(struct radix_tree_root *root)
 }
 
 /**
- *     radix_tree_delete    -    delete an item from a radix tree
+ *     radix_tree_delete_item    -    delete an item from a radix tree
  *     @root:          radix tree root
  *     @index:         index key
+ *     @item:          expected item
  *
- *     Remove the item at @index from the radix tree rooted at @root.
+ *     Remove @item at @index from the radix tree rooted at @root.
  *
- *     Returns the address of the deleted item, or NULL if it was not present.
+ *     Returns the address of the deleted item, or NULL if it was not present
+ *     or the entry at the given @index was not @item.
  */
-void *radix_tree_delete(struct radix_tree_root *root, unsigned long index)
+void *radix_tree_delete_item(struct radix_tree_root *root,
+                            unsigned long index, void *item)
 {
        struct radix_tree_node *node = NULL;
        struct radix_tree_node *slot = NULL;
@@ -1380,6 +1308,11 @@ void *radix_tree_delete(struct radix_tree_root *root, unsigned long index)
        if (slot == NULL)
                goto out;
 
+       if (item && slot != item) {
+               slot = NULL;
+               goto out;
+       }
+
        /*
         * Clear all tags associated with the item to be deleted.
         * This way of doing it would be inefficient, but seldom is any set.
@@ -1424,6 +1357,21 @@ void *radix_tree_delete(struct radix_tree_root *root, unsigned long index)
 out:
        return slot;
 }
+EXPORT_SYMBOL(radix_tree_delete_item);
+
+/**
+ *     radix_tree_delete    -    delete an item from a radix tree
+ *     @root:          radix tree root
+ *     @index:         index key
+ *
+ *     Remove the item at @index from the radix tree rooted at @root.
+ *
+ *     Returns the address of the deleted item, or NULL if it was not present.
+ */
+void *radix_tree_delete(struct radix_tree_root *root, unsigned long index)
+{
+       return radix_tree_delete_item(root, index, NULL);
+}
 EXPORT_SYMBOL(radix_tree_delete);
 
 /**
index 5e38e57..4229fc2 100644 (file)
@@ -89,7 +89,8 @@ static void __reset_isolation_suitable(struct zone *zone)
        unsigned long end_pfn = zone_end_pfn(zone);
        unsigned long pfn;
 
-       zone->compact_cached_migrate_pfn = start_pfn;
+       zone->compact_cached_migrate_pfn[0] = start_pfn;
+       zone->compact_cached_migrate_pfn[1] = start_pfn;
        zone->compact_cached_free_pfn = end_pfn;
        zone->compact_blockskip_flush = false;
 
@@ -131,9 +132,10 @@ void reset_isolation_suitable(pg_data_t *pgdat)
  */
 static void update_pageblock_skip(struct compact_control *cc,
                        struct page *page, unsigned long nr_isolated,
-                       bool migrate_scanner)
+                       bool set_unsuitable, bool migrate_scanner)
 {
        struct zone *zone = cc->zone;
+       unsigned long pfn;
 
        if (cc->ignore_skip_hint)
                return;
@@ -141,20 +143,32 @@ static void update_pageblock_skip(struct compact_control *cc,
        if (!page)
                return;
 
-       if (!nr_isolated) {
-               unsigned long pfn = page_to_pfn(page);
+       if (nr_isolated)
+               return;
+
+       /*
+        * Only skip pageblocks when all forms of compaction will be known to
+        * fail in the near future.
+        */
+       if (set_unsuitable)
                set_pageblock_skip(page);
 
-               /* Update where compaction should restart */
-               if (migrate_scanner) {
-                       if (!cc->finished_update_migrate &&
-                           pfn > zone->compact_cached_migrate_pfn)
-                               zone->compact_cached_migrate_pfn = pfn;
-               } else {
-                       if (!cc->finished_update_free &&
-                           pfn < zone->compact_cached_free_pfn)
-                               zone->compact_cached_free_pfn = pfn;
-               }
+       pfn = page_to_pfn(page);
+
+       /* Update where async and sync compaction should restart */
+       if (migrate_scanner) {
+               if (cc->finished_update_migrate)
+                       return;
+               if (pfn > zone->compact_cached_migrate_pfn[0])
+                       zone->compact_cached_migrate_pfn[0] = pfn;
+               if (cc->mode != MIGRATE_ASYNC &&
+                   pfn > zone->compact_cached_migrate_pfn[1])
+                       zone->compact_cached_migrate_pfn[1] = pfn;
+       } else {
+               if (cc->finished_update_free)
+                       return;
+               if (pfn < zone->compact_cached_free_pfn)
+                       zone->compact_cached_free_pfn = pfn;
        }
 }
 #else
@@ -166,7 +180,7 @@ static inline bool isolation_suitable(struct compact_control *cc,
 
 static void update_pageblock_skip(struct compact_control *cc,
                        struct page *page, unsigned long nr_isolated,
-                       bool migrate_scanner)
+                       bool set_unsuitable, bool migrate_scanner)
 {
 }
 #endif /* CONFIG_COMPACTION */
@@ -195,7 +209,7 @@ static bool compact_checklock_irqsave(spinlock_t *lock, unsigned long *flags,
                }
 
                /* async aborts if taking too long or contended */
-               if (!cc->sync) {
+               if (cc->mode == MIGRATE_ASYNC) {
                        cc->contended = true;
                        return false;
                }
@@ -208,10 +222,28 @@ static bool compact_checklock_irqsave(spinlock_t *lock, unsigned long *flags,
        return true;
 }
 
-static inline bool compact_trylock_irqsave(spinlock_t *lock,
-                       unsigned long *flags, struct compact_control *cc)
+/*
+ * Aside from avoiding lock contention, compaction also periodically checks
+ * need_resched() and either schedules in sync compaction or aborts async
+ * compaction. This is similar to what compact_checklock_irqsave() does, but
+ * is used where no lock is concerned.
+ *
+ * Returns false when no scheduling was needed, or sync compaction scheduled.
+ * Returns true when async compaction should abort.
+ */
+static inline bool compact_should_abort(struct compact_control *cc)
 {
-       return compact_checklock_irqsave(lock, flags, false, cc);
+       /* async compaction aborts if contended */
+       if (need_resched()) {
+               if (cc->mode == MIGRATE_ASYNC) {
+                       cc->contended = true;
+                       return true;
+               }
+
+               cond_resched();
+       }
+
+       return false;
 }
 
 /* Returns true if the page is within a block suitable for migration to */
@@ -329,7 +361,8 @@ isolate_fail:
 
        /* Update the pageblock-skip if the whole pageblock was scanned */
        if (blockpfn == end_pfn)
-               update_pageblock_skip(cc, valid_page, total_isolated, false);
+               update_pageblock_skip(cc, valid_page, total_isolated, true,
+                                     false);
 
        count_compact_events(COMPACTFREE_SCANNED, nr_scanned);
        if (total_isolated)
@@ -464,8 +497,9 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc,
        unsigned long flags;
        bool locked = false;
        struct page *page = NULL, *valid_page = NULL;
-       bool skipped_async_unsuitable = false;
-       const isolate_mode_t mode = (!cc->sync ? ISOLATE_ASYNC_MIGRATE : 0) |
+       bool set_unsuitable = true;
+       const isolate_mode_t mode = (cc->mode == MIGRATE_ASYNC ?
+                                       ISOLATE_ASYNC_MIGRATE : 0) |
                                    (unevictable ? ISOLATE_UNEVICTABLE : 0);
 
        /*
@@ -475,7 +509,7 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc,
         */
        while (unlikely(too_many_isolated(zone))) {
                /* async migration should just abort */
-               if (!cc->sync)
+               if (cc->mode == MIGRATE_ASYNC)
                        return 0;
 
                congestion_wait(BLK_RW_ASYNC, HZ/10);
@@ -484,8 +518,10 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc,
                        return 0;
        }
 
+       if (compact_should_abort(cc))
+               return 0;
+
        /* Time to isolate some pages for migration */
-       cond_resched();
        for (; low_pfn < end_pfn; low_pfn++) {
                /* give a chance to irqs before checking need_resched() */
                if (locked && !(low_pfn % SWAP_CLUSTER_MAX)) {
@@ -540,9 +576,9 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc,
                         * the minimum amount of work satisfies the allocation
                         */
                        mt = get_pageblock_migratetype(page);
-                       if (!cc->sync && !migrate_async_suitable(mt)) {
-                               cc->finished_update_migrate = true;
-                               skipped_async_unsuitable = true;
+                       if (cc->mode == MIGRATE_ASYNC &&
+                           !migrate_async_suitable(mt)) {
+                               set_unsuitable = false;
                                goto next_pageblock;
                        }
                }
@@ -646,11 +682,10 @@ next_pageblock:
        /*
         * Update the pageblock-skip information and cached scanner pfn,
         * if the whole pageblock was scanned without isolating any page.
-        * This is not done when pageblock was skipped due to being unsuitable
-        * for async compaction, so that eventual sync compaction can try.
         */
-       if (low_pfn == end_pfn && !skipped_async_unsuitable)
-               update_pageblock_skip(cc, valid_page, nr_isolated, true);
+       if (low_pfn == end_pfn)
+               update_pageblock_skip(cc, valid_page, nr_isolated,
+                                     set_unsuitable, true);
 
        trace_mm_compaction_isolate_migratepages(nr_scanned, nr_isolated);
 
@@ -671,7 +706,9 @@ static void isolate_freepages(struct zone *zone,
                                struct compact_control *cc)
 {
        struct page *page;
-       unsigned long high_pfn, low_pfn, pfn, z_end_pfn;
+       unsigned long block_start_pfn;  /* start of current pageblock */
+       unsigned long block_end_pfn;    /* end of current pageblock */
+       unsigned long low_pfn;       /* lowest pfn scanner is able to scan */
        int nr_freepages = cc->nr_freepages;
        struct list_head *freelist = &cc->freepages;
 
@@ -679,41 +716,38 @@ static void isolate_freepages(struct zone *zone,
         * Initialise the free scanner. The starting point is where we last
         * successfully isolated from, zone-cached value, or the end of the
         * zone when isolating for the first time. We need this aligned to
-        * the pageblock boundary, because we do pfn -= pageblock_nr_pages
-        * in the for loop.
+        * the pageblock boundary, because we do
+        * block_start_pfn -= pageblock_nr_pages in the for loop.
+        * For ending point, take care when isolating in last pageblock of a
+        * a zone which ends in the middle of a pageblock.
         * The low boundary is the end of the pageblock the migration scanner
         * is using.
         */
-       pfn = cc->free_pfn & ~(pageblock_nr_pages-1);
+       block_start_pfn = cc->free_pfn & ~(pageblock_nr_pages-1);
+       block_end_pfn = min(block_start_pfn + pageblock_nr_pages,
+                                               zone_end_pfn(zone));
        low_pfn = ALIGN(cc->migrate_pfn + 1, pageblock_nr_pages);
 
        /*
-        * Take care that if the migration scanner is at the end of the zone
-        * that the free scanner does not accidentally move to the next zone
-        * in the next isolation cycle.
-        */
-       high_pfn = min(low_pfn, pfn);
-
-       z_end_pfn = zone_end_pfn(zone);
-
-       /*
         * Isolate free pages until enough are available to migrate the
         * pages on cc->migratepages. We stop searching if the migrate
         * and free page scanners meet or enough free pages are isolated.
         */
-       for (; pfn >= low_pfn && cc->nr_migratepages > nr_freepages;
-                                       pfn -= pageblock_nr_pages) {
+       for (; block_start_pfn >= low_pfn && cc->nr_migratepages > nr_freepages;
+                               block_end_pfn = block_start_pfn,
+                               block_start_pfn -= pageblock_nr_pages) {
                unsigned long isolated;
-               unsigned long end_pfn;
 
                /*
                 * This can iterate a massively long zone without finding any
                 * suitable migration targets, so periodically check if we need
-                * to schedule.
+                * to schedule, or even abort async compaction.
                 */
-               cond_resched();
+               if (!(block_start_pfn % (SWAP_CLUSTER_MAX * pageblock_nr_pages))
+                                               && compact_should_abort(cc))
+                       break;
 
-               if (!pfn_valid(pfn))
+               if (!pfn_valid(block_start_pfn))
                        continue;
 
                /*
@@ -723,7 +757,7 @@ static void isolate_freepages(struct zone *zone,
                 * i.e. it's possible that all pages within a zones range of
                 * pages do not belong to a single zone.
                 */
-               page = pfn_to_page(pfn);
+               page = pfn_to_page(block_start_pfn);
                if (page_zone(page) != zone)
                        continue;
 
@@ -736,26 +770,26 @@ static void isolate_freepages(struct zone *zone,
                        continue;
 
                /* Found a block suitable for isolating free pages from */
-               isolated = 0;
+               cc->free_pfn = block_start_pfn;
+               isolated = isolate_freepages_block(cc, block_start_pfn,
+                                       block_end_pfn, freelist, false);
+               nr_freepages += isolated;
 
                /*
-                * Take care when isolating in last pageblock of a zone which
-                * ends in the middle of a pageblock.
+                * Set a flag that we successfully isolated in this pageblock.
+                * In the next loop iteration, zone->compact_cached_free_pfn
+                * will not be updated and thus it will effectively contain the
+                * highest pageblock we isolated pages from.
                 */
-               end_pfn = min(pfn + pageblock_nr_pages, z_end_pfn);
-               isolated = isolate_freepages_block(cc, pfn, end_pfn,
-                                                  freelist, false);
-               nr_freepages += isolated;
+               if (isolated)
+                       cc->finished_update_free = true;
 
                /*
-                * Record the highest PFN we isolated pages from. When next
-                * looking for free pages, the search will restart here as
-                * page migration may have returned some pages to the allocator
+                * isolate_freepages_block() might have aborted due to async
+                * compaction being contended
                 */
-               if (isolated) {
-                       cc->finished_update_free = true;
-                       high_pfn = max(high_pfn, pfn);
-               }
+               if (cc->contended)
+                       break;
        }
 
        /* split_free_page does not map the pages */
@@ -765,10 +799,9 @@ static void isolate_freepages(struct zone *zone,
         * If we crossed the migrate scanner, we want to keep it that way
         * so that compact_finished() may detect this
         */
-       if (pfn < low_pfn)
-               cc->free_pfn = max(pfn, zone->zone_start_pfn);
-       else
-               cc->free_pfn = high_pfn;
+       if (block_start_pfn < low_pfn)
+               cc->free_pfn = cc->migrate_pfn;
+
        cc->nr_freepages = nr_freepages;
 }
 
@@ -783,9 +816,13 @@ static struct page *compaction_alloc(struct page *migratepage,
        struct compact_control *cc = (struct compact_control *)data;
        struct page *freepage;
 
-       /* Isolate free pages if necessary */
+       /*
+        * Isolate free pages if necessary, and if we are not aborting due to
+        * contention.
+        */
        if (list_empty(&cc->freepages)) {
-               isolate_freepages(cc->zone, cc);
+               if (!cc->contended)
+                       isolate_freepages(cc->zone, cc);
 
                if (list_empty(&cc->freepages))
                        return NULL;
@@ -799,23 +836,16 @@ static struct page *compaction_alloc(struct page *migratepage,
 }
 
 /*
- * We cannot control nr_migratepages and nr_freepages fully when migration is
- * running as migrate_pages() has no knowledge of compact_control. When
- * migration is complete, we count the number of pages on the lists by hand.
+ * This is a migrate-callback that "frees" freepages back to the isolated
+ * freelist.  All pages on the freelist are from the same zone, so there is no
+ * special handling needed for NUMA.
  */
-static void update_nr_listpages(struct compact_control *cc)
+static void compaction_free(struct page *page, unsigned long data)
 {
-       int nr_migratepages = 0;
-       int nr_freepages = 0;
-       struct page *page;
-
-       list_for_each_entry(page, &cc->migratepages, lru)
-               nr_migratepages++;
-       list_for_each_entry(page, &cc->freepages, lru)
-               nr_freepages++;
+       struct compact_control *cc = (struct compact_control *)data;
 
-       cc->nr_migratepages = nr_migratepages;
-       cc->nr_freepages = nr_freepages;
+       list_add(&page->lru, &cc->freepages);
+       cc->nr_freepages++;
 }
 
 /* possible outcome of isolate_migratepages */
@@ -862,13 +892,14 @@ static int compact_finished(struct zone *zone,
        unsigned int order;
        unsigned long watermark;
 
-       if (fatal_signal_pending(current))
+       if (cc->contended || fatal_signal_pending(current))
                return COMPACT_PARTIAL;
 
        /* Compaction run completes if the migrate and free scanner meet */
        if (cc->free_pfn <= cc->migrate_pfn) {
                /* Let the next compaction start anew. */
-               zone->compact_cached_migrate_pfn = zone->zone_start_pfn;
+               zone->compact_cached_migrate_pfn[0] = zone->zone_start_pfn;
+               zone->compact_cached_migrate_pfn[1] = zone->zone_start_pfn;
                zone->compact_cached_free_pfn = zone_end_pfn(zone);
 
                /*
@@ -968,6 +999,7 @@ static int compact_zone(struct zone *zone, struct compact_control *cc)
        int ret;
        unsigned long start_pfn = zone->zone_start_pfn;
        unsigned long end_pfn = zone_end_pfn(zone);
+       const bool sync = cc->mode != MIGRATE_ASYNC;
 
        ret = compaction_suitable(zone, cc->order);
        switch (ret) {
@@ -993,7 +1025,7 @@ static int compact_zone(struct zone *zone, struct compact_control *cc)
         * information on where the scanners should start but check that it
         * is initialised by ensuring the values are within zone boundaries.
         */
-       cc->migrate_pfn = zone->compact_cached_migrate_pfn;
+       cc->migrate_pfn = zone->compact_cached_migrate_pfn[sync];
        cc->free_pfn = zone->compact_cached_free_pfn;
        if (cc->free_pfn < start_pfn || cc->free_pfn > end_pfn) {
                cc->free_pfn = end_pfn & ~(pageblock_nr_pages-1);
@@ -1001,7 +1033,8 @@ static int compact_zone(struct zone *zone, struct compact_control *cc)
        }
        if (cc->migrate_pfn < start_pfn || cc->migrate_pfn > end_pfn) {
                cc->migrate_pfn = start_pfn;
-               zone->compact_cached_migrate_pfn = cc->migrate_pfn;
+               zone->compact_cached_migrate_pfn[0] = cc->migrate_pfn;
+               zone->compact_cached_migrate_pfn[1] = cc->migrate_pfn;
        }
 
        trace_mm_compaction_begin(start_pfn, cc->migrate_pfn, cc->free_pfn, end_pfn);
@@ -1009,7 +1042,6 @@ static int compact_zone(struct zone *zone, struct compact_control *cc)
        migrate_prep_local();
 
        while ((ret = compact_finished(zone, cc)) == COMPACT_CONTINUE) {
-               unsigned long nr_migrate, nr_remaining;
                int err;
 
                switch (isolate_migratepages(zone, cc)) {
@@ -1024,21 +1056,20 @@ static int compact_zone(struct zone *zone, struct compact_control *cc)
                        ;
                }
 
-               nr_migrate = cc->nr_migratepages;
+               if (!cc->nr_migratepages)
+                       continue;
+
                err = migrate_pages(&cc->migratepages, compaction_alloc,
-                               (unsigned long)cc,
-                               cc->sync ? MIGRATE_SYNC_LIGHT : MIGRATE_ASYNC,
+                               compaction_free, (unsigned long)cc, cc->mode,
                                MR_COMPACTION);
-               update_nr_listpages(cc);
-               nr_remaining = cc->nr_migratepages;
 
-               trace_mm_compaction_migratepages(nr_migrate - nr_remaining,
-                                               nr_remaining);
+               trace_mm_compaction_migratepages(cc->nr_migratepages, err,
+                                                       &cc->migratepages);
 
-               /* Release isolated pages not migrated */
+               /* All pages were either migrated or will be released */
+               cc->nr_migratepages = 0;
                if (err) {
                        putback_movable_pages(&cc->migratepages);
-                       cc->nr_migratepages = 0;
                        /*
                         * migrate_pages() may return -ENOMEM when scanners meet
                         * and we want compact_finished() to detect it
@@ -1060,9 +1091,8 @@ out:
        return ret;
 }
 
-static unsigned long compact_zone_order(struct zone *zone,
-                                int order, gfp_t gfp_mask,
-                                bool sync, bool *contended)
+static unsigned long compact_zone_order(struct zone *zone, int order,
+               gfp_t gfp_mask, enum migrate_mode mode, bool *contended)
 {
        unsigned long ret;
        struct compact_control cc = {
@@ -1071,7 +1101,7 @@ static unsigned long compact_zone_order(struct zone *zone,
                .order = order,
                .migratetype = allocflags_to_migratetype(gfp_mask),
                .zone = zone,
-               .sync = sync,
+               .mode = mode,
        };
        INIT_LIST_HEAD(&cc.freepages);
        INIT_LIST_HEAD(&cc.migratepages);
@@ -1093,7 +1123,7 @@ int sysctl_extfrag_threshold = 500;
  * @order: The order of the current allocation
  * @gfp_mask: The GFP mask of the current allocation
  * @nodemask: The allowed nodes to allocate from
- * @sync: Whether migration is synchronous or not
+ * @mode: The migration mode for async, sync light, or sync migration
  * @contended: Return value that is true if compaction was aborted due to lock contention
  * @page: Optionally capture a free page of the requested order during compaction
  *
@@ -1101,7 +1131,7 @@ int sysctl_extfrag_threshold = 500;
  */
 unsigned long try_to_compact_pages(struct zonelist *zonelist,
                        int order, gfp_t gfp_mask, nodemask_t *nodemask,
-                       bool sync, bool *contended)
+                       enum migrate_mode mode, bool *contended)
 {
        enum zone_type high_zoneidx = gfp_zone(gfp_mask);
        int may_enter_fs = gfp_mask & __GFP_FS;
@@ -1126,7 +1156,7 @@ unsigned long try_to_compact_pages(struct zonelist *zonelist,
                                                                nodemask) {
                int status;
 
-               status = compact_zone_order(zone, order, gfp_mask, sync,
+               status = compact_zone_order(zone, order, gfp_mask, mode,
                                                contended);
                rc = max(status, rc);
 
@@ -1165,9 +1195,6 @@ static void __compact_pgdat(pg_data_t *pgdat, struct compact_control *cc)
                        if (zone_watermark_ok(zone, cc->order,
                                                low_wmark_pages(zone), 0, 0))
                                compaction_defer_reset(zone, cc->order, false);
-                       /* Currently async compaction is never deferred. */
-                       else if (cc->sync)
-                               defer_compaction(zone, cc->order);
                }
 
                VM_BUG_ON(!list_empty(&cc->freepages));
@@ -1179,7 +1206,7 @@ void compact_pgdat(pg_data_t *pgdat, int order)
 {
        struct compact_control cc = {
                .order = order,
-               .sync = false,
+               .mode = MIGRATE_ASYNC,
        };
 
        if (!order)
@@ -1192,7 +1219,7 @@ static void compact_node(int nid)
 {
        struct compact_control cc = {
                .order = -1,
-               .sync = true,
+               .mode = MIGRATE_SYNC,
                .ignore_skip_hint = true,
        };
 
index c2cc7c9..bdaa215 100644 (file)
@@ -448,6 +448,29 @@ int replace_page_cache_page(struct page *old, struct page *new, gfp_t gfp_mask)
 }
 EXPORT_SYMBOL_GPL(replace_page_cache_page);
 
+static int page_cache_tree_insert(struct address_space *mapping,
+                                 struct page *page)
+{
+       void **slot;
+       int error;
+
+       slot = radix_tree_lookup_slot(&mapping->page_tree, page->index);
+       if (slot) {
+               void *p;
+
+               p = radix_tree_deref_slot_protected(slot, &mapping->tree_lock);
+               if (!radix_tree_exceptional_entry(p))
+                       return -EEXIST;
+               radix_tree_replace_slot(slot, page);
+               mapping->nrpages++;
+               return 0;
+       }
+       error = radix_tree_insert(&mapping->page_tree, page->index, page);
+       if (!error)
+               mapping->nrpages++;
+       return error;
+}
+
 /**
  * add_to_page_cache_locked - add a locked page to the pagecache
  * @page:      page to add
@@ -482,11 +505,10 @@ int add_to_page_cache_locked(struct page *page, struct address_space *mapping,
        page->index = offset;
 
        spin_lock_irq(&mapping->tree_lock);
-       error = radix_tree_insert(&mapping->page_tree, offset, page);
+       error = page_cache_tree_insert(mapping, page);
        radix_tree_preload_end();
        if (unlikely(error))
                goto err_insert;
-       mapping->nrpages++;
        __inc_zone_page_state(page, NR_FILE_PAGES);
        spin_unlock_irq(&mapping->tree_lock);
        trace_mm_filemap_add_to_page_cache(page);
@@ -688,14 +710,101 @@ int __lock_page_or_retry(struct page *page, struct mm_struct *mm,
 }
 
 /**
- * find_get_page - find and get a page reference
+ * page_cache_next_hole - find the next hole (not-present entry)
+ * @mapping: mapping
+ * @index: index
+ * @max_scan: maximum range to search
+ *
+ * Search the set [index, min(index+max_scan-1, MAX_INDEX)] for the
+ * lowest indexed hole.
+ *
+ * Returns: the index of the hole if found, otherwise returns an index
+ * outside of the set specified (in which case 'return - index >=
+ * max_scan' will be true). In rare cases of index wrap-around, 0 will
+ * be returned.
+ *
+ * page_cache_next_hole may be called under rcu_read_lock. However,
+ * like radix_tree_gang_lookup, this will not atomically search a
+ * snapshot of the tree at a single point in time. For example, if a
+ * hole is created at index 5, then subsequently a hole is created at
+ * index 10, page_cache_next_hole covering both indexes may return 10
+ * if called under rcu_read_lock.
+ */
+pgoff_t page_cache_next_hole(struct address_space *mapping,
+                            pgoff_t index, unsigned long max_scan)
+{
+       unsigned long i;
+
+       for (i = 0; i < max_scan; i++) {
+               struct page *page;
+
+               page = radix_tree_lookup(&mapping->page_tree, index);
+               if (!page || radix_tree_exceptional_entry(page))
+                       break;
+               index++;
+               if (index == 0)
+                       break;
+       }
+
+       return index;
+}
+EXPORT_SYMBOL(page_cache_next_hole);
+
+/**
+ * page_cache_prev_hole - find the prev hole (not-present entry)
+ * @mapping: mapping
+ * @index: index
+ * @max_scan: maximum range to search
+ *
+ * Search backwards in the range [max(index-max_scan+1, 0), index] for
+ * the first hole.
+ *
+ * Returns: the index of the hole if found, otherwise returns an index
+ * outside of the set specified (in which case 'index - return >=
+ * max_scan' will be true). In rare cases of wrap-around, ULONG_MAX
+ * will be returned.
+ *
+ * page_cache_prev_hole may be called under rcu_read_lock. However,
+ * like radix_tree_gang_lookup, this will not atomically search a
+ * snapshot of the tree at a single point in time. For example, if a
+ * hole is created at index 10, then subsequently a hole is created at
+ * index 5, page_cache_prev_hole covering both indexes may return 5 if
+ * called under rcu_read_lock.
+ */
+pgoff_t page_cache_prev_hole(struct address_space *mapping,
+                            pgoff_t index, unsigned long max_scan)
+{
+       unsigned long i;
+
+       for (i = 0; i < max_scan; i++) {
+               struct page *page;
+
+               page = radix_tree_lookup(&mapping->page_tree, index);
+               if (!page || radix_tree_exceptional_entry(page))
+                       break;
+               index--;
+               if (index == ULONG_MAX)
+                       break;
+       }
+
+       return index;
+}
+EXPORT_SYMBOL(page_cache_prev_hole);
+
+/**
+ * find_get_entry - find and get a page cache entry
  * @mapping: the address_space to search
- * @offset: the page index
+ * @offset: the page cache index
  *
- * Is there a pagecache struct page at the given (mapping, offset) tuple?
- * If yes, increment its refcount and return it; if no, return NULL.
+ * Looks up the page cache slot at @mapping & @offset.  If there is a
+ * page cache page, it is returned with an increased refcount.
+ *
+ * If the slot holds a shadow entry of a previously evicted page, it
+ * is returned.
+ *
+ * Otherwise, %NULL is returned.
  */
-struct page *find_get_page(struct address_space *mapping, pgoff_t offset)
+struct page *find_get_entry(struct address_space *mapping, pgoff_t offset)
 {
        void **pagep;
        struct page *page;
@@ -736,24 +845,50 @@ out:
 
        return page;
 }
-EXPORT_SYMBOL(find_get_page);
+EXPORT_SYMBOL(find_get_entry);
 
 /**
- * find_lock_page - locate, pin and lock a pagecache page
+ * find_get_page - find and get a page reference
  * @mapping: the address_space to search
  * @offset: the page index
  *
- * Locates the desired pagecache page, locks it, increments its reference
- * count and returns its address.
+ * Looks up the page cache slot at @mapping & @offset.  If there is a
+ * page cache page, it is returned with an increased refcount.
  *
- * Returns zero if the page was not present. find_lock_page() may sleep.
+ * Otherwise, %NULL is returned.
  */
-struct page *find_lock_page(struct address_space *mapping, pgoff_t offset)
+struct page *find_get_page(struct address_space *mapping, pgoff_t offset)
+{
+       struct page *page = find_get_entry(mapping, offset);
+
+       if (radix_tree_exceptional_entry(page))
+               page = NULL;
+       return page;
+}
+EXPORT_SYMBOL(find_get_page);
+
+/**
+ * find_lock_entry - locate, pin and lock a page cache entry
+ * @mapping: the address_space to search
+ * @offset: the page cache index
+ *
+ * Looks up the page cache slot at @mapping & @offset.  If there is a
+ * page cache page, it is returned locked and with an increased
+ * refcount.
+ *
+ * If the slot holds a shadow entry of a previously evicted page, it
+ * is returned.
+ *
+ * Otherwise, %NULL is returned.
+ *
+ * find_lock_entry() may sleep.
+ */
+struct page *find_lock_entry(struct address_space *mapping, pgoff_t offset)
 {
        struct page *page;
 
 repeat:
-       page = find_get_page(mapping, offset);
+       page = find_get_entry(mapping, offset);
        if (page && !radix_tree_exception(page)) {
                lock_page(page);
                /* Has the page been truncated? */
@@ -766,6 +901,29 @@ repeat:
        }
        return page;
 }
+EXPORT_SYMBOL(find_lock_entry);
+
+/**
+ * find_lock_page - locate, pin and lock a pagecache page
+ * @mapping: the address_space to search
+ * @offset: the page index
+ *
+ * Looks up the page cache slot at @mapping & @offset.  If there is a
+ * page cache page, it is returned locked and with an increased
+ * refcount.
+ *
+ * Otherwise, %NULL is returned.
+ *
+ * find_lock_page() may sleep.
+ */
+struct page *find_lock_page(struct address_space *mapping, pgoff_t offset)
+{
+       struct page *page = find_lock_entry(mapping, offset);
+
+       if (radix_tree_exceptional_entry(page))
+               page = NULL;
+       return page;
+}
 EXPORT_SYMBOL(find_lock_page);
 
 /**
@@ -774,16 +932,18 @@ EXPORT_SYMBOL(find_lock_page);
  * @index: the page's index into the mapping
  * @gfp_mask: page allocation mode
  *
- * Locates a page in the pagecache.  If the page is not present, a new page
- * is allocated using @gfp_mask and is added to the pagecache and to the VM's
- * LRU list.  The returned page is locked and has its reference count
- * incremented.
+ * Looks up the page cache slot at @mapping & @offset.  If there is a
+ * page cache page, it is returned locked and with an increased
+ * refcount.
+ *
+ * If the page is not present, a new page is allocated using @gfp_mask
+ * and added to the page cache and the VM's LRU list.  The page is
+ * returned locked and with an increased refcount.
  *
- * find_or_create_page() may sleep, even if @gfp_flags specifies an atomic
- * allocation!
+ * On memory exhaustion, %NULL is returned.
  *
- * find_or_create_page() returns the desired page's address, or zero on
- * memory exhaustion.
+ * find_or_create_page() may sleep, even if @gfp_flags specifies an
+ * atomic allocation!
  */
 struct page *find_or_create_page(struct address_space *mapping,
                pgoff_t index, gfp_t gfp_mask)
@@ -816,6 +976,76 @@ repeat:
 EXPORT_SYMBOL(find_or_create_page);
 
 /**
+ * find_get_entries - gang pagecache lookup
+ * @mapping:   The address_space to search
+ * @start:     The starting page cache index
+ * @nr_entries:        The maximum number of entries
+ * @entries:   Where the resulting entries are placed
+ * @indices:   The cache indices corresponding to the entries in @entries
+ *
+ * find_get_entries() will search for and return a group of up to
+ * @nr_entries entries in the mapping.  The entries are placed at
+ * @entries.  find_get_entries() takes a reference against any actual
+ * pages it returns.
+ *
+ * The search returns a group of mapping-contiguous page cache entries
+ * with ascending indexes.  There may be holes in the indices due to
+ * not-present pages.
+ *
+ * Any shadow entries of evicted pages are included in the returned
+ * array.
+ *
+ * find_get_entries() returns the number of pages and shadow entries
+ * which were found.
+ */
+unsigned find_get_entries(struct address_space *mapping,
+                         pgoff_t start, unsigned int nr_entries,
+                         struct page **entries, pgoff_t *indices)
+{
+       void **slot;
+       unsigned int ret = 0;
+       struct radix_tree_iter iter;
+
+       if (!nr_entries)
+               return 0;
+
+       rcu_read_lock();
+restart:
+       radix_tree_for_each_slot(slot, &mapping->page_tree, &iter, start) {
+               struct page *page;
+repeat:
+               page = radix_tree_deref_slot(slot);
+               if (unlikely(!page))
+                       continue;
+               if (radix_tree_exception(page)) {
+                       if (radix_tree_deref_retry(page))
+                               goto restart;
+                       /*
+                        * Otherwise, we must be storing a swap entry
+                        * here as an exceptional entry: so return it
+                        * without attempting to raise page count.
+                        */
+                       goto export;
+               }
+               if (!page_cache_get_speculative(page))
+                       goto repeat;
+
+               /* Has the page moved? */
+               if (unlikely(page != *slot)) {
+                       page_cache_release(page);
+                       goto repeat;
+               }
+export:
+               indices[ret] = iter.index;
+               entries[ret] = page;
+               if (++ret == nr_entries)
+                       break;
+       }
+       rcu_read_unlock();
+       return ret;
+}
+
+/**
  * find_get_pages - gang pagecache lookup
  * @mapping:   The address_space to search
  * @start:     The starting page index
@@ -1797,6 +2027,18 @@ int generic_file_readonly_mmap(struct file * file, struct vm_area_struct * vma)
 EXPORT_SYMBOL(generic_file_mmap);
 EXPORT_SYMBOL(generic_file_readonly_mmap);
 
+static struct page *wait_on_page_read(struct page *page)
+{
+       if (!IS_ERR(page)) {
+               wait_on_page_locked(page);
+               if (!PageUptodate(page)) {
+                       page_cache_release(page);
+                       page = ERR_PTR(-EIO);
+               }
+       }
+       return page;
+}
+
 static struct page *__read_cache_page(struct address_space *mapping,
                                pgoff_t index,
                                int (*filler)(void *, struct page *),
@@ -1823,6 +2065,8 @@ repeat:
                if (err < 0) {
                        page_cache_release(page);
                        page = ERR_PTR(err);
+               } else {
+                       page = wait_on_page_read(page);
                }
        }
        return page;
@@ -1859,6 +2103,10 @@ retry:
        if (err < 0) {
                page_cache_release(page);
                return ERR_PTR(err);
+       } else {
+               page = wait_on_page_read(page);
+               if (IS_ERR(page))
+                       return page;
        }
 out:
        mark_page_accessed(page);
@@ -1866,40 +2114,25 @@ out:
 }
 
 /**
- * read_cache_page_async - read into page cache, fill it if needed
+ * read_cache_page - read into page cache, fill it if needed
  * @mapping:   the page's address_space
  * @index:     the page index
  * @filler:    function to perform the read
  * @data:      first arg to filler(data, page) function, often left as NULL
  *
- * Same as read_cache_page, but don't wait for page to become unlocked
- * after submitting it to the filler.
- *
  * Read into the page cache. If a page already exists, and PageUptodate() is
- * not set, try to fill the page but don't wait for it to become unlocked.
+ * not set, try to fill the page and wait for it to become unlocked.
  *
  * If the page does not get brought uptodate, return -EIO.
  */
-struct page *read_cache_page_async(struct address_space *mapping,
+struct page *read_cache_page(struct address_space *mapping,
                                pgoff_t index,
                                int (*filler)(void *, struct page *),
                                void *data)
 {
        return do_read_cache_page(mapping, index, filler, data, mapping_gfp_mask(mapping));
 }
-EXPORT_SYMBOL(read_cache_page_async);
-
-static struct page *wait_on_page_read(struct page *page)
-{
-       if (!IS_ERR(page)) {
-               wait_on_page_locked(page);
-               if (!PageUptodate(page)) {
-                       page_cache_release(page);
-                       page = ERR_PTR(-EIO);
-               }
-       }
-       return page;
-}
+EXPORT_SYMBOL(read_cache_page);
 
 /**
  * read_cache_page_gfp - read into page cache, using specified page allocation flags.
@@ -1918,31 +2151,10 @@ struct page *read_cache_page_gfp(struct address_space *mapping,
 {
        filler_t *filler = (filler_t *)mapping->a_ops->readpage;
 
-       return wait_on_page_read(do_read_cache_page(mapping, index, filler, NULL, gfp));
+       return do_read_cache_page(mapping, index, filler, NULL, gfp);
 }
 EXPORT_SYMBOL(read_cache_page_gfp);
 
-/**
- * read_cache_page - read into page cache, fill it if needed
- * @mapping:   the page's address_space
- * @index:     the page index
- * @filler:    function to perform the read
- * @data:      first arg to filler(data, page) function, often left as NULL
- *
- * Read into the page cache. If a page already exists, and PageUptodate() is
- * not set, try to fill the page then wait for it to become unlocked.
- *
- * If the page does not get brought uptodate, return -EIO.
- */
-struct page *read_cache_page(struct address_space *mapping,
-                               pgoff_t index,
-                               int (*filler)(void *, struct page *),
-                               void *data)
-{
-       return wait_on_page_read(read_cache_page_async(mapping, index, filler, data));
-}
-EXPORT_SYMBOL(read_cache_page);
-
 static size_t __iovec_copy_from_user_inatomic(char *vaddr,
                        const struct iovec *iov, size_t base, size_t bytes)
 {
@@ -1976,7 +2188,6 @@ size_t iov_iter_copy_from_user_atomic(struct page *page,
        char *kaddr;
        size_t copied;
 
-       BUG_ON(!in_atomic());
        kaddr = kmap_atomic(page);
        if (likely(i->nr_segs == 1)) {
                int left;
@@ -2350,9 +2561,7 @@ again:
                if (mapping_writably_mapped(mapping))
                        flush_dcache_page(page);
 
-               pagefault_disable();
                copied = iov_iter_copy_from_user_atomic(page, i, offset, bytes);
-               pagefault_enable();
                flush_dcache_page(page);
 
                mark_page_accessed(page);
index 3e91000..1a8a0d4 100644 (file)
@@ -11,6 +11,7 @@
 #ifndef __MM_INTERNAL_H
 #define __MM_INTERNAL_H
 
+#include <linux/fs.h>
 #include <linux/mm.h>
 
 void free_pgtables(struct mmu_gather *tlb, struct vm_area_struct *start_vma,
@@ -21,6 +22,20 @@ static inline void set_page_count(struct page *page, int v)
        atomic_set(&page->_count, v);
 }
 
+extern int __do_page_cache_readahead(struct address_space *mapping,
+               struct file *filp, pgoff_t offset, unsigned long nr_to_read,
+               unsigned long lookahead_size);
+
+/*
+ * Submit IO for the read-ahead request in file_ra_state.
+ */
+static inline unsigned long ra_submit(struct file_ra_state *ra,
+               struct address_space *mapping, struct file *filp)
+{
+       return __do_page_cache_readahead(mapping, filp,
+                                       ra->start, ra->size, ra->async_size);
+}
+
 /*
  * Turn a non-refcounted page (->_count == 0) into refcounted with
  * a count of one.
@@ -119,7 +134,7 @@ struct compact_control {
        unsigned long nr_migratepages;  /* Number of pages to migrate */
        unsigned long free_pfn;         /* isolate_freepages search base */
        unsigned long migrate_pfn;      /* isolate_migratepages search base */
-       bool sync;                      /* Synchronous migration */
+       enum migrate_mode mode;         /* Async or sync migration mode */
        bool ignore_skip_hint;          /* Scan blocks even if marked skip */
        bool finished_update_free;      /* True when the zone cached pfns are
                                         * no longer being updated
@@ -129,7 +144,10 @@ struct compact_control {
        int order;                      /* order a direct compactor needs */
        int migratetype;                /* MOVABLE, RECLAIMABLE etc */
        struct zone *zone;
-       bool contended;                 /* True if a lock was contended */
+       bool contended;                 /* True if a lock was contended, or
+                                        * need_resched() true during async
+                                        * compaction
+                                        */
 };
 
 unsigned long
index 539eeb9..a402f8f 100644 (file)
@@ -195,7 +195,7 @@ static void force_shm_swapin_readahead(struct vm_area_struct *vma,
        for (; start < end; start += PAGE_SIZE) {
                index = ((start - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
 
-               page = find_get_page(mapping, index);
+               page = find_get_entry(mapping, index);
                if (!radix_tree_exceptional_entry(page)) {
                        if (page)
                                page_cache_release(page);
index 33365e9..a98c7fc 100644 (file)
@@ -1540,7 +1540,7 @@ static int soft_offline_huge_page(struct page *page, int flags)
 
        /* Keep page count to indicate a given hugepage is isolated. */
        list_move(&hpage->lru, &pagelist);
-       ret = migrate_pages(&pagelist, new_page, MPOL_MF_MOVE_ALL,
+       ret = migrate_pages(&pagelist, new_page, NULL, MPOL_MF_MOVE_ALL,
                                MIGRATE_SYNC, MR_MEMORY_FAILURE);
        if (ret) {
                pr_info("soft offline: %#lx: migration failed %d, type %lx\n",
@@ -1621,7 +1621,7 @@ static int __soft_offline_page(struct page *page, int flags)
                inc_zone_page_state(page, NR_ISOLATED_ANON +
                                        page_is_file_cache(page));
                list_add(&page->lru, &pagelist);
-               ret = migrate_pages(&pagelist, new_page, MPOL_MF_MOVE_ALL,
+               ret = migrate_pages(&pagelist, new_page, NULL, MPOL_MF_MOVE_ALL,
                                        MIGRATE_SYNC, MR_MEMORY_FAILURE);
                if (ret) {
                        if (!list_empty(&pagelist)) {
index a650db2..f6f2383 100644 (file)
@@ -1332,7 +1332,7 @@ do_migrate_range(unsigned long start_pfn, unsigned long end_pfn)
                 * alloc_migrate_target should be improooooved!!
                 * migrate_pages returns # of failed pages.
                 */
-               ret = migrate_pages(&source, alloc_migrate_target, 0,
+               ret = migrate_pages(&source, alloc_migrate_target, NULL, 0,
                                        MIGRATE_SYNC, MR_MEMORY_HOTPLUG);
                if (ret)
                        putback_movable_pages(&source);
index 796c7e6..e8fff0f 100644 (file)
@@ -1060,7 +1060,7 @@ static int migrate_to_node(struct mm_struct *mm, int source, int dest,
                        flags | MPOL_MF_DISCONTIG_OK, &pagelist);
 
        if (!list_empty(&pagelist)) {
-               err = migrate_pages(&pagelist, new_node_page, dest,
+               err = migrate_pages(&pagelist, new_node_page, NULL, dest,
                                        MIGRATE_SYNC, MR_SYSCALL);
                if (err)
                        putback_movable_pages(&pagelist);
@@ -1306,7 +1306,7 @@ static long do_mbind(unsigned long start, unsigned long len,
 
                if (!list_empty(&pagelist)) {
                        WARN_ON_ONCE(flags & MPOL_MF_LAZY);
-                       nr_failed = migrate_pages(&pagelist, new_page,
+                       nr_failed = migrate_pages(&pagelist, new_page, NULL,
                                start, MIGRATE_SYNC, MR_MEMPOLICY_MBIND);
                        if (nr_failed)
                                putback_movable_pages(&pagelist);
index 13f47fb..3acac4a 100644 (file)
@@ -941,8 +941,9 @@ out:
  * Obtain the lock on page, remove all ptes and migrate the page
  * to the newly allocated page in newpage.
  */
-static int unmap_and_move(new_page_t get_new_page, unsigned long private,
-                       struct page *page, int force, enum migrate_mode mode)
+static int unmap_and_move(new_page_t get_new_page, free_page_t put_new_page,
+                       unsigned long private, struct page *page, int force,
+                       enum migrate_mode mode)
 {
        int rc = 0;
        int *result = NULL;
@@ -986,11 +987,18 @@ out:
                                page_is_file_cache(page));
                putback_lru_page(page);
        }
+
        /*
-        * Move the new page to the LRU. If migration was not successful
-        * then this will free the page.
+        * If migration was not successful and there's a freeing callback, use
+        * it.  Otherwise, putback_lru_page() will drop the reference grabbed
+        * during isolation.
         */
-       putback_lru_page(newpage);
+       if (rc != MIGRATEPAGE_SUCCESS && put_new_page) {
+               ClearPageSwapBacked(newpage);
+               put_new_page(newpage, private);
+       } else
+               putback_lru_page(newpage);
+
        if (result) {
                if (rc)
                        *result = rc;
@@ -1019,8 +1027,9 @@ out:
  * will wait in the page fault for migration to complete.
  */
 static int unmap_and_move_huge_page(new_page_t get_new_page,
-                               unsigned long private, struct page *hpage,
-                               int force, enum migrate_mode mode)
+                               free_page_t put_new_page, unsigned long private,
+                               struct page *hpage, int force,
+                               enum migrate_mode mode)
 {
        int rc = 0;
        int *result = NULL;
@@ -1059,20 +1068,30 @@ static int unmap_and_move_huge_page(new_page_t get_new_page,
        if (!page_mapped(hpage))
                rc = move_to_new_page(new_hpage, hpage, 1, mode);
 
-       if (rc)
+       if (rc != MIGRATEPAGE_SUCCESS)
                remove_migration_ptes(hpage, hpage);
 
        if (anon_vma)
                put_anon_vma(anon_vma);
 
-       if (!rc)
+       if (rc == MIGRATEPAGE_SUCCESS)
                hugetlb_cgroup_migrate(hpage, new_hpage);
 
        unlock_page(hpage);
 out:
        if (rc != -EAGAIN)
                putback_active_hugepage(hpage);
-       put_page(new_hpage);
+
+       /*
+        * If migration was not successful and there's a freeing callback, use
+        * it.  Otherwise, put_page() will drop the reference grabbed during
+        * isolation.
+        */
+       if (rc != MIGRATEPAGE_SUCCESS && put_new_page)
+               put_new_page(new_hpage, private);
+       else
+               put_page(new_hpage);
+
        if (result) {
                if (rc)
                        *result = rc;
@@ -1089,6 +1108,8 @@ out:
  * @from:              The list of pages to be migrated.
  * @get_new_page:      The function used to allocate free pages to be used
  *                     as the target of the page migration.
+ * @put_new_page:      The function used to free target pages if migration
+ *                     fails, or NULL if no special handling is necessary.
  * @private:           Private data to be passed on to get_new_page()
  * @mode:              The migration mode that specifies the constraints for
  *                     page migration, if any.
@@ -1102,7 +1123,8 @@ out:
  * Returns the number of pages that were not migrated, or an error code.
  */
 int migrate_pages(struct list_head *from, new_page_t get_new_page,
-               unsigned long private, enum migrate_mode mode, int reason)
+               free_page_t put_new_page, unsigned long private,
+               enum migrate_mode mode, int reason)
 {
        int retry = 1;
        int nr_failed = 0;
@@ -1124,10 +1146,11 @@ int migrate_pages(struct list_head *from, new_page_t get_new_page,
 
                        if (PageHuge(page))
                                rc = unmap_and_move_huge_page(get_new_page,
-                                               private, page, pass > 2, mode);
+                                               put_new_page, private, page,
+                                               pass > 2, mode);
                        else
-                               rc = unmap_and_move(get_new_page, private,
-                                               page, pass > 2, mode);
+                               rc = unmap_and_move(get_new_page, put_new_page,
+                                               private, page, pass > 2, mode);
 
                        switch(rc) {
                        case -ENOMEM:
@@ -1276,7 +1299,7 @@ set_status:
 
        err = 0;
        if (!list_empty(&pagelist)) {
-               err = migrate_pages(&pagelist, new_page_node,
+               err = migrate_pages(&pagelist, new_page_node, NULL,
                                (unsigned long)pm, MIGRATE_SYNC, MR_SYSCALL);
                if (err)
                        putback_movable_pages(&pagelist);
@@ -1732,7 +1755,8 @@ int migrate_misplaced_page(struct page *page, struct vm_area_struct *vma,
 
        list_add(&page->lru, &migratepages);
        nr_remaining = migrate_pages(&migratepages, alloc_misplaced_dst_page,
-                                    node, MIGRATE_ASYNC, MR_NUMA_MISPLACED);
+                                    NULL, node, MIGRATE_ASYNC,
+                                    MR_NUMA_MISPLACED);
        if (nr_remaining) {
                if (!list_empty(&migratepages)) {
                        list_del(&page->lru);
index 1016233..725c809 100644 (file)
@@ -70,13 +70,21 @@ static unsigned char mincore_page(struct address_space *mapping, pgoff_t pgoff)
         * any other file mapping (ie. marked !present and faulted in with
         * tmpfs's .fault). So swapped out tmpfs mappings are tested here.
         */
-       page = find_get_page(mapping, pgoff);
 #ifdef CONFIG_SWAP
-       /* shmem/tmpfs may return swap: account for swapcache page too. */
-       if (radix_tree_exceptional_entry(page)) {
-               swp_entry_t swap = radix_to_swp_entry(page);
-               page = find_get_page(swap_address_space(swap), swap.val);
-       }
+       if (shmem_mapping(mapping)) {
+               page = find_get_entry(mapping, pgoff);
+               /*
+                * shmem/tmpfs may return swap: account for swapcache
+                * page too.
+                */
+               if (radix_tree_exceptional_entry(page)) {
+                       swp_entry_t swp = radix_to_swp_entry(page);
+                       page = find_get_page(swap_address_space(swp), swp.val);
+               }
+       } else
+               page = find_get_page(mapping, pgoff);
+#else
+       page = find_get_page(mapping, pgoff);
 #endif
        if (page) {
                present = PageUptodate(page);
index 7b2611a..4b25829 100644 (file)
@@ -943,6 +943,7 @@ struct page *__rmqueue_smallest(struct zone *zone, unsigned int order,
                rmv_page_order(page);
                area->nr_free--;
                expand(zone, page, order, current_order, area, migratetype);
+               set_freepage_migratetype(page, migratetype);
                return page;
        }
 
@@ -1069,7 +1070,9 @@ static int try_to_steal_freepages(struct zone *zone, struct page *page,
 
        /*
         * When borrowing from MIGRATE_CMA, we need to release the excess
-        * buddy pages to CMA itself.
+        * buddy pages to CMA itself. We also ensure the freepage_migratetype
+        * is set to CMA so it is returned to the correct freelist in case
+        * the page ends up being not actually allocated from the pcp lists.
         */
        if (is_migrate_cma(fallback_type))
                return fallback_type;
@@ -1137,6 +1140,12 @@ __rmqueue_fallback(struct zone *zone, int order, int start_migratetype)
 
                        expand(zone, page, order, current_order, area,
                               new_type);
+                       /* The freepage_migratetype may differ from pageblock's
+                        * migratetype depending on the decisions in
+                        * try_to_steal_freepages. This is OK as long as it does
+                        * not differ for MIGRATE_CMA type.
+                        */
+                       set_freepage_migratetype(page, new_type);
 
                        trace_mm_page_alloc_extfrag(page, order, current_order,
                                start_migratetype, migratetype, new_type);
@@ -1187,7 +1196,7 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order,
                        unsigned long count, struct list_head *list,
                        int migratetype, int cold)
 {
-       int mt = migratetype, i;
+       int i;
 
        spin_lock(&zone->lock);
        for (i = 0; i < count; ++i) {
@@ -1208,14 +1217,8 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order,
                        list_add(&page->lru, list);
                else
                        list_add_tail(&page->lru, list);
-               if (IS_ENABLED(CONFIG_CMA)) {
-                       mt = get_pageblock_migratetype(page);
-                       if (!is_migrate_cma(mt) && !is_migrate_isolate(mt))
-                               mt = migratetype;
-               }
-               set_freepage_migratetype(page, mt);
                list = &page->lru;
-               if (is_migrate_cma(mt))
+               if (is_migrate_cma(get_freepage_migratetype(page)))
                        __mod_zone_page_state(zone, NR_FREE_CMA_PAGES,
                                              -(1 << order));
        }
@@ -1584,7 +1587,7 @@ again:
                if (!page)
                        goto failed;
                __mod_zone_freepage_state(zone, -(1 << order),
-                                         get_pageblock_migratetype(page));
+                                         get_freepage_migratetype(page));
        }
 
        __mod_zone_page_state(zone, NR_ALLOC_BATCH, -(1 << order));
@@ -2246,7 +2249,7 @@ static struct page *
 __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order,
        struct zonelist *zonelist, enum zone_type high_zoneidx,
        nodemask_t *nodemask, int alloc_flags, struct zone *preferred_zone,
-       int migratetype, bool sync_migration,
+       int migratetype, enum migrate_mode mode,
        bool *contended_compaction, bool *deferred_compaction,
        unsigned long *did_some_progress)
 {
@@ -2260,7 +2263,7 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order,
 
        current->flags |= PF_MEMALLOC;
        *did_some_progress = try_to_compact_pages(zonelist, order, gfp_mask,
-                                               nodemask, sync_migration,
+                                               nodemask, mode,
                                                contended_compaction);
        current->flags &= ~PF_MEMALLOC;
 
@@ -2293,7 +2296,7 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order,
                 * As async compaction considers a subset of pageblocks, only
                 * defer if the failure was a sync compaction failure.
                 */
-               if (sync_migration)
+               if (mode != MIGRATE_ASYNC)
                        defer_compaction(preferred_zone, order);
 
                cond_resched();
@@ -2306,9 +2309,8 @@ static inline struct page *
 __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order,
        struct zonelist *zonelist, enum zone_type high_zoneidx,
        nodemask_t *nodemask, int alloc_flags, struct zone *preferred_zone,
-       int migratetype, bool sync_migration,
-       bool *contended_compaction, bool *deferred_compaction,
-       unsigned long *did_some_progress)
+       int migratetype, enum migrate_mode mode, bool *contended_compaction,
+       bool *deferred_compaction, unsigned long *did_some_progress)
 {
        return NULL;
 }
@@ -2503,7 +2505,7 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
        int alloc_flags;
        unsigned long pages_reclaimed = 0;
        unsigned long did_some_progress;
-       bool sync_migration = false;
+       enum migrate_mode migration_mode = MIGRATE_ASYNC;
        bool deferred_compaction = false;
        bool contended_compaction = false;
 
@@ -2597,17 +2599,15 @@ rebalance:
         * Try direct compaction. The first pass is asynchronous. Subsequent
         * attempts after direct reclaim are synchronous
         */
-       page = __alloc_pages_direct_compact(gfp_mask, order,
-                                       zonelist, high_zoneidx,
-                                       nodemask,
-                                       alloc_flags, preferred_zone,
-                                       migratetype, sync_migration,
-                                       &contended_compaction,
+       page = __alloc_pages_direct_compact(gfp_mask, order, zonelist,
+                                       high_zoneidx, nodemask, alloc_flags,
+                                       preferred_zone, migratetype,
+                                       migration_mode, &contended_compaction,
                                        &deferred_compaction,
                                        &did_some_progress);
        if (page)
                goto got_pg;
-       sync_migration = true;
+       migration_mode = MIGRATE_SYNC_LIGHT;
 
        /*
         * If compaction is deferred for high-order allocations, it is because
@@ -2682,12 +2682,10 @@ rebalance:
                 * direct reclaim and reclaim/compaction depends on compaction
                 * being called after reclaim so call directly if necessary
                 */
-               page = __alloc_pages_direct_compact(gfp_mask, order,
-                                       zonelist, high_zoneidx,
-                                       nodemask,
-                                       alloc_flags, preferred_zone,
-                                       migratetype, sync_migration,
-                                       &contended_compaction,
+               page = __alloc_pages_direct_compact(gfp_mask, order, zonelist,
+                                       high_zoneidx, nodemask, alloc_flags,
+                                       preferred_zone, migratetype,
+                                       migration_mode, &contended_compaction,
                                        &deferred_compaction,
                                        &did_some_progress);
                if (page)
@@ -6261,7 +6259,7 @@ static int __alloc_contig_migrate_range(struct compact_control *cc,
                cc->nr_migratepages -= nr_reclaimed;
 
                ret = migrate_pages(&cc->migratepages, alloc_migrate_target,
-                                   0, MIGRATE_SYNC, MR_CMA);
+                                   NULL, 0, cc->mode, MR_CMA);
        }
        if (ret < 0) {
                putback_movable_pages(&cc->migratepages);
@@ -6300,7 +6298,7 @@ int alloc_contig_range(unsigned long start, unsigned long end,
                .nr_migratepages = 0,
                .order = -1,
                .zone = page_zone(pfn_to_page(start)),
-               .sync = true,
+               .mode = MIGRATE_SYNC,
                .ignore_skip_hint = true,
        };
        INIT_LIST_HEAD(&cc.migratepages);
index 1fa0d6f..0ca36a7 100644 (file)
@@ -8,9 +8,7 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/fs.h>
 #include <linux/gfp.h>
-#include <linux/mm.h>
 #include <linux/export.h>
 #include <linux/blkdev.h>
 #include <linux/backing-dev.h>
@@ -20,6 +18,8 @@
 #include <linux/syscalls.h>
 #include <linux/file.h>
 
+#include "internal.h"
+
 /*
  * Initialise a struct file's readahead state.  Assumes that the caller has
  * memset *ra to zero.
@@ -149,8 +149,7 @@ out:
  *
  * Returns the number of pages requested, or the maximum amount of I/O allowed.
  */
-static int
-__do_page_cache_readahead(struct address_space *mapping, struct file *filp,
+int __do_page_cache_readahead(struct address_space *mapping, struct file *filp,
                        pgoff_t offset, unsigned long nr_to_read,
                        unsigned long lookahead_size)
 {
@@ -179,7 +178,7 @@ __do_page_cache_readahead(struct address_space *mapping, struct file *filp,
                rcu_read_lock();
                page = radix_tree_lookup(&mapping->page_tree, page_offset);
                rcu_read_unlock();
-               if (page)
+               if (page && !radix_tree_exceptional_entry(page))
                        continue;
 
                page = page_cache_alloc_readahead(mapping);
@@ -244,20 +243,6 @@ unsigned long max_sane_readahead(unsigned long nr)
 }
 
 /*
- * Submit IO for the read-ahead request in file_ra_state.
- */
-unsigned long ra_submit(struct file_ra_state *ra,
-                      struct address_space *mapping, struct file *filp)
-{
-       int actual;
-
-       actual = __do_page_cache_readahead(mapping, filp,
-                                       ra->start, ra->size, ra->async_size);
-
-       return actual;
-}
-
-/*
  * Set the initial window size, round to next power of 2 and square
  * for small size, x 4 for medium, and x 2 for large
  * for 128k (32 page) max ra
@@ -347,7 +332,7 @@ static pgoff_t count_history_pages(struct address_space *mapping,
        pgoff_t head;
 
        rcu_read_lock();
-       head = radix_tree_prev_hole(&mapping->page_tree, offset - 1, max);
+       head = page_cache_prev_hole(mapping, offset - 1, max);
        rcu_read_unlock();
 
        return offset - 1 - head;
@@ -427,7 +412,7 @@ ondemand_readahead(struct address_space *mapping,
                pgoff_t start;
 
                rcu_read_lock();
-               start = radix_tree_next_hole(&mapping->page_tree, offset+1,max);
+               start = page_cache_next_hole(mapping, offset + 1, max);
                rcu_read_unlock();
 
                if (!start || start - offset > max)
index f0d698b..0f14475 100644 (file)
@@ -243,19 +243,17 @@ static int shmem_radix_tree_replace(struct address_space *mapping,
                        pgoff_t index, void *expected, void *replacement)
 {
        void **pslot;
-       void *item = NULL;
+       void *item;
 
        VM_BUG_ON(!expected);
+       VM_BUG_ON(!replacement);
        pslot = radix_tree_lookup_slot(&mapping->page_tree, index);
-       if (pslot)
-               item = radix_tree_deref_slot_protected(pslot,
-                                                       &mapping->tree_lock);
+       if (!pslot)
+               return -ENOENT;
+       item = radix_tree_deref_slot_protected(pslot, &mapping->tree_lock);
        if (item != expected)
                return -ENOENT;
-       if (replacement)
-               radix_tree_replace_slot(pslot, replacement);
-       else
-               radix_tree_delete(&mapping->page_tree, index);
+       radix_tree_replace_slot(pslot, replacement);
        return 0;
 }
 
@@ -332,84 +330,20 @@ static void shmem_delete_from_page_cache(struct page *page, void *radswap)
 }
 
 /*
- * Like find_get_pages, but collecting swap entries as well as pages.
- */
-static unsigned shmem_find_get_pages_and_swap(struct address_space *mapping,
-                                       pgoff_t start, unsigned int nr_pages,
-                                       struct page **pages, pgoff_t *indices)
-{
-       void **slot;
-       unsigned int ret = 0;
-       struct radix_tree_iter iter;
-
-       if (!nr_pages)
-               return 0;
-
-       rcu_read_lock();
-restart:
-       radix_tree_for_each_slot(slot, &mapping->page_tree, &iter, start) {
-               struct page *page;
-repeat:
-               page = radix_tree_deref_slot(slot);
-               if (unlikely(!page))
-                       continue;
-               if (radix_tree_exception(page)) {
-                       if (radix_tree_deref_retry(page))
-                               goto restart;
-                       /*
-                        * Otherwise, we must be storing a swap entry
-                        * here as an exceptional entry: so return it
-                        * without attempting to raise page count.
-                        */
-                       goto export;
-               }
-               if (!page_cache_get_speculative(page))
-                       goto repeat;
-
-               /* Has the page moved? */
-               if (unlikely(page != *slot)) {
-                       page_cache_release(page);
-                       goto repeat;
-               }
-export:
-               indices[ret] = iter.index;
-               pages[ret] = page;
-               if (++ret == nr_pages)
-                       break;
-       }
-       rcu_read_unlock();
-       return ret;
-}
-
-/*
  * Remove swap entry from radix tree, free the swap and its page cache.
  */
 static int shmem_free_swap(struct address_space *mapping,
                           pgoff_t index, void *radswap)
 {
-       int error;
+       void *old;
 
        spin_lock_irq(&mapping->tree_lock);
-       error = shmem_radix_tree_replace(mapping, index, radswap, NULL);
+       old = radix_tree_delete_item(&mapping->page_tree, index, radswap);
        spin_unlock_irq(&mapping->tree_lock);
-       if (!error)
-               free_swap_and_cache(radix_to_swp_entry(radswap));
-       return error;
-}
-
-/*
- * Pagevec may contain swap entries, so shuffle up pages before releasing.
- */
-static void shmem_deswap_pagevec(struct pagevec *pvec)
-{
-       int i, j;
-
-       for (i = 0, j = 0; i < pagevec_count(pvec); i++) {
-               struct page *page = pvec->pages[i];
-               if (!radix_tree_exceptional_entry(page))
-                       pvec->pages[j++] = page;
-       }
-       pvec->nr = j;
+       if (old != radswap)
+               return -ENOENT;
+       free_swap_and_cache(radix_to_swp_entry(radswap));
+       return 0;
 }
 
 /*
@@ -430,12 +364,12 @@ void shmem_unlock_mapping(struct address_space *mapping)
                 * Avoid pagevec_lookup(): find_get_pages() returns 0 as if it
                 * has finished, if it hits a row of PAGEVEC_SIZE swap entries.
                 */
-               pvec.nr = shmem_find_get_pages_and_swap(mapping, index,
-                                       PAGEVEC_SIZE, pvec.pages, indices);
+               pvec.nr = find_get_entries(mapping, index,
+                                          PAGEVEC_SIZE, pvec.pages, indices);
                if (!pvec.nr)
                        break;
                index = indices[pvec.nr - 1] + 1;
-               shmem_deswap_pagevec(&pvec);
+               pagevec_remove_exceptionals(&pvec);
                check_move_unevictable_pages(pvec.pages, pvec.nr);
                pagevec_release(&pvec);
                cond_resched();
@@ -467,9 +401,9 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend,
        pagevec_init(&pvec, 0);
        index = start;
        while (index < end) {
-               pvec.nr = shmem_find_get_pages_and_swap(mapping, index,
-                               min(end - index, (pgoff_t)PAGEVEC_SIZE),
-                                                       pvec.pages, indices);
+               pvec.nr = find_get_entries(mapping, index,
+                       min(end - index, (pgoff_t)PAGEVEC_SIZE),
+                       pvec.pages, indices);
                if (!pvec.nr)
                        break;
                mem_cgroup_uncharge_start();
@@ -498,7 +432,7 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend,
                        }
                        unlock_page(page);
                }
-               shmem_deswap_pagevec(&pvec);
+               pagevec_remove_exceptionals(&pvec);
                pagevec_release(&pvec);
                mem_cgroup_uncharge_end();
                cond_resched();
@@ -536,9 +470,10 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend,
        index = start;
        while (index < end) {
                cond_resched();
-               pvec.nr = shmem_find_get_pages_and_swap(mapping, index,
+
+               pvec.nr = find_get_entries(mapping, index,
                                min(end - index, (pgoff_t)PAGEVEC_SIZE),
-                                                       pvec.pages, indices);
+                               pvec.pages, indices);
                if (!pvec.nr) {
                        /* If all gone or hole-punch or unfalloc, we're done */
                        if (index == start || end != -1)
@@ -581,7 +516,7 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend,
                        }
                        unlock_page(page);
                }
-               shmem_deswap_pagevec(&pvec);
+               pagevec_remove_exceptionals(&pvec);
                pagevec_release(&pvec);
                mem_cgroup_uncharge_end();
                index++;
@@ -1088,7 +1023,7 @@ static int shmem_getpage_gfp(struct inode *inode, pgoff_t index,
                return -EFBIG;
 repeat:
        swap.val = 0;
-       page = find_lock_page(mapping, index);
+       page = find_lock_entry(mapping, index);
        if (radix_tree_exceptional_entry(page)) {
                swap = radix_to_swp_entry(page);
                page = NULL;
@@ -1483,6 +1418,11 @@ static struct inode *shmem_get_inode(struct super_block *sb, const struct inode
        return inode;
 }
 
+bool shmem_mapping(struct address_space *mapping)
+{
+       return mapping->backing_dev_info == &shmem_backing_dev_info;
+}
+
 #ifdef CONFIG_TMPFS
 static const struct inode_operations shmem_symlink_inode_operations;
 static const struct inode_operations shmem_short_symlink_operations;
@@ -1795,7 +1735,7 @@ static pgoff_t shmem_seek_hole_data(struct address_space *mapping,
        pagevec_init(&pvec, 0);
        pvec.nr = 1;            /* start small: we may be there already */
        while (!done) {
-               pvec.nr = shmem_find_get_pages_and_swap(mapping, index,
+               pvec.nr = find_get_entries(mapping, index,
                                        pvec.nr, pvec.pages, indices);
                if (!pvec.nr) {
                        if (whence == SEEK_DATA)
@@ -1822,7 +1762,7 @@ static pgoff_t shmem_seek_hole_data(struct address_space *mapping,
                                break;
                        }
                }
-               shmem_deswap_pagevec(&pvec);
+               pagevec_remove_exceptionals(&pvec);
                pagevec_release(&pvec);
                pvec.nr = PAGEVEC_SIZE;
                cond_resched();
index 0092097..c8048d7 100644 (file)
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -948,6 +948,57 @@ void __pagevec_lru_add(struct pagevec *pvec)
 EXPORT_SYMBOL(__pagevec_lru_add);
 
 /**
+ * pagevec_lookup_entries - gang pagecache lookup
+ * @pvec:      Where the resulting entries are placed
+ * @mapping:   The address_space to search
+ * @start:     The starting entry index
+ * @nr_entries:        The maximum number of entries
+ * @indices:   The cache indices corresponding to the entries in @pvec
+ *
+ * pagevec_lookup_entries() will search for and return a group of up
+ * to @nr_entries pages and shadow entries in the mapping.  All
+ * entries are placed in @pvec.  pagevec_lookup_entries() takes a
+ * reference against actual pages in @pvec.
+ *
+ * The search returns a group of mapping-contiguous entries with
+ * ascending indexes.  There may be holes in the indices due to
+ * not-present entries.
+ *
+ * pagevec_lookup_entries() returns the number of entries which were
+ * found.
+ */
+unsigned pagevec_lookup_entries(struct pagevec *pvec,
+                               struct address_space *mapping,
+                               pgoff_t start, unsigned nr_pages,
+                               pgoff_t *indices)
+{
+       pvec->nr = find_get_entries(mapping, start, nr_pages,
+                                   pvec->pages, indices);
+       return pagevec_count(pvec);
+}
+
+/**
+ * pagevec_remove_exceptionals - pagevec exceptionals pruning
+ * @pvec:      The pagevec to prune
+ *
+ * pagevec_lookup_entries() fills both pages and exceptional radix
+ * tree entries into the pagevec.  This function prunes all
+ * exceptionals from @pvec without leaving holes, so that it can be
+ * passed on to page-only pagevec operations.
+ */
+void pagevec_remove_exceptionals(struct pagevec *pvec)
+{
+       int i, j;
+
+       for (i = 0, j = 0; i < pagevec_count(pvec); i++) {
+               struct page *page = pvec->pages[i];
+               if (!radix_tree_exceptional_entry(page))
+                       pvec->pages[j++] = page;
+       }
+       pvec->nr = j;
+}
+
+/**
  * pagevec_lookup - gang pagecache lookup
  * @pvec:      Where the resulting pages are placed
  * @mapping:   The address_space to search
index ac18edc..827ad8d 100644 (file)
 #include <linux/rmap.h>
 #include "internal.h"
 
+static void clear_exceptional_entry(struct address_space *mapping,
+                                   pgoff_t index, void *entry)
+{
+       /* Handled by shmem itself */
+       if (shmem_mapping(mapping))
+               return;
+
+       spin_lock_irq(&mapping->tree_lock);
+       /*
+        * Regular page slots are stabilized by the page lock even
+        * without the tree itself locked.  These unlocked entries
+        * need verification under the tree lock.
+        */
+       radix_tree_delete_item(&mapping->page_tree, index, entry);
+       spin_unlock_irq(&mapping->tree_lock);
+}
 
 /**
  * do_invalidatepage - invalidate part or all of a page
@@ -209,6 +225,7 @@ void truncate_inode_pages_range(struct address_space *mapping,
        unsigned int    partial_start;  /* inclusive */
        unsigned int    partial_end;    /* exclusive */
        struct pagevec  pvec;
+       pgoff_t         indices[PAGEVEC_SIZE];
        pgoff_t         index;
        int             i;
 
@@ -239,17 +256,23 @@ void truncate_inode_pages_range(struct address_space *mapping,
 
        pagevec_init(&pvec, 0);
        index = start;
-       while (index < end && pagevec_lookup(&pvec, mapping, index,
-                       min(end - index, (pgoff_t)PAGEVEC_SIZE))) {
+       while (index < end && pagevec_lookup_entries(&pvec, mapping, index,
+                       min(end - index, (pgoff_t)PAGEVEC_SIZE),
+                       indices)) {
                mem_cgroup_uncharge_start();
                for (i = 0; i < pagevec_count(&pvec); i++) {
                        struct page *page = pvec.pages[i];
 
                        /* We rely upon deletion not changing page->index */
-                       index = page->index;
+                       index = indices[i];
                        if (index >= end)
                                break;
 
+                       if (radix_tree_exceptional_entry(page)) {
+                               clear_exceptional_entry(mapping, index, page);
+                               continue;
+                       }
+
                        if (!trylock_page(page))
                                continue;
                        WARN_ON(page->index != index);
@@ -260,6 +283,7 @@ void truncate_inode_pages_range(struct address_space *mapping,
                        truncate_inode_page(mapping, page);
                        unlock_page(page);
                }
+               pagevec_remove_exceptionals(&pvec);
                pagevec_release(&pvec);
                mem_cgroup_uncharge_end();
                cond_resched();
@@ -308,14 +332,16 @@ void truncate_inode_pages_range(struct address_space *mapping,
        index = start;
        for ( ; ; ) {
                cond_resched();
-               if (!pagevec_lookup(&pvec, mapping, index,
-                       min(end - index, (pgoff_t)PAGEVEC_SIZE))) {
+               if (!pagevec_lookup_entries(&pvec, mapping, index,
+                       min(end - index, (pgoff_t)PAGEVEC_SIZE),
+                       indices)) {
                        if (index == start)
                                break;
                        index = start;
                        continue;
                }
-               if (index == start && pvec.pages[0]->index >= end) {
+               if (index == start && indices[0] >= end) {
+                       pagevec_remove_exceptionals(&pvec);
                        pagevec_release(&pvec);
                        break;
                }
@@ -324,16 +350,22 @@ void truncate_inode_pages_range(struct address_space *mapping,
                        struct page *page = pvec.pages[i];
 
                        /* We rely upon deletion not changing page->index */
-                       index = page->index;
+                       index = indices[i];
                        if (index >= end)
                                break;
 
+                       if (radix_tree_exceptional_entry(page)) {
+                               clear_exceptional_entry(mapping, index, page);
+                               continue;
+                       }
+
                        lock_page(page);
                        WARN_ON(page->index != index);
                        wait_on_page_writeback(page);
                        truncate_inode_page(mapping, page);
                        unlock_page(page);
                }
+               pagevec_remove_exceptionals(&pvec);
                pagevec_release(&pvec);
                mem_cgroup_uncharge_end();
                index++;
@@ -376,6 +408,7 @@ EXPORT_SYMBOL(truncate_inode_pages);
 unsigned long invalidate_mapping_pages(struct address_space *mapping,
                pgoff_t start, pgoff_t end)
 {
+       pgoff_t indices[PAGEVEC_SIZE];
        struct pagevec pvec;
        pgoff_t index = start;
        unsigned long ret;
@@ -391,17 +424,23 @@ unsigned long invalidate_mapping_pages(struct address_space *mapping,
         */
 
        pagevec_init(&pvec, 0);
-       while (index <= end && pagevec_lookup(&pvec, mapping, index,
-                       min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1)) {
+       while (index <= end && pagevec_lookup_entries(&pvec, mapping, index,
+                       min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1,
+                       indices)) {
                mem_cgroup_uncharge_start();
                for (i = 0; i < pagevec_count(&pvec); i++) {
                        struct page *page = pvec.pages[i];
 
                        /* We rely upon deletion not changing page->index */
-                       index = page->index;
+                       index = indices[i];
                        if (index > end)
                                break;
 
+                       if (radix_tree_exceptional_entry(page)) {
+                               clear_exceptional_entry(mapping, index, page);
+                               continue;
+                       }
+
                        if (!trylock_page(page))
                                continue;
                        WARN_ON(page->index != index);
@@ -415,6 +454,7 @@ unsigned long invalidate_mapping_pages(struct address_space *mapping,
                                deactivate_page(page);
                        count += ret;
                }
+               pagevec_remove_exceptionals(&pvec);
                pagevec_release(&pvec);
                mem_cgroup_uncharge_end();
                cond_resched();
@@ -482,6 +522,7 @@ static int do_launder_page(struct address_space *mapping, struct page *page)
 int invalidate_inode_pages2_range(struct address_space *mapping,
                                  pgoff_t start, pgoff_t end)
 {
+       pgoff_t indices[PAGEVEC_SIZE];
        struct pagevec pvec;
        pgoff_t index;
        int i;
@@ -492,17 +533,23 @@ int invalidate_inode_pages2_range(struct address_space *mapping,
        cleancache_invalidate_inode(mapping);
        pagevec_init(&pvec, 0);
        index = start;
-       while (index <= end && pagevec_lookup(&pvec, mapping, index,
-                       min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1)) {
+       while (index <= end && pagevec_lookup_entries(&pvec, mapping, index,
+                       min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1,
+                       indices)) {
                mem_cgroup_uncharge_start();
                for (i = 0; i < pagevec_count(&pvec); i++) {
                        struct page *page = pvec.pages[i];
 
                        /* We rely upon deletion not changing page->index */
-                       index = page->index;
+                       index = indices[i];
                        if (index > end)
                                break;
 
+                       if (radix_tree_exceptional_entry(page)) {
+                               clear_exceptional_entry(mapping, index, page);
+                               continue;
+                       }
+
                        lock_page(page);
                        WARN_ON(page->index != index);
                        if (page->mapping != mapping) {
@@ -540,6 +587,7 @@ int invalidate_inode_pages2_range(struct address_space *mapping,
                                ret = ret2;
                        unlock_page(page);
                }
+               pagevec_remove_exceptionals(&pvec);
                pagevec_release(&pvec);
                mem_cgroup_uncharge_end();
                cond_resched();
index 0c0b36e..deb139e 100644 (file)
@@ -2018,13 +2018,27 @@ static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
        unsigned long nr_reclaimed = 0;
        unsigned long nr_to_reclaim = sc->nr_to_reclaim;
        struct blk_plug plug;
-       bool scan_adjusted = false;
+       bool scan_adjusted;
 
        get_scan_count(lruvec, sc, nr);
 
        /* Record the original scan target for proportional adjustments later */
        memcpy(targets, nr, sizeof(nr));
 
+       /*
+        * Global reclaiming within direct reclaim at DEF_PRIORITY is a normal
+        * event that can occur when there is little memory pressure e.g.
+        * multiple streaming readers/writers. Hence, we do not abort scanning
+        * when the requested number of pages are reclaimed when scanning at
+        * DEF_PRIORITY on the assumption that the fact we are direct
+        * reclaiming implies that kswapd is not keeping up and it is best to
+        * do a batch of work at once. For memcg reclaim one check is made to
+        * abort proportional reclaim if either the file or anon lru has already
+        * dropped to zero at the first pass.
+        */
+       scan_adjusted = (global_reclaim(sc) && !current_is_kswapd() &&
+                        sc->priority == DEF_PRIORITY);
+
        blk_start_plug(&plug);
        while (nr[LRU_INACTIVE_ANON] || nr[LRU_ACTIVE_FILE] ||
                                        nr[LRU_INACTIVE_FILE]) {
@@ -2045,17 +2059,8 @@ static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
                        continue;
 
                /*
-                * For global direct reclaim, reclaim only the number of pages
-                * requested. Less care is taken to scan proportionally as it
-                * is more important to minimise direct reclaim stall latency
-                * than it is to properly age the LRU lists.
-                */
-               if (global_reclaim(sc) && !current_is_kswapd())
-                       break;
-
-               /*
                 * For kswapd and memcg, reclaim at least the number of pages
-                * requested. Ensure that the anon and file LRUs shrink
+                * requested. Ensure that the anon and file LRUs are scanned
                 * proportionally what was requested by get_scan_count(). We
                 * stop reclaiming one LRU and reduce the amount scanning
                 * proportional to the original scan target.
@@ -2063,6 +2068,15 @@ static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
                nr_file = nr[LRU_INACTIVE_FILE] + nr[LRU_ACTIVE_FILE];
                nr_anon = nr[LRU_INACTIVE_ANON] + nr[LRU_ACTIVE_ANON];
 
+               /*
+                * It's just vindictive to attack the larger once the smaller
+                * has gone to zero.  And given the way we stop scanning the
+                * smaller below, this makes sure that we only make one nudge
+                * towards proportionality once we've got nr_to_reclaim.
+                */
+               if (!nr_file || !nr_anon)
+                       break;
+
                if (nr_file > nr_anon) {
                        unsigned long scan_target = targets[LRU_INACTIVE_ANON] +
                                                targets[LRU_ACTIVE_ANON] + 1;
index b851cc5..fbda6b5 100644 (file)
@@ -83,7 +83,7 @@ static bool batadv_is_on_batman_iface(const struct net_device *net_dev)
                return true;
 
        /* no more parents..stop recursion */
-       if (net_dev->iflink == net_dev->ifindex)
+       if (net_dev->iflink == 0 || net_dev->iflink == net_dev->ifindex)
                return false;
 
        /* recurse over the parent device */
index 6e7a236..06f19b9 100644 (file)
@@ -89,11 +89,82 @@ static struct crypto_blkcipher *ceph_crypto_alloc_cipher(void)
 
 static const u8 *aes_iv = (u8 *)CEPH_AES_IV;
 
+/*
+ * Should be used for buffers allocated with ceph_kvmalloc().
+ * Currently these are encrypt out-buffer (ceph_buffer) and decrypt
+ * in-buffer (msg front).
+ *
+ * Dispose of @sgt with teardown_sgtable().
+ *
+ * @prealloc_sg is to avoid memory allocation inside sg_alloc_table()
+ * in cases where a single sg is sufficient.  No attempt to reduce the
+ * number of sgs by squeezing physically contiguous pages together is
+ * made though, for simplicity.
+ */
+static int setup_sgtable(struct sg_table *sgt, struct scatterlist *prealloc_sg,
+                        const void *buf, unsigned int buf_len)
+{
+       struct scatterlist *sg;
+       const bool is_vmalloc = is_vmalloc_addr(buf);
+       unsigned int off = offset_in_page(buf);
+       unsigned int chunk_cnt = 1;
+       unsigned int chunk_len = PAGE_ALIGN(off + buf_len);
+       int i;
+       int ret;
+
+       if (buf_len == 0) {
+               memset(sgt, 0, sizeof(*sgt));
+               return -EINVAL;
+       }
+
+       if (is_vmalloc) {
+               chunk_cnt = chunk_len >> PAGE_SHIFT;
+               chunk_len = PAGE_SIZE;
+       }
+
+       if (chunk_cnt > 1) {
+               ret = sg_alloc_table(sgt, chunk_cnt, GFP_NOFS);
+               if (ret)
+                       return ret;
+       } else {
+               WARN_ON(chunk_cnt != 1);
+               sg_init_table(prealloc_sg, 1);
+               sgt->sgl = prealloc_sg;
+               sgt->nents = sgt->orig_nents = 1;
+       }
+
+       for_each_sg(sgt->sgl, sg, sgt->orig_nents, i) {
+               struct page *page;
+               unsigned int len = min(chunk_len - off, buf_len);
+
+               if (is_vmalloc)
+                       page = vmalloc_to_page(buf);
+               else
+                       page = virt_to_page(buf);
+
+               sg_set_page(sg, page, len, off);
+
+               off = 0;
+               buf += len;
+               buf_len -= len;
+       }
+       WARN_ON(buf_len != 0);
+
+       return 0;
+}
+
+static void teardown_sgtable(struct sg_table *sgt)
+{
+       if (sgt->orig_nents > 1)
+               sg_free_table(sgt);
+}
+
 static int ceph_aes_encrypt(const void *key, int key_len,
                            void *dst, size_t *dst_len,
                            const void *src, size_t src_len)
 {
-       struct scatterlist sg_in[2], sg_out[1];
+       struct scatterlist sg_in[2], prealloc_sg;
+       struct sg_table sg_out;
        struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher();
        struct blkcipher_desc desc = { .tfm = tfm, .flags = 0 };
        int ret;
@@ -109,16 +180,18 @@ static int ceph_aes_encrypt(const void *key, int key_len,
 
        *dst_len = src_len + zero_padding;
 
-       crypto_blkcipher_setkey((void *)tfm, key, key_len);
        sg_init_table(sg_in, 2);
        sg_set_buf(&sg_in[0], src, src_len);
        sg_set_buf(&sg_in[1], pad, zero_padding);
-       sg_init_table(sg_out, 1);
-       sg_set_buf(sg_out, dst, *dst_len);
+       ret = setup_sgtable(&sg_out, &prealloc_sg, dst, *dst_len);
+       if (ret)
+               goto out_tfm;
+
+       crypto_blkcipher_setkey((void *)tfm, key, key_len);
        iv = crypto_blkcipher_crt(tfm)->iv;
        ivsize = crypto_blkcipher_ivsize(tfm);
-
        memcpy(iv, aes_iv, ivsize);
+
        /*
        print_hex_dump(KERN_ERR, "enc key: ", DUMP_PREFIX_NONE, 16, 1,
                       key, key_len, 1);
@@ -127,16 +200,22 @@ static int ceph_aes_encrypt(const void *key, int key_len,
        print_hex_dump(KERN_ERR, "enc pad: ", DUMP_PREFIX_NONE, 16, 1,
                        pad, zero_padding, 1);
        */
-       ret = crypto_blkcipher_encrypt(&desc, sg_out, sg_in,
+       ret = crypto_blkcipher_encrypt(&desc, sg_out.sgl, sg_in,
                                     src_len + zero_padding);
-       crypto_free_blkcipher(tfm);
-       if (ret < 0)
+       if (ret < 0) {
                pr_err("ceph_aes_crypt failed %d\n", ret);
+               goto out_sg;
+       }
        /*
        print_hex_dump(KERN_ERR, "enc out: ", DUMP_PREFIX_NONE, 16, 1,
                       dst, *dst_len, 1);
        */
-       return 0;
+
+out_sg:
+       teardown_sgtable(&sg_out);
+out_tfm:
+       crypto_free_blkcipher(tfm);
+       return ret;
 }
 
 static int ceph_aes_encrypt2(const void *key, int key_len, void *dst,
@@ -144,7 +223,8 @@ static int ceph_aes_encrypt2(const void *key, int key_len, void *dst,
                             const void *src1, size_t src1_len,
                             const void *src2, size_t src2_len)
 {
-       struct scatterlist sg_in[3], sg_out[1];
+       struct scatterlist sg_in[3], prealloc_sg;
+       struct sg_table sg_out;
        struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher();
        struct blkcipher_desc desc = { .tfm = tfm, .flags = 0 };
        int ret;
@@ -160,17 +240,19 @@ static int ceph_aes_encrypt2(const void *key, int key_len, void *dst,
 
        *dst_len = src1_len + src2_len + zero_padding;
 
-       crypto_blkcipher_setkey((void *)tfm, key, key_len);
        sg_init_table(sg_in, 3);
        sg_set_buf(&sg_in[0], src1, src1_len);
        sg_set_buf(&sg_in[1], src2, src2_len);
        sg_set_buf(&sg_in[2], pad, zero_padding);
-       sg_init_table(sg_out, 1);
-       sg_set_buf(sg_out, dst, *dst_len);
+       ret = setup_sgtable(&sg_out, &prealloc_sg, dst, *dst_len);
+       if (ret)
+               goto out_tfm;
+
+       crypto_blkcipher_setkey((void *)tfm, key, key_len);
        iv = crypto_blkcipher_crt(tfm)->iv;
        ivsize = crypto_blkcipher_ivsize(tfm);
-
        memcpy(iv, aes_iv, ivsize);
+
        /*
        print_hex_dump(KERN_ERR, "enc  key: ", DUMP_PREFIX_NONE, 16, 1,
                       key, key_len, 1);
@@ -181,23 +263,30 @@ static int ceph_aes_encrypt2(const void *key, int key_len, void *dst,
        print_hex_dump(KERN_ERR, "enc  pad: ", DUMP_PREFIX_NONE, 16, 1,
                        pad, zero_padding, 1);
        */
-       ret = crypto_blkcipher_encrypt(&desc, sg_out, sg_in,
+       ret = crypto_blkcipher_encrypt(&desc, sg_out.sgl, sg_in,
                                     src1_len + src2_len + zero_padding);
-       crypto_free_blkcipher(tfm);
-       if (ret < 0)
+       if (ret < 0) {
                pr_err("ceph_aes_crypt2 failed %d\n", ret);
+               goto out_sg;
+       }
        /*
        print_hex_dump(KERN_ERR, "enc  out: ", DUMP_PREFIX_NONE, 16, 1,
                       dst, *dst_len, 1);
        */
-       return 0;
+
+out_sg:
+       teardown_sgtable(&sg_out);
+out_tfm:
+       crypto_free_blkcipher(tfm);
+       return ret;
 }
 
 static int ceph_aes_decrypt(const void *key, int key_len,
                            void *dst, size_t *dst_len,
                            const void *src, size_t src_len)
 {
-       struct scatterlist sg_in[1], sg_out[2];
+       struct sg_table sg_in;
+       struct scatterlist sg_out[2], prealloc_sg;
        struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher();
        struct blkcipher_desc desc = { .tfm = tfm };
        char pad[16];
@@ -209,16 +298,16 @@ static int ceph_aes_decrypt(const void *key, int key_len,
        if (IS_ERR(tfm))
                return PTR_ERR(tfm);
 
-       crypto_blkcipher_setkey((void *)tfm, key, key_len);
-       sg_init_table(sg_in, 1);
        sg_init_table(sg_out, 2);
-       sg_set_buf(sg_in, src, src_len);
        sg_set_buf(&sg_out[0], dst, *dst_len);
        sg_set_buf(&sg_out[1], pad, sizeof(pad));
+       ret = setup_sgtable(&sg_in, &prealloc_sg, src, src_len);
+       if (ret)
+               goto out_tfm;
 
+       crypto_blkcipher_setkey((void *)tfm, key, key_len);
        iv = crypto_blkcipher_crt(tfm)->iv;
        ivsize = crypto_blkcipher_ivsize(tfm);
-
        memcpy(iv, aes_iv, ivsize);
 
        /*
@@ -227,12 +316,10 @@ static int ceph_aes_decrypt(const void *key, int key_len,
        print_hex_dump(KERN_ERR, "dec  in: ", DUMP_PREFIX_NONE, 16, 1,
                       src, src_len, 1);
        */
-
-       ret = crypto_blkcipher_decrypt(&desc, sg_out, sg_in, src_len);
-       crypto_free_blkcipher(tfm);
+       ret = crypto_blkcipher_decrypt(&desc, sg_out, sg_in.sgl, src_len);
        if (ret < 0) {
                pr_err("ceph_aes_decrypt failed %d\n", ret);
-               return ret;
+               goto out_sg;
        }
 
        if (src_len <= *dst_len)
@@ -250,7 +337,12 @@ static int ceph_aes_decrypt(const void *key, int key_len,
        print_hex_dump(KERN_ERR, "dec out: ", DUMP_PREFIX_NONE, 16, 1,
                       dst, *dst_len, 1);
        */
-       return 0;
+
+out_sg:
+       teardown_sgtable(&sg_in);
+out_tfm:
+       crypto_free_blkcipher(tfm);
+       return ret;
 }
 
 static int ceph_aes_decrypt2(const void *key, int key_len,
@@ -258,7 +350,8 @@ static int ceph_aes_decrypt2(const void *key, int key_len,
                             void *dst2, size_t *dst2_len,
                             const void *src, size_t src_len)
 {
-       struct scatterlist sg_in[1], sg_out[3];
+       struct sg_table sg_in;
+       struct scatterlist sg_out[3], prealloc_sg;
        struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher();
        struct blkcipher_desc desc = { .tfm = tfm };
        char pad[16];
@@ -270,17 +363,17 @@ static int ceph_aes_decrypt2(const void *key, int key_len,
        if (IS_ERR(tfm))
                return PTR_ERR(tfm);
 
-       sg_init_table(sg_in, 1);
-       sg_set_buf(sg_in, src, src_len);
        sg_init_table(sg_out, 3);
        sg_set_buf(&sg_out[0], dst1, *dst1_len);
        sg_set_buf(&sg_out[1], dst2, *dst2_len);
        sg_set_buf(&sg_out[2], pad, sizeof(pad));
+       ret = setup_sgtable(&sg_in, &prealloc_sg, src, src_len);
+       if (ret)
+               goto out_tfm;
 
        crypto_blkcipher_setkey((void *)tfm, key, key_len);
        iv = crypto_blkcipher_crt(tfm)->iv;
        ivsize = crypto_blkcipher_ivsize(tfm);
-
        memcpy(iv, aes_iv, ivsize);
 
        /*
@@ -289,12 +382,10 @@ static int ceph_aes_decrypt2(const void *key, int key_len,
        print_hex_dump(KERN_ERR, "dec   in: ", DUMP_PREFIX_NONE, 16, 1,
                       src, src_len, 1);
        */
-
-       ret = crypto_blkcipher_decrypt(&desc, sg_out, sg_in, src_len);
-       crypto_free_blkcipher(tfm);
+       ret = crypto_blkcipher_decrypt(&desc, sg_out, sg_in.sgl, src_len);
        if (ret < 0) {
                pr_err("ceph_aes_decrypt failed %d\n", ret);
-               return ret;
+               goto out_sg;
        }
 
        if (src_len <= *dst1_len)
@@ -324,7 +415,11 @@ static int ceph_aes_decrypt2(const void *key, int key_len,
                       dst2, *dst2_len, 1);
        */
 
-       return 0;
+out_sg:
+       teardown_sgtable(&sg_in);
+out_tfm:
+       crypto_free_blkcipher(tfm);
+       return ret;
 }
 
 
index f2e1573..8f7bd56 100644 (file)
@@ -62,6 +62,10 @@ int __fib_lookup(struct net *net, struct flowi4 *flp, struct fib_result *res)
        else
                res->tclassid = 0;
 #endif
+
+       if (err == -ESRCH)
+               err = -ENETUNREACH;
+
        return err;
 }
 EXPORT_SYMBOL_GPL(__fib_lookup);
index e21934b..0d33f94 100644 (file)
@@ -217,6 +217,8 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident)
                                             &ipv6_hdr(skb)->daddr))
                                continue;
 #endif
+               } else {
+                       continue;
                }
 
                if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif)
index cb57aa8..b27f6d3 100644 (file)
@@ -962,8 +962,6 @@ static void ip6gre_tnl_link_config(struct ip6_tnl *t, int set_mtu)
        else
                dev->flags &= ~IFF_POINTOPOINT;
 
-       dev->iflink = p->link;
-
        /* Precalculate GRE options length */
        if (t->parms.o_flags&(GRE_CSUM|GRE_KEY|GRE_SEQ)) {
                if (t->parms.o_flags&GRE_CSUM)
@@ -1273,6 +1271,7 @@ static int ip6gre_tunnel_init(struct net_device *dev)
                u64_stats_init(&ip6gre_tunnel_stats->syncp);
        }
 
+       dev->iflink = tunnel->parms.link;
 
        return 0;
 }
@@ -1474,6 +1473,8 @@ static int ip6gre_tap_init(struct net_device *dev)
                u64_stats_init(&ip6gre_tap_stats->syncp);
        }
 
+       dev->iflink = tunnel->parms.link;
+
        return 0;
 }
 
index 9120339..657639d 100644 (file)
@@ -272,9 +272,6 @@ static int ip6_tnl_create2(struct net_device *dev)
        int err;
 
        t = netdev_priv(dev);
-       err = ip6_tnl_dev_init(dev);
-       if (err < 0)
-               goto out;
 
        err = register_netdevice(dev);
        if (err < 0)
@@ -1456,6 +1453,7 @@ ip6_tnl_change_mtu(struct net_device *dev, int new_mtu)
 
 
 static const struct net_device_ops ip6_tnl_netdev_ops = {
+       .ndo_init       = ip6_tnl_dev_init,
        .ndo_uninit     = ip6_tnl_dev_uninit,
        .ndo_start_xmit = ip6_tnl_xmit,
        .ndo_do_ioctl   = ip6_tnl_ioctl,
@@ -1547,16 +1545,10 @@ static int __net_init ip6_fb_tnl_dev_init(struct net_device *dev)
        struct ip6_tnl *t = netdev_priv(dev);
        struct net *net = dev_net(dev);
        struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
-       int err = ip6_tnl_dev_init_gen(dev);
-
-       if (err)
-               return err;
 
        t->parms.proto = IPPROTO_IPV6;
        dev_hold(dev);
 
-       ip6_tnl_link_config(t);
-
        rcu_assign_pointer(ip6n->tnls_wc[0], t);
        return 0;
 }
index 2d19272..9a5339f 100644 (file)
@@ -172,10 +172,6 @@ static int vti6_tnl_create2(struct net_device *dev)
        struct vti6_net *ip6n = net_generic(net, vti6_net_id);
        int err;
 
-       err = vti6_dev_init(dev);
-       if (err < 0)
-               goto out;
-
        err = register_netdevice(dev);
        if (err < 0)
                goto out;
@@ -693,6 +689,7 @@ static int vti6_change_mtu(struct net_device *dev, int new_mtu)
 }
 
 static const struct net_device_ops vti6_netdev_ops = {
+       .ndo_init       = vti6_dev_init,
        .ndo_uninit     = vti6_dev_uninit,
        .ndo_start_xmit = vti6_tnl_xmit,
        .ndo_do_ioctl   = vti6_ioctl,
@@ -772,16 +769,10 @@ static int __net_init vti6_fb_tnl_dev_init(struct net_device *dev)
        struct ip6_tnl *t = netdev_priv(dev);
        struct net *net = dev_net(dev);
        struct vti6_net *ip6n = net_generic(net, vti6_net_id);
-       int err = vti6_dev_init_gen(dev);
-
-       if (err)
-               return err;
 
        t->parms.proto = IPPROTO_IPV6;
        dev_hold(dev);
 
-       vti6_link_config(t);
-
        rcu_assign_pointer(ip6n->tnls_wc[0], t);
        return 0;
 }
index b12b11b..317b6db 100644 (file)
@@ -195,10 +195,8 @@ static int ipip6_tunnel_create(struct net_device *dev)
        struct sit_net *sitn = net_generic(net, sit_net_id);
        int err;
 
-       err = ipip6_tunnel_init(dev);
-       if (err < 0)
-               goto out;
-       ipip6_tunnel_clone_6rd(dev, sitn);
+       memcpy(dev->dev_addr, &t->parms.iph.saddr, 4);
+       memcpy(dev->broadcast, &t->parms.iph.daddr, 4);
 
        if ((__force u16)t->parms.i_flags & SIT_ISATAP)
                dev->priv_flags |= IFF_ISATAP;
@@ -207,7 +205,8 @@ static int ipip6_tunnel_create(struct net_device *dev)
        if (err < 0)
                goto out;
 
-       strcpy(t->parms.name, dev->name);
+       ipip6_tunnel_clone_6rd(dev, sitn);
+
        dev->rtnl_link_ops = &sit_link_ops;
 
        dev_hold(dev);
@@ -1321,6 +1320,7 @@ static int ipip6_tunnel_change_mtu(struct net_device *dev, int new_mtu)
 }
 
 static const struct net_device_ops ipip6_netdev_ops = {
+       .ndo_init       = ipip6_tunnel_init,
        .ndo_uninit     = ipip6_tunnel_uninit,
        .ndo_start_xmit = sit_tunnel_xmit,
        .ndo_do_ioctl   = ipip6_tunnel_ioctl,
@@ -1367,9 +1367,7 @@ static int ipip6_tunnel_init(struct net_device *dev)
 
        tunnel->dev = dev;
        tunnel->net = dev_net(dev);
-
-       memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4);
-       memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
+       strcpy(tunnel->parms.name, dev->name);
 
        ipip6_tunnel_bind_dev(dev);
        dev->tstats = alloc_percpu(struct pcpu_sw_netstats);
@@ -1401,7 +1399,6 @@ static int __net_init ipip6_fb_tunnel_init(struct net_device *dev)
 
        tunnel->dev = dev;
        tunnel->net = dev_net(dev);
-       strcpy(tunnel->parms.name, dev->name);
 
        iph->version            = 4;
        iph->protocol           = IPPROTO_IPV6;
index 00b2a6d..d65aea2 100644 (file)
@@ -1763,6 +1763,7 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock,
        struct ipxhdr *ipx = NULL;
        struct sk_buff *skb;
        int copied, rc;
+       bool locked = true;
 
        lock_sock(sk);
        /* put the autobinding in */
@@ -1789,6 +1790,8 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock,
        if (sock_flag(sk, SOCK_ZAPPED))
                goto out;
 
+       release_sock(sk);
+       locked = false;
        skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
                                flags & MSG_DONTWAIT, &rc);
        if (!skb)
@@ -1822,7 +1825,8 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock,
 out_free:
        skb_free_datagram(sk, skb);
 out:
-       release_sock(sk);
+       if (locked)
+               release_sock(sk);
        return rc;
 }
 
index ea7013c..3f076b9 100644 (file)
@@ -815,7 +815,7 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata,
 
        memset(&params, 0, sizeof(params));
        memset(&csa_ie, 0, sizeof(csa_ie));
-       err = ieee80211_parse_ch_switch_ie(sdata, elems, beacon,
+       err = ieee80211_parse_ch_switch_ie(sdata, elems,
                                           ifibss->chandef.chan->band,
                                           sta_flags, ifibss->bssid, &csa_ie);
        /* can't switch to destination channel, fail */
index b127902..bf7a1bb 100644 (file)
@@ -1569,7 +1569,6 @@ void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
  * ieee80211_parse_ch_switch_ie - parses channel switch IEs
  * @sdata: the sdata of the interface which has received the frame
  * @elems: parsed 802.11 elements received with the frame
- * @beacon: indicates if the frame was a beacon or probe response
  * @current_band: indicates the current band
  * @sta_flags: contains information about own capabilities and restrictions
  *     to decide which channel switch announcements can be accepted. Only the
@@ -1583,7 +1582,7 @@ void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
  * Return: 0 on success, <0 on error and >0 if there is nothing to parse.
  */
 int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
-                                struct ieee802_11_elems *elems, bool beacon,
+                                struct ieee802_11_elems *elems,
                                 enum ieee80211_band current_band,
                                 u32 sta_flags, u8 *bssid,
                                 struct ieee80211_csa_ie *csa_ie);
index 8f7fabc..06f5de4 100644 (file)
@@ -760,10 +760,12 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
        int i, flushed;
        struct ps_data *ps;
        struct cfg80211_chan_def chandef;
+       bool cancel_scan;
 
        clear_bit(SDATA_STATE_RUNNING, &sdata->state);
 
-       if (rcu_access_pointer(local->scan_sdata) == sdata)
+       cancel_scan = rcu_access_pointer(local->scan_sdata) == sdata;
+       if (cancel_scan)
                ieee80211_scan_cancel(local);
 
        /*
@@ -973,6 +975,9 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
 
        ieee80211_recalc_ps(local, -1);
 
+       if (cancel_scan)
+               flush_delayed_work(&local->scan_work);
+
        if (local->open_count == 0) {
                ieee80211_stop_device(local);
 
index 5b919ca..3d52d1d 100644 (file)
@@ -885,7 +885,7 @@ ieee80211_mesh_process_chnswitch(struct ieee80211_sub_if_data *sdata,
 
        memset(&params, 0, sizeof(params));
        memset(&csa_ie, 0, sizeof(csa_ie));
-       err = ieee80211_parse_ch_switch_ie(sdata, elems, beacon, band,
+       err = ieee80211_parse_ch_switch_ie(sdata, elems, band,
                                           sta_flags, sdata->vif.addr,
                                           &csa_ie);
        if (err < 0)
index 189eef0..c9535a9 100644 (file)
@@ -1001,7 +1001,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
 
        current_band = cbss->channel->band;
        memset(&csa_ie, 0, sizeof(csa_ie));
-       res = ieee80211_parse_ch_switch_ie(sdata, elems, beacon, current_band,
+       res = ieee80211_parse_ch_switch_ie(sdata, elems, current_band,
                                           ifmgd->flags,
                                           ifmgd->associated->bssid, &csa_ie);
        if (res < 0)
@@ -1086,7 +1086,8 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
                ieee80211_queue_work(&local->hw, &ifmgd->chswitch_work);
        else
                mod_timer(&ifmgd->chswitch_timer,
-                         TU_TO_EXP_TIME(csa_ie.count * cbss->beacon_interval));
+                         TU_TO_EXP_TIME((csa_ie.count - 1) *
+                                        cbss->beacon_interval));
 }
 
 static u32 ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
index 3e57f96..095c160 100644 (file)
@@ -1679,11 +1679,14 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
        sc = le16_to_cpu(hdr->seq_ctrl);
        frag = sc & IEEE80211_SCTL_FRAG;
 
-       if (likely((!ieee80211_has_morefrags(fc) && frag == 0) ||
-                  is_multicast_ether_addr(hdr->addr1))) {
-               /* not fragmented */
+       if (likely(!ieee80211_has_morefrags(fc) && frag == 0))
+               goto out;
+
+       if (is_multicast_ether_addr(hdr->addr1)) {
+               rx->local->dot11MulticastReceivedFrameCount++;
                goto out;
        }
+
        I802_DEBUG_INC(rx->local->rx_handlers_fragments);
 
        if (skb_linearize(rx->skb))
@@ -1776,10 +1779,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
  out:
        if (rx->sta)
                rx->sta->rx_packets++;
-       if (is_multicast_ether_addr(hdr->addr1))
-               rx->local->dot11MulticastReceivedFrameCount++;
-       else
-               ieee80211_led_rx(rx->local);
+       ieee80211_led_rx(rx->local);
        return RX_CONTINUE;
 }
 
index 6ab0090..efeba56 100644 (file)
@@ -22,7 +22,7 @@
 #include "wme.h"
 
 int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
-                                struct ieee802_11_elems *elems, bool beacon,
+                                struct ieee802_11_elems *elems,
                                 enum ieee80211_band current_band,
                                 u32 sta_flags, u8 *bssid,
                                 struct ieee80211_csa_ie *csa_ie)
@@ -91,19 +91,13 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
                return -EINVAL;
        }
 
-       if (!beacon && sec_chan_offs) {
+       if (sec_chan_offs) {
                secondary_channel_offset = sec_chan_offs->sec_chan_offs;
-       } else if (beacon && ht_oper) {
-               secondary_channel_offset =
-                       ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET;
        } else if (!(sta_flags & IEEE80211_STA_DISABLE_HT)) {
-               /* If it's not a beacon, HT is enabled and the IE not present,
-                * it's 20 MHz, 802.11-2012 8.5.2.6:
-                *      This element [the Secondary Channel Offset Element] is
-                *      present when switching to a 40 MHz channel. It may be
-                *      present when switching to a 20 MHz channel (in which
-                *      case the secondary channel offset is set to SCN).
-                */
+               /* If the secondary channel offset IE is not present,
+                * we can't know what's the post-CSA offset, so the
+                * best we can do is use 20MHz.
+               */
                secondary_channel_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE;
        }
 
index de770ec..cf99377 100644 (file)
@@ -636,7 +636,7 @@ ip_set_nfnl_get_byindex(struct net *net, ip_set_id_t index)
        struct ip_set *set;
        struct ip_set_net *inst = ip_set_pernet(net);
 
-       if (index > inst->ip_set_max)
+       if (index >= inst->ip_set_max)
                return IPSET_INVALID_ID;
 
        nfnl_lock(NFNL_SUBSYS_IPSET);
index a155d19..6ff12a1 100644 (file)
@@ -45,7 +45,8 @@
 #define NFULNL_NLBUFSIZ_DEFAULT        NLMSG_GOODSIZE
 #define NFULNL_TIMEOUT_DEFAULT         100     /* every second */
 #define NFULNL_QTHRESH_DEFAULT         100     /* 100 packets */
-#define NFULNL_COPY_RANGE_MAX  0xFFFF  /* max packet size is limited by 16-bit struct nfattr nfa_len field */
+/* max packet size is limited by 16-bit struct nfattr nfa_len field */
+#define NFULNL_COPY_RANGE_MAX  (0xFFFF - NLA_HDRLEN)
 
 #define PRINTR(x, args...)     do { if (net_ratelimit()) \
                                     printk(x, ## args); } while (0);
@@ -255,6 +256,8 @@ nfulnl_set_mode(struct nfulnl_instance *inst, u_int8_t mode,
 
        case NFULNL_COPY_PACKET:
                inst->copy_mode = mode;
+               if (range == 0)
+                       range = NFULNL_COPY_RANGE_MAX;
                inst->copy_range = min_t(unsigned int,
                                         range, NFULNL_COPY_RANGE_MAX);
                break;
@@ -346,26 +349,25 @@ nfulnl_alloc_skb(struct net *net, u32 peer_portid, unsigned int inst_size,
        return skb;
 }
 
-static int
+static void
 __nfulnl_send(struct nfulnl_instance *inst)
 {
-       int status = -1;
-
        if (inst->qlen > 1) {
                struct nlmsghdr *nlh = nlmsg_put(inst->skb, 0, 0,
                                                 NLMSG_DONE,
                                                 sizeof(struct nfgenmsg),
                                                 0);
-               if (!nlh)
+               if (WARN_ONCE(!nlh, "bad nlskb size: %u, tailroom %d\n",
+                             inst->skb->len, skb_tailroom(inst->skb))) {
+                       kfree_skb(inst->skb);
                        goto out;
+               }
        }
-       status = nfnetlink_unicast(inst->skb, inst->net, inst->peer_portid,
-                                  MSG_DONTWAIT);
-
+       nfnetlink_unicast(inst->skb, inst->net, inst->peer_portid,
+                         MSG_DONTWAIT);
+out:
        inst->qlen = 0;
        inst->skb = NULL;
-out:
-       return status;
 }
 
 static void
@@ -652,7 +654,8 @@ nfulnl_log_packet(struct net *net,
                + nla_total_size(sizeof(u_int32_t))     /* gid */
                + nla_total_size(plen)                  /* prefix */
                + nla_total_size(sizeof(struct nfulnl_msg_packet_hw))
-               + nla_total_size(sizeof(struct nfulnl_msg_packet_timestamp));
+               + nla_total_size(sizeof(struct nfulnl_msg_packet_timestamp))
+               + nla_total_size(sizeof(struct nfgenmsg));      /* NLMSG_DONE */
 
        if (in && skb_mac_header_was_set(skb)) {
                size +=   nla_total_size(skb->dev->hard_header_len)
@@ -681,8 +684,7 @@ nfulnl_log_packet(struct net *net,
                break;
 
        case NFULNL_COPY_PACKET:
-               if (inst->copy_range == 0
-                   || inst->copy_range > skb->len)
+               if (inst->copy_range > skb->len)
                        data_len = skb->len;
                else
                        data_len = inst->copy_range;
@@ -695,8 +697,7 @@ nfulnl_log_packet(struct net *net,
                goto unlock_and_release;
        }
 
-       if (inst->skb &&
-           size > skb_tailroom(inst->skb) - sizeof(struct nfgenmsg)) {
+       if (inst->skb && size > skb_tailroom(inst->skb)) {
                /* either the queue len is too high or we don't have
                 * enough room in the skb left. flush to userspace. */
                __nfulnl_flush(inst);
index 82cb823..ad97961 100644 (file)
@@ -678,7 +678,7 @@ nft_target_select_ops(const struct nft_ctx *ctx,
        family = ctx->afi->family;
 
        /* Re-use the existing target if it's already loaded. */
-       list_for_each_entry(nft_target, &nft_match_list, head) {
+       list_for_each_entry(nft_target, &nft_target_list, head) {
                struct xt_target *target = nft_target->ops.data;
 
                if (strcmp(target->name, tg_name) == 0 &&
index 5d97d8f..d477d47 100644 (file)
@@ -1627,6 +1627,8 @@ struct sctp_chunk *sctp_assoc_lookup_asconf_ack(
         * ack chunk whose serial number matches that of the request.
         */
        list_for_each_entry(ack, &asoc->asconf_ack_list, transmitted_list) {
+               if (sctp_chunk_pending(ack))
+                       continue;
                if (ack->subh.addip_hdr->serial == serial) {
                        sctp_chunk_hold(ack);
                        return ack;
index 0e85291..fb7976a 100644 (file)
@@ -862,8 +862,6 @@ int sctp_auth_set_key(struct sctp_endpoint *ep,
                list_add(&cur_key->key_list, sh_keys);
 
        cur_key->key = key;
-       sctp_auth_key_hold(key);
-
        return 0;
 nomem:
        if (!replace)
index 4de12af..7e8a16c 100644 (file)
@@ -140,18 +140,9 @@ struct sctp_chunk *sctp_inq_pop(struct sctp_inq *queue)
                } else {
                        /* Nothing to do. Next chunk in the packet, please. */
                        ch = (sctp_chunkhdr_t *) chunk->chunk_end;
-
                        /* Force chunk->skb->data to chunk->chunk_end.  */
-                       skb_pull(chunk->skb,
-                                chunk->chunk_end - chunk->skb->data);
-
-                       /* Verify that we have at least chunk headers
-                        * worth of buffer left.
-                        */
-                       if (skb_headlen(chunk->skb) < sizeof(sctp_chunkhdr_t)) {
-                               sctp_chunk_free(chunk);
-                               chunk = queue->in_progress = NULL;
-                       }
+                       skb_pull(chunk->skb, chunk->chunk_end - chunk->skb->data);
+                       /* We are guaranteed to pull a SCTP header. */
                }
        }
 
@@ -187,24 +178,14 @@ struct sctp_chunk *sctp_inq_pop(struct sctp_inq *queue)
        skb_pull(chunk->skb, sizeof(sctp_chunkhdr_t));
        chunk->subh.v = NULL; /* Subheader is no longer valid.  */
 
-       if (chunk->chunk_end < skb_tail_pointer(chunk->skb)) {
+       if (chunk->chunk_end + sizeof(sctp_chunkhdr_t) <
+           skb_tail_pointer(chunk->skb)) {
                /* This is not a singleton */
                chunk->singleton = 0;
        } else if (chunk->chunk_end > skb_tail_pointer(chunk->skb)) {
-               /* RFC 2960, Section 6.10  Bundling
-                *
-                * Partial chunks MUST NOT be placed in an SCTP packet.
-                * If the receiver detects a partial chunk, it MUST drop
-                * the chunk.
-                *
-                * Since the end of the chunk is past the end of our buffer
-                * (which contains the whole packet, we can freely discard
-                * the whole packet.
-                */
-               sctp_chunk_free(chunk);
-               chunk = queue->in_progress = NULL;
-
-               return NULL;
+               /* Discard inside state machine. */
+               chunk->pdiscard = 1;
+               chunk->chunk_end = skb_tail_pointer(chunk->skb);
        } else {
                /* We are at the end of the packet, so mark the chunk
                 * in case we need to send a SACK.
index fee5552..43abb64 100644 (file)
@@ -2609,6 +2609,9 @@ do_addr_param:
                addr_param = param.v + sizeof(sctp_addip_param_t);
 
                af = sctp_get_af_specific(param_type2af(param.p->type));
+               if (af == NULL)
+                       break;
+
                af->from_addr_param(&addr, addr_param,
                                    htons(asoc->peer.port), 0);
 
@@ -3110,50 +3113,63 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
        return SCTP_ERROR_NO_ERROR;
 }
 
-/* Verify the ASCONF packet before we process it.  */
-int sctp_verify_asconf(const struct sctp_association *asoc,
-                      struct sctp_paramhdr *param_hdr, void *chunk_end,
-                      struct sctp_paramhdr **errp) {
-       sctp_addip_param_t *asconf_param;
+/* Verify the ASCONF packet before we process it. */
+bool sctp_verify_asconf(const struct sctp_association *asoc,
+                       struct sctp_chunk *chunk, bool addr_param_needed,
+                       struct sctp_paramhdr **errp)
+{
+       sctp_addip_chunk_t *addip = (sctp_addip_chunk_t *) chunk->chunk_hdr;
        union sctp_params param;
-       int length, plen;
+       bool addr_param_seen = false;
 
-       param.v = (sctp_paramhdr_t *) param_hdr;
-       while (param.v <= chunk_end - sizeof(sctp_paramhdr_t)) {
-               length = ntohs(param.p->length);
-               *errp = param.p;
-
-               if (param.v > chunk_end - length ||
-                   length < sizeof(sctp_paramhdr_t))
-                       return 0;
+       sctp_walk_params(param, addip, addip_hdr.params) {
+               size_t length = ntohs(param.p->length);
 
+               *errp = param.p;
                switch (param.p->type) {
+               case SCTP_PARAM_ERR_CAUSE:
+                       break;
+               case SCTP_PARAM_IPV4_ADDRESS:
+                       if (length != sizeof(sctp_ipv4addr_param_t))
+                               return false;
+                       addr_param_seen = true;
+                       break;
+               case SCTP_PARAM_IPV6_ADDRESS:
+                       if (length != sizeof(sctp_ipv6addr_param_t))
+                               return false;
+                       addr_param_seen = true;
+                       break;
                case SCTP_PARAM_ADD_IP:
                case SCTP_PARAM_DEL_IP:
                case SCTP_PARAM_SET_PRIMARY:
-                       asconf_param = (sctp_addip_param_t *)param.v;
-                       plen = ntohs(asconf_param->param_hdr.length);
-                       if (plen < sizeof(sctp_addip_param_t) +
-                           sizeof(sctp_paramhdr_t))
-                               return 0;
+                       /* In ASCONF chunks, these need to be first. */
+                       if (addr_param_needed && !addr_param_seen)
+                               return false;
+                       length = ntohs(param.addip->param_hdr.length);
+                       if (length < sizeof(sctp_addip_param_t) +
+                                    sizeof(sctp_paramhdr_t))
+                               return false;
                        break;
                case SCTP_PARAM_SUCCESS_REPORT:
                case SCTP_PARAM_ADAPTATION_LAYER_IND:
                        if (length != sizeof(sctp_addip_param_t))
-                               return 0;
-
+                               return false;
                        break;
                default:
-                       break;
+                       /* This is unkown to us, reject! */
+                       return false;
                }
-
-               param.v += WORD_ROUND(length);
        }
 
-       if (param.v != chunk_end)
-               return 0;
+       /* Remaining sanity checks. */
+       if (addr_param_needed && !addr_param_seen)
+               return false;
+       if (!addr_param_needed && addr_param_seen)
+               return false;
+       if (param.v != chunk->chunk_end)
+               return false;
 
-       return 1;
+       return true;
 }
 
 /* Process an incoming ASCONF chunk with the next expected serial no. and
@@ -3162,16 +3178,17 @@ int sctp_verify_asconf(const struct sctp_association *asoc,
 struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc,
                                       struct sctp_chunk *asconf)
 {
+       sctp_addip_chunk_t *addip = (sctp_addip_chunk_t *) asconf->chunk_hdr;
+       bool all_param_pass = true;
+       union sctp_params param;
        sctp_addiphdr_t         *hdr;
        union sctp_addr_param   *addr_param;
        sctp_addip_param_t      *asconf_param;
        struct sctp_chunk       *asconf_ack;
-
        __be16  err_code;
        int     length = 0;
        int     chunk_len;
        __u32   serial;
-       int     all_param_pass = 1;
 
        chunk_len = ntohs(asconf->chunk_hdr->length) - sizeof(sctp_chunkhdr_t);
        hdr = (sctp_addiphdr_t *)asconf->skb->data;
@@ -3199,9 +3216,14 @@ struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc,
                goto done;
 
        /* Process the TLVs contained within the ASCONF chunk. */
-       while (chunk_len > 0) {
+       sctp_walk_params(param, addip, addip_hdr.params) {
+               /* Skip preceeding address parameters. */
+               if (param.p->type == SCTP_PARAM_IPV4_ADDRESS ||
+                   param.p->type == SCTP_PARAM_IPV6_ADDRESS)
+                       continue;
+
                err_code = sctp_process_asconf_param(asoc, asconf,
-                                                    asconf_param);
+                                                    param.addip);
                /* ADDIP 4.1 A7)
                 * If an error response is received for a TLV parameter,
                 * all TLVs with no response before the failed TLV are
@@ -3209,28 +3231,20 @@ struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc,
                 * the failed response are considered unsuccessful unless
                 * a specific success indication is present for the parameter.
                 */
-               if (SCTP_ERROR_NO_ERROR != err_code)
-                       all_param_pass = 0;
-
+               if (err_code != SCTP_ERROR_NO_ERROR)
+                       all_param_pass = false;
                if (!all_param_pass)
-                       sctp_add_asconf_response(asconf_ack,
-                                                asconf_param->crr_id, err_code,
-                                                asconf_param);
+                       sctp_add_asconf_response(asconf_ack, param.addip->crr_id,
+                                                err_code, param.addip);
 
                /* ADDIP 4.3 D11) When an endpoint receiving an ASCONF to add
                 * an IP address sends an 'Out of Resource' in its response, it
                 * MUST also fail any subsequent add or delete requests bundled
                 * in the ASCONF.
                 */
-               if (SCTP_ERROR_RSRC_LOW == err_code)
+               if (err_code == SCTP_ERROR_RSRC_LOW)
                        goto done;
-
-               /* Move to the next ASCONF param. */
-               length = ntohs(asconf_param->param_hdr.length);
-               asconf_param = (void *)asconf_param + length;
-               chunk_len -= length;
        }
-
 done:
        asoc->peer.addip_serial++;
 
index 7194fe8..3e287a3 100644 (file)
@@ -170,6 +170,9 @@ sctp_chunk_length_valid(struct sctp_chunk *chunk,
 {
        __u16 chunk_length = ntohs(chunk->chunk_hdr->length);
 
+       /* Previously already marked? */
+       if (unlikely(chunk->pdiscard))
+               return 0;
        if (unlikely(chunk_length < required_length))
                return 0;
 
@@ -3591,9 +3594,7 @@ sctp_disposition_t sctp_sf_do_asconf(struct net *net,
        struct sctp_chunk       *asconf_ack = NULL;
        struct sctp_paramhdr    *err_param = NULL;
        sctp_addiphdr_t         *hdr;
-       union sctp_addr_param   *addr_param;
        __u32                   serial;
-       int                     length;
 
        if (!sctp_vtag_verify(chunk, asoc)) {
                sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
@@ -3618,17 +3619,8 @@ sctp_disposition_t sctp_sf_do_asconf(struct net *net,
        hdr = (sctp_addiphdr_t *)chunk->skb->data;
        serial = ntohl(hdr->serial);
 
-       addr_param = (union sctp_addr_param *)hdr->params;
-       length = ntohs(addr_param->p.length);
-       if (length < sizeof(sctp_paramhdr_t))
-               return sctp_sf_violation_paramlen(net, ep, asoc, type, arg,
-                          (void *)addr_param, commands);
-
        /* Verify the ASCONF chunk before processing it. */
-       if (!sctp_verify_asconf(asoc,
-                           (sctp_paramhdr_t *)((void *)addr_param + length),
-                           (void *)chunk->chunk_end,
-                           &err_param))
+       if (!sctp_verify_asconf(asoc, chunk, true, &err_param))
                return sctp_sf_violation_paramlen(net, ep, asoc, type, arg,
                                                  (void *)err_param, commands);
 
@@ -3745,10 +3737,7 @@ sctp_disposition_t sctp_sf_do_asconf_ack(struct net *net,
        rcvd_serial = ntohl(addip_hdr->serial);
 
        /* Verify the ASCONF-ACK chunk before processing it. */
-       if (!sctp_verify_asconf(asoc,
-           (sctp_paramhdr_t *)addip_hdr->params,
-           (void *)asconf_ack->chunk_end,
-           &err_param))
+       if (!sctp_verify_asconf(asoc, asconf_ack, false, &err_param))
                return sctp_sf_violation_paramlen(net, ep, asoc, type, arg,
                           (void *)err_param, commands);
 
index 983d087..366c514 100644 (file)
@@ -189,8 +189,9 @@ config SND_SOC_AD73311
        tristate
 
 config SND_SOC_ADAU1701
+       tristate "Analog Devices ADAU1701 CODEC"
+       depends on I2C
        select SND_SOC_SIGMADSP
-       tristate
 
 config SND_SOC_ADAU1373
        tristate
@@ -202,28 +203,31 @@ config SND_SOC_ADS117X
        tristate
 
 config SND_SOC_AK4104
-       tristate
+       tristate "AKM AK4104 CODEC"
+       depends on SPI_MASTER
 
 config SND_SOC_AK4535
        tristate
 
 config SND_SOC_AK4554
-       tristate
+       tristate "AKM AK4554 CODEC"
 
 config SND_SOC_AK4641
        tristate
 
 config SND_SOC_AK4642
-       tristate
+       tristate "AKM AK4642 CODEC"
+       depends on I2C
 
 config SND_SOC_AK4671
        tristate
 
 config SND_SOC_AK5386
-       tristate
+       tristate "AKM AK5638 CODEC"
 
 config SND_SOC_ALC5623
        tristate
+
 config SND_SOC_ALC5632
        tristate
 
@@ -234,14 +238,17 @@ config SND_SOC_CS42L51
        tristate
 
 config SND_SOC_CS42L52
-       tristate
+       tristate "Cirrus Logic CS42L52 CODEC"
+       depends on I2C
 
 config SND_SOC_CS42L73
-       tristate
+       tristate "Cirrus Logic CS42L73 CODEC"
+       depends on I2C
 
 # Cirrus Logic CS4270 Codec
 config SND_SOC_CS4270
-       tristate
+       tristate "Cirrus Logic CS4270 CODEC"
+       depends on I2C
 
 # Cirrus Logic CS4270 Codec VD = 3.3V Errata
 # Select if you are affected by the errata where the part will not function
@@ -252,7 +259,8 @@ config SND_SOC_CS4270_VD33_ERRATA
        depends on SND_SOC_CS4270
 
 config SND_SOC_CS4271
-       tristate
+       tristate "Cirrus Logic CS4271 CODEC"
+       depends on SND_SOC_I2C_AND_SPI
 
 config SND_SOC_CX20442
        tristate
@@ -283,6 +291,9 @@ config SND_SOC_BT_SCO
 config SND_SOC_DMIC
        tristate
 
+config SND_SOC_HDMI_CODEC
+       tristate "HDMI stub CODEC"
+
 config SND_SOC_ISABELLE
         tristate
 
@@ -301,14 +312,13 @@ config SND_SOC_MAX98095
 config SND_SOC_MAX9850
        tristate
 
-config SND_SOC_HDMI_CODEC
-       tristate
-
 config SND_SOC_PCM1681
-       tristate
+       tristate "Texas Instruments PCM1681 CODEC"
+       depends on I2C
 
 config SND_SOC_PCM1792A
-       tristate
+       tristate "Texas Instruments PCM1792A CODEC"
+       depends on SPI_MASTER
 
 config SND_SOC_PCM3008
        tristate
@@ -321,7 +331,8 @@ config SND_SOC_RT5640
 
 #Freescale sgtl5000 codec
 config SND_SOC_SGTL5000
-       tristate
+       tristate "Freescale SGTL5000 CODEC"
+       depends on I2C
 
 config SND_SOC_SI476X
        tristate
@@ -334,7 +345,7 @@ config SND_SOC_SN95031
        tristate
 
 config SND_SOC_SPDIF
-       tristate
+       tristate "S/PDIF CODEC"
 
 config SND_SOC_SSM2518
        tristate
@@ -352,7 +363,8 @@ config SND_SOC_STAC9766
        tristate
 
 config SND_SOC_TAS5086
-       tristate
+       tristate "Texas Instruments TAS5086 speaker amplifier"
+       depends on I2C
 
 config SND_SOC_TLV320AIC23
        tristate
@@ -365,7 +377,8 @@ config SND_SOC_TLV320AIC32X4
        tristate
 
 config SND_SOC_TLV320AIC3X
-       tristate
+       tristate "Texas Instruments TLV320AIC3x CODECs"
+       depends on I2C
 
 config SND_SOC_TLV320DAC33
        tristate
@@ -414,55 +427,69 @@ config SND_SOC_WM8400
        tristate
 
 config SND_SOC_WM8510
-       tristate
+       tristate "Wolfson Microelectronics WM8510 CODEC"
+       depends on SND_SOC_I2C_AND_SPI
 
 config SND_SOC_WM8523
-       tristate
+       tristate "Wolfson Microelectronics WM8523 DAC"
+       depends on I2C
 
 config SND_SOC_WM8580
-       tristate
+       tristate "Wolfson Microelectronics WM8523 CODEC"
+       depends on I2C
 
 config SND_SOC_WM8711
-       tristate
+       tristate "Wolfson Microelectronics WM8711 CODEC"
+       depends on SND_SOC_I2C_AND_SPI
 
 config SND_SOC_WM8727
        tristate
 
 config SND_SOC_WM8728
-       tristate
+       tristate "Wolfson Microelectronics WM8728 DAC"
+       depends on SND_SOC_I2C_AND_SPI
 
 config SND_SOC_WM8731
-       tristate
+       tristate "Wolfson Microelectronics WM8731 CODEC"
+       depends on SND_SOC_I2C_AND_SPI
 
 config SND_SOC_WM8737
-       tristate
+       tristate "Wolfson Microelectronics WM8737 ADC"
+       depends on SND_SOC_I2C_AND_SPI
 
 config SND_SOC_WM8741
-       tristate
+       tristate "Wolfson Microelectronics WM8737 DAC"
+       depends on SND_SOC_I2C_AND_SPI
 
 config SND_SOC_WM8750
-       tristate
+       tristate "Wolfson Microelectronics WM8750 CODEC"
+       depends on SND_SOC_I2C_AND_SPI
 
 config SND_SOC_WM8753
-       tristate
+       tristate "Wolfson Microelectronics WM8753 CODEC"
+       depends on SND_SOC_I2C_AND_SPI
 
 config SND_SOC_WM8770
-       tristate
+       tristate "Wolfson Microelectronics WM8770 CODEC"
+       depends on SND_SOC_I2C_AND_SPI
 
 config SND_SOC_WM8776
-       tristate
+       tristate "Wolfson Microelectronics WM8776 CODEC"
+       depends on SND_SOC_I2C_AND_SPI
 
 config SND_SOC_WM8782
        tristate
 
 config SND_SOC_WM8804
-       tristate
+       tristate "Wolfson Microelectronics WM8804 S/PDIF transceiver"
+       depends on SND_SOC_I2C_AND_SPI
 
 config SND_SOC_WM8900
        tristate
 
 config SND_SOC_WM8903
-       tristate
+       tristate "Wolfson Microelectronics WM8903 CODEC"
+       depends on I2C
 
 config SND_SOC_WM8904
        tristate
@@ -480,7 +507,8 @@ config SND_SOC_WM8961
        tristate
 
 config SND_SOC_WM8962
-       tristate
+       tristate "Wolfson Microelectronics WM8962 CODEC"
+       depends on I2C
 
 config SND_SOC_WM8971
        tristate
@@ -553,4 +581,5 @@ config SND_SOC_ML26124
        tristate
 
 config SND_SOC_TPA6130A2
-       tristate
+       tristate "Texas Instruments TPA6130A2 headphone amplifier"
+       depends on I2C
index 0fcbe90..12528e9 100644 (file)
@@ -1369,8 +1369,7 @@ static int sgtl5000_probe(struct snd_soc_codec *codec)
 
        /* enable small pop, introduce 400ms delay in turning off */
        snd_soc_update_bits(codec, SGTL5000_CHIP_REF_CTRL,
-                               SGTL5000_SMALL_POP,
-                               SGTL5000_SMALL_POP);
+                               SGTL5000_SMALL_POP, 1);
 
        /* disable short cut detector */
        snd_soc_write(codec, SGTL5000_CHIP_SHORT_CTRL, 0);
index 2f8c889..bd7a344 100644 (file)
 #define SGTL5000_BIAS_CTRL_MASK                        0x000e
 #define SGTL5000_BIAS_CTRL_SHIFT               1
 #define SGTL5000_BIAS_CTRL_WIDTH               3
-#define SGTL5000_SMALL_POP                     0x0001
+#define SGTL5000_SMALL_POP                     0
 
 /*
  * SGTL5000_CHIP_MIC_CTRL
index 53c03af..0502e3f 100644 (file)
@@ -1341,6 +1341,7 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp)
                          file, blocks, pos - firmware->size);
 
 out_fw:
+       regmap_async_complete(regmap);
        release_firmware(firmware);
        wm_adsp_buf_free(&buf_list);
 out:
index 7a6b632..3796e33 100644 (file)
@@ -1759,8 +1759,7 @@ static const struct snd_soc_dai_ops fsi_dai_ops = {
 static struct snd_pcm_hardware fsi_pcm_hardware = {
        .info =         SNDRV_PCM_INFO_INTERLEAVED      |
                        SNDRV_PCM_INFO_MMAP             |
-                       SNDRV_PCM_INFO_MMAP_VALID       |
-                       SNDRV_PCM_INFO_PAUSE,
+                       SNDRV_PCM_INFO_MMAP_VALID,
        .buffer_bytes_max       = 64 * 1024,
        .period_bytes_min       = 32,
        .period_bytes_max       = 8192,
index 19f7896..5235248 100644 (file)
@@ -349,7 +349,7 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma,
                                                     dma_name);
        if (!dma->chan) {
                dev_err(dev, "can't get dma channel\n");
-               return -EIO;
+               goto rsnd_dma_channel_err;
        }
 
        ret = dmaengine_slave_config(dma->chan, &cfg);
@@ -363,8 +363,15 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma,
 
 rsnd_dma_init_err:
        rsnd_dma_quit(priv, dma);
+rsnd_dma_channel_err:
 
-       return ret;
+       /*
+        * DMA failed. try to PIO mode
+        * see
+        *      rsnd_ssi_dma_remove()
+        *      rsnd_rdai_continuance_probe()
+        */
+       return -EAGAIN;
 }
 
 void  rsnd_dma_quit(struct rsnd_priv *priv,
@@ -409,7 +416,7 @@ u32 rsnd_get_adinr(struct rsnd_mod *mod)
 ({                                                             \
        struct rsnd_priv *priv = rsnd_mod_to_priv(mod);         \
        struct device *dev = rsnd_priv_to_dev(priv);            \
-       dev_dbg(dev, "%s [%d] %s\n",                            \
+       dev_dbg(dev, "%s[%d] %s\n",                             \
                rsnd_mod_name(mod), rsnd_mod_id(mod), #func);   \
        (mod)->ops->func(mod, rdai);                            \
 })
@@ -456,6 +463,13 @@ static int rsnd_dai_connect(struct rsnd_mod *mod,
        return 0;
 }
 
+static void rsnd_dai_disconnect(struct rsnd_mod *mod,
+                               struct rsnd_dai_stream *io)
+{
+       mod->io = NULL;
+       io->mod[mod->type] = NULL;
+}
+
 int rsnd_dai_id(struct rsnd_priv *priv, struct rsnd_dai *rdai)
 {
        int id = rdai - priv->rdai;
@@ -686,6 +700,20 @@ static const struct snd_soc_dai_ops rsnd_soc_dai_ops = {
        ret;                                                    \
 })
 
+#define rsnd_path_break(priv, io, type)                                \
+{                                                              \
+       struct rsnd_mod *mod;                                   \
+       int id = -1;                                            \
+                                                               \
+       if (rsnd_is_enable_path(io, type)) {                    \
+               id = rsnd_info_id(priv, io, type);              \
+               if (id >= 0) {                                  \
+                       mod = rsnd_##type##_mod_get(priv, id);  \
+                       rsnd_dai_disconnect(mod, io);           \
+               }                                               \
+       }                                                       \
+}
+
 static int rsnd_path_init(struct rsnd_priv *priv,
                          struct rsnd_dai *rdai,
                          struct rsnd_dai_stream *io)
@@ -798,10 +826,8 @@ if (name##_node) {                                                 \
                        mod_parse(src);
                        mod_parse(dvc);
 
-                       if (playback)
-                               of_node_put(playback);
-                       if (capture)
-                               of_node_put(capture);
+                       of_node_put(playback);
+                       of_node_put(capture);
                }
 
                dai_i++;
@@ -888,8 +914,7 @@ static int rsnd_dai_probe(struct platform_device *pdev,
 static struct snd_pcm_hardware rsnd_pcm_hardware = {
        .info =         SNDRV_PCM_INFO_INTERLEAVED      |
                        SNDRV_PCM_INFO_MMAP             |
-                       SNDRV_PCM_INFO_MMAP_VALID       |
-                       SNDRV_PCM_INFO_PAUSE,
+                       SNDRV_PCM_INFO_MMAP_VALID,
        .buffer_bytes_max       = 64 * 1024,
        .period_bytes_min       = 32,
        .period_bytes_max       = 8192,
@@ -979,6 +1004,44 @@ static const struct snd_soc_component_driver rsnd_soc_component = {
        .name           = "rsnd",
 };
 
+static int rsnd_rdai_continuance_probe(struct rsnd_priv *priv,
+                                      struct rsnd_dai *rdai,
+                                      int is_play)
+{
+       struct rsnd_dai_stream *io = is_play ? &rdai->playback : &rdai->capture;
+       int ret;
+
+       ret = rsnd_dai_call(probe, io, rdai);
+       if (ret == -EAGAIN) {
+               /*
+                * Fallback to PIO mode
+                */
+
+               /*
+                * call "remove" for SSI/SRC/DVC
+                * SSI will be switch to PIO mode if it was DMA mode
+                * see
+                *      rsnd_dma_init()
+                *      rsnd_ssi_dma_remove()
+                */
+               rsnd_dai_call(remove, io, rdai);
+
+               /*
+                * remove SRC/DVC from DAI,
+                */
+               rsnd_path_break(priv, io, src);
+               rsnd_path_break(priv, io, dvc);
+
+               /*
+                * retry to "probe".
+                * DAI has SSI which is PIO mode only now.
+                */
+               ret = rsnd_dai_call(probe, io, rdai);
+       }
+
+       return ret;
+}
+
 /*
  *     rsnd probe
  */
@@ -1040,11 +1103,11 @@ static int rsnd_probe(struct platform_device *pdev)
        }
 
        for_each_rsnd_dai(rdai, priv, i) {
-               ret = rsnd_dai_call(probe, &rdai->playback, rdai);
+               ret = rsnd_rdai_continuance_probe(priv, rdai, 1);
                if (ret)
                        goto exit_snd_probe;
 
-               ret = rsnd_dai_call(probe, &rdai->capture, rdai);
+               ret = rsnd_rdai_continuance_probe(priv, rdai, 0);
                if (ret)
                        goto exit_snd_probe;
        }
index 3f44393..e2c8473 100644 (file)
 #include "rsnd.h"
 
 #define RSND_DVC_NAME_SIZE     16
-#define RSND_DVC_VOLUME_MAX    100
-#define RSND_DVC_VOLUME_NUM    2
+#define RSND_DVC_CHANNELS      2
 
 #define DVC_NAME "dvc"
 
+struct rsnd_dvc_cfg {
+       unsigned int max;
+       unsigned int size;
+       u32 *val;
+       const char * const *texts;
+};
+
+struct rsnd_dvc_cfg_m {
+       struct rsnd_dvc_cfg cfg;
+       u32 val[RSND_DVC_CHANNELS];
+};
+
+struct rsnd_dvc_cfg_s {
+       struct rsnd_dvc_cfg cfg;
+       u32 val;
+};
+
 struct rsnd_dvc {
        struct rsnd_dvc_platform_info *info; /* rcar_snd.h */
        struct rsnd_mod mod;
        struct clk *clk;
-       u8 volume[RSND_DVC_VOLUME_NUM];
-       u8 mute[RSND_DVC_VOLUME_NUM];
+       struct rsnd_dvc_cfg_m volume;
+       struct rsnd_dvc_cfg_m mute;
+       struct rsnd_dvc_cfg_s ren;      /* Ramp Enable */
+       struct rsnd_dvc_cfg_s rup;      /* Ramp Rate Up */
+       struct rsnd_dvc_cfg_s rdown;    /* Ramp Rate Down */
 };
 
 #define rsnd_mod_to_dvc(_mod)  \
@@ -33,23 +52,87 @@ struct rsnd_dvc {
             ((pos) = (struct rsnd_dvc *)(priv)->dvc + i);      \
             i++)
 
+static const char const *dvc_ramp_rate[] = {
+       "128 dB/1 step",         /* 00000 */
+       "64 dB/1 step",          /* 00001 */
+       "32 dB/1 step",          /* 00010 */
+       "16 dB/1 step",          /* 00011 */
+       "8 dB/1 step",           /* 00100 */
+       "4 dB/1 step",           /* 00101 */
+       "2 dB/1 step",           /* 00110 */
+       "1 dB/1 step",           /* 00111 */
+       "0.5 dB/1 step",         /* 01000 */
+       "0.25 dB/1 step",        /* 01001 */
+       "0.125 dB/1 step",       /* 01010 */
+       "0.125 dB/2 steps",      /* 01011 */
+       "0.125 dB/4 steps",      /* 01100 */
+       "0.125 dB/8 steps",      /* 01101 */
+       "0.125 dB/16 steps",     /* 01110 */
+       "0.125 dB/32 steps",     /* 01111 */
+       "0.125 dB/64 steps",     /* 10000 */
+       "0.125 dB/128 steps",    /* 10001 */
+       "0.125 dB/256 steps",    /* 10010 */
+       "0.125 dB/512 steps",    /* 10011 */
+       "0.125 dB/1024 steps",   /* 10100 */
+       "0.125 dB/2048 steps",   /* 10101 */
+       "0.125 dB/4096 steps",   /* 10110 */
+       "0.125 dB/8192 steps",   /* 10111 */
+};
+
 static void rsnd_dvc_volume_update(struct rsnd_mod *mod)
 {
        struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
-       u32 max = (0x00800000 - 1);
-       u32 vol[RSND_DVC_VOLUME_NUM];
+       u32 val[RSND_DVC_CHANNELS];
+       u32 dvucr = 0;
        u32 mute = 0;
        int i;
 
-       for (i = 0; i < RSND_DVC_VOLUME_NUM; i++) {
-               vol[i] = max / RSND_DVC_VOLUME_MAX * dvc->volume[i];
-               mute |= (!!dvc->mute[i]) << i;
+       for (i = 0; i < dvc->mute.cfg.size; i++)
+               mute |= (!!dvc->mute.cfg.val[i]) << i;
+
+       /* Disable DVC Register access */
+       rsnd_mod_write(mod, DVC_DVUER, 0);
+
+       /* Enable Ramp */
+       if (dvc->ren.val) {
+               dvucr |= 0x10;
+
+               /* Digital Volume Max */
+               for (i = 0; i < RSND_DVC_CHANNELS; i++)
+                       val[i] = dvc->volume.cfg.max;
+
+               rsnd_mod_write(mod, DVC_VRCTR, 0xff);
+               rsnd_mod_write(mod, DVC_VRPDR, dvc->rup.val << 8 |
+                                              dvc->rdown.val);
+               /*
+                * FIXME !!
+                * use scale-downed Digital Volume
+                * as Volume Ramp
+                * 7F FFFF -> 3FF
+                */
+               rsnd_mod_write(mod, DVC_VRDBR,
+                              0x3ff - (dvc->volume.val[0] >> 13));
+
+       } else {
+               for (i = 0; i < RSND_DVC_CHANNELS; i++)
+                       val[i] = dvc->volume.val[i];
+       }
+
+       /* Enable Digital Volume */
+       dvucr |= 0x100;
+       rsnd_mod_write(mod, DVC_VOL0R, val[0]);
+       rsnd_mod_write(mod, DVC_VOL1R, val[1]);
+
+       /*  Enable Mute */
+       if (mute) {
+               dvucr |= 0x1;
+               rsnd_mod_write(mod, DVC_ZCMCR, mute);
        }
 
-       rsnd_mod_write(mod, DVC_VOL0R, vol[0]);
-       rsnd_mod_write(mod, DVC_VOL1R, vol[1]);
+       rsnd_mod_write(mod, DVC_DVUCR, dvucr);
 
-       rsnd_mod_write(mod, DVC_ZCMCR, mute);
+       /* Enable DVC Register access */
+       rsnd_mod_write(mod, DVC_DVUER, 1);
 }
 
 static int rsnd_dvc_probe_gen2(struct rsnd_mod *mod,
@@ -58,7 +141,8 @@ static int rsnd_dvc_probe_gen2(struct rsnd_mod *mod,
        struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
        struct device *dev = rsnd_priv_to_dev(priv);
 
-       dev_dbg(dev, "%s (Gen2) is probed\n", rsnd_mod_name(mod));
+       dev_dbg(dev, "%s[%d] (Gen2) is probed\n",
+               rsnd_mod_name(mod), rsnd_mod_id(mod));
 
        return 0;
 }
@@ -102,16 +186,11 @@ static int rsnd_dvc_init(struct rsnd_mod *dvc_mod,
 
        rsnd_mod_write(dvc_mod, DVC_ADINR, rsnd_get_adinr(dvc_mod));
 
-       /*  enable Volume / Mute */
-       rsnd_mod_write(dvc_mod, DVC_DVUCR, 0x101);
-
        /* ch0/ch1 Volume */
        rsnd_dvc_volume_update(dvc_mod);
 
        rsnd_mod_write(dvc_mod, DVC_DVUIR, 0);
 
-       rsnd_mod_write(dvc_mod, DVC_DVUER, 1);
-
        rsnd_adg_set_cmd_timsel_gen2(rdai, dvc_mod, io);
 
        return 0;
@@ -146,19 +225,24 @@ static int rsnd_dvc_stop(struct rsnd_mod *mod,
 static int rsnd_dvc_volume_info(struct snd_kcontrol *kctrl,
                               struct snd_ctl_elem_info *uinfo)
 {
-       struct rsnd_mod *mod = snd_kcontrol_chip(kctrl);
-       struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
-       u8 *val = (u8 *)kctrl->private_value;
-
-       uinfo->count = RSND_DVC_VOLUME_NUM;
-       uinfo->value.integer.min = 0;
-
-       if (val == dvc->volume) {
-               uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
-               uinfo->value.integer.max = RSND_DVC_VOLUME_MAX;
+       struct rsnd_dvc_cfg *cfg = (struct rsnd_dvc_cfg *)kctrl->private_value;
+
+       if (cfg->texts) {
+               uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+               uinfo->count = cfg->size;
+               uinfo->value.enumerated.items = cfg->max;
+               if (uinfo->value.enumerated.item >= cfg->max)
+                       uinfo->value.enumerated.item = cfg->max - 1;
+               strlcpy(uinfo->value.enumerated.name,
+                       cfg->texts[uinfo->value.enumerated.item],
+                       sizeof(uinfo->value.enumerated.name));
        } else {
-               uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
-               uinfo->value.integer.max = 1;
+               uinfo->count = cfg->size;
+               uinfo->value.integer.min = 0;
+               uinfo->value.integer.max = cfg->max;
+               uinfo->type = (cfg->max == 1) ?
+                       SNDRV_CTL_ELEM_TYPE_BOOLEAN :
+                       SNDRV_CTL_ELEM_TYPE_INTEGER;
        }
 
        return 0;
@@ -167,11 +251,14 @@ static int rsnd_dvc_volume_info(struct snd_kcontrol *kctrl,
 static int rsnd_dvc_volume_get(struct snd_kcontrol *kctrl,
                              struct snd_ctl_elem_value *ucontrol)
 {
-       u8 *val = (u8 *)kctrl->private_value;
+       struct rsnd_dvc_cfg *cfg = (struct rsnd_dvc_cfg *)kctrl->private_value;
        int i;
 
-       for (i = 0; i < RSND_DVC_VOLUME_NUM; i++)
-               ucontrol->value.integer.value[i] = val[i];
+       for (i = 0; i < cfg->size; i++)
+               if (cfg->texts)
+                       ucontrol->value.enumerated.item[i] = cfg->val[i];
+               else
+                       ucontrol->value.integer.value[i] = cfg->val[i];
 
        return 0;
 }
@@ -180,12 +267,17 @@ static int rsnd_dvc_volume_put(struct snd_kcontrol *kctrl,
                              struct snd_ctl_elem_value *ucontrol)
 {
        struct rsnd_mod *mod = snd_kcontrol_chip(kctrl);
-       u8 *val = (u8 *)kctrl->private_value;
+       struct rsnd_dvc_cfg *cfg = (struct rsnd_dvc_cfg *)kctrl->private_value;
        int i, change = 0;
 
-       for (i = 0; i < RSND_DVC_VOLUME_NUM; i++) {
-               change |= (ucontrol->value.integer.value[i] != val[i]);
-               val[i] = ucontrol->value.integer.value[i];
+       for (i = 0; i < cfg->size; i++) {
+               if (cfg->texts) {
+                       change |= (ucontrol->value.enumerated.item[i] != cfg->val[i]);
+                       cfg->val[i] = ucontrol->value.enumerated.item[i];
+               } else {
+                       change |= (ucontrol->value.integer.value[i] != cfg->val[i]);
+                       cfg->val[i] = ucontrol->value.integer.value[i];
+               }
        }
 
        if (change)
@@ -198,7 +290,7 @@ static int __rsnd_dvc_pcm_new(struct rsnd_mod *mod,
                              struct rsnd_dai *rdai,
                              struct snd_soc_pcm_runtime *rtd,
                              const unsigned char *name,
-                             u8 *private)
+                             struct rsnd_dvc_cfg *private)
 {
        struct snd_card *card = rtd->card->snd_card;
        struct snd_kcontrol *kctrl;
@@ -223,6 +315,47 @@ static int __rsnd_dvc_pcm_new(struct rsnd_mod *mod,
        return 0;
 }
 
+static int _rsnd_dvc_pcm_new_m(struct rsnd_mod *mod,
+                              struct rsnd_dai *rdai,
+                              struct snd_soc_pcm_runtime *rtd,
+                              const unsigned char *name,
+                              struct rsnd_dvc_cfg_m *private,
+                              u32 max)
+{
+       private->cfg.max        = max;
+       private->cfg.size       = RSND_DVC_CHANNELS;
+       private->cfg.val        = private->val;
+       return __rsnd_dvc_pcm_new(mod, rdai, rtd, name, &private->cfg);
+}
+
+static int _rsnd_dvc_pcm_new_s(struct rsnd_mod *mod,
+                              struct rsnd_dai *rdai,
+                              struct snd_soc_pcm_runtime *rtd,
+                              const unsigned char *name,
+                              struct rsnd_dvc_cfg_s *private,
+                              u32 max)
+{
+       private->cfg.max        = max;
+       private->cfg.size       = 1;
+       private->cfg.val        = &private->val;
+       return __rsnd_dvc_pcm_new(mod, rdai, rtd, name, &private->cfg);
+}
+
+static int _rsnd_dvc_pcm_new_e(struct rsnd_mod *mod,
+                              struct rsnd_dai *rdai,
+                              struct snd_soc_pcm_runtime *rtd,
+                              const unsigned char *name,
+                              struct rsnd_dvc_cfg_s *private,
+                              const char * const *texts,
+                              u32 max)
+{
+       private->cfg.max        = max;
+       private->cfg.size       = 1;
+       private->cfg.val        = &private->val;
+       private->cfg.texts      = texts;
+       return __rsnd_dvc_pcm_new(mod, rdai, rtd, name, &private->cfg);
+}
+
 static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
                            struct rsnd_dai *rdai,
                            struct snd_soc_pcm_runtime *rtd)
@@ -232,18 +365,43 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
        int ret;
 
        /* Volume */
-       ret = __rsnd_dvc_pcm_new(mod, rdai, rtd,
+       ret = _rsnd_dvc_pcm_new_m(mod, rdai, rtd,
                        rsnd_dai_is_play(rdai, io) ?
                        "DVC Out Playback Volume" : "DVC In Capture Volume",
-                       dvc->volume);
+                       &dvc->volume, 0x00800000 - 1);
        if (ret < 0)
                return ret;
 
        /* Mute */
-       ret = __rsnd_dvc_pcm_new(mod, rdai, rtd,
+       ret = _rsnd_dvc_pcm_new_m(mod, rdai, rtd,
                        rsnd_dai_is_play(rdai, io) ?
                        "DVC Out Mute Switch" : "DVC In Mute Switch",
-                       dvc->mute);
+                       &dvc->mute, 1);
+       if (ret < 0)
+               return ret;
+
+       /* Ramp */
+       ret = _rsnd_dvc_pcm_new_s(mod, rdai, rtd,
+                       rsnd_dai_is_play(rdai, io) ?
+                       "DVC Out Ramp Switch" : "DVC In Ramp Switch",
+                       &dvc->ren, 1);
+       if (ret < 0)
+               return ret;
+
+       ret = _rsnd_dvc_pcm_new_e(mod, rdai, rtd,
+                       rsnd_dai_is_play(rdai, io) ?
+                       "DVC Out Ramp Up Rate" : "DVC In Ramp Up Rate",
+                       &dvc->rup,
+                       dvc_ramp_rate, ARRAY_SIZE(dvc_ramp_rate));
+       if (ret < 0)
+               return ret;
+
+       ret = _rsnd_dvc_pcm_new_e(mod, rdai, rtd,
+                       rsnd_dai_is_play(rdai, io) ?
+                       "DVC Out Ramp Down Rate" : "DVC In Ramp Down Rate",
+                       &dvc->rdown,
+                       dvc_ramp_rate, ARRAY_SIZE(dvc_ramp_rate));
+
        if (ret < 0)
                return ret;
 
index f95e7ab..87a6f2d 100644 (file)
@@ -8,6 +8,17 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+
+/*
+ * #define DEBUG
+ *
+ * you can also add below in
+ * ${LINUX}/drivers/base/regmap/regmap.c
+ * for regmap debug
+ *
+ * #define LOG_DEVICE "xxxx.rcar_sound"
+ */
+
 #include "rsnd.h"
 
 struct rsnd_gen {
@@ -67,9 +78,10 @@ u32 rsnd_read(struct rsnd_priv *priv,
        if (!rsnd_is_accessible_reg(priv, gen, reg))
                return 0;
 
-       regmap_fields_read(gen->regs[reg], rsnd_mod_id(mod), &val);
+       dev_dbg(dev, "r %s[%d] - %4d : %08x\n",
+               rsnd_mod_name(mod), rsnd_mod_id(mod), reg, val);
 
-       dev_dbg(dev, "r %s - 0x%04d : %08x\n", rsnd_mod_name(mod), reg, val);
+       regmap_fields_read(gen->regs[reg], rsnd_mod_id(mod), &val);
 
        return val;
 }
@@ -84,9 +96,10 @@ void rsnd_write(struct rsnd_priv *priv,
        if (!rsnd_is_accessible_reg(priv, gen, reg))
                return;
 
-       regmap_fields_write(gen->regs[reg], rsnd_mod_id(mod), data);
+       dev_dbg(dev, "w %s[%d] - %4d : %08x\n",
+               rsnd_mod_name(mod), rsnd_mod_id(mod), reg, data);
 
-       dev_dbg(dev, "w %s - 0x%04d : %08x\n", rsnd_mod_name(mod), reg, data);
+       regmap_fields_write(gen->regs[reg], rsnd_mod_id(mod), data);
 }
 
 void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod,
@@ -98,11 +111,11 @@ void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod,
        if (!rsnd_is_accessible_reg(priv, gen, reg))
                return;
 
+       dev_dbg(dev, "b %s[%d] - %4d : %08x/%08x\n",
+               rsnd_mod_name(mod), rsnd_mod_id(mod), reg, data, mask);
+
        regmap_fields_update_bits(gen->regs[reg], rsnd_mod_id(mod),
                                  mask, data);
-
-       dev_dbg(dev, "b %s - 0x%04d : %08x/%08x\n",
-               rsnd_mod_name(mod), reg, data, mask);
 }
 
 #define rsnd_gen_regmap_init(priv, id_size, reg_id, conf)              \
@@ -311,6 +324,9 @@ static int rsnd_gen2_probe(struct platform_device *pdev,
                RSND_GEN_M_REG(DVC_ADINR,       0xe08,  0x100),
                RSND_GEN_M_REG(DVC_DVUCR,       0xe10,  0x100),
                RSND_GEN_M_REG(DVC_ZCMCR,       0xe14,  0x100),
+               RSND_GEN_M_REG(DVC_VRCTR,       0xe18,  0x100),
+               RSND_GEN_M_REG(DVC_VRPDR,       0xe1c,  0x100),
+               RSND_GEN_M_REG(DVC_VRDBR,       0xe20,  0x100),
                RSND_GEN_M_REG(DVC_VOL0R,       0xe28,  0x100),
                RSND_GEN_M_REG(DVC_VOL1R,       0xe2c,  0x100),
                RSND_GEN_M_REG(DVC_DVUER,       0xe48,  0x100),
index d119adf..ed44ca8 100644 (file)
@@ -91,6 +91,9 @@ enum rsnd_reg {
        RSND_REG_SHARE20,
        RSND_REG_SHARE21,
        RSND_REG_SHARE22,
+       RSND_REG_SHARE23,
+       RSND_REG_SHARE24,
+       RSND_REG_SHARE25,
 
        RSND_REG_MAX,
 };
@@ -129,6 +132,9 @@ enum rsnd_reg {
 #define RSND_REG_CMD_CTRL              RSND_REG_SHARE20
 #define RSND_REG_CMDOUT_TIMSEL         RSND_REG_SHARE21
 #define RSND_REG_BUSIF_DALIGN          RSND_REG_SHARE22
+#define RSND_REG_DVC_VRCTR             RSND_REG_SHARE23
+#define RSND_REG_DVC_VRPDR             RSND_REG_SHARE24
+#define RSND_REG_DVC_VRDBR             RSND_REG_SHARE25
 
 struct rsnd_of_data;
 struct rsnd_priv;
index 9183e01..4679501 100644 (file)
@@ -438,7 +438,8 @@ static int rsnd_src_probe_gen1(struct rsnd_mod *mod,
        struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
        struct device *dev = rsnd_priv_to_dev(priv);
 
-       dev_dbg(dev, "%s (Gen1) is probed\n", rsnd_mod_name(mod));
+       dev_dbg(dev, "%s[%d] (Gen1) is probed\n",
+               rsnd_mod_name(mod), rsnd_mod_id(mod));
 
        return 0;
 }
@@ -578,9 +579,11 @@ static int rsnd_src_probe_gen2(struct rsnd_mod *mod,
                            rsnd_info_is_playback(priv, src),
                            src->info->dma_id);
        if (ret < 0)
-               dev_err(dev, "SRC DMA failed\n");
-
-       dev_dbg(dev, "%s (Gen2) is probed\n", rsnd_mod_name(mod));
+               dev_err(dev, "%s[%d] (Gen2) failed\n",
+                       rsnd_mod_name(mod), rsnd_mod_id(mod));
+       else
+               dev_dbg(dev, "%s[%d] (Gen2) is probed\n",
+                       rsnd_mod_name(mod), rsnd_mod_id(mod));
 
        return ret;
 }
index 34e8400..346d3dc 100644 (file)
@@ -159,7 +159,8 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi,
                                ssi->cr_clk     = FORCE | SWL_32 |
                                                  SCKD | SWSD | CKDV(j);
 
-                               dev_dbg(dev, "ssi%d outputs %u Hz\n",
+                               dev_dbg(dev, "%s[%d] outputs %u Hz\n",
+                                       rsnd_mod_name(&ssi->mod),
                                        rsnd_mod_id(&ssi->mod), rate);
 
                                return 0;
@@ -206,7 +207,8 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi,
 
        ssi->usrcnt++;
 
-       dev_dbg(dev, "ssi%d hw started\n", rsnd_mod_id(&ssi->mod));
+       dev_dbg(dev, "%s[%d] hw started\n",
+               rsnd_mod_name(&ssi->mod), rsnd_mod_id(&ssi->mod));
 }
 
 static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi,
@@ -249,7 +251,8 @@ static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi,
                clk_disable_unprepare(ssi->clk);
        }
 
-       dev_dbg(dev, "ssi%d hw stopped\n", rsnd_mod_id(&ssi->mod));
+       dev_dbg(dev, "%s[%d] hw stopped\n",
+               rsnd_mod_name(&ssi->mod), rsnd_mod_id(&ssi->mod));
 }
 
 /*
@@ -385,9 +388,11 @@ static int rsnd_ssi_pio_probe(struct rsnd_mod *mod,
                               IRQF_SHARED,
                               dev_name(dev), ssi);
        if (ret)
-               dev_err(dev, "SSI request interrupt failed\n");
-
-       dev_dbg(dev, "%s (PIO) is probed\n", rsnd_mod_name(mod));
+               dev_err(dev, "%s[%d] (PIO) request interrupt failed\n",
+                       rsnd_mod_name(mod), rsnd_mod_id(mod));
+       else
+               dev_dbg(dev, "%s[%d] (PIO) is probed\n",
+                       rsnd_mod_name(mod), rsnd_mod_id(mod));
 
        return ret;
 }
@@ -448,9 +453,11 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod,
                dma_id);
 
        if (ret < 0)
-               dev_err(dev, "SSI DMA failed\n");
-
-       dev_dbg(dev, "%s (DMA) is probed\n", rsnd_mod_name(mod));
+               dev_err(dev, "%s[%d] (DMA) is failed\n",
+                       rsnd_mod_name(mod), rsnd_mod_id(mod));
+       else
+               dev_dbg(dev, "%s[%d] (DMA) is probed\n",
+                       rsnd_mod_name(mod), rsnd_mod_id(mod));
 
        return ret;
 }
@@ -458,8 +465,23 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod,
 static int rsnd_ssi_dma_remove(struct rsnd_mod *mod,
                               struct rsnd_dai *rdai)
 {
+       struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
+       struct device *dev = rsnd_priv_to_dev(priv);
+
        rsnd_dma_quit(rsnd_mod_to_priv(mod), rsnd_mod_to_dma(mod));
 
+       /*
+        * fallback to PIO
+        *
+        * SSI .probe might be called again.
+        * see
+        *      rsnd_rdai_continuance_probe()
+        */
+       mod->ops = &rsnd_ssi_pio_ops;
+
+       dev_info(dev, "%s[%d] fallback to PIO mode\n",
+                rsnd_mod_name(mod), rsnd_mod_id(mod));
+
        return 0;
 }
 
index 02733de..e28704e 100644 (file)
@@ -1258,13 +1258,36 @@ static void dpcm_set_fe_runtime(struct snd_pcm_substream *substream)
                dpcm_init_runtime_hw(runtime, &cpu_dai_drv->capture);
 }
 
+static int dpcm_fe_dai_do_trigger(struct snd_pcm_substream *substream, int cmd);
+
+/* Set FE's runtime_update state; the state is protected via PCM stream lock
+ * for avoiding the race with trigger callback.
+ * If the state is unset and a trigger is pending while the previous operation,
+ * process the pending trigger action here.
+ */
+static void dpcm_set_fe_update_state(struct snd_soc_pcm_runtime *fe,
+                                    int stream, enum snd_soc_dpcm_update state)
+{
+       struct snd_pcm_substream *substream =
+               snd_soc_dpcm_get_substream(fe, stream);
+
+       snd_pcm_stream_lock_irq(substream);
+       if (state == SND_SOC_DPCM_UPDATE_NO && fe->dpcm[stream].trigger_pending) {
+               dpcm_fe_dai_do_trigger(substream,
+                                      fe->dpcm[stream].trigger_pending - 1);
+               fe->dpcm[stream].trigger_pending = 0;
+       }
+       fe->dpcm[stream].runtime_update = state;
+       snd_pcm_stream_unlock_irq(substream);
+}
+
 static int dpcm_fe_dai_startup(struct snd_pcm_substream *fe_substream)
 {
        struct snd_soc_pcm_runtime *fe = fe_substream->private_data;
        struct snd_pcm_runtime *runtime = fe_substream->runtime;
        int stream = fe_substream->stream, ret = 0;
 
-       fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
+       dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_FE);
 
        ret = dpcm_be_dai_startup(fe, fe_substream->stream);
        if (ret < 0) {
@@ -1286,13 +1309,13 @@ static int dpcm_fe_dai_startup(struct snd_pcm_substream *fe_substream)
        dpcm_set_fe_runtime(fe_substream);
        snd_pcm_limit_hw_rates(runtime);
 
-       fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
+       dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO);
        return 0;
 
 unwind:
        dpcm_be_dai_startup_unwind(fe, fe_substream->stream);
 be_err:
-       fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
+       dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO);
        return ret;
 }
 
@@ -1339,7 +1362,7 @@ static int dpcm_fe_dai_shutdown(struct snd_pcm_substream *substream)
        struct snd_soc_pcm_runtime *fe = substream->private_data;
        int stream = substream->stream;
 
-       fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
+       dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_FE);
 
        /* shutdown the BEs */
        dpcm_be_dai_shutdown(fe, substream->stream);
@@ -1353,7 +1376,7 @@ static int dpcm_fe_dai_shutdown(struct snd_pcm_substream *substream)
        dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_STOP);
 
        fe->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
-       fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
+       dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO);
        return 0;
 }
 
@@ -1401,7 +1424,7 @@ static int dpcm_fe_dai_hw_free(struct snd_pcm_substream *substream)
        int err, stream = substream->stream;
 
        mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
-       fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
+       dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_FE);
 
        dev_dbg(fe->dev, "ASoC: hw_free FE %s\n", fe->dai_link->name);
 
@@ -1416,7 +1439,7 @@ static int dpcm_fe_dai_hw_free(struct snd_pcm_substream *substream)
        err = dpcm_be_dai_hw_free(fe, stream);
 
        fe->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_FREE;
-       fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
+       dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO);
 
        mutex_unlock(&fe->card->mutex);
        return 0;
@@ -1509,7 +1532,7 @@ static int dpcm_fe_dai_hw_params(struct snd_pcm_substream *substream,
        int ret, stream = substream->stream;
 
        mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
-       fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
+       dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_FE);
 
        memcpy(&fe->dpcm[substream->stream].hw_params, params,
                        sizeof(struct snd_pcm_hw_params));
@@ -1532,7 +1555,7 @@ static int dpcm_fe_dai_hw_params(struct snd_pcm_substream *substream,
                fe->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_PARAMS;
 
 out:
-       fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
+       dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO);
        mutex_unlock(&fe->card->mutex);
        return ret;
 }
@@ -1646,7 +1669,7 @@ int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream,
 }
 EXPORT_SYMBOL_GPL(dpcm_be_dai_trigger);
 
-static int dpcm_fe_dai_trigger(struct snd_pcm_substream *substream, int cmd)
+static int dpcm_fe_dai_do_trigger(struct snd_pcm_substream *substream, int cmd)
 {
        struct snd_soc_pcm_runtime *fe = substream->private_data;
        int stream = substream->stream, ret;
@@ -1720,6 +1743,23 @@ out:
        return ret;
 }
 
+static int dpcm_fe_dai_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+       struct snd_soc_pcm_runtime *fe = substream->private_data;
+       int stream = substream->stream;
+
+       /* if FE's runtime_update is already set, we're in race;
+        * process this trigger later at exit
+        */
+       if (fe->dpcm[stream].runtime_update != SND_SOC_DPCM_UPDATE_NO) {
+               fe->dpcm[stream].trigger_pending = cmd + 1;
+               return 0; /* delayed, assuming it's successful */
+       }
+
+       /* we're alone, let's trigger */
+       return dpcm_fe_dai_do_trigger(substream, cmd);
+}
+
 int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream)
 {
        struct snd_soc_dpcm *dpcm;
@@ -1763,7 +1803,7 @@ static int dpcm_fe_dai_prepare(struct snd_pcm_substream *substream)
 
        dev_dbg(fe->dev, "ASoC: prepare FE %s\n", fe->dai_link->name);
 
-       fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
+       dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_FE);
 
        /* there is no point preparing this FE if there are no BEs */
        if (list_empty(&fe->dpcm[stream].be_clients)) {
@@ -1790,7 +1830,7 @@ static int dpcm_fe_dai_prepare(struct snd_pcm_substream *substream)
        fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PREPARE;
 
 out:
-       fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
+       dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO);
        mutex_unlock(&fe->card->mutex);
 
        return ret;
@@ -1937,11 +1977,11 @@ static int dpcm_run_new_update(struct snd_soc_pcm_runtime *fe, int stream)
 {
        int ret;
 
-       fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_BE;
+       dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_BE);
        ret = dpcm_run_update_startup(fe, stream);
        if (ret < 0)
                dev_err(fe->dev, "ASoC: failed to startup some BEs\n");
-       fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
+       dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO);
 
        return ret;
 }
@@ -1950,11 +1990,11 @@ static int dpcm_run_old_update(struct snd_soc_pcm_runtime *fe, int stream)
 {
        int ret;
 
-       fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_BE;
+       dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_BE);
        ret = dpcm_run_update_shutdown(fe, stream);
        if (ret < 0)
                dev_err(fe->dev, "ASoC: failed to shutdown some BEs\n");
-       fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
+       dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO);
 
        return ret;
 }
index f4b12c2..5a723df 100644 (file)
@@ -885,6 +885,11 @@ static int snd_ftu_eff_switch_put(struct snd_kcontrol *kctl,
        return changed;
 }
 
+static void kctl_private_value_free(struct snd_kcontrol *kctl)
+{
+       kfree((void *)kctl->private_value);
+}
+
 static int snd_ftu_create_effect_switch(struct usb_mixer_interface *mixer,
        int validx, int bUnitID)
 {
@@ -919,6 +924,7 @@ static int snd_ftu_create_effect_switch(struct usb_mixer_interface *mixer,
                return -ENOMEM;
        }
 
+       kctl->private_free = kctl_private_value_free;
        err = snd_ctl_add(mixer->chip->card, kctl);
        if (err < 0)
                return err;
index c64a3d9..827d404 100644 (file)
@@ -1142,6 +1142,20 @@ void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe,
        if ((le16_to_cpu(dev->descriptor.idVendor) == 0x23ba) &&
            (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS)
                mdelay(20);
+
+       /* Marantz/Denon devices with USB DAC functionality need a delay
+        * after each class compliant request
+        */
+       if ((le16_to_cpu(dev->descriptor.idVendor) == 0x154e) &&
+           (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS) {
+
+               switch (le16_to_cpu(dev->descriptor.idProduct)) {
+               case 0x3005: /* Marantz HD-DAC1 */
+               case 0x3006: /* Marantz SA-14S1 */
+                       mdelay(20);
+                       break;
+               }
+       }
 }
 
 /*