Merge tag 'drivers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 17 Feb 2015 17:38:59 +0000 (09:38 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 17 Feb 2015 17:38:59 +0000 (09:38 -0800)
Pull ARM SoC driver updates from Olof Johansson:
 "These are changes for drivers that are intimately tied to some SoC and
  for some reason could not get merged through the respective subsystem
  maintainer tree.

  This time around, much of this is for at91, with the bulk of it being
  syscon and udc drivers.

  Also, there's:
   - coupled cpuidle support for Samsung Exynos4210
   - Renesas 73A0 common-clk work
   - of/platform changes to tear down DMA mappings on device destruction
   - a few updates to the TI Keystone knav code"

* tag 'drivers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (26 commits)
  cpuidle: exynos: add coupled cpuidle support for exynos4210
  ARM: EXYNOS: apply S5P_CENTRAL_SEQ_OPTION fix only when necessary
  soc: ti: knav_qmss_queue: change knav_range_setup_acc_irq to static
  soc: ti: knav_qmss_queue: makefile tweak to build as dynamic module
  pcmcia: at91_cf: depend on !ARCH_MULTIPLATFORM
  soc: ti: knav_qmss_queue: export API calls for use by user driver
  of/platform: teardown DMA mappings on device destruction
  usb: gadget: at91_udc: Allocate udc instance
  usb: gadget: at91_udc: Update DT binding documentation
  usb: gadget: at91_udc: Rework for multi-platform kernel support
  usb: gadget: at91_udc: Simplify probe and remove functions
  usb: gadget: at91_udc: Remove non-DT handling code
  usb: gadget: at91_udc: Document DT clocks and clock-names property
  usb: gadget: at91_udc: Drop uclk clock
  usb: gadget: at91_udc: Fix clock names
  mfd: syscon: Add Atmel SMC binding doc
  mfd: syscon: Add atmel-smc registers definition
  mfd: syscon: Add Atmel Matrix bus DT binding documentation
  mfd: syscon: Add atmel-matrix registers definition
  clk: shmobile: fix sparse NULL pointer warning
  ...

1  2 
Documentation/devicetree/bindings/usb/atmel-usb.txt
arch/arm/boot/dts/sh73a0-kzm9g-reference.dts
arch/arm/boot/dts/sh73a0.dtsi
arch/arm/mach-exynos/exynos.c
arch/arm/mach-exynos/pm.c
arch/arm/mach-exynos/suspend.c
arch/arm/mach-shmobile/setup-sh73a0.c
drivers/of/platform.c
drivers/pcmcia/Kconfig
drivers/usb/gadget/udc/at91_udc.c
drivers/usb/gadget/udc/at91_udc.h

@@@ -33,9 -33,17 +33,17 @@@ usb1: ehci@00800000 
  AT91 USB device controller
  
  Required properties:
-  - compatible: Should be "atmel,at91rm9200-udc"
+  - compatible: Should be one of the following
+              "atmel,at91rm9200-udc"
+              "atmel,at91sam9260-udc"
+              "atmel,at91sam9261-udc"
+              "atmel,at91sam9263-udc"
   - reg: Address and length of the register set for the device
   - interrupts: Should contain macb interrupt
+  - clocks: Should reference the peripheral and the AHB clocks
+  - clock-names: Should contains two strings
+               "pclk" for the peripheral clock
+               "hclk" for the AHB clock
  
  Optional properties:
   - atmel,vbus-gpio: If present, specifies a gpio that needs to be
@@@ -51,10 -59,7 +59,10 @@@ usb1: gadget@fffa4000 
  Atmel High-Speed USB device controller
  
  Required properties:
 - - compatible: Should be "atmel,at91sam9rl-udc"
 + - compatible: Should be one of the following
 +             "at91sam9rl-udc"
 +             "at91sam9g45-udc"
 +             "sama5d3-udc"
   - reg: Address and length of the register set for the device
   - interrupts: Should contain usba interrupt
   - ep childnode: To specify the number of endpoints and their properties.
  };
  
  &cmt1 {
 -      status = "ok";
 +      status = "okay";
  };
  
+ &extal2_clk {
+       clock-frequency = <48000000>;
+ };
  &i2c0 {
        status = "okay";
        as3711@40 {
@@@ -10,6 -10,7 +10,7 @@@
  
  /include/ "skeleton.dtsi"
  
+ #include <dt-bindings/clock/sh73a0-clock.h>
  #include <dt-bindings/interrupt-controller/irq.h>
  
  / {
                      <0xf0000100 0x100>;
        };
  
 +      sbsc2: memory-controller@fb400000 {
 +              compatible = "renesas,sbsc-sh73a0";
 +              reg = <0xfb400000 0x400>;
 +              interrupts = <0 37 IRQ_TYPE_LEVEL_HIGH>,
 +                           <0 38 IRQ_TYPE_LEVEL_HIGH>;
 +              interrupt-names = "sec", "temp";
 +      };
 +
 +      sbsc1: memory-controller@fe400000 {
 +              compatible = "renesas,sbsc-sh73a0";
 +              reg = <0xfe400000 0x400>;
 +              interrupts = <0 35 IRQ_TYPE_LEVEL_HIGH>,
 +                           <0 36 IRQ_TYPE_LEVEL_HIGH>;
 +              interrupt-names = "sec", "temp";
 +      };
 +
        pmu {
                compatible = "arm,cortex-a9-pmu";
                interrupts = <0 55 IRQ_TYPE_LEVEL_HIGH>,
@@@ -71,6 -56,8 +72,8 @@@
  
                renesas,channels-mask = <0x3f>;
  
+               clocks = <&mstp3_clks SH73A0_CLK_CMT1>;
+               clock-names = "fck";
                status = "disabled";
        };
  
                              0 168 IRQ_TYPE_LEVEL_HIGH
                              0 169 IRQ_TYPE_LEVEL_HIGH
                              0 170 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp1_clks SH73A0_CLK_IIC0>;
                status = "disabled";
        };
  
                              0 52 IRQ_TYPE_LEVEL_HIGH
                              0 53 IRQ_TYPE_LEVEL_HIGH
                              0 54 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp3_clks SH73A0_CLK_IIC1>;
                status = "disabled";
        };
  
                              0 172 IRQ_TYPE_LEVEL_HIGH
                              0 173 IRQ_TYPE_LEVEL_HIGH
                              0 174 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp0_clks SH73A0_CLK_IIC2>;
                status = "disabled";
        };
  
                              0 184 IRQ_TYPE_LEVEL_HIGH
                              0 185 IRQ_TYPE_LEVEL_HIGH
                              0 186 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp4_clks SH73A0_CLK_IIC3>;
                status = "disabled";
        };
  
                              0 188 IRQ_TYPE_LEVEL_HIGH
                              0 189 IRQ_TYPE_LEVEL_HIGH
                              0 190 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp4_clks SH73A0_CLK_IIC4>;
                status = "disabled";
        };
  
                reg = <0xe6bd0000 0x100>;
                interrupts = <0 140 IRQ_TYPE_LEVEL_HIGH
                              0 141 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp3_clks SH73A0_CLK_MMCIF0>;
                reg-io-width = <4>;
                status = "disabled";
        };
                interrupts = <0 83 IRQ_TYPE_LEVEL_HIGH
                              0 84 IRQ_TYPE_LEVEL_HIGH
                              0 85 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp3_clks SH73A0_CLK_SDHI0>;
                cap-sd-highspeed;
                status = "disabled";
        };
                reg = <0xee120000 0x100>;
                interrupts = <0 88 IRQ_TYPE_LEVEL_HIGH
                              0 89 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp3_clks SH73A0_CLK_SDHI1>;
                toshiba,mmc-wrprotect-disable;
                cap-sd-highspeed;
                status = "disabled";
                reg = <0xee140000 0x100>;
                interrupts = <0 104 IRQ_TYPE_LEVEL_HIGH
                              0 105 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp3_clks SH73A0_CLK_SDHI2>;
                toshiba,mmc-wrprotect-disable;
                cap-sd-highspeed;
                status = "disabled";
                compatible = "renesas,scifa-sh73a0", "renesas,scifa";
                reg = <0xe6c40000 0x100>;
                interrupts = <0 72 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks SH73A0_CLK_SCIFA0>;
+               clock-names = "sci_ick";
                status = "disabled";
        };
  
                compatible = "renesas,scifa-sh73a0", "renesas,scifa";
                reg = <0xe6c50000 0x100>;
                interrupts = <0 73 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks SH73A0_CLK_SCIFA1>;
+               clock-names = "sci_ick";
                status = "disabled";
        };
  
                compatible = "renesas,scifa-sh73a0", "renesas,scifa";
                reg = <0xe6c60000 0x100>;
                interrupts = <0 74 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks SH73A0_CLK_SCIFA2>;
+               clock-names = "sci_ick";
                status = "disabled";
        };
  
                compatible = "renesas,scifa-sh73a0", "renesas,scifa";
                reg = <0xe6c70000 0x100>;
                interrupts = <0 75 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks SH73A0_CLK_SCIFA3>;
