]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge branch 'next/dt' into for-next
authorOlof Johansson <olof@lixom.net>
Mon, 26 Oct 2015 01:21:20 +0000 (10:21 +0900)
committerOlof Johansson <olof@lixom.net>
Mon, 26 Oct 2015 01:21:20 +0000 (10:21 +0900)
* next/dt:
  MAINTAINERS: Add documentation and dt-bindings for exynos stuff
  dt-bindings: EXYNOS: Document compatibles from other vendors
  dt-bindings: Consolidate Exynos SoC bindings
  ARM: dts: Add clocks to DISP1 domain in exynos5250
  dt-bindings: Correct the example for Exynos power domain clocks
  ARM: dts: Fix typo in regulator enable GPIO property in s5pv210-goni
  ARM: dts: Fix typo in regulator enable GPIO property in s5pv210-aquila
  ARM: dts: Add vbus regulator to USB2 phy nodes on exynos3250, exynos4210 and exynos4412 boards
  clk: samsung: exynos5250: Add DISP1 clocks
  ARM: dts: use exynos5420-dw-mshc compatible for exynos3250

353 files changed:
Documentation/arm/OMAP/README [new file with mode: 0644]
Documentation/arm/Samsung/Bootloader-interface.txt
Documentation/arm/keystone/knav-qmss.txt [new file with mode: 0644]
Documentation/arm/sunxi/README
Documentation/device-mapper/snapshot.txt
Documentation/devicetree/bindings/arm/arm,scpi.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/coherency-fabric.txt
Documentation/devicetree/bindings/arm/mvebu-cpu-config.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/psci.txt
Documentation/devicetree/bindings/arm/sunxi.txt
Documentation/devicetree/bindings/bus/sunxi-rsb.txt [new file with mode: 0644]
Documentation/devicetree/bindings/memory-controllers/arm,pl172.txt
Documentation/devicetree/bindings/memory-controllers/renesas-memory-controllers.txt
Documentation/devicetree/bindings/soc/rockchip/power_domain.txt [new file with mode: 0644]
Documentation/devicetree/bindings/soc/ti/keystone-navigator-qmss.txt
Documentation/devicetree/bindings/spi/sh-msiof.txt
Documentation/devicetree/bindings/usb/renesas_usbhs.txt
Documentation/hwmon/scpi-hwmon [new file with mode: 0644]
Documentation/spi/pxa2xx
MAINTAINERS
Makefile
arch/alpha/include/asm/word-at-a-time.h
arch/arm/Kconfig.debug
arch/arm/arm-soc-for-next-contents.txt [new file with mode: 0644]
arch/arm/boot/dts/am57xx-beagle-x15.dts
arch/arm/boot/dts/armada-385-db-ap.dts
arch/arm/boot/dts/berlin2q.dtsi
arch/arm/boot/dts/efm32gg-dk3750.dts
arch/arm/boot/dts/efm32gg.dtsi
arch/arm/boot/dts/emev2-kzm9d.dts
arch/arm/boot/dts/exynos5250-smdk5250.dts
arch/arm/boot/dts/exynos5420-peach-pit.dts
arch/arm/boot/dts/exynos5420.dtsi
arch/arm/boot/dts/exynos5800-peach-pi.dts
arch/arm/boot/dts/imx53-qsrb.dts
arch/arm/boot/dts/imx53.dtsi
arch/arm/boot/dts/imx6qdl-rex.dtsi
arch/arm/boot/dts/imx7d.dtsi
arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
arch/arm/boot/dts/omap3-evm-37xx.dts
arch/arm/boot/dts/qcom-msm8974.dtsi
arch/arm/boot/dts/r8a7790.dtsi
arch/arm/boot/dts/r8a7791.dtsi
arch/arm/boot/dts/ste-hrefv60plus.dtsi
arch/arm/boot/dts/ste-snowball.dts
arch/arm/boot/dts/tegra114.dtsi
arch/arm/boot/dts/tegra124.dtsi
arch/arm/boot/dts/tegra20.dtsi
arch/arm/boot/dts/tegra30.dtsi
arch/arm/boot/dts/uniphier-ph1-ld6b-ref.dts
arch/arm/configs/at91_dt_defconfig
arch/arm/configs/imx_v6_v7_defconfig
arch/arm/configs/keystone_defconfig
arch/arm/configs/lpc18xx_defconfig
arch/arm/configs/multi_v7_defconfig
arch/arm/configs/mvebu_v7_defconfig
arch/arm/configs/qcom_defconfig
arch/arm/configs/sama5_defconfig
arch/arm/configs/shmobile_defconfig
arch/arm/configs/socfpga_defconfig
arch/arm/configs/sunxi_defconfig
arch/arm/configs/tegra_defconfig
arch/arm/include/debug/at91.S
arch/arm/kernel/psci_smp.c
arch/arm/mach-at91/pm_suspend.S
arch/arm/mach-bcm/Kconfig
arch/arm/mach-bcm/Makefile
arch/arm/mach-bcm/bcm_nsp.c [new file with mode: 0644]
arch/arm/mach-bcm/brcmstb.c
arch/arm/mach-berlin/berlin.c
arch/arm/mach-berlin/platsmp.c
arch/arm/mach-cns3xxx/pcie.c
arch/arm/mach-davinci/board-dm644x-evm.c
arch/arm/mach-davinci/clock.c
arch/arm/mach-digicolor/Kconfig
arch/arm/mach-exynos/mcpm-exynos.c
arch/arm/mach-exynos/pm_domains.c
arch/arm/mach-exynos/regs-pmu.h
arch/arm/mach-exynos/suspend.c
arch/arm/mach-imx/common.h
arch/arm/mach-imx/gpc.c
arch/arm/mach-imx/mach-imx6ul.c
arch/arm/mach-imx/mach-imx7d.c
arch/arm/mach-imx/pm-imx6.c
arch/arm/mach-imx/suspend-imx6.S
arch/arm/mach-mediatek/Makefile
arch/arm/mach-mediatek/mediatek.c
arch/arm/mach-mediatek/platsmp.c [new file with mode: 0644]
arch/arm/mach-meson/Kconfig
arch/arm/mach-meson/meson.c
arch/arm/mach-mvebu/board-v7.c
arch/arm/mach-mvebu/coherency.c
arch/arm/mach-mvebu/pmsu.c
arch/arm/mach-omap1/Kconfig
arch/arm/mach-omap1/Makefile
arch/arm/mach-omap1/board-voiceblue.c [deleted file]
arch/arm/mach-omap1/include/mach/board-voiceblue.h [deleted file]
arch/arm/mach-omap2/Kconfig
arch/arm/mach-omap2/Makefile
arch/arm/mach-omap2/board-generic.c
arch/arm/mach-omap2/clkt34xx_dpll3m2.c [deleted file]
arch/arm/mach-omap2/devices.c
arch/arm/mach-omap2/devices.h [deleted file]
arch/arm/mach-omap2/omap-hotplug.c
arch/arm/mach-omap2/omap-wakeupgen.c
arch/arm/mach-omap2/pdata-quirks.c
arch/arm/mach-omap2/pm44xx.c
arch/arm/mach-omap2/powerdomains3xxx_data.c
arch/arm/mach-omap2/sram.c
arch/arm/mach-omap2/sram.h
arch/arm/mach-omap2/sram34xx.S [deleted file]
arch/arm/mach-omap2/vc.c
arch/arm/mach-orion5x/Kconfig
arch/arm/mach-orion5x/dns323-setup.c
arch/arm/mach-orion5x/tsx09-common.c
arch/arm/mach-prima2/hotplug.c
arch/arm/mach-pxa/cm-x300.c
arch/arm/mach-pxa/colibri-pxa270-income.c
arch/arm/mach-pxa/devices.c
arch/arm/mach-pxa/ezx.c
arch/arm/mach-pxa/hx4700.c
arch/arm/mach-pxa/icontrol.c
arch/arm/mach-pxa/include/mach/magician.h
arch/arm/mach-pxa/include/mach/pxa27x.h
arch/arm/mach-pxa/lpd270.c
arch/arm/mach-pxa/magician.c
arch/arm/mach-pxa/mainstone.c
arch/arm/mach-pxa/mioa701.c
arch/arm/mach-pxa/palm27x.c
arch/arm/mach-pxa/palmtc.c
arch/arm/mach-pxa/palmte2.c
arch/arm/mach-pxa/pcm990-baseboard.c
arch/arm/mach-pxa/pxa27x.c
arch/arm/mach-pxa/pxa3xx.c
arch/arm/mach-pxa/raumfeld.c
arch/arm/mach-pxa/tavorevb.c
arch/arm/mach-pxa/viper.c
arch/arm/mach-pxa/z2.c
arch/arm/mach-pxa/zylonite.c
arch/arm/mach-qcom/platsmp.c
arch/arm/mach-realview/hotplug.c
arch/arm/mach-s3c24xx/mach-h1940.c
arch/arm/mach-s3c24xx/mach-rx1950.c
arch/arm/mach-s3c64xx/dev-backlight.c
arch/arm/mach-s3c64xx/mach-crag6410.c
arch/arm/mach-s3c64xx/mach-hmt.c
arch/arm/mach-s3c64xx/mach-smartq.c
arch/arm/mach-s3c64xx/mach-smdk6410.c
arch/arm/mach-shmobile/platsmp-apmu.c
arch/arm/mach-shmobile/pm-r8a7779.c
arch/arm/mach-shmobile/pm-rmobile.c
arch/arm/mach-shmobile/r8a7779.h
arch/arm/mach-shmobile/setup-r8a7778.c
arch/arm/mach-spear/hotplug.c
arch/arm/mach-sunxi/sunxi.c
arch/arm/mach-tegra/board-paz00.c
arch/arm/mach-tegra/hotplug.c
arch/arm/mach-ux500/hotplug.c
arch/arm/mach-vexpress/hotplug.c
arch/arm/plat-orion/common.c
arch/arm64/Kconfig.platforms
arch/arm64/boot/dts/arm/juno-motherboard.dtsi
arch/arm64/boot/dts/mediatek/mt8173-evb.dts
arch/arm64/boot/dts/mediatek/mt8173.dtsi
arch/arm64/configs/defconfig
arch/arm64/kernel/debug-monitors.c
arch/arm64/kernel/insn.c
arch/arm64/kernel/psci.c
arch/arm64/kernel/setup.c
arch/arm64/mm/fault.c
arch/h8300/include/asm/Kbuild
arch/mips/include/asm/io.h
arch/mips/include/uapi/asm/swab.h
arch/powerpc/include/asm/Kbuild
arch/powerpc/include/asm/word-at-a-time.h
arch/s390/boot/compressed/Makefile
arch/s390/configs/default_defconfig
arch/s390/configs/gcov_defconfig
arch/s390/configs/performance_defconfig
arch/s390/include/asm/numa.h
arch/s390/include/asm/topology.h
arch/s390/kernel/asm-offsets.c
arch/s390/kernel/entry.S
arch/s390/kernel/vtime.c
arch/s390/numa/mode_emu.c
arch/s390/numa/numa.c
arch/tile/include/asm/Kbuild
arch/tile/include/asm/word-at-a-time.h
arch/x86/Kconfig
arch/x86/include/asm/xen/hypercall.h
arch/x86/xen/enlighten.c
arch/x86/xen/p2m.c
arch/x86/xen/setup.c
drivers/base/power/clock_ops.c
drivers/base/regmap/regmap-debugfs.c
drivers/bus/Kconfig
drivers/bus/Makefile
drivers/bus/arm-ccn.c
drivers/bus/sunxi-rsb.c [new file with mode: 0644]
drivers/clk/Kconfig
drivers/clk/Makefile
drivers/clk/berlin/bg2q.c
drivers/clk/clk-scpi.c [new file with mode: 0644]
drivers/clk/samsung/clk-cpu.c
drivers/clk/shmobile/clk-mstp.c
drivers/clk/sunxi/clk-sunxi.c
drivers/clk/ti/clk-3xxx.c
drivers/clk/ti/clk-7xx.c
drivers/clk/ti/clkt_dflt.c
drivers/clocksource/tcb_clksrc.c
drivers/clocksource/timer-atmel-st.c
drivers/cpufreq/Kconfig.arm
drivers/cpufreq/Makefile
drivers/cpufreq/acpi-cpufreq.c
drivers/cpufreq/cpufreq.c
drivers/cpufreq/scpi-cpufreq.c [new file with mode: 0644]
drivers/devfreq/devfreq.c
drivers/firmware/Kconfig
drivers/firmware/Makefile
drivers/firmware/arm_scpi.c [new file with mode: 0644]
drivers/firmware/psci.c
drivers/firmware/qcom_scm-32.c
drivers/hwmon/Kconfig
drivers/hwmon/Makefile
drivers/hwmon/scpi-hwmon.c [new file with mode: 0644]
drivers/mcb/mcb-pci.c
drivers/md/dm-cache-policy-cleaner.c
drivers/md/dm-exception-store.c
drivers/md/dm-exception-store.h
drivers/md/dm-raid.c
drivers/md/dm-snap-persistent.c
drivers/md/dm-snap-transient.c
drivers/md/dm-snap.c
drivers/md/dm.c
drivers/md/raid1.c
drivers/md/raid10.c
drivers/memory/Kconfig
drivers/memory/omap-gpmc.c
drivers/memory/pl172.c
drivers/misc/atmel_tclib.c
drivers/misc/mei/hbm.c
drivers/mmc/host/omap_hsmmc.c
drivers/mmc/host/sdhci-of-at91.c
drivers/mmc/host/sdhci-pxav3.c
drivers/mmc/host/sdhci.c
drivers/mmc/host/sdhci.h
drivers/mtd/nand/mxc_nand.c
drivers/mtd/nand/sunxi_nand.c
drivers/nvmem/core.c
drivers/nvmem/sunxi_sid.c
drivers/perf/arm_pmu.c
drivers/phy/phy-berlin-sata.c
drivers/phy/phy-qcom-ufs.c
drivers/phy/phy-rockchip-usb.c
drivers/pwm/pwm-atmel-tcb.c
drivers/regulator/axp20x-regulator.c
drivers/regulator/core.c
drivers/scsi/3w-9xxx.c
drivers/scsi/libiscsi.c
drivers/scsi/scsi_dh.c
drivers/soc/Kconfig
drivers/soc/Makefile
drivers/soc/brcmstb/Kconfig [new file with mode: 0644]
drivers/soc/brcmstb/Makefile [new file with mode: 0644]
drivers/soc/brcmstb/biuctrl.c [new file with mode: 0644]
drivers/soc/brcmstb/common.c [new file with mode: 0644]
drivers/soc/mediatek/mtk-pmic-wrap.c
drivers/soc/mediatek/mtk-scpsys.c
drivers/soc/qcom/Kconfig
drivers/soc/qcom/smd-rpm.c
drivers/soc/qcom/smd.c
drivers/soc/qcom/smem.c
drivers/soc/rockchip/Kconfig [new file with mode: 0644]
drivers/soc/rockchip/Makefile [new file with mode: 0644]
drivers/soc/rockchip/pm_domains.c [new file with mode: 0644]
drivers/soc/ti/knav_qmss.h
drivers/soc/ti/knav_qmss_acc.c
drivers/soc/ti/knav_qmss_queue.c
drivers/spi/spi-davinci.c
drivers/staging/speakup/fakekey.c
drivers/thermal/samsung/exynos_tmu.c
drivers/tty/n_tty.c
drivers/tty/serial/8250/8250_port.c
drivers/tty/serial/atmel_serial.c
drivers/tty/serial/imx.c
drivers/tty/tty_buffer.c
drivers/tty/tty_io.c
drivers/usb/core/quirks.c
drivers/usb/gadget/udc/bdc/bdc_ep.c
drivers/usb/misc/chaoskey.c
drivers/usb/renesas_usbhs/common.c
drivers/video/fbdev/broadsheetfb.c
drivers/video/fbdev/fsl-diu-fb.c
drivers/video/fbdev/mb862xx/mb862xxfbdrv.c
drivers/video/fbdev/omap2/displays-new/connector-dvi.c
drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c
drivers/video/fbdev/tridentfb.c
drivers/video/of_display_timing.c
fs/btrfs/disk-io.c
fs/btrfs/export.c
fs/btrfs/extent-tree.c
fs/btrfs/extent_io.c
fs/btrfs/send.c
fs/btrfs/transaction.c
fs/btrfs/transaction.h
fs/cifs/cifsfs.h
fs/cifs/inode.c
fs/cifs/smb2pdu.c
fs/namei.c
fs/nfs/nfs4proc.c
fs/nfs/nfs4state.c
fs/nfs/nfs4trace.h
fs/nfs/write.c
include/linux/atmel_tc.h
include/linux/irqdomain.h
include/linux/mfd/syscon/imx7-iomuxc-gpr.h [new file with mode: 0644]
include/linux/platform_data/atmel.h
include/linux/psci.h
include/linux/qcom_scm.h
include/linux/scpi_protocol.h [new file with mode: 0644]
include/linux/soc/brcmstb/brcmstb.h [new file with mode: 0644]
include/linux/soc/qcom/smd.h
include/linux/soc/qcom/smem.h
include/linux/spi/pxa2xx_spi.h
include/linux/sunxi-rsb.h [new file with mode: 0644]
include/linux/usb/renesas_usbhs.h
include/soc/brcmstb/common.h [new file with mode: 0644]
include/uapi/linux/psci.h
include/xen/interface/sched.h
kernel/irq/handle.c
kernel/sched/core.c
kernel/sched/sched.h
lib/string.c
mm/filemap.c
net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
net/sunrpc/xprtrdma/transport.c
net/sunrpc/xprtrdma/verbs.c
sound/pci/hda/patch_cirrus.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
sound/soc/au1x/db1200.c
sound/soc/codecs/rt5645.c
sound/soc/codecs/rt5645.h
sound/soc/codecs/sgtl5000.c
sound/soc/codecs/tas2552.c
sound/soc/codecs/tlv320aic3x.c
sound/soc/codecs/wm8962.c
sound/soc/dwc/designware_i2s.c
sound/soc/fsl/imx-ssi.c
sound/synth/emux/emux_oss.c
tools/perf/util/Build
tools/perf/util/perf_regs.c
tools/perf/util/perf_regs.h

diff --git a/Documentation/arm/OMAP/README b/Documentation/arm/OMAP/README
new file mode 100644 (file)
index 0000000..75645c4
--- /dev/null
@@ -0,0 +1,7 @@
+This file contains documentation for running mainline
+kernel on omaps.
+
+KERNEL         NEW DEPENDENCIES
+v4.3+          Update is needed for custom .config files to make sure
+               CONFIG_REGULATOR_PBIAS is enabled for MMC1 to work
+               properly.
index df8d4fb85939c82a712e74b6d3987e2598262468..ed494ac0beb2acc0a7a102224cda6e1055c15a3a 100644 (file)
@@ -19,7 +19,7 @@ executing kernel.
 Address:      sysram_ns_base_addr
 Offset        Value                                        Purpose
 =============================================================================
-0x08          exynos_cpu_resume_ns                         System suspend
+0x08          exynos_cpu_resume_ns, mcpm_entry_point       System suspend
 0x0c          0x00000bad (Magic cookie)                    System suspend
 0x1c          exynos4_secondary_startup                    Secondary CPU boot
 0x1c + 4*cpu  exynos4_secondary_startup (Exynos4412)       Secondary CPU boot
@@ -56,7 +56,8 @@ Offset        Value                                        Purpose
 Address:      pmu_base_addr
 Offset        Value                           Purpose
 =============================================================================
-0x0908        Non-zero (only Exynos3250)      Secondary CPU boot up indicator
+0x0908        Non-zero                        Secondary CPU boot up indicator
+                                              on Exynos3250 and Exynos542x
 
 
 4. Glossary
diff --git a/Documentation/arm/keystone/knav-qmss.txt b/Documentation/arm/keystone/knav-qmss.txt
new file mode 100644 (file)
index 0000000..fcdb9fd
--- /dev/null
@@ -0,0 +1,56 @@
+* Texas Instruments Keystone Navigator Queue Management SubSystem driver
+
+Driver source code path
+  drivers/soc/ti/knav_qmss.c
+  drivers/soc/ti/knav_qmss_acc.c
+
+The QMSS (Queue Manager Sub System) found on Keystone SOCs is one of
+the main hardware sub system which forms the backbone of the Keystone
+multi-core Navigator. QMSS consist of queue managers, packed-data structure
+processors(PDSP), linking RAM, descriptor pools and infrastructure
+Packet DMA.
+The Queue Manager is a hardware module that is responsible for accelerating
+management of the packet queues. Packets are queued/de-queued by writing or
+reading descriptor address to a particular memory mapped location. The PDSPs
+perform QMSS related functions like accumulation, QoS, or event management.
+Linking RAM registers are used to link the descriptors which are stored in
+descriptor RAM. Descriptor RAM is configurable as internal or external memory.
+The QMSS driver manages the PDSP setups, linking RAM regions,
+queue pool management (allocation, push, pop and notify) and descriptor
+pool management.
+
+knav qmss driver provides a set of APIs to drivers to open/close qmss queues,
+allocate descriptor pools, map the descriptors, push/pop to queues etc. For
+details of the available APIs, please refers to include/linux/soc/ti/knav_qmss.h
+
+DT documentation is available at
+Documentation/devicetree/bindings/soc/ti/keystone-navigator-qmss.txt
+
+Accumulator QMSS queues using PDSP firmware
+============================================
+The QMSS PDSP firmware support accumulator channel that can monitor a single
+queue or multiple contiguous queues. drivers/soc/ti/knav_qmss_acc.c is the
+driver that interface with the accumulator PDSP. This configures
+accumulator channels defined in DTS (example in DT documentation) to monitor
+1 or 32 queues per channel. More description on the firmware is available in
+CPPI/QMSS Low Level Driver document (docs/CPPI_QMSS_LLD_SDS.pdf) at
+       git://git.ti.com/keystone-rtos/qmss-lld.git
+
+k2_qmss_pdsp_acc48_k2_le_1_0_0_9.bin firmware supports upto 48 accumulator
+channels. This firmware is available under ti-keystone folder of
+firmware.git at
+   git://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git
+
+To use copy the firmware image to lib/firmware folder of the initramfs or
+ubifs file system and provide a sym link to k2_qmss_pdsp_acc48_k2_le_1_0_0_9.bin
+in the file system and boot up the kernel. User would see
+
+ "firmware file ks2_qmss_pdsp_acc48.bin downloaded for PDSP"
+
+in the boot up log if loading of firmware to PDSP is successful.
+
+Use of accumulated queues requires the firmware image to be present in the
+file system. The driver doesn't acc queues to the supported queue range if
+PDSP is not running in the SoC. The API call fails if there is a queue open
+request to an acc queue and PDSP is not running. So make sure to copy firmware
+to file system before using these queue types.
index 5e38e1582f9545a6c82d0252baa4841e91a577d3..430d279a8df374883f5038d0f86961843928f2a7 100644 (file)
@@ -25,7 +25,7 @@ SunXi family
         + Datasheet
           http://dl.linux-sunxi.org/A10s/A10s%20Datasheet%20-%20v1.20%20%282012-03-27%29.pdf
 
-      - Allwinner A13 (sun5i)
+      - Allwinner A13 / R8 (sun5i)
         + Datasheet
          http://dl.linux-sunxi.org/A13/A13%20Datasheet%20-%20v1.12%20%282012-03-29%29.pdf
         + User Manual
index 0d5bc46dc1676869358cd6f36975905031f17f9e..ad6949bff2e392d63e7ddb82391746687ea6235e 100644 (file)
@@ -41,9 +41,13 @@ useless and be disabled, returning errors.  So it is important to monitor
 the amount of free space and expand the <COW device> before it fills up.
 
 <persistent?> is P (Persistent) or N (Not persistent - will not survive
-after reboot).
-The difference is that for transient snapshots less metadata must be
-saved on disk - they can be kept in memory by the kernel.
+after reboot).  O (Overflow) can be added as a persistent store option
+to allow userspace to advertise its support for seeing "Overflow" in the
+snapshot status.  So supported store types are "P", "PO" and "N".
+
+The difference between persistent and transient is with transient
+snapshots less metadata must be saved on disk - they can be kept in
+memory by the kernel.
 
 
 * snapshot-merge <origin> <COW device> <persistent> <chunksize>
diff --git a/Documentation/devicetree/bindings/arm/arm,scpi.txt b/Documentation/devicetree/bindings/arm/arm,scpi.txt
new file mode 100644 (file)
index 0000000..86302de
--- /dev/null
@@ -0,0 +1,188 @@
+System Control and Power Interface (SCPI) Message Protocol
+----------------------------------------------------------
+
+Firmware implementing the SCPI described in ARM document number ARM DUI 0922B
+("ARM Compute Subsystem SCP: Message Interface Protocols")[0] can be used
+by Linux to initiate various system control and power operations.
+
+Required properties:
+
+- compatible : should be "arm,scpi"
+- mboxes: List of phandle and mailbox channel specifiers
+         All the channels reserved by remote SCP firmware for use by
+         SCPI message protocol should be specified in any order
+- shmem : List of phandle pointing to the shared memory(SHM) area between the
+         processors using these mailboxes for IPC, one for each mailbox
+         SHM can be any memory reserved for the purpose of this communication
+         between the processors.
+
+See Documentation/devicetree/bindings/mailbox/mailbox.txt
+for more details about the generic mailbox controller and
+client driver bindings.
+
+Clock bindings for the clocks based on SCPI Message Protocol
+------------------------------------------------------------
+
+This binding uses the common clock binding[1].
+
+Container Node
+==============
+Required properties:
+- compatible : should be "arm,scpi-clocks"
+              All the clocks provided by SCP firmware via SCPI message
+              protocol much be listed as sub-nodes under this node.
+
+Sub-nodes
+=========
+Required properties:
+- compatible : shall include one of the following
+       "arm,scpi-dvfs-clocks" - all the clocks that are variable and index based.
+               These clocks don't provide an entire range of values between the
+               limits but only discrete points within the range. The firmware
+               provides the mapping for each such operating frequency and the
+               index associated with it. The firmware also manages the
+               voltage scaling appropriately with the clock scaling.
+       "arm,scpi-variable-clocks" - all the clocks that are variable and provide full
+               range within the specified range. The firmware provides the
+               range of values within a specified range.
+
+Other required properties for all clocks(all from common clock binding):
+- #clock-cells : Should be 1. Contains the Clock ID value used by SCPI commands.
+- clock-output-names : shall be the corresponding names of the outputs.
+- clock-indices: The identifying number for the clocks(i.e.clock_id) in the
+       node. It can be non linear and hence provide the mapping of identifiers
+       into the clock-output-names array.
+
+SRAM and Shared Memory for SCPI
+-------------------------------
+
+A small area of SRAM is reserved for SCPI communication between application
+processors and SCP.
+
+Required properties:
+- compatible : should be "arm,juno-sram-ns" for Non-secure SRAM on Juno
+
+The rest of the properties should follow the generic mmio-sram description
+found in ../../misc/sysram.txt
+
+Each sub-node represents the reserved area for SCPI.
+
+Required sub-node properties:
+- reg : The base offset and size of the reserved area with the SRAM
+- compatible : should be "arm,juno-scp-shmem" for Non-secure SRAM based
+              shared memory on Juno platforms
+
+Sensor bindings for the sensors based on SCPI Message Protocol
+--------------------------------------------------------------
+SCPI provides an API to access the various sensors on the SoC.
+
+Required properties:
+- compatible : should be "arm,scpi-sensors".
+- #thermal-sensor-cells: should be set to 1. This property follows the
+                        thermal device tree bindings[2].
+
+                        Valid cell values are raw identifiers (Sensor
+                        ID) as used by the firmware. Refer to
+                        platform documentation for your
+                        implementation for the IDs to use. For Juno
+                        R0 and Juno R1 refer to [3].
+
+[0] http://infocenter.arm.com/help/topic/com.arm.doc.dui0922b/index.html
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+[2] Documentation/devicetree/bindings/thermal/thermal.txt
+[3] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0922b/apas03s22.html
+
+Example:
+
+sram: sram@50000000 {
+       compatible = "arm,juno-sram-ns", "mmio-sram";
+       reg = <0x0 0x50000000 0x0 0x10000>;
+
+       #address-cells = <1>;
+       #size-cells = <1>;
+       ranges = <0 0x0 0x50000000 0x10000>;
+
+       cpu_scp_lpri: scp-shmem@0 {
+               compatible = "arm,juno-scp-shmem";
+               reg = <0x0 0x200>;
+       };
+
+       cpu_scp_hpri: scp-shmem@200 {
+               compatible = "arm,juno-scp-shmem";
+               reg = <0x200 0x200>;
+       };
+};
+
+mailbox: mailbox0@40000000 {
+       ....
+       #mbox-cells = <1>;
+};
+
+scpi_protocol: scpi@2e000000 {
+       compatible = "arm,scpi";
+       mboxes = <&mailbox 0 &mailbox 1>;
+       shmem = <&cpu_scp_lpri &cpu_scp_hpri>;
+
+       clocks {
+               compatible = "arm,scpi-clocks";
+
+               scpi_dvfs: scpi_clocks@0 {
+                       compatible = "arm,scpi-dvfs-clocks";
+                       #clock-cells = <1>;
+                       clock-indices = <0>, <1>, <2>;
+                       clock-output-names = "atlclk", "aplclk","gpuclk";
+               };
+               scpi_clk: scpi_clocks@3 {
+                       compatible = "arm,scpi-variable-clocks";
+                       #clock-cells = <1>;
+                       clock-indices = <3>, <4>;
+                       clock-output-names = "pxlclk0", "pxlclk1";
+               };
+       };
+
+       scpi_sensors0: sensors {
+               compatible = "arm,scpi-sensors";
+               #thermal-sensor-cells = <1>;
+       };
+};
+
+cpu@0 {
+       ...
+       reg = <0 0>;
+       clocks = <&scpi_dvfs 0>;
+};
+
+hdlcd@7ff60000 {
+       ...
+       reg = <0 0x7ff60000 0 0x1000>;
+       clocks = <&scpi_clk 4>;
+};
+
+thermal-zones {
+       soc_thermal {
+               polling-delay-passive = <100>;
+               polling-delay = <1000>;
+
+                               /* sensor         ID */
+               thermal-sensors = <&scpi_sensors0 3>;
+               ...
+       };
+};
+
+In the above example, the #clock-cells is set to 1 as required.
+scpi_dvfs has 3 output clocks namely: atlclk, aplclk, and gpuclk with 0,
+1 and 2 as clock-indices. scpi_clk has 2 output clocks namely: pxlclk0
+and pxlclk1 with 3 and 4 as clock-indices.
+
+The first consumer in the example is cpu@0 and it has '0' as the clock
+specifier which points to the first entry in the output clocks of
+scpi_dvfs i.e. "atlclk".
+
+Similarly the second example is hdlcd@7ff60000 and it has pxlclk1 as input
+clock. '4' in the clock specifier here points to the second entry
+in the output clocks of scpi_clocks  i.e. "pxlclk1"
+
+The thermal-sensors property in the soc_thermal node uses the
+temperature sensor provided by SCP firmware to setup a thermal
+zone. The ID "3" is the sensor identifier for the temperature sensor
+as used by the firmware.
index 8dd46617c889afa3f05f1e578ddc34bc76d94cc8..9b5c3f620e65ea348ac57eed59a63c1c61d2e3a0 100644 (file)
@@ -27,6 +27,11 @@ Required properties:
  * For "marvell,armada-380-coherency-fabric", only one pair is needed
    for the per-CPU fabric registers.
 
+Optional properties:
+
+- broken-idle: boolean to set when the Idle mode is not supported by the
+  hardware.
+
 Examples:
 
 coherency-fabric@d0020200 {
diff --git a/Documentation/devicetree/bindings/arm/mvebu-cpu-config.txt b/Documentation/devicetree/bindings/arm/mvebu-cpu-config.txt
new file mode 100644 (file)
index 0000000..2cdcd71
--- /dev/null
@@ -0,0 +1,20 @@
+MVEBU CPU Config registers
+--------------------------
+
+MVEBU (Marvell SOCs: Armada 370/XP)
+
+Required properties:
+
+- compatible: one of:
+       - "marvell,armada-370-cpu-config"
+       - "marvell,armada-xp-cpu-config"
+
+- reg: Should contain CPU config registers location and length, in
+  their per-CPU variant
+
+Example:
+
+       cpu-config@21000 {
+               compatible = "marvell,armada-xp-cpu-config";
+               reg = <0x21000 0x8>;
+       };
index 5aa40ede0e99337d9c66b4b45ccf2cb7c1cd0e93..a9adab84e2feb78596ef9e0b74b3d440c9cf4ff0 100644 (file)
@@ -31,6 +31,10 @@ Main node required properties:
                                        support, but are permitted to be present for compatibility with
                                        existing software when "arm,psci" is later in the compatible list.
 
+                               * "arm,psci-1.0" : for implementations complying to PSCI 1.0. PSCI 1.0 is
+                                       backward compatible with PSCI 0.2 with minor specification updates,
+                                       as defined in the PSCI specification[2].
+
  - method        : The method of calling the PSCI firmware. Permitted
                    values are:
 
@@ -100,3 +104,5 @@ Case 3: PSCI v0.2 and PSCI v0.1.
 
 [1] Kernel documentation - ARM idle states bindings
     Documentation/devicetree/bindings/arm/idle-states.txt
+[2] Power State Coordination Interface (PSCI) specification
+    http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf
index 67da20539540cc4e7725deac8748e70fcce357a5..bb9b0faa919d098309c9eb22289f8cef3b995d9b 100644 (file)
@@ -6,6 +6,7 @@ using one of the following compatible strings:
   allwinner,sun4i-a10
   allwinner,sun5i-a10s
   allwinner,sun5i-a13
+  allwinner,sun5i-r8
   allwinner,sun6i-a31
   allwinner,sun7i-a20
   allwinner,sun8i-a23
diff --git a/Documentation/devicetree/bindings/bus/sunxi-rsb.txt b/Documentation/devicetree/bindings/bus/sunxi-rsb.txt
new file mode 100644 (file)
index 0000000..3dd2834
--- /dev/null
@@ -0,0 +1,47 @@
+Allwinner Reduced Serial Bus (RSB) controller
+
+The RSB controller found on later Allwinner SoCs is an SMBus like 2 wire
+serial bus with 1 master and up to 15 slaves. It is represented by a node
+for the controller itself, and child nodes representing the slave devices.
+
+Required properties :
+
+ - reg             : Offset and length of the register set for the controller.
+ - compatible      : Shall be "allwinner,sun8i-a23-rsb".
+ - interrupts      : The interrupt line associated to the RSB controller.
+ - clocks          : The gate clk associated to the RSB controller.
+ - resets          : The reset line associated to the RSB controller.
+ - #address-cells  : shall be 1
+ - #size-cells     : shall be 0
+
+Optional properties :
+
+ - clock-frequency : Desired RSB bus clock frequency in Hz. Maximum is 20MHz.
+                    If not set this defaults to 3MHz.
+
+Child nodes:
+
+An RSB controller node can contain zero or more child nodes representing
+slave devices on the bus.  Child 'reg' properties should contain the slave
+device's hardware address. The hardware address is hardwired in the device,
+which can normally be found in the datasheet.
+
+Example:
+
+       rsb@01f03400 {
+               compatible = "allwinner,sun8i-a23-rsb";
+               reg = <0x01f03400 0x400>;
+               interrupts = <0 39 4>;
+               clocks = <&apb0_gates 3>;
+               clock-frequency = <3000000>;
+               resets = <&apb0_rst 3>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               pmic@3e3 {
+                       compatible = "...";
+                       reg = <0x3e3>;
+
+                       /* ... */
+               };
+       };
index e6df32f9986df16fd2d25939827fc0213b7aebd1..22b77ee02f58340eca67c7566553a391e11d8461 100644 (file)
@@ -1,8 +1,9 @@
-* Device tree bindings for ARM PL172 MultiPort Memory Controller
+* Device tree bindings for ARM PL172/PL175/PL176 MultiPort Memory Controller
 
 Required properties:
 
-- compatible:          "arm,pl172", "arm,primecell"
+- compatible:          Must be "arm,primecell" and exactly one from
+                       "arm,pl172", "arm,pl175" or "arm,pl176".
 
 - reg:                 Must contains offset/length value for controller.
 
@@ -56,7 +57,8 @@ Optional child cs node config properties:
 
 - mpmc,extended-wait:  Enable extended wait.
 
-- mpmc,buffer-enable:  Enable write buffer.
+- mpmc,buffer-enable:  Enable write buffer, option is not supported by
+                       PL175 and PL176 controllers.
 
 - mpmc,write-protect:  Enable write protect.
 
index c64b7925cd0924e84a9486a6ec27b8421d0782b9..9f78e6c82740cc89ed9556e111a91ad104fe5138 100644 (file)
@@ -24,9 +24,9 @@ Required properties:
 Optional properties:
   - interrupts: Must contain a list of interrupt specifiers for memory
                controller interrupts, if available.
-  - interrupts-names: Must contain a list of interrupt names corresponding to
-                     the interrupts in the interrupts property, if available.
-                     Valid interrupt names are:
+  - interrupt-names: Must contain a list of interrupt names corresponding to
+                    the interrupts in the interrupts property, if available.
+                    Valid interrupt names are:
                        - "sec" (secure interrupt)
                        - "temp" (normal (temperature) interrupt)
   - power-domains: Must contain a reference to the PM domain that the memory
diff --git a/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt b/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt
new file mode 100644 (file)
index 0000000..112756e
--- /dev/null
@@ -0,0 +1,46 @@
+* Rockchip Power Domains
+
+Rockchip processors include support for multiple power domains which can be
+powered up/down by software based on different application scenes to save power.
+
+Required properties for power domain controller:
+- compatible: Should be one of the following.
+       "rockchip,rk3288-power-controller" - for RK3288 SoCs.
+- #power-domain-cells: Number of cells in a power-domain specifier.
+       Should be 1 for multiple PM domains.
+- #address-cells: Should be 1.
+- #size-cells: Should be 0.
+
+Required properties for power domain sub nodes:
+- reg: index of the power domain, should use macros in:
+       "include/dt-bindings/power/rk3288-power.h" - for RK3288 type power domain.
+- clocks (optional): phandles to clocks which need to be enabled while power domain
+       switches state.
+
+Example:
+
+       power: power-controller {
+               compatible = "rockchip,rk3288-power-controller";
+               #power-domain-cells = <1>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               pd_gpu {
+                       reg = <RK3288_PD_GPU>;
+                       clocks = <&cru ACLK_GPU>;
+               };
+       };
+
+Node of a device using power domains must have a power-domains property,
+containing a phandle to the power device node and an index specifying which
+power domain to use.
+The index should use macros in:
+       "include/dt-bindings/power/rk3288-power.h" - for rk3288 type power domain.
+
+Example of the node using power domain:
+
+       node {
+               /* ... */
+               power-domains = <&power RK3288_PD_GPU>;
+               /* ... */
+       };
index d8e8cdb733f96353fb75e4b94917cd6293486ed0..d1ce21a4904dee8aa6f203c3424c047ed247dc14 100644 (file)
@@ -221,7 +221,6 @@ qmss: qmss@2a40000 {
                #size-cells = <1>;
                ranges;
                pdsp0@0x2a10000 {
-                       firmware = "keystone/qmss_pdsp_acc48_k2_le_1_0_0_8.fw";
                        reg = <0x2a10000 0x1000>,
                              <0x2a0f000 0x100>,
                              <0x2a0c000 0x3c8>,
index 8f771441be60556ace93f2b29d87df856882c344..705075da2f10156e92a60828177c8483ee16eeec 100644 (file)
@@ -51,7 +51,7 @@ 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 Gen2)
+                        (default is 64)
 
 Pinctrl properties might be needed, too.  See
 Documentation/devicetree/bindings/pinctrl/renesas,*.
index 64a4ca6cf96ff5bd9df7c3b1c99abd7d086a701c..7d48f63db44ec9b9c0aa68ea0a54a70fc1a7014e 100644 (file)
@@ -5,6 +5,7 @@ Required properties:
        - "renesas,usbhs-r8a7790"
        - "renesas,usbhs-r8a7791"
        - "renesas,usbhs-r8a7794"
+       - "renesas,usbhs-r8a7795"
   - reg: Base address and length of the register for the USBHS
   - interrupts: Interrupt specifier for the USBHS
   - clocks: A list of phandle + clock specifier pairs
diff --git a/Documentation/hwmon/scpi-hwmon b/Documentation/hwmon/scpi-hwmon
new file mode 100644 (file)
index 0000000..4cfcdf2
--- /dev/null
@@ -0,0 +1,33 @@
+Kernel driver scpi-hwmon
+========================
+
+Supported chips:
+ * Chips based on ARM System Control Processor Interface
+   Addresses scanned: -
+   Datasheet: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0922b/index.html
+
+Author: Punit Agrawal <punit.agrawal@arm.com>
+
+Description
+-----------
+
+This driver supports hardware monitoring for SoC's based on the ARM
+System Control Processor (SCP) implementing the System Control
+Processor Interface (SCPI). The following sensor types are supported
+by the SCP -
+
+  * temperature
+  * voltage
+  * current
+  * power
+
+The SCP interface provides an API to query the available sensors and
+their values which are then exported to userspace by this driver.
+
+Usage Notes
+-----------
+
+The driver relies on device tree node to indicate the presence of SCPI
+support in the kernel. See
+Documentation/devicetree/bindings/arm/arm,scpi.txt for details of the
+devicetree node.
\ No newline at end of file
index 3352f97430e4e1132f41b19dd2f00ce93b3846e4..13a0b7fb192f080fd8ad300973483eb2f3b37894 100644 (file)
@@ -22,15 +22,10 @@ Typically a SPI master is defined in the arch/.../mach-*/board-*.c as a
 found in include/linux/spi/pxa2xx_spi.h:
 
 struct pxa2xx_spi_master {
-       u32 clock_enable;
        u16 num_chipselect;
        u8 enable_dma;
 };
 
-The "pxa2xx_spi_master.clock_enable" field is used to enable/disable the
-corresponding SSP peripheral block in the "Clock Enable Register (CKEN"). See
-the "PXA2xx Developer Manual" section "Clocks and Power Management".
-
 The "pxa2xx_spi_master.num_chipselect" field is used to determine the number of
 slave device (chips) attached to this SPI master.
 
@@ -57,7 +52,6 @@ static struct resource pxa_spi_nssp_resources[] = {
 };
 
 static struct pxa2xx_spi_master pxa_nssp_master_info = {
-       .clock_enable = CKEN_NSSP, /* NSSP Peripheral clock */
        .num_chipselect = 1, /* Matches the number of chips attached to NSSP */
        .enable_dma = 1, /* Enables NSSP DMA */
 };
index e729b52b7345e64ef3382eeda6aeb83418c7f4a8..be192ddb6da99c8f76d73ab1d9af7f18e186ee02 100644 (file)
@@ -899,11 +899,12 @@ M:        Lennert Buytenhek <kernel@wantstofly.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 
-ARM/Allwinner A1X SoC support
+ARM/Allwinner sunXi SoC support
 M:     Maxime Ripard <maxime.ripard@free-electrons.com>
+M:     Chen-Yu Tsai <wens@csie.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
-N:     sun[x4567]i
+N:     sun[x456789]i
 
 ARM/Allwinner SoC Clock Support
 M:     Emilio López <emilio@elopez.com.ar>
@@ -922,7 +923,7 @@ M:  Tsahee Zidenberg <tsahee@annapurnalabs.com>
 S:     Maintained
 F:     arch/arm/mach-alpine/
 
-ARM/ATMEL AT91RM9200 AND AT91SAM ARM ARCHITECTURES
+ARM/ATMEL AT91RM9200, AT91SAM9 AND SAMA5 SOC SUPPORT
 M:     Nicolas Ferre <nicolas.ferre@atmel.com>
 M:     Alexandre Belloni <alexandre.belloni@free-electrons.com>
 M:     Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
@@ -1235,6 +1236,13 @@ ARM/LPC18XX ARCHITECTURE
 M:     Joachim Eastwood <manabian@gmail.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
+F:     arch/arm/boot/dts/lpc43*
+F:     drivers/clk/nxp/clk-lpc18xx*
+F:     drivers/clocksource/time-lpc32xx.c
+F:     drivers/i2c/busses/i2c-lpc2k.c
+F:     drivers/memory/pl172.c
+F:     drivers/mtd/spi-nor/nxp-spifi.c
+F:     drivers/rtc/rtc-lpc24xx.c
 N:     lpc18xx
 
 ARM/MAGICIAN MACHINE SUPPORT
@@ -2367,19 +2375,27 @@ L:      linux-scsi@vger.kernel.org
 S:     Supported
 F:     drivers/scsi/bnx2i/
 
-BROADCOM CYGNUS/IPROC ARM ARCHITECTURE
+BROADCOM IPROC ARM ARCHITECTURE
 M:     Ray Jui <rjui@broadcom.com>
 M:     Scott Branden <sbranden@broadcom.com>
+M:     Jon Mason <jonmason@broadcom.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 L:     bcm-kernel-feedback-list@broadcom.com
 T:     git git://github.com/broadcom/cygnus-linux.git
 S:     Maintained
 N:     iproc
 N:     cygnus
+N:     nsp
 N:     bcm9113*
 N:     bcm9583*
-N:     bcm583*
+N:     bcm9585*
+N:     bcm9586*
+N:     bcm988312
 N:     bcm113*
+N:     bcm583*
+N:     bcm585*
+N:     bcm586*
+N:     bcm88312
 
 BROADCOM BRCMSTB GPIO DRIVER
 M:     Gregory Fong <gregory.0xf0@gmail.com>
@@ -4010,7 +4026,7 @@ S:        Maintained
 F:     sound/usb/misc/ua101.c
 
 EXTENSIBLE FIRMWARE INTERFACE (EFI)
-M:     Matt Fleming <matt.fleming@intel.com>
+M:     Matt Fleming <matt@codeblueprint.co.uk>
 L:     linux-efi@vger.kernel.org
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi.git
 S:     Maintained
@@ -4025,7 +4041,7 @@ F:        include/linux/efi*.h
 EFI VARIABLE FILESYSTEM
 M:     Matthew Garrett <matthew.garrett@nebula.com>
 M:     Jeremy Kerr <jk@ozlabs.org>
-M:     Matt Fleming <matt.fleming@intel.com>
+M:     Matt Fleming <matt@codeblueprint.co.uk>
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi.git
 L:     linux-efi@vger.kernel.org
 S:     Maintained
@@ -9160,6 +9176,16 @@ W:       http://www.sunplus.com
 S:     Supported
 F:     arch/score/
 
+SYSTEM CONTROL & POWER INTERFACE (SCPI) Message Protocol drivers
+M:     Sudeep Holla <sudeep.holla@arm.com>
+L:     linux-arm-kernel@lists.infradead.org
+S:     Maintained
+F:     Documentation/devicetree/bindings/arm/arm,scpi.txt
+F:     drivers/clk/clk-scpi.c
+F:     drivers/cpufreq/scpi-cpufreq.c
+F:     drivers/firmware/arm_scpi.c
+F:     include/linux/scpi_protocol.h
+
 SCSI CDROM DRIVER
 M:     Jens Axboe <axboe@kernel.dk>
 L:     linux-scsi@vger.kernel.org
@@ -9921,7 +9947,6 @@ S:        Maintained
 F:     drivers/staging/lustre
 
 STAGING - NVIDIA COMPLIANT EMBEDDED CONTROLLER INTERFACE (nvec)
-M:     Julian Andres Klode <jak@jak-linux.org>
 M:     Marc Dietrich <marvin24@gmx.de>
 L:     ac100@lists.launchpad.net (moderated for non-subscribers)
 L:     linux-tegra@vger.kernel.org
@@ -11385,15 +11410,6 @@ W:     http://oops.ghostprotocols.net:81/blog
 S:     Maintained
 F:     drivers/net/wireless/wl3501*
 
-WM97XX TOUCHSCREEN DRIVERS
-M:     Mark Brown <broonie@kernel.org>
-M:     Liam Girdwood <lrg@slimlogic.co.uk>
-L:     linux-input@vger.kernel.org
-W:     https://github.com/CirrusLogic/linux-drivers/wiki
-S:     Supported
-F:     drivers/input/touchscreen/*wm97*
-F:     include/linux/wm97xx.h
-
 WOLFSON MICROELECTRONICS DRIVERS
 L:     patches@opensource.wolfsonmicro.com
 T:     git https://github.com/CirrusLogic/linux-drivers.git
index fd46821e428d255581680130f4292447b974201c..416660d05739d5a5fe05dcb10b463f883b8c04f2 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
 VERSION = 4
 PATCHLEVEL = 3
 SUBLEVEL = 0
-EXTRAVERSION = -rc4
-NAME = Hurr durr I'ma sheep
+EXTRAVERSION = -rc5
+NAME = Blurry Fish Butt
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
index 6b340d0f1521c3ad9c4edf984abe60982ae24c04..902e6ab00a066fead53614ed86cb88980aea2fba 100644 (file)
@@ -52,4 +52,6 @@ static inline unsigned long find_zero(unsigned long bits)
 #endif
 }
 
+#define zero_bytemask(mask) ((2ul << (find_zero(mask) * 8)) - 1)
+
 #endif /* _ASM_WORD_AT_A_TIME_H */
index 40a3c25c1e0d0f75a50d3b7337c3fa887f4c4a05..259c0ca9c99a8f510410d3b1e9f2dd40707555ca 100644 (file)
@@ -123,29 +123,23 @@ choice
                    0x80020000      | 0xf0020000     | UART8
                    0x80024000      | 0xf0024000     | UART9
 
-       config AT91_DEBUG_LL_DBGU0
-               bool "Kernel low-level debugging on rm9200, 9260/9g20, 9261/9g10, 9rl, 9x5, 9n12"
-               select DEBUG_AT91_UART
+       config DEBUG_AT91_UART
+               bool "Kernel low-level debugging on Atmel SoCs"
                depends on ARCH_AT91
-               depends on SOC_AT91RM9200 || SOC_AT91SAM9
+               help
+                 Say Y here if you want the debug print routines to direct
+                 their output to the serial port on atmel devices.
 
-       config AT91_DEBUG_LL_DBGU1
-               bool "Kernel low-level debugging on 9263, 9g45 and sama5d3"
-               select DEBUG_AT91_UART
-               depends on ARCH_AT91
-               depends on SOC_AT91SAM9 || SOC_SAMA5
+                 SOC                  DEBUG_UART_PHYS   DEBUG_UART_VIRT  PORT
+                 rm9200, 9260/9g20,   0xfffff200        0xfefff200       DBGU
+                 9261/9g10, 9rl
+                 9263, 9g45, sama5d3  0xffffee00        0xfeffee00       DBGU
+                 sama5d4              0xfc00c000        0xfb00c000       USART3
+                 sama5d4              0xfc069000        0xfb069000       DBGU
+                 sama5d2              0xf8020000        0xf7020000       UART1
 
-       config AT91_DEBUG_LL_DBGU2
-               bool "Kernel low-level debugging on sama5d4"
-               select DEBUG_AT91_UART
-               depends on ARCH_AT91
-               depends on SOC_SAMA5
-
-       config AT91_DEBUG_LL_DBGU3
-               bool "Kernel low-level debugging on sama5d2"
-               select DEBUG_AT91_UART
-               depends on ARCH_AT91
-               depends on SOC_SAMA5
+                 Please adjust DEBUG_UART_PHYS configuration options based on
+                 your needs.
 
        config DEBUG_BCM2835
                bool "Kernel low-level debugging on BCM2835 PL011 UART"
@@ -1249,10 +1243,6 @@ choice
 
 endchoice
 
-config DEBUG_AT91_UART
-       bool
-       depends on ARCH_AT91
-
 config DEBUG_EXYNOS_UART
        bool
 
@@ -1485,7 +1475,8 @@ config DEBUG_UART_PHYS
                DEBUG_RMOBILE_SCIFA0 || DEBUG_RMOBILE_SCIFA1 || \
                DEBUG_RMOBILE_SCIFA4 || DEBUG_S3C24XX_UART || \
                DEBUG_UART_BCM63XX || DEBUG_ASM9260_UART || \
-               DEBUG_SIRFSOC_UART || DEBUG_DIGICOLOR_UA0
+               DEBUG_SIRFSOC_UART || DEBUG_DIGICOLOR_UA0 || \
+               DEBUG_AT91_UART
 
 config DEBUG_UART_VIRT
        hex "Virtual base address of debug UART"
diff --git a/arch/arm/arm-soc-for-next-contents.txt b/arch/arm/arm-soc-for-next-contents.txt
new file mode 100644 (file)
index 0000000..779ef7e
--- /dev/null
@@ -0,0 +1,271 @@
+next/fixes-non-critical
+       patch
+               ARM: cns3xxx: pci: avoid potential stack overflow
+       davinci/fixes
+               git://git.kernel.org/pub/scm/linux/kernel/git/nsekhar/linux-davinci tags/davinci-for-v4.4/fixes
+       patch
+               soc: ti: reset irq affinity before freeing irq
+       <no branch> (63f37ddf5c221c5a86ea9e45625bd0381feabc13)
+               http://github.com/Broadcom/stblinux tags/arm-soc/for-4.4/maintainers
+       patch
+               MAINTAINERS: update lpc18xx entry with more drivers
+
+next/cleanup
+       renesas/cleanup
+               git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas tags/renesas-cleanup-for-v4.4
+       efm32/cleanup
+               git://git.pengutronix.de/git/ukl/linux tags/efm32-for-4.4-rc1
+       mvebu/cleanup
+               git://git.infradead.org/linux-mvebu tags/mvebu-cleanup-4.4-1
+       <no branch> (d42f265a5d7a352d40fa2911666cd5236bc3ccaf)
+               git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v4.4/cleanup-pt1
+       renesas/cleanup2
+               git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas tags/renesas-cleanup2-for-v4.4
+       patch
+               ARM: Remove open-coded version of IRQCHIP_DECLARE
+               ARM: Remove __ref on hotplug cpu die path
+       mvebu/cleanup2
+               git://git.infradead.org/linux-mvebu tags/mvebu-cleanup-4.4-2
+       pxa/for-4.4
+               https://github.com/rjarzmik/linux tags/pxa-for-4.4
+
+next/soc
+       renesas/soc
+               git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas tags/renesas-soc-for-v4.4
+               contains renesas/clk
+       at91/soc
+               git://git.kernel.org/pub/scm/linux/kernel/git/nferre/linux-at91 tags/at91-soc
+       patch
+               ARM: meson: Enable Meson8b SoCs
+       mvebu/soc
+               git://git.infradead.org/linux-mvebu tags/mvebu-soc-4.4-1
+       berlin/soc64
+               git://git.infradead.org/users/hesselba/linux-berlin tags/berlin64-soc-for-4.4-1
+       berlin/soc
+               git://git.infradead.org/users/hesselba/linux-berlin tags/berlin-soc-for-4.4-1
+       broadcom/soc
+               http://github.com/Broadcom/stblinux tags/arm-soc/for-4.4/soc
+       <no branch> (045016902bf7abeeb2a86fc9284c30dce228f055)
+               git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone tags/keystone-driver-soc_v2
+       patch
+               ARM: digicolor: select pinctrl/gpio driver
+       berlin/soc2
+               git://git.infradead.org/users/hesselba/linux-berlin tags/berlin-soc-for-4.4-2
+       sunxi/core
+               https://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux tags/sunxi-core-for-4.4
+       mediatek/soc
+               https://github.com/mbgg/linux-mediatek tags/v4.3-next-soc
+       imx/soc
+               git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux tags/imx-soc-4.4
+       at91/soc2
+               git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux tags/at91-ab-soc2
+       tegra/soc
+               git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux tags/tegra-for-4.4-soc
+
+next/boards
+
+next/dt
+       hisi/dt
+               git://github.com/hisilicon/linux-hisi tags/hip05-dt-for-4.3
+       st/dt
+               https://git.kernel.org/pub/scm/linux/kernel/git/mcoquelin/sti tags/sti-dt-for-v4.4-1
+       at91/dt
+               git://git.kernel.org/pub/scm/linux/kernel/git/nferre/linux-at91 tags/at91-dt
+       xgene/dt
+               https://github.com/AppliedMicro/xgene-next tags/xgene-dts-for-v4.4-1
+       socfpga/dt
+               git://git.kernel.org/pub/scm/linux/kernel/git/dinguyen/linux tags/socfpga_dts_for_v4.4
+       patch
+               arm64: dts: add all hi6220 uart nodes
+       renesas/cleanup
+               Merge branch 'renesas/cleanup' into next/dt
+       renesas/dt
+               git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas tags/renesas-dt-for-v4.4
+       patch
+               of: documentation: Add vendor prefix for Tronfy
+               of: documentation: add bindings documentation for Meson8b
+               ARM: meson: Add DTS for Odroid-C1 and Tronfy MXQ boards
+       keystone/dt
+               git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone tags/keystone-dts
+       rockchip/dts32
+               git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip tags/v4.4-rockchip-dts32-1
+       bcm/dt
+               http://github.com/Broadcom/stblinux tags/arm-soc/for-4.4/devicetree
+       mvebu/dt
+               git://git.infradead.org/linux-mvebu tags/mvebu-dt-4.4-1
+       berlin/dt
+               git://git.infradead.org/users/hesselba/linux-berlin tags/berlin-dt-for-4.4-1
+       berlin/dt64
+               git://git.infradead.org/users/hesselba/linux-berlin tags/berlin64-dt-for-4.4-1
+       lpc18xx/dt
+               https://github.com/manabian/linux-lpc tags/lpc18xx_dts_for_4.4
+       sunxi/dt
+               https://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux tags/sunxi-dt-for-4.4
+       patch
+               ARM: meson6: DTS: Fix wrong reg mapping and IRQ numbers
+       hisi/dt2
+               git://github.com/hisilicon/linux-hisi tags/hisi-soc-dt-for-4.4
+       patch
+               ARM64: dts: vexpress: Use a symlink to vexpress-v2m-rs1.dtsi from arch=arm
+       samsung/dt
+               git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung tags/samsung-dt-1
+       patch
+               ARM: dts: uniphier: change the external bus address mapping
+       renesas/dt2
+               git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas tags/renesas-dt2-for-v4.4
+       patch
+               ARM64: juno: add NOR flash to device tree
+       qcom/dt
+               git://codeaurora.org/quic/kernel/agross-msm tags/qcom-dt-for-4.4
+       berlin/dt-cpuclk
+               git://git.infradead.org/users/hesselba/linux-berlin tags/berlin-dt-cpuclk-for-4.4-1
+       omap/dt
+               git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v4.4/dt-pt1
+       keystone/dt2
+               git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone tags/keystone-dts-part2
+       patch
+               ARM: digicolor: add pinctrl module device node
+               ARM: digicolor: dts: add uart pin configuration
+       juno/scpi
+               git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux tags/juno-scpi-for-v4.4
+       <no branch> (00a9e053da0b9e150b7f8fefa3c409d7e71ce48f)
+               git://codeaurora.org/quic/kernel/agross-msm tags/qcom-arm64-for-4.4
+       socfpga/dt2
+               git://git.kernel.org/pub/scm/linux/kernel/git/dinguyen/linux tags/socfpga_dts_for_v4.4_part_2
+       socfpga/dt-cleanup
+               git://git.kernel.org/pub/scm/linux/kernel/git/dinguyen/linux tags/socfpga_for_v4.4_cleanup
+       mvebu/dt2
+               git://git.infradead.org/linux-mvebu tags/mvebu-dt-4.4-2
+       sunxi/dt2
+               https://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux tags/sunxi-dt-for-4.4-2
+       rockchip/dt2
+               git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip tags/v4.4-rockchip-dts32-2
+       mediatek/dt
+               https://github.com/mbgg/linux-mediatek tags/v4.3-next-dts
+       imx/dt
+               git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux tags/imx-dt-4.4
+               contains depends/imx-clk
+       patch
+               ARM: dts: TI-Nspire: fix cpu compatible value
+               ARM: dts: WM8750: fix cpu compatible value
+       sti/dt2
+               https://git.kernel.org/pub/scm/linux/kernel/git/mcoquelin/sti tags/sti-dt-for-v4.4-2
+       patch
+               ARM: dts: uniphier: use stdout-path instead of console
+               ARM: dts: uniphier: add ProXstream2 Gentil board support
+               ARM: dts: uniphier: add ProXstream2 Vodka board support
+       omap/dt2
+               git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v4.4/dt-pt2
+       at91/dt2
+               git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux tags/at91-ab-dt2
+       patch
+               arm64: Use generic Layerscape SoC family naming
+               arm64: Rename FSL LS2085A SoC support code to LS2080A
+               Documentation: DT: Add entry for FSL LS2080A QDS and RDB boards
+               Documentation/dts: Move FSL board-specific bindings out of /powerpc
+               doc/bindings: Update GPIO devicetree binding documentation for LS2080A
+               doc: DTS: Update DWC3 binding to provide reference to generic bindings
+               dts/ls2080a: Update DTSI to add support of various peripherals
+               dts/ls2080a: Remove text about writing to Free Software Foundation
+               dts/ls2080a: Update Simulator DTS to add support of various peripherals
+               dts/ls2080a: Add DTS support for LS2080a QDS & RDB boards
+               dts/Makefile: Add build support for LS2080a QDS & RDB board DTS
+       tegra/dt
+               git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux tags/tegra-for-4.4-dt
+
+next/defconfig
+       renesas/defconfig
+               git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas tags/renesas-defconfig-for-v4.4
+       broadcom/defconfig
+               http://github.com/Broadcom/stblinux tags/arm-soc/for-4.4/defconfig
+       patch
+               ARM: multi_v7_defconfig: Add missing QCOM APQ8064 configs
+               ARM: multi_v7_defconfig: Enable common Rockchip devices/busses
+               ARM: multi_v7_defconfig: Enable common regulators for rockchip boards
+               ARM: multi_v7_defconfig: Enable Rockchip display support
+               ARM: multi_v7_defconfig: Enable the Rockchip USB 2.0 phy
+               ARM: multi_v7_defconfig: Support RTC devices commonly used on Rockchip boards
+       keystone/config
+               git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone tags/keystone-config
+       patch
+               arm64: defconfig: Enable devices for MSM8916
+               ARM: configs: update lpc18xx defconfig
+               ARM: configs: Enable FIXED_PHY in multi_v7 defconfig
+               ARM: multi_v7_defconfig: improve multi_v7_defconfig support for Berlin
+       qcom/defconfig
+               git://codeaurora.org/quic/kernel/agross-msm tags/qcom-defconfig-for-4.4
+       renesas/defconfig2
+               git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas tags/renesas-defconfig2-for-v4.4
+       socfpga/defconfig
+               git://git.kernel.org/pub/scm/linux/kernel/git/dinguyen/linux tags/socfpga_defconfig_for_v4.4
+       mvebu/config
+               git://git.infradead.org/linux-mvebu tags/mvebu-config-4.4-1
+       sunxi/defconfig
+               https://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux tags/sunxi-defconfig-for-4.4
+       imx/defconfig
+               git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux tags/imx-defconfig-4.4
+       at91/defconfig
+               git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux tags/at91-ab-defconfig
+       tegra/defconfig
+               git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux tags/tegra-for-4.4-defconfig
+
+next/drivers
+       renesas/clk
+               git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas tags/renesas-clk-for-v4.4
+       at91/drivers
+               git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux tags/at91-cleanup-4.4
+       rockchip/drivers
+               git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip tags/v4.4-rockchip-drivers1
+       drivers/scpi
+               git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux tags/arm-scpi-for-v4.4
+       drivers/pl172
+               https://github.com/manabian/linux-lpc tags/drivers_pl172_for_4.4
+       berlin/cpuclk
+               git://git.infradead.org/users/hesselba/linux-berlin tags/berlin-new-cpuclk-for-4.4-1
+               contains berlin/dt-cpuclk
+       qcom/soc
+               git://codeaurora.org/quic/kernel/agross-msm tags/qcom-soc-for-4.4
+       patch
+               soc: qcom/smem: add HWSPINLOCK dependency
+       drivers/psci
+               git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux tags/firmware/psci-1.0
+       drivers/psci2
+               Merge branch 'drivers/psci2' into next/drivers
+       rockchip/drivers2
+               git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip tags/v4.4-rockchip-drivers2
+
+next/arm64
+       mediatek/arm64
+               https://github.com/mbgg/linux-mediatek tags/v4.3-next-arm64
+
+next/late
+
+fixes
+       <no branch> (d836ace65ee98d7079bc3c5afdbcc0e27dca20a3)
+               git://git.infradead.org/linux-mvebu tags/mvebu-fixes-4.3-1
+       <no branch> (1f744fd317dc55cadd7132c57c499e3117aea01d)
+               git://git.infradead.org/users/hesselba/linux-berlin tags/berlin-fixes-for-4.3-1
+       <no branch> (178b2d09afc05a46f68b190c6594f3a429bc2385)
+               git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux tags/imx-fixes-4.3-2
+       patch
+               ARM: pxa: fix pxa3xx DFI lockup hack
+               ARM: ux500: modify initial levelshifter status
+               MAINTAINERS: Update Allwinner entry and add new maintainer
+               ARM: meson6: DTS: Fix wrong reg mapping and IRQ numbers
+               bus: arm-ccn: Handle correctly no-more-cpus case
+               bus: arm-ccn: Fix irq affinity setting on CPU migration
+               drivers/perf: arm_pmu: avoid CPU device_node reference leak
+               ARM: dts: uniphier: fix IRQ number for devices on PH1-LD6b ref board
+       <no branch> (d8e1f5ed11a39a68da00f05000466c4f6db4456e)
+               git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v4.3/fixes-rc5
+       patch
+               ARM: tegra: Comment out gpio-ranges properties
+       <no branch> (57df5380853460bc66b59a46273ce113c923d39c)
+               git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v4.3/fixes-rc6
+       <no branch> (b28fec1324bf8f5010d2c3c5d57db4115bda66d4)
+               git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung tags/samsung-fixes-2
+       <no branch> (db347f1a5304d68c68c52f19971924b1e5842f3c)
+               git://git.infradead.org/linux-mvebu tags/mvebu-fixes-4.3-2
+       patch
+               ARM: dts: fix gpio-keys wakeup-source property
+
index 341ec8825c5105f5b9365b5d13aee76cc711f76c..d9ba6b879fc1b25e25f8d006c8b57ab722310c7d 100644 (file)
                                /* SMPS9 unused */
 
                                ldo1_reg: ldo1 {
-                                       /* VDD_SD  */
+                                       /* VDD_SD / VDDSHV8  */
                                        regulator-name = "ldo1";
                                        regulator-min-microvolt = <1800000>;
                                        regulator-max-microvolt = <3300000>;
                                        regulator-boot-on;
+                                       regulator-always-on;
                                };
 
                                ldo2_reg: ldo2 {
index 4de813c236bf9d17eb50c8959a3003b3224a2c9a..acd5b1519edb2be2f4cd58246fba337a7059ffa1 100644 (file)
@@ -46,7 +46,7 @@
 
 / {
        model = "Marvell Armada 385 Access Point Development Board";
-       compatible = "marvell,a385-db-ap", "marvell,armada385", "marvell,armada38x";
+       compatible = "marvell,a385-db-ap", "marvell,armada385", "marvell,armada380";
 
        chosen {
                stdout-path = "serial1:115200n8";
index d996e8b8e130da693fe84039b046e01d40948724..8ea177f375ddd652c98339ac2cc8ef8935396442 100644 (file)
                };
 
                usb_phy2: phy@a2f400 {
-                       compatible = "marvell,berlin2-usb-phy";
+                       compatible = "marvell,berlin2cd-usb-phy";
                        reg = <0xa2f400 0x128>;
                        #phy-cells = <0>;
                        resets = <&chip_rst 0x104 14>;
                };
 
                usb_phy0: phy@b74000 {
-                       compatible = "marvell,berlin2-usb-phy";
+                       compatible = "marvell,berlin2cd-usb-phy";
                        reg = <0xb74000 0x128>;
                        #phy-cells = <0>;
                        resets = <&chip_rst 0x104 12>;
                };
 
                usb_phy1: phy@b78000 {
-                       compatible = "marvell,berlin2-usb-phy";
+                       compatible = "marvell,berlin2cd-usb-phy";
                        reg = <0xb78000 0x128>;
                        #phy-cells = <0>;
                        resets = <&chip_rst 0x104 13>;
index b4031fa4a567610b2a58086f98bddfaf253e77bd..504cf45d3cb8f5238d023ed7f3f0d982eda9a670 100644 (file)
@@ -26,7 +26,7 @@
                };
 
                i2c@4000a000 {
-                       efm32,location = <3>;
+                       energymicro,location = <3>;
                        status = "ok";
 
                        temp@48 {
@@ -43,7 +43,7 @@
 
                spi0: spi@4000c000 { /* USART0 */
                        cs-gpios = <&gpio 68 1>; // E4
-                       location = <1>;
+                       energymicro,location = <1>;
                        status = "ok";
 
                        microsd@0 {
@@ -57,7 +57,7 @@
 
                spi1: spi@4000c400 { /* USART1 */
                        cs-gpios = <&gpio 51 1>; // D3
-                       location = <1>;
+                       energymicro,location = <1>;
                        status = "ok";
 
                        ks8851@0 {
@@ -70,7 +70,7 @@
                };
 
                uart4: uart@4000e400 { /* UART1 */
-                       location = <2>;
+                       energymicro,location = <2>;
                        status = "ok";
                };
 
index 106d505c5d3d816fb096ab6c5e2e23843e134bfd..c747983771c7c504e58970848500cfd132e3c0b9 100644 (file)
@@ -23,7 +23,7 @@
 
        soc {
                adc: adc@40002000 {
-                       compatible = "efm32,adc";
+                       compatible = "energymicro,efm32-adc";
                        reg = <0x40002000 0x400>;
                        interrupts = <7>;
                        clocks = <&cmu clk_HFPERCLKADC0>;
@@ -31,7 +31,7 @@
                };
 
                gpio: gpio@40006000 {
-                       compatible = "efm32,gpio";
+                       compatible = "energymicro,efm32-gpio";
                        reg = <0x40006000 0x1000>;
                        interrupts = <1 11>;
                        gpio-controller;
@@ -45,7 +45,7 @@
                i2c0: i2c@4000a000 {
                        #address-cells = <1>;
                        #size-cells = <0>;
-                       compatible = "efm32,i2c";
+                       compatible = "energymicro,efm32-i2c";
                        reg = <0x4000a000 0x400>;
                        interrupts = <9>;
                        clocks = <&cmu clk_HFPERCLKI2C0>;
@@ -56,7 +56,7 @@
                i2c1: i2c@4000a400 {
                        #address-cells = <1>;
                        #size-cells = <0>;
-                       compatible = "efm32,i2c";
+                       compatible = "energymicro,efm32-i2c";
                        reg = <0x4000a400 0x400>;
                        interrupts = <10>;
                        clocks = <&cmu clk_HFPERCLKI2C1>;
@@ -67,7 +67,7 @@
                spi0: spi@4000c000 { /* USART0 */
                        #address-cells = <1>;
                        #size-cells = <0>;
-                       compatible = "efm32,spi";
+                       compatible = "energymicro,efm32-spi";
                        reg = <0x4000c000 0x400>;
                        interrupts = <3 4>;
                        clocks = <&cmu clk_HFPERCLKUSART0>;
@@ -77,7 +77,7 @@
                spi1: spi@4000c400 { /* USART1 */
                        #address-cells = <1>;
                        #size-cells = <0>;
-                       compatible = "efm32,spi";
+                       compatible = "energymicro,efm32-spi";
                        reg = <0x4000c400 0x400>;
                        interrupts = <15 16>;
                        clocks = <&cmu clk_HFPERCLKUSART1>;
@@ -87,7 +87,7 @@
                spi2: spi@4000c800 { /* USART2 */
                        #address-cells = <1>;
                        #size-cells = <0>;
-                       compatible = "efm32,spi";
+                       compatible = "energymicro,efm32-spi";
                        reg = <0x4000c800 0x400>;
                        interrupts = <18 19>;
                        clocks = <&cmu clk_HFPERCLKUSART2>;
@@ -95,7 +95,7 @@
                };
 
                uart0: uart@4000c000 { /* USART0 */
-                       compatible = "efm32,uart";
+                       compatible = "energymicro,efm32-uart";
                        reg = <0x4000c000 0x400>;
                        interrupts = <3 4>;
                        clocks = <&cmu clk_HFPERCLKUSART0>;
                };
 
                uart1: uart@4000c400 { /* USART1 */
-                       compatible = "efm32,uart";
+                       compatible = "energymicro,efm32-uart";
                        reg = <0x4000c400 0x400>;
                        interrupts = <15 16>;
                        clocks = <&cmu clk_HFPERCLKUSART1>;
                };
 
                uart2: uart@4000c800 { /* USART2 */
-                       compatible = "efm32,uart";
+                       compatible = "energymicro,efm32-uart";
                        reg = <0x4000c800 0x400>;
                        interrupts = <18 19>;
                        clocks = <&cmu clk_HFPERCLKUSART2>;
                };
 
                uart3: uart@4000e000 { /* UART0 */
-                       compatible = "efm32,uart";
+                       compatible = "energymicro,efm32-uart";
                        reg = <0x4000e000 0x400>;
                        interrupts = <20 21>;
                        clocks = <&cmu clk_HFPERCLKUART0>;
                };
 
                uart4: uart@4000e400 { /* UART1 */
-                       compatible = "efm32,uart";
+                       compatible = "energymicro,efm32-uart";
                        reg = <0x4000e400 0x400>;
                        interrupts = <22 23>;
                        clocks = <&cmu clk_HFPERCLKUART1>;
                };
 
                timer0: timer@40010000 {
-                       compatible = "efm32,timer";
+                       compatible = "energymicro,efm32-timer";
                        reg = <0x40010000 0x400>;
                        interrupts = <2>;
                        clocks = <&cmu clk_HFPERCLKTIMER0>;
                };
 
                timer1: timer@40010400 {
-                       compatible = "efm32,timer";
+                       compatible = "energymicro,efm32-timer";
                        reg = <0x40010400 0x400>;
                        interrupts = <12>;
                        clocks = <&cmu clk_HFPERCLKTIMER1>;
                };
 
                timer2: timer@40010800 {
-                       compatible = "efm32,timer";
+                       compatible = "energymicro,efm32-timer";
                        reg = <0x40010800 0x400>;
                        interrupts = <13>;
                        clocks = <&cmu clk_HFPERCLKTIMER2>;
                };
 
                timer3: timer@40010c00 {
-                       compatible = "efm32,timer";
+                       compatible = "energymicro,efm32-timer";
                        reg = <0x40010c00 0x400>;
                        interrupts = <14>;
                        clocks = <&cmu clk_HFPERCLKTIMER3>;
index 955c24ee4a8cbfea89248c2efcb93d9536c0221b..8c24975e8f9d66387b23d9eeb38ab96142609421 100644 (file)
 
                button@1 {
                        debounce_interval = <50>;
-                       wakeup = <1>;
+                       wakeup-source;
                        label = "DSW2-1";
                        linux,code = <KEY_1>;
                        gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;
                };
                button@2 {
                        debounce_interval = <50>;
-                       wakeup = <1>;
+                       wakeup-source;
                        label = "DSW2-2";
                        linux,code = <KEY_2>;
                        gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
                };
                button@3 {
                        debounce_interval = <50>;
-                       wakeup = <1>;
+                       wakeup-source;
                        label = "DSW2-3";
                        linux,code = <KEY_3>;
                        gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>;
                };
                button@4 {
                        debounce_interval = <50>;
-                       wakeup = <1>;
+                       wakeup-source;
                        label = "DSW2-4";
                        linux,code = <KEY_4>;
                        gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>;
index 66da0d1d9d8a0d03c50a825836f026cd78780b6f..0f5dcd418af8f5b3c31286518facdd34a6515bdd 100644 (file)
                                regulator-name = "P1.8V_LDO_OUT10";
                                regulator-min-microvolt = <1800000>;
                                regulator-max-microvolt = <1800000>;
+                               regulator-always-on;
                        };
 
                        ldo11_reg: LDO11 {
index e722c22b2ba9e41bc36f4d584530b881e00da77b..72ba6f032ed72b0e664f42f6dba357dd3b2e9ffd 100644 (file)
        };
 };
 
+&pmu_system_controller {
+       assigned-clocks = <&pmu_system_controller 0>;
+       assigned-clock-parents = <&clock CLK_FIN_PLL>;
+};
+
 &rtc {
        status = "okay";
        clocks = <&clock CLK_RTC>, <&max77802 MAX77802_CLK_32K_AP>;
index df9aee92ecf4d71c714e763665013e7d2f6f4591..1b3d6c769a3cbb37f88fe55914707316abea023c 100644 (file)
                interrupt-parent = <&combiner>;
                interrupts = <3 0>;
                clock-names = "sysmmu", "master";
-               clocks = <&clock CLK_SMMU_FIMD1M0>, <&clock CLK_FIMD1>;
+               clocks = <&clock CLK_SMMU_FIMD1M1>, <&clock CLK_FIMD1>;
                power-domains = <&disp_pd>;
                #iommu-cells = <0>;
        };
index 56275a6f9fca4c9e15e7b5173303972295f52d66..49a4f43e5ac25c8ad16742cca0ccdebf9f9d194c 100644 (file)
        };
 };
 
+&pmu_system_controller {
+       assigned-clocks = <&pmu_system_controller 0>;
+       assigned-clock-parents = <&clock CLK_FIN_PLL>;
+};
+
 &rtc {
        status = "okay";
        clocks = <&clock CLK_RTC>, <&max77802 MAX77802_CLK_32K_AP>;
index 66e47de5e826b0b33aaa6d066aa3c6c3104ff796..96d7eede412e1343d5e4e0a982044cec3ac347d3 100644 (file)
@@ -36,7 +36,7 @@
                pinctrl-0 = <&pinctrl_pmic>;
                reg = <0x08>;
                interrupt-parent = <&gpio5>;
-               interrupts = <23 0x8>;
+               interrupts = <23 IRQ_TYPE_LEVEL_HIGH>;
                regulators {
                        sw1_reg: sw1a {
                                regulator-name = "SW1";
index c3e3ca9362fbb78b6b2ecb8ec0125b83abdb7352..cd170376eaca6be3bc6416363250271590b75153 100644 (file)
@@ -15,6 +15,7 @@
 #include <dt-bindings/clock/imx5-clock.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
 
 / {
        aliases {
index 3373fd958e95c72b098ed14ea2a3228ba7903ea6..a503562438888fe936de6c8b9b255a06a4455d26 100644 (file)
@@ -35,7 +35,6 @@
                        compatible = "regulator-fixed";
                        reg = <1>;
                        pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_usbh1>;
                        regulator-name = "usbh1_vbus";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
@@ -47,7 +46,6 @@
                        compatible = "regulator-fixed";
                        reg = <2>;
                        pinctrl-names = "default";
-                       pinctrl-0 = <&pinctrl_usbotg>;
                        regulator-name = "usb_otg_vbus";
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
index 4ed0eea4cf1d14abfc9dad1d031a6706df1575e1..ebc053a06405e848c773fc9f66c2a779fce5780c 100644 (file)
                                status = "disabled";
                        };
 
-                       uart2: serial@30870000 {
+                       uart2: serial@30890000 {
                                compatible = "fsl,imx7d-uart",
                                             "fsl,imx6q-uart";
-                               reg = <0x30870000 0x10000>;
+                               reg = <0x30890000 0x10000>;
                                interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX7D_UART2_ROOT_CLK>,
                                        <&clks IMX7D_UART2_ROOT_CLK>;
index 91146c318798ff3422f5fecb87ec0d8f0c97df45..5b0430041ec6d1980cb47ba253ce410bcebd05d0 100644 (file)
@@ -12,7 +12,7 @@
 
 / {
        model = "LogicPD Zoom DM3730 Torpedo Development Kit";
-       compatible = "logicpd,dm3730-torpedo-devkit", "ti,omap36xx";
+       compatible = "logicpd,dm3730-torpedo-devkit", "ti,omap3630", "ti,omap3";
 
        gpio_keys {
                compatible = "gpio-keys";
index 16e8ce350ddaae4f4bedc3d86f9d0418e4852f87..bb339d1648e071c4c456a3f627de68f805e1aa9b 100644 (file)
@@ -13,7 +13,7 @@
 
 / {
        model = "TI OMAP37XX EVM (TMDSEVM3730)";
-       compatible = "ti,omap3-evm-37xx", "ti,omap36xx";
+       compatible = "ti,omap3-evm-37xx", "ti,omap3630", "ti,omap3";
 
        memory {
                device_type = "memory";
index 57e6fcab4089e91f1a915f48ab96b0e95d98c435..753bdfddd46ea5d503c8409cc5c035b239efe47c 100644 (file)
                clock-frequency = <19200000>;
        };
 
+       smem {
+               compatible = "qcom,smem";
+
+               memory-region = <&smem_region>;
+               qcom,rpm-msg-ram = <&rpm_msg_ram>;
+
+               hwlocks = <&tcsr_mutex 3>;
+       };
+
        soc: soc {
                #address-cells = <1>;
                #size-cells = <1>;
                        #hwlock-cells = <1>;
                };
 
-               smem@fa00000 {
-                       compatible = "qcom,smem";
-
-                       memory-region = <&smem_region>;
+               rpm_msg_ram: memory@fc428000 {
+                       compatible = "qcom,rpm-msg-ram";
                        reg = <0xfc428000 0x4000>;
-
-                       hwlocks = <&tcsr_mutex 3>;
                };
 
                blsp1_uart2: serial@f991e000 {
index ae5eb281d43a360eb41c79b8c114cd4bdc4f71c1..e07ae5d45e19ffd5e05cb6ce1e6cdcb7c238b649 100644 (file)
                                "mix.0", "mix.1",
                                "dvc.0", "dvc.1",
                                "clk_a", "clk_b", "clk_c", "clk_i";
+               power-domains = <&cpg_clocks>;
 
                status = "disabled";
 
index 3b8e26dde36d08d9fa00b8ad5819ba54496ba389..328f48bd15e711adb729450f4638afb24600bc99 100644 (file)
                                "mix.0", "mix.1",
                                "dvc.0", "dvc.1",
                                "clk_a", "clk_b", "clk_c", "clk_i";
+               power-domains = <&cpg_clocks>;
 
                status = "disabled";
 
index 810cda743b6d56ae19118260367f986dcee690af..9c2387b34d0c73c6942c4051d7f6ce72ee2a0aec 100644 (file)
@@ -56,7 +56,7 @@
                                        /* VMMCI level-shifter enable */
                                        default_hrefv60_cfg2 {
                                                pins = "GPIO169_D22";
-                                               ste,config = <&gpio_out_lo>;
+                                               ste,config = <&gpio_out_hi>;
                                        };
                                        /* VMMCI level-shifter voltage select */
                                        default_hrefv60_cfg3 {
index 32a5ccb14e7ebfbaec118ceed1f3bc14c2b646df..e80e42163883610005287282d9673c80377b6ce4 100644 (file)
 
                button@1 {
                        debounce_interval = <50>;
-                       wakeup = <1>;
+                       wakeup-source;
                        linux,code = <2>;
                        label = "userpb";
                        gpios = <&gpio1 0 0x4>;
                };
                button@2 {
                        debounce_interval = <50>;
-                       wakeup = <1>;
+                       wakeup-source;
                        linux,code = <3>;
                        label = "extkb1";
                        gpios = <&gpio4 23 0x4>;
                };
                button@3 {
                        debounce_interval = <50>;
-                       wakeup = <1>;
+                       wakeup-source;
                        linux,code = <4>;
                        label = "extkb2";
                        gpios = <&gpio4 24 0x4>;
                };
                button@4 {
                        debounce_interval = <50>;
-                       wakeup = <1>;
+                       wakeup-source;
                        linux,code = <5>;
                        label = "extkb3";
                        gpios = <&gpio5 1 0x4>;
                };
                button@5 {
                        debounce_interval = <50>;
-                       wakeup = <1>;
+                       wakeup-source;
                        linux,code = <6>;
                        label = "extkb4";
                        gpios = <&gpio5 2 0x4>;
index 9d4f86e9c50ada156a5ae785399799b23d67efba..d845bd1448b5459f9a6e4ab52c538c541b8832ef 100644 (file)
                gpio-controller;
                #interrupt-cells = <2>;
                interrupt-controller;
+               /*
                gpio-ranges = <&pinmux 0 0 246>;
+               */
        };
 
        apbmisc@70000800 {
index 8aa6e96b5b5c3a75b34c195d9c9f29222a9ad007..68669f791c8baa5ec9fd9d27a37e6ef716006861 100644 (file)
                gpio-controller;
                #interrupt-cells = <2>;
                interrupt-controller;
+               /*
                gpio-ranges = <&pinmux 0 0 251>;
+               */
        };
 
        apbdma: dma@0,60020000 {
index 0a8d1a6c9ebef1b5e03a4d7cca74b362e602769e..33173e1bace9cd289eda8b67679ab0df7d777c9d 100644 (file)
                gpio-controller;
                #interrupt-cells = <2>;
                interrupt-controller;
+               /*
                gpio-ranges = <&pinmux 0 0 224>;
+               */
        };
 
        apbmisc@70000800 {
index 38e1e276bafc4ce3e18dd83b608647fe08229d01..313e260529a31283a4e0c01e0b4ac92b8f102112 100644 (file)
                gpio-controller;
                #interrupt-cells = <2>;
                interrupt-controller;
+               /*
                gpio-ranges = <&pinmux 0 0 248>;
+               */
        };
 
        apbmisc@70000800 {
index 2e36b26f2762d2799895fa493838470bcdd24916..5baa9fc9c8886492b70a63e7b32e0e05b9dd4611 100644 (file)
@@ -83,7 +83,7 @@
 };
 
 &ethsc {
-       interrupts = <0 50 4>;
+       interrupts = <0 52 4>;
 };
 
 &serial0 {
index 090c5b25dbed59d2800a2121675f26f80f9dbf40..1b1e5acd76e2ebd8545f5da91397366b264a989f 100644 (file)
@@ -17,7 +17,6 @@ CONFIG_ARCH_MULTI_V4T=y
 CONFIG_ARCH_MULTI_V5=y
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_AT91=y
-CONFIG_SOC_SAM_V4_V5=y
 CONFIG_SOC_AT91RM9200=y
 CONFIG_SOC_AT91SAM9=y
 CONFIG_AEABI=y
@@ -28,7 +27,6 @@ CONFIG_ARM_APPENDED_DTB=y
 CONFIG_ARM_ATAG_DTB_COMPAT=y
 CONFIG_CMDLINE="console=ttyS0,115200 initrd=0x21100000,25165824 root=/dev/ram0 rw"
 CONFIG_KEXEC=y
-CONFIG_AUTO_ZRELADDR=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 CONFIG_NET=y
 CONFIG_PACKET=y
@@ -43,7 +41,6 @@ CONFIG_IP_PNP_RARP=y
 # CONFIG_INET_XFRM_MODE_TUNNEL is not set
 # CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_DIAG is not set
-CONFIG_IPV6=y
 # CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
 # CONFIG_INET6_XFRM_MODE_TUNNEL is not set
 # CONFIG_INET6_XFRM_MODE_BEET is not set
@@ -119,7 +116,6 @@ CONFIG_LEGACY_PTY_COUNT=4
 CONFIG_SERIAL_ATMEL=y
 CONFIG_SERIAL_ATMEL_CONSOLE=y
 CONFIG_HW_RANDOM=y
-CONFIG_I2C=y
 CONFIG_I2C_AT91=y
 CONFIG_I2C_GPIO=y
 CONFIG_SPI=y
@@ -142,16 +138,12 @@ CONFIG_SOC_CAMERA_OV2640=m
 CONFIG_DRM=y
 CONFIG_DRM_ATMEL_HLCDC=y
 CONFIG_DRM_PANEL_SIMPLE=y
-CONFIG_FB=y
 CONFIG_FB_ATMEL=y
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
 # CONFIG_LCD_CLASS_DEVICE is not set
-CONFIG_BACKLIGHT_CLASS_DEVICE=y
 CONFIG_BACKLIGHT_ATMEL_LCDC=y
 # CONFIG_BACKLIGHT_GENERIC is not set
 CONFIG_BACKLIGHT_PWM=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
 CONFIG_LOGO=y
 CONFIG_SOUND=y
 CONFIG_SND=y
@@ -216,18 +208,11 @@ CONFIG_DEBUG_FS=y
 # CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_FTRACE is not set
 CONFIG_DEBUG_USER=y
-CONFIG_CRYPTO=y
 CONFIG_CRYPTO_ECB=y
-CONFIG_CRYPTO_AES=y
-CONFIG_CRYPTO_ARC4=y
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_USER_API_HASH=m
 CONFIG_CRYPTO_USER_API_SKCIPHER=m
 # CONFIG_CRYPTO_HW is not set
 CONFIG_CRC_CCITT=y
-CONFIG_CRC_ITU_T=y
-CONFIG_CRC7=m
-CONFIG_AVERAGE=y
 CONFIG_FONTS=y
 CONFIG_FONT_8x8=y
 CONFIG_FONT_ACORN_8x8=y
index 79194c60c78c368949a21487b2191f37458d4f10..4187f69f663049ddd2ebbb0f7fdf4b6f95c9172b 100644 (file)
@@ -47,7 +47,6 @@ CONFIG_SOC_VF610=y
 CONFIG_PCI=y
 CONFIG_PCI_IMX6=y
 CONFIG_SMP=y
-CONFIG_VMSPLIT_2G=y
 CONFIG_PREEMPT_VOLUNTARY=y
 CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
@@ -159,6 +158,7 @@ CONFIG_MOUSE_PS2=m
 CONFIG_MOUSE_PS2_ELANTECH=y
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_EGALAX=y
+CONFIG_TOUCHSCREEN_IMX6UL_TSC=y
 CONFIG_TOUCHSCREEN_MC13783=y
 CONFIG_TOUCHSCREEN_TSC2007=y
 CONFIG_TOUCHSCREEN_STMPE=y
index 95ce1284bd42d329205f61a5894fd731aabc678f..5bcc9cf9d8f190cead1e74e7ab8829f5778e2930 100644 (file)
@@ -4,6 +4,12 @@ CONFIG_HIGH_RES_TIMERS=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_BLK_CGROUP=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS_ALL=y
@@ -27,6 +33,7 @@ CONFIG_SMP=y
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
+CONFIG_CMA=y
 CONFIG_VFP=y
 CONFIG_NEON=y
 # CONFIG_SUSPEND is not set
@@ -57,7 +64,6 @@ CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
 CONFIG_IP_PIMSM_V2=y
 CONFIG_INET_AH=y
 CONFIG_INET_IPCOMP=y
-CONFIG_IPV6=y
 CONFIG_INET6_XFRM_MODE_TRANSPORT=m
 CONFIG_INET6_XFRM_MODE_TUNNEL=m
 CONFIG_INET6_XFRM_MODE_BEET=m
@@ -93,7 +99,6 @@ CONFIG_IP_NF_MATCH_ECN=y
 CONFIG_IP_NF_MATCH_TTL=y
 CONFIG_IP_NF_FILTER=y
 CONFIG_IP_NF_TARGET_REJECT=y
-CONFIG_IP_NF_TARGET_ULOG=y
 CONFIG_IP_NF_MANGLE=y
 CONFIG_IP_NF_TARGET_CLUSTERIP=y
 CONFIG_IP_NF_TARGET_ECN=y
@@ -106,7 +111,8 @@ CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP_SCTP=y
 CONFIG_VLAN_8021Q=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_CMA=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_DMA_CMA=y
 CONFIG_MTD=y
 CONFIG_MTD_CMDLINE_PARTS=y
@@ -117,7 +123,6 @@ CONFIG_MTD_NAND=y
 CONFIG_MTD_NAND_DAVINCI=y
 CONFIG_MTD_SPI_NOR=y
 CONFIG_MTD_UBI=y
-CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_EEPROM_AT24=y
 CONFIG_SCSI=y
@@ -125,7 +130,7 @@ CONFIG_BLK_DEV_SD=y
 CONFIG_NETDEVICES=y
 CONFIG_TI_KEYSTONE_NETCP=y
 CONFIG_TI_KEYSTONE_NETCP_ETHSS=y
-CONFIG_PHYLIB=y
+CONFIG_MARVELL_PHY=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_OF_PLATFORM=y
@@ -137,12 +142,15 @@ CONFIG_I2C_DAVINCI=y
 CONFIG_SPI=y
 CONFIG_SPI_DAVINCI=y
 CONFIG_SPI_SPIDEV=y
-# CONFIG_HWMON is not set
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_DAVINCI=y
+CONFIG_GPIO_SYSCON=y
 CONFIG_POWER_SUPPLY=y
 CONFIG_POWER_RESET=y
 CONFIG_POWER_RESET_KEYSTONE=y
+# CONFIG_HWMON is not set
 CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_CORE=y
 CONFIG_DAVINCI_WATCHDOG=y
 CONFIG_USB=y
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
@@ -150,9 +158,15 @@ CONFIG_USB_MON=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_STORAGE=y
 CONFIG_USB_DWC3=y
-CONFIG_USB_DWC3_DEBUG=y
-CONFIG_USB_DWC3_VERBOSE=y
 CONFIG_KEYSTONE_USB_PHY=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_ONESHOT=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_BACKLIGHT=y
+CONFIG_LEDS_TRIGGER_GPIO=y
 CONFIG_DMADEVICES=y
 CONFIG_TI_EDMA=y
 CONFIG_SOC_TI=y
@@ -160,8 +174,11 @@ CONFIG_KEYSTONE_NAVIGATOR_QMSS=y
 CONFIG_KEYSTONE_NAVIGATOR_DMA=y
 CONFIG_MEMORY=y
 CONFIG_TI_AEMIF=y
+CONFIG_KEYSTONE_IRQ=y
 CONFIG_EXT4_FS=y
 CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_FANOTIFY=y
+CONFIG_AUTOFS4_FS=y
 CONFIG_MSDOS_FS=y
 CONFIG_VFAT_FS=y
 CONFIG_NTFS_FS=y
@@ -179,11 +196,10 @@ CONFIG_NFSD_V3_ACL=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ISO8859_1=y
 CONFIG_PRINTK_TIME=y
-CONFIG_DEBUG_SHIRQ=y
 CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_SHIRQ=y
 CONFIG_DEBUG_USER=y
 CONFIG_CRYPTO_USER=y
-CONFIG_CRYPTO_NULL=y
 CONFIG_CRYPTO_AUTHENC=y
 CONFIG_CRYPTO_CBC=y
 CONFIG_CRYPTO_CTR=y
@@ -192,19 +208,3 @@ CONFIG_CRYPTO_DES=y
 CONFIG_CRYPTO_ANSI_CPRNG=y
 CONFIG_CRYPTO_USER_API_HASH=y
 CONFIG_CRYPTO_USER_API_SKCIPHER=y
-CONFIG_GPIOLIB=y
-CONFIG_GPIO_SYSFS=y
-CONFIG_GPIO_DAVINCI=y
-CONFIG_LEDS_CLASS=y
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_GPIO=y
-CONFIG_LEDS_TRIGGERS=y
-CONFIG_LEDS_TRIGGER_ONESHOT=y
-CONFIG_LEDS_TRIGGER_HEARTBEAT=y
-CONFIG_LEDS_TRIGGER_BACKLIGHT=y
-CONFIG_LEDS_TRIGGER_GPIO=y
-CONFIG_KEYSTONE_IRQ=y
-CONFIG_GPIO_SYSCON=y
-CONFIG_TI_DAVINCI_MDIO=y
-CONFIG_MARVELL_PHY=y
-CONFIG_DEVTMPFS=y
index 1c47f86c3970ae926b169e00c642fa853f9f365d..b758a808d31061be6d3998213466e4a7715124b3 100644 (file)
@@ -52,15 +52,22 @@ CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
+CONFIG_MTD_BLOCK=y
 CONFIG_MTD_CFI=y
 CONFIG_MTD_CFI_INTELEXT=y
 CONFIG_MTD_CFI_AMDSTD=y
 CONFIG_MTD_CFI_STAA=y
 CONFIG_MTD_PHYSMAP=y
 CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_MTD_SPI_NOR=y
+# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set
+CONFIG_SPI_NXP_SPIFI=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_SRAM=y
 CONFIG_EEPROM_AT24=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+# CONFIG_SCSI_LOWLEVEL is not set
 CONFIG_NETDEVICES=y
 # CONFIG_NET_VENDOR_ARC is not set
 # CONFIG_NET_CADENCE is not set
@@ -102,14 +109,17 @@ CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_OF_PLATFORM=y
 # CONFIG_HW_RANDOM is not set
 CONFIG_I2C=y
+CONFIG_I2C_LPC2K=y
 CONFIG_SPI=y
 CONFIG_SPI_PL022=y
+CONFIG_GPIOLIB=y
 CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_74XX_MMIO=y
+CONFIG_GPIO_PCF857X=y
+CONFIG_SENSORS_JC42=y
 CONFIG_SENSORS_LM75=y
 CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_CORE=y
-CONFIG_MFD_SYSCON=y
+CONFIG_LPC18XX_WATCHDOG=y
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_FB=y
@@ -117,6 +127,8 @@ CONFIG_FB_ARMCLCD=y
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
+CONFIG_USB_STORAGE=y
 CONFIG_MMC=y
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_IDMAC=y
@@ -128,12 +140,20 @@ CONFIG_LEDS_GPIO=y
 CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_LPC24XX=y
 CONFIG_DMADEVICES=y
 CONFIG_AMBA_PL08X=y
+CONFIG_LPC18XX_DMAMUX=y
+CONFIG_MEMORY=y
+CONFIG_ARM_PL172_MPMC=y
+CONFIG_PWM=y
+CONFIG_PWM_LPC18XX_SCT=y
+CONFIG_PHY_LPC18XX_USB_OTG=y
 CONFIG_EXT2_FS=y
 # CONFIG_FILE_LOCKING is not set
 # CONFIG_DNOTIFY is not set
 # CONFIG_INOTIFY_USER is not set
+CONFIG_JFFS2_FS=y
 # CONFIG_NETWORK_FILESYSTEMS is not set
 CONFIG_PRINTK_TIME=y
 CONFIG_DEBUG_INFO=y
@@ -143,8 +163,6 @@ CONFIG_DEBUG_FS=y
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_SCHED_DEBUG is not set
 # CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_RCU_CPU_STALL_INFO is not set
-# CONFIG_FTRACE is not set
 CONFIG_DEBUG_LL=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_CRC_ITU_T=y
index 03deb7fb35e8999522baceb89fbae066d978f7e3..10dbe3a5acb3ba9d9c531fde8d3f3a697734711e 100644 (file)
@@ -21,10 +21,12 @@ CONFIG_MACH_ARMADA_39X=y
 CONFIG_MACH_ARMADA_XP=y
 CONFIG_MACH_DOVE=y
 CONFIG_ARCH_AT91=y
+CONFIG_SOC_SAMA5D2=y
 CONFIG_SOC_SAMA5D3=y
 CONFIG_SOC_SAMA5D4=y
 CONFIG_ARCH_BCM=y
 CONFIG_ARCH_BCM_CYGNUS=y
+CONFIG_ARCH_BCM_NSP=y
 CONFIG_ARCH_BCM_21664=y
 CONFIG_ARCH_BCM_281XX=y
 CONFIG_ARCH_BCM_5301X=y
@@ -85,7 +87,6 @@ CONFIG_ARCH_R8A7791=y
 CONFIG_ARCH_R8A7793=y
 CONFIG_ARCH_R8A7794=y
 CONFIG_ARCH_SH73A0=y
-CONFIG_MACH_MARZEN=y
 CONFIG_ARCH_SUNXI=y
 CONFIG_ARCH_SIRF=y
 CONFIG_ARCH_TEGRA=y
@@ -153,6 +154,7 @@ CONFIG_CAN_DEV=y
 CONFIG_CAN_AT91=m
 CONFIG_CAN_XILINXCAN=y
 CONFIG_CAN_MCP251X=y
+CONFIG_CAN_SUN4I=y
 CONFIG_BT=m
 CONFIG_BT_MRVL=m
 CONFIG_BT_MRVL_SDIO=m
@@ -207,6 +209,7 @@ CONFIG_NET_CALXEDA_XGMAC=y
 CONFIG_IGB=y
 CONFIG_MV643XX_ETH=y
 CONFIG_MVNETA=y
+CONFIG_PXA168_ETH=m
 CONFIG_KS8851=y
 CONFIG_R8169=y
 CONFIG_SH_ETH=y
@@ -220,6 +223,7 @@ CONFIG_SMSC_PHY=y
 CONFIG_BROADCOM_PHY=y
 CONFIG_ICPLUS_PHY=y
 CONFIG_MICREL_PHY=y
+CONFIG_FIXED_PHY=y
 CONFIG_USB_PEGASUS=y
 CONFIG_USB_USBNET=y
 CONFIG_USB_NET_SMSC75XX=y
@@ -245,6 +249,7 @@ CONFIG_TOUCHSCREEN_ATMEL_MXT=y
 CONFIG_TOUCHSCREEN_ST1232=m
 CONFIG_TOUCHSCREEN_STMPE=y
 CONFIG_TOUCHSCREEN_SUN4I=y
+CONFIG_TOUCHSCREEN_WM97XX=m
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_MPU3050=y
 CONFIG_INPUT_AXP20X_PEK=y
@@ -302,6 +307,7 @@ CONFIG_I2C_GPIO=m
 CONFIG_I2C_EXYNOS5=y
 CONFIG_I2C_MV64XXX=y
 CONFIG_I2C_RIIC=y
+CONFIG_I2C_RK3X=y
 CONFIG_I2C_S3C2410=y
 CONFIG_I2C_SH_MOBILE=y
 CONFIG_I2C_SIRF=y
@@ -318,6 +324,7 @@ CONFIG_SPI_DAVINCI=y
 CONFIG_SPI_OMAP24XX=y
 CONFIG_SPI_ORION=y
 CONFIG_SPI_PL022=y
+CONFIG_SPI_ROCKCHIP=m
 CONFIG_SPI_RSPI=y
 CONFIG_SPI_S3C64XX=m
 CONFIG_SPI_SH_MSIOF=m
@@ -332,6 +339,7 @@ CONFIG_SPI_XILINX=y
 CONFIG_SPI_SPIDEV=y
 CONFIG_PINCTRL_AS3722=y
 CONFIG_PINCTRL_PALMAS=y
+CONFIG_PINCTRL_APQ8064=y
 CONFIG_PINCTRL_APQ8084=y
 CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_GENERIC_PLATFORM=y
@@ -365,6 +373,7 @@ CONFIG_SENSORS_LM95245=y
 CONFIG_SENSORS_NTC_THERMISTOR=m
 CONFIG_THERMAL=y
 CONFIG_CPU_THERMAL=y
+CONFIG_ROCKCHIP_THERMAL=y
 CONFIG_RCAR_THERMAL=y
 CONFIG_ARMADA_THERMAL=y
 CONFIG_DAVINCI_WATCHDOG=m
@@ -382,6 +391,7 @@ CONFIG_MESON_WATCHDOG=y
 CONFIG_DIGICOLOR_WATCHDOG=y
 CONFIG_MFD_AS3711=y
 CONFIG_MFD_AS3722=y
+CONFIG_MFD_ATMEL_FLEXCOM=y
 CONFIG_MFD_BCM590XX=y
 CONFIG_MFD_AXP20X=y
 CONFIG_MFD_CROS_EC=y
@@ -391,6 +401,9 @@ CONFIG_MFD_MAX14577=y
 CONFIG_MFD_MAX77686=y
 CONFIG_MFD_MAX77693=y
 CONFIG_MFD_MAX8907=y
+CONFIG_MFD_RK808=y
+CONFIG_MFD_PM8921_CORE=y
+CONFIG_MFD_QCOM_RPM=y
 CONFIG_MFD_SEC_CORE=y
 CONFIG_MFD_STMPE=y
 CONFIG_MFD_PALMAS=y
@@ -398,11 +411,14 @@ CONFIG_MFD_TPS65090=y
 CONFIG_MFD_TPS6586X=y
 CONFIG_MFD_TPS65910=y
 CONFIG_REGULATOR_AB8500=y
+CONFIG_REGULATOR_ACT8865=y
 CONFIG_REGULATOR_AS3711=y
 CONFIG_REGULATOR_AS3722=y
 CONFIG_REGULATOR_AXP20X=y
 CONFIG_REGULATOR_BCM590XX=y
 CONFIG_REGULATOR_DA9210=y
+CONFIG_REGULATOR_FAN53555=y
+CONFIG_REGULATOR_RK808=y
 CONFIG_REGULATOR_GPIO=y
 CONFIG_MFD_SYSCON=y
 CONFIG_POWER_RESET_SYSCON=y
@@ -415,6 +431,8 @@ CONFIG_REGULATOR_MAX77802=m
 CONFIG_REGULATOR_PALMAS=y
 CONFIG_REGULATOR_PBIAS=y
 CONFIG_REGULATOR_PWM=m
+CONFIG_REGULATOR_QCOM_RPM=y
+CONFIG_REGULATOR_QCOM_SMD_RPM=y
 CONFIG_REGULATOR_S2MPS11=y
 CONFIG_REGULATOR_S5M8767=y
 CONFIG_REGULATOR_TPS51632=y
@@ -441,6 +459,7 @@ CONFIG_VIDEO_RENESAS_VSP1=m
 CONFIG_VIDEO_ADV7180=m
 CONFIG_VIDEO_ML86V7667=m
 CONFIG_DRM=y
+CONFIG_DRM_I2C_ADV7511=m
 # CONFIG_DRM_I2C_CH7006 is not set
 # CONFIG_DRM_I2C_SIL164 is not set
 CONFIG_DRM_NXP_PTN3460=m
@@ -450,7 +469,11 @@ CONFIG_DRM_EXYNOS=m
 CONFIG_DRM_EXYNOS_DSI=y
 CONFIG_DRM_EXYNOS_FIMD=y
 CONFIG_DRM_EXYNOS_HDMI=y
+CONFIG_DRM_ROCKCHIP=m
+CONFIG_ROCKCHIP_DW_HDMI=m
 CONFIG_DRM_RCAR_DU=m
+CONFIG_DRM_RCAR_HDMI=y
+CONFIG_DRM_RCAR_LVDS=y
 CONFIG_DRM_TEGRA=y
 CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0=m
 CONFIG_DRM_PANEL_SIMPLE=y
@@ -485,6 +508,7 @@ CONFIG_SND_SOC_TEGRA=m
 CONFIG_SND_SOC_TEGRA_RT5640=m
 CONFIG_SND_SOC_TEGRA_WM8753=m
 CONFIG_SND_SOC_TEGRA_WM8903=m
+CONFIG_SND_SOC_TEGRA_WM9712=m
 CONFIG_SND_SOC_TEGRA_TRIMSLICE=m
 CONFIG_SND_SOC_TEGRA_ALC5632=m
 CONFIG_SND_SOC_TEGRA_MAX98090=m
@@ -494,6 +518,7 @@ CONFIG_USB=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_MVEBU=y
 CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_MSM=m
 CONFIG_USB_EHCI_EXYNOS=y
 CONFIG_USB_EHCI_TEGRA=y
 CONFIG_USB_EHCI_HCD_STI=y
@@ -514,6 +539,7 @@ CONFIG_KEYSTONE_USB_PHY=y
 CONFIG_OMAP_USB3=y
 CONFIG_USB_GPIO_VBUS=y
 CONFIG_USB_ISP1301=y
+CONFIG_USB_MSM_OTG=m
 CONFIG_USB_MXS_PHY=y
 CONFIG_USB_RCAR_PHY=m
 CONFIG_USB_GADGET=y
@@ -524,6 +550,7 @@ CONFIG_MMC_ARMMMCI=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_SDHCI_OF_ARASAN=y
+CONFIG_MMC_SDHCI_OF_AT91=y
 CONFIG_MMC_SDHCI_ESDHC_IMX=y
 CONFIG_MMC_SDHCI_DOVE=y
 CONFIG_MMC_SDHCI_TEGRA=y
@@ -566,8 +593,10 @@ CONFIG_EDAC_HIGHBANK_L2=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_AS3722=y
 CONFIG_RTC_DRV_DS1307=y
+CONFIG_RTC_DRV_HYM8563=m
 CONFIG_RTC_DRV_MAX8907=y
 CONFIG_RTC_DRV_MAX77686=y
+CONFIG_RTC_DRV_RK808=m
 CONFIG_RTC_DRV_MAX77802=m
 CONFIG_RTC_DRV_RS5C372=m
 CONFIG_RTC_DRV_PALMAS=y
@@ -605,6 +634,7 @@ CONFIG_IMX_SDMA=y
 CONFIG_IMX_DMA=y
 CONFIG_MXS_DMA=y
 CONFIG_DMA_OMAP=y
+CONFIG_QCOM_BAM_DMA=y
 CONFIG_XILINX_VDMA=y
 CONFIG_DMA_SUN6I=y
 CONFIG_STAGING=y
@@ -617,6 +647,9 @@ CONFIG_NVEC_POWER=y
 CONFIG_NVEC_PAZ00=y
 CONFIG_QCOM_GSBI=y
 CONFIG_QCOM_PM=y
+CONFIG_QCOM_SMD=y
+CONFIG_QCOM_SMD_RPM=y
+CONFIG_QCOM_SMEM=y
 CONFIG_COMMON_CLK_QCOM=y
 CONFIG_CHROME_PLATFORMS=y
 CONFIG_CROS_EC_CHARDEV=m
@@ -627,6 +660,8 @@ CONFIG_APQ_MMCC_8084=y
 CONFIG_MSM_GCC_8660=y
 CONFIG_MSM_MMCC_8960=y
 CONFIG_MSM_MMCC_8974=y
+CONFIG_HWSPINLOCK_QCOM=y
+CONFIG_ROCKCHIP_IOMMU=y
 CONFIG_TEGRA_IOMMU_GART=y
 CONFIG_TEGRA_IOMMU_SMMU=y
 CONFIG_PM_DEVFREQ=y
@@ -636,6 +671,7 @@ CONFIG_EXTCON=y
 CONFIG_TI_AEMIF=y
 CONFIG_IIO=y
 CONFIG_AT91_ADC=m
+CONFIG_BERLIN2_ADC=m
 CONFIG_EXYNOS_ADC=m
 CONFIG_XILINX_XADC=y
 CONFIG_AK8975=y
@@ -643,6 +679,7 @@ CONFIG_PWM=y
 CONFIG_PWM_ATMEL=m
 CONFIG_PWM_ATMEL_TCB=m
 CONFIG_PWM_RENESAS_TPU=y
+CONFIG_PWM_ROCKCHIP=m
 CONFIG_PWM_SAMSUNG=m
 CONFIG_PWM_SUN4I=y
 CONFIG_PWM_TEGRA=y
@@ -651,6 +688,10 @@ CONFIG_PHY_HIX5HD2_SATA=y
 CONFIG_PWM_STI=m
 CONFIG_OMAP_USB2=y
 CONFIG_TI_PIPE3=y
+CONFIG_PHY_BERLIN_USB=y
+CONFIG_PHY_BERLIN_SATA=y
+CONFIG_PHY_ROCKCHIP_USB=m
+CONFIG_PHY_QCOM_APQ8064_SATA=m
 CONFIG_PHY_MIPHY28LP=y
 CONFIG_PHY_MIPHY365X=y
 CONFIG_PHY_RCAR_GEN2=m
index 13fcd020e37516cef27c74099c527818c464c4db..c6729bf0a8ddb5e272ee97690cd58c68b013b5fa 100644 (file)
@@ -61,6 +61,7 @@ CONFIG_MTD_SPI_NOR=y
 CONFIG_EEPROM_AT24=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_ATA=y
+CONFIG_SATA_AHCI=y
 CONFIG_AHCI_MVEBU=y
 CONFIG_SATA_MV=y
 CONFIG_NETDEVICES=y
@@ -85,6 +86,9 @@ CONFIG_SPI=y
 CONFIG_SPI_ORION=y
 CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_PCA953X=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_GPIO=y
 CONFIG_SENSORS_GPIO_FAN=y
 CONFIG_THERMAL=y
 CONFIG_ARMADA_THERMAL=y
@@ -111,12 +115,15 @@ CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_SDHCI_DOVE=y
 CONFIG_MMC_SDHCI_PXAV3=y
 CONFIG_MMC_MVSDIO=y
-CONFIG_LEDS_GPIO=y
+CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
 CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DS1307=y
+CONFIG_RTC_DRV_PCF8563=y
 CONFIG_RTC_DRV_S35390A=y
 CONFIG_RTC_DRV_MV=y
 CONFIG_RTC_DRV_ARMADA38X=y
index ff7985ba226ee1dfc3f6cdf6e11e3f570ebcac1d..ee54a706e8a356ba78829b2d8c0fd89d99209d93 100644 (file)
@@ -109,6 +109,7 @@ CONFIG_MFD_QCOM_RPM=y
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_QCOM_RPM=y
+CONFIG_REGULATOR_QCOM_SMD_RPM=y
 CONFIG_MEDIA_SUPPORT=y
 CONFIG_FB=y
 CONFIG_SOUND=y
@@ -145,16 +146,17 @@ CONFIG_MSM_GCC_8660=y
 CONFIG_MSM_LCC_8960=y
 CONFIG_MSM_MMCC_8960=y
 CONFIG_MSM_MMCC_8974=y
-CONFIG_MSM_IOMMU=y
+CONFIG_HWSPINLOCK_QCOM=y
 CONFIG_QCOM_GSBI=y
 CONFIG_QCOM_PM=y
+CONFIG_QCOM_SMD=y
+CONFIG_QCOM_SMD_RPM=y
+CONFIG_QCOM_SMEM=y
 CONFIG_PHY_QCOM_APQ8064_SATA=y
 CONFIG_PHY_QCOM_IPQ806X_SATA=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT3_FS=y
-# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-CONFIG_EXT4_FS=y
 CONFIG_FUSE_FS=y
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
index 31eb951880aee1f6d1fd879071134b2bd83490a0..a0c57ac88b2756c0a4cdf0b9758e4df65d975833 100644 (file)
@@ -10,12 +10,11 @@ CONFIG_MODULES=y
 CONFIG_MODULE_FORCE_LOAD=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
 CONFIG_ARCH_AT91=y
-CONFIG_SOC_SAM_V7=y
+CONFIG_SOC_SAMA5D2=y
 CONFIG_SOC_SAMA5D3=y
 CONFIG_SOC_SAMA5D4=y
 CONFIG_AEABI=y
@@ -25,12 +24,10 @@ CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_ARM_APPENDED_DTB=y
 CONFIG_CMDLINE="console=ttyS0,115200 initrd=0x21100000,25165824 root=/dev/ram0 rw"
 CONFIG_KEXEC=y
-CONFIG_AUTO_ZRELADDR=y
 CONFIG_VFP=y
 CONFIG_NEON=y
 CONFIG_KERNEL_MODE_NEON=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-CONFIG_PM=y
 CONFIG_PM_DEBUG=y
 CONFIG_PM_ADVANCED_DEBUG=y
 CONFIG_NET=y
@@ -47,7 +44,6 @@ CONFIG_IP_PNP_RARP=y
 # CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_LRO is not set
 # CONFIG_INET_DIAG is not set
-CONFIG_IPV6=y
 # CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
 # CONFIG_INET6_XFRM_MODE_TUNNEL is not set
 # CONFIG_INET6_XFRM_MODE_BEET is not set
@@ -123,7 +119,6 @@ CONFIG_LEGACY_PTY_COUNT=4
 CONFIG_SERIAL_ATMEL=y
 CONFIG_SERIAL_ATMEL_CONSOLE=y
 CONFIG_HW_RANDOM=y
-CONFIG_I2C=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_AT91=y
 CONFIG_I2C_GPIO=y
@@ -135,6 +130,7 @@ CONFIG_POWER_SUPPLY=y
 CONFIG_POWER_RESET=y
 # CONFIG_HWMON is not set
 CONFIG_SSB=m
+CONFIG_MFD_ATMEL_FLEXCOM=y
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_ACT8865=y
@@ -142,8 +138,8 @@ CONFIG_MEDIA_SUPPORT=y
 CONFIG_MEDIA_CAMERA_SUPPORT=y
 CONFIG_V4L_PLATFORM_DRIVERS=y
 CONFIG_SOC_CAMERA=y
-CONFIG_SOC_CAMERA_OV2640=y
 CONFIG_VIDEO_ATMEL_ISI=y
+CONFIG_SOC_CAMERA_OV2640=y
 CONFIG_FB=y
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 # CONFIG_LCD_CLASS_DEVICE is not set
@@ -171,6 +167,9 @@ CONFIG_USB_ATMEL_USBA=y
 CONFIG_USB_G_SERIAL=y
 CONFIG_MMC=y
 # CONFIG_MMC_BLOCK_BOUNCE is not set
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_OF_AT91=y
 CONFIG_MMC_ATMELMCI=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
@@ -207,11 +206,8 @@ CONFIG_DEBUG_MEMORY_INIT=y
 # CONFIG_SCHED_DEBUG is not set
 # CONFIG_FTRACE is not set
 CONFIG_DEBUG_USER=y
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_USER_API_HASH=m
 CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_DEV_ATMEL_AES=y
 CONFIG_CRYPTO_DEV_ATMEL_TDES=y
 CONFIG_CRYPTO_DEV_ATMEL_SHA=y
-CONFIG_CRC_CCITT=m
-CONFIG_CRC_ITU_T=m
index 89bf31ccfbfa1b269ce4b3e9c66c7053b7edcfb0..3aef019c0de7897de8c83d6a062218eaeb69deb0 100644 (file)
@@ -21,7 +21,6 @@ CONFIG_ARCH_R8A7791=y
 CONFIG_ARCH_R8A7793=y
 CONFIG_ARCH_R8A7794=y
 CONFIG_ARCH_SH73A0=y
-CONFIG_MACH_MARZEN=y
 CONFIG_CPU_BPREDICT_DISABLE=y
 CONFIG_PL310_ERRATA_588369=y
 CONFIG_ARM_ERRATA_754322=y
@@ -141,7 +140,10 @@ CONFIG_VIDEO_RENESAS_VSP1=y
 CONFIG_VIDEO_ADV7180=y
 CONFIG_VIDEO_ML86V7667=y
 CONFIG_DRM=y
+CONFIG_DRM_I2C_ADV7511=y
 CONFIG_DRM_RCAR_DU=y
+CONFIG_DRM_RCAR_HDMI=y
+CONFIG_DRM_RCAR_LVDS=y
 CONFIG_FB_SH_MOBILE_LCDC=y
 CONFIG_FB_SH_MOBILE_MERAM=y
 # CONFIG_LCD_CLASS_DEVICE is not set
index a2956c3112f14abd66c5ed586d621d8e7dd548b8..8128b93ed72cf8cc11c765a74c4615e9944f1b28 100644 (file)
@@ -86,6 +86,8 @@ CONFIG_USB_DWC2=y
 CONFIG_USB_DWC2_HOST=y
 CONFIG_MMC=y
 CONFIG_MMC_DW=y
+CONFIG_FPGA=y
+CONFIG_FPGA_MGR_SOCFPGA=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_POSIX_ACL=y
index 51eea220baae4be2d68ae036f8d39739ec6a9c5a..3c36e16fcacf7d44f7e8ce76f32a2cbc20f2b1d4 100644 (file)
@@ -5,6 +5,7 @@ CONFIG_CGROUPS=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_PERF_EVENTS=y
 CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
 CONFIG_ARCH_SUNXI=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=8
@@ -31,6 +32,8 @@ CONFIG_IP_PNP_BOOTP=y
 # CONFIG_INET_LRO is not set
 # CONFIG_INET_DIAG is not set
 # CONFIG_IPV6 is not set
+CONFIG_CAN=y
+CONFIG_CAN_SUN4I=y
 # CONFIG_WIRELESS is not set
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
@@ -63,6 +66,7 @@ CONFIG_STMMAC_ETH=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_AXP20X_PEK=y
 CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_KEYBOARD_SUN4I_LRADC=y
 CONFIG_TOUCHSCREEN_SUN4I=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
index 9808581176cc81790913c024e625b648a3650c68..3a36244e3cf68c2fb238f41f35130799b78211c4 100644 (file)
@@ -1,5 +1,6 @@
 CONFIG_SYSVIPC=y
 CONFIG_FHANDLE=y
+CONFIG_IRQ_DOMAIN_DEBUG=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_IKCONFIG=y
@@ -60,7 +61,6 @@ CONFIG_INET_ESP=y
 # CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_LRO is not set
 # CONFIG_INET_DIAG is not set
-CONFIG_IPV6=y
 CONFIG_IPV6_ROUTER_PREF=y
 CONFIG_IPV6_OPTIMISTIC_DAD=y
 CONFIG_INET6_AH=y
@@ -121,6 +121,9 @@ CONFIG_KEYBOARD_CROS_EC=y
 CONFIG_MOUSE_PS2_ELANTECH=y
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ATMEL_MXT=y
+CONFIG_TOUCHSCREEN_WM97XX=y
+# CONFIG_TOUCHSCREEN_WM9705 is not set
+# CONFIG_TOUCHSCREEN_WM9713 is not set
 CONFIG_TOUCHSCREEN_STMPE=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_MPU3050=y
@@ -142,6 +145,7 @@ CONFIG_SPI_TEGRA20_SFLASH=y
 CONFIG_SPI_TEGRA20_SLINK=y
 CONFIG_PINCTRL_AS3722=y
 CONFIG_PINCTRL_PALMAS=y
+CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_PCA953X=y
 CONFIG_GPIO_PCA953X_IRQ=y
 CONFIG_GPIO_PALMAS=y
@@ -208,6 +212,7 @@ CONFIG_SND_SOC_TEGRA=y
 CONFIG_SND_SOC_TEGRA_RT5640=y
 CONFIG_SND_SOC_TEGRA_WM8753=y
 CONFIG_SND_SOC_TEGRA_WM8903=y
+CONFIG_SND_SOC_TEGRA_WM9712=y
 CONFIG_SND_SOC_TEGRA_TRIMSLICE=y
 CONFIG_SND_SOC_TEGRA_ALC5632=y
 CONFIG_SND_SOC_TEGRA_MAX98090=y
@@ -266,10 +271,8 @@ CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_POSIX_ACL=y
 CONFIG_EXT2_FS_SECURITY=y
 CONFIG_EXT3_FS=y
-# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 CONFIG_EXT3_FS_POSIX_ACL=y
 CONFIG_EXT3_FS_SECURITY=y
-CONFIG_EXT4_FS=y
 # CONFIG_DNOTIFY is not set
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
@@ -278,6 +281,7 @@ CONFIG_SQUASHFS=y
 CONFIG_SQUASHFS_LZO=y
 CONFIG_SQUASHFS_XZ=y
 CONFIG_NFS_FS=y
+CONFIG_NFS_V4=y
 CONFIG_ROOT_NFS=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ISO8859_1=y
index 2556a8801c8cb973750391715878c79519197376..43243be94cfcb556d1a3a0e85f6a63089d8c89c2 100644 (file)
@@ -9,32 +9,22 @@
  *
 */
 
-#if defined(CONFIG_AT91_DEBUG_LL_DBGU0)
-#define AT91_DBGU 0xfffff200 /* AT91_BASE_DBGU0 */
-#elif defined(CONFIG_AT91_DEBUG_LL_DBGU1)
-#define AT91_DBGU 0xffffee00 /* AT91_BASE_DBGU1 */
-#elif defined(CONFIG_AT91_DEBUG_LL_DBGU2)
-/* On sama5d4, use USART3 as low level serial console */
-#define AT91_DBGU 0xfc00c000 /* SAMA5D4_BASE_USART3 */
-#else
-/* On sama5d2, use UART1 as low level serial console */
-#define AT91_DBGU 0xf8020000
-#endif
-
 #ifdef CONFIG_MMU
 #define AT91_IO_P2V(x) ((x) - 0x01000000)
 #else
 #define AT91_IO_P2V(x) (x)
 #endif
 
+#define CONFIG_DEBUG_UART_VIRT AT91_IO_P2V(CONFIG_DEBUG_UART_PHYS)
+
 #define AT91_DBGU_SR           (0x14)  /* Status Register */
 #define AT91_DBGU_THR          (0x1c)  /* Transmitter Holding Register */
 #define AT91_DBGU_TXRDY                (1 << 1)        /* Transmitter Ready */
 #define AT91_DBGU_TXEMPTY      (1 << 9)        /* Transmitter Empty */
 
        .macro  addruart, rp, rv, tmp
-       ldr     \rp, =AT91_DBGU                         @ System peripherals (phys address)
-       ldr     \rv, =AT91_IO_P2V(AT91_DBGU)            @ System peripherals (virt address)
+       ldr     \rp, =CONFIG_DEBUG_UART_PHYS            @ System peripherals (phys address)
+       ldr     \rv, =CONFIG_DEBUG_UART_VIRT            @ System peripherals (virt address)
        .endm
 
        .macro  senduart,rd,rx
index 61c04b02faebb009bf2d481cd5b651b79242f79c..9d479b2ea40dc016bda2a0d74e194d36859ceb37 100644 (file)
@@ -71,7 +71,7 @@ int psci_cpu_disable(unsigned int cpu)
        return 0;
 }
 
-void __ref psci_cpu_die(unsigned int cpu)
+void psci_cpu_die(unsigned int cpu)
 {
        u32 state = PSCI_POWER_STATE_TYPE_POWER_DOWN <<
                    PSCI_0_2_POWER_STATE_TYPE_SHIFT;
@@ -83,7 +83,7 @@ void __ref psci_cpu_die(unsigned int cpu)
        panic("psci: cpu %d failed to shutdown\n", cpu);
 }
 
-int __ref psci_cpu_kill(unsigned int cpu)
+int psci_cpu_kill(unsigned int cpu)
 {
        int err, i;
 
index 0d95f488b47a7fa40f7f837083e5b594c329dd65..a25defda3d226c98469c6150a001266aeec4c2fa 100644 (file)
@@ -80,6 +80,8 @@ tmp2  .req    r5
  *     @r2: base address of second SDRAM Controller or 0 if not present
  *     @r3: pm information
  */
+/* at91_pm_suspend_in_sram must be 8-byte aligned per the requirements of fncpy() */
+       .align 3
 ENTRY(at91_pm_suspend_in_sram)
        /* Save registers on stack */
        stmfd   sp!, {r4 - r12, lr}
index 1319c3c14327864366e396ed93516732ff6453a5..0be09af9dec724aec2ed818959753cebf84f85fe 100644 (file)
@@ -35,6 +35,20 @@ config ARCH_BCM_CYGNUS
          BCM11300, BCM11320, BCM11350, BCM11360,
          BCM58300, BCM58302, BCM58303, BCM58305.
 
+config ARCH_BCM_NSP
+       bool "Broadcom Northstar Plus SoC Support" if ARCH_MULTI_V7
+       select ARCH_BCM_IPROC
+       select ARM_ERRATA_754322
+       select ARM_ERRATA_775420
+       help
+         Support for Broadcom Northstar Plus SoC.
+         Broadcom Northstar Plus family of SoCs are used for switching control
+         and management applications as well as residential router/gateway
+         applications. The SoC features dual core Cortex A9 ARM CPUs,
+         integrating several peripheral interfaces including multiple Gigabit
+         Ethernet PHYs, DDR3 memory, PCIE Gen-2, USB 2.0 and USB 3.0, serial and
+         NAND flash, SATA and several other IO controllers.
+
 config ARCH_BCM_5301X
        bool "Broadcom BCM470X / BCM5301X ARM SoC" if ARCH_MULTI_V7
        select ARCH_BCM_IPROC
@@ -147,6 +161,7 @@ config ARCH_BRCMSTB
        select BCM7120_L2_IRQ
        select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
        select ARCH_WANT_OPTIONAL_GPIOLIB
+       select SOC_BRCMSTB
        help
          Say Y if you intend to run the kernel on a Broadcom ARM-based STB
          chipset.
index 1780a3ff42f938f3998e2ad0803ab161c32367a0..892261fec0ae7febff91c35a3b8c1aab12b3196a 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2012-2014 Broadcom Corporation
+# Copyright (C) 2012-2015 Broadcom Corporation
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
@@ -13,6 +13,9 @@
 # Cygnus
 obj-$(CONFIG_ARCH_BCM_CYGNUS) +=  bcm_cygnus.o
 
+# Northstar Plus
+obj-$(CONFIG_ARCH_BCM_NSP) += bcm_nsp.o
+
 # BCM281XX
 obj-$(CONFIG_ARCH_BCM_281XX)   += board_bcm281xx.o
 
diff --git a/arch/arm/mach-bcm/bcm_nsp.c b/arch/arm/mach-bcm/bcm_nsp.c
new file mode 100644 (file)
index 0000000..a1101a3
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2015 Broadcom 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.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <asm/mach/arch.h>
+
+static const char *const bcm_nsp_dt_compat[] __initconst = {
+       "brcm,nsp",
+       NULL,
+};
+
+DT_MACHINE_START(NSP_DT, "Broadcom Northstar Plus SoC")
+       .l2c_aux_val    = 0,
+       .l2c_aux_mask   = ~0,
+       .dt_compat = bcm_nsp_dt_compat,
+MACHINE_END
index 3a60f7ee3f0cc1583788f9cd3da81a5723354647..99a67cfb7c0d5c129dfad0ec721ba24e402171fd 100644 (file)
  */
 
 #include <linux/init.h>
+#include <linux/irqchip.h>
 #include <linux/of_platform.h>
+#include <linux/soc/brcmstb/brcmstb.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
+static void __init brcmstb_init_irq(void)
+{
+       irqchip_init();
+       brcmstb_biuctrl_init();
+}
+
 static const char *const brcmstb_match[] __initconst = {
        "brcm,bcm7445",
        "brcm,brcmstb",
@@ -25,4 +33,5 @@ static const char *const brcmstb_match[] __initconst = {
 
 DT_MACHINE_START(BRCMSTB, "Broadcom STB (Flattened Device Tree)")
        .dt_compat      = brcmstb_match,
+       .init_irq       = brcmstb_init_irq,
 MACHINE_END
index ac181c6797ee5784c2f64d80ea1b1f4b2d0fc3b1..25d73870cccad498e98eab1c4a43666a36fbaa9c 100644 (file)
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/mach/arch.h>
 
+static void __init berlin_init_late(void)
+{
+       platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
+}
+
 static const char * const berlin_dt_compat[] = {
        "marvell,berlin",
        NULL,
@@ -25,6 +30,7 @@ static const char * const berlin_dt_compat[] = {
 
 DT_MACHINE_START(BERLIN_DT, "Marvell Berlin")
        .dt_compat      = berlin_dt_compat,
+       .init_late      = berlin_init_late,
        /*
         * with DT probing for L2CCs, berlin_init_machine can be removed.
         * Note: 88DE3005 (Armada 1500-mini) uses pl310 l2cc
index 34a3753e73564ed99cf92bbaee7c94ed5a869acb..405cd37e4fba59d1010b14e1e1e11db069ef75b8 100644 (file)
 #include <linux/of_address.h>
 
 #include <asm/cacheflush.h>
+#include <asm/cp15.h>
 #include <asm/smp_plat.h>
 #include <asm/smp_scu.h>
 
-#define CPU_RESET              0x00
+/*
+ * There are two reset registers, one with self-clearing (SC)
+ * reset and one with non-self-clearing reset (NON_SC).
+ */
+#define CPU_RESET_SC           0x00
+#define CPU_RESET_NON_SC       0x20
 
 #define RESET_VECT             0x00
 #define SW_RESET_ADDR          0x94
@@ -30,9 +36,11 @@ static inline void berlin_perform_reset_cpu(unsigned int cpu)
 {
        u32 val;
 
-       val = readl(cpu_ctrl + CPU_RESET);
+       val = readl(cpu_ctrl + CPU_RESET_NON_SC);
+       val &= ~BIT(cpu_logical_map(cpu));
+       writel(val, cpu_ctrl + CPU_RESET_NON_SC);
        val |= BIT(cpu_logical_map(cpu));
-       writel(val, cpu_ctrl + CPU_RESET);
+       writel(val, cpu_ctrl + CPU_RESET_NON_SC);
 }
 
 static int berlin_boot_secondary(unsigned int cpu, struct task_struct *idle)
@@ -91,8 +99,32 @@ unmap_scu:
        iounmap(scu_base);
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
+static void berlin_cpu_die(unsigned int cpu)
+{
+       v7_exit_coherency_flush(louis);
+       while (1)
+               cpu_do_idle();
+}
+
+static int berlin_cpu_kill(unsigned int cpu)
+{
+       u32 val;
+
+       val = readl(cpu_ctrl + CPU_RESET_NON_SC);
+       val &= ~BIT(cpu_logical_map(cpu));
+       writel(val, cpu_ctrl + CPU_RESET_NON_SC);
+
+       return 1;
+}
+#endif
+
 static struct smp_operations berlin_smp_ops __initdata = {
        .smp_prepare_cpus       = berlin_smp_prepare_cpus,
        .smp_boot_secondary     = berlin_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+       .cpu_die                = berlin_cpu_die,
+       .cpu_kill               = berlin_cpu_kill,
+#endif
 };
 CPU_METHOD_OF_DECLARE(berlin_smp, "marvell,berlin-smp", &berlin_smp_ops);
index c622c306c390719f95cfac1eb8b3eff46f38c340..47905a50e0757e94c1300ec98a3924d9a51b7a5b 100644 (file)
@@ -65,8 +65,9 @@ static void __iomem *cns3xxx_pci_map_bus(struct pci_bus *bus,
 
        /*
         * The CNS PCI bridge doesn't fit into the PCI hierarchy, though
-        * we still want to access it. For this to work, we must place
-        * the first device on the same bus as the CNS PCI bridge.
+        * we still want to access it.
+        * We place the host bridge on bus 0, and the directly connected
+        * device on bus 1, slot 0.
         */
        if (busno == 0) { /* internal PCIe bus, host bridge device */
                if (devfn == 0) /* device# and function# are ignored by hw */
@@ -211,58 +212,46 @@ static void __init cns3xxx_pcie_check_link(struct cns3xxx_pcie *cnspci)
        }
 }
 
+static void cns3xxx_write_config(struct cns3xxx_pcie *cnspci,
+                                        int where, int size, u32 val)
+{
+       void __iomem *base = cnspci->host_regs + (where & 0xffc);
+       u32 v;
+       u32 mask = (0x1ull << (size * 8)) - 1;
+       int shift = (where % 4) * 8;
+
+       v = readl_relaxed(base + (where & 0xffc));
+
+       v &= ~(mask << shift);
+       v |= (val & mask) << shift;
+
+       writel_relaxed(v, base + (where & 0xffc));
+       readl_relaxed(base + (where & 0xffc));
+}
+
 static void __init cns3xxx_pcie_hw_init(struct cns3xxx_pcie *cnspci)
 {
-       int port = cnspci->port;
-       struct pci_sys_data sd = {
-               .private_data = cnspci,
-       };
-       struct pci_bus bus = {
-               .number = 0,
-               .ops = &cns3xxx_pcie_ops,
-               .sysdata = &sd,
-       };
        u16 mem_base  = cnspci->res_mem.start >> 16;
        u16 mem_limit = cnspci->res_mem.end   >> 16;
        u16 io_base   = cnspci->res_io.start  >> 16;
        u16 io_limit  = cnspci->res_io.end    >> 16;
-       u32 devfn = 0;
-       u8 tmp8;
-       u16 pos;
-       u16 dc;
-
-       pci_bus_write_config_byte(&bus, devfn, PCI_PRIMARY_BUS, 0);
-       pci_bus_write_config_byte(&bus, devfn, PCI_SECONDARY_BUS, 1);
-       pci_bus_write_config_byte(&bus, devfn, PCI_SUBORDINATE_BUS, 1);
 
-       pci_bus_read_config_byte(&bus, devfn, PCI_PRIMARY_BUS, &tmp8);
-       pci_bus_read_config_byte(&bus, devfn, PCI_SECONDARY_BUS, &tmp8);
-       pci_bus_read_config_byte(&bus, devfn, PCI_SUBORDINATE_BUS, &tmp8);
-
-       pci_bus_write_config_word(&bus, devfn, PCI_MEMORY_BASE, mem_base);
-       pci_bus_write_config_word(&bus, devfn, PCI_MEMORY_LIMIT, mem_limit);
-       pci_bus_write_config_word(&bus, devfn, PCI_IO_BASE_UPPER16, io_base);
-       pci_bus_write_config_word(&bus, devfn, PCI_IO_LIMIT_UPPER16, io_limit);
+       cns3xxx_write_config(cnspci, PCI_PRIMARY_BUS, 1, 0);
+       cns3xxx_write_config(cnspci, PCI_SECONDARY_BUS, 1, 1);
+       cns3xxx_write_config(cnspci, PCI_SUBORDINATE_BUS, 1, 1);
+       cns3xxx_write_config(cnspci, PCI_MEMORY_BASE, 2, mem_base);
+       cns3xxx_write_config(cnspci, PCI_MEMORY_LIMIT, 2, mem_limit);
+       cns3xxx_write_config(cnspci, PCI_IO_BASE_UPPER16, 2, io_base);
+       cns3xxx_write_config(cnspci, PCI_IO_LIMIT_UPPER16, 2, io_limit);
 
        if (!cnspci->linked)
                return;
 
        /* Set Device Max_Read_Request_Size to 128 byte */
-       bus.number = 1; /* directly connected PCIe device */
-       devfn = PCI_DEVFN(0, 0);
-       pos = pci_bus_find_capability(&bus, devfn, PCI_CAP_ID_EXP);
-       pci_bus_read_config_word(&bus, devfn, pos + PCI_EXP_DEVCTL, &dc);
-       if (dc & PCI_EXP_DEVCTL_READRQ) {
-               dc &= ~PCI_EXP_DEVCTL_READRQ;
-               pci_bus_write_config_word(&bus, devfn, pos + PCI_EXP_DEVCTL, dc);
-               pci_bus_read_config_word(&bus, devfn, pos + PCI_EXP_DEVCTL, &dc);
-               if (dc & PCI_EXP_DEVCTL_READRQ)
-                       pr_warn("PCIe: Unable to set device Max_Read_Request_Size\n");
-               else
-                       pr_info("PCIe: Max_Read_Request_Size set to 128 bytes\n");
-       }
+       pcie_bus_config = PCIE_BUS_PEER2PEER;
+
        /* Disable PCIe0 Interrupt Mask INTA to INTD */
-       __raw_writel(~0x3FFF, MISC_PCIE_INT_MASK(port));
+       __raw_writel(~0x3FFF, MISC_PCIE_INT_MASK(cnspci->port));
 }
 
 static int cns3xxx_pcie_abort_handler(unsigned long addr, unsigned int fsr,
index 1a0898c1c17ec40f4c66f2d3fa0f4c7d9da9f357..bbdd2d614b4978022f0b9f51a7abc898dc0b5e0f 100644 (file)
@@ -546,9 +546,7 @@ static int dm6444evm_msp430_get_pins(void)
        if (status < 0)
                return status;
 
-       dev_dbg(&dm6446evm_msp->dev,
-               "PINS: %02x %02x %02x %02x\n",
-               buf[0], buf[1], buf[2], buf[3]);
+       dev_dbg(&dm6446evm_msp->dev, "PINS: %4ph\n", buf);
 
        return (buf[3] << 8) | buf[2];
 }
index c70bb0a4dfb44cb288e671f727199c07a1d0af5f..3caff9637a82e759db99ee78c7677340f1f3e560 100644 (file)
@@ -97,7 +97,9 @@ int clk_enable(struct clk *clk)
 {
        unsigned long flags;
 
-       if (clk == NULL || IS_ERR(clk))
+       if (!clk)
+               return 0;
+       else if (IS_ERR(clk))
                return -EINVAL;
 
        spin_lock_irqsave(&clockfw_lock, flags);
@@ -124,7 +126,7 @@ EXPORT_SYMBOL(clk_disable);
 unsigned long clk_get_rate(struct clk *clk)
 {
        if (clk == NULL || IS_ERR(clk))
-               return -EINVAL;
+               return 0;
 
        return clk->rate;
 }
@@ -159,8 +161,10 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
        unsigned long flags;
        int ret = -EINVAL;
 
-       if (clk == NULL || IS_ERR(clk))
-               return ret;
+       if (!clk)
+               return 0;
+       else if (IS_ERR(clk))
+               return -EINVAL;
 
        if (clk->set_rate)
                ret = clk->set_rate(clk, rate);
@@ -181,7 +185,9 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
 {
        unsigned long flags;
 
-       if (clk == NULL || IS_ERR(clk))
+       if (!clk)
+               return 0;
+       else if (IS_ERR(clk))
                return -EINVAL;
 
        /* Cannot change parent on enabled clock */
index 4f36d8d2bc57bd59a76d5efb1ed0a6f132141310..fc65b0f1db482c9d9993be16ada142f63e95a8c9 100644 (file)
@@ -1,7 +1,10 @@
 config ARCH_DIGICOLOR
        bool "Conexant Digicolor SoC Support"
        depends on ARCH_MULTI_V7
+       select ARCH_REQUIRE_GPIOLIB
        select CLKSRC_MMIO
        select DIGICOLOR_TIMER
        select GENERIC_IRQ_CHIP
        select MFD_SYSCON
+       select PINCTRL
+       select PINCTRL_DIGICOLOR
index 9bdf54795f05de26283881729a4427bd781ea2eb..56978199c4798fa236394c232e50d58a61e4fd3d 100644 (file)
@@ -20,6 +20,7 @@
 #include <asm/cputype.h>
 #include <asm/cp15.h>
 #include <asm/mcpm.h>
+#include <asm/smp_plat.h>
 
 #include "regs-pmu.h"
 #include "common.h"
@@ -70,7 +71,31 @@ static int exynos_cpu_powerup(unsigned int cpu, unsigned int cluster)
                cluster >= EXYNOS5420_NR_CLUSTERS)
                return -EINVAL;
 
-       exynos_cpu_power_up(cpunr);
+       if (!exynos_cpu_power_state(cpunr)) {
+               exynos_cpu_power_up(cpunr);
+
+               /*
+                * This assumes the cluster number of the big cores(Cortex A15)
+                * is 0 and the Little cores(Cortex A7) is 1.
+                * When the system was booted from the Little core,
+                * they should be reset during power up cpu.
+                */
+               if (cluster &&
+                   cluster == MPIDR_AFFINITY_LEVEL(cpu_logical_map(0), 1)) {
+                       /*
+                        * Before we reset the Little cores, we should wait
+                        * the SPARE2 register is set to 1 because the init
+                        * codes of the iROM will set the register after
+                        * initialization.
+                        */
+                       while (!pmu_raw_readl(S5P_PMU_SPARE2))
+                               udelay(10);
+
+                       pmu_raw_writel(EXYNOS5420_KFC_CORE_RESET(cpu),
+                                       EXYNOS_SWRESET);
+               }
+       }
+
        return 0;
 }
 
index 4a87e86dec45d1546153ca0ebb7310bbd5f82d93..7c21760f590ffd0d4cd47fcafcbcaffe64a85952 100644 (file)
@@ -200,15 +200,15 @@ no_clk:
                args.args_count = 0;
                child_domain = of_genpd_get_from_provider(&args);
                if (IS_ERR(child_domain))
-                       goto next_pd;
+                       continue;
 
                if (of_parse_phandle_with_args(np, "power-domains",
                                         "#power-domain-cells", 0, &args) != 0)
-                       goto next_pd;
+                       continue;
 
                parent_domain = of_genpd_get_from_provider(&args);
                if (IS_ERR(parent_domain))
-                       goto next_pd;
+                       continue;
 
                if (pm_genpd_add_subdomain(parent_domain, child_domain))
                        pr_warn("%s failed to add subdomain: %s\n",
@@ -216,8 +216,6 @@ no_clk:
                else
                        pr_info("%s has as child subdomain: %s.\n",
                                parent_domain->name, child_domain->name);
-next_pd:
-               of_node_put(np);
        }
 
        return 0;
index b7614333d2968befa767109f693bf7947528db4a..fba9068ed260de7f8211525e772ffc25d7d88f0a 100644 (file)
@@ -513,6 +513,12 @@ static inline unsigned int exynos_pmu_cpunr(unsigned int mpidr)
 #define SPREAD_ENABLE                                          0xF
 #define SPREAD_USE_STANDWFI                                    0xF
 
+#define EXYNOS5420_KFC_CORE_RESET0                             BIT(8)
+#define EXYNOS5420_KFC_ETM_RESET0                              BIT(20)
+
+#define EXYNOS5420_KFC_CORE_RESET(_nr)                         \
+       ((EXYNOS5420_KFC_CORE_RESET0 | EXYNOS5420_KFC_ETM_RESET0) << (_nr))
+
 #define EXYNOS5420_BB_CON1                                     0x0784
 #define EXYNOS5420_BB_SEL_EN                                   BIT(31)
 #define EXYNOS5420_BB_PMOS_EN                                  BIT(7)
index e00eb39453a41ff3cf0090a6db53ee80a2afc7dc..dfb1fcf4042fe54abb8c1ba904da7913d0cf8a24 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/cpu_pm.h>
 #include <linux/io.h>
 #include <linux/irq.h>
+#include <linux/irqchip.h>
 #include <linux/irqdomain.h>
 #include <linux/of_address.h>
 #include <linux/err.h>
@@ -262,7 +263,7 @@ static int __init exynos_pmu_irq_init(struct device_node *node,
        return 0;
 }
 
-#define EXYNOS_PMU_IRQ(symbol, name)   OF_DECLARE_2(irqchip, symbol, name, exynos_pmu_irq_init)
+#define EXYNOS_PMU_IRQ(symbol, name)   IRQCHIP_DECLARE(symbol, name, exynos_pmu_irq_init)
 
 EXYNOS_PMU_IRQ(exynos3250_pmu_irq, "samsung,exynos3250-pmu");
 EXYNOS_PMU_IRQ(exynos4210_pmu_irq, "samsung,exynos4210-pmu");
index 21e4e8697a58f7d020d155277caabf85c5a0934e..e2d53839fceb632214a9dbe8deade9a9ed618e08 100644 (file)
@@ -131,6 +131,7 @@ void imx6q_pm_init(void);
 void imx6dl_pm_init(void);
 void imx6sl_pm_init(void);
 void imx6sx_pm_init(void);
+void imx6ul_pm_init(void);
 
 #ifdef CONFIG_PM
 void imx51_pm_init(void);
index 8c4467fad8370c73374ff104209b779e580852e1..f2783b087d3366c78910eca7ec8073a0d8879dca 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/irq.h>
+#include <linux/irqchip.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
@@ -268,12 +269,7 @@ static int __init imx_gpc_init(struct device_node *node,
 
        return 0;
 }
-
-/*
- * We cannot use the IRQCHIP_DECLARE macro that lives in
- * drivers/irqchip, so we're forced to roll our own. Not very nice.
- */
-OF_DECLARE_2(irqchip, imx_gpc, "fsl,imx6q-gpc", imx_gpc_init);
+IRQCHIP_DECLARE(imx_gpc, "fsl,imx6q-gpc", imx_gpc_init);
 
 void __init imx_gpc_check_dt(void)
 {
index 1b97fe133cef0aa47a50946e3d163c4483451212..acaf7056efa57be734cd5e447b5bae6d744b5b68 100644 (file)
@@ -67,6 +67,7 @@ static void __init imx6ul_init_machine(void)
        of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
        imx6ul_enet_init();
        imx_anatop_init();
+       imx6ul_pm_init();
 }
 
 static void __init imx6ul_init_irq(void)
@@ -74,6 +75,13 @@ static void __init imx6ul_init_irq(void)
        imx_init_revision_from_anatop();
        imx_src_init();
        irqchip_init();
+       imx6_pm_ccm_init("fsl,imx6ul-ccm");
+}
+
+static void __init imx6ul_init_late(void)
+{
+       if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ))
+               platform_device_register_simple("imx6q-cpufreq", -1, NULL, 0);
 }
 
 static const char *imx6ul_dt_compat[] __initconst = {
@@ -84,5 +92,6 @@ static const char *imx6ul_dt_compat[] __initconst = {
 DT_MACHINE_START(IMX6UL, "Freescale i.MX6 Ultralite (Device Tree)")
        .init_irq       = imx6ul_init_irq,
        .init_machine   = imx6ul_init_machine,
+       .init_late      = imx6ul_init_late,
        .dt_compat      = imx6ul_dt_compat,
 MACHINE_END
index 62f3437257f1f55b8c08c0f57b062ff23c678ff5..b450f525a670961b79cd0b3d28271a238dba70a1 100644 (file)
@@ -6,12 +6,85 @@
  * published by the Free Software Foundation.
  */
 #include <linux/irqchip.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx7-iomuxc-gpr.h>
 #include <linux/of_platform.h>
+#include <linux/phy.h>
+#include <linux/regmap.h>
+
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
 #include "common.h"
 
+static int ar8031_phy_fixup(struct phy_device *dev)
+{
+       u16 val;
+
+       /* Set RGMII IO voltage to 1.8V */
+       phy_write(dev, 0x1d, 0x1f);
+       phy_write(dev, 0x1e, 0x8);
+
+       /* disable phy AR8031 SmartEEE function. */
+       phy_write(dev, 0xd, 0x3);
+       phy_write(dev, 0xe, 0x805d);
+       phy_write(dev, 0xd, 0x4003);
+       val = phy_read(dev, 0xe);
+       val &= ~(0x1 << 8);
+       phy_write(dev, 0xe, val);
+
+       /* introduce tx clock delay */
+       phy_write(dev, 0x1d, 0x5);
+       val = phy_read(dev, 0x1e);
+       val |= 0x0100;
+       phy_write(dev, 0x1e, val);
+
+       return 0;
+}
+
+static int bcm54220_phy_fixup(struct phy_device *dev)
+{
+       /* enable RXC skew select RGMII copper mode */
+       phy_write(dev, 0x1e, 0x21);
+       phy_write(dev, 0x1f, 0x7ea8);
+       phy_write(dev, 0x1e, 0x2f);
+       phy_write(dev, 0x1f, 0x71b7);
+
+       return 0;
+}
+
+#define PHY_ID_AR8031  0x004dd074
+#define PHY_ID_BCM54220        0x600d8589
+
+static void __init imx7d_enet_phy_init(void)
+{
+       if (IS_BUILTIN(CONFIG_PHYLIB)) {
+               phy_register_fixup_for_uid(PHY_ID_AR8031, 0xffffffff,
+                                          ar8031_phy_fixup);
+               phy_register_fixup_for_uid(PHY_ID_BCM54220, 0xffffffff,
+                                          bcm54220_phy_fixup);
+       }
+}
+
+static void __init imx7d_enet_clk_sel(void)
+{
+       struct regmap *gpr;
+
+       gpr = syscon_regmap_lookup_by_compatible("fsl,imx7d-iomuxc-gpr");
+       if (!IS_ERR(gpr)) {
+               regmap_update_bits(gpr, IOMUXC_GPR1, IMX7D_GPR1_ENET_TX_CLK_SEL_MASK, 0);
+               regmap_update_bits(gpr, IOMUXC_GPR1, IMX7D_GPR1_ENET_CLK_DIR_MASK, 0);
+       } else {
+               pr_err("failed to find fsl,imx7d-iomux-gpr regmap\n");
+       }
+}
+
+static inline void imx7d_enet_init(void)
+{
+       imx7d_enet_phy_init();
+       imx7d_enet_clk_sel();
+}
+
 static void __init imx7d_init_machine(void)
 {
        struct device *parent;
@@ -22,6 +95,7 @@ static void __init imx7d_init_machine(void)
 
        of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
        imx_anatop_init();
+       imx7d_enet_init();
 }
 
 static void __init imx7d_init_irq(void)
index 8ff8fc0b261ccd7a6d6912b4478e60b15606c097..4470376af5f815fd5f8f2d12c5e7d18306675bb4 100644 (file)
@@ -93,6 +93,7 @@ struct imx6_pm_socdata {
        const char *src_compat;
        const char *iomuxc_compat;
        const char *gpc_compat;
+       const char *pl310_compat;
        const u32 mmdc_io_num;
        const u32 *mmdc_io_offset;
 };
@@ -137,11 +138,19 @@ static const u32 imx6sx_mmdc_io_offset[] __initconst = {
        0x330, 0x334, 0x338, 0x33c, /* SDQS0 ~ SDQS3 */
 };
 
+static const u32 imx6ul_mmdc_io_offset[] __initconst = {
+       0x244, 0x248, 0x24c, 0x250, /* DQM0, DQM1, RAS, CAS */
+       0x27c, 0x498, 0x4a4, 0x490, /* SDCLK0, GPR_B0DS-B1DS, GPR_ADDS */
+       0x280, 0x284, 0x260, 0x264, /* SDQS0~1, SODT0, SODT1 */
+       0x494, 0x4b0,               /* MODE_CTL, MODE, */
+};
+
 static const struct imx6_pm_socdata imx6q_pm_data __initconst = {
        .mmdc_compat = "fsl,imx6q-mmdc",
        .src_compat = "fsl,imx6q-src",
        .iomuxc_compat = "fsl,imx6q-iomuxc",
        .gpc_compat = "fsl,imx6q-gpc",
+       .pl310_compat = "arm,pl310-cache",
        .mmdc_io_num = ARRAY_SIZE(imx6q_mmdc_io_offset),
        .mmdc_io_offset = imx6q_mmdc_io_offset,
 };
@@ -151,6 +160,7 @@ static const struct imx6_pm_socdata imx6dl_pm_data __initconst = {
        .src_compat = "fsl,imx6q-src",
        .iomuxc_compat = "fsl,imx6dl-iomuxc",
        .gpc_compat = "fsl,imx6q-gpc",
+       .pl310_compat = "arm,pl310-cache",
        .mmdc_io_num = ARRAY_SIZE(imx6dl_mmdc_io_offset),
        .mmdc_io_offset = imx6dl_mmdc_io_offset,
 };
@@ -160,6 +170,7 @@ static const struct imx6_pm_socdata imx6sl_pm_data __initconst = {
        .src_compat = "fsl,imx6sl-src",
        .iomuxc_compat = "fsl,imx6sl-iomuxc",
        .gpc_compat = "fsl,imx6sl-gpc",
+       .pl310_compat = "arm,pl310-cache",
        .mmdc_io_num = ARRAY_SIZE(imx6sl_mmdc_io_offset),
        .mmdc_io_offset = imx6sl_mmdc_io_offset,
 };
@@ -169,10 +180,21 @@ static const struct imx6_pm_socdata imx6sx_pm_data __initconst = {
        .src_compat = "fsl,imx6sx-src",
        .iomuxc_compat = "fsl,imx6sx-iomuxc",
        .gpc_compat = "fsl,imx6sx-gpc",
+       .pl310_compat = "arm,pl310-cache",
        .mmdc_io_num = ARRAY_SIZE(imx6sx_mmdc_io_offset),
        .mmdc_io_offset = imx6sx_mmdc_io_offset,
 };
 
+static const struct imx6_pm_socdata imx6ul_pm_data __initconst = {
+       .mmdc_compat = "fsl,imx6ul-mmdc",
+       .src_compat = "fsl,imx6ul-src",
+       .iomuxc_compat = "fsl,imx6ul-iomuxc",
+       .gpc_compat = "fsl,imx6ul-gpc",
+       .pl310_compat = NULL,
+       .mmdc_io_num = ARRAY_SIZE(imx6ul_mmdc_io_offset),
+       .mmdc_io_offset = imx6ul_mmdc_io_offset,
+};
+
 /*
  * This structure is for passing necessary data for low level ocram
  * suspend code(arch/arm/mach-imx/suspend-imx6.S), if this struct
@@ -290,7 +312,7 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode)
                val |= BM_CLPCR_SBYOS;
                if (cpu_is_imx6sl())
                        val |= BM_CLPCR_BYPASS_PMIC_READY;
-               if (cpu_is_imx6sl() || cpu_is_imx6sx())
+               if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul())
                        val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
                else
                        val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
@@ -330,6 +352,10 @@ static int imx6q_suspend_finish(unsigned long val)
                 * as we need to float DDR IO.
                 */
                local_flush_tlb_all();
+               /* check if need to flush internal L2 cache */
+               if (!((struct imx6_cpu_pm_info *)
+                       suspend_ocram_base)->l2_base.vbase)
+                       flush_cache_all();
                imx6_suspend_in_ocram_fn(suspend_ocram_base);
        }
 
@@ -470,6 +496,7 @@ static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata)
        suspend_ocram_base = __arm_ioremap_exec(ocram_pbase,
                MX6Q_SUSPEND_OCRAM_SIZE, false);
 
+       memset(suspend_ocram_base, 0, sizeof(*pm_info));
        pm_info = suspend_ocram_base;
        pm_info->pbase = ocram_pbase;
        pm_info->resume_addr = virt_to_phys(v7_cpu_resume);
@@ -505,11 +532,13 @@ static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata)
                goto gpc_map_failed;
        }
 
-       ret = imx6_pm_get_base(&pm_info->l2_base, "arm,pl310-cache");
-       if (ret) {
-               pr_warn("%s: failed to get pl310-cache base %d!\n",
-                       __func__, ret);
-               goto pl310_cache_map_failed;
+       if (socdata->pl310_compat) {
+               ret = imx6_pm_get_base(&pm_info->l2_base, socdata->pl310_compat);
+               if (ret) {
+                       pr_warn("%s: failed to get pl310-cache base %d!\n",
+                               __func__, ret);
+                       goto pl310_cache_map_failed;
+               }
        }
 
        pm_info->ddr_type = imx_mmdc_get_ddr_type();
@@ -610,3 +639,8 @@ void __init imx6sx_pm_init(void)
 {
        imx6_pm_common_init(&imx6sx_pm_data);
 }
+
+void __init imx6ul_pm_init(void)
+{
+       imx6_pm_common_init(&imx6ul_pm_data);
+}
index b99987b023fa426bc8a225aaa3e2bb362d940c3a..76ee2ceec8d546d0ca3f51aebcb8f40509213ba6 100644 (file)
        /* sync L2 cache to drain L2's buffers to DRAM. */
 #ifdef CONFIG_CACHE_L2X0
        ldr     r11, [r0, #PM_INFO_MX6Q_L2_V_OFFSET]
+       teq     r11, #0
+       beq     6f
        mov     r6, #0x0
        str     r6, [r11, #L2X0_CACHE_SYNC]
 1:
        ldr     r6, [r11, #L2X0_CACHE_SYNC]
        ands    r6, r6, #0x1
        bne     1b
+6:
 #endif
 
        .endm
index 43e619f56172feed1cb4ebbcec544c1b73f2e121..21164605b83fcd8e923798b679b29ac75781c4cc 100644 (file)
@@ -1 +1,4 @@
+ifeq ($(CONFIG_SMP),y)
+obj-$(CONFIG_ARCH_MEDIATEK) += platsmp.o
+endif
 obj-$(CONFIG_ARCH_MEDIATEK) += mediatek.o
index a9549005097e035271ca34fae7a6a71caffdf956..19dc738c1abc5ab340d640c59a0ecccaa2f88aa5 100644 (file)
  */
 #include <linux/init.h>
 #include <asm/mach/arch.h>
+#include <linux/of.h>
+#include <linux/clk-provider.h>
+#include <linux/clocksource.h>
+
+
+#define GPT6_CON_MT65xx 0x10008060
+#define GPT_ENABLE      0x31
+
+static void __init mediatek_timer_init(void)
+{
+       void __iomem *gpt_base;
+
+       if (of_machine_is_compatible("mediatek,mt6589") ||
+           of_machine_is_compatible("mediatek,mt8135") ||
+           of_machine_is_compatible("mediatek,mt8127")) {
+               /* turn on GPT6 which ungates arch timer clocks */
+               gpt_base = ioremap(GPT6_CON_MT65xx, 0x04);
+
+               /* enable clock and set to free-run */
+               writel(GPT_ENABLE, gpt_base);
+               iounmap(gpt_base);
+       }
+
+       of_clk_init(NULL);
+       clocksource_of_init();
+};
 
 static const char * const mediatek_board_dt_compat[] = {
        "mediatek,mt6589",
@@ -27,4 +53,5 @@ static const char * const mediatek_board_dt_compat[] = {
 
 DT_MACHINE_START(MEDIATEK_DT, "Mediatek Cortex-A7 (Device Tree)")
        .dt_compat      = mediatek_board_dt_compat,
+       .init_time      = mediatek_timer_init,
 MACHINE_END
diff --git a/arch/arm/mach-mediatek/platsmp.c b/arch/arm/mach-mediatek/platsmp.c
new file mode 100644 (file)
index 0000000..8141f3f
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * arch/arm/mach-mediatek/platsmp.c
+ *
+ * Copyright (c) 2014 Mediatek Inc.
+ * Author: Shunli Wang <shunli.wang@mediatek.com>
+ *         Yingjoe Chen <yingjoe.chen@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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/io.h>
+#include <linux/memblock.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/string.h>
+#include <linux/threads.h>
+
+#define MTK_MAX_CPU            8
+#define MTK_SMP_REG_SIZE       0x1000
+
+struct mtk_smp_boot_info {
+       unsigned long smp_base;
+       unsigned int jump_reg;
+       unsigned int core_keys[MTK_MAX_CPU - 1];
+       unsigned int core_regs[MTK_MAX_CPU - 1];
+};
+
+static const struct mtk_smp_boot_info mtk_mt8135_tz_boot = {
+       0x80002000, 0x3fc,
+       { 0x534c4131, 0x4c415332, 0x41534c33 },
+       { 0x3f8, 0x3f8, 0x3f8 },
+};
+
+static const struct mtk_smp_boot_info mtk_mt6589_boot = {
+       0x10002000, 0x34,
+       { 0x534c4131, 0x4c415332, 0x41534c33 },
+       { 0x38, 0x3c, 0x40 },
+};
+
+static const struct of_device_id mtk_tz_smp_boot_infos[] __initconst = {
+       { .compatible   = "mediatek,mt8135", .data = &mtk_mt8135_tz_boot },
+       { .compatible   = "mediatek,mt8127", .data = &mtk_mt8135_tz_boot },
+};
+
+static const struct of_device_id mtk_smp_boot_infos[] __initconst = {
+       { .compatible   = "mediatek,mt6589", .data = &mtk_mt6589_boot },
+};
+
+static void __iomem *mtk_smp_base;
+static const struct mtk_smp_boot_info *mtk_smp_info;
+
+static int mtk_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+       if (!mtk_smp_base)
+               return -EINVAL;
+
+       if (!mtk_smp_info->core_keys[cpu-1])
+               return -EINVAL;
+
+       writel_relaxed(mtk_smp_info->core_keys[cpu-1],
+               mtk_smp_base + mtk_smp_info->core_regs[cpu-1]);
+
+       arch_send_wakeup_ipi_mask(cpumask_of(cpu));
+
+       return 0;
+}
+
+static void __init __mtk_smp_prepare_cpus(unsigned int max_cpus, int trustzone)
+{
+       int i, num;
+       const struct of_device_id *infos;
+
+       if (trustzone) {
+               num = ARRAY_SIZE(mtk_tz_smp_boot_infos);
+               infos = mtk_tz_smp_boot_infos;
+       } else {
+               num = ARRAY_SIZE(mtk_smp_boot_infos);
+               infos = mtk_smp_boot_infos;
+       }
+
+       /* Find smp boot info for this SoC */
+       for (i = 0; i < num; i++) {
+               if (of_machine_is_compatible(infos[i].compatible)) {
+                       mtk_smp_info = infos[i].data;
+                       break;
+               }
+       }
+
+       if (!mtk_smp_info) {
+               pr_err("%s: Device is not supported\n", __func__);
+               return;
+       }
+
+       if (trustzone) {
+               /* smp_base(trustzone-bootinfo) is reserved by device tree */
+               mtk_smp_base = phys_to_virt(mtk_smp_info->smp_base);
+       } else {
+               mtk_smp_base = ioremap(mtk_smp_info->smp_base, MTK_SMP_REG_SIZE);
+               if (!mtk_smp_base) {
+                       pr_err("%s: Can't remap %lx\n", __func__,
+                               mtk_smp_info->smp_base);
+                       return;
+               }
+       }
+
+       /*
+        * write the address of slave startup address into the system-wide
+        * jump register
+        */
+       writel_relaxed(virt_to_phys(secondary_startup_arm),
+                       mtk_smp_base + mtk_smp_info->jump_reg);
+}
+
+static void __init mtk_tz_smp_prepare_cpus(unsigned int max_cpus)
+{
+       __mtk_smp_prepare_cpus(max_cpus, 1);
+}
+
+static void __init mtk_smp_prepare_cpus(unsigned int max_cpus)
+{
+       __mtk_smp_prepare_cpus(max_cpus, 0);
+}
+
+static struct smp_operations mt81xx_tz_smp_ops __initdata = {
+       .smp_prepare_cpus = mtk_tz_smp_prepare_cpus,
+       .smp_boot_secondary = mtk_boot_secondary,
+};
+CPU_METHOD_OF_DECLARE(mt81xx_tz_smp, "mediatek,mt81xx-tz-smp", &mt81xx_tz_smp_ops);
+
+static struct smp_operations mt6589_smp_ops __initdata = {
+       .smp_prepare_cpus = mtk_smp_prepare_cpus,
+       .smp_boot_secondary = mtk_boot_secondary,
+};
+CPU_METHOD_OF_DECLARE(mt6589_smp, "mediatek,mt6589-smp", &mt6589_smp_ops);
index 0743e2059645d876af692026d9dfd74713ba2608..5d56f86ae1a4b1c96871e05c69eafd5bac5f7b26 100644 (file)
@@ -19,4 +19,9 @@ config MACH_MESON8
        default ARCH_MESON
        select MESON6_TIMER
 
+config MACH_MESON8B
+       bool "Amlogic Meson8b SoCs support"
+       default ARCH_MESON
+       select MESON6_TIMER
+
 endif
index 5d6affe6a694d38a37a34fe4d57e60f3c5ab7b7c..4e235717862599a211857c7c62cf5387fe85ebc8 100644 (file)
@@ -19,6 +19,7 @@
 static const char * const meson_common_board_compat[] = {
        "amlogic,meson6",
        "amlogic,meson8",
+       "amlogic,meson8b",
        NULL,
 };
 
index 9f739f3cad4c7e584391c0e8f79ec27376d5fa4c..1648edd515a2c2c5f313b0c9d3d68d6bebad545c 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/dma-mapping.h>
 #include <linux/memblock.h>
 #include <linux/mbus.h>
-#include <linux/signal.h>
 #include <linux/slab.h>
 #include <linux/irqchip.h>
 #include <asm/hardware/cache-l2x0.h>
@@ -105,27 +104,6 @@ static void __init mvebu_memblock_reserve(void)
 static void __init mvebu_memblock_reserve(void) {}
 #endif
 
-/*
- * Early versions of Armada 375 SoC have a bug where the BootROM
- * leaves an external data abort pending. The kernel is hit by this
- * data abort as soon as it enters userspace, because it unmasks the
- * data aborts at this moment. We register a custom abort handler
- * below to ignore the first data abort to work around this
- * problem.
- */
-static int armada_375_external_abort_wa(unsigned long addr, unsigned int fsr,
-                                       struct pt_regs *regs)
-{
-       static int ignore_first;
-
-       if (!ignore_first && fsr == 0x1406) {
-               ignore_first = 1;
-               return 0;
-       }
-
-       return 1;
-}
-
 static void __init mvebu_init_irq(void)
 {
        irqchip_init();
@@ -134,17 +112,6 @@ static void __init mvebu_init_irq(void)
        BUG_ON(mvebu_mbus_dt_init(coherency_available()));
 }
 
-static void __init external_abort_quirk(void)
-{
-       u32 dev, rev;
-
-       if (mvebu_get_soc_id(&dev, &rev) == 0 && rev > ARMADA_375_Z1_REV)
-               return;
-
-       hook_fault_code(16 + 6, armada_375_external_abort_wa, SIGBUS, 0,
-                       "imprecise external abort");
-}
-
 static void __init i2c_quirk(void)
 {
        struct device_node *np;
@@ -177,8 +144,6 @@ static void __init mvebu_dt_init(void)
 {
        if (of_machine_is_compatible("marvell,armadaxp"))
                i2c_quirk();
-       if (of_machine_is_compatible("marvell,a375-db"))
-               external_abort_quirk();
 
        of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
index 44eedf331ae7df40bb76fcfec0358e89ce128d76..55348ee5a35228cf5e8cbb8f55b0b16b4d56c805 100644 (file)
@@ -40,6 +40,7 @@
 unsigned long coherency_phys_base;
 void __iomem *coherency_base;
 static void __iomem *coherency_cpu_base;
+static void __iomem *cpu_config_base;
 
 /* Coherency fabric registers */
 #define IO_SYNC_BARRIER_CTL_OFFSET                0x0
@@ -65,6 +66,31 @@ static const struct of_device_id of_coherency_table[] = {
 int ll_enable_coherency(void);
 void ll_add_cpu_to_smp_group(void);
 
+#define CPU_CONFIG_SHARED_L2 BIT(16)
+
+/*
+ * Disable the "Shared L2 Present" bit in CPU Configuration register
+ * on Armada XP.
+ *
+ * The "Shared L2 Present" bit affects the "level of coherence" value
+ * in the clidr CP15 register.  Cache operation functions such as
+ * "flush all" and "invalidate all" operate on all the cache levels
+ * that included in the defined level of coherence. When HW I/O
+ * coherency is used, this bit causes unnecessary flushes of the L2
+ * cache.
+ */
+static void armada_xp_clear_shared_l2(void)
+{
+       u32 reg;
+
+       if (!cpu_config_base)
+               return;
+
+       reg = readl(cpu_config_base);
+       reg &= ~CPU_CONFIG_SHARED_L2;
+       writel(reg, cpu_config_base);
+}
+
 static int mvebu_hwcc_notifier(struct notifier_block *nb,
                               unsigned long event, void *__dev)
 {
@@ -85,9 +111,24 @@ static struct notifier_block mvebu_hwcc_pci_nb = {
        .notifier_call = mvebu_hwcc_notifier,
 };
 
+static int armada_xp_clear_shared_l2_notifier_func(struct notifier_block *nfb,
+                                       unsigned long action, void *hcpu)
+{
+       if (action == CPU_STARTING || action == CPU_STARTING_FROZEN)
+               armada_xp_clear_shared_l2();
+
+       return NOTIFY_OK;
+}
+
+static struct notifier_block armada_xp_clear_shared_l2_notifier = {
+       .notifier_call = armada_xp_clear_shared_l2_notifier_func,
+       .priority = 100,
+};
+
 static void __init armada_370_coherency_init(struct device_node *np)
 {
        struct resource res;
+       struct device_node *cpu_config_np;
 
        of_address_to_resource(np, 0, &res);
        coherency_phys_base = res.start;
@@ -100,6 +141,23 @@ static void __init armada_370_coherency_init(struct device_node *np)
        sync_cache_w(&coherency_phys_base);
        coherency_base = of_iomap(np, 0);
        coherency_cpu_base = of_iomap(np, 1);
+
+       cpu_config_np = of_find_compatible_node(NULL, NULL,
+                                               "marvell,armada-xp-cpu-config");
+       if (!cpu_config_np)
+               goto exit;
+
+       cpu_config_base = of_iomap(cpu_config_np, 0);
+       if (!cpu_config_base) {
+               of_node_put(cpu_config_np);
+               goto exit;
+       }
+
+       of_node_put(cpu_config_np);
+
+       register_cpu_notifier(&armada_xp_clear_shared_l2_notifier);
+
+exit:
        set_cpu_coherent();
 }
 
@@ -204,6 +262,8 @@ int set_cpu_coherent(void)
                        pr_warn("Coherency fabric is not initialized\n");
                        return 1;
                }
+
+               armada_xp_clear_shared_l2();
                ll_add_cpu_to_smp_group();
                return ll_enable_coherency();
        }
index e8fdb9ceedf0c7c9402bff4123ea9c375a1ccbfe..ed8fda4cd055848e871bb0f592b23735d4c843aa 100644 (file)
@@ -296,11 +296,11 @@ int armada_370_xp_pmsu_idle_enter(unsigned long deepidle)
        /* Test the CR_C bit and set it if it was cleared */
        asm volatile(
        "mrc    p15, 0, r0, c1, c0, 0 \n\t"
-       "tst    r0, #(1 << 2) \n\t"
+       "tst    r0, %0 \n\t"
        "orreq  r0, r0, #(1 << 2) \n\t"
        "mcreq  p15, 0, r0, c1, c0, 0 \n\t"
        "isb    "
-       : : : "r0");
+       : : "Ir" (CR_C) : "r0");
 
        pr_debug("Failed to suspend the system\n");
 
@@ -379,6 +379,16 @@ static struct notifier_block mvebu_v7_cpu_pm_notifier = {
 
 static struct platform_device mvebu_v7_cpuidle_device;
 
+static int broken_idle(struct device_node *np)
+{
+       if (of_property_read_bool(np, "broken-idle")) {
+               pr_warn("CPU idle is currently broken: disabling\n");
+               return 1;
+       }
+
+       return 0;
+}
+
 static __init int armada_370_cpuidle_init(void)
 {
        struct device_node *np;
@@ -387,7 +397,9 @@ static __init int armada_370_cpuidle_init(void)
        np = of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric");
        if (!np)
                return -ENODEV;
-       of_node_put(np);
+
+       if (broken_idle(np))
+               goto end;
 
        /*
         * On Armada 370, there is "a slow exit process from the deep
@@ -406,6 +418,8 @@ static __init int armada_370_cpuidle_init(void)
        mvebu_v7_cpuidle_device.dev.platform_data = armada_370_xp_cpu_suspend;
        mvebu_v7_cpuidle_device.name = "cpuidle-armada-370";
 
+end:
+       of_node_put(np);
        return 0;
 }
 
@@ -422,6 +436,10 @@ static __init int armada_38x_cpuidle_init(void)
                                     "marvell,armada-380-coherency-fabric");
        if (!np)
                return -ENODEV;
+
+       if (broken_idle(np))
+               goto end;
+
        of_node_put(np);
 
        np = of_find_compatible_node(NULL, NULL,
@@ -430,7 +448,6 @@ static __init int armada_38x_cpuidle_init(void)
                return -ENODEV;
        mpsoc_base = of_iomap(np, 0);
        BUG_ON(!mpsoc_base);
-       of_node_put(np);
 
        /* Set up reset mask when powering down the cpus */
        reg = readl(mpsoc_base + MPCORE_RESET_CTL);
@@ -450,6 +467,8 @@ static __init int armada_38x_cpuidle_init(void)
        mvebu_v7_cpuidle_device.dev.platform_data = armada_38x_cpu_suspend;
        mvebu_v7_cpuidle_device.name = "cpuidle-armada-38x";
 
+end:
+       of_node_put(np);
        return 0;
 }
 
@@ -460,12 +479,16 @@ static __init int armada_xp_cpuidle_init(void)
        np = of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric");
        if (!np)
                return -ENODEV;
-       of_node_put(np);
+
+       if (broken_idle(np))
+               goto end;
 
        mvebu_cpu_resume = armada_370_xp_cpu_resume;
        mvebu_v7_cpuidle_device.dev.platform_data = armada_370_xp_cpu_suspend;
        mvebu_v7_cpuidle_device.name = "cpuidle-armada-xp";
 
+end:
+       of_node_put(np);
        return 0;
 }
 
index cdd05f2e67ee87148a023bd2af8025fbfb5b5bff..afb8095091402eec1a6dd404f14b8a2b2637cd31 100644 (file)
@@ -90,13 +90,6 @@ config MACH_OMAP_FSAMPLE
          Support for TI OMAP 850 F-Sample board. Say Y here if you have such
          a board.
 
-config MACH_VOICEBLUE
-       bool "Voiceblue"
-       depends on ARCH_OMAP1 && ARCH_OMAP15XX
-       help
-         Support for Voiceblue GSM/VoIP gateway. Say Y here if you have
-         such a board.
-
 config MACH_OMAP_PALMTE
        bool "Palm Tungsten E"
        depends on ARCH_OMAP1 && ARCH_OMAP15XX
index 3889b6cd211e704b325573468246b28a45cf299d..0e8ea95ea82268958b1dcfd5edf75b55b2d8f6b4 100644 (file)
@@ -37,7 +37,6 @@ obj-$(CONFIG_MACH_OMAP_FSAMPLE)               += board-fsample.o board-nand.o
 obj-$(CONFIG_MACH_OMAP_OSK)            += board-osk.o
 obj-$(CONFIG_MACH_OMAP_H3)             += board-h3.o board-h3-mmc.o \
                                           board-nand.o
-obj-$(CONFIG_MACH_VOICEBLUE)           += board-voiceblue.o
 obj-$(CONFIG_MACH_OMAP_PALMTE)         += board-palmte.o
 obj-$(CONFIG_MACH_OMAP_PALMZ71)                += board-palmz71.o
 obj-$(CONFIG_MACH_OMAP_PALMTT)         += board-palmtt.o
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
deleted file mode 100644 (file)
index e960687..0000000
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * linux/arch/arm/mach-omap1/board-voiceblue.c
- *
- * Modified from board-generic.c
- *
- * Copyright (C) 2004 2N Telekomunikace, Ladislav Michl <michl@2n.cz>
- *
- * Code for OMAP5910 based VoiceBlue board (VoIP to GSM gateway).
- *
- * 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/delay.h>
-#include <linux/gpio.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/mtd/physmap.h>
-#include <linux/notifier.h>
-#include <linux/reboot.h>
-#include <linux/serial_8250.h>
-#include <linux/serial_reg.h>
-#include <linux/smc91x.h>
-#include <linux/export.h>
-#include <linux/reboot.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include <mach/board-voiceblue.h>
-#include <mach/flash.h>
-#include <mach/mux.h>
-#include <mach/tc.h>
-
-#include <mach/hardware.h>
-#include <mach/usb.h>
-
-#include "common.h"
-
-static struct plat_serial8250_port voiceblue_ports[] = {
-       {
-               .mapbase        = (unsigned long)(OMAP_CS1_PHYS + 0x40000),
-               .flags          = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
-               .iotype         = UPIO_MEM,
-               .regshift       = 1,
-               .uartclk        = 3686400,
-       },
-       {
-               .mapbase        = (unsigned long)(OMAP_CS1_PHYS + 0x50000),
-               .flags          = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
-               .iotype         = UPIO_MEM,
-               .regshift       = 1,
-               .uartclk        = 3686400,
-       },
-       {
-               .mapbase        = (unsigned long)(OMAP_CS1_PHYS + 0x60000),
-               .flags          = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
-               .iotype         = UPIO_MEM,
-               .regshift       = 1,
-               .uartclk        = 3686400,
-       },
-       {
-               .mapbase        = (unsigned long)(OMAP_CS1_PHYS + 0x70000),
-               .flags          = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
-               .iotype         = UPIO_MEM,
-               .regshift       = 1,
-               .uartclk        = 3686400,
-       },
-       { },
-};
-
-static struct platform_device serial_device = {
-       .name                   = "serial8250",
-       .id                     = PLAT8250_DEV_PLATFORM1,
-};
-
-static int __init ext_uart_init(void)
-{
-       if (!machine_is_voiceblue())
-               return -ENODEV;
-
-       voiceblue_ports[0].irq = gpio_to_irq(12);
-       voiceblue_ports[1].irq = gpio_to_irq(13);
-       voiceblue_ports[2].irq = gpio_to_irq(14);
-       voiceblue_ports[3].irq = gpio_to_irq(15);
-       serial_device.dev.platform_data = voiceblue_ports;
-       return platform_device_register(&serial_device);
-}
-arch_initcall(ext_uart_init);
-
-static struct physmap_flash_data voiceblue_flash_data = {
-       .width          = 2,
-       .set_vpp        = omap1_set_vpp,
-};
-
-static struct resource voiceblue_flash_resource = {
-       .start  = OMAP_CS0_PHYS,
-       .end    = OMAP_CS0_PHYS + SZ_32M - 1,
-       .flags  = IORESOURCE_MEM,
-};
-
-static struct platform_device voiceblue_flash_device = {
-       .name           = "physmap-flash",
-       .id             = 0,
-       .dev            = {
-               .platform_data  = &voiceblue_flash_data,
-       },
-       .num_resources  = 1,
-       .resource       = &voiceblue_flash_resource,
-};
-
-static struct smc91x_platdata voiceblue_smc91x_info = {
-       .flags  = SMC91X_USE_16BIT | SMC91X_NOWAIT,
-       .leda   = RPC_LED_100_10,
-       .ledb   = RPC_LED_TX_RX,
-};
-
-static struct resource voiceblue_smc91x_resources[] = {
-       [0] = {
-               .start  = OMAP_CS2_PHYS + 0x300,
-               .end    = OMAP_CS2_PHYS + 0x300 + 16,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
-       },
-};
-
-static struct platform_device voiceblue_smc91x_device = {
-       .name           = "smc91x",
-       .id             = 0,
-       .dev    = {
-               .platform_data  = &voiceblue_smc91x_info,
-       },
-       .num_resources  = ARRAY_SIZE(voiceblue_smc91x_resources),
-       .resource       = voiceblue_smc91x_resources,
-};
-
-static struct platform_device *voiceblue_devices[] __initdata = {
-       &voiceblue_flash_device,
-       &voiceblue_smc91x_device,
-};
-
-static struct omap_usb_config voiceblue_usb_config __initdata = {
-       .hmc_mode       = 3,
-       .register_host  = 1,
-       .register_dev   = 1,
-       .pins[0]        = 2,
-       .pins[1]        = 6,
-       .pins[2]        = 6,
-};
-
-#define MACHINE_PANICED                1
-#define MACHINE_REBOOTING      2
-#define MACHINE_REBOOT         4
-static unsigned long machine_state;
-
-static int panic_event(struct notifier_block *this, unsigned long event,
-        void *ptr)
-{
-       if (test_and_set_bit(MACHINE_PANICED, &machine_state))
-               return NOTIFY_DONE;
-
-       /* Flash power LED */
-       omap_writeb(0x78, OMAP_LPG1_LCR);
-       omap_writeb(0x01, OMAP_LPG1_PMR);       /* Enable clock */
-
-       return NOTIFY_DONE;
-}
-
-static struct notifier_block panic_block = {
-       .notifier_call  = panic_event,
-};
-
-static int __init voiceblue_setup(void)
-{
-       if (!machine_is_voiceblue())
-               return -ENODEV;
-
-       /* Setup panic notifier */
-       atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
-
-       return 0;
-}
-postcore_initcall(voiceblue_setup);
-
-static int wdt_gpio_state;
-
-void voiceblue_wdt_enable(void)
-{
-       gpio_direction_output(0, 0);
-       gpio_set_value(0, 1);
-       gpio_set_value(0, 0);
-       wdt_gpio_state = 0;
-}
-
-void voiceblue_wdt_disable(void)
-{
-       gpio_set_value(0, 0);
-       gpio_set_value(0, 1);
-       gpio_set_value(0, 0);
-       gpio_direction_input(0);
-}
-
-void voiceblue_wdt_ping(void)
-{
-       if (test_bit(MACHINE_REBOOT, &machine_state))
-               return;
-
-       wdt_gpio_state = !wdt_gpio_state;
-       gpio_set_value(0, wdt_gpio_state);
-}
-
-static void voiceblue_restart(enum reboot_mode mode, const char *cmd)
-{
-       /*
-        * Workaround for 5912/1611b bug mentioned in sprz209d.pdf p. 28
-        * "Global Software Reset Affects Traffic Controller Frequency".
-        */
-       if (cpu_is_omap5912()) {
-               omap_writew(omap_readw(DPLL_CTL) & ~(1 << 4), DPLL_CTL);
-               omap_writew(0x8, ARM_RSTCT1);
-       }
-
-       set_bit(MACHINE_REBOOT, &machine_state);
-       voiceblue_wdt_enable();
-       while (1) ;
-}
-
-EXPORT_SYMBOL(voiceblue_wdt_enable);
-EXPORT_SYMBOL(voiceblue_wdt_disable);
-EXPORT_SYMBOL(voiceblue_wdt_ping);
-
-static void __init voiceblue_init(void)
-{
-       /* mux pins for uarts */
-       omap_cfg_reg(UART1_TX);
-       omap_cfg_reg(UART1_RTS);
-       omap_cfg_reg(UART2_TX);
-       omap_cfg_reg(UART2_RTS);
-       omap_cfg_reg(UART3_TX);
-       omap_cfg_reg(UART3_RX);
-
-       /* Watchdog */
-       gpio_request(0, "Watchdog");
-       /* smc91x reset */
-       gpio_request(7, "SMC91x reset");
-       gpio_direction_output(7, 1);
-       udelay(2);      /* wait at least 100ns */
-       gpio_set_value(7, 0);
-       mdelay(50);     /* 50ms until PHY ready */
-       /* smc91x interrupt pin */
-       gpio_request(8, "SMC91x irq");
-       /* 16C554 reset*/
-       gpio_request(6, "16C554 reset");
-       gpio_direction_output(6, 0);
-       /* 16C554 interrupt pins */
-       gpio_request(12, "16C554 irq");
-       gpio_request(13, "16C554 irq");
-       gpio_request(14, "16C554 irq");
-       gpio_request(15, "16C554 irq");
-       irq_set_irq_type(gpio_to_irq(12), IRQ_TYPE_EDGE_RISING);
-       irq_set_irq_type(gpio_to_irq(13), IRQ_TYPE_EDGE_RISING);
-       irq_set_irq_type(gpio_to_irq(14), IRQ_TYPE_EDGE_RISING);
-       irq_set_irq_type(gpio_to_irq(15), IRQ_TYPE_EDGE_RISING);
-
-       voiceblue_smc91x_resources[1].start = gpio_to_irq(8);
-       voiceblue_smc91x_resources[1].end = gpio_to_irq(8);
-       platform_add_devices(voiceblue_devices, ARRAY_SIZE(voiceblue_devices));
-       omap_serial_init();
-       omap1_usb_init(&voiceblue_usb_config);
-       omap_register_i2c_bus(1, 100, NULL, 0);
-
-       /* There is a good chance board is going up, so enable power LED
-        * (it is connected through invertor) */
-       omap_writeb(0x00, OMAP_LPG1_LCR);
-       omap_writeb(0x00, OMAP_LPG1_PMR);       /* Disable clock */
-}
-
-MACHINE_START(VOICEBLUE, "VoiceBlue OMAP5910")
-       /* Maintainer: Ladislav Michl <michl@2n.cz> */
-       .atag_offset    = 0x100,
-       .map_io         = omap15xx_map_io,
-       .init_early     = omap1_init_early,
-       .init_irq       = omap1_init_irq,
-       .handle_irq     = omap1_handle_irq,
-       .init_machine   = voiceblue_init,
-       .init_late      = omap1_init_late,
-       .init_time      = omap1_timer_init,
-       .restart        = voiceblue_restart,
-MACHINE_END
diff --git a/arch/arm/mach-omap1/include/mach/board-voiceblue.h b/arch/arm/mach-omap1/include/mach/board-voiceblue.h
deleted file mode 100644 (file)
index 27916b2..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2004 2N Telekomunikace, Ladislav Michl <michl@2n.cz>
- *
- * Hardware definitions for OMAP5910 based VoiceBlue board.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __ASM_ARCH_VOICEBLUE_H
-#define __ASM_ARCH_VOICEBLUE_H
-
-extern void voiceblue_wdt_enable(void);
-extern void voiceblue_wdt_disable(void);
-extern void voiceblue_wdt_ping(void);
-
-#endif /*  __ASM_ARCH_VOICEBLUE_H */
-
index b3a0dff67e3fc48bb34b13567778d0f178298834..33d1460a56391c397ef305d8ed8275fa94b15720 100644 (file)
@@ -49,6 +49,7 @@ config SOC_OMAP5
        select OMAP_INTERCONNECT
        select OMAP_INTERCONNECT_BARRIER
        select PM_OPP if PM
+       select ZONE_DMA if ARM_LPAE
 
 config SOC_AM33XX
        bool "TI AM33XX"
@@ -78,6 +79,7 @@ config SOC_DRA7XX
        select OMAP_INTERCONNECT
        select OMAP_INTERCONNECT_BARRIER
        select PM_OPP if PM
+       select ZONE_DMA if ARM_LPAE
 
 config ARCH_OMAP2PLUS
        bool
index 935869698cbc45ca0b59d5d75ad326a175549c1d..ceefcee6bb85a7042ac0a3e4c077347ce93543a5 100644 (file)
@@ -48,11 +48,9 @@ AFLAGS_sleep44xx.o                   :=-Wa,-march=armv7-a$(plus_sec)
 # Functions loaded to SRAM
 obj-$(CONFIG_SOC_OMAP2420)             += sram242x.o
 obj-$(CONFIG_SOC_OMAP2430)             += sram243x.o
-obj-$(CONFIG_ARCH_OMAP3)               += sram34xx.o
 
 AFLAGS_sram242x.o                      :=-Wa,-march=armv6
 AFLAGS_sram243x.o                      :=-Wa,-march=armv6
-AFLAGS_sram34xx.o                      :=-Wa,-march=armv7-a
 
 # Restart code (OMAP4/5 currently in omap4-common.c)
 obj-$(CONFIG_SOC_OMAP2420)             += omap2-restart.o
@@ -186,7 +184,6 @@ obj-$(CONFIG_ARCH_OMAP2)            += clkt2xxx_dpllcore.o
 obj-$(CONFIG_ARCH_OMAP2)               += clkt2xxx_virt_prcm_set.o
 obj-$(CONFIG_ARCH_OMAP2)               += clkt2xxx_dpll.o
 obj-$(CONFIG_ARCH_OMAP3)               += $(clock-common)
-obj-$(CONFIG_ARCH_OMAP3)               += clkt34xx_dpll3m2.o
 obj-$(CONFIG_ARCH_OMAP4)               += $(clock-common)
 obj-$(CONFIG_SOC_AM33XX)               += $(clock-common)
 obj-$(CONFIG_SOC_OMAP5)                        += $(clock-common)
index 6133eaac685df545ec5a6665db0ae72051d8c2fa..fb219a30c10c60ff56f8b6c0ae754a861f886dc0 100644 (file)
@@ -106,6 +106,7 @@ DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)")
 MACHINE_END
 
 static const char *const omap36xx_boards_compat[] __initconst = {
+       "ti,omap3630",
        "ti,omap36xx",
        NULL,
 };
@@ -243,6 +244,9 @@ static const char *const omap5_boards_compat[] __initconst = {
 };
 
 DT_MACHINE_START(OMAP5_DT, "Generic OMAP5 (Flattened Device Tree)")
+#if defined(CONFIG_ZONE_DMA) && defined(CONFIG_ARM_LPAE)
+       .dma_zone_size  = SZ_2G,
+#endif
        .reserve        = omap_reserve,
        .smp            = smp_ops(omap4_smp_ops),
        .map_io         = omap5_map_io,
@@ -288,6 +292,9 @@ static const char *const dra74x_boards_compat[] __initconst = {
 };
 
 DT_MACHINE_START(DRA74X_DT, "Generic DRA74X (Flattened Device Tree)")
+#if defined(CONFIG_ZONE_DMA) && defined(CONFIG_ARM_LPAE)
+       .dma_zone_size  = SZ_2G,
+#endif
        .reserve        = omap_reserve,
        .smp            = smp_ops(omap4_smp_ops),
        .map_io         = dra7xx_map_io,
@@ -308,6 +315,9 @@ static const char *const dra72x_boards_compat[] __initconst = {
 };
 
 DT_MACHINE_START(DRA72X_DT, "Generic DRA72X (Flattened Device Tree)")
+#if defined(CONFIG_ZONE_DMA) && defined(CONFIG_ARM_LPAE)
+       .dma_zone_size  = SZ_2G,
+#endif
        .reserve        = omap_reserve,
        .map_io         = dra7xx_map_io,
        .init_early     = dra7xx_init_early,
diff --git a/arch/arm/mach-omap2/clkt34xx_dpll3m2.c b/arch/arm/mach-omap2/clkt34xx_dpll3m2.c
deleted file mode 100644 (file)
index 3f65213..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * OMAP34xx M2 divider clock code
- *
- * Copyright (C) 2007-2008 Texas Instruments, Inc.
- * Copyright (C) 2007-2010 Nokia Corporation
- *
- * Paul Walmsley
- * Jouni Högander
- *
- * Parts of this code are based on code written by
- * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu
- *
- * 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.
- */
-#undef DEBUG
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-
-#include "clock.h"
-#include "clock3xxx.h"
-#include "sdrc.h"
-#include "sram.h"
-
-#define CYCLES_PER_MHZ                 1000000
-
-struct clk *sdrc_ick_p, *arm_fck_p;
-
-/*
- * CORE DPLL (DPLL3) M2 divider rate programming functions
- *
- * These call into SRAM code to do the actual CM writes, since the SDRAM
- * is clocked from DPLL3.
- */
-
-/**
- * omap3_core_dpll_m2_set_rate - set CORE DPLL M2 divider
- * @clk: struct clk * of DPLL to set
- * @rate: rounded target rate
- *
- * Program the DPLL M2 divider with the rounded target rate.  Returns
- * -EINVAL upon error, or 0 upon success.
- */
-int omap3_core_dpll_m2_set_rate(struct clk_hw *hw, unsigned long rate,
-                                       unsigned long parent_rate)
-{
-       struct clk_hw_omap *clk = to_clk_hw_omap(hw);
-       u32 new_div = 0;
-       u32 unlock_dll = 0;
-       u32 c;
-       unsigned long validrate, sdrcrate, _mpurate;
-       struct omap_sdrc_params *sdrc_cs0;
-       struct omap_sdrc_params *sdrc_cs1;
-       int ret;
-       unsigned long clkrate;
-
-       if (!clk || !rate)
-               return -EINVAL;
-
-       new_div = DIV_ROUND_UP(parent_rate, rate);
-       validrate = parent_rate / new_div;
-
-       if (validrate != rate)
-               return -EINVAL;
-
-       sdrcrate = clk_get_rate(sdrc_ick_p);
-       clkrate = clk_hw_get_rate(hw);
-       if (rate > clkrate)
-               sdrcrate <<= ((rate / clkrate) >> 1);
-       else
-               sdrcrate >>= ((clkrate / rate) >> 1);
-
-       ret = omap2_sdrc_get_params(sdrcrate, &sdrc_cs0, &sdrc_cs1);
-       if (ret)
-               return -EINVAL;
-
-       if (sdrcrate < MIN_SDRC_DLL_LOCK_FREQ) {
-               pr_debug("clock: will unlock SDRC DLL\n");
-               unlock_dll = 1;
-       }
-
-       /*
-        * XXX This only needs to be done when the CPU frequency changes
-        */
-       _mpurate = clk_get_rate(arm_fck_p) / CYCLES_PER_MHZ;
-       c = (_mpurate << SDRC_MPURATE_SCALE) >> SDRC_MPURATE_BASE_SHIFT;
-       c += 1;  /* for safety */
-       c *= SDRC_MPURATE_LOOPS;
-       c >>= SDRC_MPURATE_SCALE;
-       if (c == 0)
-               c = 1;
-
-       pr_debug("clock: changing CORE DPLL rate from %lu to %lu\n",
-                clkrate, validrate);
-       pr_debug("clock: SDRC CS0 timing params used: RFR %08x CTRLA %08x CTRLB %08x MR %08x\n",
-                sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
-                sdrc_cs0->actim_ctrlb, sdrc_cs0->mr);
-       if (sdrc_cs1)
-               pr_debug("clock: SDRC CS1 timing params used: RFR %08x CTRLA %08x CTRLB %08x MR %08x\n",
-                        sdrc_cs1->rfr_ctrl, sdrc_cs1->actim_ctrla,
-                        sdrc_cs1->actim_ctrlb, sdrc_cs1->mr);
-
-       if (sdrc_cs1)
-               omap3_configure_core_dpll(
-                                 new_div, unlock_dll, c, rate > clkrate,
-                                 sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
-                                 sdrc_cs0->actim_ctrlb, sdrc_cs0->mr,
-                                 sdrc_cs1->rfr_ctrl, sdrc_cs1->actim_ctrla,
-                                 sdrc_cs1->actim_ctrlb, sdrc_cs1->mr);
-       else
-               omap3_configure_core_dpll(
-                                 new_div, unlock_dll, c, rate > clkrate,
-                                 sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
-                                 sdrc_cs0->actim_ctrlb, sdrc_cs0->mr,
-                                 0, 0, 0, 0);
-       return 0;
-}
-
index a69bd67e9028030372309ee6c80d2265493c4967..9374da313e8e3ddd86b8b3dcc10ce7d368795fa5 100644 (file)
@@ -33,7 +33,6 @@
 #include "common.h"
 #include "mux.h"
 #include "control.h"
-#include "devices.h"
 #include "display.h"
 
 #define L3_MODULES_MAX_LEN 12
@@ -67,58 +66,6 @@ static int __init omap3_l3_init(void)
 }
 omap_postcore_initcall(omap3_l3_init);
 
-#if defined(CONFIG_IOMMU_API)
-
-#include <linux/platform_data/iommu-omap.h>
-
-static struct resource omap3isp_resources[] = {
-       {
-               .start          = OMAP3430_ISP_BASE,
-               .end            = OMAP3430_ISP_BASE + 0x12fc,
-               .flags          = IORESOURCE_MEM,
-       },
-       {
-               .start          = OMAP3430_ISP_BASE2,
-               .end            = OMAP3430_ISP_BASE2 + 0x0600,
-               .flags          = IORESOURCE_MEM,
-       },
-       {
-               .start          = 24 + OMAP_INTC_START,
-               .flags          = IORESOURCE_IRQ,
-       }
-};
-
-static struct platform_device omap3isp_device = {
-       .name           = "omap3isp",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(omap3isp_resources),
-       .resource       = omap3isp_resources,
-};
-
-static struct omap_iommu_arch_data omap3_isp_iommu = {
-       .name = "mmu_isp",
-};
-
-int omap3_init_camera(struct isp_platform_data *pdata)
-{
-       if (of_have_populated_dt())
-               omap3_isp_iommu.name = "480bd400.mmu";
-
-       omap3isp_device.dev.platform_data = pdata;
-       omap3isp_device.dev.archdata.iommu = &omap3_isp_iommu;
-
-       return platform_device_register(&omap3isp_device);
-}
-
-#else /* !CONFIG_IOMMU_API */
-
-int omap3_init_camera(struct isp_platform_data *pdata)
-{
-       return 0;
-}
-
-#endif
-
 #if defined(CONFIG_OMAP2PLUS_MBOX) || defined(CONFIG_OMAP2PLUS_MBOX_MODULE)
 static inline void __init omap_init_mbox(void)
 {
diff --git a/arch/arm/mach-omap2/devices.h b/arch/arm/mach-omap2/devices.h
deleted file mode 100644 (file)
index f61eb6e..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * arch/arm/mach-omap2/devices.h
- *
- * OMAP2 platform device setup/initialization
- *
- * 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 __ARCH_ARM_MACH_OMAP_DEVICES_H
-#define __ARCH_ARM_MACH_OMAP_DEVICES_H
-
-struct isp_platform_data;
-
-int omap3_init_camera(struct isp_platform_data *pdata);
-
-#endif
index 971791fe9a3f2f684c81ca4ccdecde5e6eec93ed..593fec753b282a40b54bedb6d26c53131b78a83c 100644 (file)
@@ -27,7 +27,7 @@
  * platform-specific code to shutdown a CPU
  * Called with IRQs disabled
  */
-void __ref omap4_cpu_die(unsigned int cpu)
+void omap4_cpu_die(unsigned int cpu)
 {
        unsigned int boot_cpu = 0;
        void __iomem *base = omap_get_wakeupgen_base();
index e1d2e991d17a31fc15f1c44616c9b4b7f9de3a84..68768a1dd8a875c455589145c9fe75632bb0d2bc 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/irq.h>
+#include <linux/irqchip.h>
 #include <linux/irqdomain.h>
 #include <linux/of_address.h>
 #include <linux/platform_device.h>
@@ -330,7 +331,7 @@ static int irq_cpu_hotplug_notify(struct notifier_block *self,
        return NOTIFY_OK;
 }
 
-static struct notifier_block __refdata irq_hotplug_notifier = {
+static struct notifier_block irq_hotplug_notifier = {
        .notifier_call = irq_cpu_hotplug_notify,
 };
 
@@ -537,9 +538,4 @@ static int __init wakeupgen_init(struct device_node *node,
 
        return 0;
 }
-
-/*
- * We cannot use the IRQCHIP_DECLARE macro that lives in
- * drivers/irqchip, so we're forced to roll our own. Not very nice.
- */
-OF_DECLARE_2(irqchip, ti_wakeupgen, "ti,omap4-wugen-mpu", wakeupgen_init);
+IRQCHIP_DECLARE(ti_wakeupgen, "ti,omap4-wugen-mpu", wakeupgen_init);
index ea56397599c21b1f0c7d806ccfe9b1f4fb062f52..1dfe34654c43a353a34ac2cb9b941ff9f951b275 100644 (file)
@@ -559,7 +559,14 @@ static void pdata_quirks_check(struct pdata_init *quirks)
 
 void __init pdata_quirks_init(const struct of_device_id *omap_dt_match_table)
 {
-       omap_sdrc_init(NULL, NULL);
+       /*
+        * We still need this for omap2420 and omap3 PM to work, others are
+        * using drivers/misc/sram.c already.
+        */
+       if (of_machine_is_compatible("ti,omap2420") ||
+           of_machine_is_compatible("ti,omap3"))
+               omap_sdrc_init(NULL, NULL);
+
        pdata_quirks_check(auxdata_quirks);
        of_platform_populate(NULL, omap_dt_match_table,
                             omap_auxdata_lookup, NULL);
index d697cecf762b4501b8c3849d2bece4b25ab86967..178e22c146b7acc786ef9c32cae01ca6cdd480b9 100644 (file)
@@ -210,7 +210,7 @@ static inline int omap4plus_init_static_deps(const struct static_dep_map *map)
                }
 
                map++;
-       };
+       }
 
        return 0;
 }
index d31c495175c1aa3daaff7da2f65b8ac3075b6232..2e00c7f1f4714a822329e6e4a7e8335223c83970 100644 (file)
@@ -582,7 +582,7 @@ void __init omap3xxx_powerdomains_init(void)
 
        /* Only 81xx needs custom pwrdm_operations */
        if (!cpu_is_ti81xx())
-               pwrdm_register_platform_funcs(&omap3_pwrdm_operations);;
+               pwrdm_register_platform_funcs(&omap3_pwrdm_operations);
 
        rev = omap_rev();
 
index cd488b80ba36ed621e69828ab4d847e26259498c..83d0e61f49e64cded35f31761219ebc3a4ad82ac 100644 (file)
@@ -211,35 +211,10 @@ static inline int omap243x_sram_init(void)
 
 #ifdef CONFIG_ARCH_OMAP3
 
-static u32 (*_omap3_sram_configure_core_dpll)(
-                       u32 m2, u32 unlock_dll, u32 f, u32 inc,
-                       u32 sdrc_rfr_ctrl_0, u32 sdrc_actim_ctrl_a_0,
-                       u32 sdrc_actim_ctrl_b_0, u32 sdrc_mr_0,
-                       u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1,
-                       u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1);
-
-u32 omap3_configure_core_dpll(u32 m2, u32 unlock_dll, u32 f, u32 inc,
-                       u32 sdrc_rfr_ctrl_0, u32 sdrc_actim_ctrl_a_0,
-                       u32 sdrc_actim_ctrl_b_0, u32 sdrc_mr_0,
-                       u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1,
-                       u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1)
-{
-       BUG_ON(!_omap3_sram_configure_core_dpll);
-       return _omap3_sram_configure_core_dpll(
-                       m2, unlock_dll, f, inc,
-                       sdrc_rfr_ctrl_0, sdrc_actim_ctrl_a_0,
-                       sdrc_actim_ctrl_b_0, sdrc_mr_0,
-                       sdrc_rfr_ctrl_1, sdrc_actim_ctrl_a_1,
-                       sdrc_actim_ctrl_b_1, sdrc_mr_1);
-}
-
 void omap3_sram_restore_context(void)
 {
        omap_sram_reset();
 
-       _omap3_sram_configure_core_dpll =
-               omap_sram_push(omap3_sram_configure_core_dpll,
-                              omap3_sram_configure_core_dpll_sz);
        omap_push_sram_idle();
 }
 
index 948d3edefc3865504bd87ea328b55b9b3713ef6f..18dc884267fa6b6efa37a18596843e4e595773e3 100644 (file)
@@ -15,12 +15,6 @@ extern void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val,
                                      u32 mem_type);
 extern u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass);
 
-extern u32 omap3_configure_core_dpll(
-                       u32 m2, u32 unlock_dll, u32 f, u32 inc,
-                       u32 sdrc_rfr_ctrl_0, u32 sdrc_actim_ctrl_a_0,
-                       u32 sdrc_actim_ctrl_b_0, u32 sdrc_mr_0,
-                       u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1,
-                       u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1);
 extern void omap3_sram_restore_context(void);
 
 /* Do not use these */
@@ -52,14 +46,6 @@ extern void omap243x_sram_reprogram_sdrc(u32 perf_level, u32 dll_val,
                                                u32 mem_type);
 extern unsigned long omap243x_sram_reprogram_sdrc_sz;
 
-extern u32 omap3_sram_configure_core_dpll(
-                       u32 m2, u32 unlock_dll, u32 f, u32 inc,
-                       u32 sdrc_rfr_ctrl_0, u32 sdrc_actim_ctrl_a_0,
-                       u32 sdrc_actim_ctrl_b_0, u32 sdrc_mr_0,
-                       u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1,
-                       u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1);
-extern unsigned long omap3_sram_configure_core_dpll_sz;
-
 #ifdef CONFIG_PM
 extern void omap_push_sram_idle(void);
 #else
diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S
deleted file mode 100644 (file)
index 1446331..0000000
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * linux/arch/arm/mach-omap3/sram.S
- *
- * Omap3 specific functions that need to be run in internal SRAM
- *
- * Copyright (C) 2004, 2007, 2008 Texas Instruments, Inc.
- * Copyright (C) 2008 Nokia Corporation
- *
- * Rajendra Nayak <rnayak@ti.com>
- * Richard Woodruff <r-woodruff2@ti.com>
- * Paul Walmsley
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-#include <linux/linkage.h>
-
-#include <asm/assembler.h>
-
-#include "soc.h"
-#include "iomap.h"
-#include "sdrc.h"
-#include "cm3xxx.h"
-
-/*
- * This file needs be built unconditionally as ARM to interoperate correctly
- * with non-Thumb-2-capable firmware.
- */
-       .arm
-
-       .text
-
-/* r1 parameters */
-#define SDRC_NO_UNLOCK_DLL             0x0
-#define SDRC_UNLOCK_DLL                        0x1
-
-/* SDRC_DLLA_CTRL bit settings */
-#define FIXEDDELAY_SHIFT               24
-#define FIXEDDELAY_MASK                        (0xff << FIXEDDELAY_SHIFT)
-#define DLLIDLE_MASK                   0x4
-
-/*
- * SDRC_DLLA_CTRL default values: TI hardware team indicates that
- * FIXEDDELAY should be initialized to 0xf.  This apparently was
- * empirically determined during process testing, so no derivation
- * was provided.
- */
-#define FIXEDDELAY_DEFAULT             (0x0f << FIXEDDELAY_SHIFT)
-
-/* SDRC_DLLA_STATUS bit settings */
-#define LOCKSTATUS_MASK                        0x4
-
-/* SDRC_POWER bit settings */
-#define SRFRONIDLEREQ_MASK             0x40
-
-/* CM_IDLEST1_CORE bit settings */
-#define ST_SDRC_MASK                   0x2
-
-/* CM_ICLKEN1_CORE bit settings */
-#define EN_SDRC_MASK                   0x2
-
-/* CM_CLKSEL1_PLL bit settings */
-#define CORE_DPLL_CLKOUT_DIV_SHIFT     0x1b
-
-/*
- * omap3_sram_configure_core_dpll - change DPLL3 M2 divider
- *
- * Params passed in registers:
- *  r0 = new M2 divider setting (only 1 and 2 supported right now)
- *  r1 = unlock SDRC DLL? (1 = yes, 0 = no).  Only unlock DLL for
- *      SDRC rates < 83MHz
- *  r2 = number of MPU cycles to wait for SDRC to stabilize after
- *      reprogramming the SDRC when switching to a slower MPU speed
- *  r3 = increasing SDRC rate? (1 = yes, 0 = no)
- *
- * Params passed via the stack. The needed params will be copied in SRAM
- *  before use by the code in SRAM (SDRAM is not accessible during SDRC
- *  reconfiguration):
- *  new SDRC_RFR_CTRL_0 register contents
- *  new SDRC_ACTIM_CTRL_A_0 register contents
- *  new SDRC_ACTIM_CTRL_B_0 register contents
- *  new SDRC_MR_0 register value
- *  new SDRC_RFR_CTRL_1 register contents
- *  new SDRC_ACTIM_CTRL_A_1 register contents
- *  new SDRC_ACTIM_CTRL_B_1 register contents
- *  new SDRC_MR_1 register value
- *
- * If the param SDRC_RFR_CTRL_1 is 0, the parameters are not programmed into
- * the SDRC CS1 registers
- *
- * NOTE: This code no longer attempts to program the SDRC AC timing and MR
- * registers.  This is because the code currently cannot ensure that all
- * L3 initiators (e.g., sDMA, IVA, DSS DISPC, etc.) are not accessing the
- * SDRAM when the registers are written.  If the registers are changed while
- * an initiator is accessing SDRAM, memory can be corrupted and/or the SDRC
- * may enter an unpredictable state.  In the future, the intent is to
- * re-enable this code in cases where we can ensure that no initiators are
- * touching the SDRAM.  Until that time, users who know that their use case
- * can satisfy the above requirement can enable the CONFIG_OMAP3_SDRC_AC_TIMING
- * option.
- *
- * Richard Woodruff notes that any changes to this code must be carefully
- * audited and tested to ensure that they don't cause a TLB miss while
- * the SDRAM is inaccessible.  Such a situation will crash the system
- * since it will cause the ARM MMU to attempt to walk the page tables.
- * These crashes may be intermittent.
- */
-       .align  3
-ENTRY(omap3_sram_configure_core_dpll)
-       stmfd   sp!, {r1-r12, lr}       @ store regs to stack
-
-                                       @ pull the extra args off the stack
-                                       @  and store them in SRAM
-
-/*
- * PC-relative stores are deprecated in ARMv7 and lead to undefined behaviour
- * in Thumb-2: use a r7 as a base instead.
- * Be careful not to clobber r7 when maintaing this file.
- */
- THUMB(        adr     r7, omap3_sram_configure_core_dpll                      )
-       .macro strtext Rt:req, label:req
- ARM(  str     \Rt, \label                                             )
- THUMB(        str     \Rt, [r7, \label - omap3_sram_configure_core_dpll]      )
-       .endm
-
-       ldr     r4, [sp, #52]
-       strtext r4, omap_sdrc_rfr_ctrl_0_val
-       ldr     r4, [sp, #56]
-       strtext r4, omap_sdrc_actim_ctrl_a_0_val
-       ldr     r4, [sp, #60]
-       strtext r4, omap_sdrc_actim_ctrl_b_0_val
-       ldr     r4, [sp, #64]
-       strtext r4, omap_sdrc_mr_0_val
-       ldr     r4, [sp, #68]
-       strtext r4, omap_sdrc_rfr_ctrl_1_val
-       cmp     r4, #0                  @ if SDRC_RFR_CTRL_1 is 0,
-       beq     skip_cs1_params         @  do not use cs1 params
-       ldr     r4, [sp, #72]
-       strtext r4, omap_sdrc_actim_ctrl_a_1_val
-       ldr     r4, [sp, #76]
-       strtext r4, omap_sdrc_actim_ctrl_b_1_val
-       ldr     r4, [sp, #80]
-       strtext r4, omap_sdrc_mr_1_val
-skip_cs1_params:
-       mrc     p15, 0, r8, c1, c0, 0   @ read ctrl register
-       bic     r10, r8, #0x800         @ clear Z-bit, disable branch prediction
-       mcr     p15, 0, r10, c1, c0, 0  @ write ctrl register
-       dsb                             @ flush buffered writes to interconnect
-       isb                             @ prevent speculative exec past here
-       cmp     r3, #1                  @ if increasing SDRC clk rate,
-       bleq    configure_sdrc          @ program the SDRC regs early (for RFR)
-       cmp     r1, #SDRC_UNLOCK_DLL    @ set the intended DLL state
-       bleq    unlock_dll
-       blne    lock_dll
-       bl      sdram_in_selfrefresh    @ put SDRAM in self refresh, idle SDRC
-       bl      configure_core_dpll     @ change the DPLL3 M2 divider
-       mov     r12, r2
-       bl      wait_clk_stable         @ wait for SDRC to stabilize
-       bl      enable_sdrc             @ take SDRC out of idle
-       cmp     r1, #SDRC_UNLOCK_DLL    @ wait for DLL status to change
-       bleq    wait_dll_unlock
-       blne    wait_dll_lock
-       cmp     r3, #1                  @ if increasing SDRC clk rate,
-       beq     return_to_sdram         @ return to SDRAM code, otherwise,
-       bl      configure_sdrc          @ reprogram SDRC regs now
-return_to_sdram:
-       mcr     p15, 0, r8, c1, c0, 0   @ restore ctrl register
-       isb                             @ prevent speculative exec past here
-       mov     r0, #0                  @ return value
-       ldmfd   sp!, {r1-r12, pc}       @ restore regs and return
-unlock_dll:
-       ldr     r11, omap3_sdrc_dlla_ctrl
-       ldr     r12, [r11]
-       bic     r12, r12, #FIXEDDELAY_MASK
-       orr     r12, r12, #FIXEDDELAY_DEFAULT
-       orr     r12, r12, #DLLIDLE_MASK
-       str     r12, [r11]              @ (no OCP barrier needed)
-       bx      lr
-lock_dll:
-       ldr     r11, omap3_sdrc_dlla_ctrl
-       ldr     r12, [r11]
-       bic     r12, r12, #DLLIDLE_MASK
-       str     r12, [r11]              @ (no OCP barrier needed)
-       bx      lr
-sdram_in_selfrefresh:
-       ldr     r11, omap3_sdrc_power   @ read the SDRC_POWER register
-       ldr     r12, [r11]              @ read the contents of SDRC_POWER
-       mov     r9, r12                 @ keep a copy of SDRC_POWER bits
-       orr     r12, r12, #SRFRONIDLEREQ_MASK   @ enable self refresh on idle
-       str     r12, [r11]              @ write back to SDRC_POWER register
-       ldr     r12, [r11]              @ posted-write barrier for SDRC
-idle_sdrc:
-       ldr     r11, omap3_cm_iclken1_core      @ read the CM_ICLKEN1_CORE reg
-       ldr     r12, [r11]
-       bic     r12, r12, #EN_SDRC_MASK         @ disable iclk bit for SDRC
-       str     r12, [r11]
-wait_sdrc_idle:
-       ldr     r11, omap3_cm_idlest1_core
-       ldr     r12, [r11]
-       and     r12, r12, #ST_SDRC_MASK         @ check for SDRC idle
-       cmp     r12, #ST_SDRC_MASK
-       bne     wait_sdrc_idle
-       bx      lr
-configure_core_dpll:
-       ldr     r11, omap3_cm_clksel1_pll
-       ldr     r12, [r11]
-       ldr     r10, core_m2_mask_val   @ modify m2 for core dpll
-       and     r12, r12, r10
-       orr     r12, r12, r0, lsl #CORE_DPLL_CLKOUT_DIV_SHIFT
-       str     r12, [r11]
-       ldr     r12, [r11]              @ posted-write barrier for CM
-       bx      lr
-wait_clk_stable:
-       subs    r12, r12, #1
-       bne     wait_clk_stable
-       bx      lr
-enable_sdrc:
-       ldr     r11, omap3_cm_iclken1_core
-       ldr     r12, [r11]
-       orr     r12, r12, #EN_SDRC_MASK         @ enable iclk bit for SDRC
-       str     r12, [r11]
-wait_sdrc_idle1:
-       ldr     r11, omap3_cm_idlest1_core
-       ldr     r12, [r11]
-       and     r12, r12, #ST_SDRC_MASK
-       cmp     r12, #0
-       bne     wait_sdrc_idle1
-restore_sdrc_power_val:
-       ldr     r11, omap3_sdrc_power
-       str     r9, [r11]               @ restore SDRC_POWER, no barrier needed
-       bx      lr
-wait_dll_lock:
-       ldr     r11, omap3_sdrc_dlla_status
-       ldr     r12, [r11]
-       and     r12, r12, #LOCKSTATUS_MASK
-       cmp     r12, #LOCKSTATUS_MASK
-       bne     wait_dll_lock
-       bx      lr
-wait_dll_unlock:
-       ldr     r11, omap3_sdrc_dlla_status
-       ldr     r12, [r11]
-       and     r12, r12, #LOCKSTATUS_MASK
-       cmp     r12, #0x0
-       bne     wait_dll_unlock
-       bx      lr
-configure_sdrc:
-       ldr     r12, omap_sdrc_rfr_ctrl_0_val   @ fetch value from SRAM
-       ldr     r11, omap3_sdrc_rfr_ctrl_0      @ fetch addr from SRAM
-       str     r12, [r11]                      @ store
-#ifdef CONFIG_OMAP3_SDRC_AC_TIMING
-       ldr     r12, omap_sdrc_actim_ctrl_a_0_val
-       ldr     r11, omap3_sdrc_actim_ctrl_a_0
-       str     r12, [r11]
-       ldr     r12, omap_sdrc_actim_ctrl_b_0_val
-       ldr     r11, omap3_sdrc_actim_ctrl_b_0
-       str     r12, [r11]
-       ldr     r12, omap_sdrc_mr_0_val
-       ldr     r11, omap3_sdrc_mr_0
-       str     r12, [r11]
-#endif
-       ldr     r12, omap_sdrc_rfr_ctrl_1_val
-       cmp     r12, #0                 @ if SDRC_RFR_CTRL_1 is 0,
-       beq     skip_cs1_prog           @  do not program cs1 params
-       ldr     r11, omap3_sdrc_rfr_ctrl_1
-       str     r12, [r11]
-#ifdef CONFIG_OMAP3_SDRC_AC_TIMING
-       ldr     r12, omap_sdrc_actim_ctrl_a_1_val
-       ldr     r11, omap3_sdrc_actim_ctrl_a_1
-       str     r12, [r11]
-       ldr     r12, omap_sdrc_actim_ctrl_b_1_val
-       ldr     r11, omap3_sdrc_actim_ctrl_b_1
-       str     r12, [r11]
-       ldr     r12, omap_sdrc_mr_1_val
-       ldr     r11, omap3_sdrc_mr_1
-       str     r12, [r11]
-#endif
-skip_cs1_prog:
-       ldr     r12, [r11]              @ posted-write barrier for SDRC
-       bx      lr
-
-       .align
-omap3_sdrc_power:
-       .word OMAP34XX_SDRC_REGADDR(SDRC_POWER)
-omap3_cm_clksel1_pll:
-       .word OMAP34XX_CM_REGADDR(PLL_MOD, CM_CLKSEL1)
-omap3_cm_idlest1_core:
-       .word OMAP34XX_CM_REGADDR(CORE_MOD, CM_IDLEST)
-omap3_cm_iclken1_core:
-       .word OMAP34XX_CM_REGADDR(CORE_MOD, CM_ICLKEN1)
-
-omap3_sdrc_rfr_ctrl_0:
-       .word OMAP34XX_SDRC_REGADDR(SDRC_RFR_CTRL_0)
-omap3_sdrc_rfr_ctrl_1:
-       .word OMAP34XX_SDRC_REGADDR(SDRC_RFR_CTRL_1)
-omap3_sdrc_actim_ctrl_a_0:
-       .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_A_0)
-omap3_sdrc_actim_ctrl_a_1:
-       .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_A_1)
-omap3_sdrc_actim_ctrl_b_0:
-       .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_B_0)
-omap3_sdrc_actim_ctrl_b_1:
-       .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_B_1)
-omap3_sdrc_mr_0:
-       .word OMAP34XX_SDRC_REGADDR(SDRC_MR_0)
-omap3_sdrc_mr_1:
-       .word OMAP34XX_SDRC_REGADDR(SDRC_MR_1)
-omap_sdrc_rfr_ctrl_0_val:
-       .word 0xDEADBEEF
-omap_sdrc_rfr_ctrl_1_val:
-       .word 0xDEADBEEF
-omap_sdrc_actim_ctrl_a_0_val:
-       .word 0xDEADBEEF
-omap_sdrc_actim_ctrl_a_1_val:
-       .word 0xDEADBEEF
-omap_sdrc_actim_ctrl_b_0_val:
-       .word 0xDEADBEEF
-omap_sdrc_actim_ctrl_b_1_val:
-       .word 0xDEADBEEF
-omap_sdrc_mr_0_val:
-       .word 0xDEADBEEF
-omap_sdrc_mr_1_val:
-       .word 0xDEADBEEF
-
-omap3_sdrc_dlla_status:
-       .word OMAP34XX_SDRC_REGADDR(SDRC_DLLA_STATUS)
-omap3_sdrc_dlla_ctrl:
-       .word OMAP34XX_SDRC_REGADDR(SDRC_DLLA_CTRL)
-core_m2_mask_val:
-       .word 0x07FFFFFF
-ENDPROC(omap3_sram_configure_core_dpll)
-
-ENTRY(omap3_sram_configure_core_dpll_sz)
-       .word   . - omap3_sram_configure_core_dpll
-
index d44d311704ba97e72a8736d79cfb024ebc78a214..2028167fff310041cf54037798f81cc8efa9efc2 100644 (file)
@@ -280,10 +280,6 @@ void omap3_vc_set_pmic_signaling(int core_next_state)
        }
 }
 
-#define PRM_POLCTRL_TWL_MASK   (OMAP3430_PRM_POLCTRL_CLKREQ_POL | \
-                                       OMAP3430_PRM_POLCTRL_CLKREQ_POL)
-#define PRM_POLCTRL_TWL_VAL    OMAP3430_PRM_POLCTRL_CLKREQ_POL
-
 /*
  * Configure signal polarity for sys_clkreq and sys_off_mode pins
  * as the default values are wrong and can cause the system to hang
index 08d2be2ea41f43c8273de58924741da7c72f6e43..66f1c952c0483d4dc5830fe66fd66bcf4f058f40 100644 (file)
@@ -45,6 +45,7 @@ config MACH_KUROBOX_PRO
 
 config MACH_DNS323
        bool "D-Link DNS-323"
+       select GENERIC_NET_UTILS
        select I2C_BOARDINFO
        help
          Say 'Y' here if you want your kernel to support the
@@ -52,6 +53,7 @@ config MACH_DNS323
 
 config MACH_TS209
        bool "QNAP TS-109/TS-209"
+       select GENERIC_NET_UTILS
        help
          Say 'Y' here if you want your kernel to support the
          QNAP TS-109/TS-209 platform.
@@ -93,6 +95,7 @@ config MACH_LINKSTATION_LS_HGL
 
 config MACH_TS409
        bool "QNAP TS-409"
+       select GENERIC_NET_UTILS
        help
          Say 'Y' here if you want your kernel to support the
          QNAP TS-409 platform.
index f267e58a82833b45647608aea78990bc5e673a0a..bc279a8530753ea6531dbb0b5098498d86fa78de 100644 (file)
@@ -173,42 +173,10 @@ static struct mv643xx_eth_platform_data dns323_eth_data = {
        .phy_addr = MV643XX_ETH_PHY_ADDR(8),
 };
 
-/* dns323_parse_hex_*() taken from tsx09-common.c; should a common copy of these
- * functions be kept somewhere?
- */
-static int __init dns323_parse_hex_nibble(char n)
-{
-       if (n >= '0' && n <= '9')
-               return n - '0';
-
-       if (n >= 'A' && n <= 'F')
-               return n - 'A' + 10;
-
-       if (n >= 'a' && n <= 'f')
-               return n - 'a' + 10;
-
-       return -1;
-}
-
-static int __init dns323_parse_hex_byte(const char *b)
-{
-       int hi;
-       int lo;
-
-       hi = dns323_parse_hex_nibble(b[0]);
-       lo = dns323_parse_hex_nibble(b[1]);
-
-       if (hi < 0 || lo < 0)
-               return -1;
-
-       return (hi << 4) | lo;
-}
-
 static int __init dns323_read_mac_addr(void)
 {
        u_int8_t addr[6];
-       int i;
-       char *mac_page;
+       void __iomem *mac_page;
 
        /* MAC address is stored as a regular ol' string in /dev/mtdblock4
         * (0x007d0000-0x00800000) starting at offset 196480 (0x2ff80).
@@ -217,23 +185,8 @@ static int __init dns323_read_mac_addr(void)
        if (!mac_page)
                return -ENOMEM;
 
-       /* Sanity check the string we're looking at */
-       for (i = 0; i < 5; i++) {
-               if (*(mac_page + (i * 3) + 2) != ':') {
-                       goto error_fail;
-               }
-       }
-
-       for (i = 0; i < 6; i++) {
-               int byte;
-
-               byte = dns323_parse_hex_byte(mac_page + (i * 3));
-               if (byte < 0) {
-                       goto error_fail;
-               }
-
-               addr[i] = byte;
-       }
+       if (!mac_pton((__force const char *) mac_page, addr))
+               goto error_fail;
 
        iounmap(mac_page);
        printk("DNS-323: Found ethernet MAC address: %pM\n", addr);
index 24b2959719faf1d93e240436cc486463cf52a6f7..d42e006597c7b1e1cf4078972669b0cec3bfd6d0 100644 (file)
@@ -53,53 +53,12 @@ struct mv643xx_eth_platform_data qnap_tsx09_eth_data = {
        .phy_addr       = MV643XX_ETH_PHY_ADDR(8),
 };
 
-static int __init qnap_tsx09_parse_hex_nibble(char n)
-{
-       if (n >= '0' && n <= '9')
-               return n - '0';
-
-       if (n >= 'A' && n <= 'F')
-               return n - 'A' + 10;
-
-       if (n >= 'a' && n <= 'f')
-               return n - 'a' + 10;
-
-       return -1;
-}
-
-static int __init qnap_tsx09_parse_hex_byte(const char *b)
-{
-       int hi;
-       int lo;
-
-       hi = qnap_tsx09_parse_hex_nibble(b[0]);
-       lo = qnap_tsx09_parse_hex_nibble(b[1]);
-
-       if (hi < 0 || lo < 0)
-               return -1;
-
-       return (hi << 4) | lo;
-}
-
 static int __init qnap_tsx09_check_mac_addr(const char *addr_str)
 {
        u_int8_t addr[6];
-       int i;
 
-       for (i = 0; i < 6; i++) {
-               int byte;
-
-               /*
-                * Enforce "xx:xx:xx:xx:xx:xx\n" format.
-                */
-               if (addr_str[(i * 3) + 2] != ((i < 5) ? ':' : '\n'))
-                       return -1;
-
-               byte = qnap_tsx09_parse_hex_byte(addr_str + (i * 3));
-               if (byte < 0)
-                       return -1;
-               addr[i] = byte;
-       }
+       if (!mac_pton(addr_str, addr))
+               return -1;
 
        printk(KERN_INFO "tsx09: found ethernet mac address %pM\n", addr);
 
@@ -118,12 +77,12 @@ void __init qnap_tsx09_find_mac_addr(u32 mem_base, u32 size)
        unsigned long addr;
 
        for (addr = mem_base; addr < (mem_base + size); addr += 1024) {
-               char *nor_page;
+               void __iomem *nor_page;
                int ret = 0;
 
                nor_page = ioremap(addr, 1024);
                if (nor_page != NULL) {
-                       ret = qnap_tsx09_check_mac_addr(nor_page);
+                       ret = qnap_tsx09_check_mac_addr((__force const char *)nor_page);
                        iounmap(nor_page);
                }
 
index 0ab2f8bae28e2aa9fce403175fdc87e278bc766a..a728c78b996f7fa0e1050f9e79c775cfa14b42da 100644 (file)
@@ -32,7 +32,7 @@ static inline void platform_do_lowpower(unsigned int cpu)
  *
  * Called with IRQs disabled
  */
-void __ref sirfsoc_cpu_die(unsigned int cpu)
+void sirfsoc_cpu_die(unsigned int cpu)
 {
        platform_do_lowpower(cpu);
 }
index 5851f4c254c1618cc4a8e433491b3e08e8e5448b..a7dae60810e8717c09eda1058e934d546dd66ddc 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/dm9000.h>
 #include <linux/leds.h>
 #include <linux/rtc-v3020.h>
+#include <linux/pwm.h>
 #include <linux/pwm_backlight.h>
 
 #include <linux/i2c.h>
@@ -305,11 +306,14 @@ static inline void cm_x300_init_lcd(void) {}
 #endif
 
 #if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE)
+static struct pwm_lookup cm_x300_pwm_lookup[] = {
+       PWM_LOOKUP("pxa27x-pwm.0", 1, "pwm-backlight.0", NULL, 10000,
+                  PWM_POLARITY_NORMAL),
+};
+
 static struct platform_pwm_backlight_data cm_x300_backlight_data = {
-       .pwm_id         = 2,
        .max_brightness = 100,
        .dft_brightness = 100,
-       .pwm_period_ns  = 10000,
        .enable_gpio    = -1,
 };
 
@@ -323,6 +327,7 @@ static struct platform_device cm_x300_backlight_device = {
 
 static void cm_x300_init_bl(void)
 {
+       pwm_add_table(cm_x300_pwm_lookup, ARRAY_SIZE(cm_x300_pwm_lookup));
        platform_device_register(&cm_x300_backlight_device);
 }
 #else
index 3aa264640c9dd5a0457b99e5a34897bd684ad3ba..db20d25daaabbfb0f35e09a1dd3d79feaa924e88 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/ioport.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
+#include <linux/pwm.h>
 #include <linux/pwm_backlight.h>
 #include <linux/i2c/pxa-i2c.h>
 
@@ -184,11 +185,14 @@ static inline void income_lcd_init(void) {}
  * Backlight
  ******************************************************************************/
 #if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE)
+static struct pwm_lookup income_pwm_lookup[] = {
+       PWM_LOOKUP("pxa27x-pwm.0", 0, "pwm-backlight.0", NULL, 1000000,
+                  PWM_POLARITY_NORMAL),
+};
+
 static struct platform_pwm_backlight_data income_backlight_data = {
-       .pwm_id         = 0,
        .max_brightness = 0x3ff,
        .dft_brightness = 0x1ff,
-       .pwm_period_ns  = 1000000,
        .enable_gpio    = -1,
 };
 
@@ -202,6 +206,7 @@ static struct platform_device income_backlight = {
 
 static void __init income_pwm_init(void)
 {
+       pwm_add_table(income_pwm_lookup, ARRAY_SIZE(income_pwm_lookup));
        platform_device_register(&income_backlight);
 }
 #else
index c62473235a1332b3c7211a408b9a4501b116c211..2a6e0ae2b92050bb35547a54ef345e1b93a6f8a4 100644 (file)
@@ -395,6 +395,26 @@ static struct resource pxa_ir_resources[] = {
                .end    = IRQ_ICP,
                .flags  = IORESOURCE_IRQ,
        },
+       [3] = {
+               .start  = 0x40800000,
+               .end    = 0x4080001b,
+               .flags  = IORESOURCE_MEM,
+       },
+       [4] = {
+               .start  = 0x40700000,
+               .end    = 0x40700023,
+               .flags  = IORESOURCE_MEM,
+       },
+       [5] = {
+               .start  = 17,
+               .end    = 17,
+               .flags  = IORESOURCE_DMA,
+       },
+       [6] = {
+               .start  = 18,
+               .end    = 18,
+               .flags  = IORESOURCE_DMA,
+       },
 };
 
 struct platform_device pxa_device_ficp = {
index ab93441e596ed7eb6d3e0f4552d029626e81e42c..9a9c15bfcd3451f02c115238813b2193db266844 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
+#include <linux/pwm.h>
 #include <linux/pwm_backlight.h>
 #include <linux/input.h>
 #include <linux/gpio.h>
 #define GPIO19_GEN1_CAM_RST            19
 #define GPIO28_GEN2_CAM_RST            28
 
+static struct pwm_lookup ezx_pwm_lookup[] = {
+       PWM_LOOKUP("pxa27x-pwm.0", 0, "pwm-backlight.0", NULL, 78700,
+                  PWM_POLARITY_NORMAL),
+};
+
 static struct platform_pwm_backlight_data ezx_backlight_data = {
-       .pwm_id         = 0,
        .max_brightness = 1023,
        .dft_brightness = 1023,
-       .pwm_period_ns  = 78770,
        .enable_gpio    = -1,
 };
 
@@ -817,6 +821,7 @@ static void __init a780_init(void)
                platform_device_register(&a780_camera);
        }
 
+       pwm_add_table(ezx_pwm_lookup, ARRAY_SIZE(ezx_pwm_lookup));
        platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
        platform_add_devices(ARRAY_AND_SIZE(a780_devices));
 }
index 5fb41ad6e3bcdcdc3b07fb20382c980b7e7dfa9e..b076a835eb21b30aef39e0d46968231d23af1500 100644 (file)
@@ -557,10 +557,8 @@ static struct platform_device hx4700_lcd = {
  */
 
 static struct platform_pwm_backlight_data backlight_data = {
-       .pwm_id         = -1,   /* Superseded by pwm_lookup */
        .max_brightness = 200,
        .dft_brightness = 100,
-       .pwm_period_ns  = 30923,
        .enable_gpio    = -1,
 };
 
@@ -630,7 +628,6 @@ static struct spi_board_info tsc2046_board_info[] __initdata = {
 
 static struct pxa2xx_spi_master pxa_ssp2_master_info = {
        .num_chipselect = 1,
-       .clock_enable   = CKEN_SSP2,
        .enable_dma     = 1,
 };
 
index 9b0eb0252af6facf54158a70d97712a92373c1af..a1869f9b6219b8701ec56e6cf249a5015b6b68b5 100644 (file)
@@ -116,13 +116,11 @@ static struct spi_board_info mcp251x_board_info[] = {
 };
 
 static struct pxa2xx_spi_master pxa_ssp3_spi_master_info = {
-       .clock_enable   = CKEN_SSP3,
        .num_chipselect = 2,
        .enable_dma     = 1
 };
 
 static struct pxa2xx_spi_master pxa_ssp4_spi_master_info = {
-       .clock_enable   = CKEN_SSP4,
        .num_chipselect = 2,
        .enable_dma     = 1
 };
index ba6a6e1d29e9611c11b95363d55010e36c3a5981..5f6b850ebe33b7c8e2fee8548f6273bab14023e0 100644 (file)
@@ -52,9 +52,9 @@
 #define GPIO101_MAGICIAN_KEY_VOL_DOWN          101
 #define GPIO102_MAGICIAN_KEY_PHONE             102
 #define GPIO103_MAGICIAN_LED_KP                        103
-#define GPIO104_MAGICIAN_LCD_POWER_1           104
-#define GPIO105_MAGICIAN_LCD_POWER_2           105
-#define GPIO106_MAGICIAN_LCD_POWER_3           106
+#define GPIO104_MAGICIAN_LCD_VOFF_EN           104
+#define GPIO105_MAGICIAN_LCD_VON_EN            105
+#define GPIO106_MAGICIAN_LCD_DCDC_NRESET       106
 #define GPIO107_MAGICIAN_DS1WM_IRQ             107
 #define GPIO108_MAGICIAN_GSM_READY             108
 #define GPIO114_MAGICIAN_UNKNOWN               114
  * CPLD EGPIOs
  */
 
-#define MAGICIAN_EGPIO_BASE                    PXA_NR_BUILTIN_GPIO
+#define MAGICIAN_EGPIO_BASE            PXA_NR_BUILTIN_GPIO
 #define MAGICIAN_EGPIO(reg,bit) \
        (MAGICIAN_EGPIO_BASE + 8*reg + bit)
 
 /* output */
 
-#define EGPIO_MAGICIAN_TOPPOLY_POWER           MAGICIAN_EGPIO(0, 2)
-#define EGPIO_MAGICIAN_LED_POWER               MAGICIAN_EGPIO(0, 5)
-#define EGPIO_MAGICIAN_GSM_RESET               MAGICIAN_EGPIO(0, 6)
-#define EGPIO_MAGICIAN_LCD_POWER               MAGICIAN_EGPIO(0, 7)
-#define EGPIO_MAGICIAN_SPK_POWER               MAGICIAN_EGPIO(1, 0)
-#define EGPIO_MAGICIAN_EP_POWER                        MAGICIAN_EGPIO(1, 1)
-#define EGPIO_MAGICIAN_IN_SEL0                 MAGICIAN_EGPIO(1, 2)
-#define EGPIO_MAGICIAN_IN_SEL1                 MAGICIAN_EGPIO(1, 3)
-#define EGPIO_MAGICIAN_MIC_POWER               MAGICIAN_EGPIO(1, 4)
-#define EGPIO_MAGICIAN_CODEC_RESET             MAGICIAN_EGPIO(1, 5)
-#define EGPIO_MAGICIAN_CODEC_POWER             MAGICIAN_EGPIO(1, 6)
-#define EGPIO_MAGICIAN_BL_POWER                        MAGICIAN_EGPIO(1, 7)
-#define EGPIO_MAGICIAN_SD_POWER                        MAGICIAN_EGPIO(2, 0)
-#define EGPIO_MAGICIAN_CARKIT_MIC              MAGICIAN_EGPIO(2, 1)
-#define EGPIO_MAGICIAN_UNKNOWN_WAVEDEV_DLL     MAGICIAN_EGPIO(2, 2)
-#define EGPIO_MAGICIAN_FLASH_VPP               MAGICIAN_EGPIO(2, 3)
-#define EGPIO_MAGICIAN_BL_POWER2               MAGICIAN_EGPIO(2, 4)
-#define EGPIO_MAGICIAN_BQ24022_ISET2           MAGICIAN_EGPIO(2, 5)
-#define EGPIO_MAGICIAN_GSM_POWER               MAGICIAN_EGPIO(2, 7)
+#define EGPIO_MAGICIAN_TOPPOLY_POWER   MAGICIAN_EGPIO(0, 2)
+#define EGPIO_MAGICIAN_LED_POWER       MAGICIAN_EGPIO(0, 5)
+#define EGPIO_MAGICIAN_GSM_RESET       MAGICIAN_EGPIO(0, 6)
+#define EGPIO_MAGICIAN_LCD_POWER       MAGICIAN_EGPIO(0, 7)
+#define EGPIO_MAGICIAN_SPK_POWER       MAGICIAN_EGPIO(1, 0)
+#define EGPIO_MAGICIAN_EP_POWER                MAGICIAN_EGPIO(1, 1)
+#define EGPIO_MAGICIAN_IN_SEL0         MAGICIAN_EGPIO(1, 2)
+#define EGPIO_MAGICIAN_IN_SEL1         MAGICIAN_EGPIO(1, 3)
+#define EGPIO_MAGICIAN_MIC_POWER       MAGICIAN_EGPIO(1, 4)
+#define EGPIO_MAGICIAN_CODEC_RESET     MAGICIAN_EGPIO(1, 5)
+#define EGPIO_MAGICIAN_CODEC_POWER     MAGICIAN_EGPIO(1, 6)
+#define EGPIO_MAGICIAN_BL_POWER                MAGICIAN_EGPIO(1, 7)
+#define EGPIO_MAGICIAN_SD_POWER                MAGICIAN_EGPIO(2, 0)
+#define EGPIO_MAGICIAN_CARKIT_MIC      MAGICIAN_EGPIO(2, 1)
+#define EGPIO_MAGICIAN_IR_RX_SHUTDOWN  MAGICIAN_EGPIO(2, 2)
+#define EGPIO_MAGICIAN_FLASH_VPP       MAGICIAN_EGPIO(2, 3)
+#define EGPIO_MAGICIAN_BL_POWER2       MAGICIAN_EGPIO(2, 4)
+#define EGPIO_MAGICIAN_BQ24022_ISET2   MAGICIAN_EGPIO(2, 5)
+#define EGPIO_MAGICIAN_NICD_CHARGE     MAGICIAN_EGPIO(2, 6)
+#define EGPIO_MAGICIAN_GSM_POWER       MAGICIAN_EGPIO(2, 7)
 
 /* input */
 
-#define EGPIO_MAGICIAN_CABLE_STATE_AC          MAGICIAN_EGPIO(4, 0)
-#define EGPIO_MAGICIAN_CABLE_STATE_USB         MAGICIAN_EGPIO(4, 1)
+/* USB or AC charger type */
+#define EGPIO_MAGICIAN_CABLE_TYPE      MAGICIAN_EGPIO(4, 0)
+/*
+ * Vbus is detected
+ * FIXME behaves like (6,3), may differ for host/device
+ */
+#define EGPIO_MAGICIAN_CABLE_VBUS      MAGICIAN_EGPIO(4, 1)
 
-#define EGPIO_MAGICIAN_BOARD_ID0               MAGICIAN_EGPIO(5, 0)
-#define EGPIO_MAGICIAN_BOARD_ID1               MAGICIAN_EGPIO(5, 1)
-#define EGPIO_MAGICIAN_BOARD_ID2               MAGICIAN_EGPIO(5, 2)
-#define EGPIO_MAGICIAN_LCD_SELECT              MAGICIAN_EGPIO(5, 3)
-#define EGPIO_MAGICIAN_nSD_READONLY            MAGICIAN_EGPIO(5, 4)
+#define EGPIO_MAGICIAN_BOARD_ID0       MAGICIAN_EGPIO(5, 0)
+#define EGPIO_MAGICIAN_BOARD_ID1       MAGICIAN_EGPIO(5, 1)
+#define EGPIO_MAGICIAN_BOARD_ID2       MAGICIAN_EGPIO(5, 2)
+#define EGPIO_MAGICIAN_LCD_SELECT      MAGICIAN_EGPIO(5, 3)
+#define EGPIO_MAGICIAN_nSD_READONLY    MAGICIAN_EGPIO(5, 4)
 
-#define EGPIO_MAGICIAN_EP_INSERT               MAGICIAN_EGPIO(6, 1)
+#define EGPIO_MAGICIAN_EP_INSERT       MAGICIAN_EGPIO(6, 1)
+/* FIXME behaves like (4,1), may differ for host/device */
+#define EGPIO_MAGICIAN_CABLE_INSERTED  MAGICIAN_EGPIO(6, 3)
 
 #endif /* _MAGICIAN_H_ */
index 599b925a657c46c5679524006757350b910436a7..1a4291936c582baaef76cb9af46c94333a6467d2 100644 (file)
@@ -19,7 +19,7 @@
 #define ARB_CORE_PARK          (1<<24)    /* Be parked with core when idle */
 #define ARB_LOCK_FLAG          (1<<23)    /* Only Locking masters gain access to the bus */
 
-extern int __init pxa27x_set_pwrmode(unsigned int mode);
+extern int pxa27x_set_pwrmode(unsigned int mode);
 extern void pxa27x_cpu_pm_enter(suspend_state_t state);
 
 #endif /* __MACH_PXA27x_H */
index 4823d972e64745dd4ae10dbfed0138eb46d10311..5fcd4f094900b810b6fd902903c53fe27fb672ec 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/ioport.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
+#include <linux/pwm.h>
 #include <linux/pwm_backlight.h>
 #include <linux/smc91x.h>
 
@@ -271,11 +272,14 @@ static struct platform_device lpd270_flash_device[2] = {
        },
 };
 
+static struct pwm_lookup lpd270_pwm_lookup[] = {
+       PWM_LOOKUP("pxa27x-pwm.0", 0, "pwm-backlight.0", NULL, 78770,
+                  PWM_POLARITY_NORMAL),
+};
+
 static struct platform_pwm_backlight_data lpd270_backlight_data = {
-       .pwm_id         = 0,
        .max_brightness = 1,
        .dft_brightness = 1,
-       .pwm_period_ns  = 78770,
        .enable_gpio    = -1,
 };
 
@@ -474,6 +478,7 @@ static void __init lpd270_init(void)
         */
        ARB_CNTRL = ARB_CORE_PARK | 0x234;
 
+       pwm_add_table(lpd270_pwm_lookup, ARRAY_SIZE(lpd270_pwm_lookup));
        platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
 
        pxa_set_ac97_info(NULL);
index a9761c293028cebd348fbf7e43facdf34b166376..896b268c3ab76a70e13c5702fd92df5f9134e0ac 100644 (file)
 #include <linux/mfd/htc-pasic3.h>
 #include <linux/mtd/physmap.h>
 #include <linux/pda_power.h>
+#include <linux/pwm.h>
 #include <linux/pwm_backlight.h>
 #include <linux/regulator/driver.h>
+#include <linux/regulator/fixed.h>
 #include <linux/regulator/gpio-regulator.h>
 #include <linux/regulator/machine.h>
 #include <linux/usb/gpio_vbus.h>
 #include <linux/platform_data/irda-pxaficp.h>
 #include <linux/platform_data/usb-ohci-pxa27x.h>
 
+#include <linux/regulator/max1586.h>
+
+#include <linux/platform_data/pxa2xx_udc.h>
+#include <mach/udc.h>
+#include <mach/pxa27x-udc.h>
+
 #include "devices.h"
 #include "generic.h"
 
@@ -52,36 +60,36 @@ static unsigned long magician_pin_config[] __initdata = {
        GPIO20_nSDCS_2,
        GPIO21_nSDCS_3,
        GPIO15_nCS_1,
-       GPIO78_nCS_2,   /* PASIC3 */
-       GPIO79_nCS_3,   /* EGPIO CPLD */
+       GPIO78_nCS_2,   /* PASIC3 */
+       GPIO79_nCS_3,   /* EGPIO CPLD */
        GPIO80_nCS_4,
        GPIO33_nCS_5,
 
-       /* I2C */
+       /* I2C UDA1380 + OV9640 */
        GPIO117_I2C_SCL,
        GPIO118_I2C_SDA,
 
-       /* PWM 0 */
+       /* PWM 0 - LCD backlight */
        GPIO16_PWM0_OUT,
 
-       /* I2S */
+       /* I2S UDA1380 capture */
        GPIO28_I2S_BITCLK_OUT,
        GPIO29_I2S_SDATA_IN,
        GPIO31_I2S_SYNC,
        GPIO113_I2S_SYSCLK,
 
-       /* SSP 1 */
+       /* SSP 1 UDA1380 playback */
        GPIO23_SSP1_SCLK,
        GPIO24_SSP1_SFRM,
        GPIO25_SSP1_TXD,
 
-       /* SSP 2 */
+       /* SSP 2 TSC2046 touchscreen */
        GPIO19_SSP2_SCLK,
        GPIO14_SSP2_SFRM,
        GPIO89_SSP2_TXD,
        GPIO88_SSP2_RXD,
 
-       /* MMC */
+       /* MMC/SD/SDHC slot */
        GPIO32_MMC_CLK,
        GPIO92_MMC_DAT_0,
        GPIO109_MMC_DAT_1,
@@ -92,7 +100,7 @@ static unsigned long magician_pin_config[] __initdata = {
        /* LCD */
        GPIOxx_LCD_TFT_16BPP,
 
-       /* QCI */
+       /* QCI camera interface */
        GPIO12_CIF_DD_7,
        GPIO17_CIF_DD_6,
        GPIO50_CIF_DD_3,
@@ -120,12 +128,13 @@ static unsigned long magician_pin_config[] __initdata = {
 };
 
 /*
- * IRDA
+ * IrDA
  */
 
 static struct pxaficp_platform_data magician_ficp_info = {
        .gpio_pwdown            = GPIO83_MAGICIAN_nIR_EN,
        .transceiver_cap        = IR_SIRMODE | IR_OFF,
+       .gpio_pwdown_inverted   = 0,
 };
 
 /*
@@ -134,11 +143,11 @@ static struct pxaficp_platform_data magician_ficp_info = {
 
 #define INIT_KEY(_code, _gpio, _desc)  \
        {                               \
-               .code   = KEY_##_code,  \
-               .gpio   = _gpio,        \
-               .desc   = _desc,        \
-               .type   = EV_KEY,       \
-               .wakeup = 1,            \
+               .code   = KEY_##_code,  \
+               .gpio   = _gpio,        \
+               .desc   = _desc,        \
+               .type   = EV_KEY,       \
+               .wakeup = 1,            \
        }
 
 static struct gpio_keys_button magician_button_table[] = {
@@ -160,164 +169,162 @@ static struct gpio_keys_button magician_button_table[] = {
 };
 
 static struct gpio_keys_platform_data gpio_keys_data = {
-       .buttons  = magician_button_table,
-       .nbuttons = ARRAY_SIZE(magician_button_table),
+       .buttons        = magician_button_table,
+       .nbuttons       = ARRAY_SIZE(magician_button_table),
 };
 
 static struct platform_device gpio_keys = {
-       .name = "gpio-keys",
-       .dev  = {
+       .name   = "gpio-keys",
+       .dev    = {
                .platform_data = &gpio_keys_data,
        },
-       .id   = -1,
+       .id     = -1,
 };
 
-
 /*
  * EGPIO (Xilinx CPLD)
  *
- * 7 32-bit aligned 8-bit registers: 3x output, 1x irq, 3x input
+ * 32-bit aligned 8-bit registers
+ * 16 possible registers (reg windows size), only 7 used:
+ * 3x output, 1x irq, 3x input
  */
 
 static struct resource egpio_resources[] = {
        [0] = {
-               .start = PXA_CS3_PHYS,
-               .end   = PXA_CS3_PHYS + 0x20 - 1,
-               .flags = IORESOURCE_MEM,
+               .start  = PXA_CS3_PHYS,
+               .end    = PXA_CS3_PHYS + 0x20 - 1,
+               .flags  = IORESOURCE_MEM,
        },
        [1] = {
-               .start = PXA_GPIO_TO_IRQ(GPIO13_MAGICIAN_CPLD_IRQ),
-               .end   = PXA_GPIO_TO_IRQ(GPIO13_MAGICIAN_CPLD_IRQ),
-               .flags = IORESOURCE_IRQ,
+               .start  = PXA_GPIO_TO_IRQ(GPIO13_MAGICIAN_CPLD_IRQ),
+               .end    = PXA_GPIO_TO_IRQ(GPIO13_MAGICIAN_CPLD_IRQ),
+               .flags  = IORESOURCE_IRQ,
        },
 };
 
 static struct htc_egpio_chip egpio_chips[] = {
        [0] = {
-               .reg_start = 0,
-               .gpio_base = MAGICIAN_EGPIO(0, 0),
-               .num_gpios = 24,
-               .direction = HTC_EGPIO_OUTPUT,
-               .initial_values = 0x40, /* EGPIO_MAGICIAN_GSM_RESET */
+               .reg_start      = 0,
+               .gpio_base      = MAGICIAN_EGPIO(0, 0),
+               .num_gpios      = 24,
+               .direction      = HTC_EGPIO_OUTPUT,
+               /*
+                * Depends on modules configuration
+                */
+               .initial_values = 0x40, /* EGPIO_MAGICIAN_GSM_RESET */
        },
        [1] = {
-               .reg_start = 4,
-               .gpio_base = MAGICIAN_EGPIO(4, 0),
-               .num_gpios = 24,
-               .direction = HTC_EGPIO_INPUT,
+               .reg_start      = 4,
+               .gpio_base      = MAGICIAN_EGPIO(4, 0),
+               .num_gpios      = 24,
+               .direction      = HTC_EGPIO_INPUT,
        },
 };
 
 static struct htc_egpio_platform_data egpio_info = {
-       .reg_width    = 8,
-       .bus_width    = 32,
-       .irq_base     = IRQ_BOARD_START,
-       .num_irqs     = 4,
-       .ack_register = 3,
-       .chip         = egpio_chips,
-       .num_chips    = ARRAY_SIZE(egpio_chips),
+       .reg_width      = 8,
+       .bus_width      = 32,
+       .irq_base       = IRQ_BOARD_START,
+       .num_irqs       = 4,
+       .ack_register   = 3,
+       .chip           = egpio_chips,
+       .num_chips      = ARRAY_SIZE(egpio_chips),
 };
 
 static struct platform_device egpio = {
-       .name          = "htc-egpio",
-       .id            = -1,
-       .resource      = egpio_resources,
-       .num_resources = ARRAY_SIZE(egpio_resources),
+       .name           = "htc-egpio",
+       .id             = -1,
+       .resource       = egpio_resources,
+       .num_resources  = ARRAY_SIZE(egpio_resources),
        .dev = {
                .platform_data = &egpio_info,
        },
 };
 
 /*
- * LCD - Toppoly TD028STEB1 or Samsung LTP280QV
+ * PXAFB LCD - Toppoly TD028STEB1 or Samsung LTP280QV
  */
 
 static struct pxafb_mode_info toppoly_modes[] = {
        {
-               .pixclock     = 96153,
-               .bpp          = 16,
-               .xres         = 240,
-               .yres         = 320,
-               .hsync_len    = 11,
-               .vsync_len    = 3,
-               .left_margin  = 19,
-               .upper_margin = 2,
-               .right_margin = 10,
-               .lower_margin = 2,
-               .sync         = 0,
+               .pixclock       = 96153,
+               .bpp            = 16,
+               .xres           = 240,
+               .yres           = 320,
+               .hsync_len      = 11,
+               .vsync_len      = 3,
+               .left_margin    = 19,
+               .upper_margin   = 2,
+               .right_margin   = 10,
+               .lower_margin   = 2,
+               .sync           = 0,
        },
 };
 
 static struct pxafb_mode_info samsung_modes[] = {
        {
-               .pixclock     = 96153,
-               .bpp          = 16,
-               .xres         = 240,
-               .yres         = 320,
-               .hsync_len    = 8,
-               .vsync_len    = 4,
-               .left_margin  = 9,
-               .upper_margin = 4,
-               .right_margin = 9,
-               .lower_margin = 4,
-               .sync         = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+               .pixclock       = 226469,
+               .bpp            = 16,
+               .xres           = 240,
+               .yres           = 320,
+               .hsync_len      = 8,
+               .vsync_len      = 4,
+               .left_margin    = 9,
+               .upper_margin   = 4,
+               .right_margin   = 9,
+               .lower_margin   = 4,
+               .sync   = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
        },
 };
 
 static void toppoly_lcd_power(int on, struct fb_var_screeninfo *si)
 {
-       pr_debug("Toppoly LCD power\n");
+       pr_debug("Toppoly LCD power: %s\n", on ? "on" : "off");
 
        if (on) {
-               pr_debug("on\n");
                gpio_set_value(EGPIO_MAGICIAN_TOPPOLY_POWER, 1);
-               gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 1);
+               gpio_set_value(GPIO106_MAGICIAN_LCD_DCDC_NRESET, 1);
                udelay(2000);
                gpio_set_value(EGPIO_MAGICIAN_LCD_POWER, 1);
                udelay(2000);
                /* FIXME: enable LCDC here */
                udelay(2000);
-               gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 1);
+               gpio_set_value(GPIO104_MAGICIAN_LCD_VOFF_EN, 1);
                udelay(2000);
-               gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 1);
+               gpio_set_value(GPIO105_MAGICIAN_LCD_VON_EN, 1);
        } else {
-               pr_debug("off\n");
                msleep(15);
-               gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 0);
+               gpio_set_value(GPIO105_MAGICIAN_LCD_VON_EN, 0);
                udelay(500);
-               gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 0);
+               gpio_set_value(GPIO104_MAGICIAN_LCD_VOFF_EN, 0);
                udelay(1000);
-               gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 0);
+               gpio_set_value(GPIO106_MAGICIAN_LCD_DCDC_NRESET, 0);
                gpio_set_value(EGPIO_MAGICIAN_LCD_POWER, 0);
        }
 }
 
 static void samsung_lcd_power(int on, struct fb_var_screeninfo *si)
 {
-       pr_debug("Samsung LCD power\n");
+       pr_debug("Samsung LCD power: %s\n", on ? "on" : "off");
 
        if (on) {
-               pr_debug("on\n");
                if (system_rev < 3)
                        gpio_set_value(GPIO75_MAGICIAN_SAMSUNG_POWER, 1);
                else
                        gpio_set_value(EGPIO_MAGICIAN_LCD_POWER, 1);
-               mdelay(10);
-               gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 1);
-               mdelay(10);
-               gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 1);
-               mdelay(30);
-               gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 1);
-               mdelay(10);
+               mdelay(6);
+               gpio_set_value(GPIO106_MAGICIAN_LCD_DCDC_NRESET, 1);
+               mdelay(6);      /* Avdd -> Voff >5ms */
+               gpio_set_value(GPIO104_MAGICIAN_LCD_VOFF_EN, 1);
+               mdelay(16);     /* Voff -> Von >(5+10)ms */
+               gpio_set_value(GPIO105_MAGICIAN_LCD_VON_EN, 1);
        } else {
-               pr_debug("off\n");
-               mdelay(10);
-               gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 0);
-               mdelay(30);
-               gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 0);
-               mdelay(10);
-               gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 0);
-               mdelay(10);
+               gpio_set_value(GPIO105_MAGICIAN_LCD_VON_EN, 0);
+               mdelay(16);
+               gpio_set_value(GPIO104_MAGICIAN_LCD_VOFF_EN, 0);
+               mdelay(6);
+               gpio_set_value(GPIO106_MAGICIAN_LCD_DCDC_NRESET, 0);
+               mdelay(6);
                if (system_rev < 3)
                        gpio_set_value(GPIO75_MAGICIAN_SAMSUNG_POWER, 0);
                else
@@ -326,29 +333,43 @@ static void samsung_lcd_power(int on, struct fb_var_screeninfo *si)
 }
 
 static struct pxafb_mach_info toppoly_info = {
-       .modes           = toppoly_modes,
-       .num_modes       = 1,
-       .fixed_modes     = 1,
-       .lcd_conn       = LCD_COLOR_TFT_16BPP,
-       .pxafb_lcd_power = toppoly_lcd_power,
+       .modes                  = toppoly_modes,
+       .num_modes              = 1,
+       .fixed_modes            = 1,
+       .lcd_conn               = LCD_COLOR_TFT_16BPP,
+       .pxafb_lcd_power        = toppoly_lcd_power,
 };
 
 static struct pxafb_mach_info samsung_info = {
-       .modes           = samsung_modes,
-       .num_modes       = 1,
-       .fixed_modes     = 1,
-       .lcd_conn        = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL |\
-                          LCD_ALTERNATE_MAPPING,
-       .pxafb_lcd_power = samsung_lcd_power,
+       .modes                  = samsung_modes,
+       .num_modes              = 1,
+       .fixed_modes            = 1,
+       .lcd_conn               = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL |
+               LCD_ALTERNATE_MAPPING,
+       .pxafb_lcd_power        = samsung_lcd_power,
 };
 
 /*
  * Backlight
  */
 
+static struct pwm_lookup magician_pwm_lookup[] = {
+       PWM_LOOKUP("pxa27x-pwm.0", 0, "pwm-backlight", NULL, 30923,
+                  PWM_POLARITY_NORMAL),
+};
+
+ /*
+ * fixed regulator for pwm_backlight
+ */
+
+static struct regulator_consumer_supply pwm_backlight_supply[] = {
+       REGULATOR_SUPPLY("power", "pwm_backlight"),
+};
+
+
 static struct gpio magician_bl_gpios[] = {
-       { EGPIO_MAGICIAN_BL_POWER,  GPIOF_DIR_OUT, "Backlight power" },
-       { EGPIO_MAGICIAN_BL_POWER2, GPIOF_DIR_OUT, "Backlight power 2" },
+       { EGPIO_MAGICIAN_BL_POWER,      GPIOF_DIR_OUT, "Backlight power" },
+       { EGPIO_MAGICIAN_BL_POWER2,     GPIOF_DIR_OUT, "Backlight power 2" },
 };
 
 static int magician_backlight_init(struct device *dev)
@@ -358,6 +379,7 @@ static int magician_backlight_init(struct device *dev)
 
 static int magician_backlight_notify(struct device *dev, int brightness)
 {
+       pr_debug("Brightness = %i\n", brightness);
        gpio_set_value(EGPIO_MAGICIAN_BL_POWER, brightness);
        if (brightness >= 200) {
                gpio_set_value(EGPIO_MAGICIAN_BL_POWER2, 1);
@@ -373,28 +395,33 @@ static void magician_backlight_exit(struct device *dev)
        gpio_free_array(ARRAY_AND_SIZE(magician_bl_gpios));
 }
 
+/*
+ * LCD PWM backlight (main)
+ *
+ * MP1521 frequency should be:
+ *     100-400 Hz = 2 .5*10^6 - 10 *10^6 ns
+ */
+
 static struct platform_pwm_backlight_data backlight_data = {
-       .pwm_id         = 0,
-       .max_brightness = 272,
-       .dft_brightness = 100,
-       .pwm_period_ns  = 30923,
-       .enable_gpio    = -1,
-       .init           = magician_backlight_init,
-       .notify         = magician_backlight_notify,
-       .exit           = magician_backlight_exit,
+       .max_brightness = 272,
+       .dft_brightness = 100,
+       .enable_gpio    = -1,
+       .init           = magician_backlight_init,
+       .notify         = magician_backlight_notify,
+       .exit           = magician_backlight_exit,
 };
 
 static struct platform_device backlight = {
-       .name = "pwm-backlight",
-       .id   = -1,
-       .dev  = {
-               .parent        = &pxa27x_device_pwm0.dev,
-               .platform_data = &backlight_data,
+       .name   = "pwm-backlight",
+       .id     = -1,
+       .dev    = {
+               .parent         = &pxa27x_device_pwm0.dev,
+               .platform_data  = &backlight_data,
        },
 };
 
 /*
- * LEDs
+ * GPIO LEDs, Phone keys backlight, vibra
  */
 
 static struct gpio_led gpio_leds[] = {
@@ -416,69 +443,32 @@ static struct gpio_led_platform_data gpio_led_info = {
 };
 
 static struct platform_device leds_gpio = {
-       .name = "leds-gpio",
-       .id   = -1,
-       .dev  = {
+       .name   = "leds-gpio",
+       .id     = -1,
+       .dev    = {
                .platform_data = &gpio_led_info,
        },
 };
 
-static struct pasic3_led pasic3_leds[] = {
-       {
-               .led = {
-                       .name            = "magician:red",
-                       .default_trigger = "ds2760-battery.0-charging",
-               },
-               .hw_num = 0,
-               .bit2   = PASIC3_BIT2_LED0,
-               .mask   = PASIC3_MASK_LED0,
-       },
-       {
-               .led = {
-                       .name            = "magician:green",
-                       .default_trigger = "ds2760-battery.0-charging-or-full",
-               },
-               .hw_num = 1,
-               .bit2   = PASIC3_BIT2_LED1,
-               .mask   = PASIC3_MASK_LED1,
-       },
-       {
-               .led = {
-                       .name            = "magician:blue",
-                       .default_trigger = "bluetooth",
-               },
-               .hw_num = 2,
-               .bit2   = PASIC3_BIT2_LED2,
-               .mask   = PASIC3_MASK_LED2,
-       },
-};
-
-static struct pasic3_leds_machinfo pasic3_leds_info = {
-       .num_leds   = ARRAY_SIZE(pasic3_leds),
-       .power_gpio = EGPIO_MAGICIAN_LED_POWER,
-       .leds       = pasic3_leds,
-};
-
 /*
  * PASIC3 with DS1WM
  */
 
 static struct resource pasic3_resources[] = {
        [0] = {
-               .start  = PXA_CS2_PHYS,
+               .start  = PXA_CS2_PHYS,
                .end    = PXA_CS2_PHYS + 0x1b,
-               .flags  = IORESOURCE_MEM,
+               .flags  = IORESOURCE_MEM,
        },
        /* No IRQ handler in the PASIC3, DS1WM needs an external IRQ */
        [1] = {
-               .start  = PXA_GPIO_TO_IRQ(GPIO107_MAGICIAN_DS1WM_IRQ),
-               .end    = PXA_GPIO_TO_IRQ(GPIO107_MAGICIAN_DS1WM_IRQ),
-               .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+               .start  = PXA_GPIO_TO_IRQ(GPIO107_MAGICIAN_DS1WM_IRQ),
+               .end    = PXA_GPIO_TO_IRQ(GPIO107_MAGICIAN_DS1WM_IRQ),
+               .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
        }
 };
 
 static struct pasic3_platform_data pasic3_platform_data = {
-       .led_pdata  = &pasic3_leds_info,
        .clock_rate = 4000000,
 };
 
@@ -493,25 +483,42 @@ static struct platform_device pasic3 = {
 };
 
 /*
- * USB "Transceiver"
+ * PXA UDC
+ */
+
+static void magician_udc_command(int cmd)
+{
+       if (cmd == PXA2XX_UDC_CMD_CONNECT)
+               UP2OCR |= UP2OCR_DPPUE | UP2OCR_DPPUBE;
+       else if (cmd == PXA2XX_UDC_CMD_DISCONNECT)
+               UP2OCR &= ~(UP2OCR_DPPUE | UP2OCR_DPPUBE);
+}
+
+static struct pxa2xx_udc_mach_info magician_udc_info __initdata = {
+       .udc_command    = magician_udc_command,
+       .gpio_pullup    = GPIO27_MAGICIAN_USBC_PUEN,
+};
+
+/*
+ * USB device VBus detection
  */
 
 static struct resource gpio_vbus_resource = {
-       .flags = IORESOURCE_IRQ,
-       .start = IRQ_MAGICIAN_VBUS,
-       .end   = IRQ_MAGICIAN_VBUS,
+       .flags  = IORESOURCE_IRQ,
+       .start  = IRQ_MAGICIAN_VBUS,
+       .end    = IRQ_MAGICIAN_VBUS,
 };
 
 static struct gpio_vbus_mach_info gpio_vbus_info = {
-       .gpio_pullup = GPIO27_MAGICIAN_USBC_PUEN,
-       .gpio_vbus   = EGPIO_MAGICIAN_CABLE_STATE_USB,
+       .gpio_pullup    = GPIO27_MAGICIAN_USBC_PUEN,
+       .gpio_vbus      = EGPIO_MAGICIAN_CABLE_VBUS,
 };
 
 static struct platform_device gpio_vbus = {
-       .name          = "gpio-vbus",
-       .id            = -1,
-       .num_resources = 1,
-       .resource      = &gpio_vbus_resource,
+       .name           = "gpio-vbus",
+       .id             = -1,
+       .num_resources  = 1,
+       .resource       = &gpio_vbus_resource,
        .dev = {
                .platform_data = &gpio_vbus_info,
        },
@@ -521,19 +528,60 @@ static struct platform_device gpio_vbus = {
  * External power
  */
 
-static int power_supply_init(struct device *dev)
+static int magician_supply_init(struct device *dev)
+{
+       int ret = -1;
+
+       ret = gpio_request(EGPIO_MAGICIAN_CABLE_TYPE, "Cable is AC charger");
+       if (ret) {
+               pr_err("Cannot request AC/USB charger GPIO (%i)\n", ret);
+               goto err_ac;
+       }
+
+       ret = gpio_request(EGPIO_MAGICIAN_CABLE_INSERTED, "Cable inserted");
+       if (ret) {
+               pr_err("Cannot request cable detection GPIO (%i)\n", ret);
+               goto err_usb;
+       }
+
+       return 0;
+
+err_usb:
+       gpio_free(EGPIO_MAGICIAN_CABLE_TYPE);
+err_ac:
+       return ret;
+}
+
+static void magician_set_charge(int flags)
 {
-       return gpio_request(EGPIO_MAGICIAN_CABLE_STATE_AC, "CABLE_STATE_AC");
+       if (flags & PDA_POWER_CHARGE_AC) {
+               pr_debug("Charging from AC\n");
+               gpio_set_value(EGPIO_MAGICIAN_NICD_CHARGE, 1);
+       } else if (flags & PDA_POWER_CHARGE_USB) {
+               pr_debug("Charging from USB\n");
+               gpio_set_value(EGPIO_MAGICIAN_NICD_CHARGE, 1);
+       } else {
+               pr_debug("Charging disabled\n");
+               gpio_set_value(EGPIO_MAGICIAN_NICD_CHARGE, 0);
+       }
 }
 
 static int magician_is_ac_online(void)
 {
-       return gpio_get_value(EGPIO_MAGICIAN_CABLE_STATE_AC);
+       return gpio_get_value(EGPIO_MAGICIAN_CABLE_INSERTED) &&
+               gpio_get_value(EGPIO_MAGICIAN_CABLE_TYPE); /* AC=1 */
 }
 
-static void power_supply_exit(struct device *dev)
+static int magician_is_usb_online(void)
 {
-       gpio_free(EGPIO_MAGICIAN_CABLE_STATE_AC);
+       return gpio_get_value(EGPIO_MAGICIAN_CABLE_INSERTED) &&
+               (!gpio_get_value(EGPIO_MAGICIAN_CABLE_TYPE)); /* USB=0 */
+}
+
+static void magician_supply_exit(struct device *dev)
+{
+       gpio_free(EGPIO_MAGICIAN_CABLE_INSERTED);
+       gpio_free(EGPIO_MAGICIAN_CABLE_TYPE);
 }
 
 static char *magician_supplicants[] = {
@@ -541,38 +589,40 @@ static char *magician_supplicants[] = {
 };
 
 static struct pda_power_pdata power_supply_info = {
-       .init            = power_supply_init,
-       .is_ac_online    = magician_is_ac_online,
-       .exit            = power_supply_exit,
-       .supplied_to     = magician_supplicants,
-       .num_supplicants = ARRAY_SIZE(magician_supplicants),
+       .init                   = magician_supply_init,
+       .exit                   = magician_supply_exit,
+       .is_ac_online           = magician_is_ac_online,
+       .is_usb_online          = magician_is_usb_online,
+       .set_charge             = magician_set_charge,
+       .supplied_to            = magician_supplicants,
+       .num_supplicants        = ARRAY_SIZE(magician_supplicants),
 };
 
 static struct resource power_supply_resources[] = {
        [0] = {
-               .name  = "ac",
-               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
-                        IORESOURCE_IRQ_LOWEDGE,
-               .start = IRQ_MAGICIAN_VBUS,
-               .end   = IRQ_MAGICIAN_VBUS,
+               .name   = "ac",
+               .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
+                       IORESOURCE_IRQ_LOWEDGE,
+               .start  = IRQ_MAGICIAN_VBUS,
+               .end    = IRQ_MAGICIAN_VBUS,
        },
        [1] = {
-               .name  = "usb",
-               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
-                        IORESOURCE_IRQ_LOWEDGE,
-               .start = IRQ_MAGICIAN_VBUS,
-               .end   = IRQ_MAGICIAN_VBUS,
+               .name   = "usb",
+               .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
+                       IORESOURCE_IRQ_LOWEDGE,
+               .start  = IRQ_MAGICIAN_VBUS,
+               .end    = IRQ_MAGICIAN_VBUS,
        },
 };
 
 static struct platform_device power_supply = {
-       .name = "pda-power",
-       .id   = -1,
-       .dev  = {
+       .name   = "pda-power",
+       .id     = -1,
+       .dev = {
                .platform_data = &power_supply_info,
        },
-       .resource      = power_supply_resources,
-       .num_resources = ARRAY_SIZE(power_supply_resources),
+       .resource       = power_supply_resources,
+       .num_resources  = ARRAY_SIZE(power_supply_resources),
 };
 
 /*
@@ -586,11 +636,12 @@ static struct regulator_consumer_supply bq24022_consumers[] = {
 
 static struct regulator_init_data bq24022_init_data = {
        .constraints = {
-               .max_uA         = 500000,
-               .valid_ops_mask = REGULATOR_CHANGE_CURRENT | REGULATOR_CHANGE_STATUS,
+               .max_uA         = 500000,
+               .valid_ops_mask = REGULATOR_CHANGE_CURRENT |
+                       REGULATOR_CHANGE_STATUS,
        },
-       .num_consumer_supplies  = ARRAY_SIZE(bq24022_consumers),
-       .consumer_supplies      = bq24022_consumers,
+       .num_consumer_supplies  = ARRAY_SIZE(bq24022_consumers),
+       .consumer_supplies      = bq24022_consumers,
 };
 
 static struct gpio bq24022_gpios[] = {
@@ -603,39 +654,85 @@ static struct gpio_regulator_state bq24022_states[] = {
 };
 
 static struct gpio_regulator_config bq24022_info = {
-       .supply_name = "bq24022",
+       .supply_name            = "bq24022",
 
-       .enable_gpio = GPIO30_MAGICIAN_BQ24022_nCHARGE_EN,
-       .enable_high = 0,
-       .enabled_at_boot = 0,
+       .enable_gpio            = GPIO30_MAGICIAN_BQ24022_nCHARGE_EN,
+       .enable_high            = 0,
+       .enabled_at_boot        = 1,
 
-       .gpios = bq24022_gpios,
-       .nr_gpios = ARRAY_SIZE(bq24022_gpios),
+       .gpios                  = bq24022_gpios,
+       .nr_gpios               = ARRAY_SIZE(bq24022_gpios),
 
-       .states = bq24022_states,
-       .nr_states = ARRAY_SIZE(bq24022_states),
+       .states                 = bq24022_states,
+       .nr_states              = ARRAY_SIZE(bq24022_states),
 
-       .type = REGULATOR_CURRENT,
-       .init_data = &bq24022_init_data,
+       .type                   = REGULATOR_CURRENT,
+       .init_data              = &bq24022_init_data,
 };
 
 static struct platform_device bq24022 = {
-       .name = "gpio-regulator",
-       .id   = -1,
-       .dev  = {
+       .name   = "gpio-regulator",
+       .id     = -1,
+       .dev    = {
                .platform_data = &bq24022_info,
        },
 };
 
+/*
+ * Vcore regulator MAX1587A
+ */
+
+static struct regulator_consumer_supply magician_max1587a_consumers[] = {
+       REGULATOR_SUPPLY("vcc_core", NULL),
+};
+
+static struct regulator_init_data magician_max1587a_v3_info = {
+       .constraints = {
+               .name           = "vcc_core range",
+               .min_uV         = 700000,
+               .max_uV         = 1475000,
+               .always_on      = 1,
+               .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+       },
+       .consumer_supplies      = magician_max1587a_consumers,
+       .num_consumer_supplies  = ARRAY_SIZE(magician_max1587a_consumers),
+};
+
+static struct max1586_subdev_data magician_max1587a_subdevs[] = {
+       {
+               .name           = "vcc_core",
+               .id             = MAX1586_V3,
+               .platform_data  = &magician_max1587a_v3_info,
+       }
+};
+
+static struct max1586_platform_data magician_max1587a_info = {
+       .subdevs     = magician_max1587a_subdevs,
+       .num_subdevs = ARRAY_SIZE(magician_max1587a_subdevs),
+       /*
+        * NOTICE measured directly on the PCB (board_id == 0x3a), but
+        * if R24 is present, it will boost the voltage
+        * (write 1.475V, get 1.645V and smoke)
+        */
+       .v3_gain     = MAX1586_GAIN_NO_R24,
+};
+
+static struct i2c_board_info magician_pwr_i2c_board_info[] __initdata = {
+       {
+               I2C_BOARD_INFO("max1586", 0x14),
+               .platform_data  = &magician_max1587a_info,
+       },
+};
+
 /*
  * MMC/SD
  */
 
 static int magician_mci_init(struct device *dev,
-                               irq_handler_t detect_irq, void *data)
+       irq_handler_t detect_irq, void *data)
 {
        return request_irq(IRQ_MAGICIAN_SD, detect_irq, 0,
-                          "mmc card detect", data);
+               "mmc card detect", data);
 }
 
 static void magician_mci_exit(struct device *dev, void *data)
@@ -644,9 +741,9 @@ static void magician_mci_exit(struct device *dev, void *data)
 }
 
 static struct pxamci_platform_data magician_mci_info = {
-       .ocr_mask               = MMC_VDD_32_33|MMC_VDD_33_34,
-       .init                   = magician_mci_init,
-       .exit                   = magician_mci_exit,
+       .ocr_mask               = MMC_VDD_32_33|MMC_VDD_33_34,
+       .init                   = magician_mci_init,
+       .exit                   = magician_mci_exit,
        .gpio_card_detect       = -1,
        .gpio_card_ro           = EGPIO_MAGICIAN_nSD_READONLY,
        .gpio_card_ro_invert    = 1,
@@ -660,47 +757,102 @@ static struct pxamci_platform_data magician_mci_info = {
 
 static struct pxaohci_platform_data magician_ohci_info = {
        .port_mode      = PMM_PERPORT_MODE,
-       .flags          = ENABLE_PORT1 | ENABLE_PORT3 | POWER_CONTROL_LOW,
+       /* port1: CSR Bluetooth, port2: OTG with UDC */
+       .flags          = ENABLE_PORT1 | ENABLE_PORT2 | POWER_CONTROL_LOW,
        .power_budget   = 0,
+       .power_on_delay = 100,
 };
 
-
 /*
  * StrataFlash
  */
 
+static int magician_flash_init(struct platform_device *pdev)
+{
+       int ret = gpio_request(EGPIO_MAGICIAN_FLASH_VPP, "flash Vpp enable");
+
+       if (ret) {
+               pr_err("Cannot request flash enable GPIO (%i)\n", ret);
+               return ret;
+       }
+
+       ret = gpio_direction_output(EGPIO_MAGICIAN_FLASH_VPP, 1);
+       if (ret) {
+               pr_err("Cannot set direction for flash enable (%i)\n", ret);
+               gpio_free(EGPIO_MAGICIAN_FLASH_VPP);
+       }
+
+       return ret;
+}
+
 static void magician_set_vpp(struct platform_device *pdev, int vpp)
 {
        gpio_set_value(EGPIO_MAGICIAN_FLASH_VPP, vpp);
 }
 
+static void magician_flash_exit(struct platform_device *pdev)
+{
+       gpio_free(EGPIO_MAGICIAN_FLASH_VPP);
+}
+
 static struct resource strataflash_resource = {
-       .start = PXA_CS0_PHYS,
-       .end   = PXA_CS0_PHYS + SZ_64M - 1,
-       .flags = IORESOURCE_MEM,
+       .start  = PXA_CS0_PHYS,
+       .end    = PXA_CS0_PHYS + SZ_64M - 1,
+       .flags  = IORESOURCE_MEM,
 };
 
+static struct mtd_partition magician_flash_parts[] = {
+       {
+               .name           = "Bootloader",
+               .offset         = 0x0,
+               .size           = 0x40000,
+               .mask_flags     = MTD_WRITEABLE, /* EXPERIMENTAL */
+       },
+       {
+               .name           = "Linux Kernel",
+               .offset         = 0x40000,
+               .size           = MTDPART_SIZ_FULL,
+       },
+};
+
+/*
+ * physmap-flash driver
+ */
+
 static struct physmap_flash_data strataflash_data = {
-       .width = 4,
-       .set_vpp = magician_set_vpp,
+       .width          = 4,
+       .init           = magician_flash_init,
+       .set_vpp        = magician_set_vpp,
+       .exit           = magician_flash_exit,
+       .parts          = magician_flash_parts,
+       .nr_parts       = ARRAY_SIZE(magician_flash_parts),
 };
 
 static struct platform_device strataflash = {
-       .name          = "physmap-flash",
-       .id            = -1,
-       .resource      = &strataflash_resource,
-       .num_resources = 1,
+       .name           = "physmap-flash",
+       .id             = -1,
+       .resource       = &strataflash_resource,
+       .num_resources  = 1,
        .dev = {
                .platform_data = &strataflash_data,
        },
 };
 
 /*
- * I2C
+ * PXA I2C main controller
  */
 
 static struct i2c_pxa_platform_data i2c_info = {
-       .fast_mode = 1,
+       /* OV9640 I2C device doesn't support fast mode */
+       .fast_mode      = 0,
+};
+
+/*
+ * PXA I2C power controller
+ */
+
+static struct i2c_pxa_platform_data magician_i2c_power_info = {
+       .fast_mode      = 1,
 };
 
 /*
@@ -720,12 +872,13 @@ static struct platform_device *devices[] __initdata = {
 };
 
 static struct gpio magician_global_gpios[] = {
-       { GPIO13_MAGICIAN_CPLD_IRQ,   GPIOF_IN, "CPLD_IRQ" },
+       { GPIO13_MAGICIAN_CPLD_IRQ, GPIOF_IN, "CPLD_IRQ" },
        { GPIO107_MAGICIAN_DS1WM_IRQ, GPIOF_IN, "DS1WM_IRQ" },
-       { GPIO104_MAGICIAN_LCD_POWER_1, GPIOF_OUT_INIT_LOW, "LCD power 1" },
-       { GPIO105_MAGICIAN_LCD_POWER_2, GPIOF_OUT_INIT_LOW, "LCD power 2" },
-       { GPIO106_MAGICIAN_LCD_POWER_3, GPIOF_OUT_INIT_LOW, "LCD power 3" },
-       { GPIO83_MAGICIAN_nIR_EN, GPIOF_OUT_INIT_HIGH, "nIR_EN" },
+
+       /* NOTICE valid LCD init sequence */
+       { GPIO106_MAGICIAN_LCD_DCDC_NRESET, GPIOF_OUT_INIT_LOW, "LCD DCDC nreset" },
+       { GPIO104_MAGICIAN_LCD_VOFF_EN, GPIOF_OUT_INIT_LOW, "LCD VOFF enable" },
+       { GPIO105_MAGICIAN_LCD_VON_EN, GPIOF_OUT_INIT_LOW, "LCD VON enable" },
 };
 
 static void __init magician_init(void)
@@ -737,44 +890,55 @@ static void __init magician_init(void)
        pxa2xx_mfp_config(ARRAY_AND_SIZE(magician_pin_config));
        err = gpio_request_array(ARRAY_AND_SIZE(magician_global_gpios));
        if (err)
-               pr_err("magician: Failed to request GPIOs: %d\n", err);
+               pr_err("magician: Failed to request global GPIOs: %d\n", err);
 
        pxa_set_ffuart_info(NULL);
        pxa_set_btuart_info(NULL);
-       pxa_set_stuart_info(NULL);
 
-       platform_add_devices(ARRAY_AND_SIZE(devices));
+       pwm_add_table(magician_pwm_lookup, ARRAY_SIZE(magician_pwm_lookup));
 
        pxa_set_ficp_info(&magician_ficp_info);
-       pxa27x_set_i2c_power_info(NULL);
+       pxa27x_set_i2c_power_info(&magician_i2c_power_info);
        pxa_set_i2c_info(&i2c_info);
+
+       i2c_register_board_info(1,
+               ARRAY_AND_SIZE(magician_pwr_i2c_board_info));
+
        pxa_set_mci_info(&magician_mci_info);
        pxa_set_ohci_info(&magician_ohci_info);
+       pxa_set_udc_info(&magician_udc_info);
 
        /* Check LCD type we have */
        cpld = ioremap_nocache(PXA_CS3_PHYS, 0x1000);
        if (cpld) {
-               u8 board_id = __raw_readb(cpld+0x14);
+               u8 board_id = __raw_readb(cpld + 0x14);
+
                iounmap(cpld);
                system_rev = board_id & 0x7;
                lcd_select = board_id & 0x8;
                pr_info("LCD type: %s\n", lcd_select ? "Samsung" : "Toppoly");
                if (lcd_select && (system_rev < 3))
+                       /* NOTICE valid LCD init sequence */
                        gpio_request_one(GPIO75_MAGICIAN_SAMSUNG_POWER,
-                                        GPIOF_OUT_INIT_LOW, "SAMSUNG_POWER");
-               pxa_set_fb_info(NULL, lcd_select ? &samsung_info : &toppoly_info);
+                               GPIOF_OUT_INIT_LOW, "Samsung LCD Power");
+               pxa_set_fb_info(NULL,
+                       lcd_select ? &samsung_info : &toppoly_info);
        } else
                pr_err("LCD detection: CPLD mapping failed\n");
-}
 
+       regulator_register_always_on(0, "power", pwm_backlight_supply,
+               ARRAY_SIZE(pwm_backlight_supply), 5000000);
+
+       platform_add_devices(ARRAY_AND_SIZE(devices));
+}
 
 MACHINE_START(MAGICIAN, "HTC Magician")
-       .atag_offset = 0x100,
-       .map_io = pxa27x_map_io,
-       .nr_irqs = MAGICIAN_NR_IRQS,
-       .init_irq = pxa27x_init_irq,
-       .handle_irq = pxa27x_handle_irq,
-       .init_machine = magician_init,
+       .atag_offset    = 0x100,
+       .map_io         = pxa27x_map_io,
+       .nr_irqs        = MAGICIAN_NR_IRQS,
+       .init_irq       = pxa27x_init_irq,
+       .handle_irq     = pxa27x_handle_irq,
+       .init_machine   = magician_init,
        .init_time      = pxa_timer_init,
        .restart        = pxa_restart,
 MACHINE_END
index 2c0658cf6be261f7a7a6ea89409b0d3f52e5f0eb..c3a87c176d7277383f32fb1129a0320c3de84e11 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/mtd/partitions.h>
 #include <linux/input.h>
 #include <linux/gpio_keys.h>
+#include <linux/pwm.h>
 #include <linux/pwm_backlight.h>
 #include <linux/smc91x.h>
 #include <linux/i2c/pxa-i2c.h>
@@ -248,11 +249,14 @@ static struct platform_device mst_flash_device[2] = {
 };
 
 #if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+static struct pwm_lookup mainstone_pwm_lookup[] = {
+       PWM_LOOKUP("pxa27x-pwm.0", 0, "pwm-backlight.0", NULL, 78770,
+                  PWM_POLARITY_NORMAL),
+};
+
 static struct platform_pwm_backlight_data mainstone_backlight_data = {
-       .pwm_id         = 0,
        .max_brightness = 1023,
        .dft_brightness = 1023,
-       .pwm_period_ns  = 78770,
        .enable_gpio    = -1,
 };
 
@@ -266,9 +270,16 @@ static struct platform_device mainstone_backlight_device = {
 
 static void __init mainstone_backlight_register(void)
 {
-       int ret = platform_device_register(&mainstone_backlight_device);
-       if (ret)
+       int ret;
+
+       pwm_add_table(mainstone_pwm_lookup, ARRAY_SIZE(mainstone_pwm_lookup));
+
+       ret = platform_device_register(&mainstone_backlight_device);
+       if (ret) {
                printk(KERN_ERR "mainstone: failed to register backlight device: %d\n", ret);
+               pwm_remove_table(mainstone_pwm_lookup,
+                                ARRAY_SIZE(mainstone_pwm_lookup));
+       }
 }
 #else
 #define mainstone_backlight_register() do { } while (0)
index 29997bde277d1be730aa85d98a2ae17bc0bc2da5..3b52b1aa06594a7a591045f1b9f195307b0583f4 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/input.h>
 #include <linux/delay.h>
 #include <linux/gpio_keys.h>
+#include <linux/pwm.h>
 #include <linux/pwm_backlight.h>
 #include <linux/rtc.h>
 #include <linux/leds.h>
@@ -181,12 +182,15 @@ static unsigned long mioa701_pin_config[] = {
        MFP_CFG_OUT(GPIO116, AF0, DRIVE_HIGH),
 };
 
+static struct pwm_lookup mioa701_pwm_lookup[] = {
+       PWM_LOOKUP("pxa27x-pwm.0", 0, "pwm-backlight", NULL, 4000 * 1024,
+                  PWM_POLARITY_NORMAL),
+};
+
 /* LCD Screen and Backlight */
 static struct platform_pwm_backlight_data mioa701_backlight_data = {
-       .pwm_id         = 0,
        .max_brightness = 100,
        .dft_brightness = 50,
-       .pwm_period_ns  = 4000 * 1024,  /* Fl = 250kHz */
        .enable_gpio    = -1,
 };
 
@@ -678,6 +682,7 @@ MIO_SIMPLE_DEV(mioa701_led,   "leds-gpio",      &gpio_led_info)
 MIO_SIMPLE_DEV(pxa2xx_pcm,       "pxa2xx-pcm",     NULL)
 MIO_SIMPLE_DEV(mioa701_sound,    "mioa701-wm9713", NULL)
 MIO_SIMPLE_DEV(mioa701_board,    "mioa701-board",  NULL)
+MIO_SIMPLE_DEV(wm9713_acodec,    "wm9713-codec",   NULL);
 MIO_SIMPLE_DEV(gpio_vbus,        "gpio-vbus",      &gpio_vbus_data);
 MIO_SIMPLE_DEV(mioa701_camera,   "soc-camera-pdrv",&iclink);
 
@@ -685,6 +690,7 @@ static struct platform_device *devices[] __initdata = {
        &mioa701_gpio_keys,
        &mioa701_backlight,
        &mioa701_led,
+       &wm9713_acodec,
        &pxa2xx_pcm,
        &mioa701_sound,
        &power_dev,
@@ -751,6 +757,7 @@ static void __init mioa701_machine_init(void)
        pxa_set_udc_info(&mioa701_udc_info);
        pxa_set_ac97_info(&mioa701_ac97_info);
        pm_power_off = mioa701_poweroff;
+       pwm_add_table(mioa701_pwm_lookup, ARRAY_SIZE(mioa701_pwm_lookup));
        platform_add_devices(devices, ARRAY_SIZE(devices));
        gsm_init();
 
index e54a296fb81f8b045f814860c0dc729edb71d2c4..13eba2b26e0aa478e7e26eb541855be091ac68e0 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
 #include <linux/pda_power.h>
+#include <linux/pwm.h>
 #include <linux/pwm_backlight.h>
 #include <linux/gpio.h>
 #include <linux/wm97xx.h>
@@ -270,6 +271,11 @@ void __init palm27x_ac97_init(int minv, int maxv, int jack, int reset)
  * Backlight
  ******************************************************************************/
 #if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE)
+static struct pwm_lookup palm27x_pwm_lookup[] = {
+       PWM_LOOKUP("pxa27x-pwm.0", 0, "pwm-backlight.0", NULL, 3500 * 1024,
+                  PWM_POLARITY_NORMAL),
+};
+
 static int palm_bl_power;
 static int palm_lcd_power;
 
@@ -318,10 +324,8 @@ static void palm27x_backlight_exit(struct device *dev)
 }
 
 static struct platform_pwm_backlight_data palm27x_backlight_data = {
-       .pwm_id         = 0,
        .max_brightness = 0xfe,
        .dft_brightness = 0x7e,
-       .pwm_period_ns  = 3500 * 1024,
        .enable_gpio    = -1,
        .init           = palm27x_backlight_init,
        .notify         = palm27x_backlight_notify,
@@ -340,6 +344,7 @@ void __init palm27x_pwm_init(int bl, int lcd)
 {
        palm_bl_power   = bl;
        palm_lcd_power  = lcd;
+       pwm_add_lookup(palm27x_pwm_lookup, ARRAY_SIZE(palm27x_pwm_lookup));
        platform_device_register(&palm27x_backlight);
 }
 #endif
index 7691c974ca4bd0b6ade4c467e3ea6a26c611d9ce..aebf6de62468962b9398f6ee299c0539920cbba8 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/delay.h>
 #include <linux/irq.h>
 #include <linux/input.h>
+#include <linux/pwm.h>
 #include <linux/pwm_backlight.h>
 #include <linux/gpio.h>
 #include <linux/input/matrix_keypad.h>
@@ -166,11 +167,14 @@ static inline void palmtc_keys_init(void) {}
  * Backlight
  ******************************************************************************/
 #if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE)
+static struct pwm_lookup palmtc_pwm_lookup[] = {
+       PWM_LOOKUP("pxa25x-pwm.1", 0, "pwm-backlight.0", NULL, PALMTC_PERIOD_NS,
+                  PWM_PERIOD_NORMAL),
+};
+
 static struct platform_pwm_backlight_data palmtc_backlight_data = {
-       .pwm_id         = 1,
        .max_brightness = PALMTC_MAX_INTENSITY,
        .dft_brightness = PALMTC_MAX_INTENSITY,
-       .pwm_period_ns  = PALMTC_PERIOD_NS,
        .enable_gpio    = GPIO_NR_PALMTC_BL_POWER,
 };
 
@@ -184,6 +188,7 @@ static struct platform_device palmtc_backlight = {
 
 static void __init palmtc_pwm_init(void)
 {
+       pwm_add_table(palmtc_pwm_lookup, ARRAY_SIZE(palmtc_pwm_lookup));
        platform_device_register(&palmtc_backlight);
 }
 #else
index 956fd24ee6fdca69b63bed29ebe4b9ebe567fd83..e64bb4326e6969e4543da8593f6a3392cd87a999 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
 #include <linux/pda_power.h>
+#include <linux/pwm.h>
 #include <linux/pwm_backlight.h>
 #include <linux/gpio.h>
 #include <linux/wm97xx.h>
@@ -138,6 +139,11 @@ static struct platform_device palmte2_pxa_keys = {
 /******************************************************************************
  * Backlight
  ******************************************************************************/
+static struct pwm_lookup palmte2_pwm_lookup[] = {
+       PWM_LOOKUP("pxa25x-pwm.0", 0, "pwm-backlight.0", NULL,
+                  PALMTE2_PERIOD_NS, PWM_POLARITY_NORMAL),
+};
+
 static struct gpio palmte_bl_gpios[] = {
        { GPIO_NR_PALMTE2_BL_POWER, GPIOF_INIT_LOW, "Backlight power" },
        { GPIO_NR_PALMTE2_LCD_POWER, GPIOF_INIT_LOW, "LCD power" },
@@ -161,10 +167,8 @@ static void palmte2_backlight_exit(struct device *dev)
 }
 
 static struct platform_pwm_backlight_data palmte2_backlight_data = {
-       .pwm_id         = 0,
        .max_brightness = PALMTE2_MAX_INTENSITY,
        .dft_brightness = PALMTE2_MAX_INTENSITY,
-       .pwm_period_ns  = PALMTE2_PERIOD_NS,
        .enable_gpio    = -1,
        .init           = palmte2_backlight_init,
        .notify         = palmte2_backlight_notify,
@@ -355,6 +359,7 @@ static void __init palmte2_init(void)
        pxa_set_ac97_info(&palmte2_ac97_pdata);
        pxa_set_ficp_info(&palmte2_ficp_platform_data);
 
+       pwm_add_table(palmte2_pwm_lookup, ARRAY_SIZE(palmte2_pwm_lookup));
        platform_add_devices(devices, ARRAY_SIZE(devices));
 }
 
index d8319b54299a571d223321a53cd7776aa71ccece..b71c96f614f935317bfeb5d5b74b39a616aa64bd 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/platform_device.h>
 #include <linux/i2c.h>
 #include <linux/i2c/pxa-i2c.h>
+#include <linux/pwm.h>
 #include <linux/pwm_backlight.h>
 
 #include <media/mt9v022.h>
@@ -148,11 +149,14 @@ static struct pxafb_mach_info pcm990_fbinfo __initdata = {
 };
 #endif
 
+static struct pwm_lookup pcm990_pwm_lookup[] = {
+       PWM_LOOKUP("pxa27x-pwm.0", 0, "pwm-backlight.0", NULL, 78770,
+                  PWM_POLARITY_NORMAL),
+};
+
 static struct platform_pwm_backlight_data pcm990_backlight_data = {
-       .pwm_id         = 0,
        .max_brightness = 1023,
        .dft_brightness = 1023,
-       .pwm_period_ns  = 78770,
        .enable_gpio    = -1,
 };
 
@@ -542,6 +546,7 @@ void __init pcm990_baseboard_init(void)
 #ifndef CONFIG_PCM990_DISPLAY_NONE
        pxa_set_fb_info(NULL, &pcm990_fbinfo);
 #endif
+       pwm_add_table(pcm990_pwm_lookup, ARRAY_SIZE(pcm990_pwm_lookup));
        platform_device_register(&pcm990_backlight_device);
 
        /* MMC */
index 221260d5d1092364792e3eb181eea74a67462bc7..ffc4240285577919598820db167ec57c202fa2dd 100644 (file)
@@ -84,7 +84,7 @@ EXPORT_SYMBOL_GPL(pxa27x_configure_ac97reset);
  */
 static unsigned int pwrmode = PWRMODE_SLEEP;
 
-int __init pxa27x_set_pwrmode(unsigned int mode)
+int pxa27x_set_pwrmode(unsigned int mode)
 {
        switch (mode) {
        case PWRMODE_SLEEP:
index 06005d3f2ba33523d1ee4f9e96499290a9908572..20ce2d386f172c849459e94d1bb88601f1fdd0e7 100644 (file)
 #define PECR_IS(n)     ((1 << ((n) * 2)) << 29)
 
 extern void __init pxa_dt_irq_init(int (*fn)(struct irq_data *, unsigned int));
-#ifdef CONFIG_PM
-
-#define ISRAM_START    0x5c000000
-#define ISRAM_SIZE     SZ_256K
 
 /*
  * NAND NFC: DFI bus arbitration subset
@@ -54,6 +50,11 @@ extern void __init pxa_dt_irq_init(int (*fn)(struct irq_data *, unsigned int));
 #define NDCR_ND_ARB_EN         (1 << 12)
 #define NDCR_ND_ARB_CNTL       (1 << 19)
 
+#ifdef CONFIG_PM
+
+#define ISRAM_START    0x5c000000
+#define ISRAM_SIZE     SZ_256K
+
 static void __iomem *sram;
 static unsigned long wakeup_src;
 
index 88f70c37ad0dddef1fa85e9dd804c3c2fda41459..36571a9a44fecb47c18401b03f3a8775b0410cc8 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/leds.h>
 #include <linux/w1-gpio.h>
 #include <linux/sched.h>
+#include <linux/pwm.h>
 #include <linux/pwm_backlight.h>
 #include <linux/i2c.h>
 #include <linux/i2c/pxa-i2c.h>
@@ -507,7 +508,7 @@ static struct w1_gpio_platform_data w1_gpio_platform_data = {
        .ext_pullup_enable_pin  = -EINVAL,
 };
 
-struct platform_device raumfeld_w1_gpio_device = {
+static struct platform_device raumfeld_w1_gpio_device = {
        .name   = "w1-gpio",
        .dev    = {
                .platform_data = &w1_gpio_platform_data
@@ -531,13 +532,15 @@ static void __init raumfeld_w1_init(void)
  * Framebuffer device
  */
 
+static struct pwm_lookup raumfeld_pwm_lookup[] = {
+       PWM_LOOKUP("pxa27x-pwm.0", 0, "pwm-backlight", NULL, 10000,
+                  PWM_POLARITY_NORMAL),
+};
+
 /* PWM controlled backlight */
 static struct platform_pwm_backlight_data raumfeld_pwm_backlight_data = {
-       .pwm_id         = 0,
        .max_brightness = 100,
        .dft_brightness = 100,
-       /* 10000 ns = 10 ms ^= 100 kHz */
-       .pwm_period_ns  = 10000,
        .enable_gpio    = -1,
 };
 
@@ -618,6 +621,8 @@ static void __init raumfeld_lcd_init(void)
        } else {
                mfp_cfg_t raumfeld_pwm_pin_config = GPIO17_PWM0_OUT;
                pxa3xx_mfp_config(&raumfeld_pwm_pin_config, 1);
+               pwm_add_table(raumfeld_pwm_lookup,
+                             ARRAY_SIZE(raumfeld_pwm_lookup));
                platform_device_register(&raumfeld_pwm_backlight_device);
        }
 
@@ -629,7 +634,7 @@ static void __init raumfeld_lcd_init(void)
  * SPI devices
  */
 
-struct spi_gpio_platform_data raumfeld_spi_platform_data = {
+static struct spi_gpio_platform_data raumfeld_spi_platform_data = {
        .sck            = GPIO_SPI_CLK,
        .mosi           = GPIO_SPI_MOSI,
        .miso           = GPIO_SPI_MISO,
@@ -848,7 +853,7 @@ static void __init raumfeld_power_init(void)
 static struct regulator_consumer_supply audio_va_consumer_supply =
        REGULATOR_SUPPLY("va", "0-0048");
 
-struct regulator_init_data audio_va_initdata = {
+static struct regulator_init_data audio_va_initdata = {
        .consumer_supplies = &audio_va_consumer_supply,
        .num_consumer_supplies = 1,
        .constraints = {
@@ -880,7 +885,7 @@ static struct regulator_consumer_supply audio_dummy_supplies[] = {
        REGULATOR_SUPPLY("vlc", "0-0048"),
 };
 
-struct regulator_init_data audio_dummy_initdata = {
+static struct regulator_init_data audio_dummy_initdata = {
        .consumer_supplies = audio_dummy_supplies,
        .num_consumer_supplies = ARRAY_SIZE(audio_dummy_supplies),
        .constraints = {
@@ -928,7 +933,7 @@ static struct regulator_init_data vcc_mmc_init_data = {
        .num_consumer_supplies = 1,
 };
 
-struct max8660_subdev_data max8660_v6_subdev_data = {
+static struct max8660_subdev_data max8660_v6_subdev_data = {
        .id             = MAX8660_V6,
        .name           = "vmmc",
        .platform_data  = &vcc_mmc_init_data,
index a71da84e784b75fcf9f740758ee0cb0604d3f741..349a13a7621585cf4dbebf55c971cec80959b825 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/clk.h>
 #include <linux/gpio.h>
 #include <linux/smc91x.h>
+#include <linux/pwm.h>
 #include <linux/pwm_backlight.h>
 
 #include <asm/mach-types.h>
@@ -168,21 +169,24 @@ static inline void tavorevb_init_keypad(void) {}
 #endif /* CONFIG_KEYBOARD_PXA27x || CONFIG_KEYBOARD_PXA27x_MODULE */
 
 #if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+static struct pwm_lookup tavorevb_pwm_lookup[] = {
+       PWM_LOOKUP("pxa27x-pwm.0", 1, "pwm-backlight.0", NULL, 100000,
+                  PWM_POLARITY_NORMAL),
+       PWM_LOOKUP("pxa27x-pwm.0", 0, "pwm-backlight.1", NULL, 100000,
+                  PWM_POLARITY_NORMAL),
+};
+
 static struct platform_pwm_backlight_data tavorevb_backlight_data[] = {
        [0] = {
                /* primary backlight */
-               .pwm_id         = 2,
                .max_brightness = 100,
                .dft_brightness = 100,
-               .pwm_period_ns  = 100000,
                .enable_gpio    = -1,
        },
        [1] = {
                /* secondary backlight */
-               .pwm_id         = 0,
                .max_brightness = 100,
                .dft_brightness = 100,
-               .pwm_period_ns  = 100000,
                .enable_gpio    = -1,
        },
 };
@@ -470,6 +474,7 @@ static struct pxafb_mach_info tavorevb_lcd_info = {
 
 static void __init tavorevb_init_lcd(void)
 {
+       pwm_add_table(tavorevb_pwm_lookup, ARRAY_SIZE(tavorevb_pwm_lookup));
        platform_device_register(&tavorevb_backlight_devices[0]);
        platform_device_register(&tavorevb_backlight_devices[1]);
        pxa_set_fb_info(NULL, &tavorevb_lcd_info);
index 8ab26370107ea5d0df2742b1ac0ab31aa18eb425..7ecc61ad2bed08bb976d1f6be31851e2bd75e5cf 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/i2c/pxa-i2c.h>
 #include <linux/serial_8250.h>
 #include <linux/smc91x.h>
+#include <linux/pwm.h>
 #include <linux/pwm_backlight.h>
 #include <linux/usb/isp116x.h>
 #include <linux/mtd/mtd.h>
@@ -350,6 +351,11 @@ static struct pxafb_mach_info fb_info = {
        .lcd_conn               = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
 };
 
+static struct pwm_lookup viper_pwm_lookup[] = {
+       PWM_LOOKUP("pxa25x-pwm.0", 0, "pwm-backlight.0", NULL, 1000000,
+                  PWM_POLARITY_NORMAL),
+};
+
 static int viper_backlight_init(struct device *dev)
 {
        int ret;
@@ -398,10 +404,8 @@ static void viper_backlight_exit(struct device *dev)
 }
 
 static struct platform_pwm_backlight_data viper_backlight_data = {
-       .pwm_id         = 0,
        .max_brightness = 100,
        .dft_brightness = 100,
-       .pwm_period_ns  = 1000000,
        .enable_gpio    = -1,
        .init           = viper_backlight_init,
        .notify         = viper_backlight_notify,
@@ -939,6 +943,7 @@ static void __init viper_init(void)
                smc91x_device.num_resources--;
 
        pxa_set_i2c_info(NULL);
+       pwm_add_table(viper_pwm_lookup, ARRAY_SIZE(viper_pwm_lookup));
        platform_add_devices(viper_devs, ARRAY_SIZE(viper_devs));
 
        viper_init_vcore_gpios();
index e1a121b36cfa6eef0e9dec7155da7f929e1075ed..d9899d73e46bf8c8c1c5c09ff9b45629ded7066b 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/platform_device.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
+#include <linux/pwm.h>
 #include <linux/pwm_backlight.h>
 #include <linux/z2_battery.h>
 #include <linux/dma-mapping.h>
@@ -199,21 +200,24 @@ static inline void z2_nor_init(void) {}
  * Backlight
  ******************************************************************************/
 #if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE)
+static struct pwm_lookup z2_pwm_lookup[] = {
+       PWM_LOOKUP("pxa27x-pwm.1", 0, "pwm-backlight.0", NULL, 1260320,
+                  PWM_POLARITY_NORMAL),
+       PWM_LOOKUP("pxa27x-pwm.0", 1, "pwm-backlight.1", NULL, 1260320,
+                  PWM_POLARITY_NORMAL),
+};
+
 static struct platform_pwm_backlight_data z2_backlight_data[] = {
        [0] = {
                /* Keypad Backlight */
-               .pwm_id         = 1,
                .max_brightness = 1023,
                .dft_brightness = 0,
-               .pwm_period_ns  = 1260320,
                .enable_gpio    = -1,
        },
        [1] = {
                /* LCD Backlight */
-               .pwm_id         = 2,
                .max_brightness = 1023,
                .dft_brightness = 512,
-               .pwm_period_ns  = 1260320,
                .enable_gpio    = -1,
        },
 };
@@ -236,6 +240,7 @@ static struct platform_device z2_backlight_devices[2] = {
 };
 static void __init z2_pwm_init(void)
 {
+       pwm_add_table(z2_pwm_lookup, ARRAY_SIZE(z2_pwm_lookup));
        platform_device_register(&z2_backlight_devices[0]);
        platform_device_register(&z2_backlight_devices[1]);
 }
@@ -595,13 +600,11 @@ static struct spi_board_info spi_board_info[] __initdata = {
 };
 
 static struct pxa2xx_spi_master pxa_ssp1_master_info = {
-       .clock_enable   = CKEN_SSP,
        .num_chipselect = 1,
        .enable_dma     = 1,
 };
 
 static struct pxa2xx_spi_master pxa_ssp2_master_info = {
-       .clock_enable   = CKEN_SSP2,
        .num_chipselect = 1,
 };
 
index 77daea478e88709aa20568d30073ae3c625efa73..e20359a7433cc8c0d4b12bd5b403e9cc7852f61b 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
+#include <linux/pwm.h>
 #include <linux/pwm_backlight.h>
 #include <linux/smc91x.h>
 
@@ -120,11 +121,14 @@ static inline void zylonite_init_leds(void) {}
 #endif
 
 #if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+static struct pwm_lookup zylonite_pwm_lookup[] = {
+       PWM_LOOKUP("pxa27x-pwm.1", 1, "pwm-backlight.0", NULL, 10000,
+                  PWM_POLARITY_NORMAL),
+};
+
 static struct platform_pwm_backlight_data zylonite_backlight_data = {
-       .pwm_id         = 3,
        .max_brightness = 100,
        .dft_brightness = 100,
-       .pwm_period_ns  = 10000,
        .enable_gpio    = -1,
 };
 
@@ -206,6 +210,7 @@ static struct pxafb_mach_info zylonite_sharp_lcd_info = {
 
 static void __init zylonite_init_lcd(void)
 {
+       pwm_add_table(zylonite_pwm_lookup, ARRAY_SIZE(zylonite_pwm_lookup));
        platform_device_register(&zylonite_backlight_device);
 
        if (lcd_id & 0x20) {
index 5cde63a64b34d9d5ff2b6c1821d4a4caa77586ae..9b00123a315d253daa5183058f919f7fff98e41c 100644 (file)
@@ -49,7 +49,7 @@ extern void secondary_startup_arm(void);
 static DEFINE_SPINLOCK(boot_lock);
 
 #ifdef CONFIG_HOTPLUG_CPU
-static void __ref qcom_cpu_die(unsigned int cpu)
+static void qcom_cpu_die(unsigned int cpu)
 {
        wfi();
 }
index ac22dd41b13509e3195a21bbbeef0a24bdeb498c..968e2d1964f672536264d7bb6029907a03631e28 100644 (file)
@@ -90,7 +90,7 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
  *
  * Called with IRQs disabled
  */
-void __ref realview_cpu_die(unsigned int cpu)
+void realview_cpu_die(unsigned int cpu)
 {
        int spurious = 0;
 
index d40d4f5244c6835e4e73205b9e91a20d55613c03..9f54300df4b3c519b17070f65301abae9ba31768 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/gpio.h>
 #include <linux/input.h>
 #include <linux/gpio_keys.h>
+#include <linux/pwm.h>
 #include <linux/pwm_backlight.h>
 #include <linux/i2c.h>
 #include <linux/leds.h>
@@ -469,6 +470,11 @@ static struct s3c24xx_mci_pdata h1940_mmc_cfg __initdata = {
        .ocr_avail     = MMC_VDD_32_33,
 };
 
+static struct pwm_lookup h1940_pwm_lookup[] = {
+       PWM_LOOKUP("samsung-pwm", 0, "pwm-backlight", NULL, 36296,
+                  PWM_POLARITY_NORMAL),
+};
+
 static int h1940_backlight_init(struct device *dev)
 {
        gpio_request(S3C2410_GPB(0), "Backlight");
@@ -503,11 +509,8 @@ static void h1940_backlight_exit(struct device *dev)
 
 
 static struct platform_pwm_backlight_data backlight_data = {
-       .pwm_id         = 0,
        .max_brightness = 100,
        .dft_brightness = 50,
-       /* tcnt = 0x31 */
-       .pwm_period_ns  = 36296,
        .enable_gpio    = -1,
        .init           = h1940_backlight_init,
        .notify         = h1940_backlight_notify,
@@ -725,6 +728,7 @@ static void __init h1940_init(void)
        gpio_request(H1940_LATCH_SD_POWER, "SD power");
        gpio_direction_output(H1940_LATCH_SD_POWER, 0);
 
+       pwm_add_table(h1940_pwm_lookup, ARRAY_SIZE(h1940_pwm_lookup));
        platform_add_devices(h1940_devices, ARRAY_SIZE(h1940_devices));
 
        gpio_request(S3C2410_GPA(1), "Red LED blink");
index 1d35ff375a01297726825ffdefd3d5253a852561..774c982a7b7ed4260a49ca01d7d9714b188f65d4 100644 (file)
@@ -375,6 +375,11 @@ static struct s3c2410fb_mach_info rx1950_lcd_cfg = {
 
 };
 
+static struct pwm_lookup rx1950_pwm_lookup[] = {
+       PWM_LOOKUP("samsung-pwm", 0, "pwm-backlight.0", NULL, 48000,
+                  PWM_POLARITY_NORMAL),
+};
+
 static struct pwm_device *lcd_pwm;
 
 static void rx1950_lcd_power(int enable)
@@ -520,10 +525,8 @@ static int rx1950_backlight_notify(struct device *dev, int brightness)
 }
 
 static struct platform_pwm_backlight_data rx1950_backlight_data = {
-       .pwm_id = 0,
        .max_brightness = 24,
        .dft_brightness = 4,
-       .pwm_period_ns = 48000,
        .enable_gpio = -1,
        .init = rx1950_backlight_init,
        .notify = rx1950_backlight_notify,
@@ -792,6 +795,7 @@ static void __init rx1950_init_machine(void)
        gpio_direction_output(S3C2410_GPA(4), 0);
        gpio_direction_output(S3C2410_GPJ(6), 0);
 
+       pwm_add_table(rx1950_pwm_lookup, ARRAY_SIZE(rx1950_pwm_lookup));
        platform_add_devices(rx1950_devices, ARRAY_SIZE(rx1950_devices));
 
        i2c_register_board_info(0, rx1950_i2c_devices,
index 38c323e68e3f910ba8e9ecb413f603161a44253d..e62e789f9aeeecd279c93ce6b8c7775e283074e4 100644 (file)
@@ -69,7 +69,6 @@ static struct samsung_bl_drvdata samsung_dfl_bl_data __initdata = {
        .plat_data = {
                .max_brightness = 255,
                .dft_brightness = 255,
-               .pwm_period_ns  = 78770,
                .enable_gpio    = -1,
                .init           = samsung_bl_init,
                .exit           = samsung_bl_exit,
@@ -111,7 +110,6 @@ void __init samsung_bl_set(struct samsung_bl_gpio_info *gpio_info,
        samsung_bl_data = &samsung_bl_drvdata->plat_data;
 
        /* Copy board specific data provided by user */
-       samsung_bl_data->pwm_id = bl_data->pwm_id;
        samsung_bl_device->dev.parent = &samsung_device_pwm.dev;
 
        if (bl_data->max_brightness)
@@ -120,8 +118,6 @@ void __init samsung_bl_set(struct samsung_bl_gpio_info *gpio_info,
                samsung_bl_data->dft_brightness = bl_data->dft_brightness;
        if (bl_data->lth_brightness)
                samsung_bl_data->lth_brightness = bl_data->lth_brightness;
-       if (bl_data->pwm_period_ns)
-               samsung_bl_data->pwm_period_ns = bl_data->pwm_period_ns;
        if (bl_data->enable_gpio >= 0)
                samsung_bl_data->enable_gpio = bl_data->enable_gpio;
        if (bl_data->init)
index 65c426bc45f72eb530df0736493d4e4a373904cd..d13aa3f9bac48b70c81e20fca87741a40ca61b9c 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/mmc/host.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/fixed.h>
+#include <linux/pwm.h>
 #include <linux/pwm_backlight.h>
 #include <linux/dm9000.h>
 #include <linux/gpio_keys.h>
@@ -108,11 +109,14 @@ static struct s3c2410_uartcfg crag6410_uartcfgs[] __initdata = {
        },
 };
 
+static struct pwm_lookup crag6410_pwm_lookup[] = {
+       PWM_LOOKUP("samsung-pwm", 0, "pwm-backlight", NULL, 100000,
+                  PWM_POLARITY_NORMAL),
+};
+
 static struct platform_pwm_backlight_data crag6410_backlight_data = {
-       .pwm_id         = 0,
        .max_brightness = 1000,
        .dft_brightness = 600,
-       .pwm_period_ns  = 100000,       /* about 1kHz */
        .enable_gpio    = -1,
 };
 
@@ -843,6 +847,7 @@ static void __init crag6410_machine_init(void)
        samsung_keypad_set_platdata(&crag6410_keypad_data);
        s3c64xx_spi0_set_platdata(NULL, 0, 2);
 
+       pwm_add_table(crag6410_pwm_lookup, ARRAY_SIZE(crag6410_pwm_lookup));
        platform_add_devices(crag6410_devices, ARRAY_SIZE(crag6410_devices));
 
        gpio_led_register_device(-1, &gpio_leds_pdata);
index e4b087c58ee61ae14fbe69f8204c85d806909666..816b39d1e6d1b13c5a074676431b16efb145631c 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/gpio.h>
 #include <linux/delay.h>
 #include <linux/leds.h>
+#include <linux/pwm.h>
 #include <linux/pwm_backlight.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
@@ -73,6 +74,11 @@ static struct s3c2410_uartcfg hmt_uartcfgs[] __initdata = {
        },
 };
 
+static struct pwm_lookup hmt_pwm_lookup[] = {
+       PWM_LOOKUP("samsung-pwm", 1, "pwm-backlight.0", NULL,
+                  1000000000 / (100 * 256 * 20), PWM_POLARITY_NORMAL),
+};
+
 static int hmt_bl_init(struct device *dev)
 {
        int ret;
@@ -110,10 +116,8 @@ static void hmt_bl_exit(struct device *dev)
 }
 
 static struct platform_pwm_backlight_data hmt_backlight_data = {
-       .pwm_id         = 1,
        .max_brightness = 100 * 256,
        .dft_brightness = 40 * 256,
-       .pwm_period_ns  = 1000000000 / (100 * 256 * 20),
        .enable_gpio    = -1,
        .init           = hmt_bl_init,
        .notify         = hmt_bl_notify,
@@ -268,6 +272,7 @@ static void __init hmt_machine_init(void)
        gpio_request(S3C64XX_GPF(13), "usb power");
        gpio_direction_output(S3C64XX_GPF(13), 1);
 
+       pwm_add_table(hmt_pwm_lookup, ARRAY_SIZE(hmt_pwm_lookup));
        platform_add_devices(hmt_devices, ARRAY_SIZE(hmt_devices));
 }
 
index b3d13537a7f0b2a0ce1fb3adfcd28efce08f7c3b..7b8a3699795c0e636210455535b36c7e57566606 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
+#include <linux/pwm.h>
 #include <linux/pwm_backlight.h>
 #include <linux/serial_core.h>
 #include <linux/serial_s3c.h>
@@ -139,6 +140,11 @@ static struct platform_device smartq_usb_otg_vbus_dev = {
        .dev.platform_data      = &smartq_usb_otg_vbus_pdata,
 };
 
+static struct pwm_lookup smartq_pwm_lookup[] = {
+       PWM_LOOKUP("samsung-pwm", 1, "pwm-backlight.0", NULL,
+                  1000000000 / (1000 * 20), PWM_POLARITY_NORMAL),
+};
+
 static int smartq_bl_init(struct device *dev)
 {
     s3c_gpio_cfgpin(S3C64XX_GPF(15), S3C_GPIO_SFN(2));
@@ -147,10 +153,8 @@ static int smartq_bl_init(struct device *dev)
 }
 
 static struct platform_pwm_backlight_data smartq_backlight_data = {
-       .pwm_id         = 1,
        .max_brightness = 1000,
        .dft_brightness = 600,
-       .pwm_period_ns  = 1000000000 / (1000 * 20),
        .enable_gpio    = -1,
        .init           = smartq_bl_init,
 };
@@ -396,5 +400,6 @@ void __init smartq_machine_init(void)
        WARN_ON(smartq_usb_host_init());
        WARN_ON(smartq_wifi_init());
 
+       pwm_add_table(smartq_pwm_lookup, ARRAY_SIZE(smartq_pwm_lookup));
        platform_add_devices(smartq_devices, ARRAY_SIZE(smartq_devices));
 }
index d590b88bd8a83a8863c0cbdf5548654ba4b99776..2722800d5c11ae6c760dbf436049c3c0029856f0 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/smsc911x.h>
 #include <linux/regulator/fixed.h>
 #include <linux/regulator/machine.h>
+#include <linux/pwm.h>
 #include <linux/pwm_backlight.h>
 #include <linux/platform_data/s3c-hsotg.h>
 
@@ -623,8 +624,12 @@ static struct samsung_bl_gpio_info smdk6410_bl_gpio_info = {
        .func = S3C_GPIO_SFN(2),
 };
 
+static struct pwm_lookup smdk6410_pwm_lookup[] = {
+       PWM_LOOKUP("samsung-pwm", 1, "pwm-backlight.0", NULL, 78770,
+                  PWM_POLARITY_NORMAL),
+};
+
 static struct platform_pwm_backlight_data smdk6410_bl_data = {
-       .pwm_id = 1,
        .enable_gpio = -1,
 };
 
@@ -695,6 +700,7 @@ static void __init smdk6410_machine_init(void)
 
        platform_add_devices(smdk6410_devices, ARRAY_SIZE(smdk6410_devices));
 
+       pwm_add_table(smdk6410_pwm_lookup, ARRAY_SIZE(smdk6410_pwm_lookup));
        samsung_bl_set(&smdk6410_bl_gpio_info, &smdk6410_bl_data);
 }
 
index 4e54512bee308312a7113751832e320490fbe5db..911884f7e28b174c271c6724c863520afe859868 100644 (file)
@@ -88,7 +88,7 @@ static void apmu_init_cpu(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 id;
        int k;
        int bit, index;
        bool is_allowed;
@@ -170,7 +170,7 @@ static inline void cpu_enter_lowpower_a15(void)
        dsb();
 }
 
-void shmobile_smp_apmu_cpu_shutdown(unsigned int cpu)
+static void shmobile_smp_apmu_cpu_shutdown(unsigned int cpu)
 {
 
        /* Select next sleep mode using the APMU */
index 47a862e7f8bab242a180e3e72bba6c306ff15f03..14c42a1bdf1ef20d506f47d8fe013be7e71254b9 100644 (file)
@@ -9,20 +9,8 @@
  * for more details.
  */
 
-#include <linux/pm.h>
-#include <linux/suspend.h>
-#include <linux/err.h>
-#include <linux/pm_clock.h>
-#include <linux/pm_domain.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/irq.h>
-#include <linux/interrupt.h>
-#include <linux/console.h>
-
 #include <asm/io.h>
 
-#include "common.h"
 #include "pm-rcar.h"
 #include "r8a7779.h"
 
 #define SYSCIER 0x0c
 #define SYSCIMR 0x10
 
-struct r8a7779_pm_domain {
-       struct generic_pm_domain genpd;
-       struct rcar_sysc_ch ch;
-};
-
-static inline
-const struct rcar_sysc_ch *to_r8a7779_ch(struct generic_pm_domain *d)
-{
-       return &container_of(d, struct r8a7779_pm_domain, genpd)->ch;
-}
-
 #if defined(CONFIG_PM) || defined(CONFIG_SMP)
 
 static void __init r8a7779_sysc_init(void)
@@ -58,82 +35,6 @@ static inline void r8a7779_sysc_init(void) {}
 
 #endif /* CONFIG_PM || CONFIG_SMP */
 
-#ifdef CONFIG_PM
-
-static int pd_power_down(struct generic_pm_domain *genpd)
-{
-       return rcar_sysc_power_down(to_r8a7779_ch(genpd));
-}
-
-static int pd_power_up(struct generic_pm_domain *genpd)
-{
-       return rcar_sysc_power_up(to_r8a7779_ch(genpd));
-}
-
-static bool pd_is_off(struct generic_pm_domain *genpd)
-{
-       return rcar_sysc_power_is_off(to_r8a7779_ch(genpd));
-}
-
-static bool pd_active_wakeup(struct device *dev)
-{
-       return true;
-}
-
-static void r8a7779_init_pm_domain(struct r8a7779_pm_domain *r8a7779_pd)
-{
-       struct generic_pm_domain *genpd = &r8a7779_pd->genpd;
-
-       pm_genpd_init(genpd, NULL, false);
-       genpd->dev_ops.active_wakeup = pd_active_wakeup;
-       genpd->power_off = pd_power_down;
-       genpd->power_on = pd_power_up;
-
-       if (pd_is_off(&r8a7779_pd->genpd))
-               pd_power_up(&r8a7779_pd->genpd);
-}
-
-static struct r8a7779_pm_domain r8a7779_pm_domains[] = {
-       {
-               .genpd.name = "SH4A",
-               .ch = {
-                       .chan_offs = 0x80, /* PWRSR1 .. PWRER1 */
-                       .isr_bit = 16, /* SH4A */
-               },
-       },
-       {
-               .genpd.name = "SGX",
-               .ch = {
-                       .chan_offs = 0xc0, /* PWRSR2 .. PWRER2 */
-                       .isr_bit = 20, /* SGX */
-               },
-       },
-       {
-               .genpd.name = "VDP1",
-               .ch = {
-                       .chan_offs = 0x100, /* PWRSR3 .. PWRER3 */
-                       .isr_bit = 21, /* VDP */
-               },
-       },
-       {
-               .genpd.name = "IMPX3",
-               .ch = {
-                       .chan_offs = 0x140, /* PWRSR4 .. PWRER4 */
-                       .isr_bit = 24, /* IMP */
-               },
-       },
-};
-
-void __init r8a7779_init_pm_domains(void)
-{
-       int j;
-
-       for (j = 0; j < ARRAY_SIZE(r8a7779_pm_domains); j++)
-               r8a7779_init_pm_domain(&r8a7779_pm_domains[j]);
-}
-
-#endif /* CONFIG_PM */
-
 void __init r8a7779_pm_init(void)
 {
        static int once;
index a5b96b990aea8dfc551ea56f0421cd0837b68a82..46d0a1ddce755e80ffc3f8f1bc6a510287da7906 100644 (file)
@@ -12,6 +12,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  */
+#include <linux/clk/shmobile.h>
 #include <linux/console.h>
 #include <linux/delay.h>
 #include <linux/of.h>
@@ -124,36 +125,6 @@ static bool rmobile_pd_active_wakeup(struct device *dev)
        return true;
 }
 
-static int rmobile_pd_attach_dev(struct generic_pm_domain *domain,
-                                struct device *dev)
-{
-       int error;
-
-       error = pm_clk_create(dev);
-       if (error) {
-               dev_err(dev, "pm_clk_create failed %d\n", error);
-               return error;
-       }
-
-       error = pm_clk_add(dev, NULL);
-       if (error) {
-               dev_err(dev, "pm_clk_add failed %d\n", error);
-               goto fail;
-       }
-
-       return 0;
-
-fail:
-       pm_clk_destroy(dev);
-       return error;
-}
-
-static void rmobile_pd_detach_dev(struct generic_pm_domain *domain,
-                                 struct device *dev)
-{
-       pm_clk_destroy(dev);
-}
-
 static void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd)
 {
        struct generic_pm_domain *genpd = &rmobile_pd->genpd;
@@ -164,8 +135,8 @@ static void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd)
        genpd->dev_ops.active_wakeup    = rmobile_pd_active_wakeup;
        genpd->power_off                = rmobile_pd_power_down;
        genpd->power_on                 = rmobile_pd_power_up;
-       genpd->attach_dev               = rmobile_pd_attach_dev;
-       genpd->detach_dev               = rmobile_pd_detach_dev;
+       genpd->attach_dev               = cpg_mstp_attach_dev;
+       genpd->detach_dev               = cpg_mstp_detach_dev;
        __rmobile_pd_power_up(rmobile_pd, false);
 }
 
@@ -342,8 +313,10 @@ static int __init rmobile_add_pm_domains(void __iomem *base,
                }
 
                pd = kzalloc(sizeof(*pd), GFP_KERNEL);
-               if (!pd)
+               if (!pd) {
+                       of_node_put(np);
                        return -ENOMEM;
+               }
 
                pd->genpd.name = np->name;
                pd->base = base;
index aad833a8f0b8c5f169f9cfc09a09da7daf17c4e9..e1aaa2ef9376c91de1696ce0b475387af6390012 100644 (file)
@@ -3,12 +3,6 @@
 
 extern void r8a7779_pm_init(void);
 
-#ifdef CONFIG_PM
-extern void __init r8a7779_init_pm_domains(void);
-#else
-static inline void r8a7779_init_pm_domains(void) {}
-#endif /* CONFIG_PM */
-
 extern struct smp_operations r8a7779_smp_ops;
 
 #endif /* __ASM_R8A7779_H__ */
index b0c9986d022d86649879fa68cf6bf0dab27ae453..0ab9d32728758a9aa17dc850696ace8e75b49637 100644 (file)
@@ -42,7 +42,8 @@ static void __init r8a7778_timer_init(void)
 
 #define INT2NTSR0      0x00018 /* 0xfe700018 */
 #define INT2NTSR1      0x0002c /* 0xfe70002c */
-void __init r8a7778_init_irq_dt(void)
+
+static void __init r8a7778_init_irq_dt(void)
 {
        void __iomem *base = ioremap_nocache(0xfe700000, 0x00100000);
 
index d97749c642ce67b8bf721dc61461b5106594a3f3..12edd1cf8a12f11a2a07851f59bc5747e925cd36 100644 (file)
@@ -80,7 +80,7 @@ static inline void spear13xx_do_lowpower(unsigned int cpu, int *spurious)
  *
  * Called with IRQs disabled
  */
-void __ref spear13xx_cpu_die(unsigned int cpu)
+void spear13xx_cpu_die(unsigned int cpu)
 {
        int spurious = 0;
 
index 65bab2876343aff24707105f0432c90faaf90e60..8583a9ca86bd6f70220c4055fb9da8b916a7233a 100644 (file)
@@ -26,10 +26,11 @@ static const char * const sunxi_board_dt_compat[] = {
        "allwinner,sun4i-a10",
        "allwinner,sun5i-a10s",
        "allwinner,sun5i-a13",
+       "allwinner,sun5i-r8",
        NULL,
 };
 
-DT_MACHINE_START(SUNXI_DT, "Allwinner A1X (Device Tree)")
+DT_MACHINE_START(SUNXI_DT, "Allwinner sun4i/sun5i Families")
        .dt_compat      = sunxi_board_dt_compat,
        .init_late      = sunxi_dt_cpufreq_init,
 MACHINE_END
index fbe74c6806f3b53e726d96fe2c2f396ad81c9c5f..49d1110cff5341954e3d980d003fda4f516138f0 100644 (file)
@@ -39,8 +39,8 @@ static struct platform_device wifi_rfkill_device = {
 static struct gpiod_lookup_table wifi_gpio_lookup = {
        .dev_id = "rfkill_gpio",
        .table = {
-               GPIO_LOOKUP_IDX("tegra-gpio", 25, NULL, 0, 0),
-               GPIO_LOOKUP_IDX("tegra-gpio", 85, NULL, 1, 0),
+               GPIO_LOOKUP("tegra-gpio", 25, "reset", 0),
+               GPIO_LOOKUP("tegra-gpio", 85, "shutdown", 0),
                { },
        },
 };
index 6fc71f1534b069f9f8d28e0283e6a37812c3802d..1b129899a277f1853b6309782caac72f1f4a45d3 100644 (file)
@@ -37,7 +37,7 @@ int tegra_cpu_kill(unsigned cpu)
  *
  * Called with IRQs disabled
  */
-void __ref tegra_cpu_die(unsigned int cpu)
+void tegra_cpu_die(unsigned int cpu)
 {
        if (!tegra_hotplug_shutdown) {
                WARN(1, "hotplug is not yet initialized\n");
index 2bc00b085e38d4b1540a25563058735cd67a1af4..1cbed0331fd3267be988866016dc025dd4068052 100644 (file)
@@ -21,7 +21,7 @@
  *
  * Called with IRQs disabled
  */
-void __ref ux500_cpu_die(unsigned int cpu)
+void ux500_cpu_die(unsigned int cpu)
 {
        /* directly enter low power state, skipping secure registers */
        for (;;) {
index f0ce6b8f5e71ba19900dee86e56274a526835bf2..f2fafc10a91d67f0e5f5d2a8c652406da554f361 100644 (file)
@@ -85,7 +85,7 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
  *
  * Called with IRQs disabled
  */
-void __ref vexpress_cpu_die(unsigned int cpu)
+void vexpress_cpu_die(unsigned int cpu)
 {
        int spurious = 0;
 
index 2235081a04eeac818f58b44923aa565026c0b746..8861c367d06114651920b05420e53ebde3099712 100644 (file)
@@ -495,7 +495,7 @@ void __init orion_ge00_switch_init(struct dsa_platform_data *d, int irq)
 
        d->netdev = &orion_ge00.dev;
        for (i = 0; i < d->nr_chips; i++)
-               d->chip[i].host_dev = &orion_ge00_shared.dev;
+               d->chip[i].host_dev = &orion_ge_mvmdio.dev;
        orion_switch_device.dev.platform_data = d;
 
        platform_device_register(&orion_switch_device);
index 8aba80a20306acf6d8679f70af04870f08a60f5b..4043c35962cca5411e4edf26c0fa8da50ab9fda9 100644 (file)
@@ -7,6 +7,7 @@ config ARCH_BCM_IPROC
 
 config ARCH_BERLIN
        bool "Marvell Berlin SoC Family"
+       select ARCH_REQUIRE_GPIOLIB
        select DW_APB_ICTL
        help
          This enables support for Marvell Berlin SoC Family
index c7c99a42e2e997684449482535965a0570598044..21c945480c9c7ccac888fc277e2633f996cb12ae 100644 (file)
 
                                button@1 {
                                        debounce_interval = <50>;
-                                       wakeup = <1>;
+                                       wakeup-source;
                                        linux,code = <116>;
                                        label = "POWER";
                                        gpios = <&iofpga_gpio0 0 0x4>;
                                };
                                button@2 {
                                        debounce_interval = <50>;
-                                       wakeup = <1>;
+                                       wakeup-source;
                                        linux,code = <102>;
                                        label = "HOME";
                                        gpios = <&iofpga_gpio0 1 0x4>;
                                };
                                button@3 {
                                        debounce_interval = <50>;
-                                       wakeup = <1>;
+                                       wakeup-source;
                                        linux,code = <152>;
                                        label = "RLOCK";
                                        gpios = <&iofpga_gpio0 2 0x4>;
                                };
                                button@4 {
                                        debounce_interval = <50>;
-                                       wakeup = <1>;
+                                       wakeup-source;
                                        linux,code = <115>;
                                        label = "VOL+";
                                        gpios = <&iofpga_gpio0 3 0x4>;
                                };
                                button@5 {
                                        debounce_interval = <50>;
-                                       wakeup = <1>;
+                                       wakeup-source;
                                        linux,code = <114>;
                                        label = "VOL-";
                                        gpios = <&iofpga_gpio0 4 0x4>;
                                };
                                button@6 {
                                        debounce_interval = <50>;
-                                       wakeup = <1>;
+                                       wakeup-source;
                                        linux,code = <99>;
                                        label = "NMI";
                                        gpios = <&iofpga_gpio0 5 0x4>;
index 4be66cadbc7c19220bafe8bba7e7a9eb1df80fc3..811cb760ba49dd4e4d53140d362a47ddf8121ced 100644 (file)
        };
 };
 
+&pio {
+       spi_pins_a: spi0 {
+               pins_spi {
+                       pinmux = <MT8173_PIN_69_SPI_CK__FUNC_SPI_CK_0_>,
+                               <MT8173_PIN_70_SPI_MI__FUNC_SPI_MI_0_>,
+                               <MT8173_PIN_71_SPI_MO__FUNC_SPI_MO_0_>,
+                               <MT8173_PIN_72_SPI_CS__FUNC_SPI_CS_0_>;
+               };
+       };
+};
+
+&spi {
+       pinctrl-names = "default";
+       pinctrl-0 = <&spi_pins_a>;
+       mediatek,pad-select = <0>;
+       status = "okay";
+};
+
 &uart0 {
        status = "okay";
 };
index 06a15644be38439e63dfee78f59f2f720921c24e..4dd5f93d0303f9302e80f171ed9bfbeff8bb994b 100644 (file)
                clock-output-names = "clk32k";
        };
 
+       cpum_ck: oscillator@2 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <0>;
+               clock-output-names = "cpum_ck";
+       };
+
        timer {
                compatible = "arm,armv8-timer";
                interrupt-parent = <&gic>;
                        #power-domain-cells = <1>;
                        reg = <0 0x10006000 0 0x1000>;
                        clocks = <&clk26m>,
-                                <&topckgen CLK_TOP_MM_SEL>;
-                       clock-names = "mfg", "mm";
+                                <&topckgen CLK_TOP_MM_SEL>,
+                                <&topckgen CLK_TOP_VENC_SEL>,
+                                <&topckgen CLK_TOP_VENC_LT_SEL>;
+                       clock-names = "mfg", "mm", "venc", "venc_lt";
                        infracfg = <&infracfg>;
                };
 
                        status = "disabled";
                };
 
-               i2c3: i2c3@11010000 {
+               spi: spi@1100a000 {
+                       compatible = "mediatek,mt8173-spi";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0 0x1100a000 0 0x1000>;
+                       interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_LOW>;
+                       clocks = <&topckgen CLK_TOP_SYSPLL3_D2>,
+                                <&topckgen CLK_TOP_SPI_SEL>,
+                                <&pericfg CLK_PERI_SPI0>;
+                       clock-names = "parent-clk", "sel-clk", "spi-clk";
+                       status = "disabled";
+               };
+
+               i2c3: i2c@11010000 {
                        compatible = "mediatek,mt8173-i2c";
                        reg = <0 0x11010000 0 0x70>,
                              <0 0x11000280 0 0x80>;
                        status = "disabled";
                };
 
-               i2c4: i2c4@11011000 {
+               i2c4: i2c@11011000 {
                        compatible = "mediatek,mt8173-i2c";
                        reg = <0 0x11011000 0 0x70>,
                              <0 0x11000300 0 0x80>;
                        status = "disabled";
                };
 
-               i2c6: i2c6@11013000 {
+               i2c6: i2c@11013000 {
                        compatible = "mediatek,mt8173-i2c";
                        reg = <0 0x11013000 0 0x70>,
                              <0 0x11000080 0 0x80>;
                        clock-names = "source", "hclk";
                        status = "disabled";
                };
+
+               mmsys: clock-controller@14000000 {
+                       compatible = "mediatek,mt8173-mmsys", "syscon";
+                       reg = <0 0x14000000 0 0x1000>;
+                       #clock-cells = <1>;
+               };
+
+               imgsys: clock-controller@15000000 {
+                       compatible = "mediatek,mt8173-imgsys", "syscon";
+                       reg = <0 0x15000000 0 0x1000>;
+                       #clock-cells = <1>;
+               };
+
+               vdecsys: clock-controller@16000000 {
+                       compatible = "mediatek,mt8173-vdecsys", "syscon";
+                       reg = <0 0x16000000 0 0x1000>;
+                       #clock-cells = <1>;
+               };
+
+               vencsys: clock-controller@18000000 {
+                       compatible = "mediatek,mt8173-vencsys", "syscon";
+                       reg = <0 0x18000000 0 0x1000>;
+                       #clock-cells = <1>;
+               };
+
+               vencltsys: clock-controller@19000000 {
+                       compatible = "mediatek,mt8173-vencltsys", "syscon";
+                       reg = <0 0x19000000 0 0x1000>;
+                       #clock-cells = <1>;
+               };
        };
 };
 
index 8f07e923dd5f4da92718ea5e6eb79d85e35869bd..3a16aa5defdc847548d259fc4f1b1b49b311219f 100644 (file)
@@ -117,8 +117,11 @@ CONFIG_SERIAL_XILINX_PS_UART=y
 CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y
 CONFIG_VIRTIO_CONSOLE=y
 # CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_QUP=y
 CONFIG_SPI=y
 CONFIG_SPI_PL022=y
+CONFIG_SPI_QUP=y
 CONFIG_PINCTRL_MSM8916=y
 CONFIG_GPIO_PL061=y
 CONFIG_GPIO_XGENE=y
@@ -127,6 +130,7 @@ CONFIG_POWER_RESET_SYSCON=y
 # CONFIG_HWMON is not set
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_QCOM_SMD_RPM=y
 CONFIG_FB=y
 CONFIG_FB_ARMCLCD=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
@@ -155,12 +159,18 @@ CONFIG_LEDS_TRIGGER_CPU=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_EFI=y
 CONFIG_RTC_DRV_XGENE=y
+CONFIG_DMADEVICES=y
+CONFIG_QCOM_BAM_DMA=y
 CONFIG_VIRTIO_PCI=y
 CONFIG_VIRTIO_BALLOON=y
 CONFIG_VIRTIO_MMIO=y
 CONFIG_COMMON_CLK_QCOM=y
 CONFIG_MSM_GCC_8916=y
+CONFIG_HWSPINLOCK_QCOM=y
 # CONFIG_IOMMU_SUPPORT is not set
+CONFIG_QCOM_SMEM=y
+CONFIG_QCOM_SMD=y
+CONFIG_QCOM_SMD_RPM=y
 CONFIG_PHY_XGENE=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
index cebf78661a553775003bfee8ec89f65e33e3ec55..253021ef2769078e69793288a8cc067aebb76d34 100644 (file)
@@ -201,7 +201,7 @@ void unregister_step_hook(struct step_hook *hook)
 }
 
 /*
- * Call registered single step handers
+ * Call registered single step handlers
  * There is no Syndrome info to check for determining the handler.
  * So we call all the registered handlers, until the right handler is
  * found which returns zero.
@@ -271,20 +271,21 @@ static int single_step_handler(unsigned long addr, unsigned int esr,
  * Use reader/writer locks instead of plain spinlock.
  */
 static LIST_HEAD(break_hook);
-static DEFINE_RWLOCK(break_hook_lock);
+static DEFINE_SPINLOCK(break_hook_lock);
 
 void register_break_hook(struct break_hook *hook)
 {
-       write_lock(&break_hook_lock);
-       list_add(&hook->node, &break_hook);
-       write_unlock(&break_hook_lock);
+       spin_lock(&break_hook_lock);
+       list_add_rcu(&hook->node, &break_hook);
+       spin_unlock(&break_hook_lock);
 }
 
 void unregister_break_hook(struct break_hook *hook)
 {
-       write_lock(&break_hook_lock);
-       list_del(&hook->node);
-       write_unlock(&break_hook_lock);
+       spin_lock(&break_hook_lock);
+       list_del_rcu(&hook->node);
+       spin_unlock(&break_hook_lock);
+       synchronize_rcu();
 }
 
 static int call_break_hook(struct pt_regs *regs, unsigned int esr)
@@ -292,11 +293,11 @@ static int call_break_hook(struct pt_regs *regs, unsigned int esr)
        struct break_hook *hook;
        int (*fn)(struct pt_regs *regs, unsigned int esr) = NULL;
 
-       read_lock(&break_hook_lock);
-       list_for_each_entry(hook, &break_hook, node)
+       rcu_read_lock();
+       list_for_each_entry_rcu(hook, &break_hook, node)
                if ((esr & hook->esr_mask) == hook->esr_val)
                        fn = hook->fn;
-       read_unlock(&break_hook_lock);
+       rcu_read_unlock();
 
        return fn ? fn(regs, esr) : DBG_HOOK_ERROR;
 }
index f341866aa810340e47aa9b7283b6b472ca2eae84..c08b9ad6f42931e8766d0186daa51a6cce8dbe39 100644 (file)
@@ -85,7 +85,7 @@ bool aarch64_insn_is_branch_imm(u32 insn)
                aarch64_insn_is_bcond(insn));
 }
 
-static DEFINE_SPINLOCK(patch_lock);
+static DEFINE_RAW_SPINLOCK(patch_lock);
 
 static void __kprobes *patch_map(void *addr, int fixmap)
 {
@@ -131,13 +131,13 @@ static int __kprobes __aarch64_insn_write(void *addr, u32 insn)
        unsigned long flags = 0;
        int ret;
 
-       spin_lock_irqsave(&patch_lock, flags);
+       raw_spin_lock_irqsave(&patch_lock, flags);
        waddr = patch_map(addr, FIX_TEXT_POKE0);
 
        ret = probe_kernel_write(waddr, &insn, AARCH64_INSN_SIZE);
 
        patch_unmap(FIX_TEXT_POKE0);
-       spin_unlock_irqrestore(&patch_lock, flags);
+       raw_spin_unlock_irqrestore(&patch_lock, flags);
 
        return ret;
 }
index aa94a88f6279963ae7ef0c6477215894859c9aff..f67f35b6edb12e4d34e1db17750b07a0bec72e39 100644 (file)
 #include <asm/smp_plat.h>
 #include <asm/suspend.h>
 
-static bool psci_power_state_loses_context(u32 state)
-{
-       return state & PSCI_0_2_POWER_STATE_TYPE_MASK;
-}
-
-static bool psci_power_state_is_valid(u32 state)
-{
-       const u32 valid_mask = PSCI_0_2_POWER_STATE_ID_MASK |
-                              PSCI_0_2_POWER_STATE_TYPE_MASK |
-                              PSCI_0_2_POWER_STATE_AFFL_MASK;
-
-       return !(state & ~valid_mask);
-}
-
 static DEFINE_PER_CPU_READ_MOSTLY(u32 *, psci_power_state);
 
 static int __maybe_unused cpu_psci_cpu_init_idle(unsigned int cpu)
index 6bab21f84a9ff38402e70345016ed50ae8e95e30..232247945b1c215c25fbfd708573fe3def5c68c5 100644 (file)
@@ -364,6 +364,8 @@ static void __init relocate_initrd(void)
                to_free = ram_end - orig_start;
 
        size = orig_end - orig_start;
+       if (!size)
+               return;
 
        /* initrd needs to be relocated completely inside linear mapping */
        new_start = memblock_find_in_range(0, PFN_PHYS(max_pfn),
index aba9ead1384c036a0d6a441c92ced63cfd7ed4ae..9fadf6d7039b721b072379b5af51abce726f5b92 100644 (file)
@@ -287,6 +287,7 @@ retry:
                         * starvation.
                         */
                        mm_flags &= ~FAULT_FLAG_ALLOW_RETRY;
+                       mm_flags |= FAULT_FLAG_TRIED;
                        goto retry;
                }
        }
index 70e6ae1e700673e3acbd03452d22f57db9c1166d..373cb23301e30248bfd62f2a08c6529f93db0382 100644 (file)
@@ -73,4 +73,5 @@ generic-y += uaccess.h
 generic-y += ucontext.h
 generic-y += unaligned.h
 generic-y += vga.h
+generic-y += word-at-a-time.h
 generic-y += xor.h
index 9e777cd42b67190a5dce5ac11553a3de05e4375e..d10fd80dbb7e96b898d2230c2d0f5112d02c3bc1 100644 (file)
@@ -256,6 +256,7 @@ static inline void __iomem * __ioremap_mode(phys_addr_t offset, unsigned long si
  */
 #define ioremap_nocache(offset, size)                                  \
        __ioremap_mode((offset), (size), _CACHE_UNCACHED)
+#define ioremap_uc ioremap_nocache
 
 /*
  * ioremap_cachable -  map bus memory into CPU space
index c4ddc4f0d2dcb11c7aa55167434d72e7990e083a..23cd9b118c9e4f8f8fd43031dd67dcee8e610af8 100644 (file)
 
 #define __SWAB_64_THRU_32__
 
-#if (defined(__mips_isa_rev) && (__mips_isa_rev >= 2)) ||              \
-    defined(_MIPS_ARCH_LOONGSON3A)
+#if !defined(__mips16) &&                                      \
+       ((defined(__mips_isa_rev) && (__mips_isa_rev >= 2)) ||  \
+        defined(_MIPS_ARCH_LOONGSON3A))
 
-static inline __attribute__((nomips16)) __attribute_const__
-               __u16 __arch_swab16(__u16 x)
+static inline __attribute_const__ __u16 __arch_swab16(__u16 x)
 {
        __asm__(
        "       .set    push                    \n"
        "       .set    arch=mips32r2           \n"
-       "       .set    nomips16                \n"
        "       wsbh    %0, %1                  \n"
        "       .set    pop                     \n"
        : "=r" (x)
@@ -32,13 +31,11 @@ static inline __attribute__((nomips16)) __attribute_const__
 }
 #define __arch_swab16 __arch_swab16
 
-static inline __attribute__((nomips16)) __attribute_const__
-               __u32 __arch_swab32(__u32 x)
+static inline __attribute_const__ __u32 __arch_swab32(__u32 x)
 {
        __asm__(
        "       .set    push                    \n"
        "       .set    arch=mips32r2           \n"
-       "       .set    nomips16                \n"
        "       wsbh    %0, %1                  \n"
        "       rotr    %0, %0, 16              \n"
        "       .set    pop                     \n"
@@ -54,13 +51,11 @@ static inline __attribute__((nomips16)) __attribute_const__
  * 64-bit kernel on r2 CPUs.
  */
 #ifdef __mips64
-static inline __attribute__((nomips16)) __attribute_const__
-               __u64 __arch_swab64(__u64 x)
+static inline __attribute_const__ __u64 __arch_swab64(__u64 x)
 {
        __asm__(
        "       .set    push                    \n"
        "       .set    arch=mips64r2           \n"
-       "       .set    nomips16                \n"
        "       dsbh    %0, %1                  \n"
        "       dshd    %0, %0                  \n"
        "       .set    pop                     \n"
@@ -71,5 +66,5 @@ static inline __attribute__((nomips16)) __attribute_const__
 }
 #define __arch_swab64 __arch_swab64
 #endif /* __mips64 */
-#endif /* MIPS R2 or newer or Loongson 3A */
+#endif /* (not __mips16) and (MIPS R2 or newer or Loongson 3A) */
 #endif /* _ASM_SWAB_H */
index ac1662956e0c4d4dfe8a0a7fff432e9f2a592f2c..ab9f4e0ed4cfcfd48a8d232fe20d0482739a22c5 100644 (file)
@@ -7,4 +7,3 @@ generic-y += mcs_spinlock.h
 generic-y += preempt.h
 generic-y += rwsem.h
 generic-y += vtime.h
-generic-y += word-at-a-time.h
index 5b3a903adae6d761effa550a802ed5d6a2aeb656..e4396a7d0f7cf5627a92ea8c07756aba6bc52c7a 100644 (file)
@@ -40,6 +40,11 @@ static inline bool has_zero(unsigned long val, unsigned long *data, const struct
        return (val + c->high_bits) & ~rhs;
 }
 
+static inline unsigned long zero_bytemask(unsigned long mask)
+{
+       return ~1ul << __fls(mask);
+}
+
 #else
 
 #ifdef CONFIG_64BIT
index d4788111c16171135422a0ef29e23e2eb866236d..fac6ac9790fad18efc2f587757068f87ca7765fd 100644 (file)
@@ -10,7 +10,7 @@ targets += misc.o piggy.o sizes.h head.o
 
 KBUILD_CFLAGS := -m64 -D__KERNEL__ $(LINUX_INCLUDE) -O2
 KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING
-KBUILD_CFLAGS += $(cflags-y) -fno-delete-null-pointer-checks
+KBUILD_CFLAGS += $(cflags-y) -fno-delete-null-pointer-checks -msoft-float
 KBUILD_CFLAGS += $(call cc-option,-mpacked-stack)
 KBUILD_CFLAGS += $(call cc-option,-ffreestanding)
 
index 0c98f1508542c9f900ee2bed1394413b8d5d8d88..ed7da281df66743f0badff631c9183bf318ec9b7 100644 (file)
@@ -381,7 +381,7 @@ CONFIG_ISCSI_TCP=m
 CONFIG_SCSI_DEBUG=m
 CONFIG_ZFCP=y
 CONFIG_SCSI_VIRTIO=m
-CONFIG_SCSI_DH=m
+CONFIG_SCSI_DH=y
 CONFIG_SCSI_DH_RDAC=m
 CONFIG_SCSI_DH_HP_SW=m
 CONFIG_SCSI_DH_EMC=m
index 82083e1fbdc4c6cc9f4ad6a2c0cfbfbcd3af1210..9858b14cde1edccdcda3a217446f547641d98944 100644 (file)
@@ -377,7 +377,7 @@ CONFIG_ISCSI_TCP=m
 CONFIG_SCSI_DEBUG=m
 CONFIG_ZFCP=y
 CONFIG_SCSI_VIRTIO=m
-CONFIG_SCSI_DH=m
+CONFIG_SCSI_DH=y
 CONFIG_SCSI_DH_RDAC=m
 CONFIG_SCSI_DH_HP_SW=m
 CONFIG_SCSI_DH_EMC=m
index c05c9e0821e3bcd956b929c591e41b5445ac9565..7f14f80717d4975161a696dd2e803d4ee87011d6 100644 (file)
@@ -377,7 +377,7 @@ CONFIG_ISCSI_TCP=m
 CONFIG_SCSI_DEBUG=m
 CONFIG_ZFCP=y
 CONFIG_SCSI_VIRTIO=m
-CONFIG_SCSI_DH=m
+CONFIG_SCSI_DH=y
 CONFIG_SCSI_DH_RDAC=m
 CONFIG_SCSI_DH_HP_SW=m
 CONFIG_SCSI_DH_EMC=m
index 2a0efc63b9e5afb29cb2e6edd109dd9848353b27..dc19ee0c92aaa693d2ad3b8c4c614b3e0e427de7 100644 (file)
@@ -19,7 +19,7 @@ int numa_pfn_to_nid(unsigned long pfn);
 int __node_distance(int a, int b);
 void numa_update_cpu_topology(void);
 
-extern cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
+extern cpumask_t node_to_cpumask_map[MAX_NUMNODES];
 extern int numa_debug_enabled;
 
 #else
index 27ebde643933a908c1ebb2a75ff723d8d43a65f6..94fc55fc72ce88a18eb73d3f43d5a7895ac6cd9c 100644 (file)
@@ -68,7 +68,7 @@ static inline int cpu_to_node(int cpu)
 #define cpumask_of_node cpumask_of_node
 static inline const struct cpumask *cpumask_of_node(int node)
 {
-       return node_to_cpumask_map[node];
+       return &node_to_cpumask_map[node];
 }
 
 /*
index 48c9af7a76831ea63ef6ef92760df02f15c1188c..3aeeb1b562c00ff9c7afe559452fdc2c06457116 100644 (file)
@@ -176,6 +176,7 @@ int main(void)
        DEFINE(__LC_PASTE, offsetof(struct _lowcore, paste));
        DEFINE(__LC_FP_CREG_SAVE_AREA, offsetof(struct _lowcore, fpt_creg_save_area));
        DEFINE(__LC_LAST_BREAK, offsetof(struct _lowcore, breaking_event_addr));
+       DEFINE(__LC_PERCPU_OFFSET, offsetof(struct _lowcore, percpu_offset));
        DEFINE(__LC_VDSO_PER_CPU, offsetof(struct _lowcore, vdso_per_cpu_data));
        DEFINE(__LC_GMAP, offsetof(struct _lowcore, gmap));
        DEFINE(__LC_PGM_TDB, offsetof(struct _lowcore, pgm_tdb));
index 09b039d7983d802f2674504439e43e21c03d4cae..582fe44ab07cc69aaef1d4f782f6f89364914974 100644 (file)
@@ -733,6 +733,14 @@ ENTRY(psw_idle)
        stg     %r3,__SF_EMPTY(%r15)
        larl    %r1,.Lpsw_idle_lpsw+4
        stg     %r1,__SF_EMPTY+8(%r15)
+#ifdef CONFIG_SMP
+       larl    %r1,smp_cpu_mtid
+       llgf    %r1,0(%r1)
+       ltgr    %r1,%r1
+       jz      .Lpsw_idle_stcctm
+       .insn   rsy,0xeb0000000017,%r1,5,__SF_EMPTY+16(%r15)
+.Lpsw_idle_stcctm:
+#endif
        STCK    __CLOCK_IDLE_ENTER(%r2)
        stpt    __TIMER_IDLE_ENTER(%r2)
 .Lpsw_idle_lpsw:
@@ -1159,7 +1167,27 @@ cleanup_critical:
        jhe     1f
        mvc     __CLOCK_IDLE_ENTER(8,%r2),__CLOCK_IDLE_EXIT(%r2)
        mvc     __TIMER_IDLE_ENTER(8,%r2),__TIMER_IDLE_EXIT(%r2)
-1:     # account system time going idle
+1:     # calculate idle cycles
+#ifdef CONFIG_SMP
+       clg     %r9,BASED(.Lcleanup_idle_insn)
+       jl      3f
+       larl    %r1,smp_cpu_mtid
+       llgf    %r1,0(%r1)
+       ltgr    %r1,%r1
+       jz      3f
+       .insn   rsy,0xeb0000000017,%r1,5,__SF_EMPTY+80(%r15)
+       larl    %r3,mt_cycles
+       ag      %r3,__LC_PERCPU_OFFSET
+       la      %r4,__SF_EMPTY+16(%r15)
+2:     lg      %r0,0(%r3)
+       slg     %r0,0(%r4)
+       alg     %r0,64(%r4)
+       stg     %r0,0(%r3)
+       la      %r3,8(%r3)
+       la      %r4,8(%r4)
+       brct    %r1,2b
+#endif
+3:     # account system time going idle
        lg      %r9,__LC_STEAL_TIMER
        alg     %r9,__CLOCK_IDLE_ENTER(%r2)
        slg     %r9,__LC_LAST_UPDATE_CLOCK
index c8653435c70d9d203dbe05deed3c96d0aad6cdd9..dafc44f519c340329581c8a5b2fda6fdb6920252 100644 (file)
@@ -25,7 +25,7 @@ static DEFINE_SPINLOCK(virt_timer_lock);
 static atomic64_t virt_timer_current;
 static atomic64_t virt_timer_elapsed;
 
-static DEFINE_PER_CPU(u64, mt_cycles[32]);
+DEFINE_PER_CPU(u64, mt_cycles[8]);
 static DEFINE_PER_CPU(u64, mt_scaling_mult) = { 1 };
 static DEFINE_PER_CPU(u64, mt_scaling_div) = { 1 };
 static DEFINE_PER_CPU(u64, mt_scaling_jiffies);
@@ -60,6 +60,34 @@ static inline int virt_timer_forward(u64 elapsed)
        return elapsed >= atomic64_read(&virt_timer_current);
 }
 
+static void update_mt_scaling(void)
+{
+       u64 cycles_new[8], *cycles_old;
+       u64 delta, fac, mult, div;
+       int i;
+
+       stcctm5(smp_cpu_mtid + 1, cycles_new);
+       cycles_old = this_cpu_ptr(mt_cycles);
+       fac = 1;
+       mult = div = 0;
+       for (i = 0; i <= smp_cpu_mtid; i++) {
+               delta = cycles_new[i] - cycles_old[i];
+               div += delta;
+               mult *= i + 1;
+               mult += delta * fac;
+               fac *= i + 1;
+       }
+       div *= fac;
+       if (div > 0) {
+               /* Update scaling factor */
+               __this_cpu_write(mt_scaling_mult, mult);
+               __this_cpu_write(mt_scaling_div, div);
+               memcpy(cycles_old, cycles_new,
+                      sizeof(u64) * (smp_cpu_mtid + 1));
+       }
+       __this_cpu_write(mt_scaling_jiffies, jiffies_64);
+}
+
 /*
  * Update process times based on virtual cpu times stored by entry.S
  * to the lowcore fields user_timer, system_timer & steal_clock.
@@ -69,7 +97,6 @@ static int do_account_vtime(struct task_struct *tsk, int hardirq_offset)
        struct thread_info *ti = task_thread_info(tsk);
        u64 timer, clock, user, system, steal;
        u64 user_scaled, system_scaled;
-       int i;
 
        timer = S390_lowcore.last_update_timer;
        clock = S390_lowcore.last_update_clock;
@@ -85,34 +112,10 @@ static int do_account_vtime(struct task_struct *tsk, int hardirq_offset)
        S390_lowcore.system_timer += timer - S390_lowcore.last_update_timer;
        S390_lowcore.steal_timer += S390_lowcore.last_update_clock - clock;
 
-       /* Do MT utilization calculation */
+       /* Update MT utilization calculation */
        if (smp_cpu_mtid &&
-           time_after64(jiffies_64, __this_cpu_read(mt_scaling_jiffies))) {
-               u64 cycles_new[32], *cycles_old;
-               u64 delta, fac, mult, div;
-
-               cycles_old = this_cpu_ptr(mt_cycles);
-               if (stcctm5(smp_cpu_mtid + 1, cycles_new) < 2) {
-                       fac = 1;
-                       mult = div = 0;
-                       for (i = 0; i <= smp_cpu_mtid; i++) {
-                               delta = cycles_new[i] - cycles_old[i];
-                               div += delta;
-                               mult *= i + 1;
-                               mult += delta * fac;
-                               fac *= i + 1;
-                       }
-                       div *= fac;
-                       if (div > 0) {
-                               /* Update scaling factor */
-                               __this_cpu_write(mt_scaling_mult, mult);
-                               __this_cpu_write(mt_scaling_div, div);
-                               memcpy(cycles_old, cycles_new,
-                                      sizeof(u64) * (smp_cpu_mtid + 1));
-                       }
-               }
-               __this_cpu_write(mt_scaling_jiffies, jiffies_64);
-       }
+           time_after64(jiffies_64, this_cpu_read(mt_scaling_jiffies)))
+               update_mt_scaling();
 
        user = S390_lowcore.user_timer - ti->user_timer;
        S390_lowcore.steal_timer -= user;
@@ -181,6 +184,11 @@ void vtime_account_irq_enter(struct task_struct *tsk)
        S390_lowcore.last_update_timer = get_vtimer();
        S390_lowcore.system_timer += timer - S390_lowcore.last_update_timer;
 
+       /* Update MT utilization calculation */
+       if (smp_cpu_mtid &&
+           time_after64(jiffies_64, this_cpu_read(mt_scaling_jiffies)))
+               update_mt_scaling();
+
        system = S390_lowcore.system_timer - ti->system_timer;
        S390_lowcore.steal_timer -= system;
        ti->system_timer = S390_lowcore.system_timer;
index 7de4e2f780d789478d4d700821944f96b3846586..30b2698a28e29a6991a7116da1877e5bdee1963e 100644 (file)
@@ -368,7 +368,7 @@ static void topology_add_core(struct toptree *core)
                cpumask_copy(&top->thread_mask, &core->mask);
                cpumask_copy(&top->core_mask, &core_mc(core)->mask);
                cpumask_copy(&top->book_mask, &core_book(core)->mask);
-               cpumask_set_cpu(cpu, node_to_cpumask_map[core_node(core)->id]);
+               cpumask_set_cpu(cpu, &node_to_cpumask_map[core_node(core)->id]);
                top->node_id = core_node(core)->id;
        }
 }
@@ -383,7 +383,7 @@ static void toptree_to_topology(struct toptree *numa)
 
        /* Clear all node masks */
        for (i = 0; i < MAX_NUMNODES; i++)
-               cpumask_clear(node_to_cpumask_map[i]);
+               cpumask_clear(&node_to_cpumask_map[i]);
 
        /* Rebuild all masks */
        toptree_for_each(core, numa, CORE)
index 09b1d2355bd9849ab583bb52c33eb789b4f9804b..43f32ce60aa3d98af0b7665090fa3eb080d12fa7 100644 (file)
@@ -23,7 +23,7 @@
 pg_data_t *node_data[MAX_NUMNODES];
 EXPORT_SYMBOL(node_data);
 
-cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
+cpumask_t node_to_cpumask_map[MAX_NUMNODES];
 EXPORT_SYMBOL(node_to_cpumask_map);
 
 const struct numa_mode numa_mode_plain = {
@@ -144,7 +144,7 @@ void __init numa_setup(void)
 static int __init numa_init_early(void)
 {
        /* Attach all possible CPUs to node 0 for now. */
-       cpumask_copy(node_to_cpumask_map[0], cpu_possible_mask);
+       cpumask_copy(&node_to_cpumask_map[0], cpu_possible_mask);
        return 0;
 }
 early_initcall(numa_init_early);
index 0b6cacaad9333a4165bfd9447a180feadedb4db4..ba35c41c71fff33b2b2fe95f566ad8b3dc192c32 100644 (file)
@@ -40,5 +40,4 @@ generic-y += termbits.h
 generic-y += termios.h
 generic-y += trace_clock.h
 generic-y += types.h
-generic-y += word-at-a-time.h
 generic-y += xor.h
index 9e5ce0d7b292160d5f544fcda08c00ea6c04f168..b66a693c2c3453e4f4642fea133890ab268a32d8 100644 (file)
@@ -6,7 +6,7 @@
 struct word_at_a_time { /* unused */ };
 #define WORD_AT_A_TIME_CONSTANTS {}
 
-/* Generate 0x01 byte values for non-zero bytes using a SIMD instruction. */
+/* Generate 0x01 byte values for zero bytes using a SIMD instruction. */
 static inline unsigned long has_zero(unsigned long val, unsigned long *data,
                                     const struct word_at_a_time *c)
 {
@@ -33,4 +33,10 @@ static inline long find_zero(unsigned long mask)
 #endif
 }
 
+#ifdef __BIG_ENDIAN
+#define zero_bytemask(mask) (~1ul << (63 - __builtin_clzl(mask)))
+#else
+#define zero_bytemask(mask) ((2ul << __builtin_ctzl(mask)) - 1)
+#endif
+
 #endif /* _ASM_WORD_AT_A_TIME_H */
index 328c8352480c5dcfd34d72a70d01d6a57e5bb515..96d058a871007e7b119bd3a6d3ff14eb9a5a61eb 100644 (file)
@@ -1308,6 +1308,7 @@ config HIGHMEM
 config X86_PAE
        bool "PAE (Physical Address Extension) Support"
        depends on X86_32 && !HIGHMEM4G
+       select SWIOTLB
        ---help---
          PAE is required for NX support, and furthermore enables
          larger swapspace support for non-overcommit purposes. It
index 83aea8055119e2f26beb1c909536609d30e88943..4c20dd333412db5b367d0625e9b7cf69a7891493 100644 (file)
@@ -336,10 +336,10 @@ HYPERVISOR_update_descriptor(u64 ma, u64 desc)
        return _hypercall4(int, update_descriptor, ma, ma>>32, desc, desc>>32);
 }
 
-static inline int
+static inline long
 HYPERVISOR_memory_op(unsigned int cmd, void *arg)
 {
-       return _hypercall2(int, memory_op, cmd, arg);
+       return _hypercall2(long, memory_op, cmd, arg);
 }
 
 static inline int
index 30d12afe52ed173b2a81720cd5c89c24e667de2a..993b7a71386d53f79befa7a302ede2fdcbed6bd4 100644 (file)
 #include <linux/memblock.h>
 #include <linux/edd.h>
 
+#ifdef CONFIG_KEXEC_CORE
+#include <linux/kexec.h>
+#endif
+
 #include <xen/xen.h>
 #include <xen/events.h>
 #include <xen/interface/xen.h>
@@ -1077,6 +1081,7 @@ static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high)
                /* Fast syscall setup is all done in hypercalls, so
                   these are all ignored.  Stub them out here to stop
                   Xen console noise. */
+               break;
 
        default:
                if (!pmu_msr_write(msr, low, high, &ret))
@@ -1807,6 +1812,21 @@ static struct notifier_block xen_hvm_cpu_notifier = {
        .notifier_call  = xen_hvm_cpu_notify,
 };
 
+#ifdef CONFIG_KEXEC_CORE
+static void xen_hvm_shutdown(void)
+{
+       native_machine_shutdown();
+       if (kexec_in_progress)
+               xen_reboot(SHUTDOWN_soft_reset);
+}
+
+static void xen_hvm_crash_shutdown(struct pt_regs *regs)
+{
+       native_machine_crash_shutdown(regs);
+       xen_reboot(SHUTDOWN_soft_reset);
+}
+#endif
+
 static void __init xen_hvm_guest_init(void)
 {
        if (xen_pv_domain())
@@ -1826,6 +1846,10 @@ static void __init xen_hvm_guest_init(void)
        x86_init.irqs.intr_init = xen_init_IRQ;
        xen_hvm_init_time_ops();
        xen_hvm_init_mmu_ops();
+#ifdef CONFIG_KEXEC_CORE
+       machine_ops.shutdown = xen_hvm_shutdown;
+       machine_ops.crash_shutdown = xen_hvm_crash_shutdown;
+#endif
 }
 #endif
 
index bfc08b13044b181c5948e5a2f22c205e900e0b47..660b3cfef23485f149e1a9b0b88f0b12666dbefb 100644 (file)
@@ -112,6 +112,15 @@ static unsigned long *p2m_identity;
 static pte_t *p2m_missing_pte;
 static pte_t *p2m_identity_pte;
 
+/*
+ * Hint at last populated PFN.
+ *
+ * Used to set HYPERVISOR_shared_info->arch.max_pfn so the toolstack
+ * can avoid scanning the whole P2M (which may be sized to account for
+ * hotplugged memory).
+ */
+static unsigned long xen_p2m_last_pfn;
+
 static inline unsigned p2m_top_index(unsigned long pfn)
 {
        BUG_ON(pfn >= MAX_P2M_PFN);
@@ -270,7 +279,7 @@ void xen_setup_mfn_list_list(void)
        else
                HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
                        virt_to_mfn(p2m_top_mfn);
-       HYPERVISOR_shared_info->arch.max_pfn = xen_max_p2m_pfn;
+       HYPERVISOR_shared_info->arch.max_pfn = xen_p2m_last_pfn;
        HYPERVISOR_shared_info->arch.p2m_generation = 0;
        HYPERVISOR_shared_info->arch.p2m_vaddr = (unsigned long)xen_p2m_addr;
        HYPERVISOR_shared_info->arch.p2m_cr3 =
@@ -406,6 +415,8 @@ void __init xen_vmalloc_p2m_tree(void)
        static struct vm_struct vm;
        unsigned long p2m_limit;
 
+       xen_p2m_last_pfn = xen_max_p2m_pfn;
+
        p2m_limit = (phys_addr_t)P2M_LIMIT * 1024 * 1024 * 1024 / PAGE_SIZE;
        vm.flags = VM_ALLOC;
        vm.size = ALIGN(sizeof(unsigned long) * max(xen_max_p2m_pfn, p2m_limit),
@@ -608,6 +619,12 @@ static bool alloc_p2m(unsigned long pfn)
                        free_p2m_page(p2m);
        }
 
+       /* Expanded the p2m? */
+       if (pfn > xen_p2m_last_pfn) {
+               xen_p2m_last_pfn = pfn;
+               HYPERVISOR_shared_info->arch.max_pfn = xen_p2m_last_pfn;
+       }
+
        return true;
 }
 
index f5ef6746d47a0ee36f6b0a11edd0c49cbcf3590a..1c30e4ab1022bda71ff80d841509605ae07034cc 100644 (file)
@@ -548,7 +548,7 @@ static unsigned long __init xen_get_max_pages(void)
 {
        unsigned long max_pages, limit;
        domid_t domid = DOMID_SELF;
-       int ret;
+       long ret;
 
        limit = xen_get_pages_limit();
        max_pages = limit;
@@ -798,7 +798,7 @@ char * __init xen_memory_setup(void)
                xen_ignore_unusable();
 
        /* Make sure the Xen-supplied memory map is well-ordered. */
-       sanitize_e820_map(xen_e820_map, xen_e820_map_entries,
+       sanitize_e820_map(xen_e820_map, ARRAY_SIZE(xen_e820_map),
                          &xen_e820_map_entries);
 
        max_pages = xen_get_max_pages();
index 652b5a367c1f37fd91ee68f9da06c0a50e956224..6ce76934057fcc15831a85400754c551294b35d9 100644 (file)
@@ -93,7 +93,7 @@ static int __pm_clk_add(struct device *dev, const char *con_id,
                        return -ENOMEM;
                }
        } else {
-               if (IS_ERR(clk) || !__clk_get(clk)) {
+               if (IS_ERR(clk)) {
                        kfree(ce);
                        return -ENOENT;
                }
@@ -127,7 +127,9 @@ int pm_clk_add(struct device *dev, const char *con_id)
  * @clk: Clock pointer
  *
  * Add the clock to the list of clocks used for the power management of @dev.
- * It will increment refcount on clock pointer, use clk_put() on it when done.
+ * The power-management code will take control of the clock reference, so
+ * callers should not call clk_put() on @clk after this function sucessfully
+ * returned.
  */
 int pm_clk_add_clk(struct device *dev, struct clk *clk)
 {
index f42f2bac646623fc1db767bae3a5fff0ecf98aac..4c55cfbad19e95df8cb67864d78af960c073b4df 100644 (file)
@@ -32,8 +32,7 @@ static DEFINE_MUTEX(regmap_debugfs_early_lock);
 /* Calculate the length of a fixed format  */
 static size_t regmap_calc_reg_len(int max_val, char *buf, size_t buf_size)
 {
-       snprintf(buf, buf_size, "%x", max_val);
-       return strlen(buf);
+       return snprintf(NULL, 0, "%x", max_val);
 }
 
 static ssize_t regmap_name_read_file(struct file *file,
@@ -432,7 +431,7 @@ static ssize_t regmap_access_read_file(struct file *file,
                /* If we're in the region the user is trying to read */
                if (p >= *ppos) {
                        /* ...but not beyond it */
-                       if (buf_pos >= count - 1 - tot_len)
+                       if (buf_pos + tot_len + 1 >= count)
                                break;
 
                        /* Format the register */
index 1a82f3a17681b77926a11c29ba23cbdc27d8b6b5..116b363b79872ddbb724a6b8a6ee042d960ba9b5 100644 (file)
@@ -36,7 +36,6 @@ config ARM_CCI400_PORT_CTRL
 
 config ARM_CCI500_PMU
        bool "ARM CCI500 PMU support"
-       default y
        depends on (ARM && CPU_V7) || ARM64
        depends on PERF_EVENTS
        select ARM_CCI_PMU
@@ -121,6 +120,17 @@ config SIMPLE_PM_BUS
          Controller (BSC, sometimes called "LBSC within Bus Bridge", or
          "External Bus Interface") as found on several Renesas ARM SoCs.
 
+config SUNXI_RSB
+       tristate "Allwinner sunXi Reduced Serial Bus Driver"
+         default MACH_SUN8I || MACH_SUN9I
+         depends on ARCH_SUNXI
+         select REGMAP
+         help
+         Say y here to enable support for Allwinner's Reduced Serial Bus
+         (RSB) support. This controller is responsible for communicating
+         with various RSB based devices, such as AXP223, AXP8XX PMICs,
+         and AC100/AC200 ICs.
+
 config VEXPRESS_CONFIG
        bool "Versatile Express configuration bus"
        default y if ARCH_VEXPRESS
index 790e7b933fb2f9b2a266d43ecfec16620605fe2f..fcb9f9794a1f575979e466d5a7b72f68dac8057a 100644 (file)
@@ -15,5 +15,6 @@ obj-$(CONFIG_MVEBU_MBUS)      += mvebu-mbus.o
 obj-$(CONFIG_OMAP_INTERCONNECT)        += omap_l3_smx.o omap_l3_noc.o
 
 obj-$(CONFIG_OMAP_OCP2SCP)     += omap-ocp2scp.o
+obj-$(CONFIG_SUNXI_RSB)                += sunxi-rsb.o
 obj-$(CONFIG_SIMPLE_PM_BUS)    += simple-pm-bus.o
 obj-$(CONFIG_VEXPRESS_CONFIG)  += vexpress-config.o
index 7d9879e166cf4c4346402cb353ef3cd002483740..7082c7268845639399d9ceab44471937011e1705 100644 (file)
@@ -1184,11 +1184,12 @@ static int arm_ccn_pmu_cpu_notifier(struct notifier_block *nb,
                if (!cpumask_test_and_clear_cpu(cpu, &dt->cpu))
                        break;
                target = cpumask_any_but(cpu_online_mask, cpu);
-               if (target < 0)
+               if (target >= nr_cpu_ids)
                        break;
                perf_pmu_migrate_context(&dt->pmu, cpu, target);
                cpumask_set_cpu(target, &dt->cpu);
-               WARN_ON(irq_set_affinity(ccn->irq, &dt->cpu) != 0);
+               if (ccn->irq)
+                       WARN_ON(irq_set_affinity(ccn->irq, &dt->cpu) != 0);
        default:
                break;
        }
diff --git a/drivers/bus/sunxi-rsb.c b/drivers/bus/sunxi-rsb.c
new file mode 100644 (file)
index 0000000..846bc29
--- /dev/null
@@ -0,0 +1,783 @@
+/*
+ * RSB (Reduced Serial Bus) driver.
+ *
+ * Author: Chen-Yu Tsai <wens@csie.org>
+ *
+ * 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.
+ *
+ * The RSB controller looks like an SMBus controller which only supports
+ * byte and word data transfers. But, it differs from standard SMBus
+ * protocol on several aspects:
+ * - it uses addresses set at runtime to address slaves. Runtime addresses
+ *   are sent to slaves using their 12bit hardware addresses. Up to 15
+ *   runtime addresses are available.
+ * - it adds a parity bit every 8bits of data and address for read and
+ *   write accesses; this replaces the ack bit
+ * - only one read access is required to read a byte (instead of a write
+ *   followed by a read access in standard SMBus protocol)
+ * - there's no Ack bit after each read access
+ *
+ * This means this bus cannot be used to interface with standard SMBus
+ * devices. Devices known to support this interface include the AXP223,
+ * AXP809, and AXP806 PMICs, and the AC100 audio codec, all from X-Powers.
+ *
+ * A description of the operation and wire protocol can be found in the
+ * RSB section of Allwinner's A80 user manual, which can be found at
+ *
+ *     https://github.com/allwinner-zh/documents/tree/master/A80
+ *
+ * This document is officially released by Allwinner.
+ *
+ * This driver is based on i2c-sun6i-p2wi.c, the P2WI bus driver.
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/clk/clk-conf.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <linux/slab.h>
+#include <linux/sunxi-rsb.h>
+#include <linux/types.h>
+
+/* RSB registers */
+#define RSB_CTRL       0x0     /* Global control */
+#define RSB_CCR                0x4     /* Clock control */
+#define RSB_INTE       0x8     /* Interrupt controls */
+#define RSB_INTS       0xc     /* Interrupt status */
+#define RSB_ADDR       0x10    /* Address to send with read/write command */
+#define RSB_DATA       0x1c    /* Data to read/write */
+#define RSB_LCR                0x24    /* Line control */
+#define RSB_DMCR       0x28    /* Device mode (init) control */
+#define RSB_CMD                0x2c    /* RSB Command */
+#define RSB_DAR                0x30    /* Device address / runtime address */
+
+/* CTRL fields */
+#define RSB_CTRL_START_TRANS           BIT(7)
+#define RSB_CTRL_ABORT_TRANS           BIT(6)
+#define RSB_CTRL_GLOBAL_INT_ENB                BIT(1)
+#define RSB_CTRL_SOFT_RST              BIT(0)
+
+/* CLK CTRL fields */
+#define RSB_CCR_SDA_OUT_DELAY(v)       (((v) & 0x7) << 8)
+#define RSB_CCR_MAX_CLK_DIV            0xff
+#define RSB_CCR_CLK_DIV(v)             ((v) & RSB_CCR_MAX_CLK_DIV)
+
+/* STATUS fields */
+#define RSB_INTS_TRANS_ERR_ACK         BIT(16)
+#define RSB_INTS_TRANS_ERR_DATA_BIT(v) (((v) >> 8) & 0xf)
+#define RSB_INTS_TRANS_ERR_DATA                GENMASK(11, 8)
+#define RSB_INTS_LOAD_BSY              BIT(2)
+#define RSB_INTS_TRANS_ERR             BIT(1)
+#define RSB_INTS_TRANS_OVER            BIT(0)
+
+/* LINE CTRL fields*/
+#define RSB_LCR_SCL_STATE              BIT(5)
+#define RSB_LCR_SDA_STATE              BIT(4)
+#define RSB_LCR_SCL_CTL                        BIT(3)
+#define RSB_LCR_SCL_CTL_EN             BIT(2)
+#define RSB_LCR_SDA_CTL                        BIT(1)
+#define RSB_LCR_SDA_CTL_EN             BIT(0)
+
+/* DEVICE MODE CTRL field values */
+#define RSB_DMCR_DEVICE_START          BIT(31)
+#define RSB_DMCR_MODE_DATA             (0x7c << 16)
+#define RSB_DMCR_MODE_REG              (0x3e << 8)
+#define RSB_DMCR_DEV_ADDR              0x00
+
+/* CMD values */
+#define RSB_CMD_RD8                    0x8b
+#define RSB_CMD_RD16                   0x9c
+#define RSB_CMD_RD32                   0xa6
+#define RSB_CMD_WR8                    0x4e
+#define RSB_CMD_WR16                   0x59
+#define RSB_CMD_WR32                   0x63
+#define RSB_CMD_STRA                   0xe8
+
+/* DAR fields */
+#define RSB_DAR_RTA(v)                 (((v) & 0xff) << 16)
+#define RSB_DAR_DA(v)                  ((v) & 0xffff)
+
+#define RSB_MAX_FREQ                   20000000
+
+#define RSB_CTRL_NAME                  "sunxi-rsb"
+
+struct sunxi_rsb_addr_map {
+       u16 hwaddr;
+       u8 rtaddr;
+};
+
+struct sunxi_rsb {
+       struct device *dev;
+       void __iomem *regs;
+       struct clk *clk;
+       struct reset_control *rstc;
+       struct completion complete;
+       struct mutex lock;
+       unsigned int status;
+};
+
+/* bus / slave device related functions */
+static struct bus_type sunxi_rsb_bus;
+
+static int sunxi_rsb_device_match(struct device *dev, struct device_driver *drv)
+{
+       return of_driver_match_device(dev, drv);
+}
+
+static int sunxi_rsb_device_probe(struct device *dev)
+{
+       const struct sunxi_rsb_driver *drv = to_sunxi_rsb_driver(dev->driver);
+       struct sunxi_rsb_device *rdev = to_sunxi_rsb_device(dev);
+       int ret;
+
+       if (!drv->probe)
+               return -ENODEV;
+
+       if (!rdev->irq) {
+               int irq = -ENOENT;
+
+               if (dev->of_node)
+                       irq = of_irq_get(dev->of_node, 0);
+
+               if (irq == -EPROBE_DEFER)
+                       return irq;
+               if (irq < 0)
+                       irq = 0;
+
+               rdev->irq = irq;
+       }
+
+       ret = of_clk_set_defaults(dev->of_node, false);
+       if (ret < 0)
+               return ret;
+
+       return drv->probe(rdev);
+}
+
+static int sunxi_rsb_device_remove(struct device *dev)
+{
+       const struct sunxi_rsb_driver *drv = to_sunxi_rsb_driver(dev->driver);
+
+       return drv->remove(to_sunxi_rsb_device(dev));
+}
+
+static struct bus_type sunxi_rsb_bus = {
+       .name           = RSB_CTRL_NAME,
+       .match          = sunxi_rsb_device_match,
+       .probe          = sunxi_rsb_device_probe,
+       .remove         = sunxi_rsb_device_remove,
+};
+
+static void sunxi_rsb_dev_release(struct device *dev)
+{
+       struct sunxi_rsb_device *rdev = to_sunxi_rsb_device(dev);
+
+       kfree(rdev);
+}
+
+/**
+ * sunxi_rsb_device_create() - allocate and add an RSB device
+ * @rsb:       RSB controller
+ * @node:      RSB slave device node
+ * @hwaddr:    RSB slave hardware address
+ * @rtaddr:    RSB slave runtime address
+ */
+static struct sunxi_rsb_device *sunxi_rsb_device_create(struct sunxi_rsb *rsb,
+               struct device_node *node, u16 hwaddr, u8 rtaddr)
+{
+       int err;
+       struct sunxi_rsb_device *rdev;
+
+       rdev = kzalloc(sizeof(*rdev), GFP_KERNEL);
+       if (!rdev)
+               return ERR_PTR(-ENOMEM);
+
+       rdev->rsb = rsb;
+       rdev->hwaddr = hwaddr;
+       rdev->rtaddr = rtaddr;
+       rdev->dev.bus = &sunxi_rsb_bus;
+       rdev->dev.parent = rsb->dev;
+       rdev->dev.of_node = node;
+       rdev->dev.release = sunxi_rsb_dev_release;
+
+       dev_set_name(&rdev->dev, "%s-%x", RSB_CTRL_NAME, hwaddr);
+
+       err = device_register(&rdev->dev);
+       if (err < 0) {
+               dev_err(&rdev->dev, "Can't add %s, status %d\n",
+                       dev_name(&rdev->dev), err);
+               goto err_device_add;
+       }
+
+       dev_dbg(&rdev->dev, "device %s registered\n", dev_name(&rdev->dev));
+
+err_device_add:
+       put_device(&rdev->dev);
+
+       return ERR_PTR(err);
+}
+
+/**
+ * sunxi_rsb_device_unregister(): unregister an RSB device
+ * @rdev:      rsb_device to be removed
+ */
+static void sunxi_rsb_device_unregister(struct sunxi_rsb_device *rdev)
+{
+       device_unregister(&rdev->dev);
+}
+
+static int sunxi_rsb_remove_devices(struct device *dev, void *data)
+{
+       struct sunxi_rsb_device *rdev = to_sunxi_rsb_device(dev);
+
+       if (dev->bus == &sunxi_rsb_bus)
+               sunxi_rsb_device_unregister(rdev);
+
+       return 0;
+}
+
+/**
+ * sunxi_rsb_driver_register() - Register device driver with RSB core
+ * @rdrv:      device driver to be associated with slave-device.
+ *
+ * This API will register the client driver with the RSB framework.
+ * It is typically called from the driver's module-init function.
+ */
+int sunxi_rsb_driver_register(struct sunxi_rsb_driver *rdrv)
+{
+       rdrv->driver.bus = &sunxi_rsb_bus;
+       return driver_register(&rdrv->driver);
+}
+EXPORT_SYMBOL_GPL(sunxi_rsb_driver_register);
+
+/* common code that starts a transfer */
+static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb)
+{
+       if (readl(rsb->regs + RSB_CTRL) & RSB_CTRL_START_TRANS) {
+               dev_dbg(rsb->dev, "RSB transfer still in progress\n");
+               return -EBUSY;
+       }
+
+       reinit_completion(&rsb->complete);
+
+       writel(RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | RSB_INTS_TRANS_OVER,
+              rsb->regs + RSB_INTE);
+       writel(RSB_CTRL_START_TRANS | RSB_CTRL_GLOBAL_INT_ENB,
+              rsb->regs + RSB_CTRL);
+
+       if (!wait_for_completion_io_timeout(&rsb->complete,
+                                           msecs_to_jiffies(100))) {
+               dev_dbg(rsb->dev, "RSB timeout\n");
+
+               /* abort the transfer */
+               writel(RSB_CTRL_ABORT_TRANS, rsb->regs + RSB_CTRL);
+
+               /* clear any interrupt flags */
+               writel(readl(rsb->regs + RSB_INTS), rsb->regs + RSB_INTS);
+
+               return -ETIMEDOUT;
+       }
+
+       if (rsb->status & RSB_INTS_LOAD_BSY) {
+               dev_dbg(rsb->dev, "RSB busy\n");
+               return -EBUSY;
+       }
+
+       if (rsb->status & RSB_INTS_TRANS_ERR) {
+               if (rsb->status & RSB_INTS_TRANS_ERR_ACK) {
+                       dev_dbg(rsb->dev, "RSB slave nack\n");
+                       return -EINVAL;
+               }
+
+               if (rsb->status & RSB_INTS_TRANS_ERR_DATA) {
+                       dev_dbg(rsb->dev, "RSB transfer data error\n");
+                       return -EIO;
+               }
+       }
+
+       return 0;
+}
+
+static int sunxi_rsb_read(struct sunxi_rsb *rsb, u8 rtaddr, u8 addr,
+                         u32 *buf, size_t len)
+{
+       u32 cmd;
+       int ret;
+
+       if (!buf)
+               return -EINVAL;
+
+       switch (len) {
+       case 1:
+               cmd = RSB_CMD_RD8;
+               break;
+       case 2:
+               cmd = RSB_CMD_RD16;
+               break;
+       case 4:
+               cmd = RSB_CMD_RD32;
+               break;
+       default:
+               dev_err(rsb->dev, "Invalid access width: %d\n", len);
+               return -EINVAL;
+       }
+
+       mutex_lock(&rsb->lock);
+
+       writel(addr, rsb->regs + RSB_ADDR);
+       writel(RSB_DAR_RTA(rtaddr), rsb->regs + RSB_DAR);
+       writel(cmd, rsb->regs + RSB_CMD);
+
+       ret = _sunxi_rsb_run_xfer(rsb);
+       if (ret)
+               goto out;
+
+       *buf = readl(rsb->regs + RSB_DATA);
+
+       mutex_unlock(&rsb->lock);
+
+out:
+       return ret;
+}
+
+static int sunxi_rsb_write(struct sunxi_rsb *rsb, u8 rtaddr, u8 addr,
+                          const u32 *buf, size_t len)
+{
+       u32 cmd;
+       int ret;
+
+       if (!buf)
+               return -EINVAL;
+
+       switch (len) {
+       case 1:
+               cmd = RSB_CMD_WR8;
+               break;
+       case 2:
+               cmd = RSB_CMD_WR16;
+               break;
+       case 4:
+               cmd = RSB_CMD_WR32;
+               break;
+       default:
+               dev_err(rsb->dev, "Invalid access width: %d\n", len);
+               return -EINVAL;
+       }
+
+       mutex_lock(&rsb->lock);
+
+       writel(addr, rsb->regs + RSB_ADDR);
+       writel(RSB_DAR_RTA(rtaddr), rsb->regs + RSB_DAR);
+       writel(*buf, rsb->regs + RSB_DATA);
+       writel(cmd, rsb->regs + RSB_CMD);
+       ret = _sunxi_rsb_run_xfer(rsb);
+
+       mutex_unlock(&rsb->lock);
+
+       return ret;
+}
+
+/* RSB regmap functions */
+struct sunxi_rsb_ctx {
+       struct sunxi_rsb_device *rdev;
+       int size;
+};
+
+static int regmap_sunxi_rsb_reg_read(void *context, unsigned int reg,
+                                    unsigned int *val)
+{
+       struct sunxi_rsb_ctx *ctx = context;
+       struct sunxi_rsb_device *rdev = ctx->rdev;
+
+       if (reg > 0xff)
+               return -EINVAL;
+
+       return sunxi_rsb_read(rdev->rsb, rdev->rtaddr, reg, val, ctx->size);
+}
+
+static int regmap_sunxi_rsb_reg_write(void *context, unsigned int reg,
+                                     unsigned int val)
+{
+       struct sunxi_rsb_ctx *ctx = context;
+       struct sunxi_rsb_device *rdev = ctx->rdev;
+
+       return sunxi_rsb_write(rdev->rsb, rdev->rtaddr, reg, &val, ctx->size);
+}
+
+static void regmap_sunxi_rsb_free_ctx(void *context)
+{
+       struct sunxi_rsb_ctx *ctx = context;
+
+       kfree(ctx);
+}
+
+static struct regmap_bus regmap_sunxi_rsb = {
+       .reg_write = regmap_sunxi_rsb_reg_write,
+       .reg_read = regmap_sunxi_rsb_reg_read,
+       .free_context = regmap_sunxi_rsb_free_ctx,
+       .reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
+       .val_format_endian_default = REGMAP_ENDIAN_NATIVE,
+};
+
+static struct sunxi_rsb_ctx *regmap_sunxi_rsb_init_ctx(struct sunxi_rsb_device *rdev,
+               const struct regmap_config *config)
+{
+       struct sunxi_rsb_ctx *ctx;
+
+       switch (config->val_bits) {
+       case 8:
+       case 16:
+       case 32:
+               break;
+       default:
+               return ERR_PTR(-EINVAL);
+       }
+
+       ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+       if (!ctx)
+               return ERR_PTR(-ENOMEM);
+
+       ctx->rdev = rdev;
+       ctx->size = config->val_bits / 8;
+
+       return ctx;
+}
+
+struct regmap *__devm_regmap_init_sunxi_rsb(struct sunxi_rsb_device *rdev,
+                                           const struct regmap_config *config,
+                                           struct lock_class_key *lock_key,
+                                           const char *lock_name)
+{
+       struct sunxi_rsb_ctx *ctx = regmap_sunxi_rsb_init_ctx(rdev, config);
+
+       if (IS_ERR(ctx))
+               return ERR_CAST(ctx);
+
+       return __devm_regmap_init(&rdev->dev, &regmap_sunxi_rsb, ctx, config,
+                                 lock_key, lock_name);
+}
+EXPORT_SYMBOL_GPL(__devm_regmap_init_sunxi_rsb);
+
+/* RSB controller driver functions */
+static irqreturn_t sunxi_rsb_irq(int irq, void *dev_id)
+{
+       struct sunxi_rsb *rsb = dev_id;
+       u32 status;
+
+       status = readl(rsb->regs + RSB_INTS);
+       rsb->status = status;
+
+       /* Clear interrupts */
+       status &= (RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR |
+                  RSB_INTS_TRANS_OVER);
+       writel(status, rsb->regs + RSB_INTS);
+
+       complete(&rsb->complete);
+
+       return IRQ_HANDLED;
+}
+
+static int sunxi_rsb_init_device_mode(struct sunxi_rsb *rsb)
+{
+       int ret = 0;
+       u32 reg;
+
+       /* send init sequence */
+       writel(RSB_DMCR_DEVICE_START | RSB_DMCR_MODE_DATA |
+              RSB_DMCR_MODE_REG | RSB_DMCR_DEV_ADDR, rsb->regs + RSB_DMCR);
+
+       readl_poll_timeout(rsb->regs + RSB_DMCR, reg,
+                          !(reg & RSB_DMCR_DEVICE_START), 100, 250000);
+       if (reg & RSB_DMCR_DEVICE_START)
+               ret = -ETIMEDOUT;
+
+       /* clear interrupt status bits */
+       writel(readl(rsb->regs + RSB_INTS), rsb->regs + RSB_INTS);
+
+       return ret;
+}
+
+/*
+ * There are 15 valid runtime addresses, though Allwinner typically
+ * skips the first, for unknown reasons, and uses the following three.
+ *
+ * 0x17, 0x2d, 0x3a, 0x4e, 0x59, 0x63, 0x74, 0x8b,
+ * 0x9c, 0xa6, 0xb1, 0xc5, 0xd2, 0xe8, 0xff
+ *
+ * No designs with 2 RSB slave devices sharing identical hardware
+ * addresses on the same bus have been seen in the wild. All designs
+ * use 0x2d for the primary PMIC, 0x3a for the secondary PMIC if
+ * there is one, and 0x45 for peripheral ICs.
+ *
+ * The hardware does not seem to support re-setting runtime addresses.
+ * Attempts to do so result in the slave devices returning a NACK.
+ * Hence we just hardcode the mapping here, like Allwinner does.
+ */
+
+static const struct sunxi_rsb_addr_map sunxi_rsb_addr_maps[] = {
+       { 0x3e3, 0x2d }, /* Primary PMIC: AXP223, AXP809, AXP81X, ... */
+       { 0x745, 0x3a }, /* Secondary PMIC: AXP806, ... */
+       { 0xe89, 0x45 }, /* Peripheral IC: AC100, ... */
+};
+
+static u8 sunxi_rsb_get_rtaddr(u16 hwaddr)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(sunxi_rsb_addr_maps); i++)
+               if (hwaddr == sunxi_rsb_addr_maps[i].hwaddr)
+                       return sunxi_rsb_addr_maps[i].rtaddr;
+
+       return 0; /* 0 is an invalid runtime address */
+}
+
+static int of_rsb_register_devices(struct sunxi_rsb *rsb)
+{
+       struct device *dev = rsb->dev;
+       struct device_node *child, *np = dev->of_node;
+       u32 hwaddr;
+       u8 rtaddr;
+       int ret;
+
+       if (!np)
+               return -EINVAL;
+
+       /* Runtime addresses for all slaves should be set first */
+       for_each_available_child_of_node(np, child) {
+               dev_dbg(dev, "setting child %s runtime address\n",
+                       child->full_name);
+
+               ret = of_property_read_u32(child, "reg", &hwaddr);
+               if (ret) {
+                       dev_err(dev, "%s: invalid 'reg' property: %d\n",
+                               child->full_name, ret);
+                       continue;
+               }
+
+               rtaddr = sunxi_rsb_get_rtaddr(hwaddr);
+               if (!rtaddr) {
+                       dev_err(dev, "%s: unknown hardware device address\n",
+                               child->full_name);
+                       continue;
+               }
+
+               /*
+                * Since no devices have been registered yet, we are the
+                * only ones using the bus, we can skip locking the bus.
+                */
+
+               /* setup command parameters */
+               writel(RSB_CMD_STRA, rsb->regs + RSB_CMD);
+               writel(RSB_DAR_RTA(rtaddr) | RSB_DAR_DA(hwaddr),
+                      rsb->regs + RSB_DAR);
+
+               /* send command */
+               ret = _sunxi_rsb_run_xfer(rsb);
+               if (ret)
+                       dev_warn(dev, "%s: set runtime address failed: %d\n",
+                                child->full_name, ret);
+       }
+
+       /* Then we start adding devices and probing them */
+       for_each_available_child_of_node(np, child) {
+               struct sunxi_rsb_device *rdev;
+
+               dev_dbg(dev, "adding child %s\n", child->full_name);
+
+               ret = of_property_read_u32(child, "reg", &hwaddr);
+               if (ret)
+                       continue;
+
+               rtaddr = sunxi_rsb_get_rtaddr(hwaddr);
+               if (!rtaddr)
+                       continue;
+
+               rdev = sunxi_rsb_device_create(rsb, child, hwaddr, rtaddr);
+               if (IS_ERR(rdev))
+                       dev_err(dev, "failed to add child device %s: %ld\n",
+                               child->full_name, PTR_ERR(rdev));
+       }
+
+       return 0;
+}
+
+static const struct of_device_id sunxi_rsb_of_match_table[] = {
+       { .compatible = "allwinner,sun8i-a23-rsb" },
+       {}
+};
+MODULE_DEVICE_TABLE(of, sunxi_rsb_of_match_table);
+
+static int sunxi_rsb_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct device_node *np = dev->of_node;
+       struct resource *r;
+       struct sunxi_rsb *rsb;
+       unsigned long p_clk_freq;
+       u32 clk_delay, clk_freq = 3000000;
+       int clk_div, irq, ret;
+       u32 reg;
+
+       of_property_read_u32(np, "clock-frequency", &clk_freq);
+       if (clk_freq > RSB_MAX_FREQ) {
+               dev_err(dev,
+                       "clock-frequency (%u Hz) is too high (max = 20MHz)\n",
+                       clk_freq);
+               return -EINVAL;
+       }
+
+       rsb = devm_kzalloc(dev, sizeof(*rsb), GFP_KERNEL);
+       if (!rsb)
+               return -ENOMEM;
+
+       rsb->dev = dev;
+       platform_set_drvdata(pdev, rsb);
+       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       rsb->regs = devm_ioremap_resource(dev, r);
+       if (IS_ERR(rsb->regs))
+               return PTR_ERR(rsb->regs);
+
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+               dev_err(dev, "failed to retrieve irq: %d\n", irq);
+               return irq;
+       }
+
+       rsb->clk = devm_clk_get(dev, NULL);
+       if (IS_ERR(rsb->clk)) {
+               ret = PTR_ERR(rsb->clk);
+               dev_err(dev, "failed to retrieve clk: %d\n", ret);
+               return ret;
+       }
+
+       ret = clk_prepare_enable(rsb->clk);
+       if (ret) {
+               dev_err(dev, "failed to enable clk: %d\n", ret);
+               return ret;
+       }
+
+       p_clk_freq = clk_get_rate(rsb->clk);
+
+       rsb->rstc = devm_reset_control_get(dev, NULL);
+       if (IS_ERR(rsb->rstc)) {
+               ret = PTR_ERR(rsb->rstc);
+               dev_err(dev, "failed to retrieve reset controller: %d\n", ret);
+               goto err_clk_disable;
+       }
+
+       ret = reset_control_deassert(rsb->rstc);
+       if (ret) {
+               dev_err(dev, "failed to deassert reset line: %d\n", ret);
+               goto err_clk_disable;
+       }
+
+       init_completion(&rsb->complete);
+       mutex_init(&rsb->lock);
+
+       /* reset the controller */
+       writel(RSB_CTRL_SOFT_RST, rsb->regs + RSB_CTRL);
+       readl_poll_timeout(rsb->regs + RSB_CTRL, reg,
+                          !(reg & RSB_CTRL_SOFT_RST), 1000, 100000);
+
+       /*
+        * Clock frequency and delay calculation code is from
+        * Allwinner U-boot sources.
+        *
+        * From A83 user manual:
+        * bus clock frequency = parent clock frequency / (2 * (divider + 1))
+        */
+       clk_div = p_clk_freq / clk_freq / 2;
+       if (!clk_div)
+               clk_div = 1;
+       else if (clk_div > RSB_CCR_MAX_CLK_DIV + 1)
+               clk_div = RSB_CCR_MAX_CLK_DIV + 1;
+
+       clk_delay = clk_div >> 1;
+       if (!clk_delay)
+               clk_delay = 1;
+
+       dev_info(dev, "RSB running at %lu Hz\n", p_clk_freq / clk_div / 2);
+       writel(RSB_CCR_SDA_OUT_DELAY(clk_delay) | RSB_CCR_CLK_DIV(clk_div - 1),
+              rsb->regs + RSB_CCR);
+
+       ret = devm_request_irq(dev, irq, sunxi_rsb_irq, 0, RSB_CTRL_NAME, rsb);
+       if (ret) {
+               dev_err(dev, "can't register interrupt handler irq %d: %d\n",
+                       irq, ret);
+               goto err_reset_assert;
+       }
+
+       /* initialize all devices on the bus into RSB mode */
+       ret = sunxi_rsb_init_device_mode(rsb);
+       if (ret)
+               dev_warn(dev, "Initialize device mode failed: %d\n", ret);
+
+       of_rsb_register_devices(rsb);
+
+       return 0;
+
+err_reset_assert:
+       reset_control_assert(rsb->rstc);
+
+err_clk_disable:
+       clk_disable_unprepare(rsb->clk);
+
+       return ret;
+}
+
+static int sunxi_rsb_remove(struct platform_device *pdev)
+{
+       struct sunxi_rsb *rsb = platform_get_drvdata(pdev);
+
+       device_for_each_child(rsb->dev, NULL, sunxi_rsb_remove_devices);
+       reset_control_assert(rsb->rstc);
+       clk_disable_unprepare(rsb->clk);
+
+       return 0;
+}
+
+static struct platform_driver sunxi_rsb_driver = {
+       .probe = sunxi_rsb_probe,
+       .remove = sunxi_rsb_remove,
+       .driver = {
+               .name = RSB_CTRL_NAME,
+               .of_match_table = sunxi_rsb_of_match_table,
+       },
+};
+
+static int __init sunxi_rsb_init(void)
+{
+       int ret;
+
+       ret = bus_register(&sunxi_rsb_bus);
+       if (ret) {
+               pr_err("failed to register sunxi sunxi_rsb bus: %d\n", ret);
+               return ret;
+       }
+
+       return platform_driver_register(&sunxi_rsb_driver);
+}
+module_init(sunxi_rsb_init);
+
+static void __exit sunxi_rsb_exit(void)
+{
+       platform_driver_unregister(&sunxi_rsb_driver);
+       bus_unregister(&sunxi_rsb_bus);
+}
+module_exit(sunxi_rsb_exit);
+
+MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
+MODULE_DESCRIPTION("Allwinner sunXi Reduced Serial Bus controller driver");
+MODULE_LICENSE("GPL v2");
index 42f7120ca9ceaa1b900e737efeeb67f0913ae4e4..4aec54b90331b1662cae395bdab68f976c389696 100644 (file)
@@ -59,6 +59,16 @@ config COMMON_CLK_RK808
          clocked at 32KHz each. Clkout1 is always on, Clkout2 can off
          by control register.
 
+config COMMON_CLK_SCPI
+       tristate "Clock driver controlled via SCPI interface"
+       depends on ARM_SCPI_PROTOCOL || COMPILE_TEST
+         ---help---
+         This driver provides support for clocks that are controlled
+         by firmware that implements the SCPI interface.
+
+         This driver uses SCPI Message Protocol to interact with the
+         firmware providing all the clock controls.
+
 config COMMON_CLK_SI5351
        tristate "Clock driver for SiLabs 5351A/B/C"
        depends on I2C
index d08b3e5985bed4d2254c24aec6a9acb9645ff280..a381431bd950dd6cf8e654ef3866e454c3c5052d 100644 (file)
@@ -36,6 +36,7 @@ obj-$(CONFIG_COMMON_CLK_PALMAS)               += clk-palmas.o
 obj-$(CONFIG_CLK_QORIQ)                        += clk-qoriq.o
 obj-$(CONFIG_COMMON_CLK_RK808)         += clk-rk808.o
 obj-$(CONFIG_COMMON_CLK_S2MPS11)       += clk-s2mps11.o
+obj-$(CONFIG_COMMON_CLK_SCPI)           += clk-scpi.o
 obj-$(CONFIG_COMMON_CLK_SI5351)                += clk-si5351.o
 obj-$(CONFIG_COMMON_CLK_SI570)         += clk-si570.o
 obj-$(CONFIG_COMMON_CLK_CDCE925)       += clk-cdce925.o
index 221f40c2b850c1fafc1143e7f5b4458ecad55982..72d2f3500db85ba5d27bf173af90d9689bc1b491 100644 (file)
@@ -45,7 +45,7 @@
 #define REG_SDIO0XIN_CLKCTL    0x0158
 #define REG_SDIO1XIN_CLKCTL    0x015c
 
-#define        MAX_CLKS 27
+#define        MAX_CLKS 28
 static struct clk *clks[MAX_CLKS];
 static struct clk_onecell_data clk_data;
 static DEFINE_SPINLOCK(lock);
@@ -356,13 +356,13 @@ static void __init berlin2q_clock_setup(struct device_node *np)
                            gd->bit_idx, 0, &lock);
        }
 
-       /*
-        * twdclk is derived from cpu/3
-        * TODO: use cpupll until cpuclk is not available
-        */
+       /* cpuclk divider is fixed to 1 */
+       clks[CLKID_CPU] =
+               clk_register_fixed_factor(NULL, "cpu", clk_names[CPUPLL],
+                                         0, 1, 1);
+       /* twdclk is derived from cpu/3 */
        clks[CLKID_TWD] =
-               clk_register_fixed_factor(NULL, "twd", clk_names[CPUPLL],
-                                         0, 1, 3);
+               clk_register_fixed_factor(NULL, "twd", "cpu", 0, 1, 3);
 
        /* check for errors on leaf clocks */
        for (n = 0; n < MAX_CLKS; n++) {
diff --git a/drivers/clk/clk-scpi.c b/drivers/clk/clk-scpi.c
new file mode 100644 (file)
index 0000000..0b501a9
--- /dev/null
@@ -0,0 +1,325 @@
+/*
+ * System Control and Power Interface (SCPI) Protocol based clock driver
+ *
+ * Copyright (C) 2015 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/scpi_protocol.h>
+
+struct scpi_clk {
+       u32 id;
+       struct clk_hw hw;
+       struct scpi_dvfs_info *info;
+       struct scpi_ops *scpi_ops;
+};
+
+#define to_scpi_clk(clk) container_of(clk, struct scpi_clk, hw)
+
+static struct platform_device *cpufreq_dev;
+
+static unsigned long scpi_clk_recalc_rate(struct clk_hw *hw,
+                                         unsigned long parent_rate)
+{
+       struct scpi_clk *clk = to_scpi_clk(hw);
+
+       return clk->scpi_ops->clk_get_val(clk->id);
+}
+
+static long scpi_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+                               unsigned long *parent_rate)
+{
+       /*
+        * We can't figure out what rate it will be, so just return the
+        * rate back to the caller. scpi_clk_recalc_rate() will be called
+        * after the rate is set and we'll know what rate the clock is
+        * running at then.
+        */
+       return rate;
+}
+
+static int scpi_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+                            unsigned long parent_rate)
+{
+       struct scpi_clk *clk = to_scpi_clk(hw);
+
+       return clk->scpi_ops->clk_set_val(clk->id, rate);
+}
+
+static const struct clk_ops scpi_clk_ops = {
+       .recalc_rate = scpi_clk_recalc_rate,
+       .round_rate = scpi_clk_round_rate,
+       .set_rate = scpi_clk_set_rate,
+};
+
+/* find closest match to given frequency in OPP table */
+static int __scpi_dvfs_round_rate(struct scpi_clk *clk, unsigned long rate)
+{
+       int idx;
+       u32 fmin = 0, fmax = ~0, ftmp;
+       const struct scpi_opp *opp = clk->info->opps;
+
+       for (idx = 0; idx < clk->info->count; idx++, opp++) {
+               ftmp = opp->freq;
+               if (ftmp >= (u32)rate) {
+                       if (ftmp <= fmax)
+                               fmax = ftmp;
+                       break;
+               } else if (ftmp >= fmin) {
+                       fmin = ftmp;
+               }
+       }
+       return fmax != ~0 ? fmax : fmin;
+}
+
+static unsigned long scpi_dvfs_recalc_rate(struct clk_hw *hw,
+                                          unsigned long parent_rate)
+{
+       struct scpi_clk *clk = to_scpi_clk(hw);
+       int idx = clk->scpi_ops->dvfs_get_idx(clk->id);
+       const struct scpi_opp *opp;
+
+       if (idx < 0)
+               return 0;
+
+       opp = clk->info->opps + idx;
+       return opp->freq;
+}
+
+static long scpi_dvfs_round_rate(struct clk_hw *hw, unsigned long rate,
+                                unsigned long *parent_rate)
+{
+       struct scpi_clk *clk = to_scpi_clk(hw);
+
+       return __scpi_dvfs_round_rate(clk, rate);
+}
+
+static int __scpi_find_dvfs_index(struct scpi_clk *clk, unsigned long rate)
+{
+       int idx, max_opp = clk->info->count;
+       const struct scpi_opp *opp = clk->info->opps;
+
+       for (idx = 0; idx < max_opp; idx++, opp++)
+               if (opp->freq == rate)
+                       return idx;
+       return -EINVAL;
+}
+
+static int scpi_dvfs_set_rate(struct clk_hw *hw, unsigned long rate,
+                             unsigned long parent_rate)
+{
+       struct scpi_clk *clk = to_scpi_clk(hw);
+       int ret = __scpi_find_dvfs_index(clk, rate);
+
+       if (ret < 0)
+               return ret;
+       return clk->scpi_ops->dvfs_set_idx(clk->id, (u8)ret);
+}
+
+static const struct clk_ops scpi_dvfs_ops = {
+       .recalc_rate = scpi_dvfs_recalc_rate,
+       .round_rate = scpi_dvfs_round_rate,
+       .set_rate = scpi_dvfs_set_rate,
+};
+
+static const struct of_device_id scpi_clk_match[] = {
+       { .compatible = "arm,scpi-dvfs-clocks", .data = &scpi_dvfs_ops, },
+       { .compatible = "arm,scpi-variable-clocks", .data = &scpi_clk_ops, },
+       {}
+};
+
+static struct clk *
+scpi_clk_ops_init(struct device *dev, const struct of_device_id *match,
+                 struct scpi_clk *sclk, const char *name)
+{
+       struct clk_init_data init;
+       struct clk *clk;
+       unsigned long min = 0, max = 0;
+
+       init.name = name;
+       init.flags = CLK_IS_ROOT;
+       init.num_parents = 0;
+       init.ops = match->data;
+       sclk->hw.init = &init;
+       sclk->scpi_ops = get_scpi_ops();
+
+       if (init.ops == &scpi_dvfs_ops) {
+               sclk->info = sclk->scpi_ops->dvfs_get_info(sclk->id);
+               if (IS_ERR(sclk->info))
+                       return NULL;
+       } else if (init.ops == &scpi_clk_ops) {
+               if (sclk->scpi_ops->clk_get_range(sclk->id, &min, &max) || !max)
+                       return NULL;
+       } else {
+               return NULL;
+       }
+
+       clk = devm_clk_register(dev, &sclk->hw);
+       if (!IS_ERR(clk) && max)
+               clk_hw_set_rate_range(&sclk->hw, min, max);
+       return clk;
+}
+
+struct scpi_clk_data {
+       struct scpi_clk **clk;
+       unsigned int clk_num;
+};
+
+static struct clk *
+scpi_of_clk_src_get(struct of_phandle_args *clkspec, void *data)
+{
+       struct scpi_clk *sclk;
+       struct scpi_clk_data *clk_data = data;
+       unsigned int idx = clkspec->args[0], count;
+
+       for (count = 0; count < clk_data->clk_num; count++) {
+               sclk = clk_data->clk[count];
+               if (idx == sclk->id)
+                       return sclk->hw.clk;
+       }
+
+       return ERR_PTR(-EINVAL);
+}
+
+static int scpi_clk_add(struct device *dev, struct device_node *np,
+                       const struct of_device_id *match)
+{
+       struct clk **clks;
+       int idx, count;
+       struct scpi_clk_data *clk_data;
+
+       count = of_property_count_strings(np, "clock-output-names");
+       if (count < 0) {
+               dev_err(dev, "%s: invalid clock output count\n", np->name);
+               return -EINVAL;
+       }
+
+       clk_data = devm_kmalloc(dev, sizeof(*clk_data), GFP_KERNEL);
+       if (!clk_data)
+               return -ENOMEM;
+
+       clk_data->clk_num = count;
+       clk_data->clk = devm_kcalloc(dev, count, sizeof(*clk_data->clk),
+                                    GFP_KERNEL);
+       if (!clk_data->clk)
+               return -ENOMEM;
+
+       clks = devm_kcalloc(dev, count, sizeof(*clks), GFP_KERNEL);
+       if (!clks)
+               return -ENOMEM;
+
+       for (idx = 0; idx < count; idx++) {
+               struct scpi_clk *sclk;
+               const char *name;
+               u32 val;
+
+               sclk = devm_kzalloc(dev, sizeof(*sclk), GFP_KERNEL);
+               if (!sclk)
+                       return -ENOMEM;
+
+               if (of_property_read_string_index(np, "clock-output-names",
+                                                 idx, &name)) {
+                       dev_err(dev, "invalid clock name @ %s\n", np->name);
+                       return -EINVAL;
+               }
+
+               if (of_property_read_u32_index(np, "clock-indices",
+                                              idx, &val)) {
+                       dev_err(dev, "invalid clock index @ %s\n", np->name);
+                       return -EINVAL;
+               }
+
+               sclk->id = val;
+
+               clks[idx] = scpi_clk_ops_init(dev, match, sclk, name);
+               if (IS_ERR_OR_NULL(clks[idx]))
+                       dev_err(dev, "failed to register clock '%s'\n", name);
+               else
+                       dev_dbg(dev, "Registered clock '%s'\n", name);
+               clk_data->clk[idx] = sclk;
+       }
+
+       return of_clk_add_provider(np, scpi_of_clk_src_get, clk_data);
+}
+
+static int scpi_clocks_remove(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct device_node *child, *np = dev->of_node;
+
+       if (cpufreq_dev) {
+               platform_device_unregister(cpufreq_dev);
+               cpufreq_dev = NULL;
+       }
+
+       for_each_available_child_of_node(np, child)
+               of_clk_del_provider(np);
+       return 0;
+}
+
+static int scpi_clocks_probe(struct platform_device *pdev)
+{
+       int ret;
+       struct device *dev = &pdev->dev;
+       struct device_node *child, *np = dev->of_node;
+       const struct of_device_id *match;
+
+       if (!get_scpi_ops())
+               return -ENXIO;
+
+       for_each_available_child_of_node(np, child) {
+               match = of_match_node(scpi_clk_match, child);
+               if (!match)
+                       continue;
+               ret = scpi_clk_add(dev, child, match);
+               if (ret) {
+                       scpi_clocks_remove(pdev);
+                       return ret;
+               }
+       }
+       /* Add the virtual cpufreq device */
+       cpufreq_dev = platform_device_register_simple("scpi-cpufreq",
+                                                     -1, NULL, 0);
+       if (!cpufreq_dev)
+               pr_warn("unable to register cpufreq device");
+
+       return 0;
+}
+
+static const struct of_device_id scpi_clocks_ids[] = {
+       { .compatible = "arm,scpi-clocks", },
+       {}
+};
+MODULE_DEVICE_TABLE(of, scpi_clocks_ids);
+
+static struct platform_driver scpi_clocks_driver = {
+       .driver = {
+               .name = "scpi_clocks",
+               .of_match_table = scpi_clocks_ids,
+       },
+       .probe = scpi_clocks_probe,
+       .remove = scpi_clocks_remove,
+};
+module_platform_driver(scpi_clocks_driver);
+
+MODULE_AUTHOR("Sudeep Holla <sudeep.holla@arm.com>");
+MODULE_DESCRIPTION("ARM SCPI clock driver");
+MODULE_LICENSE("GPL v2");
index 7c1e1f58e2da2e7dc7909fce407bc477651add3a..2fe37f708dc70828ffa10fc165ecc830fff49c86 100644 (file)
@@ -164,7 +164,7 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
         * the values for DIV_COPY and DIV_HPM dividers need not be set.
         */
        div0 = cfg_data->div0;
-       if (test_bit(CLK_CPU_HAS_DIV1, &cpuclk->flags)) {
+       if (cpuclk->flags & CLK_CPU_HAS_DIV1) {
                div1 = cfg_data->div1;
                if (readl(base + E4210_SRC_CPU) & E4210_MUX_HPM_MASK)
                        div1 = readl(base + E4210_DIV_CPU1) &
@@ -185,7 +185,7 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
                alt_div = DIV_ROUND_UP(alt_prate, tmp_rate) - 1;
                WARN_ON(alt_div >= MAX_DIV);
 
-               if (test_bit(CLK_CPU_NEEDS_DEBUG_ALT_DIV, &cpuclk->flags)) {
+               if (cpuclk->flags & CLK_CPU_NEEDS_DEBUG_ALT_DIV) {
                        /*
                         * In Exynos4210, ATB clock parent is also mout_core. So
                         * ATB clock also needs to be mantained at safe speed.
@@ -206,7 +206,7 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
        writel(div0, base + E4210_DIV_CPU0);
        wait_until_divider_stable(base + E4210_DIV_STAT_CPU0, DIV_MASK_ALL);
 
-       if (test_bit(CLK_CPU_HAS_DIV1, &cpuclk->flags)) {
+       if (cpuclk->flags & CLK_CPU_HAS_DIV1) {
                writel(div1, base + E4210_DIV_CPU1);
                wait_until_divider_stable(base + E4210_DIV_STAT_CPU1,
                                DIV_MASK_ALL);
@@ -225,7 +225,7 @@ static int exynos_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
        unsigned long mux_reg;
 
        /* find out the divider values to use for clock data */
-       if (test_bit(CLK_CPU_NEEDS_DEBUG_ALT_DIV, &cpuclk->flags)) {
+       if (cpuclk->flags & CLK_CPU_NEEDS_DEBUG_ALT_DIV) {
                while ((cfg_data->prate * 1000) != ndata->new_rate) {
                        if (cfg_data->prate == 0)
                                return -EINVAL;
@@ -240,7 +240,7 @@ static int exynos_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
        writel(mux_reg & ~(1 << 16), base + E4210_SRC_CPU);
        wait_until_mux_stable(base + E4210_STAT_CPU, 16, 1);
 
-       if (test_bit(CLK_CPU_NEEDS_DEBUG_ALT_DIV, &cpuclk->flags)) {
+       if (cpuclk->flags & CLK_CPU_NEEDS_DEBUG_ALT_DIV) {
                div |= (cfg_data->div0 & E4210_DIV0_ATB_MASK);
                div_mask |= E4210_DIV0_ATB_MASK;
        }
index b1df7b2f1e970adbc0214bd6e8af68cbfca7897c..a0a56e99882ac9ab028e290c3eb6be463e89e9dc 100644 (file)
@@ -259,6 +259,10 @@ int cpg_mstp_attach_dev(struct generic_pm_domain *domain, struct device *dev)
                                            "renesas,cpg-mstp-clocks"))
                        goto found;
 
+               /* BSC on r8a73a4/sh73a0 uses zb_clk instead of an mstp clock */
+               if (!strcmp(clkspec.np->name, "zb_clk"))
+                       goto found;
+
                of_node_put(clkspec.np);
                i++;
        }
index 413070d07b3f1f255a8229a259eeb97c5aaf94ae..9c79af0c03b2115a422f49414e9b431ed0d8ab36 100644 (file)
@@ -1196,6 +1196,7 @@ static void __init sun5i_init_clocks(struct device_node *node)
 }
 CLK_OF_DECLARE(sun5i_a10s_clk_init, "allwinner,sun5i-a10s", sun5i_init_clocks);
 CLK_OF_DECLARE(sun5i_a13_clk_init, "allwinner,sun5i-a13", sun5i_init_clocks);
+CLK_OF_DECLARE(sun5i_r8_clk_init, "allwinner,sun5i-r8", sun5i_init_clocks);
 CLK_OF_DECLARE(sun7i_a20_clk_init, "allwinner,sun7i-a20", sun5i_init_clocks);
 
 static const char *sun6i_critical_clocks[] __initdata = {
index 676ee8f6d8136729a9665cfb9c29e7faed123781..8831e1a05367ad9c7473e3ee723adc3f29dc9936 100644 (file)
@@ -374,7 +374,6 @@ static struct ti_dt_clk omap3xxx_clks[] = {
        DT_CLK(NULL, "gpio2_ick", "gpio2_ick"),
        DT_CLK(NULL, "wdt3_ick", "wdt3_ick"),
        DT_CLK(NULL, "uart3_ick", "uart3_ick"),
-       DT_CLK(NULL, "uart4_ick", "uart4_ick"),
        DT_CLK(NULL, "gpt9_ick", "gpt9_ick"),
        DT_CLK(NULL, "gpt8_ick", "gpt8_ick"),
        DT_CLK(NULL, "gpt7_ick", "gpt7_ick"),
@@ -519,6 +518,7 @@ static struct ti_dt_clk am35xx_clks[] = {
 static struct ti_dt_clk omap36xx_clks[] = {
        DT_CLK(NULL, "omap_192m_alwon_fck", "omap_192m_alwon_fck"),
        DT_CLK(NULL, "uart4_fck", "uart4_fck"),
+       DT_CLK(NULL, "uart4_ick", "uart4_ick"),
        { .node_name = NULL },
 };
 
index 9b5b289e633456206e81268d00bc212a7f9f62cc..a911d7de33778d7bc7648e59f0ee60c1a6c83027 100644 (file)
@@ -18,7 +18,6 @@
 
 #include "clock.h"
 
-#define DRA7_DPLL_ABE_DEFFREQ                          180633600
 #define DRA7_DPLL_GMAC_DEFFREQ                         1000000000
 #define DRA7_DPLL_USB_DEFFREQ                          960000000
 
@@ -313,27 +312,12 @@ static struct ti_dt_clk dra7xx_clks[] = {
 int __init dra7xx_dt_clk_init(void)
 {
        int rc;
-       struct clk *abe_dpll_mux, *sys_clkin2, *dpll_ck, *hdcp_ck;
+       struct clk *dpll_ck, *hdcp_ck;
 
        ti_dt_clocks_register(dra7xx_clks);
 
        omap2_clk_disable_autoidle_all();
 
-       abe_dpll_mux = clk_get_sys(NULL, "abe_dpll_sys_clk_mux");
-       sys_clkin2 = clk_get_sys(NULL, "sys_clkin2");
-       dpll_ck = clk_get_sys(NULL, "dpll_abe_ck");
-
-       rc = clk_set_parent(abe_dpll_mux, sys_clkin2);
-       if (!rc)
-               rc = clk_set_rate(dpll_ck, DRA7_DPLL_ABE_DEFFREQ);
-       if (rc)
-               pr_err("%s: failed to configure ABE DPLL!\n", __func__);
-
-       dpll_ck = clk_get_sys(NULL, "dpll_abe_m2x2_ck");
-       rc = clk_set_rate(dpll_ck, DRA7_DPLL_ABE_DEFFREQ * 2);
-       if (rc)
-               pr_err("%s: failed to configure ABE DPLL m2x2!\n", __func__);
-
        dpll_ck = clk_get_sys(NULL, "dpll_gmac_ck");
        rc = clk_set_rate(dpll_ck, DRA7_DPLL_GMAC_DEFFREQ);
        if (rc)
index 90d7d8a21c4918d52b910fab900e78acd68c5aad..1ddc288fce4eb123e63d941971bc94bff41f69a5 100644 (file)
@@ -222,7 +222,7 @@ int omap2_dflt_clk_enable(struct clk_hw *hw)
                }
        }
 
-       if (unlikely(!clk->enable_reg)) {
+       if (unlikely(IS_ERR(clk->enable_reg))) {
                pr_err("%s: %s missing enable_reg\n", __func__,
                       clk_hw_get_name(hw));
                ret = -EINVAL;
@@ -264,7 +264,7 @@ void omap2_dflt_clk_disable(struct clk_hw *hw)
        u32 v;
 
        clk = to_clk_hw_omap(hw);
-       if (!clk->enable_reg) {
+       if (IS_ERR(clk->enable_reg)) {
                /*
                 * 'independent' here refers to a clock which is not
                 * controlled by its parent.
index d28d2fe798d570a4f3e59f34a549c82ea8ab50c6..6ee91401918eba99a33c67b554da853747a0c5fa 100644 (file)
@@ -193,10 +193,17 @@ static int __init setup_clkevents(struct atmel_tc *tc, int clk32k_divisor_idx)
        struct clk *t2_clk = tc->clk[2];
        int irq = tc->irq[2];
 
+       ret = clk_prepare_enable(tc->slow_clk);
+       if (ret)
+               return ret;
+
        /* try to enable t2 clk to avoid future errors in mode change */
        ret = clk_prepare_enable(t2_clk);
-       if (ret)
+       if (ret) {
+               clk_disable_unprepare(tc->slow_clk);
                return ret;
+       }
+
        clk_disable(t2_clk);
 
        clkevt.regs = tc->regs;
@@ -208,7 +215,8 @@ static int __init setup_clkevents(struct atmel_tc *tc, int clk32k_divisor_idx)
 
        ret = request_irq(irq, ch2_irq, IRQF_TIMER, "tc_clkevt", &clkevt);
        if (ret) {
-               clk_disable_unprepare(t2_clk);
+               clk_unprepare(t2_clk);
+               clk_disable_unprepare(tc->slow_clk);
                return ret;
        }
 
index 41b7b6dc1d0d1ff32a0be15c2c394d000195a6a8..29d21d68df5a231d78f586b2ac64ce56ed8e68b1 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/kernel.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/clk.h>
 #include <linux/clockchips.h>
 #include <linux/export.h>
 #include <linux/mfd/syscon.h>
@@ -33,9 +34,7 @@ static unsigned long last_crtr;
 static u32 irqmask;
 static struct clock_event_device clkevt;
 static struct regmap *regmap_st;
-
-#define AT91_SLOW_CLOCK                32768
-#define RM9200_TIMER_LATCH     ((AT91_SLOW_CLOCK + HZ/2) / HZ)
+static int timer_latch;
 
 /*
  * The ST_CRTR is updated asynchronously to the master clock ... but
@@ -82,8 +81,8 @@ static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id)
        if (sr & AT91_ST_PITS) {
                u32     crtr = read_CRTR();
 
-               while (((crtr - last_crtr) & AT91_ST_CRTV) >= RM9200_TIMER_LATCH) {
-                       last_crtr += RM9200_TIMER_LATCH;
+               while (((crtr - last_crtr) & AT91_ST_CRTV) >= timer_latch) {
+                       last_crtr += timer_latch;
                        clkevt.event_handler(&clkevt);
                }
                return IRQ_HANDLED;
@@ -144,7 +143,7 @@ static int clkevt32k_set_periodic(struct clock_event_device *dev)
 
        /* PIT for periodic irqs; fixed rate of 1/HZ */
        irqmask = AT91_ST_PITS;
-       regmap_write(regmap_st, AT91_ST_PIMR, RM9200_TIMER_LATCH);
+       regmap_write(regmap_st, AT91_ST_PIMR, timer_latch);
        regmap_write(regmap_st, AT91_ST_IER, irqmask);
        return 0;
 }
@@ -197,7 +196,8 @@ static struct clock_event_device clkevt = {
  */
 static void __init atmel_st_timer_init(struct device_node *node)
 {
-       unsigned int val;
+       struct clk *sclk;
+       unsigned int sclk_rate, val;
        int irq, ret;
 
        regmap_st = syscon_node_to_regmap(node);
@@ -221,6 +221,19 @@ static void __init atmel_st_timer_init(struct device_node *node)
        if (ret)
                panic(pr_fmt("Unable to setup IRQ\n"));
 
+       sclk = of_clk_get(node, 0);
+       if (IS_ERR(sclk))
+               panic(pr_fmt("Unable to get slow clock\n"));
+
+       clk_prepare_enable(sclk);
+       if (ret)
+               panic(pr_fmt("Could not enable slow clock\n"));
+
+       sclk_rate = clk_get_rate(sclk);
+       if (!sclk_rate)
+               panic(pr_fmt("Invalid slow clock rate\n"));
+       timer_latch = (sclk_rate + HZ / 2) / HZ;
+
        /* The 32KiHz "Slow Clock" (tick every 30517.58 nanoseconds) is used
         * directly for the clocksource and all clockevents, after adjusting
         * its prescaler from the 1 Hz default.
@@ -229,11 +242,11 @@ static void __init atmel_st_timer_init(struct device_node *node)
 
        /* Setup timer clockevent, with minimum of two ticks (important!!) */
        clkevt.cpumask = cpumask_of(0);
-       clockevents_config_and_register(&clkevt, AT91_SLOW_CLOCK,
+       clockevents_config_and_register(&clkevt, sclk_rate,
                                        2, AT91_ST_ALMV);
 
        /* register clocksource */
-       clocksource_register_hz(&clk32k, AT91_SLOW_CLOCK);
+       clocksource_register_hz(&clk32k, sclk_rate);
 }
 CLOCKSOURCE_OF_DECLARE(atmel_st_timer, "atmel,at91rm9200-st",
                       atmel_st_timer_init);
index cd0391e46c6dbc6163819b533ce225f3afe898e8..c737f7359974b1afe98650b05c2e67c27351d184 100644 (file)
@@ -199,6 +199,16 @@ config ARM_SA1100_CPUFREQ
 config ARM_SA1110_CPUFREQ
        bool
 
+config ARM_SCPI_CPUFREQ
+        tristate "SCPI based CPUfreq driver"
+       depends on ARM_BIG_LITTLE_CPUFREQ && ARM_SCPI_PROTOCOL
+        help
+         This adds the CPUfreq driver support for ARM big.LITTLE platforms
+         using SCPI protocol for CPU power management.
+
+         This driver uses SCPI Message Protocol driver to interact with the
+         firmware providing the CPU DVFS functionality.
+
 config ARM_SPEAR_CPUFREQ
        bool "SPEAr CPUFreq support"
        depends on PLAT_SPEAR
index 41340384f11f291c4fe93e96e73559926f4f59b1..ccfaa4c68a9a236998015e2fe2af3700759e6f3b 100644 (file)
@@ -72,6 +72,7 @@ obj-$(CONFIG_ARM_S3C64XX_CPUFREQ)     += s3c64xx-cpufreq.o
 obj-$(CONFIG_ARM_S5PV210_CPUFREQ)      += s5pv210-cpufreq.o
 obj-$(CONFIG_ARM_SA1100_CPUFREQ)       += sa1100-cpufreq.o
 obj-$(CONFIG_ARM_SA1110_CPUFREQ)       += sa1110-cpufreq.o
+obj-$(CONFIG_ARM_SCPI_CPUFREQ)         += scpi-cpufreq.o
 obj-$(CONFIG_ARM_SPEAR_CPUFREQ)                += spear-cpufreq.o
 obj-$(CONFIG_ARM_TEGRA20_CPUFREQ)      += tegra20-cpufreq.o
 obj-$(CONFIG_ARM_TEGRA124_CPUFREQ)     += tegra124-cpufreq.o
index 798277227de7f3a897a4ad79fcaabe787412fcfb..cec1ee2d2f744b968fe653f47dc5067dfe4dccb1 100644 (file)
@@ -149,6 +149,9 @@ static ssize_t show_freqdomain_cpus(struct cpufreq_policy *policy, char *buf)
 {
        struct acpi_cpufreq_data *data = policy->driver_data;
 
+       if (unlikely(!data))
+               return -ENODEV;
+
        return cpufreq_show_cpus(data->freqdomain_cpus, buf);
 }
 
index ef5ed9470de9a59d371e34e7db24a434d1f11a9f..25c4c15103a0cd8759e006eaa10d9f9edbfb5872 100644 (file)
@@ -1436,8 +1436,10 @@ static void cpufreq_offline_finish(unsigned int cpu)
         * since this is a core component, and is essential for the
         * subsequent light-weight ->init() to succeed.
         */
-       if (cpufreq_driver->exit)
+       if (cpufreq_driver->exit) {
                cpufreq_driver->exit(policy);
+               policy->freq_table = NULL;
+       }
 }
 
 /**
diff --git a/drivers/cpufreq/scpi-cpufreq.c b/drivers/cpufreq/scpi-cpufreq.c
new file mode 100644 (file)
index 0000000..2c3b16f
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * System Control and Power Interface (SCPI) based CPUFreq Interface driver
+ *
+ * It provides necessary ops to arm_big_little cpufreq driver.
+ *
+ * Copyright (C) 2015 ARM Ltd.
+ * Sudeep Holla <sudeep.holla@arm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/cpufreq.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_opp.h>
+#include <linux/scpi_protocol.h>
+#include <linux/types.h>
+
+#include "arm_big_little.h"
+
+static struct scpi_ops *scpi_ops;
+
+static struct scpi_dvfs_info *scpi_get_dvfs_info(struct device *cpu_dev)
+{
+       u8 domain = topology_physical_package_id(cpu_dev->id);
+
+       if (domain < 0)
+               return ERR_PTR(-EINVAL);
+       return scpi_ops->dvfs_get_info(domain);
+}
+
+static int scpi_opp_table_ops(struct device *cpu_dev, bool remove)
+{
+       int idx, ret = 0;
+       struct scpi_opp *opp;
+       struct scpi_dvfs_info *info = scpi_get_dvfs_info(cpu_dev);
+
+       if (IS_ERR(info))
+               return PTR_ERR(info);
+
+       if (!info->opps)
+               return -EIO;
+
+       for (opp = info->opps, idx = 0; idx < info->count; idx++, opp++) {
+               if (remove)
+                       dev_pm_opp_remove(cpu_dev, opp->freq);
+               else
+                       ret = dev_pm_opp_add(cpu_dev, opp->freq,
+                                            opp->m_volt * 1000);
+               if (ret) {
+                       dev_warn(cpu_dev, "failed to add opp %uHz %umV\n",
+                                opp->freq, opp->m_volt);
+                       while (idx-- > 0)
+                               dev_pm_opp_remove(cpu_dev, (--opp)->freq);
+                       return ret;
+               }
+       }
+       return ret;
+}
+
+static int scpi_get_transition_latency(struct device *cpu_dev)
+{
+       struct scpi_dvfs_info *info = scpi_get_dvfs_info(cpu_dev);
+
+       if (IS_ERR(info))
+               return PTR_ERR(info);
+       return info->latency;
+}
+
+static int scpi_init_opp_table(struct device *cpu_dev)
+{
+       return scpi_opp_table_ops(cpu_dev, false);
+}
+
+static void scpi_free_opp_table(struct device *cpu_dev)
+{
+       scpi_opp_table_ops(cpu_dev, true);
+}
+
+static struct cpufreq_arm_bL_ops scpi_cpufreq_ops = {
+       .name   = "scpi",
+       .get_transition_latency = scpi_get_transition_latency,
+       .init_opp_table = scpi_init_opp_table,
+       .free_opp_table = scpi_free_opp_table,
+};
+
+static int scpi_cpufreq_probe(struct platform_device *pdev)
+{
+       scpi_ops = get_scpi_ops();
+       if (!scpi_ops)
+               return -EIO;
+
+       return bL_cpufreq_register(&scpi_cpufreq_ops);
+}
+
+static int scpi_cpufreq_remove(struct platform_device *pdev)
+{
+       bL_cpufreq_unregister(&scpi_cpufreq_ops);
+       scpi_ops = NULL;
+       return 0;
+}
+
+static struct platform_driver scpi_cpufreq_platdrv = {
+       .driver = {
+               .name   = "scpi-cpufreq",
+               .owner  = THIS_MODULE,
+       },
+       .probe          = scpi_cpufreq_probe,
+       .remove         = scpi_cpufreq_remove,
+};
+module_platform_driver(scpi_cpufreq_platdrv);
+
+MODULE_AUTHOR("Sudeep Holla <sudeep.holla@arm.com>");
+MODULE_DESCRIPTION("ARM SCPI CPUFreq interface driver");
+MODULE_LICENSE("GPL v2");
index 3927ed9fdbd51f16d765aede8fef14418994ab55..ca848cc6a8fd1313bc56e5b93674b3d795814779 100644 (file)
@@ -492,7 +492,7 @@ struct devfreq *devfreq_add_device(struct device *dev,
        if (err) {
                put_device(&devfreq->dev);
                mutex_unlock(&devfreq->lock);
-               goto err_dev;
+               goto err_out;
        }
 
        mutex_unlock(&devfreq->lock);
@@ -518,7 +518,6 @@ struct devfreq *devfreq_add_device(struct device *dev,
 err_init:
        list_del(&devfreq->node);
        device_unregister(&devfreq->dev);
-err_dev:
        kfree(devfreq);
 err_out:
        return ERR_PTR(err);
@@ -795,8 +794,10 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr,
                ret = PTR_ERR(governor);
                goto out;
        }
-       if (df->governor == governor)
+       if (df->governor == governor) {
+               ret = 0;
                goto out;
+       }
 
        if (df->governor) {
                ret = df->governor->event_handler(df, DEVFREQ_GOV_STOP, NULL);
index 665efca59487a3eb4d341570002794e09f7bd11a..d00c6d338cc36a5bea00502752c5d7d64d17ca90 100644 (file)
@@ -8,6 +8,25 @@ menu "Firmware Drivers"
 config ARM_PSCI_FW
        bool
 
+config ARM_SCPI_PROTOCOL
+       tristate "ARM System Control and Power Interface (SCPI) Message Protocol"
+       depends on ARM_MHU
+       help
+         System Control and Power Interface (SCPI) Message Protocol is
+         defined for the purpose of communication between the Application
+         Cores(AP) and the System Control Processor(SCP). The MHU peripheral
+         provides a mechanism for inter-processor communication between SCP
+         and AP.
+
+         SCP controls most of the power managament on the Application
+         Processors. It offers control and management of: the core/cluster
+         power states, various power domain DVFS including the core/cluster,
+         certain system clocks configuration, thermal sensors and many
+         others.
+
+         This protocol library provides interface for all the client drivers
+         making use of the features offered by the SCP.
+
 config EDD
        tristate "BIOS Enhanced Disk Drive calls determine boot disk"
        depends on X86
index 2ee83474a3c1fec73d8e587465c9b5fb71b333b3..b984dd7d9ccba881852fa033f989eabe75859e17 100644 (file)
@@ -2,6 +2,7 @@
 # Makefile for the linux kernel.
 #
 obj-$(CONFIG_ARM_PSCI_FW)      += psci.o
+obj-$(CONFIG_ARM_SCPI_PROTOCOL)        += arm_scpi.o
 obj-$(CONFIG_DMI)              += dmi_scan.o
 obj-$(CONFIG_DMI_SYSFS)                += dmi-sysfs.o
 obj-$(CONFIG_EDD)              += edd.o
@@ -15,7 +16,7 @@ obj-$(CONFIG_FIRMWARE_MEMMAP) += memmap.o
 obj-$(CONFIG_QCOM_SCM)         += qcom_scm.o
 obj-$(CONFIG_QCOM_SCM_64)      += qcom_scm-64.o
 obj-$(CONFIG_QCOM_SCM_32)      += qcom_scm-32.o
-CFLAGS_qcom_scm-32.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
+CFLAGS_qcom_scm-32.o :=$(call as-instr,.arch armv7-a\n.arch_extension sec,-DREQUIRES_SEC=1) -march=armv7-a
 
 obj-y                          += broadcom/
 obj-$(CONFIG_GOOGLE_FIRMWARE)  += google/
diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c
new file mode 100644 (file)
index 0000000..6174db8
--- /dev/null
@@ -0,0 +1,771 @@
+/*
+ * System Control and Power Interface (SCPI) Message Protocol driver
+ *
+ * SCPI Message Protocol is used between the System Control Processor(SCP)
+ * and the Application Processors(AP). The Message Handling Unit(MHU)
+ * provides a mechanism for inter-processor communication between SCP's
+ * Cortex M3 and AP.
+ *
+ * SCP offers control and management of the core/cluster power states,
+ * various power domain DVFS including the core/cluster, certain system
+ * clocks configuration, thermal sensors and many others.
+ *
+ * Copyright (C) 2015 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/bitmap.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/export.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/mailbox_client.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/printk.h>
+#include <linux/scpi_protocol.h>
+#include <linux/slab.h>
+#include <linux/sort.h>
+#include <linux/spinlock.h>
+
+#define CMD_ID_SHIFT           0
+#define CMD_ID_MASK            0x7f
+#define CMD_TOKEN_ID_SHIFT     8
+#define CMD_TOKEN_ID_MASK      0xff
+#define CMD_DATA_SIZE_SHIFT    16
+#define CMD_DATA_SIZE_MASK     0x1ff
+#define PACK_SCPI_CMD(cmd_id, tx_sz)                   \
+       ((((cmd_id) & CMD_ID_MASK) << CMD_ID_SHIFT) |   \
+       (((tx_sz) & CMD_DATA_SIZE_MASK) << CMD_DATA_SIZE_SHIFT))
+#define ADD_SCPI_TOKEN(cmd, token)                     \
+       ((cmd) |= (((token) & CMD_TOKEN_ID_MASK) << CMD_TOKEN_ID_SHIFT))
+
+#define CMD_SIZE(cmd)  (((cmd) >> CMD_DATA_SIZE_SHIFT) & CMD_DATA_SIZE_MASK)
+#define CMD_UNIQ_MASK  (CMD_TOKEN_ID_MASK << CMD_TOKEN_ID_SHIFT | CMD_ID_MASK)
+#define CMD_XTRACT_UNIQ(cmd)   ((cmd) & CMD_UNIQ_MASK)
+
+#define SCPI_SLOT              0
+
+#define MAX_DVFS_DOMAINS       8
+#define MAX_DVFS_OPPS          8
+#define DVFS_LATENCY(hdr)      (le32_to_cpu(hdr) >> 16)
+#define DVFS_OPP_COUNT(hdr)    ((le32_to_cpu(hdr) >> 8) & 0xff)
+
+#define PROTOCOL_REV_MINOR_BITS        16
+#define PROTOCOL_REV_MINOR_MASK        ((1U << PROTOCOL_REV_MINOR_BITS) - 1)
+#define PROTOCOL_REV_MAJOR(x)  ((x) >> PROTOCOL_REV_MINOR_BITS)
+#define PROTOCOL_REV_MINOR(x)  ((x) & PROTOCOL_REV_MINOR_MASK)
+
+#define FW_REV_MAJOR_BITS      24
+#define FW_REV_MINOR_BITS      16
+#define FW_REV_PATCH_MASK      ((1U << FW_REV_MINOR_BITS) - 1)
+#define FW_REV_MINOR_MASK      ((1U << FW_REV_MAJOR_BITS) - 1)
+#define FW_REV_MAJOR(x)                ((x) >> FW_REV_MAJOR_BITS)
+#define FW_REV_MINOR(x)                (((x) & FW_REV_MINOR_MASK) >> FW_REV_MINOR_BITS)
+#define FW_REV_PATCH(x)                ((x) & FW_REV_PATCH_MASK)
+
+#define MAX_RX_TIMEOUT         (msecs_to_jiffies(20))
+
+enum scpi_error_codes {
+       SCPI_SUCCESS = 0, /* Success */
+       SCPI_ERR_PARAM = 1, /* Invalid parameter(s) */
+       SCPI_ERR_ALIGN = 2, /* Invalid alignment */
+       SCPI_ERR_SIZE = 3, /* Invalid size */
+       SCPI_ERR_HANDLER = 4, /* Invalid handler/callback */
+       SCPI_ERR_ACCESS = 5, /* Invalid access/permission denied */
+       SCPI_ERR_RANGE = 6, /* Value out of range */
+       SCPI_ERR_TIMEOUT = 7, /* Timeout has occurred */
+       SCPI_ERR_NOMEM = 8, /* Invalid memory area or pointer */
+       SCPI_ERR_PWRSTATE = 9, /* Invalid power state */
+       SCPI_ERR_SUPPORT = 10, /* Not supported or disabled */
+       SCPI_ERR_DEVICE = 11, /* Device error */
+       SCPI_ERR_BUSY = 12, /* Device busy */
+       SCPI_ERR_MAX
+};
+
+enum scpi_std_cmd {
+       SCPI_CMD_INVALID                = 0x00,
+       SCPI_CMD_SCPI_READY             = 0x01,
+       SCPI_CMD_SCPI_CAPABILITIES      = 0x02,
+       SCPI_CMD_SET_CSS_PWR_STATE      = 0x03,
+       SCPI_CMD_GET_CSS_PWR_STATE      = 0x04,
+       SCPI_CMD_SET_SYS_PWR_STATE      = 0x05,
+       SCPI_CMD_SET_CPU_TIMER          = 0x06,
+       SCPI_CMD_CANCEL_CPU_TIMER       = 0x07,
+       SCPI_CMD_DVFS_CAPABILITIES      = 0x08,
+       SCPI_CMD_GET_DVFS_INFO          = 0x09,
+       SCPI_CMD_SET_DVFS               = 0x0a,
+       SCPI_CMD_GET_DVFS               = 0x0b,
+       SCPI_CMD_GET_DVFS_STAT          = 0x0c,
+       SCPI_CMD_CLOCK_CAPABILITIES     = 0x0d,
+       SCPI_CMD_GET_CLOCK_INFO         = 0x0e,
+       SCPI_CMD_SET_CLOCK_VALUE        = 0x0f,
+       SCPI_CMD_GET_CLOCK_VALUE        = 0x10,
+       SCPI_CMD_PSU_CAPABILITIES       = 0x11,
+       SCPI_CMD_GET_PSU_INFO           = 0x12,
+       SCPI_CMD_SET_PSU                = 0x13,
+       SCPI_CMD_GET_PSU                = 0x14,
+       SCPI_CMD_SENSOR_CAPABILITIES    = 0x15,
+       SCPI_CMD_SENSOR_INFO            = 0x16,
+       SCPI_CMD_SENSOR_VALUE           = 0x17,
+       SCPI_CMD_SENSOR_CFG_PERIODIC    = 0x18,
+       SCPI_CMD_SENSOR_CFG_BOUNDS      = 0x19,
+       SCPI_CMD_SENSOR_ASYNC_VALUE     = 0x1a,
+       SCPI_CMD_SET_DEVICE_PWR_STATE   = 0x1b,
+       SCPI_CMD_GET_DEVICE_PWR_STATE   = 0x1c,
+       SCPI_CMD_COUNT
+};
+
+struct scpi_xfer {
+       u32 slot; /* has to be first element */
+       u32 cmd;
+       u32 status;
+       const void *tx_buf;
+       void *rx_buf;
+       unsigned int tx_len;
+       unsigned int rx_len;
+       struct list_head node;
+       struct completion done;
+};
+
+struct scpi_chan {
+       struct mbox_client cl;
+       struct mbox_chan *chan;
+       void __iomem *tx_payload;
+       void __iomem *rx_payload;
+       struct list_head rx_pending;
+       struct list_head xfers_list;
+       struct scpi_xfer *xfers;
+       spinlock_t rx_lock; /* locking for the rx pending list */
+       struct mutex xfers_lock;
+       u8 token;
+};
+
+struct scpi_drvinfo {
+       u32 protocol_version;
+       u32 firmware_version;
+       int num_chans;
+       atomic_t next_chan;
+       struct scpi_ops *scpi_ops;
+       struct scpi_chan *channels;
+       struct scpi_dvfs_info *dvfs[MAX_DVFS_DOMAINS];
+};
+
+/*
+ * The SCP firmware only executes in little-endian mode, so any buffers
+ * shared through SCPI should have their contents converted to little-endian
+ */
+struct scpi_shared_mem {
+       __le32 command;
+       __le32 status;
+       u8 payload[0];
+} __packed;
+
+struct scp_capabilities {
+       __le32 protocol_version;
+       __le32 event_version;
+       __le32 platform_version;
+       __le32 commands[4];
+} __packed;
+
+struct clk_get_info {
+       __le16 id;
+       __le16 flags;
+       __le32 min_rate;
+       __le32 max_rate;
+       u8 name[20];
+} __packed;
+
+struct clk_get_value {
+       __le32 rate;
+} __packed;
+
+struct clk_set_value {
+       __le16 id;
+       __le16 reserved;
+       __le32 rate;
+} __packed;
+
+struct dvfs_info {
+       __le32 header;
+       struct {
+               __le32 freq;
+               __le32 m_volt;
+       } opps[MAX_DVFS_OPPS];
+} __packed;
+
+struct dvfs_get {
+       u8 index;
+} __packed;
+
+struct dvfs_set {
+       u8 domain;
+       u8 index;
+} __packed;
+
+struct sensor_capabilities {
+       __le16 sensors;
+} __packed;
+
+struct _scpi_sensor_info {
+       __le16 sensor_id;
+       u8 class;
+       u8 trigger_type;
+       char name[20];
+};
+
+struct sensor_value {
+       __le32 val;
+} __packed;
+
+static struct scpi_drvinfo *scpi_info;
+
+static int scpi_linux_errmap[SCPI_ERR_MAX] = {
+       /* better than switch case as long as return value is continuous */
+       0, /* SCPI_SUCCESS */
+       -EINVAL, /* SCPI_ERR_PARAM */
+       -ENOEXEC, /* SCPI_ERR_ALIGN */
+       -EMSGSIZE, /* SCPI_ERR_SIZE */
+       -EINVAL, /* SCPI_ERR_HANDLER */
+       -EACCES, /* SCPI_ERR_ACCESS */
+       -ERANGE, /* SCPI_ERR_RANGE */
+       -ETIMEDOUT, /* SCPI_ERR_TIMEOUT */
+       -ENOMEM, /* SCPI_ERR_NOMEM */
+       -EINVAL, /* SCPI_ERR_PWRSTATE */
+       -EOPNOTSUPP, /* SCPI_ERR_SUPPORT */
+       -EIO, /* SCPI_ERR_DEVICE */
+       -EBUSY, /* SCPI_ERR_BUSY */
+};
+
+static inline int scpi_to_linux_errno(int errno)
+{
+       if (errno >= SCPI_SUCCESS && errno < SCPI_ERR_MAX)
+               return scpi_linux_errmap[errno];
+       return -EIO;
+}
+
+static void scpi_process_cmd(struct scpi_chan *ch, u32 cmd)
+{
+       unsigned long flags;
+       struct scpi_xfer *t, *match = NULL;
+
+       spin_lock_irqsave(&ch->rx_lock, flags);
+       if (list_empty(&ch->rx_pending)) {
+               spin_unlock_irqrestore(&ch->rx_lock, flags);
+               return;
+       }
+
+       list_for_each_entry(t, &ch->rx_pending, node)
+               if (CMD_XTRACT_UNIQ(t->cmd) == CMD_XTRACT_UNIQ(cmd)) {
+                       list_del(&t->node);
+                       match = t;
+                       break;
+               }
+       /* check if wait_for_completion is in progress or timed-out */
+       if (match && !completion_done(&match->done)) {
+               struct scpi_shared_mem *mem = ch->rx_payload;
+               unsigned int len = min(match->rx_len, CMD_SIZE(cmd));
+
+               match->status = le32_to_cpu(mem->status);
+               memcpy_fromio(match->rx_buf, mem->payload, len);
+               if (match->rx_len > len)
+                       memset(match->rx_buf + len, 0, match->rx_len - len);
+               complete(&match->done);
+       }
+       spin_unlock_irqrestore(&ch->rx_lock, flags);
+}
+
+static void scpi_handle_remote_msg(struct mbox_client *c, void *msg)
+{
+       struct scpi_chan *ch = container_of(c, struct scpi_chan, cl);
+       struct scpi_shared_mem *mem = ch->rx_payload;
+       u32 cmd = le32_to_cpu(mem->command);
+
+       scpi_process_cmd(ch, cmd);
+}
+
+static void scpi_tx_prepare(struct mbox_client *c, void *msg)
+{
+       unsigned long flags;
+       struct scpi_xfer *t = msg;
+       struct scpi_chan *ch = container_of(c, struct scpi_chan, cl);
+       struct scpi_shared_mem *mem = (struct scpi_shared_mem *)ch->tx_payload;
+
+       if (t->tx_buf)
+               memcpy_toio(mem->payload, t->tx_buf, t->tx_len);
+       if (t->rx_buf) {
+               if (!(++ch->token))
+                       ++ch->token;
+               ADD_SCPI_TOKEN(t->cmd, ch->token);
+               spin_lock_irqsave(&ch->rx_lock, flags);
+               list_add_tail(&t->node, &ch->rx_pending);
+               spin_unlock_irqrestore(&ch->rx_lock, flags);
+       }
+       mem->command = cpu_to_le32(t->cmd);
+}
+
+static struct scpi_xfer *get_scpi_xfer(struct scpi_chan *ch)
+{
+       struct scpi_xfer *t;
+
+       mutex_lock(&ch->xfers_lock);
+       if (list_empty(&ch->xfers_list)) {
+               mutex_unlock(&ch->xfers_lock);
+               return NULL;
+       }
+       t = list_first_entry(&ch->xfers_list, struct scpi_xfer, node);
+       list_del(&t->node);
+       mutex_unlock(&ch->xfers_lock);
+       return t;
+}
+
+static void put_scpi_xfer(struct scpi_xfer *t, struct scpi_chan *ch)
+{
+       mutex_lock(&ch->xfers_lock);
+       list_add_tail(&t->node, &ch->xfers_list);
+       mutex_unlock(&ch->xfers_lock);
+}
+
+static int scpi_send_message(u8 cmd, void *tx_buf, unsigned int tx_len,
+                            void *rx_buf, unsigned int rx_len)
+{
+       int ret;
+       u8 chan;
+       struct scpi_xfer *msg;
+       struct scpi_chan *scpi_chan;
+
+       chan = atomic_inc_return(&scpi_info->next_chan) % scpi_info->num_chans;
+       scpi_chan = scpi_info->channels + chan;
+
+       msg = get_scpi_xfer(scpi_chan);
+       if (!msg)
+               return -ENOMEM;
+
+       msg->slot = BIT(SCPI_SLOT);
+       msg->cmd = PACK_SCPI_CMD(cmd, tx_len);
+       msg->tx_buf = tx_buf;
+       msg->tx_len = tx_len;
+       msg->rx_buf = rx_buf;
+       msg->rx_len = rx_len;
+       init_completion(&msg->done);
+
+       ret = mbox_send_message(scpi_chan->chan, msg);
+       if (ret < 0 || !rx_buf)
+               goto out;
+
+       if (!wait_for_completion_timeout(&msg->done, MAX_RX_TIMEOUT))
+               ret = -ETIMEDOUT;
+       else
+               /* first status word */
+               ret = le32_to_cpu(msg->status);
+out:
+       if (ret < 0 && rx_buf) /* remove entry from the list if timed-out */
+               scpi_process_cmd(scpi_chan, msg->cmd);
+
+       put_scpi_xfer(msg, scpi_chan);
+       /* SCPI error codes > 0, translate them to Linux scale*/
+       return ret > 0 ? scpi_to_linux_errno(ret) : ret;
+}
+
+static u32 scpi_get_version(void)
+{
+       return scpi_info->protocol_version;
+}
+
+static int
+scpi_clk_get_range(u16 clk_id, unsigned long *min, unsigned long *max)
+{
+       int ret;
+       struct clk_get_info clk;
+       __le16 le_clk_id = cpu_to_le16(clk_id);
+
+       ret = scpi_send_message(SCPI_CMD_GET_CLOCK_INFO, &le_clk_id,
+                               sizeof(le_clk_id), &clk, sizeof(clk));
+       if (!ret) {
+               *min = le32_to_cpu(clk.min_rate);
+               *max = le32_to_cpu(clk.max_rate);
+       }
+       return ret;
+}
+
+static unsigned long scpi_clk_get_val(u16 clk_id)
+{
+       int ret;
+       struct clk_get_value clk;
+       __le16 le_clk_id = cpu_to_le16(clk_id);
+
+       ret = scpi_send_message(SCPI_CMD_GET_CLOCK_VALUE, &le_clk_id,
+                               sizeof(le_clk_id), &clk, sizeof(clk));
+       return ret ? ret : le32_to_cpu(clk.rate);
+}
+
+static int scpi_clk_set_val(u16 clk_id, unsigned long rate)
+{
+       int stat;
+       struct clk_set_value clk = {
+               .id = cpu_to_le16(clk_id),
+               .rate = cpu_to_le32(rate)
+       };
+
+       return scpi_send_message(SCPI_CMD_SET_CLOCK_VALUE, &clk, sizeof(clk),
+                                &stat, sizeof(stat));
+}
+
+static int scpi_dvfs_get_idx(u8 domain)
+{
+       int ret;
+       struct dvfs_get dvfs;
+
+       ret = scpi_send_message(SCPI_CMD_GET_DVFS, &domain, sizeof(domain),
+                               &dvfs, sizeof(dvfs));
+       return ret ? ret : dvfs.index;
+}
+
+static int scpi_dvfs_set_idx(u8 domain, u8 index)
+{
+       int stat;
+       struct dvfs_set dvfs = {domain, index};
+
+       return scpi_send_message(SCPI_CMD_SET_DVFS, &dvfs, sizeof(dvfs),
+                                &stat, sizeof(stat));
+}
+
+static int opp_cmp_func(const void *opp1, const void *opp2)
+{
+       const struct scpi_opp *t1 = opp1, *t2 = opp2;
+
+       return t1->freq - t2->freq;
+}
+
+static struct scpi_dvfs_info *scpi_dvfs_get_info(u8 domain)
+{
+       struct scpi_dvfs_info *info;
+       struct scpi_opp *opp;
+       struct dvfs_info buf;
+       int ret, i;
+
+       if (domain >= MAX_DVFS_DOMAINS)
+               return ERR_PTR(-EINVAL);
+
+       if (scpi_info->dvfs[domain])    /* data already populated */
+               return scpi_info->dvfs[domain];
+
+       ret = scpi_send_message(SCPI_CMD_GET_DVFS_INFO, &domain, sizeof(domain),
+                               &buf, sizeof(buf));
+
+       if (ret)
+               return ERR_PTR(ret);
+
+       info = kmalloc(sizeof(*info), GFP_KERNEL);
+       if (!info)
+               return ERR_PTR(-ENOMEM);
+
+       info->count = DVFS_OPP_COUNT(buf.header);
+       info->latency = DVFS_LATENCY(buf.header) * 1000; /* uS to nS */
+
+       info->opps = kcalloc(info->count, sizeof(*opp), GFP_KERNEL);
+       if (!info->opps) {
+               kfree(info);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       for (i = 0, opp = info->opps; i < info->count; i++, opp++) {
+               opp->freq = le32_to_cpu(buf.opps[i].freq);
+               opp->m_volt = le32_to_cpu(buf.opps[i].m_volt);
+       }
+
+       sort(info->opps, info->count, sizeof(*opp), opp_cmp_func, NULL);
+
+       scpi_info->dvfs[domain] = info;
+       return info;
+}
+
+static int scpi_sensor_get_capability(u16 *sensors)
+{
+       struct sensor_capabilities cap_buf;
+       int ret;
+
+       ret = scpi_send_message(SCPI_CMD_SENSOR_CAPABILITIES, NULL, 0, &cap_buf,
+                               sizeof(cap_buf));
+       if (!ret)
+               *sensors = le16_to_cpu(cap_buf.sensors);
+
+       return ret;
+}
+
+static int scpi_sensor_get_info(u16 sensor_id, struct scpi_sensor_info *info)
+{
+       __le16 id = cpu_to_le16(sensor_id);
+       struct _scpi_sensor_info _info;
+       int ret;
+
+       ret = scpi_send_message(SCPI_CMD_SENSOR_INFO, &id, sizeof(id),
+                               &_info, sizeof(_info));
+       if (!ret) {
+               memcpy(info, &_info, sizeof(*info));
+               info->sensor_id = le16_to_cpu(_info.sensor_id);
+       }
+
+       return ret;
+}
+
+int scpi_sensor_get_value(u16 sensor, u32 *val)
+{
+       struct sensor_value buf;
+       int ret;
+
+       ret = scpi_send_message(SCPI_CMD_SENSOR_VALUE, &sensor, sizeof(sensor),
+                               &buf, sizeof(buf));
+       if (!ret)
+               *val = le32_to_cpu(buf.val);
+
+       return ret;
+}
+
+static struct scpi_ops scpi_ops = {
+       .get_version = scpi_get_version,
+       .clk_get_range = scpi_clk_get_range,
+       .clk_get_val = scpi_clk_get_val,
+       .clk_set_val = scpi_clk_set_val,
+       .dvfs_get_idx = scpi_dvfs_get_idx,
+       .dvfs_set_idx = scpi_dvfs_set_idx,
+       .dvfs_get_info = scpi_dvfs_get_info,
+       .sensor_get_capability = scpi_sensor_get_capability,
+       .sensor_get_info = scpi_sensor_get_info,
+       .sensor_get_value = scpi_sensor_get_value,
+};
+
+struct scpi_ops *get_scpi_ops(void)
+{
+       return scpi_info ? scpi_info->scpi_ops : NULL;
+}
+EXPORT_SYMBOL_GPL(get_scpi_ops);
+
+static int scpi_init_versions(struct scpi_drvinfo *info)
+{
+       int ret;
+       struct scp_capabilities caps;
+
+       ret = scpi_send_message(SCPI_CMD_SCPI_CAPABILITIES, NULL, 0,
+                               &caps, sizeof(caps));
+       if (!ret) {
+               info->protocol_version = le32_to_cpu(caps.protocol_version);
+               info->firmware_version = le32_to_cpu(caps.platform_version);
+       }
+       return ret;
+}
+
+static ssize_t protocol_version_show(struct device *dev,
+                                    struct device_attribute *attr, char *buf)
+{
+       struct scpi_drvinfo *scpi_info = dev_get_drvdata(dev);
+
+       return sprintf(buf, "%d.%d\n",
+                      PROTOCOL_REV_MAJOR(scpi_info->protocol_version),
+                      PROTOCOL_REV_MINOR(scpi_info->protocol_version));
+}
+static DEVICE_ATTR_RO(protocol_version);
+
+static ssize_t firmware_version_show(struct device *dev,
+                                    struct device_attribute *attr, char *buf)
+{
+       struct scpi_drvinfo *scpi_info = dev_get_drvdata(dev);
+
+       return sprintf(buf, "%d.%d.%d\n",
+                      FW_REV_MAJOR(scpi_info->firmware_version),
+                      FW_REV_MINOR(scpi_info->firmware_version),
+                      FW_REV_PATCH(scpi_info->firmware_version));
+}
+static DEVICE_ATTR_RO(firmware_version);
+
+static struct attribute *versions_attrs[] = {
+       &dev_attr_firmware_version.attr,
+       &dev_attr_protocol_version.attr,
+       NULL,
+};
+ATTRIBUTE_GROUPS(versions);
+
+static void
+scpi_free_channels(struct device *dev, struct scpi_chan *pchan, int count)
+{
+       int i;
+
+       for (i = 0; i < count && pchan->chan; i++, pchan++) {
+               mbox_free_channel(pchan->chan);
+               devm_kfree(dev, pchan->xfers);
+               devm_iounmap(dev, pchan->rx_payload);
+       }
+}
+
+static int scpi_remove(struct platform_device *pdev)
+{
+       int i;
+       struct device *dev = &pdev->dev;
+       struct scpi_drvinfo *info = platform_get_drvdata(pdev);
+
+       scpi_info = NULL; /* stop exporting SCPI ops through get_scpi_ops */
+
+       of_platform_depopulate(dev);
+       sysfs_remove_groups(&dev->kobj, versions_groups);
+       scpi_free_channels(dev, info->channels, info->num_chans);
+       platform_set_drvdata(pdev, NULL);
+
+       for (i = 0; i < MAX_DVFS_DOMAINS && info->dvfs[i]; i++) {
+               kfree(info->dvfs[i]->opps);
+               kfree(info->dvfs[i]);
+       }
+       devm_kfree(dev, info->channels);
+       devm_kfree(dev, info);
+
+       return 0;
+}
+
+#define MAX_SCPI_XFERS         10
+static int scpi_alloc_xfer_list(struct device *dev, struct scpi_chan *ch)
+{
+       int i;
+       struct scpi_xfer *xfers;
+
+       xfers = devm_kzalloc(dev, MAX_SCPI_XFERS * sizeof(*xfers), GFP_KERNEL);
+       if (!xfers)
+               return -ENOMEM;
+
+       ch->xfers = xfers;
+       for (i = 0; i < MAX_SCPI_XFERS; i++, xfers++)
+               list_add_tail(&xfers->node, &ch->xfers_list);
+       return 0;
+}
+
+static int scpi_probe(struct platform_device *pdev)
+{
+       int count, idx, ret;
+       struct resource res;
+       struct scpi_chan *scpi_chan;
+       struct device *dev = &pdev->dev;
+       struct device_node *np = dev->of_node;
+
+       scpi_info = devm_kzalloc(dev, sizeof(*scpi_info), GFP_KERNEL);
+       if (!scpi_info)
+               return -ENOMEM;
+
+       count = of_count_phandle_with_args(np, "mboxes", "#mbox-cells");
+       if (count < 0) {
+               dev_err(dev, "no mboxes property in '%s'\n", np->full_name);
+               return -ENODEV;
+       }
+
+       scpi_chan = devm_kcalloc(dev, count, sizeof(*scpi_chan), GFP_KERNEL);
+       if (!scpi_chan)
+               return -ENOMEM;
+
+       for (idx = 0; idx < count; idx++) {
+               resource_size_t size;
+               struct scpi_chan *pchan = scpi_chan + idx;
+               struct mbox_client *cl = &pchan->cl;
+               struct device_node *shmem = of_parse_phandle(np, "shmem", idx);
+
+               if (of_address_to_resource(shmem, 0, &res)) {
+                       dev_err(dev, "failed to get SCPI payload mem resource\n");
+                       ret = -EINVAL;
+                       goto err;
+               }
+
+               size = resource_size(&res);
+               pchan->rx_payload = devm_ioremap(dev, res.start, size);
+               if (!pchan->rx_payload) {
+                       dev_err(dev, "failed to ioremap SCPI payload\n");
+                       ret = -EADDRNOTAVAIL;
+                       goto err;
+               }
+               pchan->tx_payload = pchan->rx_payload + (size >> 1);
+
+               cl->dev = dev;
+               cl->rx_callback = scpi_handle_remote_msg;
+               cl->tx_prepare = scpi_tx_prepare;
+               cl->tx_block = true;
+               cl->tx_tout = 50;
+               cl->knows_txdone = false; /* controller can't ack */
+
+               INIT_LIST_HEAD(&pchan->rx_pending);
+               INIT_LIST_HEAD(&pchan->xfers_list);
+               spin_lock_init(&pchan->rx_lock);
+               mutex_init(&pchan->xfers_lock);
+
+               ret = scpi_alloc_xfer_list(dev, pchan);
+               if (!ret) {
+                       pchan->chan = mbox_request_channel(cl, idx);
+                       if (!IS_ERR(pchan->chan))
+                               continue;
+                       ret = PTR_ERR(pchan->chan);
+                       if (ret != -EPROBE_DEFER)
+                               dev_err(dev, "failed to get channel%d err %d\n",
+                                       idx, ret);
+               }
+err:
+               scpi_free_channels(dev, scpi_chan, idx);
+               scpi_info = NULL;
+               return ret;
+       }
+
+       scpi_info->channels = scpi_chan;
+       scpi_info->num_chans = count;
+       platform_set_drvdata(pdev, scpi_info);
+
+       ret = scpi_init_versions(scpi_info);
+       if (ret) {
+               dev_err(dev, "incorrect or no SCP firmware found\n");
+               scpi_remove(pdev);
+               return ret;
+       }
+
+       _dev_info(dev, "SCP Protocol %d.%d Firmware %d.%d.%d version\n",
+                 PROTOCOL_REV_MAJOR(scpi_info->protocol_version),
+                 PROTOCOL_REV_MINOR(scpi_info->protocol_version),
+                 FW_REV_MAJOR(scpi_info->firmware_version),
+                 FW_REV_MINOR(scpi_info->firmware_version),
+                 FW_REV_PATCH(scpi_info->firmware_version));
+       scpi_info->scpi_ops = &scpi_ops;
+
+       ret = sysfs_create_groups(&dev->kobj, versions_groups);
+       if (ret)
+               dev_err(dev, "unable to create sysfs version group\n");
+
+       return of_platform_populate(dev->of_node, NULL, NULL, dev);
+}
+
+static const struct of_device_id scpi_of_match[] = {
+       {.compatible = "arm,scpi"},
+       {},
+};
+
+MODULE_DEVICE_TABLE(of, scpi_of_match);
+
+static struct platform_driver scpi_driver = {
+       .driver = {
+               .name = "scpi_protocol",
+               .of_match_table = scpi_of_match,
+       },
+       .probe = scpi_probe,
+       .remove = scpi_remove,
+};
+module_platform_driver(scpi_driver);
+
+MODULE_AUTHOR("Sudeep Holla <sudeep.holla@arm.com>");
+MODULE_DESCRIPTION("ARM SCPI mailbox protocol driver");
+MODULE_LICENSE("GPL v2");
index 42700f09a8c5845f418709c8802c08d6043c2f10..d24f35d74b27079afeae5c08d601c3bcd899dee6 100644 (file)
 #include <linux/printk.h>
 #include <linux/psci.h>
 #include <linux/reboot.h>
+#include <linux/suspend.h>
 
 #include <uapi/linux/psci.h>
 
 #include <asm/cputype.h>
 #include <asm/system_misc.h>
 #include <asm/smp_plat.h>
+#include <asm/suspend.h>
 
 /*
  * While a 64-bit OS can make calls with SMC32 calling conventions, for some
- * calls it is necessary to use SMC64 to pass or return 64-bit values. For such
- * calls PSCI_0_2_FN_NATIVE(x) will choose the appropriate (native-width)
- * function ID.
+ * calls it is necessary to use SMC64 to pass or return 64-bit values.
+ * For such calls PSCI_FN_NATIVE(version, name) will choose the appropriate
+ * (native-width) function ID.
  */
 #ifdef CONFIG_64BIT
-#define PSCI_0_2_FN_NATIVE(name)       PSCI_0_2_FN64_##name
+#define PSCI_FN_NATIVE(version, name)  PSCI_##version##_FN64_##name
 #else
-#define PSCI_0_2_FN_NATIVE(name)       PSCI_0_2_FN_##name
+#define PSCI_FN_NATIVE(version, name)  PSCI_##version##_FN_##name
 #endif
 
 /*
@@ -70,6 +72,41 @@ enum psci_function {
 
 static u32 psci_function_id[PSCI_FN_MAX];
 
+#define PSCI_0_2_POWER_STATE_MASK              \
+                               (PSCI_0_2_POWER_STATE_ID_MASK | \
+                               PSCI_0_2_POWER_STATE_TYPE_MASK | \
+                               PSCI_0_2_POWER_STATE_AFFL_MASK)
+
+#define PSCI_1_0_EXT_POWER_STATE_MASK          \
+                               (PSCI_1_0_EXT_POWER_STATE_ID_MASK | \
+                               PSCI_1_0_EXT_POWER_STATE_TYPE_MASK)
+
+static u32 psci_cpu_suspend_feature;
+
+static inline bool psci_has_ext_power_state(void)
+{
+       return psci_cpu_suspend_feature &
+                               PSCI_1_0_FEATURES_CPU_SUSPEND_PF_MASK;
+}
+
+bool psci_power_state_loses_context(u32 state)
+{
+       const u32 mask = psci_has_ext_power_state() ?
+                                       PSCI_1_0_EXT_POWER_STATE_TYPE_MASK :
+                                       PSCI_0_2_POWER_STATE_TYPE_MASK;
+
+       return state & mask;
+}
+
+bool psci_power_state_is_valid(u32 state)
+{
+       const u32 valid_mask = psci_has_ext_power_state() ?
+                              PSCI_1_0_EXT_POWER_STATE_MASK :
+                              PSCI_0_2_POWER_STATE_MASK;
+
+       return !(state & ~valid_mask);
+}
+
 static int psci_to_linux_errno(int errno)
 {
        switch (errno) {
@@ -78,6 +115,7 @@ static int psci_to_linux_errno(int errno)
        case PSCI_RET_NOT_SUPPORTED:
                return -EOPNOTSUPP;
        case PSCI_RET_INVALID_PARAMS:
+       case PSCI_RET_INVALID_ADDRESS:
                return -EINVAL;
        case PSCI_RET_DENIED:
                return -EPERM;
@@ -134,7 +172,7 @@ static int psci_migrate(unsigned long cpuid)
 static int psci_affinity_info(unsigned long target_affinity,
                unsigned long lowest_affinity_level)
 {
-       return invoke_psci_fn(PSCI_0_2_FN_NATIVE(AFFINITY_INFO),
+       return invoke_psci_fn(PSCI_FN_NATIVE(0_2, AFFINITY_INFO),
                              target_affinity, lowest_affinity_level, 0);
 }
 
@@ -145,7 +183,7 @@ static int psci_migrate_info_type(void)
 
 static unsigned long psci_migrate_info_up_cpu(void)
 {
-       return invoke_psci_fn(PSCI_0_2_FN_NATIVE(MIGRATE_INFO_UP_CPU),
+       return invoke_psci_fn(PSCI_FN_NATIVE(0_2, MIGRATE_INFO_UP_CPU),
                              0, 0, 0);
 }
 
@@ -181,6 +219,49 @@ static void psci_sys_poweroff(void)
        invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0);
 }
 
+static int __init psci_features(u32 psci_func_id)
+{
+       return invoke_psci_fn(PSCI_1_0_FN_PSCI_FEATURES,
+                             psci_func_id, 0, 0);
+}
+
+static int psci_system_suspend(unsigned long unused)
+{
+       return invoke_psci_fn(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND),
+                             virt_to_phys(cpu_resume), 0, 0);
+}
+
+static int psci_system_suspend_enter(suspend_state_t state)
+{
+       return cpu_suspend(0, psci_system_suspend);
+}
+
+static const struct platform_suspend_ops psci_suspend_ops = {
+       .valid          = suspend_valid_only_mem,
+       .enter          = psci_system_suspend_enter,
+};
+
+static void __init psci_init_system_suspend(void)
+{
+       int ret;
+
+       if (!IS_ENABLED(CONFIG_SUSPEND))
+               return;
+
+       ret = psci_features(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND));
+
+       if (ret != PSCI_RET_NOT_SUPPORTED)
+               suspend_set_ops(&psci_suspend_ops);
+}
+
+static void __init psci_init_cpu_suspend(void)
+{
+       int feature = psci_features(psci_function_id[PSCI_FN_CPU_SUSPEND]);
+
+       if (feature != PSCI_RET_NOT_SUPPORTED)
+               psci_cpu_suspend_feature = feature;
+}
+
 /*
  * Detect the presence of a resident Trusted OS which may cause CPU_OFF to
  * return DENIED (which would be fatal).
@@ -224,16 +305,17 @@ static void __init psci_init_migrate(void)
 static void __init psci_0_2_set_functions(void)
 {
        pr_info("Using standard PSCI v0.2 function IDs\n");
-       psci_function_id[PSCI_FN_CPU_SUSPEND] = PSCI_0_2_FN_NATIVE(CPU_SUSPEND);
+       psci_function_id[PSCI_FN_CPU_SUSPEND] =
+                                       PSCI_FN_NATIVE(0_2, CPU_SUSPEND);
        psci_ops.cpu_suspend = psci_cpu_suspend;
 
        psci_function_id[PSCI_FN_CPU_OFF] = PSCI_0_2_FN_CPU_OFF;
        psci_ops.cpu_off = psci_cpu_off;
 
-       psci_function_id[PSCI_FN_CPU_ON] = PSCI_0_2_FN_NATIVE(CPU_ON);
+       psci_function_id[PSCI_FN_CPU_ON] = PSCI_FN_NATIVE(0_2, CPU_ON);
        psci_ops.cpu_on = psci_cpu_on;
 
-       psci_function_id[PSCI_FN_MIGRATE] = PSCI_0_2_FN_NATIVE(MIGRATE);
+       psci_function_id[PSCI_FN_MIGRATE] = PSCI_FN_NATIVE(0_2, MIGRATE);
        psci_ops.migrate = psci_migrate;
 
        psci_ops.affinity_info = psci_affinity_info;
@@ -265,6 +347,11 @@ static int __init psci_probe(void)
 
        psci_init_migrate();
 
+       if (PSCI_VERSION_MAJOR(ver) >= 1) {
+               psci_init_cpu_suspend();
+               psci_init_system_suspend();
+       }
+
        return 0;
 }
 
@@ -340,6 +427,7 @@ out_put_node:
 static const struct of_device_id const psci_of_match[] __initconst = {
        { .compatible = "arm,psci",     .data = psci_0_1_init},
        { .compatible = "arm,psci-0.2", .data = psci_0_2_init},
+       { .compatible = "arm,psci-1.0", .data = psci_0_2_init},
        {},
 };
 
index 29e6850665eb344cbbc946273343ec13cef81e12..0883292f640f4d512c8b198d90a65ed945c02f87 100644 (file)
@@ -480,15 +480,15 @@ void __qcom_scm_cpu_power_down(u32 flags)
 int __qcom_scm_is_call_available(u32 svc_id, u32 cmd_id)
 {
        int ret;
-       u32 svc_cmd = (svc_id << 10) | cmd_id;
-       u32 ret_val = 0;
+       __le32 svc_cmd = cpu_to_le32((svc_id << 10) | cmd_id);
+       __le32 ret_val = 0;
 
        ret = qcom_scm_call(QCOM_SCM_SVC_INFO, QCOM_IS_CALL_AVAIL_CMD, &svc_cmd,
                        sizeof(svc_cmd), &ret_val, sizeof(ret_val));
        if (ret)
                return ret;
 
-       return ret_val;
+       return le32_to_cpu(ret_val);
 }
 
 int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp)
index e13c902e8966977581f1959155b3f83774e94aa5..50146bb69833fe99d0b852a57d39e3a7c9e241a7 100644 (file)
@@ -321,6 +321,14 @@ config SENSORS_APPLESMC
          Say Y here if you have an applicable laptop and want to experience
          the awesome power of applesmc.
 
+config SENSORS_ARM_SCPI
+       tristate "ARM SCPI Sensors"
+       depends on ARM_SCPI_PROTOCOL
+       help
+         This driver provides support for temperature, voltage, current
+         and power sensors available on ARM Ltd's SCP based platforms. The
+         actual number and type of sensors exported depend on the platform.
+
 config SENSORS_ASB100
        tristate "Asus ASB100 Bach"
        depends on X86 && I2C
index 9e0f3dd2841daaa1531acd3897c9077b2d18a09d..66e7a4715da7db42119221c586fa25aec4c505bc 100644 (file)
@@ -44,6 +44,7 @@ obj-$(CONFIG_SENSORS_ADT7462) += adt7462.o
 obj-$(CONFIG_SENSORS_ADT7470)  += adt7470.o
 obj-$(CONFIG_SENSORS_ADT7475)  += adt7475.o
 obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o
+obj-$(CONFIG_SENSORS_ARM_SCPI) += scpi-hwmon.o
 obj-$(CONFIG_SENSORS_ASC7621)  += asc7621.o
 obj-$(CONFIG_SENSORS_ATXP1)    += atxp1.o
 obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o
diff --git a/drivers/hwmon/scpi-hwmon.c b/drivers/hwmon/scpi-hwmon.c
new file mode 100644 (file)
index 0000000..2c1241b
--- /dev/null
@@ -0,0 +1,288 @@
+/*
+ * System Control and Power Interface(SCPI) based hwmon sensor driver
+ *
+ * Copyright (C) 2015 ARM Ltd.
+ * Punit Agrawal <punit.agrawal@arm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/hwmon.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/scpi_protocol.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/thermal.h>
+
+struct sensor_data {
+       struct scpi_sensor_info info;
+       struct device_attribute dev_attr_input;
+       struct device_attribute dev_attr_label;
+       char input[20];
+       char label[20];
+};
+
+struct scpi_thermal_zone {
+       struct list_head list;
+       int sensor_id;
+       struct scpi_sensors *scpi_sensors;
+       struct thermal_zone_device *tzd;
+};
+
+struct scpi_sensors {
+       struct scpi_ops *scpi_ops;
+       struct sensor_data *data;
+       struct list_head thermal_zones;
+       struct attribute **attrs;
+       struct attribute_group group;
+       const struct attribute_group *groups[2];
+};
+
+static int scpi_read_temp(void *dev, int *temp)
+{
+       struct scpi_thermal_zone *zone = dev;
+       struct scpi_sensors *scpi_sensors = zone->scpi_sensors;
+       struct scpi_ops *scpi_ops = scpi_sensors->scpi_ops;
+       struct sensor_data *sensor = &scpi_sensors->data[zone->sensor_id];
+       u32 value;
+       int ret;
+
+       ret = scpi_ops->sensor_get_value(sensor->info.sensor_id, &value);
+       if (ret)
+               return ret;
+
+       *temp = value;
+       return 0;
+}
+
+/* hwmon callback functions */
+static ssize_t
+scpi_show_sensor(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct scpi_sensors *scpi_sensors = dev_get_drvdata(dev);
+       struct scpi_ops *scpi_ops = scpi_sensors->scpi_ops;
+       struct sensor_data *sensor;
+       u32 value;
+       int ret;
+
+       sensor = container_of(attr, struct sensor_data, dev_attr_input);
+
+       ret = scpi_ops->sensor_get_value(sensor->info.sensor_id, &value);
+       if (ret)
+               return ret;
+
+       return sprintf(buf, "%u\n", value);
+}
+
+static ssize_t
+scpi_show_label(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct sensor_data *sensor;
+
+       sensor = container_of(attr, struct sensor_data, dev_attr_label);
+
+       return sprintf(buf, "%s\n", sensor->info.name);
+}
+
+static void
+unregister_thermal_zones(struct platform_device *pdev,
+                        struct scpi_sensors *scpi_sensors)
+{
+       struct list_head *pos;
+
+       list_for_each(pos, &scpi_sensors->thermal_zones) {
+               struct scpi_thermal_zone *zone;
+
+               zone = list_entry(pos, struct scpi_thermal_zone, list);
+               thermal_zone_of_sensor_unregister(&pdev->dev, zone->tzd);
+       }
+}
+
+static struct thermal_zone_of_device_ops scpi_sensor_ops = {
+       .get_temp = scpi_read_temp,
+};
+
+static int scpi_hwmon_probe(struct platform_device *pdev)
+{
+       u16 nr_sensors, i;
+       int num_temp = 0, num_volt = 0, num_current = 0, num_power = 0;
+       struct scpi_ops *scpi_ops;
+       struct device *hwdev, *dev = &pdev->dev;
+       struct scpi_sensors *scpi_sensors;
+       int ret;
+
+       scpi_ops = get_scpi_ops();
+       if (!scpi_ops)
+               return -EPROBE_DEFER;
+
+       ret = scpi_ops->sensor_get_capability(&nr_sensors);
+       if (ret)
+               return ret;
+
+       if (!nr_sensors)
+               return -ENODEV;
+
+       scpi_sensors = devm_kzalloc(dev, sizeof(*scpi_sensors), GFP_KERNEL);
+       if (!scpi_sensors)
+               return -ENOMEM;
+
+       scpi_sensors->data = devm_kcalloc(dev, nr_sensors,
+                                  sizeof(*scpi_sensors->data), GFP_KERNEL);
+       if (!scpi_sensors->data)
+               return -ENOMEM;
+
+       scpi_sensors->attrs = devm_kcalloc(dev, (nr_sensors * 2) + 1,
+                                  sizeof(*scpi_sensors->attrs), GFP_KERNEL);
+       if (!scpi_sensors->attrs)
+               return -ENOMEM;
+
+       scpi_sensors->scpi_ops = scpi_ops;
+
+       for (i = 0; i < nr_sensors; i++) {
+               struct sensor_data *sensor = &scpi_sensors->data[i];
+
+               ret = scpi_ops->sensor_get_info(i, &sensor->info);
+               if (ret)
+                       return ret;
+
+               switch (sensor->info.class) {
+               case TEMPERATURE:
+                       snprintf(sensor->input, sizeof(sensor->input),
+                                "temp%d_input", num_temp + 1);
+                       snprintf(sensor->label, sizeof(sensor->input),
+                                "temp%d_label", num_temp + 1);
+                       num_temp++;
+                       break;
+               case VOLTAGE:
+                       snprintf(sensor->input, sizeof(sensor->input),
+                                "in%d_input", num_volt);
+                       snprintf(sensor->label, sizeof(sensor->input),
+                                "in%d_label", num_volt);
+                       num_volt++;
+                       break;
+               case CURRENT:
+                       snprintf(sensor->input, sizeof(sensor->input),
+                                "curr%d_input", num_current + 1);
+                       snprintf(sensor->label, sizeof(sensor->input),
+                                "curr%d_label", num_current + 1);
+                       num_current++;
+                       break;
+               case POWER:
+                       snprintf(sensor->input, sizeof(sensor->input),
+                                "power%d_input", num_power + 1);
+                       snprintf(sensor->label, sizeof(sensor->input),
+                                "power%d_label", num_power + 1);
+                       num_power++;
+                       break;
+               default:
+                       break;
+               }
+
+               sensor->dev_attr_input.attr.mode = S_IRUGO;
+               sensor->dev_attr_input.show = scpi_show_sensor;
+               sensor->dev_attr_input.attr.name = sensor->input;
+
+               sensor->dev_attr_label.attr.mode = S_IRUGO;
+               sensor->dev_attr_label.show = scpi_show_label;
+               sensor->dev_attr_label.attr.name = sensor->label;
+
+               scpi_sensors->attrs[i << 1] = &sensor->dev_attr_input.attr;
+               scpi_sensors->attrs[(i << 1) + 1] = &sensor->dev_attr_label.attr;
+
+               sysfs_attr_init(scpi_sensors->attrs[i << 1]);
+               sysfs_attr_init(scpi_sensors->attrs[(i << 1) + 1]);
+       }
+
+       scpi_sensors->group.attrs = scpi_sensors->attrs;
+       scpi_sensors->groups[0] = &scpi_sensors->group;
+
+       platform_set_drvdata(pdev, scpi_sensors);
+
+       hwdev = devm_hwmon_device_register_with_groups(dev,
+                       "scpi_sensors", scpi_sensors, scpi_sensors->groups);
+
+       if (IS_ERR(hwdev))
+               return PTR_ERR(hwdev);
+
+       /*
+        * Register the temperature sensors with the thermal framework
+        * to allow their usage in setting up the thermal zones from
+        * device tree.
+        *
+        * NOTE: Not all temperature sensors maybe used for thermal
+        * control
+        */
+       INIT_LIST_HEAD(&scpi_sensors->thermal_zones);
+       for (i = 0; i < nr_sensors; i++) {
+               struct sensor_data *sensor = &scpi_sensors->data[i];
+               struct scpi_thermal_zone *zone;
+
+               if (sensor->info.class != TEMPERATURE)
+                       continue;
+
+               zone = devm_kzalloc(dev, sizeof(*zone), GFP_KERNEL);
+               if (!zone) {
+                       ret = -ENOMEM;
+                       goto unregister_tzd;
+               }
+
+               zone->sensor_id = i;
+               zone->scpi_sensors = scpi_sensors;
+               zone->tzd = thermal_zone_of_sensor_register(dev, i, zone,
+                                                           &scpi_sensor_ops);
+               /*
+                * The call to thermal_zone_of_sensor_register returns
+                * an error for sensors that are not associated with
+                * any thermal zones or if the thermal subsystem is
+                * not configured.
+                */
+               if (IS_ERR(zone->tzd)) {
+                       devm_kfree(dev, zone);
+                       continue;
+               }
+               list_add(&zone->list, &scpi_sensors->thermal_zones);
+       }
+
+       return 0;
+
+unregister_tzd:
+       unregister_thermal_zones(pdev, scpi_sensors);
+       return ret;
+}
+
+static int scpi_hwmon_remove(struct platform_device *pdev)
+{
+       struct scpi_sensors *scpi_sensors = platform_get_drvdata(pdev);
+
+       unregister_thermal_zones(pdev, scpi_sensors);
+
+       return 0;
+}
+
+static const struct of_device_id scpi_of_match[] = {
+       {.compatible = "arm,scpi-sensors"},
+       {},
+};
+
+static struct platform_driver scpi_hwmon_platdrv = {
+       .driver = {
+               .name   = "scpi-hwmon",
+               .owner  = THIS_MODULE,
+               .of_match_table = scpi_of_match,
+       },
+       .probe          = scpi_hwmon_probe,
+       .remove         = scpi_hwmon_remove,
+};
+module_platform_driver(scpi_hwmon_platdrv);
+
+MODULE_AUTHOR("Punit Agrawal <punit.agrawal@arm.com>");
+MODULE_DESCRIPTION("ARM SCPI HWMON interface driver");
+MODULE_LICENSE("GPL v2");
index de36237d7c6b45de10fca57cc1870fde5a0620e5..051645498b53f8931e6f1db9a11aeb65e61ac2fd 100644 (file)
@@ -74,7 +74,7 @@ static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                ret = -ENOTSUPP;
                dev_err(&pdev->dev,
                        "IO mapped PCI devices are not supported\n");
-               goto out_release;
+               goto out_iounmap;
        }
 
        pci_set_drvdata(pdev, priv);
@@ -89,7 +89,7 @@ static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 
        ret = chameleon_parse_cells(priv->bus, priv->mapbase, priv->base);
        if (ret < 0)
-               goto out_iounmap;
+               goto out_mcb_bus;
        num_cells = ret;
 
        dev_dbg(&pdev->dev, "Found %d cells\n", num_cells);
@@ -98,6 +98,8 @@ static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 
        return 0;
 
+out_mcb_bus:
+       mcb_release_bus(priv->bus);
 out_iounmap:
        iounmap(priv->base);
 out_release:
index 240c9f0e85e74e864624f0cb972c5b4394eaf11f..8a096456579bead67b182f27e65956341a7c8d73 100644 (file)
@@ -436,7 +436,7 @@ static struct dm_cache_policy *wb_create(dm_cblock_t cache_size,
 static struct dm_cache_policy_type wb_policy_type = {
        .name = "cleaner",
        .version = {1, 0, 0},
-       .hint_size = 0,
+       .hint_size = 4,
        .owner = THIS_MODULE,
        .create = wb_create
 };
index ebaa4f803eec3a08a0cd9fcd9a9a1b933618c50c..192bb8beeb6b59e296d9a2e06c0ef8c0a9be8aeb 100644 (file)
@@ -203,7 +203,7 @@ int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
                return -EINVAL;
        }
 
-       tmp_store = kmalloc(sizeof(*tmp_store), GFP_KERNEL);
+       tmp_store = kzalloc(sizeof(*tmp_store), GFP_KERNEL);
        if (!tmp_store) {
                ti->error = "Exception store allocation failed";
                return -ENOMEM;
@@ -215,7 +215,7 @@ int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
        else if (persistent == 'N')
                type = get_type("N");
        else {
-               ti->error = "Persistent flag is not P or N";
+               ti->error = "Exception store type is not P or N";
                r = -EINVAL;
                goto bad_type;
        }
@@ -233,7 +233,7 @@ int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
        if (r)
                goto bad;
 
-       r = type->ctr(tmp_store, 0, NULL);
+       r = type->ctr(tmp_store, (strlen(argv[0]) > 1 ? &argv[0][1] : NULL));
        if (r) {
                ti->error = "Exception store type constructor failed";
                goto bad;
index 0b2536247cf55a3215223b8b0c72ff29a629b87a..fae34e7a0b1e4e4d60b5867eff9422e432fba83b 100644 (file)
@@ -42,8 +42,7 @@ struct dm_exception_store_type {
        const char *name;
        struct module *module;
 
-       int (*ctr) (struct dm_exception_store *store,
-                   unsigned argc, char **argv);
+       int (*ctr) (struct dm_exception_store *store, char *options);
 
        /*
         * Destroys this object when you've finished with it.
@@ -123,6 +122,8 @@ struct dm_exception_store {
        unsigned chunk_shift;
 
        void *context;
+
+       bool userspace_supports_overflow;
 };
 
 /*
index 97e165183e79f2991f8191913e0b44fb91b00310..a0901214aef57de00419a14c573bc128431749c7 100644 (file)
@@ -329,8 +329,7 @@ static int validate_region_size(struct raid_set *rs, unsigned long region_size)
                 */
                if (min_region_size > (1 << 13)) {
                        /* If not a power of 2, make it the next power of 2 */
-                       if (min_region_size & (min_region_size - 1))
-                               region_size = 1 << fls(region_size);
+                       region_size = roundup_pow_of_two(min_region_size);
                        DMINFO("Choosing default region size of %lu sectors",
                               region_size);
                } else {
index bf71583296f732b6b78c71ae67dee5222824b2f8..aeacad9be51dcb1c10c78df1398abddb9e8bc4f1 100644 (file)
@@ -7,6 +7,7 @@
 
 #include "dm-exception-store.h"
 
+#include <linux/ctype.h>
 #include <linux/mm.h>
 #include <linux/pagemap.h>
 #include <linux/vmalloc.h>
@@ -843,8 +844,7 @@ static void persistent_drop_snapshot(struct dm_exception_store *store)
                DMWARN("write header failed");
 }
 
-static int persistent_ctr(struct dm_exception_store *store,
-                         unsigned argc, char **argv)
+static int persistent_ctr(struct dm_exception_store *store, char *options)
 {
        struct pstore *ps;
 
@@ -873,6 +873,16 @@ static int persistent_ctr(struct dm_exception_store *store,
                return -ENOMEM;
        }
 
+       if (options) {
+               char overflow = toupper(options[0]);
+               if (overflow == 'O')
+                       store->userspace_supports_overflow = true;
+               else {
+                       DMERR("Unsupported persistent store option: %s", options);
+                       return -EINVAL;
+               }
+       }
+
        store->context = ps;
 
        return 0;
@@ -888,7 +898,8 @@ static unsigned persistent_status(struct dm_exception_store *store,
        case STATUSTYPE_INFO:
                break;
        case STATUSTYPE_TABLE:
-               DMEMIT(" P %llu", (unsigned long long)store->chunk_size);
+               DMEMIT(" %s %llu", store->userspace_supports_overflow ? "PO" : "P",
+                      (unsigned long long)store->chunk_size);
        }
 
        return sz;
index 1ce9a2586e4134a79ec3289808f8229e9aaa2080..9b7c8c8049d6186f54bdfec114c43cb3ce4d77fa 100644 (file)
@@ -70,8 +70,7 @@ static void transient_usage(struct dm_exception_store *store,
        *metadata_sectors = 0;
 }
 
-static int transient_ctr(struct dm_exception_store *store,
-                        unsigned argc, char **argv)
+static int transient_ctr(struct dm_exception_store *store, char *options)
 {
        struct transient_c *tc;
 
index c0bcd6516dfe17f8e7a06ec8c66d1e1d5801f133..c06b74e91cd6aeef00ef4eefae9953d4d8c8f91b 100644 (file)
@@ -1098,7 +1098,7 @@ static void stop_merge(struct dm_snapshot *s)
 }
 
 /*
- * Construct a snapshot mapping: <origin_dev> <COW-dev> <p/n> <chunk-size>
+ * Construct a snapshot mapping: <origin_dev> <COW-dev> <p|po|n> <chunk-size>
  */
 static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 {
@@ -1302,6 +1302,7 @@ static void __handover_exceptions(struct dm_snapshot *snap_src,
 
        u.store_swap = snap_dest->store;
        snap_dest->store = snap_src->store;
+       snap_dest->store->userspace_supports_overflow = u.store_swap->userspace_supports_overflow;
        snap_src->store = u.store_swap;
 
        snap_dest->store->snap = snap_dest;
@@ -1739,8 +1740,11 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio)
 
                        pe = __find_pending_exception(s, pe, chunk);
                        if (!pe) {
-                               s->snapshot_overflowed = 1;
-                               DMERR("Snapshot overflowed: Unable to allocate exception.");
+                               if (s->store->userspace_supports_overflow) {
+                                       s->snapshot_overflowed = 1;
+                                       DMERR("Snapshot overflowed: Unable to allocate exception.");
+                               } else
+                                       __invalidate_snapshot(s, -ENOMEM);
                                r = -EIO;
                                goto out_unlock;
                        }
@@ -2365,7 +2369,7 @@ static struct target_type origin_target = {
 
 static struct target_type snapshot_target = {
        .name    = "snapshot",
-       .version = {1, 14, 0},
+       .version = {1, 15, 0},
        .module  = THIS_MODULE,
        .ctr     = snapshot_ctr,
        .dtr     = snapshot_dtr,
@@ -2379,7 +2383,7 @@ static struct target_type snapshot_target = {
 
 static struct target_type merge_target = {
        .name    = dm_snapshot_merge_target_name,
-       .version = {1, 3, 0},
+       .version = {1, 4, 0},
        .module  = THIS_MODULE,
        .ctr     = snapshot_ctr,
        .dtr     = snapshot_dtr,
index 6264781dc69a6066b88d719537c471b7d1cd7b27..1b5c6047e4f19882fbbe9facbc29aeee54dc8723 100644 (file)
@@ -1001,6 +1001,7 @@ static void end_clone_bio(struct bio *clone)
        struct dm_rq_target_io *tio = info->tio;
        struct bio *bio = info->orig;
        unsigned int nr_bytes = info->orig->bi_iter.bi_size;
+       int error = clone->bi_error;
 
        bio_put(clone);
 
@@ -1011,13 +1012,13 @@ static void end_clone_bio(struct bio *clone)
                 * the remainder.
                 */
                return;
-       else if (bio->bi_error) {
+       else if (error) {
                /*
                 * Don't notice the error to the upper layer yet.
                 * The error handling decision is made by the target driver,
                 * when the request is completed.
                 */
-               tio->error = bio->bi_error;
+               tio->error = error;
                return;
        }
 
@@ -2837,8 +2838,6 @@ static void __dm_destroy(struct mapped_device *md, bool wait)
 
        might_sleep();
 
-       map = dm_get_live_table(md, &srcu_idx);
-
        spin_lock(&_minor_lock);
        idr_replace(&_minor_idr, MINOR_ALLOCED, MINOR(disk_devt(dm_disk(md))));
        set_bit(DMF_FREEING, &md->flags);
@@ -2852,14 +2851,14 @@ static void __dm_destroy(struct mapped_device *md, bool wait)
         * do not race with internal suspend.
         */
        mutex_lock(&md->suspend_lock);
+       map = dm_get_live_table(md, &srcu_idx);
        if (!dm_suspended_md(md)) {
                dm_table_presuspend_targets(map);
                dm_table_postsuspend_targets(map);
        }
-       mutex_unlock(&md->suspend_lock);
-
        /* dm_put_live_table must be before msleep, otherwise deadlock is possible */
        dm_put_live_table(md, srcu_idx);
+       mutex_unlock(&md->suspend_lock);
 
        /*
         * Rare, but there may be I/O requests still going to complete,
index 049df6c4a8cc302c9a266e34e5a1edefecb31cf7..ddd8a5f572aa1c023db07b3eab6b72bc0371c1dd 100644 (file)
@@ -2382,8 +2382,8 @@ static void raid1d(struct md_thread *thread)
                }
                spin_unlock_irqrestore(&conf->device_lock, flags);
                while (!list_empty(&tmp)) {
-                       r1_bio = list_first_entry(&conf->bio_end_io_list,
-                                                 struct r1bio, retry_list);
+                       r1_bio = list_first_entry(&tmp, struct r1bio,
+                                                 retry_list);
                        list_del(&r1_bio->retry_list);
                        raid_end_bio_io(r1_bio);
                }
index 7c99a403771527354a5323137f5004d7adf9e007..9f69dc526f8cbf271f45b4d7745a442aa6324329 100644 (file)
@@ -2688,8 +2688,8 @@ static void raid10d(struct md_thread *thread)
                }
                spin_unlock_irqrestore(&conf->device_lock, flags);
                while (!list_empty(&tmp)) {
-                       r10_bio = list_first_entry(&conf->bio_end_io_list,
-                                                 struct r10bio, retry_list);
+                       r10_bio = list_first_entry(&tmp, struct r10bio,
+                                                  retry_list);
                        list_del(&r10_bio->retry_list);
                        raid_end_bio_io(r10_bio);
                }
index c6a644b22af44e53b5cee18fc596df48ff675835..6f3154613dc7174b04a7e91dff0af1d3aae9b31e 100644 (file)
@@ -58,12 +58,18 @@ config OMAP_GPMC
          memory drives like NOR, NAND, OneNAND, SRAM.
 
 config OMAP_GPMC_DEBUG
-       bool
+       bool "Enable GPMC debug output and skip reset of GPMC during init"
        depends on OMAP_GPMC
        help
          Enables verbose debugging mostly to decode the bootloader provided
-         timings. Enable this during development to configure devices
-         connected to the GPMC bus.
+         timings. To preserve the bootloader provided timings, the reset
+         of GPMC is skipped during init. Enable this during development to
+         configure devices connected to the GPMC bus.
+
+         NOTE: In addition to matching the register setup with the bootloader
+         you also need to match the GPMC FCLK frequency used by the
+         bootloader or else the GPMC timings won't be identical with the
+         bootloader timings.
 
 config MVEBU_DEVBUS
        bool "Marvell EBU Device Bus Controller"
index 32ac049f2bc4dbda4418587cc017cc074d5989c9..6515dfc2b805d6c5198756e17bacd23724689dac 100644 (file)
@@ -696,7 +696,6 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t,
        int div;
        u32 l;
 
-       gpmc_cs_show_timings(cs, "before gpmc_cs_set_timings");
        div = gpmc_calc_divider(t->sync_clk);
        if (div < 0)
                return div;
@@ -1988,6 +1987,7 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
        if (ret < 0)
                goto err;
 
+       gpmc_cs_show_timings(cs, "before gpmc_cs_program_settings");
        ret = gpmc_cs_program_settings(cs, &gpmc_s);
        if (ret < 0)
                goto err;
index b2ef6072fbf41193d636ff88415ee033e42021aa..ff57195b4e37ef98a399f6bb2ad1d98c8f2cdcdf 100644 (file)
@@ -118,7 +118,8 @@ static int pl172_setup_static(struct amba_device *adev,
        if (of_property_read_bool(np, "mpmc,extended-wait"))
                cfg |= MPMC_STATIC_CFG_EW;
 
-       if (of_property_read_bool(np, "mpmc,buffer-enable"))
+       if (amba_part(adev) == 0x172 &&
+           of_property_read_bool(np, "mpmc,buffer-enable"))
                cfg |= MPMC_STATIC_CFG_B;
 
        if (of_property_read_bool(np, "mpmc,write-protect"))
@@ -190,6 +191,8 @@ static int pl172_parse_cs_config(struct amba_device *adev,
 }
 
 static const char * const pl172_revisions[] = {"r1", "r2", "r2p3", "r2p4"};
+static const char * const pl175_revisions[] = {"r1"};
+static const char * const pl176_revisions[] = {"r0"};
 
 static int pl172_probe(struct amba_device *adev, const struct amba_id *id)
 {
@@ -202,6 +205,12 @@ static int pl172_probe(struct amba_device *adev, const struct amba_id *id)
        if (amba_part(adev) == 0x172) {
                if (amba_rev(adev) < ARRAY_SIZE(pl172_revisions))
                        rev = pl172_revisions[amba_rev(adev)];
+       } else if (amba_part(adev) == 0x175) {
+               if (amba_rev(adev) < ARRAY_SIZE(pl175_revisions))
+                       rev = pl175_revisions[amba_rev(adev)];
+       } else if (amba_part(adev) == 0x176) {
+               if (amba_rev(adev) < ARRAY_SIZE(pl176_revisions))
+                       rev = pl176_revisions[amba_rev(adev)];
        }
 
        dev_info(dev, "ARM PL%x revision %s\n", amba_part(adev), rev);
@@ -278,9 +287,20 @@ static int pl172_remove(struct amba_device *adev)
 }
 
 static const struct amba_id pl172_ids[] = {
+       /*  PrimeCell MPMC PL172, EMC found on NXP LPC18xx and LPC43xx */
        {
-               .id     = 0x07341172,
-               .mask   = 0xffffffff,
+               .id     = 0x07041172,
+               .mask   = 0x3f0fffff,
+       },
+       /* PrimeCell MPMC PL175, EMC found on NXP LPC32xx */
+       {
+               .id     = 0x07041175,
+               .mask   = 0x3f0fffff,
+       },
+       /* PrimeCell MPMC PL176 */
+       {
+               .id     = 0x89041176,
+               .mask   = 0xff0fffff,
        },
        { 0, 0 },
 };
index 0ca05c3ec8d68ac78d5268b8accca776647d12c0..ac24a4bd63f755d2aa08e9fa2310072d0c65b719 100644 (file)
@@ -125,6 +125,10 @@ static int __init tc_probe(struct platform_device *pdev)
        if (IS_ERR(clk))
                return PTR_ERR(clk);
 
+       tc->slow_clk = devm_clk_get(&pdev->dev, "slow_clk");
+       if (IS_ERR(tc->slow_clk))
+               return PTR_ERR(tc->slow_clk);
+
        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        tc->regs = devm_ioremap_resource(&pdev->dev, r);
        if (IS_ERR(tc->regs))
index 8eec887c8f701ce732a6278a49b1fbe298ca0635..6d7c188fb65c8ce288817e0ffb5728764e2ac133 100644 (file)
@@ -1209,7 +1209,7 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
                 * after the host receives the enum_resp
                 * message clients may be added or removed
                 */
-               if (dev->hbm_state <= MEI_HBM_ENUM_CLIENTS &&
+               if (dev->hbm_state <= MEI_HBM_ENUM_CLIENTS ||
                    dev->hbm_state >= MEI_HBM_STOPPED) {
                        dev_err(dev->dev, "hbm: add client: state mismatch, [%d, %d]\n",
                                dev->dev_state, dev->hbm_state);
index 781e4db317671ce6146dea121a56f42f90e7c491..7fb0753abe3041bc1814ebc14c1136d103b254e1 100644 (file)
@@ -182,6 +182,7 @@ struct omap_hsmmc_host {
        struct  clk             *fclk;
        struct  clk             *dbclk;
        struct  regulator       *pbias;
+       bool                    pbias_enabled;
        void    __iomem         *base;
        int                     vqmmc_enabled;
        resource_size_t         mapbase;
@@ -328,20 +329,22 @@ static int omap_hsmmc_set_pbias(struct omap_hsmmc_host *host, bool power_on,
                        return ret;
                }
 
-               if (!regulator_is_enabled(host->pbias)) {
+               if (host->pbias_enabled == 0) {
                        ret = regulator_enable(host->pbias);
                        if (ret) {
                                dev_err(host->dev, "pbias reg enable fail\n");
                                return ret;
                        }
+                       host->pbias_enabled = 1;
                }
        } else {
-               if (regulator_is_enabled(host->pbias)) {
+               if (host->pbias_enabled == 1) {
                        ret = regulator_disable(host->pbias);
                        if (ret) {
                                dev_err(host->dev, "pbias reg disable fail\n");
                                return ret;
                        }
+                       host->pbias_enabled = 0;
                }
        }
 
@@ -475,7 +478,7 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
        mmc->supply.vmmc = devm_regulator_get_optional(host->dev, "vmmc");
        if (IS_ERR(mmc->supply.vmmc)) {
                ret = PTR_ERR(mmc->supply.vmmc);
-               if (ret != -ENODEV)
+               if ((ret != -ENODEV) && host->dev->of_node)
                        return ret;
                dev_dbg(host->dev, "unable to get vmmc regulator %ld\n",
                        PTR_ERR(mmc->supply.vmmc));
@@ -490,7 +493,7 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
        mmc->supply.vqmmc = devm_regulator_get_optional(host->dev, "vmmc_aux");
        if (IS_ERR(mmc->supply.vqmmc)) {
                ret = PTR_ERR(mmc->supply.vqmmc);
-               if (ret != -ENODEV)
+               if ((ret != -ENODEV) && host->dev->of_node)
                        return ret;
                dev_dbg(host->dev, "unable to get vmmc_aux regulator %ld\n",
                        PTR_ERR(mmc->supply.vqmmc));
@@ -500,7 +503,7 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
        host->pbias = devm_regulator_get_optional(host->dev, "pbias");
        if (IS_ERR(host->pbias)) {
                ret = PTR_ERR(host->pbias);
-               if (ret != -ENODEV)
+               if ((ret != -ENODEV) && host->dev->of_node)
                        return ret;
                dev_dbg(host->dev, "unable to get pbias regulator %ld\n",
                        PTR_ERR(host->pbias));
@@ -2053,6 +2056,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
        host->base      = base + pdata->reg_offset;
        host->power_mode = MMC_POWER_OFF;
        host->next_data.cookie = 1;
+       host->pbias_enabled = 0;
        host->vqmmc_enabled = 0;
 
        ret = omap_hsmmc_gpio_init(mmc, host, pdata);
index d1556643a41d325abc7b7637ac94c694e778fedc..a0f05de5409f7d0c42f3d2457ff4dc1bb0e74f3c 100644 (file)
@@ -43,6 +43,7 @@ static const struct sdhci_ops sdhci_at91_sama5d2_ops = {
 
 static const struct sdhci_pltfm_data soc_data_sama5d2 = {
        .ops = &sdhci_at91_sama5d2_ops,
+       .quirks2 = SDHCI_QUIRK2_NEED_DELAY_AFTER_INT_CLK_RST,
 };
 
 static const struct of_device_id sdhci_at91_dt_match[] = {
index 946d37f94a31b29e8739304ec71cf7b1468eead6..f5edf9d3a18a2088a2b08705d876c413b1d659b5 100644 (file)
@@ -135,6 +135,7 @@ static int armada_38x_quirks(struct platform_device *pdev,
        struct sdhci_pxa *pxa = pltfm_host->priv;
        struct resource *res;
 
+       host->quirks &= ~SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN;
        host->quirks |= SDHCI_QUIRK_MISSING_CAPS;
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
                                           "conf-sdio3");
@@ -290,6 +291,9 @@ static void pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
                    uhs == MMC_TIMING_UHS_DDR50) {
                        reg_val &= ~SDIO3_CONF_CLK_INV;
                        reg_val |= SDIO3_CONF_SD_FB_CLK;
+               } else if (uhs == MMC_TIMING_MMC_HS) {
+                       reg_val &= ~SDIO3_CONF_CLK_INV;
+                       reg_val &= ~SDIO3_CONF_SD_FB_CLK;
                } else {
                        reg_val |= SDIO3_CONF_CLK_INV;
                        reg_val &= ~SDIO3_CONF_SD_FB_CLK;
@@ -398,7 +402,7 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
        if (of_device_is_compatible(np, "marvell,armada-380-sdhci")) {
                ret = armada_38x_quirks(pdev, host);
                if (ret < 0)
-                       goto err_clk_get;
+                       goto err_mbus_win;
                ret = mv_conf_mbus_windows(pdev, mv_mbus_dram_info());
                if (ret < 0)
                        goto err_mbus_win;
index 64b7fdbd1a9ccab80034e8a38660ef944daf8bae..fbc7efdddcb5a4cb9c2726b91e2ee29acfa85f08 100644 (file)
@@ -1160,6 +1160,8 @@ void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
        host->mmc->actual_clock = 0;
 
        sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
+       if (host->quirks2 & SDHCI_QUIRK2_NEED_DELAY_AFTER_INT_CLK_RST)
+               mdelay(1);
 
        if (clock == 0)
                return;
index 7c02ff46c8ac3ecdaf37e792fd6bcb43c9bd029e..9d4aa31b683ac2d64e16f31f88d8d0893162a225 100644 (file)
@@ -412,6 +412,11 @@ struct sdhci_host {
 #define SDHCI_QUIRK2_ACMD23_BROKEN                     (1<<14)
 /* Broken Clock divider zero in controller */
 #define SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN             (1<<15)
+/*
+ * When internal clock is disabled, a delay is needed before modifying the
+ * SD clock frequency or enabling back the internal clock.
+ */
+#define SDHCI_QUIRK2_NEED_DELAY_AFTER_INT_CLK_RST      (1<<16)
 
        int irq;                /* Device IRQ */
        void __iomem *ioaddr;   /* Mapped address */
index 2426db88db36bf95f1f247eeae597ff69238c70d..f04445b992f512c537018b81bf0d685a3ee2f62b 100644 (file)
@@ -879,7 +879,7 @@ static void copy_spare(struct mtd_info *mtd, bool bfrom)
                                      oob_chunk_size);
 
                /* the last chunk */
-               memcpy16_toio(&s[oob_chunk_size * sparebuf_size],
+               memcpy16_toio(&s[i * sparebuf_size],
                              &d[i * oob_chunk_size],
                              host->used_oobsize - i * oob_chunk_size);
        }
index f97a58d6aae1bbbacdb29ca86ac30c1f21d19e48..e7d333c162befd274f891b8674b5ca8fd905315e 100644 (file)
 #define NFC_ECC_MODE           GENMASK(15, 12)
 #define NFC_RANDOM_SEED                GENMASK(30, 16)
 
+/* NFC_USER_DATA helper macros */
+#define NFC_BUF_TO_USER_DATA(buf)      ((buf)[0] | ((buf)[1] << 8) | \
+                                       ((buf)[2] << 16) | ((buf)[3] << 24))
+
 #define NFC_DEFAULT_TIMEOUT_MS 1000
 
 #define NFC_SRAM_SIZE          1024
@@ -646,15 +650,9 @@ static int sunxi_nfc_hw_ecc_write_page(struct mtd_info *mtd,
                offset = layout->eccpos[i * ecc->bytes] - 4 + mtd->writesize;
 
                /* Fill OOB data in */
-               if (oob_required) {
-                       tmp = 0xffffffff;
-                       memcpy_toio(nfc->regs + NFC_REG_USER_DATA_BASE, &tmp,
-                                   4);
-               } else {
-                       memcpy_toio(nfc->regs + NFC_REG_USER_DATA_BASE,
-                                   chip->oob_poi + offset - mtd->writesize,
-                                   4);
-               }
+               writel(NFC_BUF_TO_USER_DATA(chip->oob_poi +
+                                           layout->oobfree[i].offset),
+                      nfc->regs + NFC_REG_USER_DATA_BASE);
 
                chip->cmdfunc(mtd, NAND_CMD_RNDIN, offset, -1);
 
@@ -784,14 +782,8 @@ static int sunxi_nfc_hw_syndrome_ecc_write_page(struct mtd_info *mtd,
                offset += ecc->size;
 
                /* Fill OOB data in */
-               if (oob_required) {
-                       tmp = 0xffffffff;
-                       memcpy_toio(nfc->regs + NFC_REG_USER_DATA_BASE, &tmp,
-                                   4);
-               } else {
-                       memcpy_toio(nfc->regs + NFC_REG_USER_DATA_BASE, oob,
-                                   4);
-               }
+               writel(NFC_BUF_TO_USER_DATA(oob),
+                      nfc->regs + NFC_REG_USER_DATA_BASE);
 
                tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_ACCESS_DIR |
                      (1 << 30);
@@ -1389,6 +1381,7 @@ static void sunxi_nand_chips_cleanup(struct sunxi_nfc *nfc)
                                        node);
                nand_release(&chip->mtd);
                sunxi_nand_ecc_cleanup(&chip->nand.ecc);
+               list_del(&chip->node);
        }
 }
 
index d3c6676b3c0cafbaa996c1f60d1c21adb0f20b21..6fd4e5a5ef4a495bbd412ee33b931f4fb3a8a24f 100644 (file)
@@ -67,7 +67,7 @@ static ssize_t bin_attr_nvmem_read(struct file *filp, struct kobject *kobj,
        int rc;
 
        /* Stop the user from reading */
-       if (pos > nvmem->size)
+       if (pos >= nvmem->size)
                return 0;
 
        if (pos + count > nvmem->size)
@@ -92,7 +92,7 @@ static ssize_t bin_attr_nvmem_write(struct file *filp, struct kobject *kobj,
        int rc;
 
        /* Stop the user from writing */
-       if (pos > nvmem->size)
+       if (pos >= nvmem->size)
                return 0;
 
        if (pos + count > nvmem->size)
@@ -825,7 +825,7 @@ static int __nvmem_cell_read(struct nvmem_device *nvmem,
                return rc;
 
        /* shift bits in-place */
-       if (cell->bit_offset || cell->bit_offset)
+       if (cell->bit_offset || cell->nbits)
                nvmem_shift_read_buffer_in_place(cell, buf);
 
        *len = cell->bytes;
@@ -938,7 +938,7 @@ int nvmem_cell_write(struct nvmem_cell *cell, void *buf, size_t len)
        rc = regmap_raw_write(nvmem->regmap, cell->offset, buf, cell->bytes);
 
        /* free the tmp buffer */
-       if (cell->bit_offset)
+       if (cell->bit_offset || cell->nbits)
                kfree(buf);
 
        if (IS_ERR_VALUE(rc))
index 14777dd5212d29d10c672a18c8b85c17fdcdceb4..cfa3b85064dd233a463b1556742274d960e4f47b 100644 (file)
@@ -103,7 +103,7 @@ static int sunxi_sid_probe(struct platform_device *pdev)
        struct nvmem_device *nvmem;
        struct regmap *regmap;
        struct sunxi_sid *sid;
-       int i, size;
+       int ret, i, size;
        char *randomness;
 
        sid = devm_kzalloc(dev, sizeof(*sid), GFP_KERNEL);
@@ -131,6 +131,11 @@ static int sunxi_sid_probe(struct platform_device *pdev)
                return PTR_ERR(nvmem);
 
        randomness = kzalloc(sizeof(u8) * size, GFP_KERNEL);
+       if (!randomness) {
+               ret = -EINVAL;
+               goto err_unreg_nvmem;
+       }
+
        for (i = 0; i < size; i++)
                randomness[i] = sunxi_sid_read_byte(sid, i);
 
@@ -140,6 +145,10 @@ static int sunxi_sid_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, nvmem);
 
        return 0;
+
+err_unreg_nvmem:
+       nvmem_unregister(nvmem);
+       return ret;
 }
 
 static int sunxi_sid_remove(struct platform_device *pdev)
index 2365a32a595e42b8ddf43c2dc32603749cf990d7..be3755c973e96d4c6ee48f0459c751ba6d225665 100644 (file)
@@ -823,9 +823,15 @@ static int of_pmu_irq_cfg(struct arm_pmu *pmu)
                }
 
                /* Now look up the logical CPU number */
-               for_each_possible_cpu(cpu)
-                       if (dn == of_cpu_device_node_get(cpu))
+               for_each_possible_cpu(cpu) {
+                       struct device_node *cpu_dn;
+
+                       cpu_dn = of_cpu_device_node_get(cpu);
+                       of_node_put(cpu_dn);
+
+                       if (dn == cpu_dn)
                                break;
+               }
 
                if (cpu >= nr_cpu_ids) {
                        pr_warn("Failed to find logical CPU for %s\n",
index 0062027afb1ef90335ae46782dba06448949b989..77a2e054fdea0f46ccd3d2841f5f837f80a985e1 100644 (file)
@@ -276,6 +276,7 @@ static const struct of_device_id phy_berlin_sata_of_match[] = {
        { .compatible = "marvell,berlin2q-sata-phy" },
        { },
 };
+MODULE_DEVICE_TABLE(of, phy_berlin_sata_of_match);
 
 static struct platform_driver phy_berlin_sata_driver = {
        .probe  = phy_berlin_sata_probe,
index 49a1ed0cef56fe7cbf9aed102b47149415f021f0..107cb57c3513c22642bb14420f47c469a39dcfa2 100644 (file)
@@ -432,6 +432,7 @@ out_disable_src:
 out:
        return ret;
 }
+EXPORT_SYMBOL_GPL(ufs_qcom_phy_enable_ref_clk);
 
 static
 int ufs_qcom_phy_disable_vreg(struct phy *phy,
@@ -474,6 +475,7 @@ void ufs_qcom_phy_disable_ref_clk(struct phy *generic_phy)
                phy->is_ref_clk_enabled = false;
        }
 }
+EXPORT_SYMBOL_GPL(ufs_qcom_phy_disable_ref_clk);
 
 #define UFS_REF_CLK_EN (1 << 5)
 
@@ -517,11 +519,13 @@ void ufs_qcom_phy_enable_dev_ref_clk(struct phy *generic_phy)
 {
        ufs_qcom_phy_dev_ref_clk_ctrl(generic_phy, true);
 }
+EXPORT_SYMBOL_GPL(ufs_qcom_phy_enable_dev_ref_clk);
 
 void ufs_qcom_phy_disable_dev_ref_clk(struct phy *generic_phy)
 {
        ufs_qcom_phy_dev_ref_clk_ctrl(generic_phy, false);
 }
+EXPORT_SYMBOL_GPL(ufs_qcom_phy_disable_dev_ref_clk);
 
 /* Turn ON M-PHY RMMI interface clocks */
 int ufs_qcom_phy_enable_iface_clk(struct phy *generic_phy)
@@ -550,6 +554,7 @@ int ufs_qcom_phy_enable_iface_clk(struct phy *generic_phy)
 out:
        return ret;
 }
+EXPORT_SYMBOL_GPL(ufs_qcom_phy_enable_iface_clk);
 
 /* Turn OFF M-PHY RMMI interface clocks */
 void ufs_qcom_phy_disable_iface_clk(struct phy *generic_phy)
@@ -562,6 +567,7 @@ void ufs_qcom_phy_disable_iface_clk(struct phy *generic_phy)
                phy->is_iface_clk_enabled = false;
        }
 }
+EXPORT_SYMBOL_GPL(ufs_qcom_phy_disable_iface_clk);
 
 int ufs_qcom_phy_start_serdes(struct phy *generic_phy)
 {
@@ -578,6 +584,7 @@ int ufs_qcom_phy_start_serdes(struct phy *generic_phy)
 
        return ret;
 }
+EXPORT_SYMBOL_GPL(ufs_qcom_phy_start_serdes);
 
 int ufs_qcom_phy_set_tx_lane_enable(struct phy *generic_phy, u32 tx_lanes)
 {
@@ -595,6 +602,7 @@ int ufs_qcom_phy_set_tx_lane_enable(struct phy *generic_phy, u32 tx_lanes)
 
        return ret;
 }
+EXPORT_SYMBOL_GPL(ufs_qcom_phy_set_tx_lane_enable);
 
 void ufs_qcom_phy_save_controller_version(struct phy *generic_phy,
                                          u8 major, u16 minor, u16 step)
@@ -605,6 +613,7 @@ void ufs_qcom_phy_save_controller_version(struct phy *generic_phy,
        ufs_qcom_phy->host_ctrl_rev_minor = minor;
        ufs_qcom_phy->host_ctrl_rev_step = step;
 }
+EXPORT_SYMBOL_GPL(ufs_qcom_phy_save_controller_version);
 
 int ufs_qcom_phy_calibrate_phy(struct phy *generic_phy, bool is_rate_B)
 {
@@ -625,6 +634,7 @@ int ufs_qcom_phy_calibrate_phy(struct phy *generic_phy, bool is_rate_B)
 
        return ret;
 }
+EXPORT_SYMBOL_GPL(ufs_qcom_phy_calibrate_phy);
 
 int ufs_qcom_phy_remove(struct phy *generic_phy,
                        struct ufs_qcom_phy *ufs_qcom_phy)
@@ -662,6 +672,7 @@ int ufs_qcom_phy_is_pcs_ready(struct phy *generic_phy)
        return ufs_qcom_phy->phy_spec_ops->
                        is_physical_coding_sublayer_ready(ufs_qcom_phy);
 }
+EXPORT_SYMBOL_GPL(ufs_qcom_phy_is_pcs_ready);
 
 int ufs_qcom_phy_power_on(struct phy *generic_phy)
 {
index 5a5c073e72fe1ee6115bea310890b646b6b40a69..91d6f342c56596fc2e3fcff18213dba004546c3e 100644 (file)
@@ -98,6 +98,7 @@ static int rockchip_usb_phy_probe(struct platform_device *pdev)
        struct device_node *child;
        struct regmap *grf;
        unsigned int reg_offset;
+       int err;
 
        grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf");
        if (IS_ERR(grf)) {
@@ -129,6 +130,11 @@ static int rockchip_usb_phy_probe(struct platform_device *pdev)
                        return PTR_ERR(rk_phy->phy);
                }
                phy_set_drvdata(rk_phy->phy, rk_phy);
+
+               /* only power up usb phy when it use, so disable it when init*/
+               err = rockchip_usb_phy_power(rk_phy, 1);
+               if (err)
+                       return err;
        }
 
        phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
index 6da01b3bf6f463b606cac8e3b5cb2d834243456a..75db585a2a9486e354c08cf971b46507f014c3d4 100644 (file)
@@ -305,7 +305,7 @@ static int atmel_tcb_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
         */
        if (i == 5) {
                i = slowclk;
-               rate = 32768;
+               rate = clk_get_rate(tc->slow_clk);
                min = div_u64(NSEC_PER_SEC, rate);
                max = min << tc->tcb_config->counter_width;
 
@@ -387,9 +387,9 @@ static int atmel_tcb_pwm_probe(struct platform_device *pdev)
 
        tcbpwm = devm_kzalloc(&pdev->dev, sizeof(*tcbpwm), GFP_KERNEL);
        if (tcbpwm == NULL) {
-               atmel_tc_free(tc);
+               err = -ENOMEM;
                dev_err(&pdev->dev, "failed to allocate memory\n");
-               return -ENOMEM;
+               goto err_free_tc;
        }
 
        tcbpwm->chip.dev = &pdev->dev;
@@ -400,17 +400,27 @@ static int atmel_tcb_pwm_probe(struct platform_device *pdev)
        tcbpwm->chip.npwm = NPWM;
        tcbpwm->tc = tc;
 
+       err = clk_prepare_enable(tc->slow_clk);
+       if (err)
+               goto err_free_tc;
+
        spin_lock_init(&tcbpwm->lock);
 
        err = pwmchip_add(&tcbpwm->chip);
-       if (err < 0) {
-               atmel_tc_free(tc);
-               return err;
-       }
+       if (err < 0)
+               goto err_disable_clk;
 
        platform_set_drvdata(pdev, tcbpwm);
 
        return 0;
+
+err_disable_clk:
+       clk_disable_unprepare(tcbpwm->tc->slow_clk);
+
+err_free_tc:
+       atmel_tc_free(tc);
+
+       return err;
 }
 
 static int atmel_tcb_pwm_remove(struct platform_device *pdev)
@@ -418,6 +428,8 @@ static int atmel_tcb_pwm_remove(struct platform_device *pdev)
        struct atmel_tcb_pwm_chip *tcbpwm = platform_get_drvdata(pdev);
        int err;
 
+       clk_disable_unprepare(tcbpwm->tc->slow_clk);
+
        err = pwmchip_remove(&tcbpwm->chip);
        if (err < 0)
                return err;
index 01bf3476a79183714f62f67efcf5d8b17b70d497..a9567af7cec02c5a13102be118010e7bb7b1c888 100644 (file)
@@ -192,9 +192,9 @@ static const struct regulator_desc axp22x_regulators[] = {
        AXP_DESC(AXP22X, DCDC3, "dcdc3", "vin3", 600, 1860, 20,
                 AXP22X_DCDC3_V_OUT, 0x3f, AXP22X_PWR_OUT_CTRL1, BIT(3)),
        AXP_DESC(AXP22X, DCDC4, "dcdc4", "vin4", 600, 1540, 20,
-                AXP22X_DCDC4_V_OUT, 0x3f, AXP22X_PWR_OUT_CTRL1, BIT(3)),
+                AXP22X_DCDC4_V_OUT, 0x3f, AXP22X_PWR_OUT_CTRL1, BIT(4)),
        AXP_DESC(AXP22X, DCDC5, "dcdc5", "vin5", 1000, 2550, 50,
-                AXP22X_DCDC5_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(4)),
+                AXP22X_DCDC5_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(5)),
        /* secondary switchable output of DCDC1 */
        AXP_DESC_SW(AXP22X, DC1SW, "dc1sw", "dcdc1", 1600, 3400, 100,
                    AXP22X_DCDC1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(7)),
index 7849187d91aea909fdd9d0ce5bbabb35fc2e5736..8a34f6acc801531ce8eb16882fed2b04ed4c874c 100644 (file)
@@ -1403,6 +1403,10 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
                        return 0;
                }
 
+               /* Did the lookup explicitly defer for us? */
+               if (ret == -EPROBE_DEFER)
+                       return ret;
+
                if (have_full_constraints()) {
                        r = dummy_regulator_rdev;
                } else {
index add419d6ff34996ed4aab8a145aee637ee987dbf..a56a7b243e91fae96b05cae0118d96e9d284dd7b 100644 (file)
@@ -212,6 +212,17 @@ static const struct file_operations twa_fops = {
        .llseek         = noop_llseek,
 };
 
+/*
+ * The controllers use an inline buffer instead of a mapped SGL for small,
+ * single entry buffers.  Note that we treat a zero-length transfer like
+ * a mapped SGL.
+ */
+static bool twa_command_mapped(struct scsi_cmnd *cmd)
+{
+       return scsi_sg_count(cmd) != 1 ||
+               scsi_bufflen(cmd) >= TW_MIN_SGL_LENGTH;
+}
+
 /* This function will complete an aen request from the isr */
 static int twa_aen_complete(TW_Device_Extension *tw_dev, int request_id)
 {
@@ -1339,7 +1350,8 @@ static irqreturn_t twa_interrupt(int irq, void *dev_instance)
                                }
 
                                /* Now complete the io */
-                               scsi_dma_unmap(cmd);
+                               if (twa_command_mapped(cmd))
+                                       scsi_dma_unmap(cmd);
                                cmd->scsi_done(cmd);
                                tw_dev->state[request_id] = TW_S_COMPLETED;
                                twa_free_request_id(tw_dev, request_id);
@@ -1582,7 +1594,8 @@ static int twa_reset_device_extension(TW_Device_Extension *tw_dev)
                                struct scsi_cmnd *cmd = tw_dev->srb[i];
 
                                cmd->result = (DID_RESET << 16);
-                               scsi_dma_unmap(cmd);
+                               if (twa_command_mapped(cmd))
+                                       scsi_dma_unmap(cmd);
                                cmd->scsi_done(cmd);
                        }
                }
@@ -1765,12 +1778,14 @@ static int twa_scsi_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_
        retval = twa_scsiop_execute_scsi(tw_dev, request_id, NULL, 0, NULL);
        switch (retval) {
        case SCSI_MLQUEUE_HOST_BUSY:
-               scsi_dma_unmap(SCpnt);
+               if (twa_command_mapped(SCpnt))
+                       scsi_dma_unmap(SCpnt);
                twa_free_request_id(tw_dev, request_id);
                break;
        case 1:
                SCpnt->result = (DID_ERROR << 16);
-               scsi_dma_unmap(SCpnt);
+               if (twa_command_mapped(SCpnt))
+                       scsi_dma_unmap(SCpnt);
                done(SCpnt);
                tw_dev->state[request_id] = TW_S_COMPLETED;
                twa_free_request_id(tw_dev, request_id);
@@ -1831,8 +1846,7 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id,
                /* Map sglist from scsi layer to cmd packet */
 
                if (scsi_sg_count(srb)) {
-                       if ((scsi_sg_count(srb) == 1) &&
-                           (scsi_bufflen(srb) < TW_MIN_SGL_LENGTH)) {
+                       if (!twa_command_mapped(srb)) {
                                if (srb->sc_data_direction == DMA_TO_DEVICE ||
                                    srb->sc_data_direction == DMA_BIDIRECTIONAL)
                                        scsi_sg_copy_to_buffer(srb,
@@ -1905,7 +1919,7 @@ static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int re
 {
        struct scsi_cmnd *cmd = tw_dev->srb[request_id];
 
-       if (scsi_bufflen(cmd) < TW_MIN_SGL_LENGTH &&
+       if (!twa_command_mapped(cmd) &&
            (cmd->sc_data_direction == DMA_FROM_DEVICE ||
             cmd->sc_data_direction == DMA_BIDIRECTIONAL)) {
                if (scsi_sg_count(cmd) == 1) {
index 33c74d3436c947a7f11ca22498206f6efa97fcc2..6bffd91b973a475d614500a077be0034dbf6786f 100644 (file)
@@ -976,13 +976,13 @@ static void iscsi_tmf_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
        wake_up(&conn->ehwait);
 }
 
-static void iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr)
+static int iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr)
 {
         struct iscsi_nopout hdr;
        struct iscsi_task *task;
 
        if (!rhdr && conn->ping_task)
-               return;
+               return -EINVAL;
 
        memset(&hdr, 0, sizeof(struct iscsi_nopout));
        hdr.opcode = ISCSI_OP_NOOP_OUT | ISCSI_OP_IMMEDIATE;
@@ -996,13 +996,16 @@ static void iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr)
                hdr.ttt = RESERVED_ITT;
 
        task = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)&hdr, NULL, 0);
-       if (!task)
+       if (!task) {
                iscsi_conn_printk(KERN_ERR, conn, "Could not send nopout\n");
-       else if (!rhdr) {
+               return -EIO;
+       } else if (!rhdr) {
                /* only track our nops */
                conn->ping_task = task;
                conn->last_ping = jiffies;
        }
+
+       return 0;
 }
 
 static int iscsi_nop_out_rsp(struct iscsi_task *task,
@@ -2092,8 +2095,10 @@ static void iscsi_check_transport_timeouts(unsigned long data)
        if (time_before_eq(last_recv + recv_timeout, jiffies)) {
                /* send a ping to try to provoke some traffic */
                ISCSI_DBG_CONN(conn, "Sending nopout as ping\n");
-               iscsi_send_nopout(conn, NULL);
-               next_timeout = conn->last_ping + (conn->ping_timeout * HZ);
+               if (iscsi_send_nopout(conn, NULL))
+                       next_timeout = jiffies + (1 * HZ);
+               else
+                       next_timeout = conn->last_ping + (conn->ping_timeout * HZ);
        } else
                next_timeout = last_recv + recv_timeout;
 
index edb044a7b56d348a269634212155edce3a89f9b8..0a2168e69bbcd31c91a995dae5439a1485cc0a7d 100644 (file)
@@ -111,7 +111,7 @@ static struct scsi_device_handler *scsi_dh_lookup(const char *name)
 
        dh = __scsi_dh_lookup(name);
        if (!dh) {
-               request_module(name);
+               request_module("scsi_dh_%s", name);
                dh = __scsi_dh_lookup(name);
        }
 
index 96ddecb922545e9294040e05950e6c695e01b3c6..4e853ed2c82b937ebd8fb6cf4c22288a122fca3a 100644 (file)
@@ -1,7 +1,9 @@
 menu "SOC (System On Chip) specific Drivers"
 
+source "drivers/soc/brcmstb/Kconfig"
 source "drivers/soc/mediatek/Kconfig"
 source "drivers/soc/qcom/Kconfig"
+source "drivers/soc/rockchip/Kconfig"
 source "drivers/soc/sunxi/Kconfig"
 source "drivers/soc/ti/Kconfig"
 source "drivers/soc/versatile/Kconfig"
index 0b12d777d3c4a9114fa80911b27fbb496c0ae307..f2ba2e932ae10c5d2cda1de269b826b9875a4a5c 100644 (file)
@@ -2,9 +2,11 @@
 # Makefile for the Linux Kernel SOC specific device drivers.
 #
 
+obj-$(CONFIG_SOC_BRCMSTB)      += brcmstb/
 obj-$(CONFIG_MACH_DOVE)                += dove/
 obj-$(CONFIG_ARCH_MEDIATEK)    += mediatek/
 obj-$(CONFIG_ARCH_QCOM)                += qcom/
+obj-$(CONFIG_ARCH_ROCKCHIP)            += rockchip/
 obj-$(CONFIG_ARCH_SUNXI)       += sunxi/
 obj-$(CONFIG_ARCH_TEGRA)       += tegra/
 obj-$(CONFIG_SOC_TI)           += ti/
diff --git a/drivers/soc/brcmstb/Kconfig b/drivers/soc/brcmstb/Kconfig
new file mode 100644 (file)
index 0000000..39cab3b
--- /dev/null
@@ -0,0 +1,9 @@
+menuconfig SOC_BRCMSTB
+       bool "Broadcom STB SoC drivers"
+       depends on ARM
+       help
+         Enables drivers for the Broadcom Set-Top Box (STB) series of chips.
+         This option alone enables only some support code, while the drivers
+         can be enabled individually within this menu.
+
+         If unsure, say N.
diff --git a/drivers/soc/brcmstb/Makefile b/drivers/soc/brcmstb/Makefile
new file mode 100644 (file)
index 0000000..9120b27
--- /dev/null
@@ -0,0 +1 @@
+obj-y                          += common.o biuctrl.o
diff --git a/drivers/soc/brcmstb/biuctrl.c b/drivers/soc/brcmstb/biuctrl.c
new file mode 100644 (file)
index 0000000..9049c07
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * Broadcom STB SoCs Bus Unit Interface controls
+ *
+ * Copyright (C) 2015, Broadcom Corporation
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#define pr_fmt(fmt)    "brcmstb: " KBUILD_MODNAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/syscore_ops.h>
+
+#define CPU_CREDIT_REG_OFFSET                  0x184
+#define  CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK        0x70000000
+
+static void __iomem *cpubiuctrl_base;
+static bool mcp_wr_pairing_en;
+
+static int __init mcp_write_pairing_set(void)
+{
+       u32 creds = 0;
+
+       if (!cpubiuctrl_base)
+               return -1;
+
+       creds = readl_relaxed(cpubiuctrl_base + CPU_CREDIT_REG_OFFSET);
+       if (mcp_wr_pairing_en) {
+               pr_info("MCP: Enabling write pairing\n");
+               writel_relaxed(creds | CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK,
+                            cpubiuctrl_base + CPU_CREDIT_REG_OFFSET);
+       } else if (creds & CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK) {
+               pr_info("MCP: Disabling write pairing\n");
+               writel_relaxed(creds & ~CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK,
+                               cpubiuctrl_base + CPU_CREDIT_REG_OFFSET);
+       } else {
+               pr_info("MCP: Write pairing already disabled\n");
+       }
+
+       return 0;
+}
+
+static int __init setup_hifcpubiuctrl_regs(void)
+{
+       struct device_node *np;
+       int ret = 0;
+
+       np = of_find_compatible_node(NULL, NULL, "brcm,brcmstb-cpu-biu-ctrl");
+       if (!np) {
+               pr_err("missing BIU control node\n");
+               return -ENODEV;
+       }
+
+       cpubiuctrl_base = of_iomap(np, 0);
+       if (!cpubiuctrl_base) {
+               pr_err("failed to remap BIU control base\n");
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       mcp_wr_pairing_en = of_property_read_bool(np, "brcm,write-pairing");
+out:
+       of_node_put(np);
+       return ret;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static u32 cpu_credit_reg_dump;  /* for save/restore */
+
+static int brcmstb_cpu_credit_reg_suspend(void)
+{
+       if (cpubiuctrl_base)
+               cpu_credit_reg_dump =
+                       readl_relaxed(cpubiuctrl_base + CPU_CREDIT_REG_OFFSET);
+       return 0;
+}
+
+static void brcmstb_cpu_credit_reg_resume(void)
+{
+       if (cpubiuctrl_base)
+               writel_relaxed(cpu_credit_reg_dump,
+                               cpubiuctrl_base + CPU_CREDIT_REG_OFFSET);
+}
+
+static struct syscore_ops brcmstb_cpu_credit_syscore_ops = {
+       .suspend = brcmstb_cpu_credit_reg_suspend,
+       .resume = brcmstb_cpu_credit_reg_resume,
+};
+#endif
+
+
+void __init brcmstb_biuctrl_init(void)
+{
+       int ret;
+
+       setup_hifcpubiuctrl_regs();
+
+       ret = mcp_write_pairing_set();
+       if (ret) {
+               pr_err("MCP: Unable to disable write pairing!\n");
+               return;
+       }
+
+#ifdef CONFIG_PM_SLEEP
+       register_syscore_ops(&brcmstb_cpu_credit_syscore_ops);
+#endif
+}
diff --git a/drivers/soc/brcmstb/common.c b/drivers/soc/brcmstb/common.c
new file mode 100644 (file)
index 0000000..c262c02
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright Â© 2014 NVIDIA Corporation
+ * Copyright Â© 2015 Broadcom Corporation
+ *
+ * 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.
+ *
+ * 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.h>
+
+#include <soc/brcmstb/common.h>
+
+static const struct of_device_id brcmstb_machine_match[] = {
+       { .compatible = "brcm,brcmstb", },
+       { }
+};
+
+bool soc_is_brcmstb(void)
+{
+       struct device_node *root;
+
+       root = of_find_node_by_path("/");
+       if (!root)
+               return false;
+
+       return of_match_node(brcmstb_machine_match, root) != NULL;
+}
index 8bc7b41b09fd218bb0e540933c1c07be95005dcb..105597a885cb4f2db4314e5cc9194d701cf843b0 100644 (file)
@@ -725,10 +725,6 @@ static int pwrap_init(struct pmic_wrapper *wrp)
        pwrap_writel(wrp, 0x1, PWRAP_WACS2_EN);
        pwrap_writel(wrp, 0x5, PWRAP_STAUPD_PRD);
        pwrap_writel(wrp, 0xff, PWRAP_STAUPD_GRPEN);
-       pwrap_writel(wrp, 0xf, PWRAP_WDT_UNIT);
-       pwrap_writel(wrp, 0xffffffff, PWRAP_WDT_SRC_EN);
-       pwrap_writel(wrp, 0x1, PWRAP_TIMER_EN);
-       pwrap_writel(wrp, ~((1 << 31) | (1 << 1)), PWRAP_INT_EN);
 
        if (pwrap_is_mt8135(wrp)) {
                /* enable pwrap events and pwrap bridge in AP side */
@@ -896,6 +892,12 @@ static int pwrap_probe(struct platform_device *pdev)
                return -ENODEV;
        }
 
+       /* Initialize watchdog, may not be done by the bootloader */
+       pwrap_writel(wrp, 0xf, PWRAP_WDT_UNIT);
+       pwrap_writel(wrp, 0xffffffff, PWRAP_WDT_SRC_EN);
+       pwrap_writel(wrp, 0x1, PWRAP_TIMER_EN);
+       pwrap_writel(wrp, ~((1 << 31) | (1 << 1)), PWRAP_INT_EN);
+
        irq = platform_get_irq(pdev, 0);
        ret = devm_request_irq(wrp->dev, irq, pwrap_interrupt, IRQF_TRIGGER_HIGH,
                        "mt-pmic-pwrap", wrp);
index 164a7d8439b148de97d7a3f4153786c52277df5b..4d4203c896c40e71486dd27e60e0918071c1e0ae 100644 (file)
 #define PWR_STATUS_USB                 BIT(25)
 
 enum clk_id {
+       MT8173_CLK_NONE,
        MT8173_CLK_MM,
        MT8173_CLK_MFG,
-       MT8173_CLK_NONE,
-       MT8173_CLK_MAX = MT8173_CLK_NONE,
+       MT8173_CLK_VENC,
+       MT8173_CLK_VENC_LT,
+       MT8173_CLK_MAX,
 };
 
+#define MAX_CLKS       2
+
 struct scp_domain_data {
        const char *name;
        u32 sta_mask;
@@ -67,7 +71,8 @@ struct scp_domain_data {
        u32 sram_pdn_bits;
        u32 sram_pdn_ack_bits;
        u32 bus_prot_mask;
-       enum clk_id clk_id;
+       enum clk_id clk_id[MAX_CLKS];
+       bool active_wakeup;
 };
 
 static const struct scp_domain_data scp_domain_data[] __initconst = {
@@ -77,7 +82,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
                .ctl_offs = SPM_VDE_PWR_CON,
                .sram_pdn_bits = GENMASK(11, 8),
                .sram_pdn_ack_bits = GENMASK(12, 12),
-               .clk_id = MT8173_CLK_MM,
+               .clk_id = {MT8173_CLK_MM},
        },
        [MT8173_POWER_DOMAIN_VENC] = {
                .name = "venc",
@@ -85,7 +90,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
                .ctl_offs = SPM_VEN_PWR_CON,
                .sram_pdn_bits = GENMASK(11, 8),
                .sram_pdn_ack_bits = GENMASK(15, 12),
-               .clk_id = MT8173_CLK_MM,
+               .clk_id = {MT8173_CLK_MM, MT8173_CLK_VENC},
        },
        [MT8173_POWER_DOMAIN_ISP] = {
                .name = "isp",
@@ -93,7 +98,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
                .ctl_offs = SPM_ISP_PWR_CON,
                .sram_pdn_bits = GENMASK(11, 8),
                .sram_pdn_ack_bits = GENMASK(13, 12),
-               .clk_id = MT8173_CLK_MM,
+               .clk_id = {MT8173_CLK_MM},
        },
        [MT8173_POWER_DOMAIN_MM] = {
                .name = "mm",
@@ -101,7 +106,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
                .ctl_offs = SPM_DIS_PWR_CON,
                .sram_pdn_bits = GENMASK(11, 8),
                .sram_pdn_ack_bits = GENMASK(12, 12),
-               .clk_id = MT8173_CLK_MM,
+               .clk_id = {MT8173_CLK_MM},
                .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MM_M0 |
                        MT8173_TOP_AXI_PROT_EN_MM_M1,
        },
@@ -111,7 +116,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
                .ctl_offs = SPM_VEN2_PWR_CON,
                .sram_pdn_bits = GENMASK(11, 8),
                .sram_pdn_ack_bits = GENMASK(15, 12),
-               .clk_id = MT8173_CLK_MM,
+               .clk_id = {MT8173_CLK_MM, MT8173_CLK_VENC_LT},
        },
        [MT8173_POWER_DOMAIN_AUDIO] = {
                .name = "audio",
@@ -119,7 +124,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
                .ctl_offs = SPM_AUDIO_PWR_CON,
                .sram_pdn_bits = GENMASK(11, 8),
                .sram_pdn_ack_bits = GENMASK(15, 12),
-               .clk_id = MT8173_CLK_NONE,
+               .clk_id = {MT8173_CLK_NONE},
        },
        [MT8173_POWER_DOMAIN_USB] = {
                .name = "usb",
@@ -127,7 +132,8 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
                .ctl_offs = SPM_USB_PWR_CON,
                .sram_pdn_bits = GENMASK(11, 8),
                .sram_pdn_ack_bits = GENMASK(15, 12),
-               .clk_id = MT8173_CLK_NONE,
+               .clk_id = {MT8173_CLK_NONE},
+               .active_wakeup = true,
        },
        [MT8173_POWER_DOMAIN_MFG_ASYNC] = {
                .name = "mfg_async",
@@ -135,7 +141,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
                .ctl_offs = SPM_MFG_ASYNC_PWR_CON,
                .sram_pdn_bits = GENMASK(11, 8),
                .sram_pdn_ack_bits = 0,
-               .clk_id = MT8173_CLK_MFG,
+               .clk_id = {MT8173_CLK_MFG},
        },
        [MT8173_POWER_DOMAIN_MFG_2D] = {
                .name = "mfg_2d",
@@ -143,7 +149,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
                .ctl_offs = SPM_MFG_2D_PWR_CON,
                .sram_pdn_bits = GENMASK(11, 8),
                .sram_pdn_ack_bits = GENMASK(13, 12),
-               .clk_id = MT8173_CLK_NONE,
+               .clk_id = {MT8173_CLK_NONE},
        },
        [MT8173_POWER_DOMAIN_MFG] = {
                .name = "mfg",
@@ -151,7 +157,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
                .ctl_offs = SPM_MFG_PWR_CON,
                .sram_pdn_bits = GENMASK(13, 8),
                .sram_pdn_ack_bits = GENMASK(21, 16),
-               .clk_id = MT8173_CLK_NONE,
+               .clk_id = {MT8173_CLK_NONE},
                .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MFG_S |
                        MT8173_TOP_AXI_PROT_EN_MFG_M0 |
                        MT8173_TOP_AXI_PROT_EN_MFG_M1 |
@@ -166,12 +172,13 @@ struct scp;
 struct scp_domain {
        struct generic_pm_domain genpd;
        struct scp *scp;
-       struct clk *clk;
+       struct clk *clk[MAX_CLKS];
        u32 sta_mask;
        void __iomem *ctl_addr;
        u32 sram_pdn_bits;
        u32 sram_pdn_ack_bits;
        u32 bus_prot_mask;
+       bool active_wakeup;
 };
 
 struct scp {
@@ -212,11 +219,16 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
        u32 sram_pdn_ack = scpd->sram_pdn_ack_bits;
        u32 val;
        int ret;
+       int i;
+
+       for (i = 0; i < MAX_CLKS && scpd->clk[i]; i++) {
+               ret = clk_prepare_enable(scpd->clk[i]);
+               if (ret) {
+                       for (--i; i >= 0; i--)
+                               clk_disable_unprepare(scpd->clk[i]);
 
-       if (scpd->clk) {
-               ret = clk_prepare_enable(scpd->clk);
-               if (ret)
                        goto err_clk;
+               }
        }
 
        val = readl(ctl_addr);
@@ -282,7 +294,10 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
        return 0;
 
 err_pwr_ack:
-       clk_disable_unprepare(scpd->clk);
+       for (i = MAX_CLKS - 1; i >= 0; i--) {
+               if (scpd->clk[i])
+                       clk_disable_unprepare(scpd->clk[i]);
+       }
 err_clk:
        dev_err(scp->dev, "Failed to power on domain %s\n", genpd->name);
 
@@ -299,6 +314,7 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
        u32 pdn_ack = scpd->sram_pdn_ack_bits;
        u32 val;
        int ret;
+       int i;
 
        if (scpd->bus_prot_mask) {
                ret = mtk_infracfg_set_bus_protection(scp->infracfg,
@@ -360,8 +376,8 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
                        expired = true;
        }
 
-       if (scpd->clk)
-               clk_disable_unprepare(scpd->clk);
+       for (i = 0; i < MAX_CLKS && scpd->clk[i]; i++)
+               clk_disable_unprepare(scpd->clk[i]);
 
        return 0;
 
@@ -371,11 +387,22 @@ out:
        return ret;
 }
 
+static bool scpsys_active_wakeup(struct device *dev)
+{
+       struct generic_pm_domain *genpd;
+       struct scp_domain *scpd;
+
+       genpd = pd_to_genpd(dev->pm_domain);
+       scpd = container_of(genpd, struct scp_domain, genpd);
+
+       return scpd->active_wakeup;
+}
+
 static int __init scpsys_probe(struct platform_device *pdev)
 {
        struct genpd_onecell_data *pd_data;
        struct resource *res;
-       int i, ret;
+       int i, j, ret;
        struct scp *scp;
        struct clk *clk[MT8173_CLK_MAX];
 
@@ -405,6 +432,14 @@ static int __init scpsys_probe(struct platform_device *pdev)
        if (IS_ERR(clk[MT8173_CLK_MFG]))
                return PTR_ERR(clk[MT8173_CLK_MFG]);
 
+       clk[MT8173_CLK_VENC] = devm_clk_get(&pdev->dev, "venc");
+       if (IS_ERR(clk[MT8173_CLK_VENC]))
+               return PTR_ERR(clk[MT8173_CLK_VENC]);
+
+       clk[MT8173_CLK_VENC_LT] = devm_clk_get(&pdev->dev, "venc_lt");
+       if (IS_ERR(clk[MT8173_CLK_VENC_LT]))
+               return PTR_ERR(clk[MT8173_CLK_VENC_LT]);
+
        scp->infracfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
                        "infracfg");
        if (IS_ERR(scp->infracfg)) {
@@ -428,12 +463,14 @@ static int __init scpsys_probe(struct platform_device *pdev)
                scpd->sram_pdn_bits = data->sram_pdn_bits;
                scpd->sram_pdn_ack_bits = data->sram_pdn_ack_bits;
                scpd->bus_prot_mask = data->bus_prot_mask;
-               if (data->clk_id != MT8173_CLK_NONE)
-                       scpd->clk = clk[data->clk_id];
+               scpd->active_wakeup = data->active_wakeup;
+               for (j = 0; j < MAX_CLKS && data->clk_id[j]; j++)
+                       scpd->clk[j] = clk[data->clk_id[j]];
 
                genpd->name = data->name;
                genpd->power_off = scpsys_power_off;
                genpd->power_on = scpsys_power_on;
+               genpd->dev_ops.active_wakeup = scpsys_active_wakeup;
 
                /*
                 * Initially turn on all domains to make the domains usable
index ba47b70f4d856d23a58ae6df69577b2dbc1932d8..eec76141d9b9a64cb0e606b069c8a63984fcb1ca 100644 (file)
@@ -19,6 +19,15 @@ config QCOM_PM
          modes. It interface with various system drivers to put the cores in
          low power modes.
 
+config QCOM_SMEM
+       tristate "Qualcomm Shared Memory Manager (SMEM)"
+       depends on ARCH_QCOM
+       depends on HWSPINLOCK
+       help
+         Say y here to enable support for the Qualcomm Shared Memory Manager.
+         The driver provides an interface to items in a heap shared among all
+         processors in a Qualcomm platform.
+
 config QCOM_SMD
        tristate "Qualcomm Shared Memory Driver (SMD)"
        depends on QCOM_SMEM
@@ -40,11 +49,3 @@ config QCOM_SMD_RPM
 
          Say M here if you want to include support for the Qualcomm RPM as a
          module. This will build a module called "qcom-smd-rpm".
-
-config QCOM_SMEM
-       tristate "Qualcomm Shared Memory Manager (SMEM)"
-       depends on ARCH_QCOM
-       help
-         Say y here to enable support for the Qualcomm Shared Memory Manager.
-         The driver provides an interface to items in a heap shared among all
-         processors in a Qualcomm platform.
index 1392ccf14a201b2ba01c76fdebc356c90cc99c4f..1ee02d2587b2831819d7e183a3a4ccd210f61298 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/of_platform.h>
 #include <linux/io.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 
 #include <linux/soc/qcom/smd.h>
 #include <linux/soc/qcom/smd-rpm.h>
@@ -44,8 +45,8 @@ struct qcom_smd_rpm {
  * @length:            length of the payload
  */
 struct qcom_rpm_header {
-       u32 service_type;
-       u32 length;
+       __le32 service_type;
+       __le32 length;
 };
 
 /**
@@ -57,11 +58,11 @@ struct qcom_rpm_header {
  * @data_len:  length of the payload following this header
  */
 struct qcom_rpm_request {
-       u32 msg_id;
-       u32 flags;
-       u32 type;
-       u32 id;
-       u32 data_len;
+       __le32 msg_id;
+       __le32 flags;
+       __le32 type;
+       __le32 id;
+       __le32 data_len;
 };
 
 /**
@@ -74,10 +75,10 @@ struct qcom_rpm_request {
  * Multiple of these messages can be stacked in an rpm message.
  */
 struct qcom_rpm_message {
-       u32 msg_type;
-       u32 length;
+       __le32 msg_type;
+       __le32 length;
        union {
-               u32 msg_id;
+               __le32 msg_id;
                u8 message[0];
        };
 };
@@ -104,30 +105,34 @@ int qcom_rpm_smd_write(struct qcom_smd_rpm *rpm,
        static unsigned msg_id = 1;
        int left;
        int ret;
-
        struct {
                struct qcom_rpm_header hdr;
                struct qcom_rpm_request req;
-               u8 payload[count];
-       } pkt;
+               u8 payload[];
+       } *pkt;
+       size_t size = sizeof(*pkt) + count;
 
        /* SMD packets to the RPM may not exceed 256 bytes */
-       if (WARN_ON(sizeof(pkt) >= 256))
+       if (WARN_ON(size >= 256))
                return -EINVAL;
 
+       pkt = kmalloc(size, GFP_KERNEL);
+       if (!pkt)
+               return -ENOMEM;
+
        mutex_lock(&rpm->lock);
 
-       pkt.hdr.service_type = RPM_SERVICE_TYPE_REQUEST;
-       pkt.hdr.length = sizeof(struct qcom_rpm_request) + count;
+       pkt->hdr.service_type = cpu_to_le32(RPM_SERVICE_TYPE_REQUEST);
+       pkt->hdr.length = cpu_to_le32(sizeof(struct qcom_rpm_request) + count);
 
-       pkt.req.msg_id = msg_id++;
-       pkt.req.flags = BIT(state);
-       pkt.req.type = type;
-       pkt.req.id = id;
-       pkt.req.data_len = count;
-       memcpy(pkt.payload, buf, count);
+       pkt->req.msg_id = cpu_to_le32(msg_id++);
+       pkt->req.flags = cpu_to_le32(state);
+       pkt->req.type = cpu_to_le32(type);
+       pkt->req.id = cpu_to_le32(id);
+       pkt->req.data_len = cpu_to_le32(count);
+       memcpy(pkt->payload, buf, count);
 
-       ret = qcom_smd_send(rpm->rpm_channel, &pkt, sizeof(pkt));
+       ret = qcom_smd_send(rpm->rpm_channel, pkt, sizeof(*pkt));
        if (ret)
                goto out;
 
@@ -138,6 +143,7 @@ int qcom_rpm_smd_write(struct qcom_smd_rpm *rpm,
                ret = rpm->ack_status;
 
 out:
+       kfree(pkt);
        mutex_unlock(&rpm->lock);
        return ret;
 }
@@ -148,27 +154,29 @@ static int qcom_smd_rpm_callback(struct qcom_smd_device *qsdev,
                                 size_t count)
 {
        const struct qcom_rpm_header *hdr = data;
+       size_t hdr_length = le32_to_cpu(hdr->length);
        const struct qcom_rpm_message *msg;
        struct qcom_smd_rpm *rpm = dev_get_drvdata(&qsdev->dev);
        const u8 *buf = data + sizeof(struct qcom_rpm_header);
-       const u8 *end = buf + hdr->length;
+       const u8 *end = buf + hdr_length;
        char msgbuf[32];
        int status = 0;
-       u32 len;
+       u32 len, msg_length;
 
-       if (hdr->service_type != RPM_SERVICE_TYPE_REQUEST ||
-           hdr->length < sizeof(struct qcom_rpm_message)) {
+       if (le32_to_cpu(hdr->service_type) != RPM_SERVICE_TYPE_REQUEST ||
+           hdr_length < sizeof(struct qcom_rpm_message)) {
                dev_err(&qsdev->dev, "invalid request\n");
                return 0;
        }
 
        while (buf < end) {
                msg = (struct qcom_rpm_message *)buf;
-               switch (msg->msg_type) {
+               msg_length = le32_to_cpu(msg->length);
+               switch (le32_to_cpu(msg->msg_type)) {
                case RPM_MSG_TYPE_MSG_ID:
                        break;
                case RPM_MSG_TYPE_ERR:
-                       len = min_t(u32, ALIGN(msg->length, 4), sizeof(msgbuf));
+                       len = min_t(u32, ALIGN(msg_length, 4), sizeof(msgbuf));
                        memcpy_fromio(msgbuf, msg->message, len);
                        msgbuf[len - 1] = 0;
 
@@ -179,7 +187,7 @@ static int qcom_smd_rpm_callback(struct qcom_smd_device *qsdev,
                        break;
                }
 
-               buf = PTR_ALIGN(buf + 2 * sizeof(u32) + msg->length, 4);
+               buf = PTR_ALIGN(buf + 2 * sizeof(u32) + msg_length, 4);
        }
 
        rpm->ack_status = status;
index a6155c917d52d03a088a2ccbbd5a25220f392c60..86b598cff91a95a38003a65682135989dfa8f3e3 100644 (file)
@@ -65,7 +65,9 @@
  */
 
 struct smd_channel_info;
+struct smd_channel_info_pair;
 struct smd_channel_info_word;
+struct smd_channel_info_word_pair;
 
 #define SMD_ALLOC_TBL_COUNT    2
 #define SMD_ALLOC_TBL_SIZE     64
@@ -85,8 +87,8 @@ static const struct {
                .fifo_base_id = 338
        },
        {
-               .alloc_tbl_id = 14,
-               .info_base_id = 266,
+               .alloc_tbl_id = 266,
+               .info_base_id = 138,
                .fifo_base_id = 202,
        },
 };
@@ -151,10 +153,8 @@ enum smd_channel_state {
  * @name:              name of the channel
  * @state:             local state of the channel
  * @remote_state:      remote state of the channel
- * @tx_info:           byte aligned outgoing channel info
- * @rx_info:           byte aligned incoming channel info
- * @tx_info_word:      word aligned outgoing channel info
- * @rx_info_word:      word aligned incoming channel info
+ * @info:              byte aligned outgoing/incoming channel info
+ * @info_word:         word aligned outgoing/incoming channel info
  * @tx_lock:           lock to make writes to the channel mutually exclusive
  * @fblockread_event:  wakeup event tied to tx fBLOCKREADINTR
  * @tx_fifo:           pointer to the outgoing ring buffer
@@ -175,11 +175,8 @@ struct qcom_smd_channel {
        enum smd_channel_state state;
        enum smd_channel_state remote_state;
 
-       struct smd_channel_info *tx_info;
-       struct smd_channel_info *rx_info;
-
-       struct smd_channel_info_word *tx_info_word;
-       struct smd_channel_info_word *rx_info_word;
+       struct smd_channel_info_pair *info;
+       struct smd_channel_info_word_pair *info_word;
 
        struct mutex tx_lock;
        wait_queue_head_t fblockread_event;
@@ -215,7 +212,7 @@ struct qcom_smd {
  * Format of the smd_info smem items, for byte aligned channels.
  */
 struct smd_channel_info {
-       u32 state;
+       __le32 state;
        u8  fDSR;
        u8  fCTS;
        u8  fCD;
@@ -224,46 +221,104 @@ struct smd_channel_info {
        u8  fTAIL;
        u8  fSTATE;
        u8  fBLOCKREADINTR;
-       u32 tail;
-       u32 head;
+       __le32 tail;
+       __le32 head;
+};
+
+struct smd_channel_info_pair {
+       struct smd_channel_info tx;
+       struct smd_channel_info rx;
 };
 
 /*
  * Format of the smd_info smem items, for word aligned channels.
  */
 struct smd_channel_info_word {
-       u32 state;
-       u32 fDSR;
-       u32 fCTS;
-       u32 fCD;
-       u32 fRI;
-       u32 fHEAD;
-       u32 fTAIL;
-       u32 fSTATE;
-       u32 fBLOCKREADINTR;
-       u32 tail;
-       u32 head;
+       __le32 state;
+       __le32 fDSR;
+       __le32 fCTS;
+       __le32 fCD;
+       __le32 fRI;
+       __le32 fHEAD;
+       __le32 fTAIL;
+       __le32 fSTATE;
+       __le32 fBLOCKREADINTR;
+       __le32 tail;
+       __le32 head;
 };
 
-#define GET_RX_CHANNEL_INFO(channel, param) \
-       (channel->rx_info_word ? \
-               channel->rx_info_word->param : \
-               channel->rx_info->param)
-
-#define SET_RX_CHANNEL_INFO(channel, param, value) \
-       (channel->rx_info_word ? \
-               (channel->rx_info_word->param = value) : \
-               (channel->rx_info->param = value))
-
-#define GET_TX_CHANNEL_INFO(channel, param) \
-       (channel->tx_info_word ? \
-               channel->tx_info_word->param : \
-               channel->tx_info->param)
+struct smd_channel_info_word_pair {
+       struct smd_channel_info_word tx;
+       struct smd_channel_info_word rx;
+};
 
-#define SET_TX_CHANNEL_INFO(channel, param, value) \
-       (channel->tx_info_word ? \
-               (channel->tx_info_word->param = value) : \
-               (channel->tx_info->param = value))
+#define GET_RX_CHANNEL_FLAG(channel, param)                                 \
+       ({                                                                   \
+               BUILD_BUG_ON(sizeof(channel->info->rx.param) != sizeof(u8)); \
+               channel->info_word ?                                         \
+                       le32_to_cpu(channel->info_word->rx.param) :          \
+                       channel->info->rx.param;                             \
+       })
+
+#define GET_RX_CHANNEL_INFO(channel, param)                                  \
+       ({                                                                    \
+               BUILD_BUG_ON(sizeof(channel->info->rx.param) != sizeof(u32)); \
+               le32_to_cpu(channel->info_word ?                              \
+                       channel->info_word->rx.param :                        \
+                       channel->info->rx.param);                             \
+       })
+
+#define SET_RX_CHANNEL_FLAG(channel, param, value)                          \
+       ({                                                                   \
+               BUILD_BUG_ON(sizeof(channel->info->rx.param) != sizeof(u8)); \
+               if (channel->info_word)                                      \
+                       channel->info_word->rx.param = cpu_to_le32(value);   \
+               else                                                         \
+                       channel->info->rx.param = value;                     \
+       })
+
+#define SET_RX_CHANNEL_INFO(channel, param, value)                           \
+       ({                                                                    \
+               BUILD_BUG_ON(sizeof(channel->info->rx.param) != sizeof(u32)); \
+               if (channel->info_word)                                       \
+                       channel->info_word->rx.param = cpu_to_le32(value);    \
+               else                                                          \
+                       channel->info->rx.param = cpu_to_le32(value);         \
+       })
+
+#define GET_TX_CHANNEL_FLAG(channel, param)                                 \
+       ({                                                                   \
+               BUILD_BUG_ON(sizeof(channel->info->tx.param) != sizeof(u8)); \
+               channel->info_word ?                                         \
+                       le32_to_cpu(channel->info_word->tx.param) :          \
+                       channel->info->tx.param;                             \
+       })
+
+#define GET_TX_CHANNEL_INFO(channel, param)                                  \
+       ({                                                                    \
+               BUILD_BUG_ON(sizeof(channel->info->tx.param) != sizeof(u32)); \
+               le32_to_cpu(channel->info_word ?                              \
+                       channel->info_word->tx.param :                        \
+                       channel->info->tx.param);                             \
+       })
+
+#define SET_TX_CHANNEL_FLAG(channel, param, value)                          \
+       ({                                                                   \
+               BUILD_BUG_ON(sizeof(channel->info->tx.param) != sizeof(u8)); \
+               if (channel->info_word)                                      \
+                       channel->info_word->tx.param = cpu_to_le32(value);   \
+               else                                                         \
+                       channel->info->tx.param = value;                     \
+       })
+
+#define SET_TX_CHANNEL_INFO(channel, param, value)                           \
+       ({                                                                    \
+               BUILD_BUG_ON(sizeof(channel->info->tx.param) != sizeof(u32)); \
+               if (channel->info_word)                                       \
+                       channel->info_word->tx.param = cpu_to_le32(value);   \
+               else                                                          \
+                       channel->info->tx.param = cpu_to_le32(value);         \
+       })
 
 /**
  * struct qcom_smd_alloc_entry - channel allocation entry
@@ -274,9 +329,9 @@ struct smd_channel_info_word {
  */
 struct qcom_smd_alloc_entry {
        u8 name[20];
-       u32 cid;
-       u32 flags;
-       u32 ref_count;
+       __le32 cid;
+       __le32 flags;
+       __le32 ref_count;
 } __packed;
 
 #define SMD_CHANNEL_FLAGS_EDGE_MASK    0xff
@@ -305,14 +360,14 @@ static void qcom_smd_signal_channel(struct qcom_smd_channel *channel)
 static void qcom_smd_channel_reset(struct qcom_smd_channel *channel)
 {
        SET_TX_CHANNEL_INFO(channel, state, SMD_CHANNEL_CLOSED);
-       SET_TX_CHANNEL_INFO(channel, fDSR, 0);
-       SET_TX_CHANNEL_INFO(channel, fCTS, 0);
-       SET_TX_CHANNEL_INFO(channel, fCD, 0);
-       SET_TX_CHANNEL_INFO(channel, fRI, 0);
-       SET_TX_CHANNEL_INFO(channel, fHEAD, 0);
-       SET_TX_CHANNEL_INFO(channel, fTAIL, 0);
-       SET_TX_CHANNEL_INFO(channel, fSTATE, 1);
-       SET_TX_CHANNEL_INFO(channel, fBLOCKREADINTR, 1);
+       SET_TX_CHANNEL_FLAG(channel, fDSR, 0);
+       SET_TX_CHANNEL_FLAG(channel, fCTS, 0);
+       SET_TX_CHANNEL_FLAG(channel, fCD, 0);
+       SET_TX_CHANNEL_FLAG(channel, fRI, 0);
+       SET_TX_CHANNEL_FLAG(channel, fHEAD, 0);
+       SET_TX_CHANNEL_FLAG(channel, fTAIL, 0);
+       SET_TX_CHANNEL_FLAG(channel, fSTATE, 1);
+       SET_TX_CHANNEL_FLAG(channel, fBLOCKREADINTR, 1);
        SET_TX_CHANNEL_INFO(channel, head, 0);
        SET_TX_CHANNEL_INFO(channel, tail, 0);
 
@@ -350,12 +405,12 @@ static void qcom_smd_channel_set_state(struct qcom_smd_channel *channel,
 
        dev_dbg(edge->smd->dev, "set_state(%s, %d)\n", channel->name, state);
 
-       SET_TX_CHANNEL_INFO(channel, fDSR, is_open);
-       SET_TX_CHANNEL_INFO(channel, fCTS, is_open);
-       SET_TX_CHANNEL_INFO(channel, fCD, is_open);
+       SET_TX_CHANNEL_FLAG(channel, fDSR, is_open);
+       SET_TX_CHANNEL_FLAG(channel, fCTS, is_open);
+       SET_TX_CHANNEL_FLAG(channel, fCD, is_open);
 
        SET_TX_CHANNEL_INFO(channel, state, state);
-       SET_TX_CHANNEL_INFO(channel, fSTATE, 1);
+       SET_TX_CHANNEL_FLAG(channel, fSTATE, 1);
 
        channel->state = state;
        qcom_smd_signal_channel(channel);
@@ -364,20 +419,15 @@ static void qcom_smd_channel_set_state(struct qcom_smd_channel *channel,
 /*
  * Copy count bytes of data using 32bit accesses, if that's required.
  */
-static void smd_copy_to_fifo(void __iomem *_dst,
-                            const void *_src,
+static void smd_copy_to_fifo(void __iomem *dst,
+                            const void *src,
                             size_t count,
                             bool word_aligned)
 {
-       u32 *dst = (u32 *)_dst;
-       u32 *src = (u32 *)_src;
-
        if (word_aligned) {
-               count /= sizeof(u32);
-               while (count--)
-                       writel_relaxed(*src++, dst++);
+               __iowrite32_copy(dst, src, count / sizeof(u32));
        } else {
-               memcpy_toio(_dst, _src, count);
+               memcpy_toio(dst, src, count);
        }
 }
 
@@ -395,7 +445,7 @@ static void smd_copy_from_fifo(void *_dst,
        if (word_aligned) {
                count /= sizeof(u32);
                while (count--)
-                       *dst++ = readl_relaxed(src++);
+                       *dst++ = __raw_readl(src++);
        } else {
                memcpy_fromio(_dst, _src, count);
        }
@@ -412,7 +462,7 @@ static size_t qcom_smd_channel_peek(struct qcom_smd_channel *channel,
        unsigned tail;
        size_t len;
 
-       word_aligned = channel->rx_info_word != NULL;
+       word_aligned = channel->info_word;
        tail = GET_RX_CHANNEL_INFO(channel, tail);
 
        len = min_t(size_t, count, channel->fifo_size - tail);
@@ -491,7 +541,7 @@ static bool qcom_smd_channel_intr(struct qcom_smd_channel *channel)
 {
        bool need_state_scan = false;
        int remote_state;
-       u32 pktlen;
+       __le32 pktlen;
        int avail;
        int ret;
 
@@ -502,10 +552,10 @@ static bool qcom_smd_channel_intr(struct qcom_smd_channel *channel)
                need_state_scan = true;
        }
        /* Indicate that we have seen any state change */
-       SET_RX_CHANNEL_INFO(channel, fSTATE, 0);
+       SET_RX_CHANNEL_FLAG(channel, fSTATE, 0);
 
        /* Signal waiting qcom_smd_send() about the interrupt */
-       if (!GET_TX_CHANNEL_INFO(channel, fBLOCKREADINTR))
+       if (!GET_TX_CHANNEL_FLAG(channel, fBLOCKREADINTR))
                wake_up_interruptible(&channel->fblockread_event);
 
        /* Don't consume any data until we've opened the channel */
@@ -513,7 +563,7 @@ static bool qcom_smd_channel_intr(struct qcom_smd_channel *channel)
                goto out;
 
        /* Indicate that we've seen the new data */
-       SET_RX_CHANNEL_INFO(channel, fHEAD, 0);
+       SET_RX_CHANNEL_FLAG(channel, fHEAD, 0);
 
        /* Consume data */
        for (;;) {
@@ -522,7 +572,7 @@ static bool qcom_smd_channel_intr(struct qcom_smd_channel *channel)
                if (!channel->pkt_size && avail >= SMD_PACKET_HEADER_LEN) {
                        qcom_smd_channel_peek(channel, &pktlen, sizeof(pktlen));
                        qcom_smd_channel_advance(channel, SMD_PACKET_HEADER_LEN);
-                       channel->pkt_size = pktlen;
+                       channel->pkt_size = le32_to_cpu(pktlen);
                } else if (channel->pkt_size && avail >= channel->pkt_size) {
                        ret = qcom_smd_channel_recv_single(channel);
                        if (ret)
@@ -533,10 +583,10 @@ static bool qcom_smd_channel_intr(struct qcom_smd_channel *channel)
        }
 
        /* Indicate that we have seen and updated tail */
-       SET_RX_CHANNEL_INFO(channel, fTAIL, 1);
+       SET_RX_CHANNEL_FLAG(channel, fTAIL, 1);
 
        /* Signal the remote that we've consumed the data (if requested) */
-       if (!GET_RX_CHANNEL_INFO(channel, fBLOCKREADINTR)) {
+       if (!GET_RX_CHANNEL_FLAG(channel, fBLOCKREADINTR)) {
                /* Ensure ordering of channel info updates */
                wmb();
 
@@ -627,7 +677,7 @@ static int qcom_smd_write_fifo(struct qcom_smd_channel *channel,
        unsigned head;
        size_t len;
 
-       word_aligned = channel->tx_info_word != NULL;
+       word_aligned = channel->info_word;
        head = GET_TX_CHANNEL_INFO(channel, head);
 
        len = min_t(size_t, count, channel->fifo_size - head);
@@ -665,12 +715,16 @@ static int qcom_smd_write_fifo(struct qcom_smd_channel *channel,
  */
 int qcom_smd_send(struct qcom_smd_channel *channel, const void *data, int len)
 {
-       u32 hdr[5] = {len,};
+       __le32 hdr[5] = { cpu_to_le32(len), };
        int tlen = sizeof(hdr) + len;
        int ret;
 
        /* Word aligned channels only accept word size aligned data */
-       if (channel->rx_info_word != NULL && len % 4)
+       if (channel->info_word && len % 4)
+               return -EINVAL;
+
+       /* Reject packets that are too big */
+       if (tlen >= channel->fifo_size)
                return -EINVAL;
 
        ret = mutex_lock_interruptible(&channel->tx_lock);
@@ -683,7 +737,7 @@ int qcom_smd_send(struct qcom_smd_channel *channel, const void *data, int len)
                        goto out;
                }
 
-               SET_TX_CHANNEL_INFO(channel, fBLOCKREADINTR, 0);
+               SET_TX_CHANNEL_FLAG(channel, fBLOCKREADINTR, 0);
 
                ret = wait_event_interruptible(channel->fblockread_event,
                                       qcom_smd_get_tx_avail(channel) >= tlen ||
@@ -691,15 +745,15 @@ int qcom_smd_send(struct qcom_smd_channel *channel, const void *data, int len)
                if (ret)
                        goto out;
 
-               SET_TX_CHANNEL_INFO(channel, fBLOCKREADINTR, 1);
+               SET_TX_CHANNEL_FLAG(channel, fBLOCKREADINTR, 1);
        }
 
-       SET_TX_CHANNEL_INFO(channel, fTAIL, 0);
+       SET_TX_CHANNEL_FLAG(channel, fTAIL, 0);
 
        qcom_smd_write_fifo(channel, hdr, sizeof(hdr));
        qcom_smd_write_fifo(channel, data, len);
 
-       SET_TX_CHANNEL_INFO(channel, fHEAD, 1);
+       SET_TX_CHANNEL_FLAG(channel, fHEAD, 1);
 
        /* Ensure ordering of channel info updates */
        wmb();
@@ -727,6 +781,19 @@ static struct qcom_smd_driver *to_smd_driver(struct device *dev)
 
 static int qcom_smd_dev_match(struct device *dev, struct device_driver *drv)
 {
+       struct qcom_smd_device *qsdev = to_smd_device(dev);
+       struct qcom_smd_driver *qsdrv = container_of(drv, struct qcom_smd_driver, driver);
+       const struct qcom_smd_id *match = qsdrv->smd_match_table;
+       const char *name = qsdev->channel->name;
+
+       if (match) {
+               while (match->name[0]) {
+                       if (!strcmp(match->name, name))
+                               return 1;
+                       match++;
+               }
+       }
+
        return of_driver_match_device(dev, drv);
 }
 
@@ -854,10 +921,8 @@ static struct device_node *qcom_smd_match_channel(struct device_node *edge_node,
        for_each_available_child_of_node(edge_node, child) {
                key = "qcom,smd-channels";
                ret = of_property_read_string(child, key, &name);
-               if (ret) {
-                       of_node_put(child);
+               if (ret)
                        continue;
-               }
 
                if (strcmp(name, channel) == 0)
                        return child;
@@ -880,19 +945,17 @@ static int qcom_smd_create_device(struct qcom_smd_channel *channel)
        if (channel->qsdev)
                return -EEXIST;
 
-       node = qcom_smd_match_channel(edge->of_node, channel->name);
-       if (!node) {
-               dev_dbg(smd->dev, "no match for '%s'\n", channel->name);
-               return -ENXIO;
-       }
-
        dev_dbg(smd->dev, "registering '%s'\n", channel->name);
 
        qsdev = kzalloc(sizeof(*qsdev), GFP_KERNEL);
        if (!qsdev)
                return -ENOMEM;
 
-       dev_set_name(&qsdev->dev, "%s.%s", edge->of_node->name, node->name);
+       node = qcom_smd_match_channel(edge->of_node, channel->name);
+       dev_set_name(&qsdev->dev, "%s.%s",
+                    edge->of_node->name,
+                    node ? node->name : channel->name);
+
        qsdev->dev.parent = smd->dev;
        qsdev->dev.bus = &qcom_smd_bus;
        qsdev->dev.release = qcom_smd_release_device;
@@ -978,21 +1041,20 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed
        spin_lock_init(&channel->recv_lock);
        init_waitqueue_head(&channel->fblockread_event);
 
-       ret = qcom_smem_get(edge->remote_pid, smem_info_item, (void **)&info,
-                           &info_size);
-       if (ret)
+       info = qcom_smem_get(edge->remote_pid, smem_info_item, &info_size);
+       if (IS_ERR(info)) {
+               ret = PTR_ERR(info);
                goto free_name_and_channel;
+       }
 
        /*
         * Use the size of the item to figure out which channel info struct to
         * use.
         */
        if (info_size == 2 * sizeof(struct smd_channel_info_word)) {
-               channel->tx_info_word = info;
-               channel->rx_info_word = info + sizeof(struct smd_channel_info_word);
+               channel->info_word = info;
        } else if (info_size == 2 * sizeof(struct smd_channel_info)) {
-               channel->tx_info = info;
-               channel->rx_info = info + sizeof(struct smd_channel_info);
+               channel->info = info;
        } else {
                dev_err(smd->dev,
                        "channel info of size %zu not supported\n", info_size);
@@ -1000,10 +1062,11 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed
                goto free_name_and_channel;
        }
 
-       ret = qcom_smem_get(edge->remote_pid, smem_fifo_item, &fifo_base,
-                           &fifo_size);
-       if (ret)
+       fifo_base = qcom_smem_get(edge->remote_pid, smem_fifo_item, &fifo_size);
+       if (IS_ERR(fifo_base)) {
+               ret =  PTR_ERR(fifo_base);
                goto free_name_and_channel;
+       }
 
        /* The channel consist of a rx and tx fifo of equal size */
        fifo_size /= 2;
@@ -1040,20 +1103,19 @@ static void qcom_discover_channels(struct qcom_smd_edge *edge)
        unsigned long flags;
        unsigned fifo_id;
        unsigned info_id;
-       int ret;
        int tbl;
        int i;
+       u32 eflags, cid;
 
        for (tbl = 0; tbl < SMD_ALLOC_TBL_COUNT; tbl++) {
-               ret = qcom_smem_get(edge->remote_pid,
-                                   smem_items[tbl].alloc_tbl_id,
-                                   (void **)&alloc_tbl,
-                                   NULL);
-               if (ret < 0)
+               alloc_tbl = qcom_smem_get(edge->remote_pid,
+                                   smem_items[tbl].alloc_tbl_id, NULL);
+               if (IS_ERR(alloc_tbl))
                        continue;
 
                for (i = 0; i < SMD_ALLOC_TBL_SIZE; i++) {
                        entry = &alloc_tbl[i];
+                       eflags = le32_to_cpu(entry->flags);
                        if (test_bit(i, edge->allocated[tbl]))
                                continue;
 
@@ -1063,14 +1125,15 @@ static void qcom_discover_channels(struct qcom_smd_edge *edge)
                        if (!entry->name[0])
                                continue;
 
-                       if (!(entry->flags & SMD_CHANNEL_FLAGS_PACKET))
+                       if (!(eflags & SMD_CHANNEL_FLAGS_PACKET))
                                continue;
 
-                       if ((entry->flags & SMD_CHANNEL_FLAGS_EDGE_MASK) != edge->edge_id)
+                       if ((eflags & SMD_CHANNEL_FLAGS_EDGE_MASK) != edge->edge_id)
                                continue;
 
-                       info_id = smem_items[tbl].info_base_id + entry->cid;
-                       fifo_id = smem_items[tbl].fifo_base_id + entry->cid;
+                       cid = le32_to_cpu(entry->cid);
+                       info_id = smem_items[tbl].info_base_id + cid;
+                       fifo_id = smem_items[tbl].fifo_base_id + cid;
 
                        channel = qcom_smd_create_channel(edge, info_id, fifo_id, entry->name);
                        if (IS_ERR(channel))
@@ -1227,11 +1290,12 @@ static int qcom_smd_probe(struct platform_device *pdev)
        int num_edges;
        int ret;
        int i = 0;
+       void *p;
 
        /* Wait for smem */
-       ret = qcom_smem_get(QCOM_SMEM_HOST_ANY, smem_items[0].alloc_tbl_id, NULL, NULL);
-       if (ret == -EPROBE_DEFER)
-               return ret;
+       p = qcom_smem_get(QCOM_SMEM_HOST_ANY, smem_items[0].alloc_tbl_id, NULL);
+       if (PTR_ERR(p) == -EPROBE_DEFER)
+               return PTR_ERR(p);
 
        num_edges = of_get_available_child_count(pdev->dev.of_node);
        array_size = sizeof(*smd) + num_edges * sizeof(struct qcom_smd_edge);
index 52365188a1c20288a754dc7e1a530e4b25570ac3..19019aa092e86d76ad5a24b80f34616b9e38e320 100644 (file)
@@ -92,9 +92,9 @@
   * @params:   parameters to the command
   */
 struct smem_proc_comm {
-       u32 command;
-       u32 status;
-       u32 params[2];
+       __le32 command;
+       __le32 status;
+       __le32 params[2];
 };
 
 /**
@@ -106,10 +106,10 @@ struct smem_proc_comm {
  *             the default region. bits 0,1 are reserved
  */
 struct smem_global_entry {
-       u32 allocated;
-       u32 offset;
-       u32 size;
-       u32 aux_base; /* bits 1:0 reserved */
+       __le32 allocated;
+       __le32 offset;
+       __le32 size;
+       __le32 aux_base; /* bits 1:0 reserved */
 };
 #define AUX_BASE_MASK          0xfffffffc
 
@@ -125,11 +125,11 @@ struct smem_global_entry {
  */
 struct smem_header {
        struct smem_proc_comm proc_comm[4];
-       u32 version[32];
-       u32 initialized;
-       u32 free_offset;
-       u32 available;
-       u32 reserved;
+       __le32 version[32];
+       __le32 initialized;
+       __le32 free_offset;
+       __le32 available;
+       __le32 reserved;
        struct smem_global_entry toc[SMEM_ITEM_COUNT];
 };
 
@@ -143,12 +143,12 @@ struct smem_header {
  * @reserved:  reserved entries for later use
  */
 struct smem_ptable_entry {
-       u32 offset;
-       u32 size;
-       u32 flags;
-       u16 host0;
-       u16 host1;
-       u32 reserved[8];
+       __le32 offset;
+       __le32 size;
+       __le32 flags;
+       __le16 host0;
+       __le16 host1;
+       __le32 reserved[8];
 };
 
 /**
@@ -160,13 +160,14 @@ struct smem_ptable_entry {
  * @entry:     list of @smem_ptable_entry for the @num_entries partitions
  */
 struct smem_ptable {
-       u32 magic;
-       u32 version;
-       u32 num_entries;
-       u32 reserved[5];
+       u8 magic[4];
+       __le32 version;
+       __le32 num_entries;
+       __le32 reserved[5];
        struct smem_ptable_entry entry[];
 };
-#define SMEM_PTABLE_MAGIC      0x434f5424 /* "$TOC" */
+
+static const u8 SMEM_PTABLE_MAGIC[] = { 0x24, 0x54, 0x4f, 0x43 }; /* "$TOC" */
 
 /**
  * struct smem_partition_header - header of the partitions
@@ -181,15 +182,16 @@ struct smem_ptable {
  * @reserved:  for now reserved entries
  */
 struct smem_partition_header {
-       u32 magic;
-       u16 host0;
-       u16 host1;
-       u32 size;
-       u32 offset_free_uncached;
-       u32 offset_free_cached;
-       u32 reserved[3];
+       u8 magic[4];
+       __le16 host0;
+       __le16 host1;
+       __le32 size;
+       __le32 offset_free_uncached;
+       __le32 offset_free_cached;
+       __le32 reserved[3];
 };
-#define SMEM_PART_MAGIC                0x54525024 /* "$PRT" */
+
+static const u8 SMEM_PART_MAGIC[] = { 0x24, 0x50, 0x52, 0x54 };
 
 /**
  * struct smem_private_entry - header of each item in the private partition
@@ -201,12 +203,12 @@ struct smem_partition_header {
  * @reserved:  for now reserved entry
  */
 struct smem_private_entry {
-       u16 canary;
-       u16 item;
-       u32 size; /* includes padding bytes */
-       u16 padding_data;
-       u16 padding_hdr;
-       u32 reserved;
+       u16 canary; /* bytes are the same so no swapping needed */
+       __le16 item;
+       __le32 size; /* includes padding bytes */
+       __le16 padding_data;
+       __le16 padding_hdr;
+       __le32 reserved;
 };
 #define SMEM_PRIVATE_CANARY    0xa5a5
 
@@ -242,6 +244,45 @@ struct qcom_smem {
        struct smem_region regions[0];
 };
 
+static struct smem_private_entry *
+phdr_to_last_private_entry(struct smem_partition_header *phdr)
+{
+       void *p = phdr;
+
+       return p + le32_to_cpu(phdr->offset_free_uncached);
+}
+
+static void *phdr_to_first_cached_entry(struct smem_partition_header *phdr)
+{
+       void *p = phdr;
+
+       return p + le32_to_cpu(phdr->offset_free_cached);
+}
+
+static struct smem_private_entry *
+phdr_to_first_private_entry(struct smem_partition_header *phdr)
+{
+       void *p = phdr;
+
+       return p + sizeof(*phdr);
+}
+
+static struct smem_private_entry *
+private_entry_next(struct smem_private_entry *e)
+{
+       void *p = e;
+
+       return p + sizeof(*e) + le16_to_cpu(e->padding_hdr) +
+              le32_to_cpu(e->size);
+}
+
+static void *entry_to_item(struct smem_private_entry *e)
+{
+       void *p = e;
+
+       return p + sizeof(*e) + le16_to_cpu(e->padding_hdr);
+}
+
 /* Pointer to the one and only smem handle */
 static struct qcom_smem *__smem;
 
@@ -254,16 +295,16 @@ static int qcom_smem_alloc_private(struct qcom_smem *smem,
                                   size_t size)
 {
        struct smem_partition_header *phdr;
-       struct smem_private_entry *hdr;
+       struct smem_private_entry *hdr, *end;
        size_t alloc_size;
-       void *p;
+       void *cached;
 
        phdr = smem->partitions[host];
+       hdr = phdr_to_first_private_entry(phdr);
+       end = phdr_to_last_private_entry(phdr);
+       cached = phdr_to_first_cached_entry(phdr);
 
-       p = (void *)phdr + sizeof(*phdr);
-       while (p < (void *)phdr + phdr->offset_free_uncached) {
-               hdr = p;
-
+       while (hdr < end) {
                if (hdr->canary != SMEM_PRIVATE_CANARY) {
                        dev_err(smem->dev,
                                "Found invalid canary in host %d partition\n",
@@ -271,24 +312,23 @@ static int qcom_smem_alloc_private(struct qcom_smem *smem,
                        return -EINVAL;
                }
 
-               if (hdr->item == item)
+               if (le16_to_cpu(hdr->item) == item)
                        return -EEXIST;
 
-               p += sizeof(*hdr) + hdr->padding_hdr + hdr->size;
+               hdr = private_entry_next(hdr);
        }
 
        /* Check that we don't grow into the cached region */
        alloc_size = sizeof(*hdr) + ALIGN(size, 8);
-       if (p + alloc_size >= (void *)phdr + phdr->offset_free_cached) {
+       if ((void *)hdr + alloc_size >= cached) {
                dev_err(smem->dev, "Out of memory\n");
                return -ENOSPC;
        }
 
-       hdr = p;
        hdr->canary = SMEM_PRIVATE_CANARY;
-       hdr->item = item;
-       hdr->size = ALIGN(size, 8);
-       hdr->padding_data = hdr->size - size;
+       hdr->item = cpu_to_le16(item);
+       hdr->size = cpu_to_le32(ALIGN(size, 8));
+       hdr->padding_data = cpu_to_le16(le32_to_cpu(hdr->size) - size);
        hdr->padding_hdr = 0;
 
        /*
@@ -297,7 +337,7 @@ static int qcom_smem_alloc_private(struct qcom_smem *smem,
         * gets a consistent view of the linked list.
         */
        wmb();
-       phdr->offset_free_uncached += alloc_size;
+       le32_add_cpu(&phdr->offset_free_uncached, alloc_size);
 
        return 0;
 }
@@ -318,11 +358,11 @@ static int qcom_smem_alloc_global(struct qcom_smem *smem,
                return -EEXIST;
 
        size = ALIGN(size, 8);
-       if (WARN_ON(size > header->available))
+       if (WARN_ON(size > le32_to_cpu(header->available)))
                return -ENOMEM;
 
        entry->offset = header->free_offset;
-       entry->size = size;
+       entry->size = cpu_to_le32(size);
 
        /*
         * Ensure the header is consistent before we mark the item allocated,
@@ -330,10 +370,10 @@ static int qcom_smem_alloc_global(struct qcom_smem *smem,
         * even though they do not take the spinlock on read.
         */
        wmb();
-       entry->allocated = 1;
+       entry->allocated = cpu_to_le32(1);
 
-       header->free_offset += size;
-       header->available -= size;
+       le32_add_cpu(&header->free_offset, size);
+       le32_add_cpu(&header->available, -size);
 
        return 0;
 }
@@ -378,10 +418,9 @@ int qcom_smem_alloc(unsigned host, unsigned item, size_t size)
 }
 EXPORT_SYMBOL(qcom_smem_alloc);
 
-static int qcom_smem_get_global(struct qcom_smem *smem,
-                               unsigned item,
-                               void **ptr,
-                               size_t *size)
+static void *qcom_smem_get_global(struct qcom_smem *smem,
+                                 unsigned item,
+                                 size_t *size)
 {
        struct smem_header *header;
        struct smem_region *area;
@@ -390,100 +429,94 @@ static int qcom_smem_get_global(struct qcom_smem *smem,
        unsigned i;
 
        if (WARN_ON(item >= SMEM_ITEM_COUNT))
-               return -EINVAL;
+               return ERR_PTR(-EINVAL);
 
        header = smem->regions[0].virt_base;
        entry = &header->toc[item];
        if (!entry->allocated)
-               return -ENXIO;
+               return ERR_PTR(-ENXIO);
 
-       if (ptr != NULL) {
-               aux_base = entry->aux_base & AUX_BASE_MASK;
+       aux_base = le32_to_cpu(entry->aux_base) & AUX_BASE_MASK;
 
-               for (i = 0; i < smem->num_regions; i++) {
-                       area = &smem->regions[i];
+       for (i = 0; i < smem->num_regions; i++) {
+               area = &smem->regions[i];
 
-                       if (area->aux_base == aux_base || !aux_base) {
-                               *ptr = area->virt_base + entry->offset;
-                               break;
-                       }
+               if (area->aux_base == aux_base || !aux_base) {
+                       if (size != NULL)
+                               *size = le32_to_cpu(entry->size);
+                       return area->virt_base + le32_to_cpu(entry->offset);
                }
        }
-       if (size != NULL)
-               *size = entry->size;
 
-       return 0;
+       return ERR_PTR(-ENOENT);
 }
 
-static int qcom_smem_get_private(struct qcom_smem *smem,
-                                unsigned host,
-                                unsigned item,
-                                void **ptr,
-                                size_t *size)
+static void *qcom_smem_get_private(struct qcom_smem *smem,
+                                  unsigned host,
+                                  unsigned item,
+                                  size_t *size)
 {
        struct smem_partition_header *phdr;
-       struct smem_private_entry *hdr;
-       void *p;
+       struct smem_private_entry *e, *end;
 
        phdr = smem->partitions[host];
+       e = phdr_to_first_private_entry(phdr);
+       end = phdr_to_last_private_entry(phdr);
 
-       p = (void *)phdr + sizeof(*phdr);
-       while (p < (void *)phdr + phdr->offset_free_uncached) {
-               hdr = p;
-
-               if (hdr->canary != SMEM_PRIVATE_CANARY) {
+       while (e < end) {
+               if (e->canary != SMEM_PRIVATE_CANARY) {
                        dev_err(smem->dev,
                                "Found invalid canary in host %d partition\n",
                                host);
-                       return -EINVAL;
+                       return ERR_PTR(-EINVAL);
                }
 
-               if (hdr->item == item) {
-                       if (ptr != NULL)
-                               *ptr = p + sizeof(*hdr) + hdr->padding_hdr;
-
+               if (le16_to_cpu(e->item) == item) {
                        if (size != NULL)
-                               *size = hdr->size - hdr->padding_data;
+                               *size = le32_to_cpu(e->size) -
+                                       le16_to_cpu(e->padding_data);
 
-                       return 0;
+                       return entry_to_item(e);
                }
 
-               p += sizeof(*hdr) + hdr->padding_hdr + hdr->size;
+               e = private_entry_next(e);
        }
 
-       return -ENOENT;
+       return ERR_PTR(-ENOENT);
 }
 
 /**
  * qcom_smem_get() - resolve ptr of size of a smem item
  * @host:      the remote processor, or -1
  * @item:      smem item handle
- * @ptr:       pointer to be filled out with address of the item
  * @size:      pointer to be filled out with size of the item
  *
- * Looks up pointer and size of a smem item.
+ * Looks up smem item and returns pointer to it. Size of smem
+ * item is returned in @size.
  */
-int qcom_smem_get(unsigned host, unsigned item, void **ptr, size_t *size)
+void *qcom_smem_get(unsigned host, unsigned item, size_t *size)
 {
        unsigned long flags;
        int ret;
+       void *ptr = ERR_PTR(-EPROBE_DEFER);
 
        if (!__smem)
-               return -EPROBE_DEFER;
+               return ptr;
 
        ret = hwspin_lock_timeout_irqsave(__smem->hwlock,
                                          HWSPINLOCK_TIMEOUT,
                                          &flags);
        if (ret)
-               return ret;
+               return ERR_PTR(ret);
 
        if (host < SMEM_HOST_COUNT && __smem->partitions[host])
-               ret = qcom_smem_get_private(__smem, host, item, ptr, size);
+               ptr = qcom_smem_get_private(__smem, host, item, size);
        else
-               ret = qcom_smem_get_global(__smem, item, ptr, size);
+               ptr = qcom_smem_get_global(__smem, item, size);
 
        hwspin_unlock_irqrestore(__smem->hwlock, &flags);
-       return ret;
+
+       return ptr;
 
 }
 EXPORT_SYMBOL(qcom_smem_get);
@@ -506,10 +539,11 @@ int qcom_smem_get_free_space(unsigned host)
 
        if (host < SMEM_HOST_COUNT && __smem->partitions[host]) {
                phdr = __smem->partitions[host];
-               ret = phdr->offset_free_cached - phdr->offset_free_uncached;
+               ret = le32_to_cpu(phdr->offset_free_cached) -
+                     le32_to_cpu(phdr->offset_free_uncached);
        } else {
                header = __smem->regions[0].virt_base;
-               ret = header->available;
+               ret = le32_to_cpu(header->available);
        }
 
        return ret;
@@ -518,13 +552,11 @@ EXPORT_SYMBOL(qcom_smem_get_free_space);
 
 static int qcom_smem_get_sbl_version(struct qcom_smem *smem)
 {
-       unsigned *versions;
+       __le32 *versions;
        size_t size;
-       int ret;
 
-       ret = qcom_smem_get_global(smem, SMEM_ITEM_VERSION,
-                                  (void **)&versions, &size);
-       if (ret < 0) {
+       versions = qcom_smem_get_global(smem, SMEM_ITEM_VERSION, &size);
+       if (IS_ERR(versions)) {
                dev_err(smem->dev, "Unable to read the version item\n");
                return -ENOENT;
        }
@@ -534,7 +566,7 @@ static int qcom_smem_get_sbl_version(struct qcom_smem *smem)
                return -EINVAL;
        }
 
-       return versions[SMEM_MASTER_SBL_VERSION_INDEX];
+       return le32_to_cpu(versions[SMEM_MASTER_SBL_VERSION_INDEX]);
 }
 
 static int qcom_smem_enumerate_partitions(struct qcom_smem *smem,
@@ -544,35 +576,38 @@ static int qcom_smem_enumerate_partitions(struct qcom_smem *smem,
        struct smem_ptable_entry *entry;
        struct smem_ptable *ptable;
        unsigned remote_host;
+       u32 version, host0, host1;
        int i;
 
        ptable = smem->regions[0].virt_base + smem->regions[0].size - SZ_4K;
-       if (ptable->magic != SMEM_PTABLE_MAGIC)
+       if (memcmp(ptable->magic, SMEM_PTABLE_MAGIC, sizeof(ptable->magic)))
                return 0;
 
-       if (ptable->version != 1) {
+       version = le32_to_cpu(ptable->version);
+       if (version != 1) {
                dev_err(smem->dev,
-                       "Unsupported partition header version %d\n",
-                       ptable->version);
+                       "Unsupported partition header version %d\n", version);
                return -EINVAL;
        }
 
-       for (i = 0; i < ptable->num_entries; i++) {
+       for (i = 0; i < le32_to_cpu(ptable->num_entries); i++) {
                entry = &ptable->entry[i];
+               host0 = le16_to_cpu(entry->host0);
+               host1 = le16_to_cpu(entry->host1);
 
-               if (entry->host0 != local_host && entry->host1 != local_host)
+               if (host0 != local_host && host1 != local_host)
                        continue;
 
-               if (!entry->offset)
+               if (!le32_to_cpu(entry->offset))
                        continue;
 
-               if (!entry->size)
+               if (!le32_to_cpu(entry->size))
                        continue;
 
-               if (entry->host0 == local_host)
-                       remote_host = entry->host1;
+               if (host0 == local_host)
+                       remote_host = host1;
                else
-                       remote_host = entry->host0;
+                       remote_host = host0;
 
                if (remote_host >= SMEM_HOST_COUNT) {
                        dev_err(smem->dev,
@@ -588,21 +623,24 @@ static int qcom_smem_enumerate_partitions(struct qcom_smem *smem,
                        return -EINVAL;
                }
 
-               header = smem->regions[0].virt_base + entry->offset;
+               header = smem->regions[0].virt_base + le32_to_cpu(entry->offset);
+               host0 = le16_to_cpu(header->host0);
+               host1 = le16_to_cpu(header->host1);
 
-               if (header->magic != SMEM_PART_MAGIC) {
+               if (memcmp(header->magic, SMEM_PART_MAGIC,
+                           sizeof(header->magic))) {
                        dev_err(smem->dev,
                                "Partition %d has invalid magic\n", i);
                        return -EINVAL;
                }
 
-               if (header->host0 != local_host && header->host1 != local_host) {
+               if (host0 != local_host && host1 != local_host) {
                        dev_err(smem->dev,
                                "Partition %d hosts are invalid\n", i);
                        return -EINVAL;
                }
 
-               if (header->host0 != remote_host && header->host1 != remote_host) {
+               if (host0 != remote_host && host1 != remote_host) {
                        dev_err(smem->dev,
                                "Partition %d hosts are invalid\n", i);
                        return -EINVAL;
@@ -614,7 +652,7 @@ static int qcom_smem_enumerate_partitions(struct qcom_smem *smem,
                        return -EINVAL;
                }
 
-               if (header->offset_free_uncached > header->size) {
+               if (le32_to_cpu(header->offset_free_uncached) > le32_to_cpu(header->size)) {
                        dev_err(smem->dev,
                                "Partition %d has invalid free pointer\n", i);
                        return -EINVAL;
@@ -626,37 +664,47 @@ static int qcom_smem_enumerate_partitions(struct qcom_smem *smem,
        return 0;
 }
 
-static int qcom_smem_count_mem_regions(struct platform_device *pdev)
+static int qcom_smem_map_memory(struct qcom_smem *smem, struct device *dev,
+                               const char *name, int i)
 {
-       struct resource *res;
-       int num_regions = 0;
-       int i;
-
-       for (i = 0; i < pdev->num_resources; i++) {
-               res = &pdev->resource[i];
+       struct device_node *np;
+       struct resource r;
+       int ret;
 
-               if (resource_type(res) == IORESOURCE_MEM)
-                       num_regions++;
+       np = of_parse_phandle(dev->of_node, name, 0);
+       if (!np) {
+               dev_err(dev, "No %s specified\n", name);
+               return -EINVAL;
        }
 
-       return num_regions;
+       ret = of_address_to_resource(np, 0, &r);
+       of_node_put(np);
+       if (ret)
+               return ret;
+
+       smem->regions[i].aux_base = (u32)r.start;
+       smem->regions[i].size = resource_size(&r);
+       smem->regions[i].virt_base = devm_ioremap_nocache(dev, r.start,
+                                                         resource_size(&r));
+       if (!smem->regions[i].virt_base)
+               return -ENOMEM;
+
+       return 0;
 }
 
 static int qcom_smem_probe(struct platform_device *pdev)
 {
        struct smem_header *header;
-       struct device_node *np;
        struct qcom_smem *smem;
-       struct resource *res;
-       struct resource r;
        size_t array_size;
-       int num_regions = 0;
+       int num_regions;
        int hwlock_id;
        u32 version;
        int ret;
-       int i;
 
-       num_regions = qcom_smem_count_mem_regions(pdev) + 1;
+       num_regions = 1;
+       if (of_find_property(pdev->dev.of_node, "qcom,rpm-msg-ram", NULL))
+               num_regions++;
 
        array_size = num_regions * sizeof(struct smem_region);
        smem = devm_kzalloc(&pdev->dev, sizeof(*smem) + array_size, GFP_KERNEL);
@@ -666,39 +714,17 @@ static int qcom_smem_probe(struct platform_device *pdev)
        smem->dev = &pdev->dev;
        smem->num_regions = num_regions;
 
-       np = of_parse_phandle(pdev->dev.of_node, "memory-region", 0);
-       if (!np) {
-               dev_err(&pdev->dev, "No memory-region specified\n");
-               return -EINVAL;
-       }
-
-       ret = of_address_to_resource(np, 0, &r);
-       of_node_put(np);
+       ret = qcom_smem_map_memory(smem, &pdev->dev, "memory-region", 0);
        if (ret)
                return ret;
 
-       smem->regions[0].aux_base = (u32)r.start;
-       smem->regions[0].size = resource_size(&r);
-       smem->regions[0].virt_base = devm_ioremap_nocache(&pdev->dev,
-                                                         r.start,
-                                                         resource_size(&r));
-       if (!smem->regions[0].virt_base)
-               return -ENOMEM;
-
-       for (i = 1; i < num_regions; i++) {
-               res = platform_get_resource(pdev, IORESOURCE_MEM, i - 1);
-
-               smem->regions[i].aux_base = (u32)res->start;
-               smem->regions[i].size = resource_size(res);
-               smem->regions[i].virt_base = devm_ioremap_nocache(&pdev->dev,
-                                                                 res->start,
-                                                                 resource_size(res));
-               if (!smem->regions[i].virt_base)
-                       return -ENOMEM;
-       }
+       if (num_regions > 1 && (ret = qcom_smem_map_memory(smem, &pdev->dev,
+                                       "qcom,rpm-msg-ram", 1)))
+               return ret;
 
        header = smem->regions[0].virt_base;
-       if (header->initialized != 1 || header->reserved) {
+       if (le32_to_cpu(header->initialized) != 1 ||
+           le32_to_cpu(header->reserved)) {
                dev_err(&pdev->dev, "SMEM is not initialized by SBL\n");
                return -EINVAL;
        }
@@ -730,8 +756,8 @@ static int qcom_smem_probe(struct platform_device *pdev)
 
 static int qcom_smem_remove(struct platform_device *pdev)
 {
-       __smem = NULL;
        hwspin_lock_free(__smem->hwlock);
+       __smem = NULL;
 
        return 0;
 }
diff --git a/drivers/soc/rockchip/Kconfig b/drivers/soc/rockchip/Kconfig
new file mode 100644 (file)
index 0000000..7140ff8
--- /dev/null
@@ -0,0 +1,18 @@
+if ARCH_ROCKCHIP || COMPILE_TEST
+
+#
+# Rockchip Soc drivers
+#
+config ROCKCHIP_PM_DOMAINS
+        bool "Rockchip generic power domain"
+        depends on PM
+        select PM_GENERIC_DOMAINS
+        help
+          Say y here to enable power domain support.
+          In order to meet high performance and low power requirements, a power
+          management unit is designed or saving power when RK3288 in low power
+          mode. The RK3288 PMU is dedicated for managing the power of the whole chip.
+
+          If unsure, say N.
+
+endif
diff --git a/drivers/soc/rockchip/Makefile b/drivers/soc/rockchip/Makefile
new file mode 100644 (file)
index 0000000..3d73d06
--- /dev/null
@@ -0,0 +1,4 @@
+#
+# Rockchip Soc drivers
+#
+obj-$(CONFIG_ROCKCHIP_PM_DOMAINS) += pm_domains.o
diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c
new file mode 100644 (file)
index 0000000..534c589
--- /dev/null
@@ -0,0 +1,490 @@
+/*
+ * Rockchip Generic power domain support.
+ *
+ * Copyright (c) 2015 ROCKCHIP, Co. Ltd.
+ *
+ * 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/io.h>
+#include <linux/err.h>
+#include <linux/pm_clock.h>
+#include <linux/pm_domain.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/clk.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+#include <dt-bindings/power/rk3288-power.h>
+
+struct rockchip_domain_info {
+       int pwr_mask;
+       int status_mask;
+       int req_mask;
+       int idle_mask;
+       int ack_mask;
+};
+
+struct rockchip_pmu_info {
+       u32 pwr_offset;
+       u32 status_offset;
+       u32 req_offset;
+       u32 idle_offset;
+       u32 ack_offset;
+
+       u32 core_pwrcnt_offset;
+       u32 gpu_pwrcnt_offset;
+
+       unsigned int core_power_transition_time;
+       unsigned int gpu_power_transition_time;
+
+       int num_domains;
+       const struct rockchip_domain_info *domain_info;
+};
+
+struct rockchip_pm_domain {
+       struct generic_pm_domain genpd;
+       const struct rockchip_domain_info *info;
+       struct rockchip_pmu *pmu;
+       int num_clks;
+       struct clk *clks[];
+};
+
+struct rockchip_pmu {
+       struct device *dev;
+       struct regmap *regmap;
+       const struct rockchip_pmu_info *info;
+       struct mutex mutex; /* mutex lock for pmu */
+       struct genpd_onecell_data genpd_data;
+       struct generic_pm_domain *domains[];
+};
+
+#define to_rockchip_pd(gpd) container_of(gpd, struct rockchip_pm_domain, genpd)
+
+#define DOMAIN(pwr, status, req, idle, ack)    \
+{                                              \
+       .pwr_mask = BIT(pwr),                   \
+       .status_mask = BIT(status),             \
+       .req_mask = BIT(req),                   \
+       .idle_mask = BIT(idle),                 \
+       .ack_mask = BIT(ack),                   \
+}
+
+#define DOMAIN_RK3288(pwr, status, req)                \
+       DOMAIN(pwr, status, req, req, (req) + 16)
+
+static bool rockchip_pmu_domain_is_idle(struct rockchip_pm_domain *pd)
+{
+       struct rockchip_pmu *pmu = pd->pmu;
+       const struct rockchip_domain_info *pd_info = pd->info;
+       unsigned int val;
+
+       regmap_read(pmu->regmap, pmu->info->idle_offset, &val);
+       return (val & pd_info->idle_mask) == pd_info->idle_mask;
+}
+
+static int rockchip_pmu_set_idle_request(struct rockchip_pm_domain *pd,
+                                        bool idle)
+{
+       const struct rockchip_domain_info *pd_info = pd->info;
+       struct rockchip_pmu *pmu = pd->pmu;
+       unsigned int val;
+
+       regmap_update_bits(pmu->regmap, pmu->info->req_offset,
+                          pd_info->req_mask, idle ? -1U : 0);
+
+       dsb(sy);
+
+       do {
+               regmap_read(pmu->regmap, pmu->info->ack_offset, &val);
+       } while ((val & pd_info->ack_mask) != (idle ? pd_info->ack_mask : 0));
+
+       while (rockchip_pmu_domain_is_idle(pd) != idle)
+               cpu_relax();
+
+       return 0;
+}
+
+static bool rockchip_pmu_domain_is_on(struct rockchip_pm_domain *pd)
+{
+       struct rockchip_pmu *pmu = pd->pmu;
+       unsigned int val;
+
+       regmap_read(pmu->regmap, pmu->info->status_offset, &val);
+
+       /* 1'b0: power on, 1'b1: power off */
+       return !(val & pd->info->status_mask);
+}
+
+static void rockchip_do_pmu_set_power_domain(struct rockchip_pm_domain *pd,
+                                            bool on)
+{
+       struct rockchip_pmu *pmu = pd->pmu;
+
+       regmap_update_bits(pmu->regmap, pmu->info->pwr_offset,
+                          pd->info->pwr_mask, on ? 0 : -1U);
+
+       dsb(sy);
+
+       while (rockchip_pmu_domain_is_on(pd) != on)
+               cpu_relax();
+}
+
+static int rockchip_pd_power(struct rockchip_pm_domain *pd, bool power_on)
+{
+       int i;
+
+       mutex_lock(&pd->pmu->mutex);
+
+       if (rockchip_pmu_domain_is_on(pd) != power_on) {
+               for (i = 0; i < pd->num_clks; i++)
+                       clk_enable(pd->clks[i]);
+
+               if (!power_on) {
+                       /* FIXME: add code to save AXI_QOS */
+
+                       /* if powering down, idle request to NIU first */
+                       rockchip_pmu_set_idle_request(pd, true);
+               }
+
+               rockchip_do_pmu_set_power_domain(pd, power_on);
+
+               if (power_on) {
+                       /* if powering up, leave idle mode */
+                       rockchip_pmu_set_idle_request(pd, false);
+
+                       /* FIXME: add code to restore AXI_QOS */
+               }
+
+               for (i = pd->num_clks - 1; i >= 0; i--)
+                       clk_disable(pd->clks[i]);
+       }
+
+       mutex_unlock(&pd->pmu->mutex);
+       return 0;
+}
+
+static int rockchip_pd_power_on(struct generic_pm_domain *domain)
+{
+       struct rockchip_pm_domain *pd = to_rockchip_pd(domain);
+
+       return rockchip_pd_power(pd, true);
+}
+
+static int rockchip_pd_power_off(struct generic_pm_domain *domain)
+{
+       struct rockchip_pm_domain *pd = to_rockchip_pd(domain);
+
+       return rockchip_pd_power(pd, false);
+}
+
+static int rockchip_pd_attach_dev(struct generic_pm_domain *genpd,
+                                 struct device *dev)
+{
+       struct clk *clk;
+       int i;
+       int error;
+
+       dev_dbg(dev, "attaching to power domain '%s'\n", genpd->name);
+
+       error = pm_clk_create(dev);
+       if (error) {
+               dev_err(dev, "pm_clk_create failed %d\n", error);
+               return error;
+       }
+
+       i = 0;
+       while ((clk = of_clk_get(dev->of_node, i++)) && !IS_ERR(clk)) {
+               dev_dbg(dev, "adding clock '%pC' to list of PM clocks\n", clk);
+               error = pm_clk_add_clk(dev, clk);
+               if (error) {
+                       dev_err(dev, "pm_clk_add_clk failed %d\n", error);
+                       clk_put(clk);
+                       pm_clk_destroy(dev);
+                       return error;
+               }
+       }
+
+       return 0;
+}
+
+static void rockchip_pd_detach_dev(struct generic_pm_domain *genpd,
+                                  struct device *dev)
+{
+       dev_dbg(dev, "detaching from power domain '%s'\n", genpd->name);
+
+       pm_clk_destroy(dev);
+}
+
+static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
+                                     struct device_node *node)
+{
+       const struct rockchip_domain_info *pd_info;
+       struct rockchip_pm_domain *pd;
+       struct clk *clk;
+       int clk_cnt;
+       int i;
+       u32 id;
+       int error;
+
+       error = of_property_read_u32(node, "reg", &id);
+       if (error) {
+               dev_err(pmu->dev,
+                       "%s: failed to retrieve domain id (reg): %d\n",
+                       node->name, error);
+               return -EINVAL;
+       }
+
+       if (id >= pmu->info->num_domains) {
+               dev_err(pmu->dev, "%s: invalid domain id %d\n",
+                       node->name, id);
+               return -EINVAL;
+       }
+
+       pd_info = &pmu->info->domain_info[id];
+       if (!pd_info) {
+               dev_err(pmu->dev, "%s: undefined domain id %d\n",
+                       node->name, id);
+               return -EINVAL;
+       }
+
+       clk_cnt = of_count_phandle_with_args(node, "clocks", "#clock-cells");
+       pd = devm_kzalloc(pmu->dev,
+                         sizeof(*pd) + clk_cnt * sizeof(pd->clks[0]),
+                         GFP_KERNEL);
+       if (!pd)
+               return -ENOMEM;
+
+       pd->info = pd_info;
+       pd->pmu = pmu;
+
+       for (i = 0; i < clk_cnt; i++) {
+               clk = of_clk_get(node, i);
+               if (IS_ERR(clk)) {
+                       error = PTR_ERR(clk);
+                       dev_err(pmu->dev,
+                               "%s: failed to get clk at index %d: %d\n",
+                               node->name, i, error);
+                       goto err_out;
+               }
+
+               error = clk_prepare(clk);
+               if (error) {
+                       dev_err(pmu->dev,
+                               "%s: failed to prepare clk %pC (index %d): %d\n",
+                               node->name, clk, i, error);
+                       clk_put(clk);
+                       goto err_out;
+               }
+
+               pd->clks[pd->num_clks++] = clk;
+
+               dev_dbg(pmu->dev, "added clock '%pC' to domain '%s'\n",
+                       clk, node->name);
+       }
+
+       error = rockchip_pd_power(pd, true);
+       if (error) {
+               dev_err(pmu->dev,
+                       "failed to power on domain '%s': %d\n",
+                       node->name, error);
+               goto err_out;
+       }
+
+       pd->genpd.name = node->name;
+       pd->genpd.power_off = rockchip_pd_power_off;
+       pd->genpd.power_on = rockchip_pd_power_on;
+       pd->genpd.attach_dev = rockchip_pd_attach_dev;
+       pd->genpd.detach_dev = rockchip_pd_detach_dev;
+       pd->genpd.flags = GENPD_FLAG_PM_CLK;
+       pm_genpd_init(&pd->genpd, NULL, false);
+
+       pmu->genpd_data.domains[id] = &pd->genpd;
+       return 0;
+
+err_out:
+       while (--i >= 0) {
+               clk_unprepare(pd->clks[i]);
+               clk_put(pd->clks[i]);
+       }
+       return error;
+}
+
+static void rockchip_pm_remove_one_domain(struct rockchip_pm_domain *pd)
+{
+       int i;
+
+       for (i = 0; i < pd->num_clks; i++) {
+               clk_unprepare(pd->clks[i]);
+               clk_put(pd->clks[i]);
+       }
+
+       /* protect the zeroing of pm->num_clks */
+       mutex_lock(&pd->pmu->mutex);
+       pd->num_clks = 0;
+       mutex_unlock(&pd->pmu->mutex);
+
+       /* devm will free our memory */
+}
+
+static void rockchip_pm_domain_cleanup(struct rockchip_pmu *pmu)
+{
+       struct generic_pm_domain *genpd;
+       struct rockchip_pm_domain *pd;
+       int i;
+
+       for (i = 0; i < pmu->genpd_data.num_domains; i++) {
+               genpd = pmu->genpd_data.domains[i];
+               if (genpd) {
+                       pd = to_rockchip_pd(genpd);
+                       rockchip_pm_remove_one_domain(pd);
+               }
+       }
+
+       /* devm will free our memory */
+}
+
+static void rockchip_configure_pd_cnt(struct rockchip_pmu *pmu,
+                                     u32 domain_reg_offset,
+                                     unsigned int count)
+{
+       /* First configure domain power down transition count ... */
+       regmap_write(pmu->regmap, domain_reg_offset, count);
+       /* ... and then power up count. */
+       regmap_write(pmu->regmap, domain_reg_offset + 4, count);
+}
+
+static int rockchip_pm_domain_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct device_node *np = dev->of_node;
+       struct device_node *node;
+       struct device *parent;
+       struct rockchip_pmu *pmu;
+       const struct of_device_id *match;
+       const struct rockchip_pmu_info *pmu_info;
+       int error;
+
+       if (!np) {
+               dev_err(dev, "device tree node not found\n");
+               return -ENODEV;
+       }
+
+       match = of_match_device(dev->driver->of_match_table, dev);
+       if (!match || !match->data) {
+               dev_err(dev, "missing pmu data\n");
+               return -EINVAL;
+       }
+
+       pmu_info = match->data;
+
+       pmu = devm_kzalloc(dev,
+                          sizeof(*pmu) +
+                               pmu_info->num_domains * sizeof(pmu->domains[0]),
+                          GFP_KERNEL);
+       if (!pmu)
+               return -ENOMEM;
+
+       pmu->dev = &pdev->dev;
+       mutex_init(&pmu->mutex);
+
+       pmu->info = pmu_info;
+
+       pmu->genpd_data.domains = pmu->domains;
+       pmu->genpd_data.num_domains = pmu_info->num_domains;
+
+       parent = dev->parent;
+       if (!parent) {
+               dev_err(dev, "no parent for syscon devices\n");
+               return -ENODEV;
+       }
+
+       pmu->regmap = syscon_node_to_regmap(parent->of_node);
+
+       /*
+        * Configure power up and down transition delays for CORE
+        * and GPU domains.
+        */
+       rockchip_configure_pd_cnt(pmu, pmu_info->core_pwrcnt_offset,
+                                 pmu_info->core_power_transition_time);
+       rockchip_configure_pd_cnt(pmu, pmu_info->gpu_pwrcnt_offset,
+                                 pmu_info->gpu_power_transition_time);
+
+       error = -ENODEV;
+
+       for_each_available_child_of_node(np, node) {
+               error = rockchip_pm_add_one_domain(pmu, node);
+               if (error) {
+                       dev_err(dev, "failed to handle node %s: %d\n",
+                               node->name, error);
+                       goto err_out;
+               }
+       }
+
+       if (error) {
+               dev_dbg(dev, "no power domains defined\n");
+               goto err_out;
+       }
+
+       of_genpd_add_provider_onecell(np, &pmu->genpd_data);
+
+       return 0;
+
+err_out:
+       rockchip_pm_domain_cleanup(pmu);
+       return error;
+}
+
+static const struct rockchip_domain_info rk3288_pm_domains[] = {
+       [RK3288_PD_VIO]         = DOMAIN_RK3288(7, 7, 4),
+       [RK3288_PD_HEVC]        = DOMAIN_RK3288(14, 10, 9),
+       [RK3288_PD_VIDEO]       = DOMAIN_RK3288(8, 8, 3),
+       [RK3288_PD_GPU]         = DOMAIN_RK3288(9, 9, 2),
+};
+
+static const struct rockchip_pmu_info rk3288_pmu = {
+       .pwr_offset = 0x08,
+       .status_offset = 0x0c,
+       .req_offset = 0x10,
+       .idle_offset = 0x14,
+       .ack_offset = 0x14,
+
+       .core_pwrcnt_offset = 0x34,
+       .gpu_pwrcnt_offset = 0x3c,
+
+       .core_power_transition_time = 24, /* 1us */
+       .gpu_power_transition_time = 24, /* 1us */
+
+       .num_domains = ARRAY_SIZE(rk3288_pm_domains),
+       .domain_info = rk3288_pm_domains,
+};
+
+static const struct of_device_id rockchip_pm_domain_dt_match[] = {
+       {
+               .compatible = "rockchip,rk3288-power-controller",
+               .data = (void *)&rk3288_pmu,
+       },
+       { /* sentinel */ },
+};
+
+static struct platform_driver rockchip_pm_domain_driver = {
+       .probe = rockchip_pm_domain_probe,
+       .driver = {
+               .name   = "rockchip-pm-domain",
+               .of_match_table = rockchip_pm_domain_dt_match,
+               /*
+                * We can't forcibly eject devices form power domain,
+                * so we can't really remove power domains once they
+                * were added.
+                */
+               .suppress_bind_attrs = true,
+       },
+};
+
+static int __init rockchip_pm_domain_drv_register(void)
+{
+       return platform_driver_register(&rockchip_pm_domain_driver);
+}
+postcore_initcall(rockchip_pm_domain_drv_register);
index 51da2341280d76fcff7f0be7f7f4916363726fa5..6ff936cacb700e958dcbfa8086ce315d96a2d426 100644 (file)
@@ -135,9 +135,10 @@ struct knav_pdsp_info {
        };
        void __iomem                                    *intd;
        u32 __iomem                                     *iram;
-       const char                                      *firmware;
        u32                                             id;
        struct list_head                                list;
+       bool                                            loaded;
+       bool                                            started;
 };
 
 struct knav_qmgr_info {
index ef6f69db0bd04c06caa6c1b955e3dbbebc91677a..d2d48f2802bc45b0077c9ce39f496a07306648d9 100644 (file)
@@ -261,6 +261,10 @@ static int knav_range_setup_acc_irq(struct knav_range_info *range,
        if (old && !new) {
                dev_dbg(kdev->dev, "setup-acc-irq: freeing %s for channel %s\n",
                        acc->name, acc->name);
+               ret = irq_set_affinity_hint(irq, NULL);
+               if (ret)
+                       dev_warn(range->kdev->dev,
+                                "Failed to set IRQ affinity\n");
                free_irq(irq, range);
        }
 
@@ -482,8 +486,8 @@ struct knav_range_ops knav_acc_range_ops = {
  * Return 0 on success or error
  */
 int knav_init_acc_range(struct knav_device *kdev,
-                               struct device_node *node,
-                               struct knav_range_info *range)
+                       struct device_node *node,
+                       struct knav_range_info *range)
 {
        struct knav_acc_channel *acc;
        struct knav_pdsp_info *pdsp;
@@ -526,6 +530,12 @@ int knav_init_acc_range(struct knav_device *kdev,
                return -EINVAL;
        }
 
+       if (!pdsp->started) {
+               dev_err(kdev->dev, "pdsp id %d not started for range %s\n",
+                       info->pdsp_id, range->name);
+               return -ENODEV;
+       }
+
        info->pdsp = pdsp;
        channels = range->num_queues;
        if (of_get_property(node, "multi-queue", NULL)) {
index 6d8646db52cca164fa09c10faa5c59761e75ab2f..f3a0b6a4b54ef8093f2dbbabbcdd7c07de1cddbe 100644 (file)
@@ -68,6 +68,12 @@ static DEFINE_MUTEX(knav_dev_lock);
             idx < (kdev)->num_queues_in_use;                   \
             idx++, inst = knav_queue_idx_to_inst(kdev, idx))
 
+/* All firmware file names end up here. List the firmware file names below.
+ * Newest followed by older ones. Search is done from start of the array
+ * until a firmware file is found.
+ */
+const char *knav_acc_firmwares[] = {"ks2_qmss_pdsp_acc48.bin"};
+
 /**
  * knav_queue_notify: qmss queue notfier call
  *
@@ -1439,7 +1445,6 @@ static int knav_queue_init_pdsps(struct knav_device *kdev,
        struct device *dev = kdev->dev;
        struct knav_pdsp_info *pdsp;
        struct device_node *child;
-       int ret;
 
        for_each_child_of_node(pdsps, child) {
                pdsp = devm_kzalloc(dev, sizeof(*pdsp), GFP_KERNEL);
@@ -1448,17 +1453,6 @@ static int knav_queue_init_pdsps(struct knav_device *kdev,
                        return -ENOMEM;
                }
                pdsp->name = knav_queue_find_name(child);
-               ret = of_property_read_string(child, "firmware",
-                                             &pdsp->firmware);
-               if (ret < 0 || !pdsp->firmware) {
-                       dev_err(dev, "unknown firmware for pdsp %s\n",
-                               pdsp->name);
-                       devm_kfree(dev, pdsp);
-                       continue;
-               }
-               dev_dbg(dev, "pdsp name %s fw name :%s\n", pdsp->name,
-                       pdsp->firmware);
-
                pdsp->iram =
                        knav_queue_map_reg(kdev, child,
                                           KNAV_QUEUE_PDSP_IRAM_REG_INDEX);
@@ -1489,9 +1483,9 @@ static int knav_queue_init_pdsps(struct knav_device *kdev,
                }
                of_property_read_u32(child, "id", &pdsp->id);
                list_add_tail(&pdsp->list, &kdev->pdsps);
-               dev_dbg(dev, "added pdsp %s: command %p, iram %p, regs %p, intd %p, firmware %s\n",
+               dev_dbg(dev, "added pdsp %s: command %p, iram %p, regs %p, intd %p\n",
                        pdsp->name, pdsp->command, pdsp->iram, pdsp->regs,
-                       pdsp->intd, pdsp->firmware);
+                       pdsp->intd);
        }
        return 0;
 }
@@ -1510,6 +1504,8 @@ static int knav_queue_stop_pdsp(struct knav_device *kdev,
                dev_err(kdev->dev, "timed out on pdsp %s stop\n", pdsp->name);
                return ret;
        }
+       pdsp->loaded = false;
+       pdsp->started = false;
        return 0;
 }
 
@@ -1518,14 +1514,29 @@ static int knav_queue_load_pdsp(struct knav_device *kdev,
 {
        int i, ret, fwlen;
        const struct firmware *fw;
+       bool found = false;
        u32 *fwdata;
 
-       ret = request_firmware(&fw, pdsp->firmware, kdev->dev);
-       if (ret) {
-               dev_err(kdev->dev, "failed to get firmware %s for pdsp %s\n",
-                       pdsp->firmware, pdsp->name);
-               return ret;
+       for (i = 0; i < ARRAY_SIZE(knav_acc_firmwares); i++) {
+               if (knav_acc_firmwares[i]) {
+                       ret = request_firmware(&fw,
+                                              knav_acc_firmwares[i],
+                                              kdev->dev);
+                       if (!ret) {
+                               found = true;
+                               break;
+                       }
+               }
+       }
+
+       if (!found) {
+               dev_err(kdev->dev, "failed to get firmware for pdsp\n");
+               return -ENODEV;
        }
+
+       dev_info(kdev->dev, "firmware file %s downloaded for PDSP\n",
+                knav_acc_firmwares[i]);
+
        writel_relaxed(pdsp->id + 1, pdsp->command + 0x18);
        /* download the firmware */
        fwdata = (u32 *)fw->data;
@@ -1583,16 +1594,24 @@ static int knav_queue_start_pdsps(struct knav_device *kdev)
        int ret;
 
        knav_queue_stop_pdsps(kdev);
-       /* now load them all */
+       /* now load them all. We return success even if pdsp
+        * is not loaded as acc channels are optional on having
+        * firmware availability in the system. We set the loaded
+        * and stated flag and when initialize the acc range, check
+        * it and init the range only if pdsp is started.
+        */
        for_each_pdsp(kdev, pdsp) {
                ret = knav_queue_load_pdsp(kdev, pdsp);
-               if (ret < 0)
-                       return ret;
+               if (!ret)
+                       pdsp->loaded = true;
        }
 
        for_each_pdsp(kdev, pdsp) {
-               ret = knav_queue_start_pdsp(kdev, pdsp);
-               WARN_ON(ret);
+               if (pdsp->loaded) {
+                       ret = knav_queue_start_pdsp(kdev, pdsp);
+                       if (!ret)
+                               pdsp->started = true;
+               }
        }
        return 0;
 }
index 3cf9faa6cc3fe871174ec1b2777472b0ac4c6883..a85d863d4a442f2f30633db5de0ff469ee9c6348 100644 (file)
@@ -992,11 +992,12 @@ static int davinci_spi_probe(struct platform_device *pdev)
                goto free_master;
        }
 
-       dspi->irq = platform_get_irq(pdev, 0);
-       if (dspi->irq <= 0) {
+       ret = platform_get_irq(pdev, 0);
+       if (ret == 0)
                ret = -EINVAL;
+       if (ret < 0)
                goto free_master;
-       }
+       dspi->irq = ret;
 
        ret = devm_request_threaded_irq(&pdev->dev, dspi->irq, davinci_spi_irq,
                                dummy_thread_fn, 0, dev_name(&pdev->dev), dspi);
index 4299cf45f947ded9433fa045c1cb54bc957a02c4..5e1f16c36b49adfd45dbd2221435fd9bcda57daa 100644 (file)
@@ -81,6 +81,7 @@ void speakup_fake_down_arrow(void)
        __this_cpu_write(reporting_keystroke, true);
        input_report_key(virt_keyboard, KEY_DOWN, PRESSED);
        input_report_key(virt_keyboard, KEY_DOWN, RELEASED);
+       input_sync(virt_keyboard);
        __this_cpu_write(reporting_keystroke, false);
 
        /* reenable preemption */
index 0bae8cc6c23a0be622b2addf1479830e838cb243..ca920b0ecf8f8688763426ba2d6b253a3620a1b6 100644 (file)
@@ -932,7 +932,7 @@ static void exynos4412_tmu_set_emulation(struct exynos_tmu_data *data,
 
        if (data->soc == SOC_ARCH_EXYNOS5260)
                emul_con = EXYNOS5260_EMUL_CON;
-       if (data->soc == SOC_ARCH_EXYNOS5433)
+       else if (data->soc == SOC_ARCH_EXYNOS5433)
                emul_con = EXYNOS5433_TMU_EMUL_CON;
        else if (data->soc == SOC_ARCH_EXYNOS7)
                emul_con = EXYNOS7_TMU_REG_EMUL_CON;
index 20932cc9c8f71681038bf5e505fec87d9c402280..b09023b071696c2a5d25e003dcff798b42235602 100644 (file)
@@ -343,8 +343,7 @@ static void n_tty_packet_mode_flush(struct tty_struct *tty)
                spin_lock_irqsave(&tty->ctrl_lock, flags);
                tty->ctrl_status |= TIOCPKT_FLUSHREAD;
                spin_unlock_irqrestore(&tty->ctrl_lock, flags);
-               if (waitqueue_active(&tty->link->read_wait))
-                       wake_up_interruptible(&tty->link->read_wait);
+               wake_up_interruptible(&tty->link->read_wait);
        }
 }
 
@@ -1382,8 +1381,7 @@ handle_newline:
                        put_tty_queue(c, ldata);
                        smp_store_release(&ldata->canon_head, ldata->read_head);
                        kill_fasync(&tty->fasync, SIGIO, POLL_IN);
-                       if (waitqueue_active(&tty->read_wait))
-                               wake_up_interruptible_poll(&tty->read_wait, POLLIN);
+                       wake_up_interruptible_poll(&tty->read_wait, POLLIN);
                        return 0;
                }
        }
@@ -1667,8 +1665,7 @@ static void __receive_buf(struct tty_struct *tty, const unsigned char *cp,
 
        if ((read_cnt(ldata) >= ldata->minimum_to_wake) || L_EXTPROC(tty)) {
                kill_fasync(&tty->fasync, SIGIO, POLL_IN);
-               if (waitqueue_active(&tty->read_wait))
-                       wake_up_interruptible_poll(&tty->read_wait, POLLIN);
+               wake_up_interruptible_poll(&tty->read_wait, POLLIN);
        }
 }
 
@@ -1887,10 +1884,8 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
        }
 
        /* The termios change make the tty ready for I/O */
-       if (waitqueue_active(&tty->write_wait))
-               wake_up_interruptible(&tty->write_wait);
-       if (waitqueue_active(&tty->read_wait))
-               wake_up_interruptible(&tty->read_wait);
+       wake_up_interruptible(&tty->write_wait);
+       wake_up_interruptible(&tty->read_wait);
 }
 
 /**
index b1e0ba3e525b069d9649dff9d7cd4a661f2c2014..0bbf34035d6a51edb267d2f53c66fc13d7b54260 100644 (file)
@@ -261,6 +261,14 @@ configured less than Maximum supported fifo bytes */
                                  UART_FCR7_64BYTE,
                .flags          = UART_CAP_FIFO,
        },
+       [PORT_RT2880] = {
+               .name           = "Palmchip BK-3103",
+               .fifo_size      = 16,
+               .tx_loadsz      = 16,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+               .rxtrig_bytes   = {1, 4, 8, 14},
+               .flags          = UART_CAP_FIFO,
+       },
 };
 
 /* Uart divisor latch read */
index 5ca5cf3e9359cf17f9a3aaebbff028ecada3a910..538ea03bc101a2994324d2ce33b8f7b237c12c78 100644 (file)
@@ -2786,7 +2786,7 @@ static int atmel_serial_probe(struct platform_device *pdev)
        ret = atmel_init_gpios(port, &pdev->dev);
        if (ret < 0) {
                dev_err(&pdev->dev, "Failed to initialize GPIOs.");
-               goto err;
+               goto err_clear_bit;
        }
 
        ret = atmel_init_port(port, pdev);
index fe3d41cc841632134fd907b1fb7af08f0e9d6e81..d0388a071ba1d474025a74fec8cfb80f5a1ed4a0 100644 (file)
@@ -1631,12 +1631,12 @@ imx_console_write(struct console *co, const char *s, unsigned int count)
        int locked = 1;
        int retval;
 
-       retval = clk_prepare_enable(sport->clk_per);
+       retval = clk_enable(sport->clk_per);
        if (retval)
                return;
-       retval = clk_prepare_enable(sport->clk_ipg);
+       retval = clk_enable(sport->clk_ipg);
        if (retval) {
-               clk_disable_unprepare(sport->clk_per);
+               clk_disable(sport->clk_per);
                return;
        }
 
@@ -1675,8 +1675,8 @@ imx_console_write(struct console *co, const char *s, unsigned int count)
        if (locked)
                spin_unlock_irqrestore(&sport->port.lock, flags);
 
-       clk_disable_unprepare(sport->clk_ipg);
-       clk_disable_unprepare(sport->clk_per);
+       clk_disable(sport->clk_ipg);
+       clk_disable(sport->clk_per);
 }
 
 /*
@@ -1777,7 +1777,15 @@ imx_console_setup(struct console *co, char *options)
 
        retval = uart_set_options(&sport->port, co, baud, parity, bits, flow);
 
-       clk_disable_unprepare(sport->clk_ipg);
+       clk_disable(sport->clk_ipg);
+       if (retval) {
+               clk_unprepare(sport->clk_ipg);
+               goto error_console;
+       }
+
+       retval = clk_prepare(sport->clk_per);
+       if (retval)
+               clk_disable_unprepare(sport->clk_ipg);
 
 error_console:
        return retval;
index 5a3fa89138801ea63907ec102fbb589b36d7201c..a660ab181cca7357c59c7256303628eb8bb929a9 100644 (file)
@@ -242,7 +242,10 @@ void tty_buffer_flush(struct tty_struct *tty, struct tty_ldisc *ld)
        atomic_inc(&buf->priority);
 
        mutex_lock(&buf->lock);
-       while ((next = buf->head->next) != NULL) {
+       /* paired w/ release in __tty_buffer_request_room; ensures there are
+        * no pending memory accesses to the freed buffer
+        */
+       while ((next = smp_load_acquire(&buf->head->next)) != NULL) {
                tty_buffer_free(port, buf->head);
                buf->head = next;
        }
@@ -290,7 +293,10 @@ static int __tty_buffer_request_room(struct tty_port *port, size_t size,
                if (n != NULL) {
                        n->flags = flags;
                        buf->tail = n;
-                       b->commit = b->used;
+                       /* paired w/ acquire in flush_to_ldisc(); ensures
+                        * flush_to_ldisc() sees buffer data.
+                        */
+                       smp_store_release(&b->commit, b->used);
                        /* paired w/ acquire in flush_to_ldisc(); ensures the
                         * latest commit value can be read before the head is
                         * advanced to the next buffer
@@ -393,7 +399,10 @@ void tty_schedule_flip(struct tty_port *port)
 {
        struct tty_bufhead *buf = &port->buf;
 
-       buf->tail->commit = buf->tail->used;
+       /* paired w/ acquire in flush_to_ldisc(); ensures
+        * flush_to_ldisc() sees buffer data.
+        */
+       smp_store_release(&buf->tail->commit, buf->tail->used);
        schedule_work(&buf->work);
 }
 EXPORT_SYMBOL(tty_schedule_flip);
@@ -467,7 +476,7 @@ static void flush_to_ldisc(struct work_struct *work)
        struct tty_struct *tty;
        struct tty_ldisc *disc;
 
-       tty = port->itty;
+       tty = READ_ONCE(port->itty);
        if (tty == NULL)
                return;
 
@@ -491,7 +500,10 @@ static void flush_to_ldisc(struct work_struct *work)
                 * is advancing to the next buffer
                 */
                next = smp_load_acquire(&head->next);
-               count = head->commit - head->read;
+               /* paired w/ release in __tty_buffer_request_room() or in
+                * tty_buffer_flush(); ensures we see the committed buffer data
+                */
+               count = smp_load_acquire(&head->commit) - head->read;
                if (!count) {
                        if (next == NULL) {
                                check_other_closed(tty);
index 02785d844354be01b9774ad10e70ab398297c6da..2eefaa6e3e3a4af9a5ab2b03cf03f9e75a04ca1d 100644 (file)
@@ -2128,8 +2128,24 @@ retry_open:
        if (!noctty &&
            current->signal->leader &&
            !current->signal->tty &&
-           tty->session == NULL)
-               __proc_set_tty(tty);
+           tty->session == NULL) {
+               /*
+                * Don't let a process that only has write access to the tty
+                * obtain the privileges associated with having a tty as
+                * controlling terminal (being able to reopen it with full
+                * access through /dev/tty, being able to perform pushback).
+                * Many distributions set the group of all ttys to "tty" and
+                * grant write-only access to all terminals for setgid tty
+                * binaries, which should not imply full privileges on all ttys.
+                *
+                * This could theoretically break old code that performs open()
+                * on a write-only file descriptor. In that case, it might be
+                * necessary to also permit this if
+                * inode_permission(inode, MAY_READ) == 0.
+                */
+               if (filp->f_mode & FMODE_READ)
+                       __proc_set_tty(tty);
+       }
        spin_unlock_irq(&current->sighand->siglock);
        read_unlock(&tasklist_lock);
        tty_unlock(tty);
@@ -2418,7 +2434,7 @@ static int fionbio(struct file *file, int __user *p)
  *             Takes ->siglock() when updating signal->tty
  */
 
-static int tiocsctty(struct tty_struct *tty, int arg)
+static int tiocsctty(struct tty_struct *tty, struct file *file, int arg)
 {
        int ret = 0;
 
@@ -2452,6 +2468,13 @@ static int tiocsctty(struct tty_struct *tty, int arg)
                        goto unlock;
                }
        }
+
+       /* See the comment in tty_open(). */
+       if ((file->f_mode & FMODE_READ) == 0 && !capable(CAP_SYS_ADMIN)) {
+               ret = -EPERM;
+               goto unlock;
+       }
+
        proc_set_tty(tty);
 unlock:
        read_unlock(&tasklist_lock);
@@ -2844,7 +2867,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                no_tty();
                return 0;
        case TIOCSCTTY:
-               return tiocsctty(tty, arg);
+               return tiocsctty(tty, file, arg);
        case TIOCGPGRP:
                return tiocgpgrp(tty, real_tty, p);
        case TIOCSPGRP:
@@ -3151,13 +3174,18 @@ struct class *tty_class;
 static int tty_cdev_add(struct tty_driver *driver, dev_t dev,
                unsigned int index, unsigned int count)
 {
+       int err;
+
        /* init here, since reused cdevs cause crashes */
        driver->cdevs[index] = cdev_alloc();
        if (!driver->cdevs[index])
                return -ENOMEM;
-       cdev_init(driver->cdevs[index], &tty_fops);
+       driver->cdevs[index]->ops = &tty_fops;
        driver->cdevs[index]->owner = driver->owner;
-       return cdev_add(driver->cdevs[index], dev, count);
+       err = cdev_add(driver->cdevs[index], dev, count);
+       if (err)
+               kobject_put(&driver->cdevs[index]->kobj);
+       return err;
 }
 
 /**
index d85abfed84ccaa2327820f1b35cabac11422d647..f5a381945db2886a77e23a8fcf40ba9a34bb7fe7 100644 (file)
@@ -54,6 +54,13 @@ static const struct usb_device_id usb_quirk_list[] = {
        { USB_DEVICE(0x046d, 0x082d), .driver_info = USB_QUIRK_DELAY_INIT },
        { USB_DEVICE(0x046d, 0x0843), .driver_info = USB_QUIRK_DELAY_INIT },
 
+       /* Logitech ConferenceCam CC3000e */
+       { USB_DEVICE(0x046d, 0x0847), .driver_info = USB_QUIRK_DELAY_INIT },
+       { USB_DEVICE(0x046d, 0x0848), .driver_info = USB_QUIRK_DELAY_INIT },
+
+       /* Logitech PTZ Pro Camera */
+       { USB_DEVICE(0x046d, 0x0853), .driver_info = USB_QUIRK_DELAY_INIT },
+
        /* Logitech Quickcam Fusion */
        { USB_DEVICE(0x046d, 0x08c1), .driver_info = USB_QUIRK_RESET_RESUME },
 
@@ -78,6 +85,12 @@ static const struct usb_device_id usb_quirk_list[] = {
        /* Philips PSC805 audio device */
        { USB_DEVICE(0x0471, 0x0155), .driver_info = USB_QUIRK_RESET_RESUME },
 
+       /* Plantronic Audio 655 DSP */
+       { USB_DEVICE(0x047f, 0xc008), .driver_info = USB_QUIRK_RESET_RESUME },
+
+       /* Plantronic Audio 648 USB */
+       { USB_DEVICE(0x047f, 0xc013), .driver_info = USB_QUIRK_RESET_RESUME },
+
        /* Artisman Watchdog Dongle */
        { USB_DEVICE(0x04b4, 0x0526), .driver_info =
                        USB_QUIRK_CONFIG_INTF_STRINGS },
index d1b81539d6320b3baed7c5bc9bc4cdde7440aee9..d6199507f86140b15439463f97f234aa7955d6fe 100644 (file)
@@ -159,8 +159,10 @@ static int ep_bd_list_alloc(struct bdc_ep *ep)
                bd_table->start_bd = dma_pool_alloc(bdc->bd_table_pool,
                                                        GFP_ATOMIC,
                                                        &dma);
-               if (!bd_table->start_bd)
+               if (!bd_table->start_bd) {
+                       kfree(bd_table);
                        goto fail;
+               }
 
                bd_table->dma = dma;
 
index 3ad5d19e4d04ede93fb8bc34debdbb9fcf2f4704..23c794813e6a923bff5b0a3719abbea860ee416d 100644 (file)
@@ -472,7 +472,7 @@ static int chaoskey_rng_read(struct hwrng *rng, void *data,
        if (this_time > max)
                this_time = max;
 
-       memcpy(data, dev->buf, this_time);
+       memcpy(data, dev->buf + dev->used, this_time);
 
        dev->used += this_time;
 
index 7b98e1d9194cb3571452c7143603f4e9d9966244..d82fa36c346503985867cc55b0e40dfd724ebf12 100644 (file)
@@ -476,6 +476,11 @@ static const struct of_device_id usbhs_of_match[] = {
                .compatible = "renesas,usbhs-r8a7794",
                .data = (void *)USBHS_TYPE_RCAR_GEN2,
        },
+       {
+               /* Gen3 is compatible with Gen2 */
+               .compatible = "renesas,usbhs-r8a7795",
+               .data = (void *)USBHS_TYPE_RCAR_GEN2,
+       },
        { },
 };
 MODULE_DEVICE_TABLE(of, usbhs_of_match);
@@ -493,7 +498,7 @@ static struct renesas_usbhs_platform_info *usbhs_parse_dt(struct device *dev)
                return NULL;
 
        dparam = &info->driver_param;
-       dparam->type = of_id ? (u32)of_id->data : 0;
+       dparam->type = of_id ? (uintptr_t)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,
index 0e5fde1d3ffbe5a152035f33063afa98bf84f33e..9f9a7bef1ff6d46d80fe8cb6dcfeea5a3e26729d 100644 (file)
@@ -752,7 +752,7 @@ static ssize_t broadsheet_loadstore_waveform(struct device *dev,
        if ((fw_entry->size < 8*1024) || (fw_entry->size > 64*1024)) {
                dev_err(dev, "Invalid waveform\n");
                err = -EINVAL;
-               goto err_failed;
+               goto err_fw;
        }
 
        mutex_lock(&(par->io_lock));
@@ -762,13 +762,15 @@ static ssize_t broadsheet_loadstore_waveform(struct device *dev,
        mutex_unlock(&(par->io_lock));
        if (err < 0) {
                dev_err(dev, "Failed to store broadsheet waveform\n");
-               goto err_failed;
+               goto err_fw;
        }
 
        dev_info(dev, "Stored broadsheet waveform, size %zd\n", fw_entry->size);
 
-       return len;
+       err = len;
 
+err_fw:
+       release_firmware(fw_entry);
 err_failed:
        return err;
 }
index 7fa2e6f9e322d1e2223116474800b515684abfc2..b335c1ae8625106efff818d696ebad532ade7f17 100644 (file)
@@ -1628,9 +1628,16 @@ static int fsl_diu_suspend(struct platform_device *ofdev, pm_message_t state)
 static int fsl_diu_resume(struct platform_device *ofdev)
 {
        struct fsl_diu_data *data;
+       unsigned int i;
 
        data = dev_get_drvdata(&ofdev->dev);
-       enable_lcdc(data->fsl_diu_info);
+
+       fsl_diu_enable_interrupts(data);
+       update_lcdc(data->fsl_diu_info);
+       for (i = 0; i < NUM_AOIS; i++) {
+               if (data->mfb[i].count)
+                       fsl_diu_enable_panel(&data->fsl_diu_info[i]);
+       }
 
        return 0;
 }
index 9b8bebdf8f86e1209f0ca2f6f9779e8c64fa2e43..f9ec5c0484fabbd8d6f2cc5b5e5897c003e07b10 100644 (file)
@@ -831,6 +831,7 @@ static struct of_device_id of_platform_mb862xx_tbl[] = {
        { .compatible = "fujitsu,coral", },
        { /* end */ }
 };
+MODULE_DEVICE_TABLE(of, of_platform_mb862xx_tbl);
 
 static struct platform_driver of_platform_mb862xxfb_driver = {
        .driver = {
index a8ce920fa797d335d2dbfbbc1c9d8f93a4378959..d811e6dcaef727588cdc65695673a4f7144f0f30 100644 (file)
@@ -294,7 +294,7 @@ static int dvic_probe_of(struct platform_device *pdev)
 
        adapter_node = of_parse_phandle(node, "ddc-i2c-bus", 0);
        if (adapter_node) {
-               adapter = of_find_i2c_adapter_by_node(adapter_node);
+               adapter = of_get_i2c_adapter_by_node(adapter_node);
                if (adapter == NULL) {
                        dev_err(&pdev->dev, "failed to parse ddc-i2c-bus\n");
                        omap_dss_put_device(ddata->in);
index 90cbc4c3406c719909f3495cb97533face292d3c..c581231c74a53bb837dcc24da190202ed56cb648 100644 (file)
@@ -898,6 +898,7 @@ static const struct of_device_id acx565akm_of_match[] = {
        { .compatible = "omapdss,sony,acx565akm", },
        {},
 };
+MODULE_DEVICE_TABLE(of, acx565akm_of_match);
 
 static struct spi_driver acx565akm_driver = {
        .driver = {
index 7ed9a227f5eaf006ed5c2a9759ee9db299d114e3..01b43e9ce941acb8751c0c2e8294e19db7ce927c 100644 (file)
@@ -226,7 +226,7 @@ static void blade_image_blit(struct tridentfb_par *par, const char *data,
        writemmr(par, DST1, point(x, y));
        writemmr(par, DST2, point(x + w - 1, y + h - 1));
 
-       memcpy(par->io_virt + 0x10000, data, 4 * size);
+       iowrite32_rep(par->io_virt + 0x10000, data, size);
 }
 
 static void blade_copy_rect(struct tridentfb_par *par,
@@ -673,8 +673,14 @@ static int get_nativex(struct tridentfb_par *par)
 static inline void set_lwidth(struct tridentfb_par *par, int width)
 {
        write3X4(par, VGA_CRTC_OFFSET, width & 0xFF);
-       write3X4(par, AddColReg,
-                (read3X4(par, AddColReg) & 0xCF) | ((width & 0x300) >> 4));
+       /* chips older than TGUI9660 have only 1 width bit in AddColReg */
+       /* touching the other one breaks I2C/DDC */
+       if (par->chip_id == TGUI9440 || par->chip_id == CYBER9320)
+               write3X4(par, AddColReg,
+                    (read3X4(par, AddColReg) & 0xEF) | ((width & 0x100) >> 4));
+       else
+               write3X4(par, AddColReg,
+                    (read3X4(par, AddColReg) & 0xCF) | ((width & 0x300) >> 4));
 }
 
 /* For resolutions smaller than FP resolution stretch */
index 32d8275e4c88485b2b522f56733e90ba614fc7b2..8a1076beecd33aa29891849f5feaa36b42027036 100644 (file)
@@ -210,6 +210,7 @@ struct display_timings *of_get_display_timings(struct device_node *np)
                         */
                        pr_err("%s: error in timing %d\n",
                                of_node_full_name(np), disp->num_timings + 1);
+                       kfree(dt);
                        goto timingfail;
                }
 
index 295795aebe0b42330cc1147e02340eb2c59f1d7b..1e60d00d4ea7c42104614ede9e203a1f56e6408a 100644 (file)
@@ -2847,6 +2847,8 @@ int open_ctree(struct super_block *sb,
            !extent_buffer_uptodate(chunk_root->node)) {
                printk(KERN_ERR "BTRFS: failed to read chunk root on %s\n",
                       sb->s_id);
+               if (!IS_ERR(chunk_root->node))
+                       free_extent_buffer(chunk_root->node);
                chunk_root->node = NULL;
                goto fail_tree_roots;
        }
@@ -2885,6 +2887,8 @@ retry_root_backup:
            !extent_buffer_uptodate(tree_root->node)) {
                printk(KERN_WARNING "BTRFS: failed to read tree root on %s\n",
                       sb->s_id);
+               if (!IS_ERR(tree_root->node))
+                       free_extent_buffer(tree_root->node);
                tree_root->node = NULL;
                goto recovery_tree_root;
        }
index 8d052209f473be1d0959b6e65bded71b92c05584..2513a7f533342c827c5c5e1150de6a3d196879ac 100644 (file)
@@ -112,11 +112,11 @@ static struct dentry *btrfs_fh_to_parent(struct super_block *sb, struct fid *fh,
        u32 generation;
 
        if (fh_type == FILEID_BTRFS_WITH_PARENT) {
-               if (fh_len !=  BTRFS_FID_SIZE_CONNECTABLE)
+               if (fh_len <  BTRFS_FID_SIZE_CONNECTABLE)
                        return NULL;
                root_objectid = fid->root_objectid;
        } else if (fh_type == FILEID_BTRFS_WITH_PARENT_ROOT) {
-               if (fh_len != BTRFS_FID_SIZE_CONNECTABLE_ROOT)
+               if (fh_len < BTRFS_FID_SIZE_CONNECTABLE_ROOT)
                        return NULL;
                root_objectid = fid->parent_root_objectid;
        } else
@@ -136,11 +136,11 @@ static struct dentry *btrfs_fh_to_dentry(struct super_block *sb, struct fid *fh,
        u32 generation;
 
        if ((fh_type != FILEID_BTRFS_WITH_PARENT ||
-            fh_len != BTRFS_FID_SIZE_CONNECTABLE) &&
+            fh_len < BTRFS_FID_SIZE_CONNECTABLE) &&
            (fh_type != FILEID_BTRFS_WITH_PARENT_ROOT ||
-            fh_len != BTRFS_FID_SIZE_CONNECTABLE_ROOT) &&
+            fh_len < BTRFS_FID_SIZE_CONNECTABLE_ROOT) &&
            (fh_type != FILEID_BTRFS_WITHOUT_PARENT ||
-            fh_len != BTRFS_FID_SIZE_NON_CONNECTABLE))
+            fh_len < BTRFS_FID_SIZE_NON_CONNECTABLE))
                return NULL;
 
        objectid = fid->objectid;
index 9f960420133307b5d9b26c7b07bd37d64bec89cf..601d7d45d164a7e91477748a900bbef8cf67d0b0 100644 (file)
@@ -2828,6 +2828,7 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
        struct btrfs_delayed_ref_head *head;
        int ret;
        int run_all = count == (unsigned long)-1;
+       bool can_flush_pending_bgs = trans->can_flush_pending_bgs;
 
        /* We'll clean this up in btrfs_cleanup_transaction */
        if (trans->aborted)
@@ -2844,6 +2845,7 @@ again:
 #ifdef SCRAMBLE_DELAYED_REFS
        delayed_refs->run_delayed_start = find_middle(&delayed_refs->root);
 #endif
+       trans->can_flush_pending_bgs = false;
        ret = __btrfs_run_delayed_refs(trans, root, count);
        if (ret < 0) {
                btrfs_abort_transaction(trans, root, ret);
@@ -2893,6 +2895,7 @@ again:
        }
 out:
        assert_qgroups_uptodate(trans);
+       trans->can_flush_pending_bgs = can_flush_pending_bgs;
        return 0;
 }
 
@@ -4306,7 +4309,8 @@ out:
         * the block groups that were made dirty during the lifetime of the
         * transaction.
         */
-       if (trans->chunk_bytes_reserved >= (2 * 1024 * 1024ull)) {
+       if (trans->can_flush_pending_bgs &&
+           trans->chunk_bytes_reserved >= (2 * 1024 * 1024ull)) {
                btrfs_create_pending_block_groups(trans, trans->root);
                btrfs_trans_release_chunk_metadata(trans);
        }
@@ -9560,7 +9564,9 @@ void btrfs_create_pending_block_groups(struct btrfs_trans_handle *trans,
        struct btrfs_block_group_item item;
        struct btrfs_key key;
        int ret = 0;
+       bool can_flush_pending_bgs = trans->can_flush_pending_bgs;
 
+       trans->can_flush_pending_bgs = false;
        list_for_each_entry_safe(block_group, tmp, &trans->new_bgs, bg_list) {
                if (ret)
                        goto next;
@@ -9581,6 +9587,7 @@ void btrfs_create_pending_block_groups(struct btrfs_trans_handle *trans,
 next:
                list_del_init(&block_group->bg_list);
        }
+       trans->can_flush_pending_bgs = can_flush_pending_bgs;
 }
 
 int btrfs_make_block_group(struct btrfs_trans_handle *trans,
index e2357e31609a2e8469b38c7e95b66f6dd68fcd93..3915c9473e9445d4aeada81c8fb96af7fb521f2c 100644 (file)
@@ -3132,12 +3132,12 @@ static inline void __do_contiguous_readpages(struct extent_io_tree *tree,
                                             get_extent_t *get_extent,
                                             struct extent_map **em_cached,
                                             struct bio **bio, int mirror_num,
-                                            unsigned long *bio_flags, int rw)
+                                            unsigned long *bio_flags, int rw,
+                                            u64 *prev_em_start)
 {
        struct inode *inode;
        struct btrfs_ordered_extent *ordered;
        int index;
-       u64 prev_em_start = (u64)-1;
 
        inode = pages[0]->mapping->host;
        while (1) {
@@ -3153,7 +3153,7 @@ static inline void __do_contiguous_readpages(struct extent_io_tree *tree,
 
        for (index = 0; index < nr_pages; index++) {
                __do_readpage(tree, pages[index], get_extent, em_cached, bio,
-                             mirror_num, bio_flags, rw, &prev_em_start);
+                             mirror_num, bio_flags, rw, prev_em_start);
                page_cache_release(pages[index]);
        }
 }
@@ -3163,7 +3163,8 @@ static void __extent_readpages(struct extent_io_tree *tree,
                               int nr_pages, get_extent_t *get_extent,
                               struct extent_map **em_cached,
                               struct bio **bio, int mirror_num,
-                              unsigned long *bio_flags, int rw)
+                              unsigned long *bio_flags, int rw,
+                              u64 *prev_em_start)
 {
        u64 start = 0;
        u64 end = 0;
@@ -3184,7 +3185,7 @@ static void __extent_readpages(struct extent_io_tree *tree,
                                                  index - first_index, start,
                                                  end, get_extent, em_cached,
                                                  bio, mirror_num, bio_flags,
-                                                 rw);
+                                                 rw, prev_em_start);
                        start = page_start;
                        end = start + PAGE_CACHE_SIZE - 1;
                        first_index = index;
@@ -3195,7 +3196,8 @@ static void __extent_readpages(struct extent_io_tree *tree,
                __do_contiguous_readpages(tree, &pages[first_index],
                                          index - first_index, start,
                                          end, get_extent, em_cached, bio,
-                                         mirror_num, bio_flags, rw);
+                                         mirror_num, bio_flags, rw,
+                                         prev_em_start);
 }
 
 static int __extent_read_full_page(struct extent_io_tree *tree,
@@ -4207,6 +4209,7 @@ int extent_readpages(struct extent_io_tree *tree,
        struct page *page;
        struct extent_map *em_cached = NULL;
        int nr = 0;
+       u64 prev_em_start = (u64)-1;
 
        for (page_idx = 0; page_idx < nr_pages; page_idx++) {
                page = list_entry(pages->prev, struct page, lru);
@@ -4223,12 +4226,12 @@ int extent_readpages(struct extent_io_tree *tree,
                if (nr < ARRAY_SIZE(pagepool))
                        continue;
                __extent_readpages(tree, pagepool, nr, get_extent, &em_cached,
-                                  &bio, 0, &bio_flags, READ);
+                                  &bio, 0, &bio_flags, READ, &prev_em_start);
                nr = 0;
        }
        if (nr)
                __extent_readpages(tree, pagepool, nr, get_extent, &em_cached,
-                                  &bio, 0, &bio_flags, READ);
+                                  &bio, 0, &bio_flags, READ, &prev_em_start);
 
        if (em_cached)
                free_extent_map(em_cached);
index aa72bfd28f7dcbd88c73452aafd2a3d9e7f42e00..a739b825bdd364cfa9cbf16edc9f978a68feb95f 100644 (file)
@@ -1920,10 +1920,12 @@ static int did_overwrite_ref(struct send_ctx *sctx,
        /*
         * We know that it is or will be overwritten. Check this now.
         * The current inode being processed might have been the one that caused
-        * inode 'ino' to be orphanized, therefore ow_inode can actually be the
-        * same as sctx->send_progress.
+        * inode 'ino' to be orphanized, therefore check if ow_inode matches
+        * the current inode being processed.
         */
-       if (ow_inode <= sctx->send_progress)
+       if ((ow_inode < sctx->send_progress) ||
+           (ino != sctx->cur_ino && ow_inode == sctx->cur_ino &&
+            gen == sctx->cur_inode_gen))
                ret = 1;
        else
                ret = 0;
index 74bc3338418be39badb2eb73160c20b3e2240c74..a5b06442f0bf9d1630f201da3e0eb5c0422e8cc9 100644 (file)
@@ -557,6 +557,7 @@ again:
        h->delayed_ref_elem.seq = 0;
        h->type = type;
        h->allocating_chunk = false;
+       h->can_flush_pending_bgs = true;
        h->reloc_reserved = false;
        h->sync = false;
        INIT_LIST_HEAD(&h->qgroup_ref_list);
index 87964bf8892d50f1da01abb725a1d3f6286279f9..a994bb097ee59c12bb0d5599f10c8a64b1954f43 100644 (file)
@@ -118,6 +118,7 @@ struct btrfs_trans_handle {
        short aborted;
        short adding_csums;
        bool allocating_chunk;
+       bool can_flush_pending_bgs;
        bool reloc_reserved;
        bool sync;
        unsigned int type;
index 27aea110e92365e1e91610579369215cc54644ea..c3cc1609025fa3a966c2d5b10f32626214a9e4ef 100644 (file)
@@ -136,5 +136,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
 extern const struct export_operations cifs_export_ops;
 #endif /* CONFIG_CIFS_NFSD_EXPORT */
 
-#define CIFS_VERSION   "2.07"
+#define CIFS_VERSION   "2.08"
 #endif                         /* _CIFSFS_H */
index f621b44cb8009fe87bf631e0a96c941fe63d3408..6b66dd5d15408676ab6510f7ce415164fe5c0571 100644 (file)
@@ -2034,7 +2034,6 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
        struct tcon_link *tlink = NULL;
        struct cifs_tcon *tcon = NULL;
        struct TCP_Server_Info *server;
-       struct cifs_io_parms io_parms;
 
        /*
         * To avoid spurious oplock breaks from server, in the case of
@@ -2056,18 +2055,6 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
                        rc = -ENOSYS;
                cifsFileInfo_put(open_file);
                cifs_dbg(FYI, "SetFSize for attrs rc = %d\n", rc);
-               if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
-                       unsigned int bytes_written;
-
-                       io_parms.netfid = open_file->fid.netfid;
-                       io_parms.pid = open_file->pid;
-                       io_parms.tcon = tcon;
-                       io_parms.offset = 0;
-                       io_parms.length = attrs->ia_size;
-                       rc = CIFSSMBWrite(xid, &io_parms, &bytes_written,
-                                         NULL, NULL, 1);
-                       cifs_dbg(FYI, "Wrt seteof rc %d\n", rc);
-               }
        } else
                rc = -EINVAL;
 
@@ -2093,28 +2080,7 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
        else
                rc = -ENOSYS;
        cifs_dbg(FYI, "SetEOF by path (setattrs) rc = %d\n", rc);
-       if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
-               __u16 netfid;
-               int oplock = 0;
 
-               rc = SMBLegacyOpen(xid, tcon, full_path, FILE_OPEN,
-                                  GENERIC_WRITE, CREATE_NOT_DIR, &netfid,
-                                  &oplock, NULL, cifs_sb->local_nls,
-                                  cifs_remap(cifs_sb));
-               if (rc == 0) {
-                       unsigned int bytes_written;
-
-                       io_parms.netfid = netfid;
-                       io_parms.pid = current->tgid;
-                       io_parms.tcon = tcon;
-                       io_parms.offset = 0;
-                       io_parms.length = attrs->ia_size;
-                       rc = CIFSSMBWrite(xid, &io_parms, &bytes_written, NULL,
-                                         NULL,  1);
-                       cifs_dbg(FYI, "wrt seteof rc %d\n", rc);
-                       CIFSSMBClose(xid, tcon, netfid);
-               }
-       }
        if (tlink)
                cifs_put_tlink(tlink);
 
index ce83e2edbe0a22ae9858ec5a04caa4e2b6ad59d2..597a417ba94d3bb910f52e3f14119a197ff2d090 100644 (file)
@@ -922,7 +922,7 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
        if (tcon && tcon->bad_network_name)
                return -ENOENT;
 
-       if ((tcon->seal) &&
+       if ((tcon && tcon->seal) &&
            ((ses->server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION) == 0)) {
                cifs_dbg(VFS, "encryption requested but no server support");
                return -EOPNOTSUPP;
index 726d211db4842715f71e1911f6940c93b19fe57f..33e9495a31293e2c080b5b0bd2e50523a460ceee 100644 (file)
@@ -1558,8 +1558,6 @@ static int lookup_fast(struct nameidata *nd,
                negative = d_is_negative(dentry);
                if (read_seqcount_retry(&dentry->d_seq, seq))
                        return -ECHILD;
-               if (negative)
-                       return -ENOENT;
 
                /*
                 * This sequence count validates that the parent had no
@@ -1580,6 +1578,12 @@ static int lookup_fast(struct nameidata *nd,
                                goto unlazy;
                        }
                }
+               /*
+                * Note: do negative dentry check after revalidation in
+                * case that drops it.
+                */
+               if (negative)
+                       return -ENOENT;
                path->mnt = mnt;
                path->dentry = dentry;
                if (likely(__follow_mount_rcu(nd, path, inode, seqp)))
index f93b9cdb4934d17739bf4c6442d79bbfe32dcf13..5133bb18830e8c8b97e68e8f2c55d617ff92a321 100644 (file)
@@ -1458,12 +1458,18 @@ nfs4_opendata_check_deleg(struct nfs4_opendata *data, struct nfs4_state *state)
        if (delegation)
                delegation_flags = delegation->flags;
        rcu_read_unlock();
-       if (data->o_arg.claim == NFS4_OPEN_CLAIM_DELEGATE_CUR) {
+       switch (data->o_arg.claim) {
+       default:
+               break;
+       case NFS4_OPEN_CLAIM_DELEGATE_CUR:
+       case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
                pr_err_ratelimited("NFS: Broken NFSv4 server %s is "
                                   "returning a delegation for "
                                   "OPEN(CLAIM_DELEGATE_CUR)\n",
                                   clp->cl_hostname);
-       } else if ((delegation_flags & 1UL<<NFS_DELEGATION_NEED_RECLAIM) == 0)
+               return;
+       }
+       if ((delegation_flags & 1UL<<NFS_DELEGATION_NEED_RECLAIM) == 0)
                nfs_inode_set_delegation(state->inode,
                                         data->owner->so_cred,
                                         &data->o_res);
@@ -1771,6 +1777,9 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx,
        if (IS_ERR(opendata))
                return PTR_ERR(opendata);
        nfs4_stateid_copy(&opendata->o_arg.u.delegation, stateid);
+       write_seqlock(&state->seqlock);
+       nfs4_stateid_copy(&state->stateid, &state->open_stateid);
+       write_sequnlock(&state->seqlock);
        clear_bit(NFS_DELEGATED_STATE, &state->flags);
        switch (type & (FMODE_READ|FMODE_WRITE)) {
        case FMODE_READ|FMODE_WRITE:
@@ -1863,6 +1872,8 @@ static int _nfs4_proc_open_confirm(struct nfs4_opendata *data)
        data->rpc_done = 0;
        data->rpc_status = 0;
        data->timestamp = jiffies;
+       if (data->is_recover)
+               nfs4_set_sequence_privileged(&data->c_arg.seq_args);
        task = rpc_run_task(&task_setup_data);
        if (IS_ERR(task))
                return PTR_ERR(task);
index 5db324635e920a51923b37c3d22c9d3dee2f6682..d854693a15b0e2443779986552d29d9db3f6cdc2 100644 (file)
@@ -1725,7 +1725,8 @@ restart:
                        if (!test_and_clear_bit(ops->owner_flag_bit,
                                                        &sp->so_flags))
                                continue;
-                       atomic_inc(&sp->so_count);
+                       if (!atomic_inc_not_zero(&sp->so_count))
+                               continue;
                        spin_unlock(&clp->cl_lock);
                        rcu_read_unlock();
 
index 28df12e525bac5857c0d41aba62d558db82f526a..671cf68fe56bed7a457fddd4ccdd5913509ff1bd 100644 (file)
@@ -409,7 +409,7 @@ DECLARE_EVENT_CLASS(nfs4_open_event,
                        __entry->flags = flags;
                        __entry->fmode = (__force unsigned int)ctx->mode;
                        __entry->dev = ctx->dentry->d_sb->s_dev;
-                       if (!IS_ERR(state))
+                       if (!IS_ERR_OR_NULL(state))
                                inode = state->inode;
                        if (inode != NULL) {
                                __entry->fileid = NFS_FILEID(inode);
index 72624dc4a623b894ca0be949c5feab1cec455e02..75ab7622e0cc193bab28f2ba5bb56d37e5f49465 100644 (file)
@@ -569,19 +569,17 @@ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio,
        if (!nfs_pageio_add_request(pgio, req)) {
                nfs_redirty_request(req);
                ret = pgio->pg_error;
-       }
+       } else
+               nfs_add_stats(page_file_mapping(page)->host,
+                               NFSIOS_WRITEPAGES, 1);
 out:
        return ret;
 }
 
 static int nfs_do_writepage(struct page *page, struct writeback_control *wbc, struct nfs_pageio_descriptor *pgio)
 {
-       struct inode *inode = page_file_mapping(page)->host;
        int ret;
 
-       nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGE);
-       nfs_add_stats(inode, NFSIOS_WRITEPAGES, 1);
-
        nfs_pageio_cond_complete(pgio, page_file_index(page));
        ret = nfs_page_async_flush(pgio, page, wbc->sync_mode == WB_SYNC_NONE);
        if (ret == -EAGAIN) {
@@ -597,9 +595,11 @@ static int nfs_do_writepage(struct page *page, struct writeback_control *wbc, st
 static int nfs_writepage_locked(struct page *page, struct writeback_control *wbc)
 {
        struct nfs_pageio_descriptor pgio;
+       struct inode *inode = page_file_mapping(page)->host;
        int err;
 
-       nfs_pageio_init_write(&pgio, page->mapping->host, wb_priority(wbc),
+       nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGE);
+       nfs_pageio_init_write(&pgio, inode, wb_priority(wbc),
                                false, &nfs_async_write_completion_ops);
        err = nfs_do_writepage(page, wbc, &pgio);
        nfs_pageio_complete(&pgio);
@@ -1223,7 +1223,7 @@ static int nfs_can_extend_write(struct file *file, struct page *page, struct ino
                return 1;
        if (!flctx || (list_empty_careful(&flctx->flc_flock) &&
                       list_empty_careful(&flctx->flc_posix)))
-               return 0;
+               return 1;
 
        /* Check to see if there are whole file write locks */
        ret = 0;
index b87c1c7c242a7eea1eff286b3f292e5fa8ccd2d4..468fdfa643f0d1c535becd96f4dd3b46d58e263f 100644 (file)
@@ -67,6 +67,7 @@ struct atmel_tc {
        const struct atmel_tcb_config *tcb_config;
        int                     irq[3];
        struct clk              *clk[3];
+       struct clk              *slow_clk;
        struct list_head        node;
        bool                    allocated;
 };
index d3ca79236fb00ee5543e507ae9e69bc62b700e43..f644fdb06dd691ba2d218384b1172791100f9aaf 100644 (file)
@@ -161,6 +161,11 @@ enum {
        IRQ_DOMAIN_FLAG_NONCORE         = (1 << 16),
 };
 
+static inline struct device_node *irq_domain_get_of_node(struct irq_domain *d)
+{
+       return d->of_node;
+}
+
 #ifdef CONFIG_IRQ_DOMAIN
 struct irq_domain *__irq_domain_add(struct device_node *of_node, int size,
                                    irq_hw_number_t hwirq_max, int direct_max,
diff --git a/include/linux/mfd/syscon/imx7-iomuxc-gpr.h b/include/linux/mfd/syscon/imx7-iomuxc-gpr.h
new file mode 100644 (file)
index 0000000..4585d61
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_IMX7_IOMUXC_GPR_H
+#define __LINUX_IMX7_IOMUXC_GPR_H
+
+#define IOMUXC_GPR0    0x00
+#define IOMUXC_GPR1    0x04
+#define IOMUXC_GPR2    0x08
+#define IOMUXC_GPR3    0x0c
+#define IOMUXC_GPR4    0x10
+#define IOMUXC_GPR5    0x14
+#define IOMUXC_GPR6    0x18
+#define IOMUXC_GPR7    0x1c
+#define IOMUXC_GPR8    0x20
+#define IOMUXC_GPR9    0x24
+#define IOMUXC_GPR10   0x28
+#define IOMUXC_GPR11   0x2c
+#define IOMUXC_GPR12   0x30
+#define IOMUXC_GPR13   0x34
+#define IOMUXC_GPR14   0x38
+#define IOMUXC_GPR15   0x3c
+#define IOMUXC_GPR16   0x40
+#define IOMUXC_GPR17   0x44
+#define IOMUXC_GPR18   0x48
+#define IOMUXC_GPR19   0x4c
+#define IOMUXC_GPR20   0x50
+#define IOMUXC_GPR21   0x54
+#define IOMUXC_GPR22   0x58
+
+/* For imx7d iomux gpr register field define */
+#define IMX7D_GPR1_IRQ_MASK                    (0x1 << 12)
+#define IMX7D_GPR1_ENET1_TX_CLK_SEL_MASK       (0x1 << 13)
+#define IMX7D_GPR1_ENET2_TX_CLK_SEL_MASK       (0x1 << 14)
+#define IMX7D_GPR1_ENET_TX_CLK_SEL_MASK                (0x3 << 13)
+#define IMX7D_GPR1_ENET1_CLK_DIR_MASK          (0x1 << 17)
+#define IMX7D_GPR1_ENET2_CLK_DIR_MASK          (0x1 << 18)
+#define IMX7D_GPR1_ENET_CLK_DIR_MASK           (0x3 << 17)
+
+#define IMX7D_GPR5_CSI_MUX_CONTROL_MIPI                (0x1 << 4)
+
+#endif /* __LINUX_IMX7_IOMUXC_GPR_H */
index 527a85c6192443a50ca8846f24fe40d7e726eca9..4d67a5e82c8311ee39508b817a78c307f22d1567 100644 (file)
@@ -9,15 +9,7 @@
 
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
-#include <linux/device.h>
-#include <linux/i2c.h>
-#include <linux/leds.h>
-#include <linux/spi/spi.h>
-#include <linux/usb/atmel_usba_udc.h>
-#include <linux/atmel-mci.h>
-#include <sound/atmel-ac97c.h>
 #include <linux/serial.h>
-#include <linux/platform_data/macb.h>
 
 /*
  * at91: 6 USARTs and one DBGU port (SAM9260)
index a682fcc91c3321b386a13313dd9135b590117ee4..12c4865457adc3d0412c573b710feec7d3d6fd81 100644 (file)
@@ -21,6 +21,8 @@
 #define PSCI_POWER_STATE_TYPE_POWER_DOWN       1
 
 bool psci_tos_resident_on(int cpu);
+bool psci_power_state_loses_context(u32 state);
+bool psci_power_state_is_valid(u32 state);
 
 struct psci_operations {
        int (*cpu_suspend)(u32 state, unsigned long entry_point);
index 6e7d5ec65838249cb8e5117eaa410c4d35adde5c..9e12000914b3451107abdde161e1ea64b7cfeb5e 100644 (file)
@@ -23,6 +23,8 @@ struct qcom_scm_hdcp_req {
        u32 val;
 };
 
+extern bool qcom_scm_is_available(void);
+
 extern bool qcom_scm_hdcp_available(void);
 extern int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt,
                u32 *resp);
diff --git a/include/linux/scpi_protocol.h b/include/linux/scpi_protocol.h
new file mode 100644 (file)
index 0000000..80af3cd
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * SCPI Message Protocol driver header
+ *
+ * Copyright (C) 2014 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/types.h>
+
+struct scpi_opp {
+       u32 freq;
+       u32 m_volt;
+} __packed;
+
+struct scpi_dvfs_info {
+       unsigned int count;
+       unsigned int latency; /* in nanoseconds */
+       struct scpi_opp *opps;
+};
+
+enum scpi_sensor_class {
+       TEMPERATURE,
+       VOLTAGE,
+       CURRENT,
+       POWER,
+};
+
+struct scpi_sensor_info {
+       u16 sensor_id;
+       u8 class;
+       u8 trigger_type;
+       char name[20];
+} __packed;
+
+/**
+ * struct scpi_ops - represents the various operations provided
+ *     by SCP through SCPI message protocol
+ * @get_version: returns the major and minor revision on the SCPI
+ *     message protocol
+ * @clk_get_range: gets clock range limit(min - max in Hz)
+ * @clk_get_val: gets clock value(in Hz)
+ * @clk_set_val: sets the clock value, setting to 0 will disable the
+ *     clock (if supported)
+ * @dvfs_get_idx: gets the Operating Point of the given power domain.
+ *     OPP is an index to the list return by @dvfs_get_info
+ * @dvfs_set_idx: sets the Operating Point of the given power domain.
+ *     OPP is an index to the list return by @dvfs_get_info
+ * @dvfs_get_info: returns the DVFS capabilities of the given power
+ *     domain. It includes the OPP list and the latency information
+ */
+struct scpi_ops {
+       u32 (*get_version)(void);
+       int (*clk_get_range)(u16, unsigned long *, unsigned long *);
+       unsigned long (*clk_get_val)(u16);
+       int (*clk_set_val)(u16, unsigned long);
+       int (*dvfs_get_idx)(u8);
+       int (*dvfs_set_idx)(u8, u8);
+       struct scpi_dvfs_info *(*dvfs_get_info)(u8);
+       int (*sensor_get_capability)(u16 *sensors);
+       int (*sensor_get_info)(u16 sensor_id, struct scpi_sensor_info *);
+       int (*sensor_get_value)(u16, u32 *);
+};
+
+#if IS_ENABLED(CONFIG_ARM_SCPI_PROTOCOL)
+struct scpi_ops *get_scpi_ops(void);
+#else
+static inline struct scpi_ops *get_scpi_ops(void) { return NULL; }
+#endif
diff --git a/include/linux/soc/brcmstb/brcmstb.h b/include/linux/soc/brcmstb/brcmstb.h
new file mode 100644 (file)
index 0000000..337ce41
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef __BRCMSTB_SOC_H
+#define __BRCMSTB_SOC_H
+
+/*
+ * Bus Interface Unit control register setup, must happen early during boot,
+ * before SMP is brought up, called by machine entry point.
+ */
+void brcmstb_biuctrl_init(void);
+
+#endif /* __BRCMSTB_SOC_H */
index d7e50aa6a4ac09884008377f7db668c5bac555bf..d0cb6d189a0a02bd28459c7b143229563f23c4e4 100644 (file)
@@ -8,6 +8,14 @@ struct qcom_smd;
 struct qcom_smd_channel;
 struct qcom_smd_lookup;
 
+/**
+ * struct qcom_smd_id - struct used for matching a smd device
+ * @name:      name of the channel
+ */
+struct qcom_smd_id {
+       char name[20];
+};
+
 /**
  * struct qcom_smd_device - smd device struct
  * @dev:       the device struct
@@ -21,6 +29,7 @@ struct qcom_smd_device {
 /**
  * struct qcom_smd_driver - smd driver struct
  * @driver:    underlying device driver
+ * @smd_match_table: static channel match table
  * @probe:     invoked when the smd channel is found
  * @remove:    invoked when the smd channel is closed
  * @callback:  invoked when an inbound message is received on the channel,
@@ -29,6 +38,8 @@ struct qcom_smd_device {
  */
 struct qcom_smd_driver {
        struct device_driver driver;
+       const struct qcom_smd_id *smd_match_table;
+
        int (*probe)(struct qcom_smd_device *dev);
        void (*remove)(struct qcom_smd_device *dev);
        int (*callback)(struct qcom_smd_device *, const void *, size_t);
index bc9630d3acede09a43b7be1bd03f37ac76266a46..785e196ee2cae6f1b0ec48fad8816db3839aa943 100644 (file)
@@ -4,7 +4,7 @@
 #define QCOM_SMEM_HOST_ANY -1
 
 int qcom_smem_alloc(unsigned host, unsigned item, size_t size);
-int qcom_smem_get(unsigned host, unsigned item, void **ptr, size_t *size);
+void *qcom_smem_get(unsigned host, unsigned item, size_t *size);
 
 int qcom_smem_get_free_space(unsigned host);
 
index 6d36dacec4baa1cd88a6bfebd259c4b685a34876..9ec4c147abbc7750710da12924c96a7343127364 100644 (file)
@@ -23,7 +23,6 @@ struct dma_chan;
 
 /* device.platform_data for SSP controller devices */
 struct pxa2xx_spi_master {
-       u32 clock_enable;
        u16 num_chipselect;
        u8 enable_dma;
 
diff --git a/include/linux/sunxi-rsb.h b/include/linux/sunxi-rsb.h
new file mode 100644 (file)
index 0000000..7e75bb0
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Allwinner Reduced Serial Bus Driver
+ *
+ * Copyright (c) 2015 Chen-Yu Tsai
+ *
+ * Author: Chen-Yu Tsai <wens@csie.org>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#ifndef _SUNXI_RSB_H
+#define _SUNXI_RSB_H
+
+#include <linux/device.h>
+#include <linux/regmap.h>
+#include <linux/types.h>
+
+struct sunxi_rsb;
+
+/**
+ * struct sunxi_rsb_device - Basic representation of an RSB device
+ * @dev:       Driver model representation of the device.
+ * @ctrl:      RSB controller managing the bus hosting this device.
+ * @rtaddr:    This device's runtime address
+ * @hwaddr:    This device's hardware address
+ */
+struct sunxi_rsb_device {
+       struct device           dev;
+       struct sunxi_rsb        *rsb;
+       int                     irq;
+       u8                      rtaddr;
+       u16                     hwaddr;
+};
+
+static inline struct sunxi_rsb_device *to_sunxi_rsb_device(struct device *d)
+{
+       return container_of(d, struct sunxi_rsb_device, dev);
+}
+
+static inline void *sunxi_rsb_device_get_drvdata(const struct sunxi_rsb_device *rdev)
+{
+       return dev_get_drvdata(&rdev->dev);
+}
+
+static inline void sunxi_rsb_device_set_drvdata(struct sunxi_rsb_device *rdev,
+                                               void *data)
+{
+       dev_set_drvdata(&rdev->dev, data);
+}
+
+/**
+ * struct sunxi_rsb_driver - RSB slave device driver
+ * @driver:    RSB device drivers should initialize name and owner field of
+ *             this structure.
+ * @probe:     binds this driver to a RSB device.
+ * @remove:    unbinds this driver from the RSB device.
+ */
+struct sunxi_rsb_driver {
+       struct device_driver driver;
+       int (*probe)(struct sunxi_rsb_device *rdev);
+       int (*remove)(struct sunxi_rsb_device *rdev);
+};
+
+static inline struct sunxi_rsb_driver *to_sunxi_rsb_driver(struct device_driver *d)
+{
+       return container_of(d, struct sunxi_rsb_driver, driver);
+}
+
+int sunxi_rsb_driver_register(struct sunxi_rsb_driver *rdrv);
+
+/**
+ * sunxi_rsb_driver_unregister() - unregister an RSB client driver
+ * @rdrv:      the driver to unregister
+ */
+static inline void sunxi_rsb_driver_unregister(struct sunxi_rsb_driver *rdrv)
+{
+       if (rdrv)
+               driver_unregister(&rdrv->driver);
+}
+
+#define module_sunxi_rsb_driver(__sunxi_rsb_driver) \
+       module_driver(__sunxi_rsb_driver, sunxi_rsb_driver_register, \
+                       sunxi_rsb_driver_unregister)
+
+struct regmap *__devm_regmap_init_sunxi_rsb(struct sunxi_rsb_device *rdev,
+                                           const struct regmap_config *config,
+                                           struct lock_class_key *lock_key,
+                                           const char *lock_name);
+
+/**
+ * devm_regmap_init_sunxi_rsb(): Initialise managed register map
+ *
+ * @rdev: Device that will be interacted with
+ * @config: Configuration for register map
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer
+ * to a struct regmap.  The regmap will be automatically freed by the
+ * device management code.
+ */
+#define devm_regmap_init_sunxi_rsb(rdev, config)                       \
+       __regmap_lockdep_wrapper(__devm_regmap_init_sunxi_rsb, #config, \
+                                rdev, config)
+
+#endif /* _SUNXI_RSB_H */
index 3dd5a781da99f163930e8a0611f269d1946daf6b..bfb74723f151512780ceb404255cb43ef92c764d 100644 (file)
@@ -157,7 +157,7 @@ struct renesas_usbhs_driver_param {
         */
        int pio_dma_border; /* default is 64byte */
 
-       u32 type;
+       uintptr_t type;
        u32 enable_gpio;
 
        /*
diff --git a/include/soc/brcmstb/common.h b/include/soc/brcmstb/common.h
new file mode 100644 (file)
index 0000000..cfb5335
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * Copyright Â© 2014 NVIDIA Corporation
+ * Copyright Â© 2015 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __SOC_BRCMSTB_COMMON_H__
+#define __SOC_BRCMSTB_COMMON_H__
+
+bool soc_is_brcmstb(void);
+
+#endif /* __SOC_BRCMSTB_COMMON_H__ */
index 310d83e0a91b6bb000b462cdd130c2445b945268..3d7a0fc021a75a7b52c725c151dee15eb9fc5830 100644 (file)
 #define PSCI_0_2_FN64_MIGRATE                  PSCI_0_2_FN64(5)
 #define PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU      PSCI_0_2_FN64(7)
 
+#define PSCI_1_0_FN_PSCI_FEATURES              PSCI_0_2_FN(10)
+#define PSCI_1_0_FN_SYSTEM_SUSPEND             PSCI_0_2_FN(14)
+
+#define PSCI_1_0_FN64_SYSTEM_SUSPEND           PSCI_0_2_FN64(14)
+
 /* PSCI v0.2 power state encoding for CPU_SUSPEND function */
 #define PSCI_0_2_POWER_STATE_ID_MASK           0xffff
 #define PSCI_0_2_POWER_STATE_ID_SHIFT          0
 #define PSCI_0_2_POWER_STATE_AFFL_MASK         \
                                (0x3 << PSCI_0_2_POWER_STATE_AFFL_SHIFT)
 
+/* PSCI extended power state encoding for CPU_SUSPEND function */
+#define PSCI_1_0_EXT_POWER_STATE_ID_MASK       0xfffffff
+#define PSCI_1_0_EXT_POWER_STATE_ID_SHIFT      0
+#define PSCI_1_0_EXT_POWER_STATE_TYPE_SHIFT    30
+#define PSCI_1_0_EXT_POWER_STATE_TYPE_MASK     \
+                               (0x1 << PSCI_1_0_EXT_POWER_STATE_TYPE_SHIFT)
+
 /* PSCI v0.2 affinity level state returned by AFFINITY_INFO */
 #define PSCI_0_2_AFFINITY_LEVEL_ON             0
 #define PSCI_0_2_AFFINITY_LEVEL_OFF            1
 #define PSCI_VERSION_MINOR(ver)                        \
                ((ver) & PSCI_VERSION_MINOR_MASK)
 
+/* PSCI features decoding (>=1.0) */
+#define PSCI_1_0_FEATURES_CPU_SUSPEND_PF_SHIFT 1
+#define PSCI_1_0_FEATURES_CPU_SUSPEND_PF_MASK  \
+                       (0x1 << PSCI_1_0_FEATURES_CPU_SUSPEND_PF_SHIFT)
+
 /* PSCI return values (inclusive of all PSCI versions) */
 #define PSCI_RET_SUCCESS                       0
 #define PSCI_RET_NOT_SUPPORTED                 -1
 #define PSCI_RET_INTERNAL_FAILURE              -6
 #define PSCI_RET_NOT_PRESENT                   -7
 #define PSCI_RET_DISABLED                      -8
+#define PSCI_RET_INVALID_ADDRESS               -9
 
 #endif /* _UAPI_LINUX_PSCI_H */
index 9ce083960a2575df0bd2a4e31ac3c8b881012880..f18490985fc8e5f39d10ed442d302293ac0e7699 100644 (file)
@@ -107,5 +107,13 @@ struct sched_watchdog {
 #define SHUTDOWN_suspend    2  /* Clean up, save suspend info, kill.         */
 #define SHUTDOWN_crash      3  /* Tell controller we've crashed.             */
 #define SHUTDOWN_watchdog   4  /* Restart because watchdog time expired.     */
+/*
+ * Domain asked to perform 'soft reset' for it. The expected behavior is to
+ * reset internal Xen state for the domain returning it to the point where it
+ * was created but leaving the domain's memory contents and vCPU contexts
+ * intact. This will allow the domain to start over and set up all Xen specific
+ * interfaces again.
+ */
+#define SHUTDOWN_soft_reset 5
 
 #endif /* __XEN_PUBLIC_SCHED_H__ */
index de41a68fc038df70b8578e6ec1174fbcf53a1f0f..e25a83b67ccea18568f932636b72bd0e9ba182d0 100644 (file)
@@ -22,7 +22,6 @@
 
 /**
  * handle_bad_irq - handle spurious and unhandled irqs
- * @irq:       the interrupt number
  * @desc:      description of the interrupt
  *
  * Handles spurious and unhandled IRQ's. It also prints a debugmessage.
@@ -35,6 +34,7 @@ void handle_bad_irq(struct irq_desc *desc)
        kstat_incr_irqs_this_cpu(desc);
        ack_bad_irq(irq);
 }
+EXPORT_SYMBOL_GPL(handle_bad_irq);
 
 /*
  * Special, empty irq handler:
index 615953141951747dba2715ac32fed23b5d256627..10a8faa1b0d4a5f737bd9008eb8f9a7e817b6ec9 100644 (file)
@@ -2517,11 +2517,11 @@ static struct rq *finish_task_switch(struct task_struct *prev)
         * If a task dies, then it sets TASK_DEAD in tsk->state and calls
         * schedule one last time. The schedule call will never return, and
         * the scheduled task must drop that reference.
-        * The test for TASK_DEAD must occur while the runqueue locks are
-        * still held, otherwise prev could be scheduled on another cpu, die
-        * there before we look at prev->state, and then the reference would
-        * be dropped twice.
-        *              Manfred Spraul <manfred@colorfullife.com>
+        *
+        * We must observe prev->state before clearing prev->on_cpu (in
+        * finish_lock_switch), otherwise a concurrent wakeup can get prev
+        * running on another CPU and we could rave with its RUNNING -> DEAD
+        * transition, resulting in a double drop.
         */
        prev_state = prev->state;
        vtime_task_switch(prev);
index 68cda117574c3aed0e1849a6c07eb28e1f3369c9..6d2a119c7ad9f63338ffb0e9e92efcbc269c2141 100644 (file)
@@ -1078,9 +1078,10 @@ static inline void finish_lock_switch(struct rq *rq, struct task_struct *prev)
         * After ->on_cpu is cleared, the task can be moved to a different CPU.
         * We must ensure this doesn't happen until the switch is completely
         * finished.
+        *
+        * Pairs with the control dependency and rmb in try_to_wake_up().
         */
-       smp_wmb();
-       prev->on_cpu = 0;
+       smp_store_release(&prev->on_cpu, 0);
 #endif
 #ifdef CONFIG_DEBUG_SPINLOCK
        /* this is a valid case when another task releases the spinlock */
index 8dbb7b1eab508712da538d0ef7cadc0e24b6c723..84775ba873b9efd978fa006be56e58057b34031f 100644 (file)
@@ -203,12 +203,13 @@ ssize_t strscpy(char *dest, const char *src, size_t count)
                unsigned long c, data;
 
                c = *(unsigned long *)(src+res);
-               *(unsigned long *)(dest+res) = c;
                if (has_zero(c, &data, &constants)) {
                        data = prep_zero_mask(c, data, &constants);
                        data = create_zero_mask(data);
+                       *(unsigned long *)(dest+res) = c & zero_bytemask(data);
                        return res + find_zero(data);
                }
+               *(unsigned long *)(dest+res) = c;
                res += sizeof(unsigned long);
                count -= sizeof(unsigned long);
                max -= sizeof(unsigned long);
index 72940fb38666811b80c146bc085a1c84fc0e7ecc..1cc5467cf36ce7852f7a0474d5fd3237b3dfff10 100644 (file)
@@ -2473,6 +2473,21 @@ ssize_t generic_perform_write(struct file *file,
                                                iov_iter_count(i));
 
 again:
+               /*
+                * Bring in the user page that we will copy from _first_.
+                * Otherwise there's a nasty deadlock on copying from the
+                * same page as we're writing to, without it being marked
+                * up-to-date.
+                *
+                * Not only is this an optimisation, but it is also required
+                * to check that the address is actually valid, when atomic
+                * usercopies are used, below.
+                */
+               if (unlikely(iov_iter_fault_in_readable(i, bytes))) {
+                       status = -EFAULT;
+                       break;
+               }
+
                status = a_ops->write_begin(file, mapping, pos, bytes, flags,
                                                &page, &fsdata);
                if (unlikely(status < 0))
@@ -2480,17 +2495,8 @@ again:
 
                if (mapping_writably_mapped(mapping))
                        flush_dcache_page(page);
-               /*
-                * 'page' is now locked.  If we are trying to copy from a
-                * mapping of 'page' in userspace, the copy might fault and
-                * would need PageUptodate() to complete.  But, page can not be
-                * made Uptodate without acquiring the page lock, which we hold.
-                * Deadlock.  Avoid with pagefault_disable().  Fix up below with
-                * iov_iter_fault_in_readable().
-                */
-               pagefault_disable();
+
                copied = iov_iter_copy_from_user_atomic(page, i, offset, bytes);
-               pagefault_enable();
                flush_dcache_page(page);
 
                status = a_ops->write_end(file, mapping, pos, bytes, copied,
@@ -2513,14 +2519,6 @@ again:
                         */
                        bytes = min_t(unsigned long, PAGE_CACHE_SIZE - offset,
                                                iov_iter_single_seg_count(i));
-                       /*
-                        * This is the fallback to recover if the copy from
-                        * userspace above faults.
-                        */
-                       if (unlikely(iov_iter_fault_in_readable(i, bytes))) {
-                               status = -EFAULT;
-                               break;
-                       }
                        goto again;
                }
                pos += copied;
index cb51742840740f790d24797e585e7fb520646a09..5f6ca47092b039a1c927420a51b851a83047b5fc 100644 (file)
@@ -136,7 +136,8 @@ int rdma_read_chunk_lcl(struct svcxprt_rdma *xprt,
        ctxt->direction = DMA_FROM_DEVICE;
        ctxt->read_hdr = head;
        pages_needed = min_t(int, pages_needed, xprt->sc_max_sge_rd);
-       read = min_t(int, pages_needed << PAGE_SHIFT, rs_length);
+       read = min_t(int, (pages_needed << PAGE_SHIFT) - *page_offset,
+                    rs_length);
 
        for (pno = 0; pno < pages_needed; pno++) {
                int len = min_t(int, rs_length, PAGE_SIZE - pg_off);
@@ -235,7 +236,8 @@ int rdma_read_chunk_frmr(struct svcxprt_rdma *xprt,
        ctxt->direction = DMA_FROM_DEVICE;
        ctxt->frmr = frmr;
        pages_needed = min_t(int, pages_needed, xprt->sc_frmr_pg_list_len);
-       read = min_t(int, pages_needed << PAGE_SHIFT, rs_length);
+       read = min_t(int, (pages_needed << PAGE_SHIFT) - *page_offset,
+                    rs_length);
 
        frmr->kva = page_address(rqstp->rq_arg.pages[pg_no]);
        frmr->direction = DMA_FROM_DEVICE;
index 64443eb754ad0fe7fd0b16633c3aa10cebdc3e26..41e452bc580c0fea0f39fe71924b72dcdff6782f 100644 (file)
@@ -270,8 +270,8 @@ xprt_rdma_destroy(struct rpc_xprt *xprt)
 
        xprt_clear_connected(xprt);
 
-       rpcrdma_buffer_destroy(&r_xprt->rx_buf);
        rpcrdma_ep_destroy(&r_xprt->rx_ep, &r_xprt->rx_ia);
+       rpcrdma_buffer_destroy(&r_xprt->rx_buf);
        rpcrdma_ia_close(&r_xprt->rx_ia);
 
        xprt_rdma_free_addresses(xprt);
index eb081ad05e33bb65a89b4afb499177dff4d2de89..8a477e27bad75f4b9a6c8feeceb745ffe9407c71 100644 (file)
@@ -755,19 +755,22 @@ rpcrdma_ep_destroy(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia)
 
        cancel_delayed_work_sync(&ep->rep_connect_worker);
 
-       if (ia->ri_id->qp) {
+       if (ia->ri_id->qp)
                rpcrdma_ep_disconnect(ep, ia);
+
+       rpcrdma_clean_cq(ep->rep_attr.recv_cq);
+       rpcrdma_clean_cq(ep->rep_attr.send_cq);
+
+       if (ia->ri_id->qp) {
                rdma_destroy_qp(ia->ri_id);
                ia->ri_id->qp = NULL;
        }
 
-       rpcrdma_clean_cq(ep->rep_attr.recv_cq);
        rc = ib_destroy_cq(ep->rep_attr.recv_cq);
        if (rc)
                dprintk("RPC:       %s: ib_destroy_cq returned %i\n",
                        __func__, rc);
 
-       rpcrdma_clean_cq(ep->rep_attr.send_cq);
        rc = ib_destroy_cq(ep->rep_attr.send_cq);
        if (rc)
                dprintk("RPC:       %s: ib_destroy_cq returned %i\n",
index 584a0343ab0cc132b7c2038679923b6617926cf7..85813de26da87715df7d1d259339e30450c7815a 100644 (file)
@@ -633,6 +633,7 @@ static const struct snd_pci_quirk cs4208_mac_fixup_tbl[] = {
        SND_PCI_QUIRK(0x106b, 0x5e00, "MacBookPro 11,2", CS4208_MBP11),
        SND_PCI_QUIRK(0x106b, 0x7100, "MacBookAir 6,1", CS4208_MBA6),
        SND_PCI_QUIRK(0x106b, 0x7200, "MacBookAir 6,2", CS4208_MBA6),
+       SND_PCI_QUIRK(0x106b, 0x7b00, "MacBookPro 12,1", CS4208_MBP11),
        {} /* terminator */
 };
 
index afec6dc9f91fddcf8c0023b344771307aa684d3a..16b8dcba5c12d2d13ed7c80c4e6f93df69d9944f 100644 (file)
@@ -5306,6 +5306,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad T440", ALC292_FIXUP_TPT440_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad X240", ALC292_FIXUP_TPT440_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
+       SND_PCI_QUIRK(0x17aa, 0x2223, "ThinkPad T550", ALC292_FIXUP_TPT440_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
        SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP),
index 9d947aef2c8b60b99f63fd9464ad289bef0c7061..def5cc8dff0293c2f70c4c3fcf67da1aea1bf55e 100644 (file)
@@ -4520,7 +4520,11 @@ static int patch_stac92hd73xx(struct hda_codec *codec)
                return err;
 
        spec = codec->spec;
-       codec->power_save_node = 1;
+       /* enable power_save_node only for new 92HD89xx chips, as it causes
+        * click noises on old 92HD73xx chips.
+        */
+       if ((codec->core.vendor_id & 0xfffffff0) != 0x111d7670)
+               codec->power_save_node = 1;
        spec->linear_tone_beep = 0;
        spec->gen.mixer_nid = 0x1d;
        spec->have_spdif_mux = 1;
index 58c3164802b8ceda545e1469f557a814702694be..8c907ebea18960ec8e48942f5746fd2121705736 100644 (file)
@@ -129,6 +129,8 @@ static struct snd_soc_dai_link db1300_i2s_dai = {
        .cpu_dai_name   = "au1xpsc_i2s.2",
        .platform_name  = "au1xpsc-pcm.2",
        .codec_name     = "wm8731.0-001b",
+       .dai_fmt        = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF |
+                         SND_SOC_DAIFMT_CBM_CFM,
        .ops            = &db1200_i2s_wm8731_ops,
 };
 
@@ -146,6 +148,8 @@ static struct snd_soc_dai_link db1550_i2s_dai = {
        .cpu_dai_name   = "au1xpsc_i2s.3",
        .platform_name  = "au1xpsc-pcm.3",
        .codec_name     = "wm8731.0-001b",
+       .dai_fmt        = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF |
+                         SND_SOC_DAIFMT_CBM_CFM,
        .ops            = &db1200_i2s_wm8731_ops,
 };
 
index 268a28bd1df409dd103d08bbe809cfe294b1e858..5c101af0ac630dddf1cf12085846d5cfd9c08911 100644 (file)
@@ -519,11 +519,11 @@ static const struct snd_kcontrol_new rt5645_snd_controls[] = {
                RT5645_L_VOL_SFT + 1, RT5645_R_VOL_SFT + 1, 63, 0, adc_vol_tlv),
 
        /* ADC Boost Volume Control */
-       SOC_DOUBLE_TLV("STO1 ADC Boost Gain", RT5645_ADC_BST_VOL1,
+       SOC_DOUBLE_TLV("ADC Boost Capture Volume", RT5645_ADC_BST_VOL1,
                RT5645_STO1_ADC_L_BST_SFT, RT5645_STO1_ADC_R_BST_SFT, 3, 0,
                adc_bst_tlv),
-       SOC_DOUBLE_TLV("STO2 ADC Boost Gain", RT5645_ADC_BST_VOL1,
-               RT5645_STO2_ADC_L_BST_SFT, RT5645_STO2_ADC_R_BST_SFT, 3, 0,
+       SOC_DOUBLE_TLV("Mono ADC Boost Capture Volume", RT5645_ADC_BST_VOL2,
+               RT5645_MONO_ADC_L_BST_SFT, RT5645_MONO_ADC_R_BST_SFT, 3, 0,
                adc_bst_tlv),
 
        /* I2S2 function select */
index 0e4cfc6ac64984acb1bd395a7477b7cf21cfc020..8c964cfb120ddc4130e5d39e9ab96ae34623eb34 100644 (file)
@@ -39,8 +39,8 @@
 #define RT5645_STO1_ADC_DIG_VOL                        0x1c
 #define RT5645_MONO_ADC_DIG_VOL                        0x1d
 #define RT5645_ADC_BST_VOL1                    0x1e
-/* Mixer - D-D */
 #define RT5645_ADC_BST_VOL2                    0x20
+/* Mixer - D-D */
 #define RT5645_STO1_ADC_MIXER                  0x27
 #define RT5645_MONO_ADC_MIXER                  0x28
 #define RT5645_AD_DA_MIXER                     0x29
 #define RT5645_STO1_ADC_R_BST_SFT              12
 #define RT5645_STO1_ADC_COMP_MASK              (0x3 << 10)
 #define RT5645_STO1_ADC_COMP_SFT               10
-#define RT5645_STO2_ADC_L_BST_MASK             (0x3 << 8)
-#define RT5645_STO2_ADC_L_BST_SFT              8
-#define RT5645_STO2_ADC_R_BST_MASK             (0x3 << 6)
-#define RT5645_STO2_ADC_R_BST_SFT              6
-#define RT5645_STO2_ADC_COMP_MASK              (0x3 << 4)
-#define RT5645_STO2_ADC_COMP_SFT               4
+
+/* ADC Boost Volume Control (0x20) */
+#define RT5645_MONO_ADC_L_BST_MASK             (0x3 << 14)
+#define RT5645_MONO_ADC_L_BST_SFT              14
+#define RT5645_MONO_ADC_R_BST_MASK             (0x3 << 12)
+#define RT5645_MONO_ADC_R_BST_SFT              12
+#define RT5645_MONO_ADC_COMP_MASK              (0x3 << 10)
+#define RT5645_MONO_ADC_COMP_SFT               10
 
 /* Stereo2 ADC Mixer Control (0x26) */
 #define RT5645_STO2_ADC_SRC_MASK               (0x1 << 15)
index bfda25ef0dd43313f066a7afca06c11b8a8ecbe0..f540f82b1f271ec4833d9ea43aa7f4567c0df712 100644 (file)
@@ -1376,8 +1376,8 @@ static int sgtl5000_probe(struct snd_soc_codec *codec)
                        sgtl5000->micbias_resistor << SGTL5000_BIAS_R_SHIFT);
 
        snd_soc_update_bits(codec, SGTL5000_CHIP_MIC_CTRL,
-                       SGTL5000_BIAS_R_MASK,
-                       sgtl5000->micbias_voltage << SGTL5000_BIAS_R_SHIFT);
+                       SGTL5000_BIAS_VOLT_MASK,
+                       sgtl5000->micbias_voltage << SGTL5000_BIAS_VOLT_SHIFT);
        /*
         * disable DAP
         * TODO:
@@ -1549,7 +1549,7 @@ static int sgtl5000_i2c_probe(struct i2c_client *client,
                        else {
                                sgtl5000->micbias_voltage = 0;
                                dev_err(&client->dev,
-                                       "Unsuitable MicBias resistor\n");
+                                       "Unsuitable MicBias voltage\n");
                        }
                } else {
                        sgtl5000->micbias_voltage = 0;
index e3a0bca28bcf5fb7c454de1abf235c1c5ace347d..cc1d3981fa4b6b92c018d596a0aaac1192f141f1 100644 (file)
@@ -549,7 +549,7 @@ static struct snd_soc_dai_driver tas2552_dai[] = {
 /*
  * DAC digital volumes. From -7 to 24 dB in 1 dB steps
  */
-static DECLARE_TLV_DB_SCALE(dac_tlv, -7, 100, 0);
+static DECLARE_TLV_DB_SCALE(dac_tlv, -700, 100, 0);
 
 static const char * const tas2552_din_source_select[] = {
        "Muted",
index 1a82b19b26442e31eb38e8fa38287d9710aa3546..8739126a1f6f60d4c9e3eac08aaf337c2f7b3a2b 100644 (file)
@@ -1509,14 +1509,17 @@ static int aic3x_init(struct snd_soc_codec *codec)
        snd_soc_write(codec, PGAL_2_LLOPM_VOL, DEFAULT_VOL);
        snd_soc_write(codec, PGAR_2_RLOPM_VOL, DEFAULT_VOL);
 
-       /* Line2 to HP Bypass default volume, disconnect from Output Mixer */
-       snd_soc_write(codec, LINE2L_2_HPLOUT_VOL, DEFAULT_VOL);
-       snd_soc_write(codec, LINE2R_2_HPROUT_VOL, DEFAULT_VOL);
-       snd_soc_write(codec, LINE2L_2_HPLCOM_VOL, DEFAULT_VOL);
-       snd_soc_write(codec, LINE2R_2_HPRCOM_VOL, DEFAULT_VOL);
-       /* Line2 Line Out default volume, disconnect from Output Mixer */
-       snd_soc_write(codec, LINE2L_2_LLOPM_VOL, DEFAULT_VOL);
-       snd_soc_write(codec, LINE2R_2_RLOPM_VOL, DEFAULT_VOL);
+       /* On tlv320aic3104, these registers are reserved and must not be written */
+       if (aic3x->model != AIC3X_MODEL_3104) {
+               /* Line2 to HP Bypass default volume, disconnect from Output Mixer */
+               snd_soc_write(codec, LINE2L_2_HPLOUT_VOL, DEFAULT_VOL);
+               snd_soc_write(codec, LINE2R_2_HPROUT_VOL, DEFAULT_VOL);
+               snd_soc_write(codec, LINE2L_2_HPLCOM_VOL, DEFAULT_VOL);
+               snd_soc_write(codec, LINE2R_2_HPRCOM_VOL, DEFAULT_VOL);
+               /* Line2 Line Out default volume, disconnect from Output Mixer */
+               snd_soc_write(codec, LINE2L_2_LLOPM_VOL, DEFAULT_VOL);
+               snd_soc_write(codec, LINE2R_2_RLOPM_VOL, DEFAULT_VOL);
+       }
 
        switch (aic3x->model) {
        case AIC3X_MODEL_3X:
index 293e47a6ff59073af3aaf0bb6c6d76521d1b1d94..2fbc6ef8cbdb394fd4ffa2b612f50d111fcdc4e5 100644 (file)
@@ -3760,7 +3760,7 @@ static int wm8962_i2c_probe(struct i2c_client *i2c,
        ret = snd_soc_register_codec(&i2c->dev,
                                     &soc_codec_dev_wm8962, &wm8962_dai, 1);
        if (ret < 0)
-               goto err_enable;
+               goto err_pm_runtime;
 
        regcache_cache_only(wm8962->regmap, true);
 
@@ -3769,6 +3769,8 @@ static int wm8962_i2c_probe(struct i2c_client *i2c,
 
        return 0;
 
+err_pm_runtime:
+       pm_runtime_disable(&i2c->dev);
 err_enable:
        regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
 err:
@@ -3778,6 +3780,7 @@ err:
 static int wm8962_i2c_remove(struct i2c_client *client)
 {
        snd_soc_unregister_codec(&client->dev);
+       pm_runtime_disable(&client->dev);
        return 0;
 }
 
index a3e97b46b64e3871ec9362b231d19f9334628229..ba34252b7bba4fdd8d1b7c58a313b490c14aa329 100644 (file)
@@ -131,23 +131,32 @@ static inline void i2s_clear_irqs(struct dw_i2s_dev *dev, u32 stream)
 
        if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
                for (i = 0; i < 4; i++)
-                       i2s_write_reg(dev->i2s_base, TOR(i), 0);
+                       i2s_read_reg(dev->i2s_base, TOR(i));
        } else {
                for (i = 0; i < 4; i++)
-                       i2s_write_reg(dev->i2s_base, ROR(i), 0);
+                       i2s_read_reg(dev->i2s_base, ROR(i));
        }
 }
 
 static void i2s_start(struct dw_i2s_dev *dev,
                      struct snd_pcm_substream *substream)
 {
-
+       u32 i, irq;
        i2s_write_reg(dev->i2s_base, IER, 1);
 
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+               for (i = 0; i < 4; i++) {
+                       irq = i2s_read_reg(dev->i2s_base, IMR(i));
+                       i2s_write_reg(dev->i2s_base, IMR(i), irq & ~0x30);
+               }
                i2s_write_reg(dev->i2s_base, ITER, 1);
-       else
+       } else {
+               for (i = 0; i < 4; i++) {
+                       irq = i2s_read_reg(dev->i2s_base, IMR(i));
+                       i2s_write_reg(dev->i2s_base, IMR(i), irq & ~0x03);
+               }
                i2s_write_reg(dev->i2s_base, IRER, 1);
+       }
 
        i2s_write_reg(dev->i2s_base, CER, 1);
 }
index 48b2d24dd1f0a9a639c6bd7e7549035ed38f8e15..b95132e2f9dc299d82c783810982c2d5b768fb35 100644 (file)
@@ -95,7 +95,8 @@ static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
        case SND_SOC_DAIFMT_I2S:
                /* data on rising edge of bclk, frame low 1clk before data */
-               strcr |= SSI_STCR_TFSI | SSI_STCR_TEFS | SSI_STCR_TXBIT0;
+               strcr |= SSI_STCR_TXBIT0 | SSI_STCR_TSCKP | SSI_STCR_TFSI |
+                       SSI_STCR_TEFS;
                scr |= SSI_SCR_NET;
                if (ssi->flags & IMX_SSI_USE_I2S_SLAVE) {
                        scr &= ~SSI_I2S_MODE_MASK;
@@ -104,33 +105,31 @@ static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
                break;
        case SND_SOC_DAIFMT_LEFT_J:
                /* data on rising edge of bclk, frame high with data */
-               strcr |= SSI_STCR_TXBIT0;
+               strcr |= SSI_STCR_TXBIT0 | SSI_STCR_TSCKP;
                break;
        case SND_SOC_DAIFMT_DSP_B:
                /* data on rising edge of bclk, frame high with data */
-               strcr |= SSI_STCR_TFSL | SSI_STCR_TXBIT0;
+               strcr |= SSI_STCR_TXBIT0 | SSI_STCR_TSCKP | SSI_STCR_TFSL;
                break;
        case SND_SOC_DAIFMT_DSP_A:
                /* data on rising edge of bclk, frame high 1clk before data */
-               strcr |= SSI_STCR_TFSL | SSI_STCR_TXBIT0 | SSI_STCR_TEFS;
+               strcr |= SSI_STCR_TXBIT0 | SSI_STCR_TSCKP | SSI_STCR_TFSL |
+                       SSI_STCR_TEFS;
                break;
        }
 
        /* DAI clock inversion */
        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
        case SND_SOC_DAIFMT_IB_IF:
-               strcr |= SSI_STCR_TFSI;
-               strcr &= ~SSI_STCR_TSCKP;
+               strcr ^= SSI_STCR_TSCKP | SSI_STCR_TFSI;
                break;
        case SND_SOC_DAIFMT_IB_NF:
-               strcr &= ~(SSI_STCR_TSCKP | SSI_STCR_TFSI);
+               strcr ^= SSI_STCR_TSCKP;
                break;
        case SND_SOC_DAIFMT_NB_IF:
-               strcr |= SSI_STCR_TFSI | SSI_STCR_TSCKP;
+               strcr ^= SSI_STCR_TFSI;
                break;
        case SND_SOC_DAIFMT_NB_NF:
-               strcr &= ~SSI_STCR_TFSI;
-               strcr |= SSI_STCR_TSCKP;
                break;
        }
 
index 82e350e9501ccc0d5ebc82962f60c034466448eb..ac75816ada7c31b133586693e5c73a41dc79348f 100644 (file)
@@ -69,7 +69,8 @@ snd_emux_init_seq_oss(struct snd_emux *emu)
        struct snd_seq_oss_reg *arg;
        struct snd_seq_device *dev;
 
-       if (snd_seq_device_new(emu->card, 0, SNDRV_SEQ_DEV_ID_OSS,
+       /* using device#1 here for avoiding conflicts with OPL3 */
+       if (snd_seq_device_new(emu->card, 1, SNDRV_SEQ_DEV_ID_OSS,
                               sizeof(struct snd_seq_oss_reg), &dev) < 0)
                return;
 
index 349bc96ca1fedc4946ab9596edd5dd1b3813ac0b..e5f18a288b7489a93e880657401dd1f99014deda 100644 (file)
@@ -17,6 +17,7 @@ libperf-y += levenshtein.o
 libperf-y += llvm-utils.o
 libperf-y += parse-options.o
 libperf-y += parse-events.o
+libperf-y += perf_regs.o
 libperf-y += path.o
 libperf-y += rbtree.o
 libperf-y += bitmap.o
@@ -103,7 +104,6 @@ libperf-$(CONFIG_LIBBABELTRACE) += data-convert-bt.o
 
 libperf-y += scripting-engines/
 
-libperf-$(CONFIG_PERF_REGS) += perf_regs.o
 libperf-$(CONFIG_ZLIB) += zlib.o
 libperf-$(CONFIG_LZMA) += lzma.o
 
index 885e8ac83997905db7baa0d334015b5cf46e37d9..6b8eb13e14e4d5897fca71c41634a07cc9ec5d16 100644 (file)
@@ -6,6 +6,7 @@ const struct sample_reg __weak sample_reg_masks[] = {
        SMPL_REG_END
 };
 
+#ifdef HAVE_PERF_REGS_SUPPORT
 int perf_reg_value(u64 *valp, struct regs_dump *regs, int id)
 {
        int i, idx = 0;
@@ -29,3 +30,4 @@ out:
        *valp = regs->cache_regs[id];
        return 0;
 }
+#endif
index 2984dcc54d67cd7acb9d02975c4fb1b7b55fdb7c..679d6e493962267f7b219b88c05d06c61ef1d2ea 100644 (file)
@@ -2,6 +2,7 @@
 #define __PERF_REGS_H
 
 #include <linux/types.h>
+#include <linux/compiler.h>
 
 struct regs_dump;