+               clock-names = "sci_ick";
                status = "disabled";
        };
  
                compatible = "renesas,scifa-sh73a0", "renesas,scifa";
                reg = <0xe6c80000 0x100>;
                interrupts = <0 78 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks SH73A0_CLK_SCIFA4>;
+               clock-names = "sci_ick";
                status = "disabled";
        };
  
                compatible = "renesas,scifa-sh73a0", "renesas,scifa";
                reg = <0xe6cb0000 0x100>;
                interrupts = <0 79 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks SH73A0_CLK_SCIFA5>;
+               clock-names = "sci_ick";
                status = "disabled";
        };
  
                compatible = "renesas,scifa-sh73a0", "renesas,scifa";
                reg = <0xe6cc0000 0x100>;
                interrupts = <0 156 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp3_clks SH73A0_CLK_SCIFA6>;
+               clock-names = "sci_ick";
                status = "disabled";
        };
  
                compatible = "renesas,scifa-sh73a0", "renesas,scifa";
                reg = <0xe6cd0000 0x100>;
                interrupts = <0 143 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks SH73A0_CLK_SCIFA7>;
+               clock-names = "sci_ick";
                status = "disabled";
        };
  
                compatible = "renesas,scifb-sh73a0", "renesas,scifb";
                reg = <0xe6c30000 0x100>;
                interrupts = <0 80 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&mstp2_clks SH73A0_CLK_SCIFB>;
+               clock-names = "sci_ick";
                status = "disabled";
        };
  
  
        sh_fsi2: sound@ec230000 {
                #sound-dai-cells = <1>;
 -              compatible = "renesas,sh_fsi2";
 +              compatible = "renesas,fsi2-sh73a0", "renesas,sh_fsi2";
                reg = <0xec230000 0x400>;
                interrupts = <0 146 0x4>;
                status = "disabled";
        };
+       clocks {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+               /* External root clocks */
+               extalr_clk: extalr_clk {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <32768>;
+                       clock-output-names = "extalr";
+               };
+               extal1_clk: extal1_clk {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <26000000>;
+                       clock-output-names = "extal1";
+               };
+               extal2_clk: extal2_clk {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-output-names = "extal2";
+               };
+               extcki_clk: extcki_clk {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-output-names = "extcki";
+               };
+               fsiack_clk: fsiack_clk {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <0>;
+                       clock-output-names = "fsiack";
+               };
+               fsibck_clk: fsibck_clk {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <0>;
+                       clock-output-names = "fsibck";
+               };
+               /* Special CPG clocks */
+               cpg_clocks: cpg_clocks@e6150000 {
+                       compatible = "renesas,sh73a0-cpg-clocks";
+                       reg = <0xe6150000 0x10000>;
+                       clocks = <&extal1_clk>, <&extal2_clk>;
+                       #clock-cells = <1>;
+                       clock-output-names = "main", "pll0", "pll1", "pll2",
+                                            "pll3", "dsi0phy", "dsi1phy",
+                                            "zg", "m3", "b", "m1", "m2",
+                                            "z", "zx", "hp";
+               };
+               /* Variable factor clocks (DIV6) */
+               vclk1_clk: vclk1_clk@e6150008 {
+                       compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+                       reg = <0xe6150008 4>;
+                       clocks = <&pll1_div2_clk>;
+                       #clock-cells = <0>;
+                       clock-output-names = "vclk1";
+               };
+               vclk2_clk: vclk2_clk@e615000c {
+                       compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+                       reg = <0xe615000c 4>;
+                       clocks = <&pll1_div2_clk>;
+                       #clock-cells = <0>;
+                       clock-output-names = "vclk2";
+               };
+               vclk3_clk: vclk3_clk@e615001c {
+                       compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+                       reg = <0xe615001c 4>;
+                       clocks = <&pll1_div2_clk>;
+                       #clock-cells = <0>;
+                       clock-output-names = "vclk3";
+               };
+               zb_clk: zb_clk@e6150010 {
+                       compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+                       reg = <0xe6150010 4>;
+                       clocks = <&pll1_div2_clk>;
+                       #clock-cells = <0>;
+                       clock-output-names = "zb";
+               };
+               flctl_clk: flctl_clk@e6150014 {
+                       compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+                       reg = <0xe6150014 4>;
+                       clocks = <&pll1_div2_clk>;
+                       #clock-cells = <0>;
+                       clock-output-names = "flctlck";
+               };
+               sdhi0_clk: sdhi0_clk@e6150074 {
+                       compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+                       reg = <0xe6150074 4>;
+                       clocks = <&pll1_div2_clk>;
+                       #clock-cells = <0>;
+                       clock-output-names = "sdhi0ck";
+               };
+               sdhi1_clk: sdhi1_clk@e6150078 {
+                       compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+                       reg = <0xe6150078 4>;
+                       clocks = <&pll1_div2_clk>;
+                       #clock-cells = <0>;
+                       clock-output-names = "sdhi1ck";
+               };
+               sdhi2_clk: sdhi2_clk@e615007c {
+                       compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+                       reg = <0xe615007c 4>;
+                       clocks = <&pll1_div2_clk>;
+                       #clock-cells = <0>;
+                       clock-output-names = "sdhi2ck";
+               };
+               fsia_clk: fsia_clk@e6150018 {
+                       compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+                       reg = <0xe6150018 4>;
+                       clocks = <&pll1_div2_clk>;
+                       #clock-cells = <0>;
+                       clock-output-names = "fsia";
+               };
+               fsib_clk: fsib_clk@e6150090 {
+                       compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+                       reg = <0xe6150090 4>;
+                       clocks = <&pll1_div2_clk>;
+                       #clock-cells = <0>;
+                       clock-output-names = "fsib";
+               };
+               sub_clk: sub_clk@e6150080 {
+                       compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+                       reg = <0xe6150080 4>;
+                       clocks = <&extal2_clk>;
+                       #clock-cells = <0>;
+                       clock-output-names = "sub";
+               };
+               spua_clk: spua_clk@e6150084 {
+                       compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+                       reg = <0xe6150084 4>;
+                       clocks = <&pll1_div2_clk>;
+                       #clock-cells = <0>;
+                       clock-output-names = "spua";
+               };
+               spuv_clk: spuv_clk@e6150094 {
+                       compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+                       reg = <0xe6150094 4>;
+                       clocks = <&pll1_div2_clk>;
+                       #clock-cells = <0>;
+                       clock-output-names = "spuv";
+               };
+               msu_clk: msu_clk@e6150088 {
+                       compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+                       reg = <0xe6150088 4>;
+                       clocks = <&pll1_div2_clk>;
+                       #clock-cells = <0>;
+                       clock-output-names = "msu";
+               };
+               hsi_clk: hsi_clk@e615008c {
+                       compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+                       reg = <0xe615008c 4>;
+                       clocks = <&pll1_div2_clk>;
+                       #clock-cells = <0>;
+                       clock-output-names = "hsi";
+               };
+               mfg1_clk: mfg1_clk@e6150098 {
+                       compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+                       reg = <0xe6150098 4>;
+                       clocks = <&pll1_div2_clk>;
+                       #clock-cells = <0>;
+                       clock-output-names = "mfg1";
+               };
+               mfg2_clk: mfg2_clk@e615009c {
+                       compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+                       reg = <0xe615009c 4>;
+                       clocks = <&pll1_div2_clk>;
+                       #clock-cells = <0>;
+                       clock-output-names = "mfg2";
+               };
+               dsit_clk: dsit_clk@e6150060 {
+                       compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+                       reg = <0xe6150060 4>;
+                       clocks = <&pll1_div2_clk>;
+                       #clock-cells = <0>;
+                       clock-output-names = "dsit";
+               };
+               dsi0p_clk: dsi0p_clk@e6150064 {
+                       compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+                       reg = <0xe6150064 4>;
+                       clocks = <&pll1_div2_clk>;
+                       #clock-cells = <0>;
+                       clock-output-names = "dsi0pck";
+               };
+               /* Fixed factor clocks */
+               main_div2_clk: main_div2_clk {
+                       compatible = "fixed-factor-clock";
+                       clocks = <&cpg_clocks SH73A0_CLK_MAIN>;
+                       #clock-cells = <0>;
+                       clock-div = <2>;
+                       clock-mult = <1>;
+                       clock-output-names = "main_div2";
+               };
+               pll1_div2_clk: pll1_div2_clk {
+                       compatible = "fixed-factor-clock";
+                       clocks = <&cpg_clocks SH73A0_CLK_PLL1>;
+                       #clock-cells = <0>;
+                       clock-div = <2>;
+                       clock-mult = <1>;
+                       clock-output-names = "pll1_div2";
+               };
+               pll1_div7_clk: pll1_div7_clk {
+                       compatible = "fixed-factor-clock";
+                       clocks = <&cpg_clocks SH73A0_CLK_PLL1>;
+                       #clock-cells = <0>;
+                       clock-div = <7>;
+                       clock-mult = <1>;
+                       clock-output-names = "pll1_div7";
+               };
+               pll1_div13_clk: pll1_div13_clk {
+                       compatible = "fixed-factor-clock";
+                       clocks = <&cpg_clocks SH73A0_CLK_PLL1>;
+                       #clock-cells = <0>;
+                       clock-div = <13>;
+                       clock-mult = <1>;
+                       clock-output-names = "pll1_div13";
+               };
+               twd_clk: twd_clk {
+                       compatible = "fixed-factor-clock";
+                       clocks = <&cpg_clocks SH73A0_CLK_Z>;
+                       #clock-cells = <0>;
+                       clock-div = <4>;
+                       clock-mult = <1>;
+                       clock-output-names = "twd";
+               };
+               /* Gate clocks */
+               mstp0_clks: mstp0_clks@e6150130 {
+                       compatible = "renesas,sh73a0-mstp-clocks", "renesas,cpg-mstp-clocks";
+                       reg = <0xe6150130 4>, <0xe6150030 4>;
+                       clocks = <&cpg_clocks SH73A0_CLK_HP>;
+                       #clock-cells = <1>;
+                       clock-indices = <
+                               SH73A0_CLK_IIC2
+                       >;
+                       clock-output-names =
+                               "iic2";
+               };
+               mstp1_clks: mstp1_clks@e6150134 {
+                       compatible = "renesas,sh73a0-mstp-clocks", "renesas,cpg-mstp-clocks";
+                       reg = <0xe6150134 4>, <0xe6150038 4>;
+                       clocks = <&cpg_clocks SH73A0_CLK_B>,
+                                <&cpg_clocks SH73A0_CLK_B>,
+                                <&cpg_clocks SH73A0_CLK_B>,
+                                <&cpg_clocks SH73A0_CLK_B>,
+                                <&sub_clk>, <&cpg_clocks SH73A0_CLK_B>,
+                                <&cpg_clocks SH73A0_CLK_HP>,
+                                <&cpg_clocks SH73A0_CLK_ZG>,
+                                <&cpg_clocks SH73A0_CLK_B>;
+                       #clock-cells = <1>;
+                       clock-indices = <
+                               SH73A0_CLK_CEU1 SH73A0_CLK_CSI2_RX1
+                               SH73A0_CLK_CEU0 SH73A0_CLK_CSI2_RX0
+                               SH73A0_CLK_TMU0 SH73A0_CLK_DSITX0
+                               SH73A0_CLK_IIC0 SH73A0_CLK_SGX
+                               SH73A0_CLK_LCDC0
+                       >;
+                       clock-output-names =
+                               "ceu1", "csi2_rx1", "ceu0", "csi2_rx0",
+                               "tmu0", "dsitx0", "iic0", "sgx", "lcdc0";
+               };
+               mstp2_clks: mstp2_clks@e6150138 {
+                       compatible = "renesas,sh73a0-mstp-clocks", "renesas,cpg-mstp-clocks";
+                       reg = <0xe6150138 4>, <0xe6150040 4>;
+                       clocks = <&sub_clk>, <&cpg_clocks SH73A0_CLK_HP>,
+                                <&cpg_clocks SH73A0_CLK_HP>, <&sub_clk>,
+                                <&sub_clk>, <&sub_clk>, <&sub_clk>, <&sub_clk>,
+                                <&sub_clk>, <&sub_clk>;
+                       #clock-cells = <1>;
+                       clock-indices = <
+                               SH73A0_CLK_SCIFA7 SH73A0_CLK_SY_DMAC
+                               SH73A0_CLK_MP_DMAC SH73A0_CLK_SCIFA5
+                               SH73A0_CLK_SCIFB SH73A0_CLK_SCIFA0
+                               SH73A0_CLK_SCIFA1 SH73A0_CLK_SCIFA2
+                               SH73A0_CLK_SCIFA3 SH73A0_CLK_SCIFA4
+                       >;
+                       clock-output-names =
+                               "scifa7", "sy_dmac", "mp_dmac", "scifa5",
+                               "scifb", "scifa0", "scifa1", "scifa2",
+                               "scifa3", "scifa4";
+               };
+               mstp3_clks: mstp3_clks@e615013c {
+                       compatible = "renesas,sh73a0-mstp-clocks", "renesas,cpg-mstp-clocks";
+                       reg = <0xe615013c 4>, <0xe6150048 4>;
+                       clocks = <&sub_clk>, <&extalr_clk>,
+                                <&cpg_clocks SH73A0_CLK_HP>, <&sub_clk>,
+                                <&cpg_clocks SH73A0_CLK_HP>,
+                                <&cpg_clocks SH73A0_CLK_HP>, <&flctl_clk>,
+                                <&sdhi0_clk>, <&sdhi1_clk>,
+                                <&cpg_clocks SH73A0_CLK_HP>, <&sdhi2_clk>,
+                                <&main_div2_clk>, <&main_div2_clk>,
+                                <&main_div2_clk>, <&main_div2_clk>,
+                                <&main_div2_clk>;
+                       #clock-cells = <1>;
+                       clock-indices = <
+                               SH73A0_CLK_SCIFA6 SH73A0_CLK_CMT1
+                               SH73A0_CLK_FSI SH73A0_CLK_IRDA
+                               SH73A0_CLK_IIC1 SH73A0_CLK_USB SH73A0_CLK_FLCTL
+                               SH73A0_CLK_SDHI0 SH73A0_CLK_SDHI1
+                               SH73A0_CLK_MMCIF0 SH73A0_CLK_SDHI2
+                               SH73A0_CLK_TPU0 SH73A0_CLK_TPU1
+                               SH73A0_CLK_TPU2 SH73A0_CLK_TPU3
+                               SH73A0_CLK_TPU4
+                       >;
+                       clock-output-names =
+                               "scifa6", "cmt1", "fsi", "irda", "iic1",
+                               "usb", "flctl", "sdhi0", "sdhi1", "mmcif0", "sdhi2",
+                               "tpu0", "tpu1", "tpu2", "tpu3", "tpu4";
+               };
+               mstp4_clks: mstp4_clks@e6150140 {
+                       compatible = "renesas,sh73a0-mstp-clocks", "renesas,cpg-mstp-clocks";
+                       reg = <0xe6150140 4>, <0xe615004c 4>;
+                       clocks = <&cpg_clocks SH73A0_CLK_HP>,
+                                <&cpg_clocks SH73A0_CLK_HP>, <&extalr_clk>;
+                       #clock-cells = <1>;
+                       clock-indices = <
+                               SH73A0_CLK_IIC3 SH73A0_CLK_IIC4
+                               SH73A0_CLK_KEYSC
+                       >;
+                       clock-output-names =
+                               "iic3", "iic4", "keysc";
+               };
+       };
  };
  #include <asm/mach/map.h>
  #include <asm/memory.h>
  
 +#include <mach/map.h>
 +
  #include "common.h"
  #include "mfc.h"
  #include "regs-pmu.h"
 -#include "regs-sys.h"
  
  void __iomem *pmu_base_addr;
  
  static struct map_desc exynos4_iodesc[] __initdata = {
        {
 -              .virtual        = (unsigned long)S3C_VA_SYS,
 -              .pfn            = __phys_to_pfn(EXYNOS4_PA_SYSCON),
 -              .length         = SZ_64K,
 -              .type           = MT_DEVICE,
 -      }, {
                .virtual        = (unsigned long)S5P_VA_SROMC,
                .pfn            = __phys_to_pfn(EXYNOS4_PA_SROMC),
                .length         = SZ_4K,
  
  static struct map_desc exynos5_iodesc[] __initdata = {
        {
 -              .virtual        = (unsigned long)S3C_VA_SYS,
 -              .pfn            = __phys_to_pfn(EXYNOS5_PA_SYSCON),
 -              .length         = SZ_64K,
 -              .type           = MT_DEVICE,
 -      }, {
                .virtual        = (unsigned long)S5P_VA_SROMC,
                .pfn            = __phys_to_pfn(EXYNOS5_PA_SROMC),
                .length         = SZ_4K,
@@@ -204,6 -213,32 +204,6 @@@ static void __init exynos_init_irq(void
  
  static void __init exynos_dt_machine_init(void)
  {
 -      struct device_node *i2c_np;
 -      const char *i2c_compat = "samsung,s3c2440-i2c";
 -      unsigned int tmp;
 -      int id;
 -
 -      /*
 -       * Exynos5's legacy i2c controller and new high speed i2c
 -       * controller have muxed interrupt sources. By default the
 -       * interrupts for 4-channel HS-I2C controller are enabled.
 -       * If node for first four channels of legacy i2c controller
 -       * are available then re-configure the interrupts via the
 -       * system register.
 -       */
 -      if (soc_is_exynos5()) {
 -              for_each_compatible_node(i2c_np, NULL, i2c_compat) {
 -                      if (of_device_is_available(i2c_np)) {
 -                              id = of_alias_get_id(i2c_np, "i2c");
 -                              if (id < 4) {
 -                                      tmp = readl(EXYNOS5_SYS_I2C_CFG);
 -                                      writel(tmp & ~(0x1 << id),
 -                                                      EXYNOS5_SYS_I2C_CFG);
 -                              }
 -                      }
 -              }
 -      }
 -
        /*
         * This is called from smp_prepare_cpus if we've built for SMP, but
         * we still need to set it up for PM and firmware ops if not.
        if (!IS_ENABLED(CONFIG_SMP))
                exynos_sysram_init();
  
+ #ifdef CONFIG_ARM_EXYNOS_CPUIDLE
+       if (of_machine_is_compatible("samsung,exynos4210"))
+               exynos_cpuidle.dev.platform_data = &cpuidle_coupled_exynos_data;
+ #endif
        if (of_machine_is_compatible("samsung,exynos4210") ||
            of_machine_is_compatible("samsung,exynos4212") ||
            (of_machine_is_compatible("samsung,exynos4412") &&
@@@ -247,7 -286,6 +251,7 @@@ static void __init exynos_reserve(void
                "samsung,mfc-v5",
                "samsung,mfc-v6",
                "samsung,mfc-v7",
 +              "samsung,mfc-v8",
        };
  
        for (i = 0; i < ARRAY_SIZE(mfc_mem); i++)
  #include <asm/smp_scu.h>
  #include <asm/suspend.h>
  
 +#include <mach/map.h>
 +
  #include <plat/pm-common.h>
  
  #include "common.h"
  #include "exynos-pmu.h"
  #include "regs-pmu.h"
 -#include "regs-sys.h"
  
  static inline void __iomem *exynos_boot_vector_addr(void)
  {
@@@ -98,10 -97,6 +98,6 @@@ void exynos_pm_central_suspend(void
        tmp = pmu_raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
        tmp &= ~S5P_CENTRAL_LOWPWR_CFG;
        pmu_raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
-       /* Setting SEQ_OPTION register */
-       pmu_raw_writel(S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0,
-                      S5P_CENTRAL_SEQ_OPTION);
  }
  
  int exynos_pm_central_resume(void)
@@@ -165,6 -160,13 +161,13 @@@ void exynos_enter_aftr(void
  
        exynos_pm_central_suspend();
  
+       if (of_machine_is_compatible("samsung,exynos4212") ||
+           of_machine_is_compatible("samsung,exynos4412")) {
+               /* Setting SEQ_OPTION register */
+               pmu_raw_writel(S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0,
+                              S5P_CENTRAL_SEQ_OPTION);
+       }
        cpu_suspend(0, exynos_aftr_finisher);
  
        if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) {
  
        cpu_pm_exit();
  }
+ static atomic_t cpu1_wakeup = ATOMIC_INIT(0);
+ static int exynos_cpu0_enter_aftr(void)
+ {
+       int ret = -1;
+       /*
+        * If the other cpu is powered on, we have to power it off, because
+        * the AFTR state won't work otherwise
+        */
+       if (cpu_online(1)) {
+               /*
+                * We reach a sync point with the coupled idle state, we know
+                * the other cpu will power down itself or will abort the
+                * sequence, let's wait for one of these to happen
+                */
+               while (exynos_cpu_power_state(1)) {
+                       /*
+                        * The other cpu may skip idle and boot back
+                        * up again
+                        */
+                       if (atomic_read(&cpu1_wakeup))
+                               goto abort;
+                       /*
+                        * The other cpu may bounce through idle and
+                        * boot back up again, getting stuck in the
+                        * boot rom code
+                        */
+                       if (__raw_readl(cpu_boot_reg_base()) == 0)
+                               goto abort;
+                       cpu_relax();
+               }
+       }
+       exynos_enter_aftr();
+       ret = 0;
+ abort:
+       if (cpu_online(1)) {
+               /*
+                * Set the boot vector to something non-zero
+                */
+               __raw_writel(virt_to_phys(exynos_cpu_resume),
+                            cpu_boot_reg_base());
+               dsb();
+               /*
+                * Turn on cpu1 and wait for it to be on
+                */
+               exynos_cpu_power_up(1);
+               while (exynos_cpu_power_state(1) != S5P_CORE_LOCAL_PWR_EN)
+                       cpu_relax();
+               while (!atomic_read(&cpu1_wakeup)) {
+                       /*
+                        * Poke cpu1 out of the boot rom
+                        */
+                       __raw_writel(virt_to_phys(exynos_cpu_resume),
+                                    cpu_boot_reg_base());
+                       arch_send_wakeup_ipi_mask(cpumask_of(1));
+               }
+       }
+       return ret;
+ }
+ static int exynos_wfi_finisher(unsigned long flags)
+ {
+       cpu_do_idle();
+       return -1;
+ }
+ static int exynos_cpu1_powerdown(void)
+ {
+       int ret = -1;
+       /*
+        * Idle sequence for cpu1
+        */
+       if (cpu_pm_enter())
+               goto cpu1_aborted;
+       /*
+        * Turn off cpu 1
+        */
+       exynos_cpu_power_down(1);
+       ret = cpu_suspend(0, exynos_wfi_finisher);
+       cpu_pm_exit();
+ cpu1_aborted:
+       dsb();
+       /*
+        * Notify cpu 0 that cpu 1 is awake
+        */
+       atomic_set(&cpu1_wakeup, 1);
+       return ret;
+ }
+ static void exynos_pre_enter_aftr(void)
+ {
+       __raw_writel(virt_to_phys(exynos_cpu_resume), cpu_boot_reg_base());
+ }
+ static void exynos_post_enter_aftr(void)
+ {
+       atomic_set(&cpu1_wakeup, 0);
+ }
+ struct cpuidle_exynos_data cpuidle_coupled_exynos_data = {
+       .cpu0_enter_aftr                = exynos_cpu0_enter_aftr,
+       .cpu1_powerdown         = exynos_cpu1_powerdown,
+       .pre_enter_aftr         = exynos_pre_enter_aftr,
+       .post_enter_aftr                = exynos_post_enter_aftr,
+ };
@@@ -34,6 -34,7 +34,6 @@@
  
  #include "common.h"
  #include "regs-pmu.h"
 -#include "regs-sys.h"
  #include "exynos-pmu.h"
  
  #define S5P_CHECK_SLEEP 0x00000BAD
@@@ -52,6 -53,10 +52,6 @@@ struct exynos_wkup_irq 
        u32 mask;
  };
  
 -static struct sleep_save exynos5_sys_save[] = {
 -      SAVE_ITEM(EXYNOS5_SYS_I2C_CFG),
 -};
 -
  static struct sleep_save exynos_core_save[] = {
        /* SROM side */
        SAVE_ITEM(S5P_SROM_BW),
@@@ -86,12 -91,6 +86,12 @@@ static unsigned int exynos_pmu_spare3
  
  static u32 exynos_irqwake_intmask = 0xffffffff;
  
 +static const struct exynos_wkup_irq exynos3250_wkup_irq[] = {
 +      { 73, BIT(1) }, /* RTC alarm */
 +      { 74, BIT(2) }, /* RTC tick */
 +      { /* sentinel */ },
 +};
 +
  static const struct exynos_wkup_irq exynos4_wkup_irq[] = {
        { 76, BIT(1) }, /* RTC alarm */
        { 77, BIT(2) }, /* RTC tick */
@@@ -115,19 -114,6 +115,19 @@@ unsigned int exynos_release_ret_regs[] 
        REG_TABLE_END,
  };
  
 +unsigned int exynos3250_release_ret_regs[] = {
 +      S5P_PAD_RET_MAUDIO_OPTION,
 +      S5P_PAD_RET_GPIO_OPTION,
 +      S5P_PAD_RET_UART_OPTION,
 +      S5P_PAD_RET_MMCA_OPTION,
 +      S5P_PAD_RET_MMCB_OPTION,
 +      S5P_PAD_RET_EBIA_OPTION,
 +      S5P_PAD_RET_EBIB_OPTION,
 +      S5P_PAD_RET_MMC2_OPTION,
 +      S5P_PAD_RET_SPI_OPTION,
 +      REG_TABLE_END,
 +};
 +
  unsigned int exynos5420_release_ret_regs[] = {
        EXYNOS_PAD_RET_DRAM_OPTION,
        EXYNOS_PAD_RET_MAUDIO_OPTION,
@@@ -187,12 -173,6 +187,12 @@@ static int exynos_cpu_suspend(unsigned 
        return exynos_cpu_do_idle();
  }
  
 +static int exynos3250_cpu_suspend(unsigned long arg)
 +{
 +      flush_cache_all();
 +      return exynos_cpu_do_idle();
 +}
 +
  static int exynos5420_cpu_suspend(unsigned long arg)
  {
        /* MCPM works with HW CPU identifiers */
@@@ -250,23 -230,6 +250,23 @@@ static void exynos_pm_prepare(void
        pmu_raw_writel(virt_to_phys(exynos_cpu_resume), S5P_INFORM0);
  }
  
 +static void exynos3250_pm_prepare(void)
 +{
 +      unsigned int tmp;
 +
 +      /* Set wake-up mask registers */
 +      exynos_pm_set_wakeup_mask();
 +
 +      tmp = pmu_raw_readl(EXYNOS3_ARM_L2_OPTION);
 +      tmp &= ~EXYNOS5_OPTION_USE_RETENTION;
 +      pmu_raw_writel(tmp, EXYNOS3_ARM_L2_OPTION);
 +
 +      exynos_pm_enter_sleep_mode();
 +
 +      /* ensure at least INFORM0 has the resume address */
 +      pmu_raw_writel(virt_to_phys(exynos_cpu_resume), S5P_INFORM0);
 +}
 +
  static void exynos5420_pm_prepare(void)
  {
        unsigned int tmp;
@@@ -319,6 -282,10 +319,10 @@@ static int exynos_pm_suspend(void
  {
        exynos_pm_central_suspend();
  
+       /* Setting SEQ_OPTION register */
+       pmu_raw_writel(S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0,
+                      S5P_CENTRAL_SEQ_OPTION);
        if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
                exynos_cpu_save_register();
  
@@@ -381,28 -348,6 +385,28 @@@ early_wakeup
        pmu_raw_writel(0x0, S5P_INFORM1);
  }
  
 +static void exynos3250_pm_resume(void)
 +{
 +      u32 cpuid = read_cpuid_part();
 +
 +      if (exynos_pm_central_resume())
 +              goto early_wakeup;
 +
 +      /* For release retention */
 +      exynos_pm_release_retention();
 +
 +      pmu_raw_writel(S5P_USE_STANDBY_WFI_ALL, S5P_CENTRAL_SEQ_OPTION);
 +
 +      if (call_firmware_op(resume) == -ENOSYS
 +          && cpuid == ARM_CPU_PART_CORTEX_A9)
 +              exynos_cpu_restore_register();
 +
 +early_wakeup:
 +
 +      /* Clear SLEEP mode set in INFORM1 */
 +      pmu_raw_writel(0x0, S5P_INFORM1);
 +}
 +
  static void exynos5420_prepare_pm_resume(void)
  {
        if (IS_ENABLED(CONFIG_EXYNOS5420_MCPM))
@@@ -542,16 -487,6 +546,16 @@@ static const struct platform_suspend_op
        .valid          = suspend_valid_only_mem,
  };
  
 +static const struct exynos_pm_data exynos3250_pm_data = {
 +      .wkup_irq       = exynos3250_wkup_irq,
 +      .wake_disable_mask = ((0xFF << 8) | (0x1F << 1)),
 +      .release_ret_regs = exynos3250_release_ret_regs,
 +      .pm_suspend     = exynos_pm_suspend,
 +      .pm_resume      = exynos3250_pm_resume,
 +      .pm_prepare     = exynos3250_pm_prepare,
 +      .cpu_suspend    = exynos3250_cpu_suspend,
 +};
 +
  static const struct exynos_pm_data exynos4_pm_data = {
        .wkup_irq       = exynos4_wkup_irq,
        .wake_disable_mask = ((0xFF << 8) | (0x1F << 1)),
@@@ -566,6 -501,8 +570,6 @@@ static const struct exynos_pm_data exyn
        .wkup_irq       = exynos5250_wkup_irq,
        .wake_disable_mask = ((0xFF << 8) | (0x1F << 1)),
        .release_ret_regs = exynos_release_ret_regs,
 -      .extra_save     = exynos5_sys_save,
 -      .num_extra_save = ARRAY_SIZE(exynos5_sys_save),
        .pm_suspend     = exynos_pm_suspend,
        .pm_resume      = exynos_pm_resume,
        .pm_prepare     = exynos_pm_prepare,
@@@ -585,9 -522,6 +589,9 @@@ static struct exynos_pm_data exynos5420
  
  static struct of_device_id exynos_pmu_of_device_ids[] = {
        {
 +              .compatible = "samsung,exynos3250-pmu",
 +              .data = &exynos3250_pm_data,
 +      }, {
                .compatible = "samsung,exynos4210-pmu",
                .data = &exynos4_pm_data,
        }, {
@@@ -563,7 -563,7 +563,7 @@@ static struct resource pmu_resources[] 
  };
  
  static struct platform_device pmu_device = {
 -      .name           = "arm-pmu",
 +      .name           = "armv7-pmu",
        .id             = -1,
        .num_resources  = ARRAY_SIZE(pmu_resources),
        .resource       = pmu_resources,
@@@ -595,7 -595,6 +595,7 @@@ static struct platform_device ipmmu_dev
  
  static struct renesas_intc_irqpin_config irqpin0_platform_data = {
        .irq_base = irq_pin(0), /* IRQ0 -> IRQ7 */
 +      .control_parent = true,
  };
  
  static struct resource irqpin0_resources[] = {
@@@ -657,7 -656,6 +657,7 @@@ static struct platform_device irqpin1_d
  
  static struct renesas_intc_irqpin_config irqpin2_platform_data = {
        .irq_base = irq_pin(16), /* IRQ16 -> IRQ23 */
 +      .control_parent = true,
  };
  
  static struct resource irqpin2_resources[] = {
@@@ -688,7 -686,6 +688,7 @@@ static struct platform_device irqpin2_d
  
  static struct renesas_intc_irqpin_config irqpin3_platform_data = {
        .irq_base = irq_pin(24), /* IRQ24 -> IRQ31 */
 +      .control_parent = true,
  };
  
  static struct resource irqpin3_resources[] = {
@@@ -766,7 -763,9 +766,9 @@@ void __init __weak sh73a0_register_twd(
  void __init sh73a0_earlytimer_init(void)
  {
        shmobile_init_delay();
+ #ifndef CONFIG_COMMON_CLK
        sh73a0_clock_init();
+ #endif
        shmobile_earlytimer_init();
        sh73a0_register_twd();
  }
@@@ -785,8 -784,9 +787,9 @@@ void __init sh73a0_add_early_devices(vo
  void __init sh73a0_add_standard_devices_dt(void)
  {
        /* clocks are setup late during boot in the case of DT */
+ #ifndef CONFIG_COMMON_CLK
        sh73a0_clock_init();
+ #endif
        of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
  }
  
diff --combined drivers/of/platform.c
@@@ -188,7 -188,7 +188,7 @@@ static void of_dma_configure(struct dev
                size = dev->coherent_dma_mask;
        } else {
                offset = PFN_DOWN(paddr - dma_addr);
 -              dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", dev->dma_pfn_offset);
 +              dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset);
        }
        dev->dma_pfn_offset = offset;
  
@@@ -526,6 -526,7 +526,7 @@@ static int of_platform_device_destroy(s
                amba_device_unregister(to_amba_device(dev));
  #endif
  
+       of_dma_deconfigure(dev);
        of_node_clear_flag(dev->of_node, OF_POPULATED);
        of_node_clear_flag(dev->of_node, OF_POPULATED_BUS);
        return 0;
@@@ -566,10 -567,6 +567,10 @@@ static int of_platform_notify(struct no
                if (!of_node_check_flag(rd->dn->parent, OF_POPULATED_BUS))
                        return NOTIFY_OK;       /* not for us */
  
 +              /* already populated? (driver using of_populate manually) */
 +              if (of_node_check_flag(rd->dn, OF_POPULATED))
 +                      return NOTIFY_OK;
 +
                /* pdev_parent may be NULL when no bus platform device */
                pdev_parent = of_find_device_by_node(rd->dn->parent);
                pdev = of_platform_device_create(rd->dn, NULL,
                break;
  
        case OF_RECONFIG_CHANGE_REMOVE:
 +
 +              /* already depopulated? */
 +              if (!of_node_check_flag(rd->dn, OF_POPULATED))
 +                      return NOTIFY_OK;
 +
                /* find our device by node */
                pdev = of_find_device_by_node(rd->dn);
                if (pdev == NULL)
diff --combined drivers/pcmcia/Kconfig
@@@ -69,8 -69,7 +69,8 @@@ config YENT
        tristate "CardBus yenta-compatible bridge support"
        depends on PCI
        select CARDBUS if !EXPERT
 -      select PCCARD_NONSTATIC if PCMCIA != n
 +      select PCCARD_NONSTATIC if PCMCIA != n && ISA
 +      select PCCARD_PCI if PCMCIA !=n && !ISA
        ---help---
          This option enables support for CardBus host bridges.  Virtually
          all modern PCMCIA bridges are CardBus compatible.  A "bridge" is
@@@ -110,8 -109,7 +110,8 @@@ config YENTA_TOSHIB
  config PD6729
        tristate "Cirrus PD6729 compatible bridge support"
        depends on PCMCIA && PCI
 -      select PCCARD_NONSTATIC
 +      select PCCARD_NONSTATIC if PCMCIA != n && ISA
 +      select PCCARD_PCI if PCMCIA !=n && !ISA
        help
          This provides support for the Cirrus PD6729 PCI-to-PCMCIA bridge
          device, found in some older laptops and PCMCIA card readers.
  config I82092
        tristate "i82092 compatible bridge support"
        depends on PCMCIA && PCI
 -      select PCCARD_NONSTATIC
 +      select PCCARD_NONSTATIC if PCMCIA != n && ISA
 +      select PCCARD_PCI if PCMCIA !=n && !ISA
        help
          This provides support for the Intel I82092AA PCI-to-PCMCIA bridge device,
          found in some older laptops and more commonly in evaluation boards for the
@@@ -279,6 -276,7 +279,7 @@@ config BFIN_CFPCMCI
  config AT91_CF
        tristate "AT91 CompactFlash Controller"
        depends on PCMCIA && ARCH_AT91
+       depends on !ARCH_MULTIPLATFORM
        help
          Say Y here to support the CompactFlash controller on AT91 chips.
          Or choose M to compile the driver as a module named "at91_cf".
@@@ -290,9 -288,6 +291,9 @@@ config ELECTRA_C
          Say Y here to support the CompactFlash controller on the
          PA Semi Electra eval board.
  
 +config PCCARD_PCI
 +      bool
 +
  config PCCARD_NONSTATIC
        bool
  
  #include <linux/of.h>
  #include <linux/of_gpio.h>
  #include <linux/platform_data/atmel.h>
- #include <asm/byteorder.h>
- #include <mach/hardware.h>
- #include <asm/io.h>
- #include <asm/irq.h>
- #include <asm/gpio.h>
- #include <mach/cpu.h>
- #include <mach/at91sam9261_matrix.h>
- #include <mach/at91_matrix.h>
+ #include <linux/regmap.h>
+ #include <linux/mfd/syscon.h>
+ #include <linux/mfd/syscon/atmel-matrix.h>
  
  #include "at91_udc.h"
  
  #define       DRIVER_VERSION  "3 May 2006"
  
  static const char driver_name [] = "at91_udc";
- static const char ep0name[] = "ep0";
+ static const char * const ep_names[] = {
+       "ep0",
+       "ep1",
+       "ep2",
+       "ep3-int",
+       "ep4",
+       "ep5",
+ };
+ #define ep0name               ep_names[0]
  
  #define VBUS_POLL_TIMEOUT     msecs_to_jiffies(1000)
  
@@@ -176,7 -177,7 +177,7 @@@ static int proc_udc_show(struct seq_fil
                udc->enabled
                        ? (udc->vbus ? "active" : "enabled")
                        : "disabled",
 -              udc->selfpowered ? "self" : "VBUS",
 +              udc->gadget.is_selfpowered ? "self" : "VBUS",
                udc->suspended ? ", suspended" : "",
                udc->driver ? udc->driver->driver.name : "(none)");
  
@@@ -895,8 -896,6 +896,6 @@@ static void clk_on(struct at91_udc *udc
                return;
        udc->clocked = 1;
  
-       if (IS_ENABLED(CONFIG_COMMON_CLK))
-               clk_enable(udc->uclk);
        clk_enable(udc->iclk);
        clk_enable(udc->fclk);
  }
@@@ -909,8 -908,6 +908,6 @@@ static void clk_off(struct at91_udc *ud
        udc->gadget.speed = USB_SPEED_UNKNOWN;
        clk_disable(udc->fclk);
        clk_disable(udc->iclk);
-       if (IS_ENABLED(CONFIG_COMMON_CLK))
-               clk_disable(udc->uclk);
  }
  
  /*
   */
  static void pullup(struct at91_udc *udc, int is_on)
  {
-       int     active = !udc->board.pullup_active_low;
        if (!udc->enabled || !udc->vbus)
                is_on = 0;
        DBG("%sactive\n", is_on ? "" : "in");
                clk_on(udc);
                at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_RXRSM);
                at91_udp_write(udc, AT91_UDP_TXVC, 0);
-               if (cpu_is_at91rm9200())
-                       gpio_set_value(udc->board.pullup_pin, active);
-               else if (cpu_is_at91sam9260() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) {
-                       u32     txvc = at91_udp_read(udc, AT91_UDP_TXVC);
-                       txvc |= AT91_UDP_TXVC_PUON;
-                       at91_udp_write(udc, AT91_UDP_TXVC, txvc);
-               } else if (cpu_is_at91sam9261() || cpu_is_at91sam9g10()) {
-                       u32     usbpucr;
-                       usbpucr = at91_matrix_read(AT91_MATRIX_USBPUCR);
-                       usbpucr |= AT91_MATRIX_USBPUCR_PUON;
-                       at91_matrix_write(AT91_MATRIX_USBPUCR, usbpucr);
-               }
        } else {
                stop_activity(udc);
                at91_udp_write(udc, AT91_UDP_IDR, AT91_UDP_RXRSM);
                at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS);
-               if (cpu_is_at91rm9200())
-                       gpio_set_value(udc->board.pullup_pin, !active);
-               else if (cpu_is_at91sam9260() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) {
-                       u32     txvc = at91_udp_read(udc, AT91_UDP_TXVC);
-                       txvc &= ~AT91_UDP_TXVC_PUON;
-                       at91_udp_write(udc, AT91_UDP_TXVC, txvc);
-               } else if (cpu_is_at91sam9261() || cpu_is_at91sam9g10()) {
-                       u32     usbpucr;
-                       usbpucr = at91_matrix_read(AT91_MATRIX_USBPUCR);
-                       usbpucr &= ~AT91_MATRIX_USBPUCR_PUON;
-                       at91_matrix_write(AT91_MATRIX_USBPUCR, usbpucr);
-               }
                clk_off(udc);
        }
+       if (udc->caps && udc->caps->pullup)
+               udc->caps->pullup(udc, is_on);
  }
  
  /* vbus is here!  turn everything on that's ready */
@@@ -1000,7 -970,7 +970,7 @@@ static int at91_set_selfpowered(struct 
        unsigned long   flags;
  
        spin_lock_irqsave(&udc->lock, flags);
 -      udc->selfpowered = (is_on != 0);
 +      gadget->is_selfpowered = (is_on != 0);
        spin_unlock_irqrestore(&udc->lock, flags);
        return 0;
  }
@@@ -1149,7 -1119,7 +1119,7 @@@ static void handle_setup(struct at91_ud
         */
        case ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8)
                        | USB_REQ_GET_STATUS:
 -              tmp = (udc->selfpowered << USB_DEVICE_SELF_POWERED);
 +              tmp = (udc->gadget.is_selfpowered << USB_DEVICE_SELF_POWERED);
                if (at91_udp_read(udc, AT91_UDP_GLB_STAT) & AT91_UDP_ESR)
                        tmp |= (1 << USB_DEVICE_REMOTE_WAKEUP);
                PACKET("get device status\n");
@@@ -1535,74 -1505,6 +1505,6 @@@ static irqreturn_t at91_udc_irq (int ir
  
  /*-------------------------------------------------------------------------*/
  
- static struct at91_udc controller = {
-       .gadget = {
-               .ops    = &at91_udc_ops,
-               .ep0    = &controller.ep[0].ep,
-               .name   = driver_name,
-       },
-       .ep[0] = {
-               .ep = {
-                       .name   = ep0name,
-                       .ops    = &at91_ep_ops,
-               },
-               .udc            = &controller,
-               .maxpacket      = 8,
-               .int_mask       = 1 << 0,
-       },
-       .ep[1] = {
-               .ep = {
-                       .name   = "ep1",
-                       .ops    = &at91_ep_ops,
-               },
-               .udc            = &controller,
-               .is_pingpong    = 1,
-               .maxpacket      = 64,
-               .int_mask       = 1 << 1,
-       },
-       .ep[2] = {
-               .ep = {
-                       .name   = "ep2",
-                       .ops    = &at91_ep_ops,
-               },
-               .udc            = &controller,
-               .is_pingpong    = 1,
-               .maxpacket      = 64,
-               .int_mask       = 1 << 2,
-       },
-       .ep[3] = {
-               .ep = {
-                       /* could actually do bulk too */
-                       .name   = "ep3-int",
-                       .ops    = &at91_ep_ops,
-               },
-               .udc            = &controller,
-               .maxpacket      = 8,
-               .int_mask       = 1 << 3,
-       },
-       .ep[4] = {
-               .ep = {
-                       .name   = "ep4",
-                       .ops    = &at91_ep_ops,
-               },
-               .udc            = &controller,
-               .is_pingpong    = 1,
-               .maxpacket      = 256,
-               .int_mask       = 1 << 4,
-       },
-       .ep[5] = {
-               .ep = {
-                       .name   = "ep5",
-                       .ops    = &at91_ep_ops,
-               },
-               .udc            = &controller,
-               .is_pingpong    = 1,
-               .maxpacket      = 256,
-               .int_mask       = 1 << 5,
-       },
-       /* ep6 and ep7 are also reserved (custom silicon might use them) */
- };
  static void at91_vbus_update(struct at91_udc *udc, unsigned value)
  {
        value ^= udc->board.vbus_active_low;
@@@ -1653,7 -1555,7 +1555,7 @@@ static int at91_start(struct usb_gadge
        udc->driver = driver;
        udc->gadget.dev.of_node = udc->pdev->dev.of_node;
        udc->enabled = 1;
 -      udc->selfpowered = 1;
 +      udc->gadget.is_selfpowered = 1;
  
        return 0;
  }
@@@ -1687,12 -1589,202 +1589,202 @@@ static void at91udc_shutdown(struct pla
        spin_unlock_irqrestore(&udc->lock, flags);
  }
  
- static void at91udc_of_init(struct at91_udc *udc,
-                                    struct device_node *np)
+ static int at91rm9200_udc_init(struct at91_udc *udc)
+ {
+       struct at91_ep *ep;
+       int ret;
+       int i;
+       for (i = 0; i < NUM_ENDPOINTS; i++) {
+               ep = &udc->ep[i];
+               switch (i) {
+               case 0:
+               case 3:
+                       ep->maxpacket = 8;
+                       break;
+               case 1 ... 2:
+                       ep->maxpacket = 64;
+                       break;
+               case 4 ... 5:
+                       ep->maxpacket = 256;
+                       break;
+               }
+       }
+       if (!gpio_is_valid(udc->board.pullup_pin)) {
+               DBG("no D+ pullup?\n");
+               return -ENODEV;
+       }
+       ret = devm_gpio_request(&udc->pdev->dev, udc->board.pullup_pin,
+                               "udc_pullup");
+       if (ret) {
+               DBG("D+ pullup is busy\n");
+               return ret;
+       }
+       gpio_direction_output(udc->board.pullup_pin,
+                             udc->board.pullup_active_low);
+       return 0;
+ }
+ static void at91rm9200_udc_pullup(struct at91_udc *udc, int is_on)
+ {
+       int active = !udc->board.pullup_active_low;
+       if (is_on)
+               gpio_set_value(udc->board.pullup_pin, active);
+       else
+               gpio_set_value(udc->board.pullup_pin, !active);
+ }
+ static const struct at91_udc_caps at91rm9200_udc_caps = {
+       .init = at91rm9200_udc_init,
+       .pullup = at91rm9200_udc_pullup,
+ };
+ static int at91sam9260_udc_init(struct at91_udc *udc)
+ {
+       struct at91_ep *ep;
+       int i;
+       for (i = 0; i < NUM_ENDPOINTS; i++) {
+               ep = &udc->ep[i];
+               switch (i) {
+               case 0 ... 3:
+                       ep->maxpacket = 64;
+                       break;
+               case 4 ... 5:
+                       ep->maxpacket = 512;
+                       break;
+               }
+       }
+       return 0;
+ }
+ static void at91sam9260_udc_pullup(struct at91_udc *udc, int is_on)
+ {
+       u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC);
+       if (is_on)
+               txvc |= AT91_UDP_TXVC_PUON;
+       else
+               txvc &= ~AT91_UDP_TXVC_PUON;
+       at91_udp_write(udc, AT91_UDP_TXVC, txvc);
+ }
+ static const struct at91_udc_caps at91sam9260_udc_caps = {
+       .init = at91sam9260_udc_init,
+       .pullup = at91sam9260_udc_pullup,
+ };
+ static int at91sam9261_udc_init(struct at91_udc *udc)
+ {
+       struct at91_ep *ep;
+       int i;
+       for (i = 0; i < NUM_ENDPOINTS; i++) {
+               ep = &udc->ep[i];
+               switch (i) {
+               case 0:
+                       ep->maxpacket = 8;
+                       break;
+               case 1 ... 3:
+                       ep->maxpacket = 64;
+                       break;
+               case 4 ... 5:
+                       ep->maxpacket = 256;
+                       break;
+               }
+       }
+       udc->matrix = syscon_regmap_lookup_by_phandle(udc->pdev->dev.of_node,
+                                                     "atmel,matrix");
+       if (IS_ERR(udc->matrix))
+               return PTR_ERR(udc->matrix);
+       return 0;
+ }
+ static void at91sam9261_udc_pullup(struct at91_udc *udc, int is_on)
+ {
+       u32 usbpucr = 0;
+       if (is_on)
+               usbpucr = AT91_MATRIX_USBPUCR_PUON;
+       regmap_update_bits(udc->matrix, AT91SAM9261_MATRIX_USBPUCR,
+                          AT91_MATRIX_USBPUCR_PUON, usbpucr);
+ }
+ static const struct at91_udc_caps at91sam9261_udc_caps = {
+       .init = at91sam9261_udc_init,
+       .pullup = at91sam9261_udc_pullup,
+ };
+ static int at91sam9263_udc_init(struct at91_udc *udc)
+ {
+       struct at91_ep *ep;
+       int i;
+       for (i = 0; i < NUM_ENDPOINTS; i++) {
+               ep = &udc->ep[i];
+               switch (i) {
+               case 0:
+               case 1:
+               case 2:
+               case 3:
+                       ep->maxpacket = 64;
+                       break;
+               case 4:
+               case 5:
+                       ep->maxpacket = 256;
+                       break;
+               }
+       }
+       return 0;
+ }
+ static const struct at91_udc_caps at91sam9263_udc_caps = {
+       .init = at91sam9263_udc_init,
+       .pullup = at91sam9260_udc_pullup,
+ };
+ static const struct of_device_id at91_udc_dt_ids[] = {
+       {
+               .compatible = "atmel,at91rm9200-udc",
+               .data = &at91rm9200_udc_caps,
+       },
+       {
+               .compatible = "atmel,at91sam9260-udc",
+               .data = &at91sam9260_udc_caps,
+       },
+       {
+               .compatible = "atmel,at91sam9261-udc",
+               .data = &at91sam9261_udc_caps,
+       },
+       {
+               .compatible = "atmel,at91sam9263-udc",
+               .data = &at91sam9263_udc_caps,
+       },
+       { /* sentinel */ }
+ };
+ MODULE_DEVICE_TABLE(of, at91_udc_dt_ids);
+ static void at91udc_of_init(struct at91_udc *udc, struct device_node *np)
  {
        struct at91_udc_data *board = &udc->board;
-       u32 val;
+       const struct of_device_id *match;
        enum of_gpio_flags flags;
+       u32 val;
  
        if (of_property_read_u32(np, "atmel,vbus-polled", &val) == 0)
                board->vbus_polled = 1;
                                                  &flags);
  
        board->pullup_active_low = (flags & OF_GPIO_ACTIVE_LOW) ? 1 : 0;
+       match = of_match_node(at91_udc_dt_ids, np);
+       if (match)
+               udc->caps = match->data;
  }
  
  static int at91udc_probe(struct platform_device *pdev)
        struct at91_udc *udc;
        int             retval;
        struct resource *res;
+       struct at91_ep  *ep;
+       int             i;
  
-       if (!dev_get_platdata(dev) && !pdev->dev.of_node) {
-               /* small (so we copy it) but critical! */
-               DBG("missing platform_data\n");
-               return -ENODEV;
-       }
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res)
-               return -ENXIO;
-       if (!request_mem_region(res->start, resource_size(res), driver_name)) {
-               DBG("someone's using UDC memory\n");
-               return -EBUSY;
-       }
+       udc = devm_kzalloc(dev, sizeof(*udc), GFP_KERNEL);
+       if (!udc)
+               return -ENOMEM;
  
        /* init software state */
-       udc = &controller;
        udc->gadget.dev.parent = dev;
-       if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node)
-               at91udc_of_init(udc, pdev->dev.of_node);
-       else
-               memcpy(&udc->board, dev_get_platdata(dev),
-                      sizeof(struct at91_udc_data));
+       at91udc_of_init(udc, pdev->dev.of_node);
        udc->pdev = pdev;
        udc->enabled = 0;
        spin_lock_init(&udc->lock);
  
-       /* rm9200 needs manual D+ pullup; off by default */
-       if (cpu_is_at91rm9200()) {
-               if (!gpio_is_valid(udc->board.pullup_pin)) {
-                       DBG("no D+ pullup?\n");
-                       retval = -ENODEV;
-                       goto fail0;
-               }
-               retval = gpio_request(udc->board.pullup_pin, "udc_pullup");
-               if (retval) {
-                       DBG("D+ pullup is busy\n");
-                       goto fail0;
-               }
-               gpio_direction_output(udc->board.pullup_pin,
-                               udc->board.pullup_active_low);
-       }
+       udc->gadget.ops = &at91_udc_ops;
+       udc->gadget.ep0 = &udc->ep[0].ep;
+       udc->gadget.name = driver_name;
+       udc->gadget.dev.init_name = "gadget";
  
-       /* newer chips have more FIFO memory than rm9200 */
-       if (cpu_is_at91sam9260() || cpu_is_at91sam9g20()) {
-               udc->ep[0].maxpacket = 64;
-               udc->ep[3].maxpacket = 64;
-               udc->ep[4].maxpacket = 512;
-               udc->ep[5].maxpacket = 512;
-       } else if (cpu_is_at91sam9261() || cpu_is_at91sam9g10()) {
-               udc->ep[3].maxpacket = 64;
-       } else if (cpu_is_at91sam9263()) {
-               udc->ep[0].maxpacket = 64;
-               udc->ep[3].maxpacket = 64;
+       for (i = 0; i < NUM_ENDPOINTS; i++) {
+               ep = &udc->ep[i];
+               ep->ep.name = ep_names[i];
+               ep->ep.ops = &at91_ep_ops;
+               ep->udc = udc;
+               ep->int_mask = BIT(i);
+               if (i != 0 && i != 3)
+                       ep->is_pingpong = 1;
        }
  
-       udc->udp_baseaddr = ioremap(res->start, resource_size(res));
-       if (!udc->udp_baseaddr) {
-               retval = -ENOMEM;
-               goto fail0a;
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       udc->udp_baseaddr = devm_ioremap_resource(dev, res);
+       if (IS_ERR(udc->udp_baseaddr))
+               return PTR_ERR(udc->udp_baseaddr);
+       if (udc->caps && udc->caps->init) {
+               retval = udc->caps->init(udc);
+               if (retval)
+                       return retval;
        }
  
        udc_reinit(udc);
  
        /* get interface and function clocks */
-       udc->iclk = clk_get(dev, "udc_clk");
-       udc->fclk = clk_get(dev, "udpck");
-       if (IS_ENABLED(CONFIG_COMMON_CLK))
-               udc->uclk = clk_get(dev, "usb_clk");
-       if (IS_ERR(udc->iclk) || IS_ERR(udc->fclk) ||
-           (IS_ENABLED(CONFIG_COMMON_CLK) && IS_ERR(udc->uclk))) {
-               DBG("clocks missing\n");
-               retval = -ENODEV;
-               goto fail1;
-       }
+       udc->iclk = devm_clk_get(dev, "pclk");
+       if (IS_ERR(udc->iclk))
+               return PTR_ERR(udc->iclk);
+       udc->fclk = devm_clk_get(dev, "hclk");
+       if (IS_ERR(udc->fclk))
+               return PTR_ERR(udc->fclk);
  
        /* don't do anything until we have both gadget driver and VBUS */
-       if (IS_ENABLED(CONFIG_COMMON_CLK)) {
-               clk_set_rate(udc->uclk, 48000000);
-               retval = clk_prepare(udc->uclk);
-               if (retval)
-                       goto fail1;
-       }
+       clk_set_rate(udc->fclk, 48000000);
        retval = clk_prepare(udc->fclk);
        if (retval)
-               goto fail1a;
+               return retval;
  
        retval = clk_prepare_enable(udc->iclk);
        if (retval)
-               goto fail1b;
+               goto err_unprepare_fclk;
        at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS);
        at91_udp_write(udc, AT91_UDP_IDR, 0xffffffff);
        /* Clear all pending interrupts - UDP may be used by bootloader. */
  
        /* request UDC and maybe VBUS irqs */
        udc->udp_irq = platform_get_irq(pdev, 0);
-       retval = request_irq(udc->udp_irq, at91_udc_irq,
-                       0, driver_name, udc);
-       if (retval < 0) {
+       retval = devm_request_irq(dev, udc->udp_irq, at91_udc_irq, 0,
+                                 driver_name, udc);
+       if (retval) {
                DBG("request irq %d failed\n", udc->udp_irq);
-               goto fail1c;
+               goto err_unprepare_iclk;
        }
        if (gpio_is_valid(udc->board.vbus_pin)) {
-               retval = gpio_request(udc->board.vbus_pin, "udc_vbus");
-               if (retval < 0) {
+               retval = devm_gpio_request(dev, udc->board.vbus_pin,
+                                          "udc_vbus");
+               if (retval) {
                        DBG("request vbus pin failed\n");
-                       goto fail2;
+                       goto err_unprepare_iclk;
                }
                gpio_direction_input(udc->board.vbus_pin);
  
                /*
                        mod_timer(&udc->vbus_timer,
                                  jiffies + VBUS_POLL_TIMEOUT);
                } else {
-                       if (request_irq(gpio_to_irq(udc->board.vbus_pin),
-                                       at91_vbus_irq, 0, driver_name, udc)) {
+                       retval = devm_request_irq(dev,
+                                       gpio_to_irq(udc->board.vbus_pin),
+                                       at91_vbus_irq, 0, driver_name, udc);
+                       if (retval) {
                                DBG("request vbus irq %d failed\n",
                                    udc->board.vbus_pin);
-                               retval = -EBUSY;
-                               goto fail3;
+                               goto err_unprepare_iclk;
                        }
                }
        } else {
        }
        retval = usb_add_gadget_udc(dev, &udc->gadget);
        if (retval)
-               goto fail4;
+               goto err_unprepare_iclk;
        dev_set_drvdata(dev, udc);
        device_init_wakeup(dev, 1);
        create_debug_file(udc);
  
        INFO("%s version %s\n", driver_name, DRIVER_VERSION);
        return 0;
- fail4:
-       if (gpio_is_valid(udc->board.vbus_pin) && !udc->board.vbus_polled)
-               free_irq(gpio_to_irq(udc->board.vbus_pin), udc);
- fail3:
-       if (gpio_is_valid(udc->board.vbus_pin))
-               gpio_free(udc->board.vbus_pin);
- fail2:
-       free_irq(udc->udp_irq, udc);
- fail1c:
+ err_unprepare_iclk:
        clk_unprepare(udc->iclk);
fail1b:
err_unprepare_fclk:
        clk_unprepare(udc->fclk);
- fail1a:
-       if (IS_ENABLED(CONFIG_COMMON_CLK))
-               clk_unprepare(udc->uclk);
- fail1:
-       if (IS_ENABLED(CONFIG_COMMON_CLK) && !IS_ERR(udc->uclk))
-               clk_put(udc->uclk);
-       if (!IS_ERR(udc->fclk))
-               clk_put(udc->fclk);
-       if (!IS_ERR(udc->iclk))
-               clk_put(udc->iclk);
-       iounmap(udc->udp_baseaddr);
- fail0a:
-       if (cpu_is_at91rm9200())
-               gpio_free(udc->board.pullup_pin);
- fail0:
-       release_mem_region(res->start, resource_size(res));
        DBG("%s probe failed, %d\n", driver_name, retval);
        return retval;
  }
  
  static int __exit at91udc_remove(struct platform_device *pdev)
  {
        struct at91_udc *udc = platform_get_drvdata(pdev);
-       struct resource *res;
        unsigned long   flags;
  
        DBG("remove\n");
  
        device_init_wakeup(&pdev->dev, 0);
        remove_debug_file(udc);
-       if (gpio_is_valid(udc->board.vbus_pin)) {
-               free_irq(gpio_to_irq(udc->board.vbus_pin), udc);
-               gpio_free(udc->board.vbus_pin);
-       }
-       free_irq(udc->udp_irq, udc);
-       iounmap(udc->udp_baseaddr);
-       if (cpu_is_at91rm9200())
-               gpio_free(udc->board.pullup_pin);
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       release_mem_region(res->start, resource_size(res));
-       if (IS_ENABLED(CONFIG_COMMON_CLK))
-               clk_unprepare(udc->uclk);
        clk_unprepare(udc->fclk);
        clk_unprepare(udc->iclk);
  
-       clk_put(udc->iclk);
-       clk_put(udc->fclk);
-       if (IS_ENABLED(CONFIG_COMMON_CLK))
-               clk_put(udc->uclk);
        return 0;
  }
  
@@@ -1989,15 -2017,6 +2017,6 @@@ static int at91udc_resume(struct platfo
  #define       at91udc_resume  NULL
  #endif
  
- #if defined(CONFIG_OF)
- static const struct of_device_id at91_udc_dt_ids[] = {
-       { .compatible = "atmel,at91rm9200-udc" },
-       { /* sentinel */ }
- };
- MODULE_DEVICE_TABLE(of, at91_udc_dt_ids);
- #endif
  static struct platform_driver at91_udc_driver = {
        .remove         = __exit_p(at91udc_remove),
        .shutdown       = at91udc_shutdown,
        .resume         = at91udc_resume,
        .driver         = {
                .name   = (char *) driver_name,
-               .of_match_table = of_match_ptr(at91_udc_dt_ids),
+               .of_match_table = at91_udc_dt_ids,
        },
  };
  
@@@ -107,6 -107,11 +107,11 @@@ struct at91_ep 
        unsigned                        fifo_bank:1;
  };
  
+ struct at91_udc_caps {
+       int (*init)(struct at91_udc *udc);
+       void (*pullup)(struct at91_udc *udc, int is_on);
+ };
  /*
   * driver is non-SMP, and just blocks IRQs whenever it needs
   * access protection for chip registers or driver state
@@@ -115,6 -120,7 +120,7 @@@ struct at91_udc 
        struct usb_gadget               gadget;
        struct at91_ep                  ep[NUM_ENDPOINTS];
        struct usb_gadget_driver        *driver;
+       const struct at91_udc_caps      *caps;
        unsigned                        vbus:1;
        unsigned                        enabled:1;
        unsigned                        clocked:1;
        unsigned                        req_pending:1;
        unsigned                        wait_for_addr_ack:1;
        unsigned                        wait_for_config_ack:1;
 -      unsigned                        selfpowered:1;
        unsigned                        active_suspend:1;
        u8                              addr;
        struct at91_udc_data            board;
-       struct clk                      *iclk, *fclk, *uclk;
+       struct clk                      *iclk, *fclk;
        struct platform_device          *pdev;
        struct proc_dir_entry           *pde;
        void __iomem                    *udp_baseaddr;
        spinlock_t                      lock;
        struct timer_list               vbus_timer;
        struct work_struct              vbus_timer_work;
+       struct regmap                   *matrix;
  };
  
  static inline struct at91_udc *to_udc(struct usb_gadget *g)