Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'vt8500-for-next' of git://git.code.sf.net/p/linuxwmt/code into next/dt

From Tony Prisk:

Update arch-vt8500 and drivers to device tree and
remove existing non-dt code.

* tag 'vt8500-for-next' of git://git.code.sf.net/p/linuxwmt/code:
arm: vt8500: Update arch-vt8500 to devicetree support.
arm: vt8500: gpio: Devicetree support for arch-vt8500
arm: vt8500: doc: Add device tree bindings for arch-vt8500 devices
arm: vt8500: clk: Add Common Clock Framework support
video: vt8500: Add devicetree support for vt8500-fb and wm8505-fb
serial: vt8500: Add devicetree support for vt8500-serial
rtc: vt8500: Add devicetree support for vt8500-rtc
arm: vt8500: Add device tree files for VIA/Wondermedia SoC's

Resolved add/change conflict in drivers/clk/Makefile.

Signed-off-by: Olof Johansson <olof@lixom.net>

+2294 -1587
+14
Documentation/devicetree/bindings/arm/vt8500.txt
··· 1 + VIA/Wondermedia VT8500 Platforms Device Tree Bindings 2 + --------------------------------------- 3 + 4 + Boards with the VIA VT8500 SoC shall have the following properties: 5 + Required root node property: 6 + compatible = "via,vt8500"; 7 + 8 + Boards with the Wondermedia WM8505 SoC shall have the following properties: 9 + Required root node property: 10 + compatible = "wm,wm8505"; 11 + 12 + Boards with the Wondermedia WM8650 SoC shall have the following properties: 13 + Required root node property: 14 + compatible = "wm,wm8650";
+16
Documentation/devicetree/bindings/arm/vt8500/via,vt8500-intc.txt
··· 1 + VIA/Wondermedia VT8500 Interrupt Controller 2 + ----------------------------------------------------- 3 + 4 + Required properties: 5 + - compatible : "via,vt8500-intc" 6 + - reg : Should contain 1 register ranges(address and length) 7 + - #interrupt-cells : should be <1> 8 + 9 + Example: 10 + 11 + intc: interrupt-controller@d8140000 { 12 + compatible = "via,vt8500-intc"; 13 + interrupt-controller; 14 + reg = <0xd8140000 0x10000>; 15 + #interrupt-cells = <1>; 16 + };
+13
Documentation/devicetree/bindings/arm/vt8500/via,vt8500-pmc.txt
··· 1 + VIA/Wondermedia VT8500 Power Management Controller 2 + ----------------------------------------------------- 3 + 4 + Required properties: 5 + - compatible : "via,vt8500-pmc" 6 + - reg : Should contain 1 register ranges(address and length) 7 + 8 + Example: 9 + 10 + pmc@d8130000 { 11 + compatible = "via,vt8500-pmc"; 12 + reg = <0xd8130000 0x1000>; 13 + };
+15
Documentation/devicetree/bindings/arm/vt8500/via,vt8500-timer.txt
··· 1 + VIA/Wondermedia VT8500 Timer 2 + ----------------------------------------------------- 3 + 4 + Required properties: 5 + - compatible : "via,vt8500-timer" 6 + - reg : Should contain 1 register ranges(address and length) 7 + - interrupts : interrupt for the timer 8 + 9 + Example: 10 + 11 + timer@d8130100 { 12 + compatible = "via,vt8500-timer"; 13 + reg = <0xd8130100 0x28>; 14 + interrupts = <36>; 15 + };
+72
Documentation/devicetree/bindings/clock/vt8500.txt
··· 1 + Device Tree Clock bindings for arch-vt8500 2 + 3 + This binding uses the common clock binding[1]. 4 + 5 + [1] Documentation/devicetree/bindings/clock/clock-bindings.txt 6 + 7 + Required properties: 8 + - compatible : shall be one of the following: 9 + "via,vt8500-pll-clock" - for a VT8500/WM8505 PLL clock 10 + "wm,wm8650-pll-clock" - for a WM8650 PLL clock 11 + "via,vt8500-device-clock" - for a VT/WM device clock 12 + 13 + Required properties for PLL clocks: 14 + - reg : shall be the control register offset from PMC base for the pll clock. 15 + - clocks : shall be the input parent clock phandle for the clock. This should 16 + be the reference clock. 17 + - #clock-cells : from common clock binding; shall be set to 0. 18 + 19 + Required properties for device clocks: 20 + - clocks : shall be the input parent clock phandle for the clock. This should 21 + be a pll output. 22 + - #clock-cells : from common clock binding; shall be set to 0. 23 + 24 + 25 + Device Clocks 26 + 27 + Device clocks are required to have one or both of the following sets of 28 + properties: 29 + 30 + 31 + Gated device clocks: 32 + 33 + Required properties: 34 + - enable-reg : shall be the register offset from PMC base for the enable 35 + register. 36 + - enable-bit : shall be the bit within enable-reg to enable/disable the clock. 37 + 38 + 39 + Divisor device clocks: 40 + 41 + Required property: 42 + - divisor-reg : shall be the register offset from PMC base for the divisor 43 + register. 44 + Optional property: 45 + - divisor-mask : shall be the mask for the divisor register. Defaults to 0x1f 46 + if not specified. 47 + 48 + 49 + For example: 50 + 51 + ref25: ref25M { 52 + #clock-cells = <0>; 53 + compatible = "fixed-clock"; 54 + clock-frequency = <25000000>; 55 + }; 56 + 57 + plla: plla { 58 + #clock-cells = <0>; 59 + compatible = "wm,wm8650-pll-clock"; 60 + clocks = <&ref25>; 61 + reg = <0x200>; 62 + }; 63 + 64 + sdhc: sdhc { 65 + #clock-cells = <0>; 66 + compatible = "via,vt8500-device-clock"; 67 + clocks = <&pllb>; 68 + divisor-reg = <0x328>; 69 + divisor-mask = <0x3f>; 70 + enable-reg = <0x254>; 71 + enable-bit = <18>; 72 + };
+24
Documentation/devicetree/bindings/gpio/gpio-vt8500.txt
··· 1 + VIA/Wondermedia VT8500 GPIO Controller 2 + ----------------------------------------------------- 3 + 4 + Required properties: 5 + - compatible : "via,vt8500-gpio", "wm,wm8505-gpio" 6 + or "wm,wm8650-gpio" depending on your SoC 7 + - reg : Should contain 1 register range (address and length) 8 + - #gpio-cells : should be <3>. 9 + 1) bank 10 + 2) pin number 11 + 3) flags - should be 0 12 + 13 + Example: 14 + 15 + gpio: gpio-controller@d8110000 { 16 + compatible = "via,vt8500-gpio"; 17 + gpio-controller; 18 + reg = <0xd8110000 0x10000>; 19 + #gpio-cells = <3>; 20 + }; 21 + 22 + vibrate { 23 + gpios = <&gpio 0 1 0>; /* Bank 0, Pin 1, No flags */ 24 + };
+15
Documentation/devicetree/bindings/rtc/via,vt8500-rtc.txt
··· 1 + VIA/Wondermedia VT8500 Realtime Clock Controller 2 + ----------------------------------------------------- 3 + 4 + Required properties: 5 + - compatible : "via,vt8500-rtc" 6 + - reg : Should contain 1 register ranges(address and length) 7 + - interrupts : alarm interrupt 8 + 9 + Example: 10 + 11 + rtc@d8100000 { 12 + compatible = "via,vt8500-rtc"; 13 + reg = <0xd8100000 0x10000>; 14 + interrupts = <48>; 15 + };
+17
Documentation/devicetree/bindings/tty/serial/via,vt8500-uart.txt
··· 1 + VIA/Wondermedia VT8500 UART Controller 2 + ----------------------------------------------------- 3 + 4 + Required properties: 5 + - compatible : "via,vt8500-uart" 6 + - reg : Should contain 1 register ranges(address and length) 7 + - interrupts : UART interrupt 8 + - clocks : phandle to the uart source clock (usually a 24Mhz fixed clock) 9 + 10 + Example: 11 + 12 + uart@d8210000 { 13 + compatible = "via,vt8500-uart"; 14 + reg = <0xd8210000 0x1040>; 15 + interrupts = <47>; 16 + clocks = <&ref24>; 17 + };
+15
Documentation/devicetree/bindings/usb/platform-uhci.txt
··· 1 + Generic Platform UHCI Controller 2 + ----------------------------------------------------- 3 + 4 + Required properties: 5 + - compatible : "platform-uhci" 6 + - reg : Should contain 1 register ranges(address and length) 7 + - interrupts : UHCI controller interrupt 8 + 9 + Example: 10 + 11 + uhci@d8007b00 { 12 + compatible = "platform-uhci"; 13 + reg = <0xd8007b00 0x200>; 14 + interrupts = <43>; 15 + };
+15
Documentation/devicetree/bindings/usb/via,vt8500-ehci.txt
··· 1 + VIA/Wondermedia VT8500 EHCI Controller 2 + ----------------------------------------------------- 3 + 4 + Required properties: 5 + - compatible : "via,vt8500-ehci" 6 + - reg : Should contain 1 register ranges(address and length) 7 + - interrupts : ehci controller interrupt 8 + 9 + Example: 10 + 11 + ehci@d8007900 { 12 + compatible = "via,vt8500-ehci"; 13 + reg = <0xd8007900 0x200>; 14 + interrupts = <43>; 15 + };
+2
Documentation/devicetree/bindings/vendor-prefixes.txt
··· 47 47 st STMicroelectronics 48 48 stericsson ST-Ericsson 49 49 ti Texas Instruments 50 + via VIA Technologies, Inc. 50 51 wlf Wolfson Microelectronics 52 + wm Wondermedia Technologies, Inc. 51 53 xlnx Xilinx
+62
Documentation/devicetree/bindings/video/via,vt8500-fb.txt
··· 1 + VIA VT8500 Framebuffer 2 + ----------------------------------------------------- 3 + 4 + Required properties: 5 + - compatible : "via,vt8500-fb" 6 + - reg : Should contain 1 register ranges(address and length) 7 + - interrupts : framebuffer controller interrupt 8 + - display: a phandle pointing to the display node 9 + 10 + Required nodes: 11 + - display: a display node is required to initialize the lcd panel 12 + This should be in the board dts. 13 + - default-mode: a videomode within the display with timing parameters 14 + as specified below. 15 + 16 + Example: 17 + 18 + fb@d800e400 { 19 + compatible = "via,vt8500-fb"; 20 + reg = <0xd800e400 0x400>; 21 + interrupts = <12>; 22 + display = <&display>; 23 + default-mode = <&mode0>; 24 + }; 25 + 26 + VIA VT8500 Display 27 + ----------------------------------------------------- 28 + Required properties (as per of_videomode_helper): 29 + 30 + - hactive, vactive: Display resolution 31 + - hfront-porch, hback-porch, hsync-len: Horizontal Display timing parameters 32 + in pixels 33 + vfront-porch, vback-porch, vsync-len: Vertical display timing parameters in 34 + lines 35 + - clock: displayclock in Hz 36 + - bpp: lcd panel bit-depth. 37 + <16> for RGB565, <32> for RGB888 38 + 39 + Optional properties (as per of_videomode_helper): 40 + - width-mm, height-mm: Display dimensions in mm 41 + - hsync-active-high (bool): Hsync pulse is active high 42 + - vsync-active-high (bool): Vsync pulse is active high 43 + - interlaced (bool): This is an interlaced mode 44 + - doublescan (bool): This is a doublescan mode 45 + 46 + Example: 47 + display: display@0 { 48 + modes { 49 + mode0: mode@0 { 50 + hactive = <800>; 51 + vactive = <480>; 52 + hback-porch = <88>; 53 + hfront-porch = <40>; 54 + hsync-len = <0>; 55 + vback-porch = <32>; 56 + vfront-porch = <11>; 57 + vsync-len = <1>; 58 + clock = <0>; /* unused but required */ 59 + bpp = <16>; /* non-standard but required */ 60 + }; 61 + }; 62 + };
+13
Documentation/devicetree/bindings/video/wm,prizm-ge-rops.txt
··· 1 + VIA/Wondermedia Graphics Engine Controller 2 + ----------------------------------------------------- 3 + 4 + Required properties: 5 + - compatible : "wm,prizm-ge-rops" 6 + - reg : Should contain 1 register ranges(address and length) 7 + 8 + Example: 9 + 10 + ge_rops@d8050400 { 11 + compatible = "wm,prizm-ge-rops"; 12 + reg = <0xd8050400 0x100>; 13 + };
+23
Documentation/devicetree/bindings/video/wm,wm8505-fb.txt
··· 1 + Wondermedia WM8505 Framebuffer 2 + ----------------------------------------------------- 3 + 4 + Required properties: 5 + - compatible : "wm,wm8505-fb" 6 + - reg : Should contain 1 register ranges(address and length) 7 + - via,display: a phandle pointing to the display node 8 + 9 + Required nodes: 10 + - display: a display node is required to initialize the lcd panel 11 + This should be in the board dts. See definition in 12 + Documentation/devicetree/bindings/video/via,vt8500-fb.txt 13 + - default-mode: a videomode node as specified in 14 + Documentation/devicetree/bindings/video/via,vt8500-fb.txt 15 + 16 + Example: 17 + 18 + fb@d8050800 { 19 + compatible = "wm,wm8505-fb"; 20 + reg = <0xd8050800 0x200>; 21 + display = <&display>; 22 + default-mode = <&mode0>; 23 + };
+5 -2
arch/arm/Kconfig
··· 1004 1004 select ARCH_HAS_CPUFREQ 1005 1005 select GENERIC_CLOCKEVENTS 1006 1006 select ARCH_REQUIRE_GPIOLIB 1007 + select USE_OF 1008 + select COMMON_CLK 1009 + select HAVE_CLK 1010 + select CLKDEV_LOOKUP 1007 1011 help 1008 1012 Support for VIA/WonderMedia VT8500/WM85xx System-on-Chip. 1009 1013 ··· 1131 1127 1132 1128 source "arch/arm/mach-vexpress/Kconfig" 1133 1129 source "arch/arm/plat-versatile/Kconfig" 1134 - 1135 - source "arch/arm/mach-vt8500/Kconfig" 1136 1130 1137 1131 source "arch/arm/mach-w90x900/Kconfig" 1138 1132 ··· 1624 1622 default 355 if ARCH_U8500 1625 1623 default 264 if MACH_H4700 1626 1624 default 512 if SOC_OMAP5 1625 + default 288 if ARCH_VT8500 1627 1626 default 0 1628 1627 help 1629 1628 Maximum number of GPIOs in the system.
+36
arch/arm/boot/dts/vt8500-bv07.dts
··· 1 + /* 2 + * vt8500-bv07.dts - Device tree file for Benign BV07 Netbook 3 + * 4 + * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz> 5 + * 6 + * Licensed under GPLv2 or later 7 + */ 8 + 9 + /dts-v1/; 10 + /include/ "vt8500.dtsi" 11 + 12 + / { 13 + model = "Benign BV07 Netbook"; 14 + 15 + /* 16 + * Display node is based on Sascha Hauer's patch on dri-devel. 17 + * Added a bpp property to calculate the size of the framebuffer 18 + * until the binding is formalized. 19 + */ 20 + display: display@0 { 21 + modes { 22 + mode0: mode@0 { 23 + hactive = <800>; 24 + vactive = <480>; 25 + hback-porch = <88>; 26 + hfront-porch = <40>; 27 + hsync-len = <0>; 28 + vback-porch = <32>; 29 + vfront-porch = <11>; 30 + vsync-len = <1>; 31 + clock = <0>; /* unused but required */ 32 + bpp = <16>; /* non-standard but required */ 33 + }; 34 + }; 35 + }; 36 + };
+116
arch/arm/boot/dts/vt8500.dtsi
··· 1 + /* 2 + * vt8500.dtsi - Device tree file for VIA VT8500 SoC 3 + * 4 + * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz> 5 + * 6 + * Licensed under GPLv2 or later 7 + */ 8 + 9 + /include/ "skeleton.dtsi" 10 + 11 + / { 12 + compatible = "via,vt8500"; 13 + 14 + soc { 15 + #address-cells = <1>; 16 + #size-cells = <1>; 17 + compatible = "simple-bus"; 18 + ranges; 19 + interrupt-parent = <&intc>; 20 + 21 + intc: interrupt-controller@d8140000 { 22 + compatible = "via,vt8500-intc"; 23 + interrupt-controller; 24 + reg = <0xd8140000 0x10000>; 25 + #interrupt-cells = <1>; 26 + }; 27 + 28 + gpio: gpio-controller@d8110000 { 29 + compatible = "via,vt8500-gpio"; 30 + gpio-controller; 31 + reg = <0xd8110000 0x10000>; 32 + #gpio-cells = <3>; 33 + }; 34 + 35 + pmc@d8130000 { 36 + compatible = "via,vt8500-pmc"; 37 + reg = <0xd8130000 0x1000>; 38 + 39 + clocks { 40 + #address-cells = <1>; 41 + #size-cells = <0>; 42 + 43 + ref24: ref24M { 44 + #clock-cells = <0>; 45 + compatible = "fixed-clock"; 46 + clock-frequency = <24000000>; 47 + }; 48 + }; 49 + }; 50 + 51 + timer@d8130100 { 52 + compatible = "via,vt8500-timer"; 53 + reg = <0xd8130100 0x28>; 54 + interrupts = <36>; 55 + }; 56 + 57 + ehci@d8007900 { 58 + compatible = "via,vt8500-ehci"; 59 + reg = <0xd8007900 0x200>; 60 + interrupts = <43>; 61 + }; 62 + 63 + uhci@d8007b00 { 64 + compatible = "platform-uhci"; 65 + reg = <0xd8007b00 0x200>; 66 + interrupts = <43>; 67 + }; 68 + 69 + fb@d800e400 { 70 + compatible = "via,vt8500-fb"; 71 + reg = <0xd800e400 0x400>; 72 + interrupts = <12>; 73 + display = <&display>; 74 + default-mode = <&mode0>; 75 + }; 76 + 77 + ge_rops@d8050400 { 78 + compatible = "wm,prizm-ge-rops"; 79 + reg = <0xd8050400 0x100>; 80 + }; 81 + 82 + uart@d8200000 { 83 + compatible = "via,vt8500-uart"; 84 + reg = <0xd8200000 0x1040>; 85 + interrupts = <32>; 86 + clocks = <&ref24>; 87 + }; 88 + 89 + uart@d82b0000 { 90 + compatible = "via,vt8500-uart"; 91 + reg = <0xd82b0000 0x1040>; 92 + interrupts = <33>; 93 + clocks = <&ref24>; 94 + }; 95 + 96 + uart@d8210000 { 97 + compatible = "via,vt8500-uart"; 98 + reg = <0xd8210000 0x1040>; 99 + interrupts = <47>; 100 + clocks = <&ref24>; 101 + }; 102 + 103 + uart@d82c0000 { 104 + compatible = "via,vt8500-uart"; 105 + reg = <0xd82c0000 0x1040>; 106 + interrupts = <50>; 107 + clocks = <&ref24>; 108 + }; 109 + 110 + rtc@d8100000 { 111 + compatible = "via,vt8500-rtc"; 112 + reg = <0xd8100000 0x10000>; 113 + interrupts = <48>; 114 + }; 115 + }; 116 + };
+36
arch/arm/boot/dts/wm8505-ref.dts
··· 1 + /* 2 + * wm8505-ref.dts - Device tree file for Wondermedia WM8505 reference netbook 3 + * 4 + * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz> 5 + * 6 + * Licensed under GPLv2 or later 7 + */ 8 + 9 + /dts-v1/; 10 + /include/ "wm8505.dtsi" 11 + 12 + / { 13 + model = "Wondermedia WM8505 Netbook"; 14 + 15 + /* 16 + * Display node is based on Sascha Hauer's patch on dri-devel. 17 + * Added a bpp property to calculate the size of the framebuffer 18 + * until the binding is formalized. 19 + */ 20 + display: display@0 { 21 + modes { 22 + mode0: mode@0 { 23 + hactive = <800>; 24 + vactive = <480>; 25 + hback-porch = <88>; 26 + hfront-porch = <40>; 27 + hsync-len = <0>; 28 + vback-porch = <32>; 29 + vfront-porch = <11>; 30 + vsync-len = <1>; 31 + clock = <0>; /* unused but required */ 32 + bpp = <32>; /* non-standard but required */ 33 + }; 34 + }; 35 + }; 36 + };
+143
arch/arm/boot/dts/wm8505.dtsi
··· 1 + /* 2 + * wm8505.dtsi - Device tree file for Wondermedia WM8505 SoC 3 + * 4 + * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz> 5 + * 6 + * Licensed under GPLv2 or later 7 + */ 8 + 9 + /include/ "skeleton.dtsi" 10 + 11 + / { 12 + compatible = "wm,wm8505"; 13 + 14 + cpus { 15 + cpu@0 { 16 + compatible = "arm,arm926ejs"; 17 + }; 18 + }; 19 + 20 + soc { 21 + #address-cells = <1>; 22 + #size-cells = <1>; 23 + compatible = "simple-bus"; 24 + ranges; 25 + interrupt-parent = <&intc0>; 26 + 27 + intc0: interrupt-controller@d8140000 { 28 + compatible = "via,vt8500-intc"; 29 + interrupt-controller; 30 + reg = <0xd8140000 0x10000>; 31 + #interrupt-cells = <1>; 32 + }; 33 + 34 + /* Secondary IC cascaded to intc0 */ 35 + intc1: interrupt-controller@d8150000 { 36 + compatible = "via,vt8500-intc"; 37 + interrupt-controller; 38 + #interrupt-cells = <1>; 39 + reg = <0xD8150000 0x10000>; 40 + interrupts = <56 57 58 59 60 61 62 63>; 41 + }; 42 + 43 + gpio: gpio-controller@d8110000 { 44 + compatible = "wm,wm8505-gpio"; 45 + gpio-controller; 46 + reg = <0xd8110000 0x10000>; 47 + #gpio-cells = <3>; 48 + }; 49 + 50 + pmc@d8130000 { 51 + compatible = "via,vt8500-pmc"; 52 + reg = <0xd8130000 0x1000>; 53 + clocks { 54 + #address-cells = <1>; 55 + #size-cells = <0>; 56 + 57 + ref24: ref24M { 58 + #clock-cells = <0>; 59 + compatible = "fixed-clock"; 60 + clock-frequency = <24000000>; 61 + }; 62 + }; 63 + }; 64 + 65 + timer@d8130100 { 66 + compatible = "via,vt8500-timer"; 67 + reg = <0xd8130100 0x28>; 68 + interrupts = <36>; 69 + }; 70 + 71 + ehci@d8007100 { 72 + compatible = "via,vt8500-ehci"; 73 + reg = <0xd8007100 0x200>; 74 + interrupts = <43>; 75 + }; 76 + 77 + uhci@d8007300 { 78 + compatible = "platform-uhci"; 79 + reg = <0xd8007300 0x200>; 80 + interrupts = <43>; 81 + }; 82 + 83 + fb@d8050800 { 84 + compatible = "wm,wm8505-fb"; 85 + reg = <0xd8050800 0x200>; 86 + display = <&display>; 87 + default-mode = <&mode0>; 88 + }; 89 + 90 + ge_rops@d8050400 { 91 + compatible = "wm,prizm-ge-rops"; 92 + reg = <0xd8050400 0x100>; 93 + }; 94 + 95 + uart@d8200000 { 96 + compatible = "via,vt8500-uart"; 97 + reg = <0xd8200000 0x1040>; 98 + interrupts = <32>; 99 + clocks = <&ref24>; 100 + }; 101 + 102 + uart@d82b0000 { 103 + compatible = "via,vt8500-uart"; 104 + reg = <0xd82b0000 0x1040>; 105 + interrupts = <33>; 106 + clocks = <&ref24>; 107 + }; 108 + 109 + uart@d8210000 { 110 + compatible = "via,vt8500-uart"; 111 + reg = <0xd8210000 0x1040>; 112 + interrupts = <47>; 113 + clocks = <&ref24>; 114 + }; 115 + 116 + uart@d82c0000 { 117 + compatible = "via,vt8500-uart"; 118 + reg = <0xd82c0000 0x1040>; 119 + interrupts = <50>; 120 + clocks = <&ref24>; 121 + }; 122 + 123 + uart@d8370000 { 124 + compatible = "via,vt8500-uart"; 125 + reg = <0xd8370000 0x1040>; 126 + interrupts = <31>; 127 + clocks = <&ref24>; 128 + }; 129 + 130 + uart@d8380000 { 131 + compatible = "via,vt8500-uart"; 132 + reg = <0xd8380000 0x1040>; 133 + interrupts = <30>; 134 + clocks = <&ref24>; 135 + }; 136 + 137 + rtc@d8100000 { 138 + compatible = "via,vt8500-rtc"; 139 + reg = <0xd8100000 0x10000>; 140 + interrupts = <48>; 141 + }; 142 + }; 143 + };
+36
arch/arm/boot/dts/wm8650-mid.dts
··· 1 + /* 2 + * wm8650-mid.dts - Device tree file for Wondermedia WM8650-MID Tablet 3 + * 4 + * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz> 5 + * 6 + * Licensed under GPLv2 or later 7 + */ 8 + 9 + /dts-v1/; 10 + /include/ "wm8650.dtsi" 11 + 12 + / { 13 + model = "Wondermedia WM8650-MID Tablet"; 14 + 15 + /* 16 + * Display node is based on Sascha Hauer's patch on dri-devel. 17 + * Added a bpp property to calculate the size of the framebuffer 18 + * until the binding is formalized. 19 + */ 20 + display: display@0 { 21 + modes { 22 + mode0: mode@0 { 23 + hactive = <800>; 24 + vactive = <480>; 25 + hback-porch = <88>; 26 + hfront-porch = <40>; 27 + hsync-len = <0>; 28 + vback-porch = <32>; 29 + vfront-porch = <11>; 30 + vsync-len = <1>; 31 + clock = <0>; /* unused but required */ 32 + bpp = <16>; /* non-standard but required */ 33 + }; 34 + }; 35 + }; 36 + };
+147
arch/arm/boot/dts/wm8650.dtsi
··· 1 + /* 2 + * wm8650.dtsi - Device tree file for Wondermedia WM8650 SoC 3 + * 4 + * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz> 5 + * 6 + * Licensed under GPLv2 or later 7 + */ 8 + 9 + /include/ "skeleton.dtsi" 10 + 11 + / { 12 + compatible = "wm,wm8650"; 13 + 14 + soc { 15 + #address-cells = <1>; 16 + #size-cells = <1>; 17 + compatible = "simple-bus"; 18 + ranges; 19 + interrupt-parent = <&intc0>; 20 + 21 + intc0: interrupt-controller@d8140000 { 22 + compatible = "via,vt8500-intc"; 23 + interrupt-controller; 24 + reg = <0xd8140000 0x10000>; 25 + #interrupt-cells = <1>; 26 + }; 27 + 28 + /* Secondary IC cascaded to intc0 */ 29 + intc1: interrupt-controller@d8150000 { 30 + compatible = "via,vt8500-intc"; 31 + interrupt-controller; 32 + #interrupt-cells = <1>; 33 + reg = <0xD8150000 0x10000>; 34 + interrupts = <56 57 58 59 60 61 62 63>; 35 + }; 36 + 37 + gpio: gpio-controller@d8110000 { 38 + compatible = "wm,wm8650-gpio"; 39 + gpio-controller; 40 + reg = <0xd8110000 0x10000>; 41 + #gpio-cells = <3>; 42 + }; 43 + 44 + pmc@d8130000 { 45 + compatible = "via,vt8500-pmc"; 46 + reg = <0xd8130000 0x1000>; 47 + 48 + clocks { 49 + #address-cells = <1>; 50 + #size-cells = <0>; 51 + 52 + ref25: ref25M { 53 + #clock-cells = <0>; 54 + compatible = "fixed-clock"; 55 + clock-frequency = <25000000>; 56 + }; 57 + 58 + ref24: ref24M { 59 + #clock-cells = <0>; 60 + compatible = "fixed-clock"; 61 + clock-frequency = <24000000>; 62 + }; 63 + 64 + plla: plla { 65 + #clock-cells = <0>; 66 + compatible = "wm,wm8650-pll-clock"; 67 + clocks = <&ref25>; 68 + reg = <0x200>; 69 + }; 70 + 71 + pllb: pllb { 72 + #clock-cells = <0>; 73 + compatible = "wm,wm8650-pll-clock"; 74 + clocks = <&ref25>; 75 + reg = <0x204>; 76 + }; 77 + 78 + arm: arm { 79 + #clock-cells = <0>; 80 + compatible = "via,vt8500-device-clock"; 81 + clocks = <&plla>; 82 + divisor-reg = <0x300>; 83 + }; 84 + 85 + sdhc: sdhc { 86 + #clock-cells = <0>; 87 + compatible = "via,vt8500-device-clock"; 88 + clocks = <&pllb>; 89 + divisor-reg = <0x328>; 90 + divisor-mask = <0x3f>; 91 + enable-reg = <0x254>; 92 + enable-bit = <18>; 93 + }; 94 + }; 95 + }; 96 + 97 + timer@d8130100 { 98 + compatible = "via,vt8500-timer"; 99 + reg = <0xd8130100 0x28>; 100 + interrupts = <36>; 101 + }; 102 + 103 + ehci@d8007900 { 104 + compatible = "via,vt8500-ehci"; 105 + reg = <0xd8007900 0x200>; 106 + interrupts = <43>; 107 + }; 108 + 109 + uhci@d8007b00 { 110 + compatible = "platform-uhci"; 111 + reg = <0xd8007b00 0x200>; 112 + interrupts = <43>; 113 + }; 114 + 115 + fb@d8050800 { 116 + compatible = "wm,wm8505-fb"; 117 + reg = <0xd8050800 0x200>; 118 + display = <&display>; 119 + default-mode = <&mode0>; 120 + }; 121 + 122 + ge_rops@d8050400 { 123 + compatible = "wm,prizm-ge-rops"; 124 + reg = <0xd8050400 0x100>; 125 + }; 126 + 127 + uart@d8200000 { 128 + compatible = "via,vt8500-uart"; 129 + reg = <0xd8200000 0x1040>; 130 + interrupts = <32>; 131 + clocks = <&ref24>; 132 + }; 133 + 134 + uart@d82b0000 { 135 + compatible = "via,vt8500-uart"; 136 + reg = <0xd82b0000 0x1040>; 137 + interrupts = <33>; 138 + clocks = <&ref24>; 139 + }; 140 + 141 + rtc@d8100000 { 142 + compatible = "via,vt8500-rtc"; 143 + reg = <0xd8100000 0x10000>; 144 + interrupts = <48>; 145 + }; 146 + }; 147 + };
-73
arch/arm/mach-vt8500/Kconfig
··· 1 - if ARCH_VT8500 2 - 3 - config VTWM_VERSION_VT8500 4 - bool 5 - 6 - config VTWM_VERSION_WM8505 7 - bool 8 - 9 - config MACH_BV07 10 - bool "Benign BV07-8500 Mini Netbook" 11 - depends on ARCH_VT8500 12 - select VTWM_VERSION_VT8500 13 - help 14 - Add support for the inexpensive 7-inch netbooks sold by many 15 - Chinese distributors under various names. Note that there are 16 - many hardware implementations in identical exterior, make sure 17 - that yours is indeed based on a VIA VT8500 chip. 18 - 19 - config MACH_WM8505_7IN_NETBOOK 20 - bool "WM8505 7-inch generic netbook" 21 - depends on ARCH_VT8500 22 - select VTWM_VERSION_WM8505 23 - help 24 - Add support for the inexpensive 7-inch netbooks sold by many 25 - Chinese distributors under various names. Note that there are 26 - many hardware implementations in identical exterior, make sure 27 - that yours is indeed based on a WonderMedia WM8505 chip. 28 - 29 - comment "LCD panel size" 30 - 31 - config WMT_PANEL_800X480 32 - bool "7-inch with 800x480 resolution" 33 - depends on (FB_VT8500 || FB_WM8505) 34 - default y 35 - help 36 - These are found in most of the netbooks in generic cases, as 37 - well as in Eken M001 tablets and possibly elsewhere. 38 - 39 - To select this panel at runtime, say y here and append 40 - 'panel=800x480' to your kernel command line. Otherwise, the 41 - largest one available will be used. 42 - 43 - config WMT_PANEL_800X600 44 - bool "8-inch with 800x600 resolution" 45 - depends on (FB_VT8500 || FB_WM8505) 46 - help 47 - These are found in Eken M003 tablets and possibly elsewhere. 48 - 49 - To select this panel at runtime, say y here and append 50 - 'panel=800x600' to your kernel command line. Otherwise, the 51 - largest one available will be used. 52 - 53 - config WMT_PANEL_1024X576 54 - bool "10-inch with 1024x576 resolution" 55 - depends on (FB_VT8500 || FB_WM8505) 56 - help 57 - These are found in CherryPal netbooks and possibly elsewhere. 58 - 59 - To select this panel at runtime, say y here and append 60 - 'panel=1024x576' to your kernel command line. Otherwise, the 61 - largest one available will be used. 62 - 63 - config WMT_PANEL_1024X600 64 - bool "10-inch with 1024x600 resolution" 65 - depends on (FB_VT8500 || FB_WM8505) 66 - help 67 - These are found in Eken M006 tablets and possibly elsewhere. 68 - 69 - To select this panel at runtime, say y here and append 70 - 'panel=1024x600' to your kernel command line. Otherwise, the 71 - largest one available will be used. 72 - 73 - endif
+1 -7
arch/arm/mach-vt8500/Makefile
··· 1 - obj-y += devices.o gpio.o irq.o timer.o restart.o 2 - 3 - obj-$(CONFIG_VTWM_VERSION_VT8500) += devices-vt8500.o 4 - obj-$(CONFIG_VTWM_VERSION_WM8505) += devices-wm8505.o 5 - 6 - obj-$(CONFIG_MACH_BV07) += bv07.o 7 - obj-$(CONFIG_MACH_WM8505_7IN_NETBOOK) += wm8505_7in.o 1 + obj-$(CONFIG_ARCH_VT8500) += irq.o timer.o vt8500.o
-80
arch/arm/mach-vt8500/bv07.c
··· 1 - /* 2 - * arch/arm/mach-vt8500/bv07.c 3 - * 4 - * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> 5 - * 6 - * This program is free software; you can redistribute it and/or modify 7 - * it under the terms of the GNU General Public License as published by 8 - * the Free Software Foundation; either version 2 of the License, or 9 - * (at your option) any later version. 10 - * 11 - * This program is distributed in the hope that it will be useful, 12 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 - * GNU General Public License for more details. 15 - * 16 - * You should have received a copy of the GNU General Public License 17 - * along with this program; if not, write to the Free Software 18 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 - */ 20 - 21 - #include <linux/io.h> 22 - #include <linux/pm.h> 23 - 24 - #include <asm/mach-types.h> 25 - #include <asm/mach/arch.h> 26 - #include <mach/restart.h> 27 - 28 - #include "devices.h" 29 - 30 - static void __iomem *pmc_hiber; 31 - 32 - static struct platform_device *devices[] __initdata = { 33 - &vt8500_device_uart0, 34 - &vt8500_device_lcdc, 35 - &vt8500_device_ehci, 36 - &vt8500_device_ge_rops, 37 - &vt8500_device_pwm, 38 - &vt8500_device_pwmbl, 39 - &vt8500_device_rtc, 40 - }; 41 - 42 - static void vt8500_power_off(void) 43 - { 44 - local_irq_disable(); 45 - writew(5, pmc_hiber); 46 - asm("mcr%? p15, 0, %0, c7, c0, 4" : : "r" (0)); 47 - } 48 - 49 - void __init bv07_init(void) 50 - { 51 - #ifdef CONFIG_FB_VT8500 52 - void __iomem *gpio_mux_reg = ioremap(wmt_gpio_base + 0x200, 4); 53 - if (gpio_mux_reg) { 54 - writel(readl(gpio_mux_reg) | 1, gpio_mux_reg); 55 - iounmap(gpio_mux_reg); 56 - } else { 57 - printk(KERN_ERR "Could not remap the GPIO mux register, display may not work properly!\n"); 58 - } 59 - #endif 60 - pmc_hiber = ioremap(wmt_pmc_base + 0x12, 2); 61 - if (pmc_hiber) 62 - pm_power_off = &vt8500_power_off; 63 - else 64 - printk(KERN_ERR "PMC Hibernation register could not be remapped, not enabling power off!\n"); 65 - 66 - wmt_setup_restart(); 67 - vt8500_set_resources(); 68 - platform_add_devices(devices, ARRAY_SIZE(devices)); 69 - vt8500_gpio_init(); 70 - } 71 - 72 - MACHINE_START(BV07, "Benign BV07 Mini Netbook") 73 - .atag_offset = 0x100, 74 - .restart = wmt_restart, 75 - .reserve = vt8500_reserve_mem, 76 - .map_io = vt8500_map_io, 77 - .init_irq = vt8500_init_irq, 78 - .timer = &vt8500_timer, 79 - .init_machine = bv07_init, 80 - MACHINE_END
+28
arch/arm/mach-vt8500/common.h
··· 1 + /* linux/arch/arm/mach-vt8500/dt_common.h 2 + * 3 + * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz> 4 + * 5 + * This software is licensed under the terms of the GNU General Public 6 + * License version 2, as published by the Free Software Foundation, and 7 + * may be copied, distributed, and modified under those terms. 8 + * 9 + * This program is distributed in the hope that it will be useful, 10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 + * GNU General Public License for more details. 13 + * 14 + */ 15 + 16 + #ifndef __ARCH_ARM_MACH_VT8500_DT_COMMON_H 17 + #define __ARCH_ARM_MACH_VT8500_DT_COMMON_H 18 + 19 + #include <linux/of.h> 20 + 21 + void __init vt8500_timer_init(void); 22 + int __init vt8500_irq_init(struct device_node *node, 23 + struct device_node *parent); 24 + 25 + /* defined in drivers/clk/clk-vt8500.c */ 26 + void __init vtwm_clk_init(void __iomem *pmc_base); 27 + 28 + #endif
-91
arch/arm/mach-vt8500/devices-vt8500.c
··· 1 - /* linux/arch/arm/mach-vt8500/devices-vt8500.c 2 - * 3 - * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> 4 - * 5 - * This software is licensed under the terms of the GNU General Public 6 - * License version 2, as published by the Free Software Foundation, and 7 - * may be copied, distributed, and modified under those terms. 8 - * 9 - * This program is distributed in the hope that it will be useful, 10 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 - * GNU General Public License for more details. 13 - * 14 - */ 15 - 16 - #include <linux/platform_device.h> 17 - 18 - #include <mach/vt8500_regs.h> 19 - #include <mach/vt8500_irqs.h> 20 - #include <mach/i8042.h> 21 - #include "devices.h" 22 - 23 - void __init vt8500_set_resources(void) 24 - { 25 - struct resource tmp[3]; 26 - 27 - tmp[0] = wmt_mmio_res(VT8500_LCDC_BASE, SZ_1K); 28 - tmp[1] = wmt_irq_res(IRQ_LCDC); 29 - wmt_res_add(&vt8500_device_lcdc, tmp, 2); 30 - 31 - tmp[0] = wmt_mmio_res(VT8500_UART0_BASE, 0x1040); 32 - tmp[1] = wmt_irq_res(IRQ_UART0); 33 - wmt_res_add(&vt8500_device_uart0, tmp, 2); 34 - 35 - tmp[0] = wmt_mmio_res(VT8500_UART1_BASE, 0x1040); 36 - tmp[1] = wmt_irq_res(IRQ_UART1); 37 - wmt_res_add(&vt8500_device_uart1, tmp, 2); 38 - 39 - tmp[0] = wmt_mmio_res(VT8500_UART2_BASE, 0x1040); 40 - tmp[1] = wmt_irq_res(IRQ_UART2); 41 - wmt_res_add(&vt8500_device_uart2, tmp, 2); 42 - 43 - tmp[0] = wmt_mmio_res(VT8500_UART3_BASE, 0x1040); 44 - tmp[1] = wmt_irq_res(IRQ_UART3); 45 - wmt_res_add(&vt8500_device_uart3, tmp, 2); 46 - 47 - tmp[0] = wmt_mmio_res(VT8500_EHCI_BASE, SZ_512); 48 - tmp[1] = wmt_irq_res(IRQ_EHCI); 49 - wmt_res_add(&vt8500_device_ehci, tmp, 2); 50 - 51 - tmp[0] = wmt_mmio_res(VT8500_GEGEA_BASE, SZ_256); 52 - wmt_res_add(&vt8500_device_ge_rops, tmp, 1); 53 - 54 - tmp[0] = wmt_mmio_res(VT8500_PWM_BASE, 0x44); 55 - wmt_res_add(&vt8500_device_pwm, tmp, 1); 56 - 57 - tmp[0] = wmt_mmio_res(VT8500_RTC_BASE, 0x2c); 58 - tmp[1] = wmt_irq_res(IRQ_RTC); 59 - tmp[2] = wmt_irq_res(IRQ_RTCSM); 60 - wmt_res_add(&vt8500_device_rtc, tmp, 3); 61 - } 62 - 63 - static void __init vt8500_set_externs(void) 64 - { 65 - /* Non-resource-aware stuff */ 66 - wmt_ic_base = VT8500_IC_BASE; 67 - wmt_gpio_base = VT8500_GPIO_BASE; 68 - wmt_pmc_base = VT8500_PMC_BASE; 69 - wmt_i8042_base = VT8500_PS2_BASE; 70 - 71 - wmt_nr_irqs = VT8500_NR_IRQS; 72 - wmt_timer_irq = IRQ_PMCOS0; 73 - wmt_gpio_ext_irq[0] = IRQ_EXT0; 74 - wmt_gpio_ext_irq[1] = IRQ_EXT1; 75 - wmt_gpio_ext_irq[2] = IRQ_EXT2; 76 - wmt_gpio_ext_irq[3] = IRQ_EXT3; 77 - wmt_gpio_ext_irq[4] = IRQ_EXT4; 78 - wmt_gpio_ext_irq[5] = IRQ_EXT5; 79 - wmt_gpio_ext_irq[6] = IRQ_EXT6; 80 - wmt_gpio_ext_irq[7] = IRQ_EXT7; 81 - wmt_i8042_kbd_irq = IRQ_PS2KBD; 82 - wmt_i8042_aux_irq = IRQ_PS2MOUSE; 83 - } 84 - 85 - void __init vt8500_map_io(void) 86 - { 87 - iotable_init(wmt_io_desc, ARRAY_SIZE(wmt_io_desc)); 88 - 89 - /* Should be done before interrupts and timers are initialized */ 90 - vt8500_set_externs(); 91 - }
-99
arch/arm/mach-vt8500/devices-wm8505.c
··· 1 - /* linux/arch/arm/mach-vt8500/devices-wm8505.c 2 - * 3 - * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> 4 - * 5 - * This software is licensed under the terms of the GNU General Public 6 - * License version 2, as published by the Free Software Foundation, and 7 - * may be copied, distributed, and modified under those terms. 8 - * 9 - * This program is distributed in the hope that it will be useful, 10 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 - * GNU General Public License for more details. 13 - * 14 - */ 15 - 16 - #include <linux/platform_device.h> 17 - 18 - #include <mach/wm8505_regs.h> 19 - #include <mach/wm8505_irqs.h> 20 - #include <mach/i8042.h> 21 - #include "devices.h" 22 - 23 - void __init wm8505_set_resources(void) 24 - { 25 - struct resource tmp[3]; 26 - 27 - tmp[0] = wmt_mmio_res(WM8505_GOVR_BASE, SZ_512); 28 - wmt_res_add(&vt8500_device_wm8505_fb, tmp, 1); 29 - 30 - tmp[0] = wmt_mmio_res(WM8505_UART0_BASE, 0x1040); 31 - tmp[1] = wmt_irq_res(IRQ_UART0); 32 - wmt_res_add(&vt8500_device_uart0, tmp, 2); 33 - 34 - tmp[0] = wmt_mmio_res(WM8505_UART1_BASE, 0x1040); 35 - tmp[1] = wmt_irq_res(IRQ_UART1); 36 - wmt_res_add(&vt8500_device_uart1, tmp, 2); 37 - 38 - tmp[0] = wmt_mmio_res(WM8505_UART2_BASE, 0x1040); 39 - tmp[1] = wmt_irq_res(IRQ_UART2); 40 - wmt_res_add(&vt8500_device_uart2, tmp, 2); 41 - 42 - tmp[0] = wmt_mmio_res(WM8505_UART3_BASE, 0x1040); 43 - tmp[1] = wmt_irq_res(IRQ_UART3); 44 - wmt_res_add(&vt8500_device_uart3, tmp, 2); 45 - 46 - tmp[0] = wmt_mmio_res(WM8505_UART4_BASE, 0x1040); 47 - tmp[1] = wmt_irq_res(IRQ_UART4); 48 - wmt_res_add(&vt8500_device_uart4, tmp, 2); 49 - 50 - tmp[0] = wmt_mmio_res(WM8505_UART5_BASE, 0x1040); 51 - tmp[1] = wmt_irq_res(IRQ_UART5); 52 - wmt_res_add(&vt8500_device_uart5, tmp, 2); 53 - 54 - tmp[0] = wmt_mmio_res(WM8505_EHCI_BASE, SZ_512); 55 - tmp[1] = wmt_irq_res(IRQ_EHCI); 56 - wmt_res_add(&vt8500_device_ehci, tmp, 2); 57 - 58 - tmp[0] = wmt_mmio_res(WM8505_GEGEA_BASE, SZ_256); 59 - wmt_res_add(&vt8500_device_ge_rops, tmp, 1); 60 - 61 - tmp[0] = wmt_mmio_res(WM8505_PWM_BASE, 0x44); 62 - wmt_res_add(&vt8500_device_pwm, tmp, 1); 63 - 64 - tmp[0] = wmt_mmio_res(WM8505_RTC_BASE, 0x2c); 65 - tmp[1] = wmt_irq_res(IRQ_RTC); 66 - tmp[2] = wmt_irq_res(IRQ_RTCSM); 67 - wmt_res_add(&vt8500_device_rtc, tmp, 3); 68 - } 69 - 70 - static void __init wm8505_set_externs(void) 71 - { 72 - /* Non-resource-aware stuff */ 73 - wmt_ic_base = WM8505_IC_BASE; 74 - wmt_sic_base = WM8505_SIC_BASE; 75 - wmt_gpio_base = WM8505_GPIO_BASE; 76 - wmt_pmc_base = WM8505_PMC_BASE; 77 - wmt_i8042_base = WM8505_PS2_BASE; 78 - 79 - wmt_nr_irqs = WM8505_NR_IRQS; 80 - wmt_timer_irq = IRQ_PMCOS0; 81 - wmt_gpio_ext_irq[0] = IRQ_EXT0; 82 - wmt_gpio_ext_irq[1] = IRQ_EXT1; 83 - wmt_gpio_ext_irq[2] = IRQ_EXT2; 84 - wmt_gpio_ext_irq[3] = IRQ_EXT3; 85 - wmt_gpio_ext_irq[4] = IRQ_EXT4; 86 - wmt_gpio_ext_irq[5] = IRQ_EXT5; 87 - wmt_gpio_ext_irq[6] = IRQ_EXT6; 88 - wmt_gpio_ext_irq[7] = IRQ_EXT7; 89 - wmt_i8042_kbd_irq = IRQ_PS2KBD; 90 - wmt_i8042_aux_irq = IRQ_PS2MOUSE; 91 - } 92 - 93 - void __init wm8505_map_io(void) 94 - { 95 - iotable_init(wmt_io_desc, ARRAY_SIZE(wmt_io_desc)); 96 - 97 - /* Should be done before interrupts and timers are initialized */ 98 - wm8505_set_externs(); 99 - }
-270
arch/arm/mach-vt8500/devices.c
··· 1 - /* linux/arch/arm/mach-vt8500/devices.c 2 - * 3 - * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> 4 - * 5 - * This software is licensed under the terms of the GNU General Public 6 - * License version 2, as published by the Free Software Foundation, and 7 - * may be copied, distributed, and modified under those terms. 8 - * 9 - * This program is distributed in the hope that it will be useful, 10 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 - * GNU General Public License for more details. 13 - * 14 - */ 15 - 16 - #include <linux/kernel.h> 17 - #include <linux/io.h> 18 - #include <linux/device.h> 19 - #include <linux/dma-mapping.h> 20 - #include <linux/platform_device.h> 21 - #include <linux/pwm_backlight.h> 22 - #include <linux/memblock.h> 23 - 24 - #include <asm/mach/arch.h> 25 - 26 - #include <mach/vt8500fb.h> 27 - #include <mach/i8042.h> 28 - #include "devices.h" 29 - 30 - /* These can't use resources currently */ 31 - unsigned long wmt_ic_base __initdata; 32 - unsigned long wmt_sic_base __initdata; 33 - unsigned long wmt_gpio_base __initdata; 34 - unsigned long wmt_pmc_base __initdata; 35 - unsigned long wmt_i8042_base __initdata; 36 - 37 - int wmt_nr_irqs __initdata; 38 - int wmt_timer_irq __initdata; 39 - int wmt_gpio_ext_irq[8] __initdata; 40 - 41 - /* Should remain accessible after init. 42 - * i8042 driver desperately calls for attention... 43 - */ 44 - int wmt_i8042_kbd_irq; 45 - int wmt_i8042_aux_irq; 46 - 47 - static u64 fb_dma_mask = DMA_BIT_MASK(32); 48 - 49 - struct platform_device vt8500_device_lcdc = { 50 - .name = "vt8500-lcd", 51 - .id = 0, 52 - .dev = { 53 - .dma_mask = &fb_dma_mask, 54 - .coherent_dma_mask = DMA_BIT_MASK(32), 55 - }, 56 - }; 57 - 58 - struct platform_device vt8500_device_wm8505_fb = { 59 - .name = "wm8505-fb", 60 - .id = 0, 61 - }; 62 - 63 - /* Smallest to largest */ 64 - static struct vt8500fb_platform_data panels[] = { 65 - #ifdef CONFIG_WMT_PANEL_800X480 66 - { 67 - .xres_virtual = 800, 68 - .yres_virtual = 480 * 2, 69 - .mode = { 70 - .name = "800x480", 71 - .xres = 800, 72 - .yres = 480, 73 - .left_margin = 88, 74 - .right_margin = 40, 75 - .upper_margin = 32, 76 - .lower_margin = 11, 77 - .hsync_len = 0, 78 - .vsync_len = 1, 79 - .vmode = FB_VMODE_NONINTERLACED, 80 - }, 81 - }, 82 - #endif 83 - #ifdef CONFIG_WMT_PANEL_800X600 84 - { 85 - .xres_virtual = 800, 86 - .yres_virtual = 600 * 2, 87 - .mode = { 88 - .name = "800x600", 89 - .xres = 800, 90 - .yres = 600, 91 - .left_margin = 88, 92 - .right_margin = 40, 93 - .upper_margin = 32, 94 - .lower_margin = 11, 95 - .hsync_len = 0, 96 - .vsync_len = 1, 97 - .vmode = FB_VMODE_NONINTERLACED, 98 - }, 99 - }, 100 - #endif 101 - #ifdef CONFIG_WMT_PANEL_1024X576 102 - { 103 - .xres_virtual = 1024, 104 - .yres_virtual = 576 * 2, 105 - .mode = { 106 - .name = "1024x576", 107 - .xres = 1024, 108 - .yres = 576, 109 - .left_margin = 40, 110 - .right_margin = 24, 111 - .upper_margin = 32, 112 - .lower_margin = 11, 113 - .hsync_len = 96, 114 - .vsync_len = 2, 115 - .vmode = FB_VMODE_NONINTERLACED, 116 - }, 117 - }, 118 - #endif 119 - #ifdef CONFIG_WMT_PANEL_1024X600 120 - { 121 - .xres_virtual = 1024, 122 - .yres_virtual = 600 * 2, 123 - .mode = { 124 - .name = "1024x600", 125 - .xres = 1024, 126 - .yres = 600, 127 - .left_margin = 66, 128 - .right_margin = 2, 129 - .upper_margin = 19, 130 - .lower_margin = 1, 131 - .hsync_len = 23, 132 - .vsync_len = 8, 133 - .vmode = FB_VMODE_NONINTERLACED, 134 - }, 135 - }, 136 - #endif 137 - }; 138 - 139 - static int current_panel_idx __initdata = ARRAY_SIZE(panels) - 1; 140 - 141 - static int __init panel_setup(char *str) 142 - { 143 - int i; 144 - 145 - for (i = 0; i < ARRAY_SIZE(panels); i++) { 146 - if (strcmp(panels[i].mode.name, str) == 0) { 147 - current_panel_idx = i; 148 - break; 149 - } 150 - } 151 - return 0; 152 - } 153 - 154 - early_param("panel", panel_setup); 155 - 156 - static inline void preallocate_fb(struct vt8500fb_platform_data *p, 157 - unsigned long align) { 158 - p->video_mem_len = (p->xres_virtual * p->yres_virtual * 4) >> 159 - (p->bpp > 16 ? 0 : (p->bpp > 8 ? 1 : 160 - (8 / p->bpp) + 1)); 161 - p->video_mem_phys = (unsigned long)memblock_alloc(p->video_mem_len, 162 - align); 163 - p->video_mem_virt = phys_to_virt(p->video_mem_phys); 164 - } 165 - 166 - struct platform_device vt8500_device_uart0 = { 167 - .name = "vt8500_serial", 168 - .id = 0, 169 - }; 170 - 171 - struct platform_device vt8500_device_uart1 = { 172 - .name = "vt8500_serial", 173 - .id = 1, 174 - }; 175 - 176 - struct platform_device vt8500_device_uart2 = { 177 - .name = "vt8500_serial", 178 - .id = 2, 179 - }; 180 - 181 - struct platform_device vt8500_device_uart3 = { 182 - .name = "vt8500_serial", 183 - .id = 3, 184 - }; 185 - 186 - struct platform_device vt8500_device_uart4 = { 187 - .name = "vt8500_serial", 188 - .id = 4, 189 - }; 190 - 191 - struct platform_device vt8500_device_uart5 = { 192 - .name = "vt8500_serial", 193 - .id = 5, 194 - }; 195 - 196 - static u64 ehci_dma_mask = DMA_BIT_MASK(32); 197 - 198 - struct platform_device vt8500_device_ehci = { 199 - .name = "vt8500-ehci", 200 - .id = 0, 201 - .dev = { 202 - .dma_mask = &ehci_dma_mask, 203 - .coherent_dma_mask = DMA_BIT_MASK(32), 204 - }, 205 - }; 206 - 207 - struct platform_device vt8500_device_ge_rops = { 208 - .name = "wmt_ge_rops", 209 - .id = -1, 210 - }; 211 - 212 - struct platform_device vt8500_device_pwm = { 213 - .name = "vt8500-pwm", 214 - .id = 0, 215 - }; 216 - 217 - static struct platform_pwm_backlight_data vt8500_pwmbl_data = { 218 - .pwm_id = 0, 219 - .max_brightness = 128, 220 - .dft_brightness = 70, 221 - .pwm_period_ns = 250000, /* revisit when clocks are implemented */ 222 - }; 223 - 224 - struct platform_device vt8500_device_pwmbl = { 225 - .name = "pwm-backlight", 226 - .id = 0, 227 - .dev = { 228 - .platform_data = &vt8500_pwmbl_data, 229 - }, 230 - }; 231 - 232 - struct platform_device vt8500_device_rtc = { 233 - .name = "vt8500-rtc", 234 - .id = 0, 235 - }; 236 - 237 - struct map_desc wmt_io_desc[] __initdata = { 238 - /* SoC MMIO registers */ 239 - [0] = { 240 - .virtual = 0xf8000000, 241 - .pfn = __phys_to_pfn(0xd8000000), 242 - .length = 0x00390000, /* max of all chip variants */ 243 - .type = MT_DEVICE 244 - }, 245 - /* PCI I/O space, numbers tied to those in <mach/io.h> */ 246 - [1] = { 247 - .virtual = 0xf0000000, 248 - .pfn = __phys_to_pfn(0xc0000000), 249 - .length = SZ_64K, 250 - .type = MT_DEVICE 251 - }, 252 - }; 253 - 254 - void __init vt8500_reserve_mem(void) 255 - { 256 - #ifdef CONFIG_FB_VT8500 257 - panels[current_panel_idx].bpp = 16; /* Always use RGB565 */ 258 - preallocate_fb(&panels[current_panel_idx], SZ_4M); 259 - vt8500_device_lcdc.dev.platform_data = &panels[current_panel_idx]; 260 - #endif 261 - } 262 - 263 - void __init wm8505_reserve_mem(void) 264 - { 265 - #if defined CONFIG_FB_WM8505 266 - panels[current_panel_idx].bpp = 32; /* Always use RGB888 */ 267 - preallocate_fb(&panels[current_panel_idx], 32); 268 - vt8500_device_wm8505_fb.dev.platform_data = &panels[current_panel_idx]; 269 - #endif 270 - }
-88
arch/arm/mach-vt8500/devices.h
··· 1 - /* linux/arch/arm/mach-vt8500/devices.h 2 - * 3 - * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> 4 - * 5 - * This software is licensed under the terms of the GNU General Public 6 - * License version 2, as published by the Free Software Foundation, and 7 - * may be copied, distributed, and modified under those terms. 8 - * 9 - * This program is distributed in the hope that it will be useful, 10 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 - * GNU General Public License for more details. 13 - * 14 - */ 15 - 16 - #ifndef __ARCH_ARM_MACH_VT8500_DEVICES_H 17 - #define __ARCH_ARM_MACH_VT8500_DEVICES_H 18 - 19 - #include <linux/platform_device.h> 20 - #include <asm/mach/map.h> 21 - 22 - void __init vt8500_init_irq(void); 23 - void __init wm8505_init_irq(void); 24 - void __init vt8500_map_io(void); 25 - void __init wm8505_map_io(void); 26 - void __init vt8500_reserve_mem(void); 27 - void __init wm8505_reserve_mem(void); 28 - void __init vt8500_gpio_init(void); 29 - void __init vt8500_set_resources(void); 30 - void __init wm8505_set_resources(void); 31 - 32 - extern unsigned long wmt_ic_base __initdata; 33 - extern unsigned long wmt_sic_base __initdata; 34 - extern unsigned long wmt_gpio_base __initdata; 35 - extern unsigned long wmt_pmc_base __initdata; 36 - 37 - extern int wmt_nr_irqs __initdata; 38 - extern int wmt_timer_irq __initdata; 39 - extern int wmt_gpio_ext_irq[8] __initdata; 40 - 41 - extern struct map_desc wmt_io_desc[2] __initdata; 42 - 43 - static inline struct resource wmt_mmio_res(u32 start, u32 size) 44 - { 45 - struct resource tmp = { 46 - .flags = IORESOURCE_MEM, 47 - .start = start, 48 - .end = start + size - 1, 49 - }; 50 - 51 - return tmp; 52 - } 53 - 54 - static inline struct resource wmt_irq_res(int irq) 55 - { 56 - struct resource tmp = { 57 - .flags = IORESOURCE_IRQ, 58 - .start = irq, 59 - .end = irq, 60 - }; 61 - 62 - return tmp; 63 - } 64 - 65 - static inline void wmt_res_add(struct platform_device *pdev, 66 - const struct resource *res, unsigned int num) 67 - { 68 - if (unlikely(platform_device_add_resources(pdev, res, num))) 69 - pr_err("Failed to assign resources\n"); 70 - } 71 - 72 - extern struct sys_timer vt8500_timer; 73 - 74 - extern struct platform_device vt8500_device_uart0; 75 - extern struct platform_device vt8500_device_uart1; 76 - extern struct platform_device vt8500_device_uart2; 77 - extern struct platform_device vt8500_device_uart3; 78 - extern struct platform_device vt8500_device_uart4; 79 - extern struct platform_device vt8500_device_uart5; 80 - 81 - extern struct platform_device vt8500_device_lcdc; 82 - extern struct platform_device vt8500_device_wm8505_fb; 83 - extern struct platform_device vt8500_device_ehci; 84 - extern struct platform_device vt8500_device_ge_rops; 85 - extern struct platform_device vt8500_device_pwm; 86 - extern struct platform_device vt8500_device_pwmbl; 87 - extern struct platform_device vt8500_device_rtc; 88 - #endif
-240
arch/arm/mach-vt8500/gpio.c
··· 1 - /* linux/arch/arm/mach-vt8500/gpio.c 2 - * 3 - * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> 4 - * 5 - * This software is licensed under the terms of the GNU General Public 6 - * License version 2, as published by the Free Software Foundation, and 7 - * may be copied, distributed, and modified under those terms. 8 - * 9 - * This program is distributed in the hope that it will be useful, 10 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 - * GNU General Public License for more details. 13 - * 14 - */ 15 - 16 - #include <linux/gpio.h> 17 - #include <linux/init.h> 18 - #include <linux/irq.h> 19 - #include <linux/io.h> 20 - 21 - #include "devices.h" 22 - 23 - #define to_vt8500(__chip) container_of(__chip, struct vt8500_gpio_chip, chip) 24 - 25 - #define ENABLE_REGS 0x0 26 - #define DIRECTION_REGS 0x20 27 - #define OUTVALUE_REGS 0x40 28 - #define INVALUE_REGS 0x60 29 - 30 - #define EXT_REGOFF 0x1c 31 - 32 - static void __iomem *regbase; 33 - 34 - struct vt8500_gpio_chip { 35 - struct gpio_chip chip; 36 - unsigned int shift; 37 - unsigned int regoff; 38 - }; 39 - 40 - static int gpio_to_irq_map[8]; 41 - 42 - static int vt8500_muxed_gpio_request(struct gpio_chip *chip, 43 - unsigned offset) 44 - { 45 - struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip); 46 - unsigned val = readl(regbase + ENABLE_REGS + vt8500_chip->regoff); 47 - 48 - val |= (1 << vt8500_chip->shift << offset); 49 - writel(val, regbase + ENABLE_REGS + vt8500_chip->regoff); 50 - 51 - return 0; 52 - } 53 - 54 - static void vt8500_muxed_gpio_free(struct gpio_chip *chip, 55 - unsigned offset) 56 - { 57 - struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip); 58 - unsigned val = readl(regbase + ENABLE_REGS + vt8500_chip->regoff); 59 - 60 - val &= ~(1 << vt8500_chip->shift << offset); 61 - writel(val, regbase + ENABLE_REGS + vt8500_chip->regoff); 62 - } 63 - 64 - static int vt8500_muxed_gpio_direction_input(struct gpio_chip *chip, 65 - unsigned offset) 66 - { 67 - struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip); 68 - unsigned val = readl(regbase + DIRECTION_REGS + vt8500_chip->regoff); 69 - 70 - val &= ~(1 << vt8500_chip->shift << offset); 71 - writel(val, regbase + DIRECTION_REGS + vt8500_chip->regoff); 72 - 73 - return 0; 74 - } 75 - 76 - static int vt8500_muxed_gpio_direction_output(struct gpio_chip *chip, 77 - unsigned offset, int value) 78 - { 79 - struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip); 80 - unsigned val = readl(regbase + DIRECTION_REGS + vt8500_chip->regoff); 81 - 82 - val |= (1 << vt8500_chip->shift << offset); 83 - writel(val, regbase + DIRECTION_REGS + vt8500_chip->regoff); 84 - 85 - if (value) { 86 - val = readl(regbase + OUTVALUE_REGS + vt8500_chip->regoff); 87 - val |= (1 << vt8500_chip->shift << offset); 88 - writel(val, regbase + OUTVALUE_REGS + vt8500_chip->regoff); 89 - } 90 - return 0; 91 - } 92 - 93 - static int vt8500_muxed_gpio_get_value(struct gpio_chip *chip, 94 - unsigned offset) 95 - { 96 - struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip); 97 - 98 - return (readl(regbase + INVALUE_REGS + vt8500_chip->regoff) 99 - >> vt8500_chip->shift >> offset) & 1; 100 - } 101 - 102 - static void vt8500_muxed_gpio_set_value(struct gpio_chip *chip, 103 - unsigned offset, int value) 104 - { 105 - struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip); 106 - unsigned val = readl(regbase + INVALUE_REGS + vt8500_chip->regoff); 107 - 108 - if (value) 109 - val |= (1 << vt8500_chip->shift << offset); 110 - else 111 - val &= ~(1 << vt8500_chip->shift << offset); 112 - 113 - writel(val, regbase + INVALUE_REGS + vt8500_chip->regoff); 114 - } 115 - 116 - #define VT8500_GPIO_BANK(__name, __shift, __off, __base, __num) \ 117 - { \ 118 - .chip = { \ 119 - .label = __name, \ 120 - .request = vt8500_muxed_gpio_request, \ 121 - .free = vt8500_muxed_gpio_free, \ 122 - .direction_input = vt8500_muxed_gpio_direction_input, \ 123 - .direction_output = vt8500_muxed_gpio_direction_output, \ 124 - .get = vt8500_muxed_gpio_get_value, \ 125 - .set = vt8500_muxed_gpio_set_value, \ 126 - .can_sleep = 0, \ 127 - .base = __base, \ 128 - .ngpio = __num, \ 129 - }, \ 130 - .shift = __shift, \ 131 - .regoff = __off, \ 132 - } 133 - 134 - static struct vt8500_gpio_chip vt8500_muxed_gpios[] = { 135 - VT8500_GPIO_BANK("uart0", 0, 0x0, 8, 4), 136 - VT8500_GPIO_BANK("uart1", 4, 0x0, 12, 4), 137 - VT8500_GPIO_BANK("spi0", 8, 0x0, 16, 4), 138 - VT8500_GPIO_BANK("spi1", 12, 0x0, 20, 4), 139 - VT8500_GPIO_BANK("spi2", 16, 0x0, 24, 4), 140 - VT8500_GPIO_BANK("pwmout", 24, 0x0, 28, 2), 141 - 142 - VT8500_GPIO_BANK("sdmmc", 0, 0x4, 30, 11), 143 - VT8500_GPIO_BANK("ms", 16, 0x4, 41, 7), 144 - VT8500_GPIO_BANK("i2c0", 24, 0x4, 48, 2), 145 - VT8500_GPIO_BANK("i2c1", 26, 0x4, 50, 2), 146 - 147 - VT8500_GPIO_BANK("mii", 0, 0x8, 52, 20), 148 - VT8500_GPIO_BANK("see", 20, 0x8, 72, 4), 149 - VT8500_GPIO_BANK("ide", 24, 0x8, 76, 7), 150 - 151 - VT8500_GPIO_BANK("ccir", 0, 0xc, 83, 19), 152 - 153 - VT8500_GPIO_BANK("ts", 8, 0x10, 102, 11), 154 - 155 - VT8500_GPIO_BANK("lcd", 0, 0x14, 113, 23), 156 - }; 157 - 158 - static int vt8500_gpio_direction_input(struct gpio_chip *chip, 159 - unsigned offset) 160 - { 161 - unsigned val = readl(regbase + DIRECTION_REGS + EXT_REGOFF); 162 - 163 - val &= ~(1 << offset); 164 - writel(val, regbase + DIRECTION_REGS + EXT_REGOFF); 165 - return 0; 166 - } 167 - 168 - static int vt8500_gpio_direction_output(struct gpio_chip *chip, 169 - unsigned offset, int value) 170 - { 171 - unsigned val = readl(regbase + DIRECTION_REGS + EXT_REGOFF); 172 - 173 - val |= (1 << offset); 174 - writel(val, regbase + DIRECTION_REGS + EXT_REGOFF); 175 - 176 - if (value) { 177 - val = readl(regbase + OUTVALUE_REGS + EXT_REGOFF); 178 - val |= (1 << offset); 179 - writel(val, regbase + OUTVALUE_REGS + EXT_REGOFF); 180 - } 181 - return 0; 182 - } 183 - 184 - static int vt8500_gpio_get_value(struct gpio_chip *chip, 185 - unsigned offset) 186 - { 187 - return (readl(regbase + INVALUE_REGS + EXT_REGOFF) >> offset) & 1; 188 - } 189 - 190 - static void vt8500_gpio_set_value(struct gpio_chip *chip, 191 - unsigned offset, int value) 192 - { 193 - unsigned val = readl(regbase + OUTVALUE_REGS + EXT_REGOFF); 194 - 195 - if (value) 196 - val |= (1 << offset); 197 - else 198 - val &= ~(1 << offset); 199 - 200 - writel(val, regbase + OUTVALUE_REGS + EXT_REGOFF); 201 - } 202 - 203 - static int vt8500_gpio_to_irq(struct gpio_chip *chip, unsigned offset) 204 - { 205 - if (offset > 7) 206 - return -EINVAL; 207 - 208 - return gpio_to_irq_map[offset]; 209 - } 210 - 211 - static struct gpio_chip vt8500_external_gpios = { 212 - .label = "extgpio", 213 - .direction_input = vt8500_gpio_direction_input, 214 - .direction_output = vt8500_gpio_direction_output, 215 - .get = vt8500_gpio_get_value, 216 - .set = vt8500_gpio_set_value, 217 - .to_irq = vt8500_gpio_to_irq, 218 - .can_sleep = 0, 219 - .base = 0, 220 - .ngpio = 8, 221 - }; 222 - 223 - void __init vt8500_gpio_init(void) 224 - { 225 - int i; 226 - 227 - for (i = 0; i < 8; i++) 228 - gpio_to_irq_map[i] = wmt_gpio_ext_irq[i]; 229 - 230 - regbase = ioremap(wmt_gpio_base, SZ_64K); 231 - if (!regbase) { 232 - printk(KERN_ERR "Failed to map MMIO registers for GPIO\n"); 233 - return; 234 - } 235 - 236 - gpiochip_add(&vt8500_external_gpios); 237 - 238 - for (i = 0; i < ARRAY_SIZE(vt8500_muxed_gpios); i++) 239 - gpiochip_add(&vt8500_muxed_gpios[i].chip); 240 - }
+2 -2
arch/arm/mach-vt8500/include/mach/restart.h
··· 13 13 * 14 14 */ 15 15 16 - void wmt_setup_restart(void); 17 - void wmt_restart(char mode, const char *cmd); 16 + void vt8500_setup_restart(void); 17 + void vt8500_restart(char mode, const char *cmd);
-88
arch/arm/mach-vt8500/include/mach/vt8500_irqs.h
··· 1 - /* 2 - * arch/arm/mach-vt8500/include/mach/vt8500_irqs.h 3 - * 4 - * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> 5 - * 6 - * This program is free software; you can redistribute it and/or modify 7 - * it under the terms of the GNU General Public License as published by 8 - * the Free Software Foundation; either version 2 of the License, or 9 - * (at your option) any later version. 10 - * 11 - * This program is distributed in the hope that it will be useful, 12 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 - * GNU General Public License for more details. 15 - * 16 - * You should have received a copy of the GNU General Public License 17 - * along with this program; if not, write to the Free Software 18 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 - */ 20 - 21 - /* VT8500 Interrupt Sources */ 22 - 23 - #define IRQ_JPEGENC 0 /* JPEG Encoder */ 24 - #define IRQ_JPEGDEC 1 /* JPEG Decoder */ 25 - /* Reserved */ 26 - #define IRQ_PATA 3 /* PATA Controller */ 27 - /* Reserved */ 28 - #define IRQ_DMA 5 /* DMA Controller */ 29 - #define IRQ_EXT0 6 /* External Interrupt 0 */ 30 - #define IRQ_EXT1 7 /* External Interrupt 1 */ 31 - #define IRQ_GE 8 /* Graphic Engine */ 32 - #define IRQ_GOV 9 /* Graphic Overlay Engine */ 33 - #define IRQ_ETHER 10 /* Ethernet MAC */ 34 - #define IRQ_MPEGTS 11 /* Transport Stream Interface */ 35 - #define IRQ_LCDC 12 /* LCD Controller */ 36 - #define IRQ_EXT2 13 /* External Interrupt 2 */ 37 - #define IRQ_EXT3 14 /* External Interrupt 3 */ 38 - #define IRQ_EXT4 15 /* External Interrupt 4 */ 39 - #define IRQ_CIPHER 16 /* Cipher */ 40 - #define IRQ_VPP 17 /* Video Post-Processor */ 41 - #define IRQ_I2C1 18 /* I2C 1 */ 42 - #define IRQ_I2C0 19 /* I2C 0 */ 43 - #define IRQ_SDMMC 20 /* SD/MMC Controller */ 44 - #define IRQ_SDMMC_DMA 21 /* SD/MMC Controller DMA */ 45 - #define IRQ_PMC_WU 22 /* Power Management Controller Wakeup */ 46 - /* Reserved */ 47 - #define IRQ_SPI0 24 /* SPI 0 */ 48 - #define IRQ_SPI1 25 /* SPI 1 */ 49 - #define IRQ_SPI2 26 /* SPI 2 */ 50 - #define IRQ_LCDDF 27 /* LCD Data Formatter */ 51 - #define IRQ_NAND 28 /* NAND Flash Controller */ 52 - #define IRQ_NAND_DMA 29 /* NAND Flash Controller DMA */ 53 - #define IRQ_MS 30 /* MemoryStick Controller */ 54 - #define IRQ_MS_DMA 31 /* MemoryStick Controller DMA */ 55 - #define IRQ_UART0 32 /* UART 0 */ 56 - #define IRQ_UART1 33 /* UART 1 */ 57 - #define IRQ_I2S 34 /* I2S */ 58 - #define IRQ_PCM 35 /* PCM */ 59 - #define IRQ_PMCOS0 36 /* PMC OS Timer 0 */ 60 - #define IRQ_PMCOS1 37 /* PMC OS Timer 1 */ 61 - #define IRQ_PMCOS2 38 /* PMC OS Timer 2 */ 62 - #define IRQ_PMCOS3 39 /* PMC OS Timer 3 */ 63 - #define IRQ_VPU 40 /* Video Processing Unit */ 64 - #define IRQ_VID 41 /* Video Digital Input Interface */ 65 - #define IRQ_AC97 42 /* AC97 Interface */ 66 - #define IRQ_EHCI 43 /* USB */ 67 - #define IRQ_NOR 44 /* NOR Flash Controller */ 68 - #define IRQ_PS2MOUSE 45 /* PS/2 Mouse */ 69 - #define IRQ_PS2KBD 46 /* PS/2 Keyboard */ 70 - #define IRQ_UART2 47 /* UART 2 */ 71 - #define IRQ_RTC 48 /* RTC Interrupt */ 72 - #define IRQ_RTCSM 49 /* RTC Second/Minute Update Interrupt */ 73 - #define IRQ_UART3 50 /* UART 3 */ 74 - #define IRQ_ADC 51 /* ADC */ 75 - #define IRQ_EXT5 52 /* External Interrupt 5 */ 76 - #define IRQ_EXT6 53 /* External Interrupt 6 */ 77 - #define IRQ_EXT7 54 /* External Interrupt 7 */ 78 - #define IRQ_CIR 55 /* CIR */ 79 - #define IRQ_DMA0 56 /* DMA Channel 0 */ 80 - #define IRQ_DMA1 57 /* DMA Channel 1 */ 81 - #define IRQ_DMA2 58 /* DMA Channel 2 */ 82 - #define IRQ_DMA3 59 /* DMA Channel 3 */ 83 - #define IRQ_DMA4 60 /* DMA Channel 4 */ 84 - #define IRQ_DMA5 61 /* DMA Channel 5 */ 85 - #define IRQ_DMA6 62 /* DMA Channel 6 */ 86 - #define IRQ_DMA7 63 /* DMA Channel 7 */ 87 - 88 - #define VT8500_NR_IRQS 64
-79
arch/arm/mach-vt8500/include/mach/vt8500_regs.h
··· 1 - /* 2 - * arch/arm/mach-vt8500/include/mach/vt8500_regs.h 3 - * 4 - * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> 5 - * 6 - * This program is free software; you can redistribute it and/or modify 7 - * it under the terms of the GNU General Public License as published by 8 - * the Free Software Foundation; either version 2 of the License, or 9 - * (at your option) any later version. 10 - * 11 - * This program is distributed in the hope that it will be useful, 12 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 - * GNU General Public License for more details. 15 - * 16 - * You should have received a copy of the GNU General Public License 17 - * along with this program; if not, write to the Free Software 18 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 - */ 20 - #ifndef __ASM_ARM_ARCH_VT8500_REGS_H 21 - #define __ASM_ARM_ARCH_VT8500_REGS_H 22 - 23 - /* VT8500 Registers Map */ 24 - 25 - #define VT8500_REGS_START_PHYS 0xd8000000 /* Start of MMIO registers */ 26 - #define VT8500_REGS_START_VIRT 0xf8000000 /* Virtual mapping start */ 27 - 28 - #define VT8500_DDR_BASE 0xd8000000 /* 1k DDR/DDR2 Memory 29 - Controller */ 30 - #define VT8500_DMA_BASE 0xd8001000 /* 1k DMA Controller */ 31 - #define VT8500_SFLASH_BASE 0xd8002000 /* 1k Serial Flash Memory 32 - Controller */ 33 - #define VT8500_ETHER_BASE 0xd8004000 /* 1k Ethernet MAC 0 */ 34 - #define VT8500_CIPHER_BASE 0xd8006000 /* 4k Cipher */ 35 - #define VT8500_USB_BASE 0xd8007800 /* 2k USB OTG */ 36 - # define VT8500_EHCI_BASE 0xd8007900 /* EHCI */ 37 - # define VT8500_UHCI_BASE 0xd8007b01 /* UHCI */ 38 - #define VT8500_PATA_BASE 0xd8008000 /* 512 PATA */ 39 - #define VT8500_PS2_BASE 0xd8008800 /* 1k PS/2 */ 40 - #define VT8500_NAND_BASE 0xd8009000 /* 1k NAND Controller */ 41 - #define VT8500_NOR_BASE 0xd8009400 /* 1k NOR Controller */ 42 - #define VT8500_SDMMC_BASE 0xd800a000 /* 1k SD/MMC Controller */ 43 - #define VT8500_MS_BASE 0xd800b000 /* 1k MS/MSPRO Controller */ 44 - #define VT8500_LCDC_BASE 0xd800e400 /* 1k LCD Controller */ 45 - #define VT8500_VPU_BASE 0xd8050000 /* 256 VPU */ 46 - #define VT8500_GOV_BASE 0xd8050300 /* 256 GOV */ 47 - #define VT8500_GEGEA_BASE 0xd8050400 /* 768 GE/GE Alpha Mixing */ 48 - #define VT8500_LCDF_BASE 0xd8050900 /* 256 LCD Formatter */ 49 - #define VT8500_VID_BASE 0xd8050a00 /* 256 VID */ 50 - #define VT8500_VPP_BASE 0xd8050b00 /* 256 VPP */ 51 - #define VT8500_TSBK_BASE 0xd80f4000 /* 4k TSBK */ 52 - #define VT8500_JPEGDEC_BASE 0xd80fe000 /* 4k JPEG Decoder */ 53 - #define VT8500_JPEGENC_BASE 0xd80ff000 /* 4k JPEG Encoder */ 54 - #define VT8500_RTC_BASE 0xd8100000 /* 64k RTC */ 55 - #define VT8500_GPIO_BASE 0xd8110000 /* 64k GPIO Configuration */ 56 - #define VT8500_SCC_BASE 0xd8120000 /* 64k System Configuration*/ 57 - #define VT8500_PMC_BASE 0xd8130000 /* 64k PMC Configuration */ 58 - #define VT8500_IC_BASE 0xd8140000 /* 64k Interrupt Controller*/ 59 - #define VT8500_UART0_BASE 0xd8200000 /* 64k UART 0 */ 60 - #define VT8500_UART2_BASE 0xd8210000 /* 64k UART 2 */ 61 - #define VT8500_PWM_BASE 0xd8220000 /* 64k PWM Configuration */ 62 - #define VT8500_SPI0_BASE 0xd8240000 /* 64k SPI 0 */ 63 - #define VT8500_SPI1_BASE 0xd8250000 /* 64k SPI 1 */ 64 - #define VT8500_CIR_BASE 0xd8270000 /* 64k CIR */ 65 - #define VT8500_I2C0_BASE 0xd8280000 /* 64k I2C 0 */ 66 - #define VT8500_AC97_BASE 0xd8290000 /* 64k AC97 */ 67 - #define VT8500_SPI2_BASE 0xd82a0000 /* 64k SPI 2 */ 68 - #define VT8500_UART1_BASE 0xd82b0000 /* 64k UART 1 */ 69 - #define VT8500_UART3_BASE 0xd82c0000 /* 64k UART 3 */ 70 - #define VT8500_PCM_BASE 0xd82d0000 /* 64k PCM */ 71 - #define VT8500_I2C1_BASE 0xd8320000 /* 64k I2C 1 */ 72 - #define VT8500_I2S_BASE 0xd8330000 /* 64k I2S */ 73 - #define VT8500_ADC_BASE 0xd8340000 /* 64k ADC */ 74 - 75 - #define VT8500_REGS_END_PHYS 0xd834ffff /* End of MMIO registers */ 76 - #define VT8500_REGS_LENGTH (VT8500_REGS_END_PHYS \ 77 - - VT8500_REGS_START_PHYS + 1) 78 - 79 - #endif
-115
arch/arm/mach-vt8500/include/mach/wm8505_irqs.h
··· 1 - /* 2 - * arch/arm/mach-vt8500/include/mach/wm8505_irqs.h 3 - * 4 - * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> 5 - * 6 - * This program is free software; you can redistribute it and/or modify 7 - * it under the terms of the GNU General Public License as published by 8 - * the Free Software Foundation; either version 2 of the License, or 9 - * (at your option) any later version. 10 - * 11 - * This program is distributed in the hope that it will be useful, 12 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 - * GNU General Public License for more details. 15 - * 16 - * You should have received a copy of the GNU General Public License 17 - * along with this program; if not, write to the Free Software 18 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 - */ 20 - 21 - /* WM8505 Interrupt Sources */ 22 - 23 - #define IRQ_UHCI 0 /* UHC FS (UHCI?) */ 24 - #define IRQ_EHCI 1 /* UHC HS */ 25 - #define IRQ_UDCDMA 2 /* UDC DMA */ 26 - /* Reserved */ 27 - #define IRQ_PS2MOUSE 4 /* PS/2 Mouse */ 28 - #define IRQ_UDC 5 /* UDC */ 29 - #define IRQ_EXT0 6 /* External Interrupt 0 */ 30 - #define IRQ_EXT1 7 /* External Interrupt 1 */ 31 - #define IRQ_KEYPAD 8 /* Keypad */ 32 - #define IRQ_DMA 9 /* DMA Controller */ 33 - #define IRQ_ETHER 10 /* Ethernet MAC */ 34 - /* Reserved */ 35 - /* Reserved */ 36 - #define IRQ_EXT2 13 /* External Interrupt 2 */ 37 - #define IRQ_EXT3 14 /* External Interrupt 3 */ 38 - #define IRQ_EXT4 15 /* External Interrupt 4 */ 39 - #define IRQ_APB 16 /* APB Bridge */ 40 - #define IRQ_DMA0 17 /* DMA Channel 0 */ 41 - #define IRQ_I2C1 18 /* I2C 1 */ 42 - #define IRQ_I2C0 19 /* I2C 0 */ 43 - #define IRQ_SDMMC 20 /* SD/MMC Controller */ 44 - #define IRQ_SDMMC_DMA 21 /* SD/MMC Controller DMA */ 45 - #define IRQ_PMC_WU 22 /* Power Management Controller Wakeup */ 46 - #define IRQ_PS2KBD 23 /* PS/2 Keyboard */ 47 - #define IRQ_SPI0 24 /* SPI 0 */ 48 - #define IRQ_SPI1 25 /* SPI 1 */ 49 - #define IRQ_SPI2 26 /* SPI 2 */ 50 - #define IRQ_DMA1 27 /* DMA Channel 1 */ 51 - #define IRQ_NAND 28 /* NAND Flash Controller */ 52 - #define IRQ_NAND_DMA 29 /* NAND Flash Controller DMA */ 53 - #define IRQ_UART5 30 /* UART 5 */ 54 - #define IRQ_UART4 31 /* UART 4 */ 55 - #define IRQ_UART0 32 /* UART 0 */ 56 - #define IRQ_UART1 33 /* UART 1 */ 57 - #define IRQ_DMA2 34 /* DMA Channel 2 */ 58 - #define IRQ_I2S 35 /* I2S */ 59 - #define IRQ_PMCOS0 36 /* PMC OS Timer 0 */ 60 - #define IRQ_PMCOS1 37 /* PMC OS Timer 1 */ 61 - #define IRQ_PMCOS2 38 /* PMC OS Timer 2 */ 62 - #define IRQ_PMCOS3 39 /* PMC OS Timer 3 */ 63 - #define IRQ_DMA3 40 /* DMA Channel 3 */ 64 - #define IRQ_DMA4 41 /* DMA Channel 4 */ 65 - #define IRQ_AC97 42 /* AC97 Interface */ 66 - /* Reserved */ 67 - #define IRQ_NOR 44 /* NOR Flash Controller */ 68 - #define IRQ_DMA5 45 /* DMA Channel 5 */ 69 - #define IRQ_DMA6 46 /* DMA Channel 6 */ 70 - #define IRQ_UART2 47 /* UART 2 */ 71 - #define IRQ_RTC 48 /* RTC Interrupt */ 72 - #define IRQ_RTCSM 49 /* RTC Second/Minute Update Interrupt */ 73 - #define IRQ_UART3 50 /* UART 3 */ 74 - #define IRQ_DMA7 51 /* DMA Channel 7 */ 75 - #define IRQ_EXT5 52 /* External Interrupt 5 */ 76 - #define IRQ_EXT6 53 /* External Interrupt 6 */ 77 - #define IRQ_EXT7 54 /* External Interrupt 7 */ 78 - #define IRQ_CIR 55 /* CIR */ 79 - #define IRQ_SIC0 56 /* SIC IRQ0 */ 80 - #define IRQ_SIC1 57 /* SIC IRQ1 */ 81 - #define IRQ_SIC2 58 /* SIC IRQ2 */ 82 - #define IRQ_SIC3 59 /* SIC IRQ3 */ 83 - #define IRQ_SIC4 60 /* SIC IRQ4 */ 84 - #define IRQ_SIC5 61 /* SIC IRQ5 */ 85 - #define IRQ_SIC6 62 /* SIC IRQ6 */ 86 - #define IRQ_SIC7 63 /* SIC IRQ7 */ 87 - /* Reserved */ 88 - #define IRQ_JPEGDEC 65 /* JPEG Decoder */ 89 - #define IRQ_SAE 66 /* SAE (?) */ 90 - /* Reserved */ 91 - #define IRQ_VPU 79 /* Video Processing Unit */ 92 - #define IRQ_VPP 80 /* Video Post-Processor */ 93 - #define IRQ_VID 81 /* Video Digital Input Interface */ 94 - #define IRQ_SPU 82 /* SPU (?) */ 95 - #define IRQ_PIP 83 /* PIP Error */ 96 - #define IRQ_GE 84 /* Graphic Engine */ 97 - #define IRQ_GOV 85 /* Graphic Overlay Engine */ 98 - #define IRQ_DVO 86 /* Digital Video Output */ 99 - /* Reserved */ 100 - #define IRQ_DMA8 92 /* DMA Channel 8 */ 101 - #define IRQ_DMA9 93 /* DMA Channel 9 */ 102 - #define IRQ_DMA10 94 /* DMA Channel 10 */ 103 - #define IRQ_DMA11 95 /* DMA Channel 11 */ 104 - #define IRQ_DMA12 96 /* DMA Channel 12 */ 105 - #define IRQ_DMA13 97 /* DMA Channel 13 */ 106 - #define IRQ_DMA14 98 /* DMA Channel 14 */ 107 - #define IRQ_DMA15 99 /* DMA Channel 15 */ 108 - /* Reserved */ 109 - #define IRQ_GOVW 111 /* GOVW (?) */ 110 - #define IRQ_GOVRSDSCD 112 /* GOVR SDSCD (?) */ 111 - #define IRQ_GOVRSDMIF 113 /* GOVR SDMIF (?) */ 112 - #define IRQ_GOVRHDSCD 114 /* GOVR HDSCD (?) */ 113 - #define IRQ_GOVRHDMIF 115 /* GOVR HDMIF (?) */ 114 - 115 - #define WM8505_NR_IRQS 116
-78
arch/arm/mach-vt8500/include/mach/wm8505_regs.h
··· 1 - /* 2 - * arch/arm/mach-vt8500/include/mach/wm8505_regs.h 3 - * 4 - * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> 5 - * 6 - * This program is free software; you can redistribute it and/or modify 7 - * it under the terms of the GNU General Public License as published by 8 - * the Free Software Foundation; either version 2 of the License, or 9 - * (at your option) any later version. 10 - * 11 - * This program is distributed in the hope that it will be useful, 12 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 - * GNU General Public License for more details. 15 - * 16 - * You should have received a copy of the GNU General Public License 17 - * along with this program; if not, write to the Free Software 18 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 - */ 20 - #ifndef __ASM_ARM_ARCH_WM8505_REGS_H 21 - #define __ASM_ARM_ARCH_WM8505_REGS_H 22 - 23 - /* WM8505 Registers Map */ 24 - 25 - #define WM8505_REGS_START_PHYS 0xd8000000 /* Start of MMIO registers */ 26 - #define WM8505_REGS_START_VIRT 0xf8000000 /* Virtual mapping start */ 27 - 28 - #define WM8505_DDR_BASE 0xd8000400 /* 1k DDR/DDR2 Memory 29 - Controller */ 30 - #define WM8505_DMA_BASE 0xd8001800 /* 1k DMA Controller */ 31 - #define WM8505_VDMA_BASE 0xd8001c00 /* 1k VDMA */ 32 - #define WM8505_SFLASH_BASE 0xd8002000 /* 1k Serial Flash Memory 33 - Controller */ 34 - #define WM8505_ETHER_BASE 0xd8004000 /* 1k Ethernet MAC 0 */ 35 - #define WM8505_CIPHER_BASE 0xd8006000 /* 4k Cipher */ 36 - #define WM8505_USB_BASE 0xd8007000 /* 2k USB 2.0 Host */ 37 - # define WM8505_EHCI_BASE 0xd8007100 /* EHCI */ 38 - # define WM8505_UHCI_BASE 0xd8007301 /* UHCI */ 39 - #define WM8505_PS2_BASE 0xd8008800 /* 1k PS/2 */ 40 - #define WM8505_NAND_BASE 0xd8009000 /* 1k NAND Controller */ 41 - #define WM8505_NOR_BASE 0xd8009400 /* 1k NOR Controller */ 42 - #define WM8505_SDMMC_BASE 0xd800a000 /* 1k SD/MMC Controller */ 43 - #define WM8505_VPU_BASE 0xd8050000 /* 256 VPU */ 44 - #define WM8505_GOV_BASE 0xd8050300 /* 256 GOV */ 45 - #define WM8505_GEGEA_BASE 0xd8050400 /* 768 GE/GE Alpha Mixing */ 46 - #define WM8505_GOVR_BASE 0xd8050800 /* 512 GOVR (frambuffer) */ 47 - #define WM8505_VID_BASE 0xd8050a00 /* 256 VID */ 48 - #define WM8505_SCL_BASE 0xd8050d00 /* 256 SCL */ 49 - #define WM8505_VPP_BASE 0xd8050f00 /* 256 VPP */ 50 - #define WM8505_JPEGDEC_BASE 0xd80fe000 /* 4k JPEG Decoder */ 51 - #define WM8505_RTC_BASE 0xd8100000 /* 64k RTC */ 52 - #define WM8505_GPIO_BASE 0xd8110000 /* 64k GPIO Configuration */ 53 - #define WM8505_SCC_BASE 0xd8120000 /* 64k System Configuration*/ 54 - #define WM8505_PMC_BASE 0xd8130000 /* 64k PMC Configuration */ 55 - #define WM8505_IC_BASE 0xd8140000 /* 64k Interrupt Controller*/ 56 - #define WM8505_SIC_BASE 0xd8150000 /* 64k Secondary IC */ 57 - #define WM8505_UART0_BASE 0xd8200000 /* 64k UART 0 */ 58 - #define WM8505_UART2_BASE 0xd8210000 /* 64k UART 2 */ 59 - #define WM8505_PWM_BASE 0xd8220000 /* 64k PWM Configuration */ 60 - #define WM8505_SPI0_BASE 0xd8240000 /* 64k SPI 0 */ 61 - #define WM8505_SPI1_BASE 0xd8250000 /* 64k SPI 1 */ 62 - #define WM8505_KEYPAD_BASE 0xd8260000 /* 64k Keypad control */ 63 - #define WM8505_CIR_BASE 0xd8270000 /* 64k CIR */ 64 - #define WM8505_I2C0_BASE 0xd8280000 /* 64k I2C 0 */ 65 - #define WM8505_AC97_BASE 0xd8290000 /* 64k AC97 */ 66 - #define WM8505_SPI2_BASE 0xd82a0000 /* 64k SPI 2 */ 67 - #define WM8505_UART1_BASE 0xd82b0000 /* 64k UART 1 */ 68 - #define WM8505_UART3_BASE 0xd82c0000 /* 64k UART 3 */ 69 - #define WM8505_I2C1_BASE 0xd8320000 /* 64k I2C 1 */ 70 - #define WM8505_I2S_BASE 0xd8330000 /* 64k I2S */ 71 - #define WM8505_UART4_BASE 0xd8370000 /* 64k UART 4 */ 72 - #define WM8505_UART5_BASE 0xd8380000 /* 64k UART 5 */ 73 - 74 - #define WM8505_REGS_END_PHYS 0xd838ffff /* End of MMIO registers */ 75 - #define WM8505_REGS_LENGTH (WM8505_REGS_END_PHYS \ 76 - - WM8505_REGS_START_PHYS + 1) 77 - 78 - #endif
+128 -87
arch/arm/mach-vt8500/irq.c
··· 1 1 /* 2 2 * arch/arm/mach-vt8500/irq.c 3 3 * 4 + * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz> 4 5 * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> 5 6 * 6 7 * This program is free software; you can redistribute it and/or modify ··· 19 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 19 */ 21 20 21 + /* 22 + * This file is copied and modified from the original irq.c provided by 23 + * Alexey Charkov. Minor changes have been made for Device Tree Support. 24 + */ 25 + 26 + #include <linux/slab.h> 22 27 #include <linux/io.h> 23 28 #include <linux/irq.h> 29 + #include <linux/irqdomain.h> 24 30 #include <linux/interrupt.h> 31 + #include <linux/bitops.h> 32 + 33 + #include <linux/of.h> 34 + #include <linux/of_irq.h> 35 + #include <linux/of_address.h> 25 36 26 37 #include <asm/irq.h> 27 38 28 - #include "devices.h" 29 39 30 - #define VT8500_IC_DCTR 0x40 /* Destination control 31 - register, 64*u8 */ 32 - #define VT8500_INT_ENABLE (1 << 3) 33 - #define VT8500_TRIGGER_HIGH (0 << 4) 34 - #define VT8500_TRIGGER_RISING (1 << 4) 35 - #define VT8500_TRIGGER_FALLING (2 << 4) 40 + #define VT8500_ICPC_IRQ 0x20 41 + #define VT8500_ICPC_FIQ 0x24 42 + #define VT8500_ICDC 0x40 /* Destination Control 64*u32 */ 43 + #define VT8500_ICIS 0x80 /* Interrupt status, 16*u32 */ 44 + 45 + /* ICPC */ 46 + #define ICPC_MASK 0x3F 47 + #define ICPC_ROTATE BIT(6) 48 + 49 + /* IC_DCTR */ 50 + #define ICDC_IRQ 0x00 51 + #define ICDC_FIQ 0x01 52 + #define ICDC_DSS0 0x02 53 + #define ICDC_DSS1 0x03 54 + #define ICDC_DSS2 0x04 55 + #define ICDC_DSS3 0x05 56 + #define ICDC_DSS4 0x06 57 + #define ICDC_DSS5 0x07 58 + 59 + #define VT8500_INT_DISABLE 0 60 + #define VT8500_INT_ENABLE BIT(3) 61 + 62 + #define VT8500_TRIGGER_HIGH 0 63 + #define VT8500_TRIGGER_RISING BIT(5) 64 + #define VT8500_TRIGGER_FALLING BIT(6) 36 65 #define VT8500_EDGE ( VT8500_TRIGGER_RISING \ 37 66 | VT8500_TRIGGER_FALLING) 38 - #define VT8500_IC_STATUS 0x80 /* Interrupt status, 2*u32 */ 39 67 40 - static void __iomem *ic_regbase; 41 - static void __iomem *sic_regbase; 68 + static int irq_cnt; 69 + 70 + struct vt8500_irq_priv { 71 + void __iomem *base; 72 + }; 42 73 43 74 static void vt8500_irq_mask(struct irq_data *d) 44 75 { 45 - void __iomem *base = ic_regbase; 46 - unsigned irq = d->irq; 76 + struct vt8500_irq_priv *priv = 77 + (struct vt8500_irq_priv *)(d->domain->host_data); 78 + void __iomem *base = priv->base; 47 79 u8 edge; 48 80 49 - if (irq >= 64) { 50 - base = sic_regbase; 51 - irq -= 64; 52 - } 53 - edge = readb(base + VT8500_IC_DCTR + irq) & VT8500_EDGE; 81 + edge = readb(base + VT8500_ICDC + d->hwirq) & VT8500_EDGE; 54 82 if (edge) { 55 - void __iomem *stat_reg = base + VT8500_IC_STATUS 56 - + (irq < 32 ? 0 : 4); 83 + void __iomem *stat_reg = base + VT8500_ICIS 84 + + (d->hwirq < 32 ? 0 : 4); 57 85 unsigned status = readl(stat_reg); 58 86 59 - status |= (1 << (irq & 0x1f)); 87 + status |= (1 << (d->hwirq & 0x1f)); 60 88 writel(status, stat_reg); 61 89 } else { 62 - u8 dctr = readb(base + VT8500_IC_DCTR + irq); 90 + u8 dctr = readb(base + VT8500_ICDC + d->hwirq); 63 91 64 92 dctr &= ~VT8500_INT_ENABLE; 65 - writeb(dctr, base + VT8500_IC_DCTR + irq); 93 + writeb(dctr, base + VT8500_ICDC + d->hwirq); 66 94 } 67 95 } 68 96 69 97 static void vt8500_irq_unmask(struct irq_data *d) 70 98 { 71 - void __iomem *base = ic_regbase; 72 - unsigned irq = d->irq; 99 + struct vt8500_irq_priv *priv = 100 + (struct vt8500_irq_priv *)(d->domain->host_data); 101 + void __iomem *base = priv->base; 73 102 u8 dctr; 74 103 75 - if (irq >= 64) { 76 - base = sic_regbase; 77 - irq -= 64; 78 - } 79 - dctr = readb(base + VT8500_IC_DCTR + irq); 104 + dctr = readb(base + VT8500_ICDC + d->hwirq); 80 105 dctr |= VT8500_INT_ENABLE; 81 - writeb(dctr, base + VT8500_IC_DCTR + irq); 106 + writeb(dctr, base + VT8500_ICDC + d->hwirq); 82 107 } 83 108 84 109 static int vt8500_irq_set_type(struct irq_data *d, unsigned int flow_type) 85 110 { 86 - void __iomem *base = ic_regbase; 87 - unsigned irq = d->irq; 88 - unsigned orig_irq = irq; 111 + struct vt8500_irq_priv *priv = 112 + (struct vt8500_irq_priv *)(d->domain->host_data); 113 + void __iomem *base = priv->base; 89 114 u8 dctr; 90 115 91 - if (irq >= 64) { 92 - base = sic_regbase; 93 - irq -= 64; 94 - } 95 - 96 - dctr = readb(base + VT8500_IC_DCTR + irq); 116 + dctr = readb(base + VT8500_ICDC + d->hwirq); 97 117 dctr &= ~VT8500_EDGE; 98 118 99 119 switch (flow_type) { ··· 122 100 return -EINVAL; 123 101 case IRQF_TRIGGER_HIGH: 124 102 dctr |= VT8500_TRIGGER_HIGH; 125 - __irq_set_handler_locked(orig_irq, handle_level_irq); 103 + __irq_set_handler_locked(d->irq, handle_level_irq); 126 104 break; 127 105 case IRQF_TRIGGER_FALLING: 128 106 dctr |= VT8500_TRIGGER_FALLING; 129 - __irq_set_handler_locked(orig_irq, handle_edge_irq); 107 + __irq_set_handler_locked(d->irq, handle_edge_irq); 130 108 break; 131 109 case IRQF_TRIGGER_RISING: 132 110 dctr |= VT8500_TRIGGER_RISING; 133 - __irq_set_handler_locked(orig_irq, handle_edge_irq); 111 + __irq_set_handler_locked(d->irq, handle_edge_irq); 134 112 break; 135 113 } 136 - writeb(dctr, base + VT8500_IC_DCTR + irq); 114 + writeb(dctr, base + VT8500_ICDC + d->hwirq); 137 115 138 116 return 0; 139 117 } ··· 146 124 .irq_set_type = vt8500_irq_set_type, 147 125 }; 148 126 149 - void __init vt8500_init_irq(void) 127 + static void __init vt8500_init_irq_hw(void __iomem *base) 150 128 { 151 129 unsigned int i; 152 130 153 - ic_regbase = ioremap(wmt_ic_base, SZ_64K); 131 + /* Enable rotating priority for IRQ */ 132 + writel(ICPC_ROTATE, base + VT8500_ICPC_IRQ); 133 + writel(0x00, base + VT8500_ICPC_FIQ); 154 134 155 - if (ic_regbase) { 156 - /* Enable rotating priority for IRQ */ 157 - writel((1 << 6), ic_regbase + 0x20); 158 - writel(0, ic_regbase + 0x24); 159 - 160 - for (i = 0; i < wmt_nr_irqs; i++) { 161 - /* Disable all interrupts and route them to IRQ */ 162 - writeb(0x00, ic_regbase + VT8500_IC_DCTR + i); 163 - 164 - irq_set_chip_and_handler(i, &vt8500_irq_chip, 165 - handle_level_irq); 166 - set_irq_flags(i, IRQF_VALID); 167 - } 168 - } else { 169 - printk(KERN_ERR "Unable to remap the Interrupt Controller registers, not enabling IRQs!\n"); 135 + for (i = 0; i < 64; i++) { 136 + /* Disable all interrupts and route them to IRQ */ 137 + writeb(VT8500_INT_DISABLE | ICDC_IRQ, 138 + base + VT8500_ICDC + i); 170 139 } 171 140 } 172 141 173 - void __init wm8505_init_irq(void) 142 + static int vt8500_irq_map(struct irq_domain *h, unsigned int virq, 143 + irq_hw_number_t hw) 174 144 { 175 - unsigned int i; 145 + irq_set_chip_and_handler(virq, &vt8500_irq_chip, handle_level_irq); 146 + set_irq_flags(virq, IRQF_VALID); 176 147 177 - ic_regbase = ioremap(wmt_ic_base, SZ_64K); 178 - sic_regbase = ioremap(wmt_sic_base, SZ_64K); 179 - 180 - if (ic_regbase && sic_regbase) { 181 - /* Enable rotating priority for IRQ */ 182 - writel((1 << 6), ic_regbase + 0x20); 183 - writel(0, ic_regbase + 0x24); 184 - writel((1 << 6), sic_regbase + 0x20); 185 - writel(0, sic_regbase + 0x24); 186 - 187 - for (i = 0; i < wmt_nr_irqs; i++) { 188 - /* Disable all interrupts and route them to IRQ */ 189 - if (i < 64) 190 - writeb(0x00, ic_regbase + VT8500_IC_DCTR + i); 191 - else 192 - writeb(0x00, sic_regbase + VT8500_IC_DCTR 193 - + i - 64); 194 - 195 - irq_set_chip_and_handler(i, &vt8500_irq_chip, 196 - handle_level_irq); 197 - set_irq_flags(i, IRQF_VALID); 198 - } 199 - } else { 200 - printk(KERN_ERR "Unable to remap the Interrupt Controller registers, not enabling IRQs!\n"); 201 - } 148 + return 0; 202 149 } 150 + 151 + static struct irq_domain_ops vt8500_irq_domain_ops = { 152 + .map = vt8500_irq_map, 153 + .xlate = irq_domain_xlate_onecell, 154 + }; 155 + 156 + int __init vt8500_irq_init(struct device_node *node, struct device_node *parent) 157 + { 158 + struct irq_domain *vt8500_irq_domain; 159 + struct vt8500_irq_priv *priv; 160 + int irq, i; 161 + struct device_node *np = node; 162 + 163 + priv = kzalloc(sizeof(struct vt8500_irq_priv), GFP_KERNEL); 164 + priv->base = of_iomap(np, 0); 165 + 166 + vt8500_irq_domain = irq_domain_add_legacy(node, 64, irq_cnt, 0, 167 + &vt8500_irq_domain_ops, priv); 168 + if (!vt8500_irq_domain) 169 + pr_err("%s: Unable to add wmt irq domain!\n", __func__); 170 + 171 + irq_set_default_host(vt8500_irq_domain); 172 + 173 + vt8500_init_irq_hw(priv->base); 174 + 175 + pr_info("Added IRQ Controller @ %x [virq_base = %d]\n", 176 + (u32)(priv->base), irq_cnt); 177 + 178 + /* check if this is a slaved controller */ 179 + if (of_irq_count(np) != 0) { 180 + /* check that we have the correct number of interrupts */ 181 + if (of_irq_count(np) != 8) { 182 + pr_err("%s: Incorrect IRQ map for slave controller\n", 183 + __func__); 184 + return -EINVAL; 185 + } 186 + 187 + for (i = 0; i < 8; i++) { 188 + irq = irq_of_parse_and_map(np, i); 189 + enable_irq(irq); 190 + } 191 + 192 + pr_info("vt8500-irq: Enabled slave->parent interrupts\n"); 193 + } 194 + 195 + irq_cnt += 64; 196 + 197 + return 0; 198 + } 199 +
-54
arch/arm/mach-vt8500/restart.c
··· 1 - /* linux/arch/arm/mach-vt8500/restart.c 2 - * 3 - * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz> 4 - * 5 - * This software is licensed under the terms of the GNU General Public 6 - * License version 2, as published by the Free Software Foundation, and 7 - * may be copied, distributed, and modified under those terms. 8 - * 9 - * This program is distributed in the hope that it will be useful, 10 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 - * GNU General Public License for more details. 13 - * 14 - */ 15 - #include <asm/io.h> 16 - #include <linux/of.h> 17 - #include <linux/of_address.h> 18 - 19 - #define LEGACY_PMC_BASE 0xD8130000 20 - #define WMT_PRIZM_PMSR_REG 0x60 21 - 22 - static void __iomem *pmc_base; 23 - 24 - void wmt_setup_restart(void) 25 - { 26 - struct device_node *np; 27 - 28 - /* 29 - * Check if Power Mgmt Controller node is present in device tree. If no 30 - * device tree node, use the legacy PMSR value (valid for all current 31 - * SoCs). 32 - */ 33 - np = of_find_compatible_node(NULL, NULL, "wmt,prizm-pmc"); 34 - if (np) { 35 - pmc_base = of_iomap(np, 0); 36 - 37 - if (!pmc_base) 38 - pr_err("%s:of_iomap(pmc) failed\n", __func__); 39 - 40 - of_node_put(np); 41 - } else { 42 - pmc_base = ioremap(LEGACY_PMC_BASE, 0x1000); 43 - if (!pmc_base) { 44 - pr_err("%s:ioremap(rstc) failed\n", __func__); 45 - return; 46 - } 47 - } 48 - } 49 - 50 - void wmt_restart(char mode, const char *cmd) 51 - { 52 - if (pmc_base) 53 - writel(1, pmc_base + WMT_PRIZM_PMSR_REG); 54 - }
+48 -19
arch/arm/mach-vt8500/timer.c
··· 1 1 /* 2 - * arch/arm/mach-vt8500/timer.c 2 + * arch/arm/mach-vt8500/timer_dt.c 3 3 * 4 + * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz> 4 5 * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> 5 6 * 6 7 * This program is free software; you can redistribute it and/or modify ··· 19 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 19 */ 21 20 21 + /* 22 + * This file is copied and modified from the original timer.c provided by 23 + * Alexey Charkov. Minor changes have been made for Device Tree Support. 24 + */ 25 + 22 26 #include <linux/io.h> 23 27 #include <linux/irq.h> 24 28 #include <linux/interrupt.h> 25 29 #include <linux/clocksource.h> 26 30 #include <linux/clockchips.h> 27 31 #include <linux/delay.h> 28 - 29 32 #include <asm/mach/time.h> 30 33 31 - #include "devices.h" 34 + #include <linux/of.h> 35 + #include <linux/of_address.h> 36 + #include <linux/of_irq.h> 32 37 33 38 #define VT8500_TIMER_OFFSET 0x0100 39 + #define VT8500_TIMER_HZ 3000000 34 40 #define TIMER_MATCH_VAL 0x0000 35 41 #define TIMER_COUNT_VAL 0x0010 36 42 #define TIMER_STATUS_VAL 0x0014 ··· 47 39 #define TIMER_COUNT_R_ACTIVE (1 << 5) /* not ready for read */ 48 40 #define TIMER_COUNT_W_ACTIVE (1 << 4) /* not ready for write */ 49 41 #define TIMER_MATCH_W_ACTIVE (1 << 0) /* not ready for write */ 50 - #define VT8500_TIMER_HZ 3000000 51 42 52 43 #define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t) 53 44 ··· 62 55 return readl(regbase + TIMER_COUNT_VAL); 63 56 } 64 57 65 - struct clocksource clocksource = { 58 + static struct clocksource clocksource = { 66 59 .name = "vt8500_timer", 67 60 .rating = 200, 68 61 .read = vt8500_timer_read, ··· 105 98 } 106 99 } 107 100 108 - struct clock_event_device clockevent = { 101 + static struct clock_event_device clockevent = { 109 102 .name = "vt8500_timer", 110 103 .features = CLOCK_EVT_FEAT_ONESHOT, 111 104 .rating = 200, ··· 122 115 return IRQ_HANDLED; 123 116 } 124 117 125 - struct irqaction irq = { 118 + static struct irqaction irq = { 126 119 .name = "vt8500_timer", 127 120 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, 128 121 .handler = vt8500_timer_interrupt, 129 122 .dev_id = &clockevent, 130 123 }; 131 124 132 - static void __init vt8500_timer_init(void) 125 + static struct of_device_id vt8500_timer_ids[] = { 126 + { .compatible = "via,vt8500-timer" }, 127 + { } 128 + }; 129 + 130 + void __init vt8500_timer_init(void) 133 131 { 134 - regbase = ioremap(wmt_pmc_base + VT8500_TIMER_OFFSET, 0x28); 135 - if (!regbase) 136 - printk(KERN_ERR "vt8500_timer_init: failed to map MMIO registers\n"); 132 + struct device_node *np; 133 + int timer_irq; 134 + 135 + np = of_find_matching_node(NULL, vt8500_timer_ids); 136 + if (!np) { 137 + pr_err("%s: Timer description missing from Device Tree\n", 138 + __func__); 139 + return; 140 + } 141 + regbase = of_iomap(np, 0); 142 + if (!regbase) { 143 + pr_err("%s: Missing iobase description in Device Tree\n", 144 + __func__); 145 + of_node_put(np); 146 + return; 147 + } 148 + timer_irq = irq_of_parse_and_map(np, 0); 149 + if (!timer_irq) { 150 + pr_err("%s: Missing irq description in Device Tree\n", 151 + __func__); 152 + of_node_put(np); 153 + return; 154 + } 137 155 138 156 writel(1, regbase + TIMER_CTRL_VAL); 139 157 writel(0xf, regbase + TIMER_STATUS_VAL); 140 158 writel(~0, regbase + TIMER_MATCH_VAL); 141 159 142 160 if (clocksource_register_hz(&clocksource, VT8500_TIMER_HZ)) 143 - printk(KERN_ERR "vt8500_timer_init: clocksource_register failed for %s\n", 144 - clocksource.name); 161 + pr_err("%s: vt8500_timer_init: clocksource_register failed for %s\n", 162 + __func__, clocksource.name); 145 163 146 164 clockevents_calc_mult_shift(&clockevent, VT8500_TIMER_HZ, 4); 147 165 ··· 176 144 clockevent.min_delta_ns = clockevent_delta2ns(4, &clockevent); 177 145 clockevent.cpumask = cpumask_of(0); 178 146 179 - if (setup_irq(wmt_timer_irq, &irq)) 180 - printk(KERN_ERR "vt8500_timer_init: setup_irq failed for %s\n", 181 - clockevent.name); 147 + if (setup_irq(timer_irq, &irq)) 148 + pr_err("%s: setup_irq failed for %s\n", __func__, 149 + clockevent.name); 182 150 clockevents_register_device(&clockevent); 183 151 } 184 152 185 - struct sys_timer vt8500_timer = { 186 - .init = vt8500_timer_init 187 - };
+196
arch/arm/mach-vt8500/vt8500.c
··· 1 + /* 2 + * arch/arm/mach-vt8500/vt8500.c 3 + * 4 + * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program; if not, write to the Free Software 18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 + */ 20 + 21 + #include <linux/io.h> 22 + #include <linux/pm.h> 23 + 24 + #include <asm/mach-types.h> 25 + #include <asm/mach/arch.h> 26 + #include <asm/mach/time.h> 27 + #include <asm/mach/map.h> 28 + 29 + #include <linux/of.h> 30 + #include <linux/of_address.h> 31 + #include <linux/of_irq.h> 32 + #include <linux/of_platform.h> 33 + 34 + #include <mach/restart.h> 35 + #include <mach/gpio.h> 36 + 37 + #include "common.h" 38 + 39 + #define LEGACY_GPIO_BASE 0xD8110000 40 + #define LEGACY_PMC_BASE 0xD8130000 41 + 42 + /* Registers in GPIO Controller */ 43 + #define VT8500_GPIO_MUX_REG 0x200 44 + 45 + /* Registers in Power Management Controller */ 46 + #define VT8500_HCR_REG 0x12 47 + #define VT8500_PMSR_REG 0x60 48 + 49 + static void __iomem *pmc_base; 50 + 51 + void vt8500_restart(char mode, const char *cmd) 52 + { 53 + if (pmc_base) 54 + writel(1, pmc_base + VT8500_PMSR_REG); 55 + } 56 + 57 + static struct map_desc vt8500_io_desc[] __initdata = { 58 + /* SoC MMIO registers */ 59 + [0] = { 60 + .virtual = 0xf8000000, 61 + .pfn = __phys_to_pfn(0xd8000000), 62 + .length = 0x00390000, /* max of all chip variants */ 63 + .type = MT_DEVICE 64 + }, 65 + }; 66 + 67 + void __init vt8500_map_io(void) 68 + { 69 + iotable_init(vt8500_io_desc, ARRAY_SIZE(vt8500_io_desc)); 70 + } 71 + 72 + static void vt8500_power_off(void) 73 + { 74 + local_irq_disable(); 75 + writew(5, pmc_base + VT8500_HCR_REG); 76 + asm("mcr%? p15, 0, %0, c7, c0, 4" : : "r" (0)); 77 + } 78 + 79 + void __init vt8500_init(void) 80 + { 81 + struct device_node *np, *fb; 82 + void __iomem *gpio_base; 83 + 84 + #ifdef CONFIG_FB_VT8500 85 + fb = of_find_compatible_node(NULL, NULL, "via,vt8500-fb"); 86 + if (fb) { 87 + np = of_find_compatible_node(NULL, NULL, "via,vt8500-gpio"); 88 + if (np) { 89 + gpio_base = of_iomap(np, 0); 90 + 91 + if (!gpio_base) 92 + pr_err("%s: of_iomap(gpio_mux) failed\n", 93 + __func__); 94 + 95 + of_node_put(np); 96 + } else { 97 + gpio_base = ioremap(LEGACY_GPIO_BASE, 0x1000); 98 + if (!gpio_base) 99 + pr_err("%s: ioremap(legacy_gpio_mux) failed\n", 100 + __func__); 101 + } 102 + if (gpio_base) { 103 + writel(readl(gpio_base + VT8500_GPIO_MUX_REG) | 1, 104 + gpio_base + VT8500_GPIO_MUX_REG); 105 + iounmap(gpio_base); 106 + } else 107 + pr_err("%s: Could not remap GPIO mux\n", __func__); 108 + 109 + of_node_put(fb); 110 + } 111 + #endif 112 + 113 + #ifdef CONFIG_FB_WM8505 114 + fb = of_find_compatible_node(NULL, NULL, "wm,wm8505-fb"); 115 + if (fb) { 116 + np = of_find_compatible_node(NULL, NULL, "wm,wm8505-gpio"); 117 + if (!np) 118 + np = of_find_compatible_node(NULL, NULL, 119 + "wm,wm8650-gpio"); 120 + if (np) { 121 + gpio_base = of_iomap(np, 0); 122 + 123 + if (!gpio_base) 124 + pr_err("%s: of_iomap(gpio_mux) failed\n", 125 + __func__); 126 + 127 + of_node_put(np); 128 + } else { 129 + gpio_base = ioremap(LEGACY_GPIO_BASE, 0x1000); 130 + if (!gpio_base) 131 + pr_err("%s: ioremap(legacy_gpio_mux) failed\n", 132 + __func__); 133 + } 134 + if (gpio_base) { 135 + writel(readl(gpio_base + VT8500_GPIO_MUX_REG) | 136 + 0x80000000, gpio_base + VT8500_GPIO_MUX_REG); 137 + iounmap(gpio_base); 138 + } else 139 + pr_err("%s: Could not remap GPIO mux\n", __func__); 140 + 141 + of_node_put(fb); 142 + } 143 + #endif 144 + 145 + np = of_find_compatible_node(NULL, NULL, "via,vt8500-pmc"); 146 + if (np) { 147 + pmc_base = of_iomap(np, 0); 148 + 149 + if (!pmc_base) 150 + pr_err("%s:of_iomap(pmc) failed\n", __func__); 151 + 152 + of_node_put(np); 153 + } else { 154 + pmc_base = ioremap(LEGACY_PMC_BASE, 0x1000); 155 + if (!pmc_base) 156 + pr_err("%s:ioremap(power_off) failed\n", __func__); 157 + } 158 + if (pmc_base) 159 + pm_power_off = &vt8500_power_off; 160 + else 161 + pr_err("%s: PMC Hibernation register could not be remapped, not enabling power off!\n", __func__); 162 + 163 + vtwm_clk_init(pmc_base); 164 + 165 + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); 166 + } 167 + 168 + static const struct of_device_id vt8500_irq_match[] __initconst = { 169 + { .compatible = "via,vt8500-intc", .data = vt8500_irq_init, }, 170 + { /* sentinel */ }, 171 + }; 172 + 173 + static void __init vt8500_init_irq(void) 174 + { 175 + of_irq_init(vt8500_irq_match); 176 + }; 177 + 178 + static struct sys_timer vt8500_timer = { 179 + .init = vt8500_timer_init, 180 + }; 181 + 182 + static const char * const vt8500_dt_compat[] = { 183 + "via,vt8500", 184 + "wm,wm8650", 185 + "wm,wm8505", 186 + }; 187 + 188 + DT_MACHINE_START(WMT_DT, "VIA/Wondermedia SoC (Device Tree Support)") 189 + .dt_compat = vt8500_dt_compat, 190 + .map_io = vt8500_map_io, 191 + .init_irq = vt8500_init_irq, 192 + .timer = &vt8500_timer, 193 + .init_machine = vt8500_init, 194 + .restart = vt8500_restart, 195 + MACHINE_END 196 +
-79
arch/arm/mach-vt8500/wm8505_7in.c
··· 1 - /* 2 - * arch/arm/mach-vt8500/wm8505_7in.c 3 - * 4 - * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> 5 - * 6 - * This program is free software; you can redistribute it and/or modify 7 - * it under the terms of the GNU General Public License as published by 8 - * the Free Software Foundation; either version 2 of the License, or 9 - * (at your option) any later version. 10 - * 11 - * This program is distributed in the hope that it will be useful, 12 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 - * GNU General Public License for more details. 15 - * 16 - * You should have received a copy of the GNU General Public License 17 - * along with this program; if not, write to the Free Software 18 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 - */ 20 - 21 - #include <linux/io.h> 22 - #include <linux/pm.h> 23 - 24 - #include <asm/mach-types.h> 25 - #include <asm/mach/arch.h> 26 - #include <mach/restart.h> 27 - 28 - #include "devices.h" 29 - 30 - static void __iomem *pmc_hiber; 31 - 32 - static struct platform_device *devices[] __initdata = { 33 - &vt8500_device_uart0, 34 - &vt8500_device_ehci, 35 - &vt8500_device_wm8505_fb, 36 - &vt8500_device_ge_rops, 37 - &vt8500_device_pwm, 38 - &vt8500_device_pwmbl, 39 - &vt8500_device_rtc, 40 - }; 41 - 42 - static void vt8500_power_off(void) 43 - { 44 - local_irq_disable(); 45 - writew(5, pmc_hiber); 46 - asm("mcr%? p15, 0, %0, c7, c0, 4" : : "r" (0)); 47 - } 48 - 49 - void __init wm8505_7in_init(void) 50 - { 51 - #ifdef CONFIG_FB_WM8505 52 - void __iomem *gpio_mux_reg = ioremap(wmt_gpio_base + 0x200, 4); 53 - if (gpio_mux_reg) { 54 - writel(readl(gpio_mux_reg) | 0x80000000, gpio_mux_reg); 55 - iounmap(gpio_mux_reg); 56 - } else { 57 - printk(KERN_ERR "Could not remap the GPIO mux register, display may not work properly!\n"); 58 - } 59 - #endif 60 - pmc_hiber = ioremap(wmt_pmc_base + 0x12, 2); 61 - if (pmc_hiber) 62 - pm_power_off = &vt8500_power_off; 63 - else 64 - printk(KERN_ERR "PMC Hibernation register could not be remapped, not enabling power off!\n"); 65 - wmt_setup_restart(); 66 - wm8505_set_resources(); 67 - platform_add_devices(devices, ARRAY_SIZE(devices)); 68 - vt8500_gpio_init(); 69 - } 70 - 71 - MACHINE_START(WM8505_7IN_NETBOOK, "WM8505 7-inch generic netbook") 72 - .atag_offset = 0x100, 73 - .restart = wmt_restart, 74 - .reserve = wm8505_reserve_mem, 75 - .map_io = wm8505_map_io, 76 - .init_irq = wm8505_init_irq, 77 - .timer = &vt8500_timer, 78 - .init_machine = wm8505_7in_init, 79 - MACHINE_END
+1
drivers/clk/Makefile
··· 16 16 endif 17 17 obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o 18 18 obj-$(CONFIG_ARCH_U8500) += ux500/ 19 + obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o 19 20 20 21 # Chip specific 21 22 obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
+510
drivers/clk/clk-vt8500.c
··· 1 + /* 2 + * Clock implementation for VIA/Wondermedia SoC's 3 + * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz> 4 + * 5 + * This software is licensed under the terms of the GNU General Public 6 + * License version 2, as published by the Free Software Foundation, and 7 + * may be copied, distributed, and modified under those terms. 8 + * 9 + * This program is distributed in the hope that it will be useful, 10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 + * GNU General Public License for more details. 13 + * 14 + */ 15 + 16 + #include <linux/io.h> 17 + #include <linux/of.h> 18 + #include <linux/slab.h> 19 + #include <linux/bitops.h> 20 + #include <linux/clkdev.h> 21 + #include <linux/clk-provider.h> 22 + 23 + /* All clocks share the same lock as none can be changed concurrently */ 24 + static DEFINE_SPINLOCK(_lock); 25 + 26 + struct clk_device { 27 + struct clk_hw hw; 28 + void __iomem *div_reg; 29 + unsigned int div_mask; 30 + void __iomem *en_reg; 31 + int en_bit; 32 + spinlock_t *lock; 33 + }; 34 + 35 + /* 36 + * Add new PLL_TYPE_x definitions here as required. Use the first known model 37 + * to support the new type as the name. 38 + * Add case statements to vtwm_pll_recalc_rate(), vtwm_pll_round_round() and 39 + * vtwm_pll_set_rate() to handle the new PLL_TYPE_x 40 + */ 41 + 42 + #define PLL_TYPE_VT8500 0 43 + #define PLL_TYPE_WM8650 1 44 + 45 + struct clk_pll { 46 + struct clk_hw hw; 47 + void __iomem *reg; 48 + spinlock_t *lock; 49 + int type; 50 + }; 51 + 52 + static void __iomem *pmc_base; 53 + 54 + #define to_clk_device(_hw) container_of(_hw, struct clk_device, hw) 55 + 56 + #define VT8500_PMC_BUSY_MASK 0x18 57 + 58 + static void vt8500_pmc_wait_busy(void) 59 + { 60 + while (readl(pmc_base) & VT8500_PMC_BUSY_MASK) 61 + cpu_relax(); 62 + } 63 + 64 + static int vt8500_dclk_enable(struct clk_hw *hw) 65 + { 66 + struct clk_device *cdev = to_clk_device(hw); 67 + u32 en_val; 68 + unsigned long flags = 0; 69 + 70 + spin_lock_irqsave(cdev->lock, flags); 71 + 72 + en_val = readl(cdev->en_reg); 73 + en_val |= BIT(cdev->en_bit); 74 + writel(en_val, cdev->en_reg); 75 + 76 + spin_unlock_irqrestore(cdev->lock, flags); 77 + return 0; 78 + } 79 + 80 + static void vt8500_dclk_disable(struct clk_hw *hw) 81 + { 82 + struct clk_device *cdev = to_clk_device(hw); 83 + u32 en_val; 84 + unsigned long flags = 0; 85 + 86 + spin_lock_irqsave(cdev->lock, flags); 87 + 88 + en_val = readl(cdev->en_reg); 89 + en_val &= ~BIT(cdev->en_bit); 90 + writel(en_val, cdev->en_reg); 91 + 92 + spin_unlock_irqrestore(cdev->lock, flags); 93 + } 94 + 95 + static int vt8500_dclk_is_enabled(struct clk_hw *hw) 96 + { 97 + struct clk_device *cdev = to_clk_device(hw); 98 + u32 en_val = (readl(cdev->en_reg) & BIT(cdev->en_bit)); 99 + 100 + return en_val ? 1 : 0; 101 + } 102 + 103 + static unsigned long vt8500_dclk_recalc_rate(struct clk_hw *hw, 104 + unsigned long parent_rate) 105 + { 106 + struct clk_device *cdev = to_clk_device(hw); 107 + u32 div = readl(cdev->div_reg) & cdev->div_mask; 108 + 109 + /* Special case for SDMMC devices */ 110 + if ((cdev->div_mask == 0x3F) && (div & BIT(5))) 111 + div = 64 * (div & 0x1f); 112 + 113 + /* div == 0 is actually the highest divisor */ 114 + if (div == 0) 115 + div = (cdev->div_mask + 1); 116 + 117 + return parent_rate / div; 118 + } 119 + 120 + static long vt8500_dclk_round_rate(struct clk_hw *hw, unsigned long rate, 121 + unsigned long *prate) 122 + { 123 + u32 divisor = *prate / rate; 124 + 125 + return *prate / divisor; 126 + } 127 + 128 + static int vt8500_dclk_set_rate(struct clk_hw *hw, unsigned long rate, 129 + unsigned long parent_rate) 130 + { 131 + struct clk_device *cdev = to_clk_device(hw); 132 + u32 divisor = parent_rate / rate; 133 + unsigned long flags = 0; 134 + 135 + if (divisor == cdev->div_mask + 1) 136 + divisor = 0; 137 + 138 + if (divisor > cdev->div_mask) { 139 + pr_err("%s: invalid divisor for clock\n", __func__); 140 + return -EINVAL; 141 + } 142 + 143 + spin_lock_irqsave(cdev->lock, flags); 144 + 145 + vt8500_pmc_wait_busy(); 146 + writel(divisor, cdev->div_reg); 147 + vt8500_pmc_wait_busy(); 148 + 149 + spin_lock_irqsave(cdev->lock, flags); 150 + 151 + return 0; 152 + } 153 + 154 + 155 + static const struct clk_ops vt8500_gated_clk_ops = { 156 + .enable = vt8500_dclk_enable, 157 + .disable = vt8500_dclk_disable, 158 + .is_enabled = vt8500_dclk_is_enabled, 159 + }; 160 + 161 + static const struct clk_ops vt8500_divisor_clk_ops = { 162 + .round_rate = vt8500_dclk_round_rate, 163 + .set_rate = vt8500_dclk_set_rate, 164 + .recalc_rate = vt8500_dclk_recalc_rate, 165 + }; 166 + 167 + static const struct clk_ops vt8500_gated_divisor_clk_ops = { 168 + .enable = vt8500_dclk_enable, 169 + .disable = vt8500_dclk_disable, 170 + .is_enabled = vt8500_dclk_is_enabled, 171 + .round_rate = vt8500_dclk_round_rate, 172 + .set_rate = vt8500_dclk_set_rate, 173 + .recalc_rate = vt8500_dclk_recalc_rate, 174 + }; 175 + 176 + #define CLK_INIT_GATED BIT(0) 177 + #define CLK_INIT_DIVISOR BIT(1) 178 + #define CLK_INIT_GATED_DIVISOR (CLK_INIT_DIVISOR | CLK_INIT_GATED) 179 + 180 + static __init void vtwm_device_clk_init(struct device_node *node) 181 + { 182 + u32 en_reg, div_reg; 183 + struct clk *clk; 184 + struct clk_device *dev_clk; 185 + const char *clk_name = node->name; 186 + const char *parent_name; 187 + struct clk_init_data init; 188 + int rc; 189 + int clk_init_flags = 0; 190 + 191 + dev_clk = kzalloc(sizeof(*dev_clk), GFP_KERNEL); 192 + if (WARN_ON(!dev_clk)) 193 + return; 194 + 195 + dev_clk->lock = &_lock; 196 + 197 + rc = of_property_read_u32(node, "enable-reg", &en_reg); 198 + if (!rc) { 199 + dev_clk->en_reg = pmc_base + en_reg; 200 + rc = of_property_read_u32(node, "enable-bit", &dev_clk->en_bit); 201 + if (rc) { 202 + pr_err("%s: enable-bit property required for gated clock\n", 203 + __func__); 204 + return; 205 + } 206 + clk_init_flags |= CLK_INIT_GATED; 207 + } 208 + 209 + rc = of_property_read_u32(node, "divisor-reg", &div_reg); 210 + if (!rc) { 211 + dev_clk->div_reg = pmc_base + div_reg; 212 + /* 213 + * use 0x1f as the default mask since it covers 214 + * almost all the clocks and reduces dts properties 215 + */ 216 + dev_clk->div_mask = 0x1f; 217 + 218 + of_property_read_u32(node, "divisor-mask", &dev_clk->div_mask); 219 + clk_init_flags |= CLK_INIT_DIVISOR; 220 + } 221 + 222 + of_property_read_string(node, "clock-output-names", &clk_name); 223 + 224 + switch (clk_init_flags) { 225 + case CLK_INIT_GATED: 226 + init.ops = &vt8500_gated_clk_ops; 227 + break; 228 + case CLK_INIT_DIVISOR: 229 + init.ops = &vt8500_divisor_clk_ops; 230 + break; 231 + case CLK_INIT_GATED_DIVISOR: 232 + init.ops = &vt8500_gated_divisor_clk_ops; 233 + break; 234 + default: 235 + pr_err("%s: Invalid clock description in device tree\n", 236 + __func__); 237 + kfree(dev_clk); 238 + return; 239 + } 240 + 241 + init.name = clk_name; 242 + init.flags = 0; 243 + parent_name = of_clk_get_parent_name(node, 0); 244 + init.parent_names = &parent_name; 245 + init.num_parents = 1; 246 + 247 + dev_clk->hw.init = &init; 248 + 249 + clk = clk_register(NULL, &dev_clk->hw); 250 + if (WARN_ON(IS_ERR(clk))) { 251 + kfree(dev_clk); 252 + return; 253 + } 254 + rc = of_clk_add_provider(node, of_clk_src_simple_get, clk); 255 + clk_register_clkdev(clk, clk_name, NULL); 256 + } 257 + 258 + 259 + /* PLL clock related functions */ 260 + 261 + #define to_clk_pll(_hw) container_of(_hw, struct clk_pll, hw) 262 + 263 + /* Helper macros for PLL_VT8500 */ 264 + #define VT8500_PLL_MUL(x) ((x & 0x1F) << 1) 265 + #define VT8500_PLL_DIV(x) ((x & 0x100) ? 1 : 2) 266 + 267 + #define VT8500_BITS_TO_FREQ(r, m, d) \ 268 + ((r / d) * m) 269 + 270 + #define VT8500_BITS_TO_VAL(m, d) \ 271 + ((d == 2 ? 0 : 0x100) | ((m >> 1) & 0x1F)) 272 + 273 + /* Helper macros for PLL_WM8650 */ 274 + #define WM8650_PLL_MUL(x) (x & 0x3FF) 275 + #define WM8650_PLL_DIV(x) (((x >> 10) & 7) * (1 << ((x >> 13) & 3))) 276 + 277 + #define WM8650_BITS_TO_FREQ(r, m, d1, d2) \ 278 + (r * m / (d1 * (1 << d2))) 279 + 280 + #define WM8650_BITS_TO_VAL(m, d1, d2) \ 281 + ((d2 << 13) | (d1 << 10) | (m & 0x3FF)) 282 + 283 + 284 + static void vt8500_find_pll_bits(unsigned long rate, unsigned long parent_rate, 285 + u32 *multiplier, u32 *prediv) 286 + { 287 + unsigned long tclk; 288 + 289 + /* sanity check */ 290 + if ((rate < parent_rate * 4) || (rate > parent_rate * 62)) { 291 + pr_err("%s: requested rate out of range\n", __func__); 292 + *multiplier = 0; 293 + *prediv = 1; 294 + return; 295 + } 296 + if (rate <= parent_rate * 31) 297 + /* use the prediv to double the resolution */ 298 + *prediv = 2; 299 + else 300 + *prediv = 1; 301 + 302 + *multiplier = rate / (parent_rate / *prediv); 303 + tclk = (parent_rate / *prediv) * *multiplier; 304 + 305 + if (tclk != rate) 306 + pr_warn("%s: requested rate %lu, found rate %lu\n", __func__, 307 + rate, tclk); 308 + } 309 + 310 + static void wm8650_find_pll_bits(unsigned long rate, unsigned long parent_rate, 311 + u32 *multiplier, u32 *divisor1, u32 *divisor2) 312 + { 313 + u32 mul, div1, div2; 314 + u32 best_mul, best_div1, best_div2; 315 + unsigned long tclk, rate_err, best_err; 316 + 317 + best_err = (unsigned long)-1; 318 + 319 + /* Find the closest match (lower or equal to requested) */ 320 + for (div1 = 5; div1 >= 3; div1--) 321 + for (div2 = 3; div2 >= 0; div2--) 322 + for (mul = 3; mul <= 1023; mul++) { 323 + tclk = parent_rate * mul / (div1 * (1 << div2)); 324 + if (tclk > rate) 325 + continue; 326 + /* error will always be +ve */ 327 + rate_err = rate - tclk; 328 + if (rate_err == 0) { 329 + *multiplier = mul; 330 + *divisor1 = div1; 331 + *divisor2 = div2; 332 + return; 333 + } 334 + 335 + if (rate_err < best_err) { 336 + best_err = rate_err; 337 + best_mul = mul; 338 + best_div1 = div1; 339 + best_div2 = div2; 340 + } 341 + } 342 + 343 + /* if we got here, it wasn't an exact match */ 344 + pr_warn("%s: requested rate %lu, found rate %lu\n", __func__, rate, 345 + rate - best_err); 346 + *multiplier = mul; 347 + *divisor1 = div1; 348 + *divisor2 = div2; 349 + } 350 + 351 + static int vtwm_pll_set_rate(struct clk_hw *hw, unsigned long rate, 352 + unsigned long parent_rate) 353 + { 354 + struct clk_pll *pll = to_clk_pll(hw); 355 + u32 mul, div1, div2; 356 + u32 pll_val; 357 + unsigned long flags = 0; 358 + 359 + /* sanity check */ 360 + 361 + switch (pll->type) { 362 + case PLL_TYPE_VT8500: 363 + vt8500_find_pll_bits(rate, parent_rate, &mul, &div1); 364 + pll_val = VT8500_BITS_TO_VAL(mul, div1); 365 + break; 366 + case PLL_TYPE_WM8650: 367 + wm8650_find_pll_bits(rate, parent_rate, &mul, &div1, &div2); 368 + pll_val = WM8650_BITS_TO_VAL(mul, div1, div2); 369 + break; 370 + default: 371 + pr_err("%s: invalid pll type\n", __func__); 372 + return 0; 373 + } 374 + 375 + spin_lock_irqsave(pll->lock, flags); 376 + 377 + vt8500_pmc_wait_busy(); 378 + writel(pll_val, pll->reg); 379 + vt8500_pmc_wait_busy(); 380 + 381 + spin_unlock_irqrestore(pll->lock, flags); 382 + 383 + return 0; 384 + } 385 + 386 + static long vtwm_pll_round_rate(struct clk_hw *hw, unsigned long rate, 387 + unsigned long *prate) 388 + { 389 + struct clk_pll *pll = to_clk_pll(hw); 390 + u32 mul, div1, div2; 391 + long round_rate; 392 + 393 + switch (pll->type) { 394 + case PLL_TYPE_VT8500: 395 + vt8500_find_pll_bits(rate, *prate, &mul, &div1); 396 + round_rate = VT8500_BITS_TO_FREQ(*prate, mul, div1); 397 + break; 398 + case PLL_TYPE_WM8650: 399 + wm8650_find_pll_bits(rate, *prate, &mul, &div1, &div2); 400 + round_rate = WM8650_BITS_TO_FREQ(*prate, mul, div1, div2); 401 + break; 402 + default: 403 + round_rate = 0; 404 + } 405 + 406 + return round_rate; 407 + } 408 + 409 + static unsigned long vtwm_pll_recalc_rate(struct clk_hw *hw, 410 + unsigned long parent_rate) 411 + { 412 + struct clk_pll *pll = to_clk_pll(hw); 413 + u32 pll_val = readl(pll->reg); 414 + unsigned long pll_freq; 415 + 416 + switch (pll->type) { 417 + case PLL_TYPE_VT8500: 418 + pll_freq = parent_rate * VT8500_PLL_MUL(pll_val); 419 + pll_freq /= VT8500_PLL_DIV(pll_val); 420 + break; 421 + case PLL_TYPE_WM8650: 422 + pll_freq = parent_rate * WM8650_PLL_MUL(pll_val); 423 + pll_freq /= WM8650_PLL_DIV(pll_val); 424 + break; 425 + default: 426 + pll_freq = 0; 427 + } 428 + 429 + return pll_freq; 430 + } 431 + 432 + const struct clk_ops vtwm_pll_ops = { 433 + .round_rate = vtwm_pll_round_rate, 434 + .set_rate = vtwm_pll_set_rate, 435 + .recalc_rate = vtwm_pll_recalc_rate, 436 + }; 437 + 438 + static __init void vtwm_pll_clk_init(struct device_node *node, int pll_type) 439 + { 440 + u32 reg; 441 + struct clk *clk; 442 + struct clk_pll *pll_clk; 443 + const char *clk_name = node->name; 444 + const char *parent_name; 445 + struct clk_init_data init; 446 + int rc; 447 + 448 + rc = of_property_read_u32(node, "reg", &reg); 449 + if (WARN_ON(rc)) 450 + return; 451 + 452 + pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL); 453 + if (WARN_ON(!pll_clk)) 454 + return; 455 + 456 + pll_clk->reg = pmc_base + reg; 457 + pll_clk->lock = &_lock; 458 + pll_clk->type = pll_type; 459 + 460 + of_property_read_string(node, "clock-output-names", &clk_name); 461 + 462 + init.name = clk_name; 463 + init.ops = &vtwm_pll_ops; 464 + init.flags = 0; 465 + parent_name = of_clk_get_parent_name(node, 0); 466 + init.parent_names = &parent_name; 467 + init.num_parents = 1; 468 + 469 + pll_clk->hw.init = &init; 470 + 471 + clk = clk_register(NULL, &pll_clk->hw); 472 + if (WARN_ON(IS_ERR(clk))) { 473 + kfree(pll_clk); 474 + return; 475 + } 476 + rc = of_clk_add_provider(node, of_clk_src_simple_get, clk); 477 + clk_register_clkdev(clk, clk_name, NULL); 478 + } 479 + 480 + 481 + /* Wrappers for initialization functions */ 482 + 483 + static void __init vt8500_pll_init(struct device_node *node) 484 + { 485 + vtwm_pll_clk_init(node, PLL_TYPE_VT8500); 486 + } 487 + 488 + static void __init wm8650_pll_init(struct device_node *node) 489 + { 490 + vtwm_pll_clk_init(node, PLL_TYPE_WM8650); 491 + } 492 + 493 + static const __initconst struct of_device_id clk_match[] = { 494 + { .compatible = "fixed-clock", .data = of_fixed_clk_setup, }, 495 + { .compatible = "via,vt8500-pll-clock", .data = vt8500_pll_init, }, 496 + { .compatible = "wm,wm8650-pll-clock", .data = wm8650_pll_init, }, 497 + { .compatible = "via,vt8500-device-clock", 498 + .data = vtwm_device_clk_init, }, 499 + { /* sentinel */ } 500 + }; 501 + 502 + void __init vtwm_clk_init(void __iomem *base) 503 + { 504 + if (!base) 505 + return; 506 + 507 + pmc_base = base; 508 + 509 + of_clk_init(clk_match); 510 + }
+6
drivers/gpio/Kconfig
··· 183 183 Say yes here to support the STA2x11/ConneXt GPIO device. 184 184 The GPIO module has 128 GPIO pins with alternate functions. 185 185 186 + config GPIO_VT8500 187 + bool "VIA/Wondermedia SoC GPIO Support" 188 + depends on ARCH_VT8500 189 + help 190 + Say yes here to support the VT8500/WM8505/WM8650 GPIO controller. 191 + 186 192 config GPIO_XILINX 187 193 bool "Xilinx GPIO support" 188 194 depends on PPC_OF || MICROBLAZE
+1
drivers/gpio/Makefile
··· 69 69 obj-$(CONFIG_GPIO_TWL4030) += gpio-twl4030.o 70 70 obj-$(CONFIG_GPIO_UCB1400) += gpio-ucb1400.o 71 71 obj-$(CONFIG_GPIO_VR41XX) += gpio-vr41xx.o 72 + obj-$(CONFIG_GPIO_VT8500) += gpio-vt8500.o 72 73 obj-$(CONFIG_GPIO_VX855) += gpio-vx855.o 73 74 obj-$(CONFIG_GPIO_WM831X) += gpio-wm831x.o 74 75 obj-$(CONFIG_GPIO_WM8350) += gpio-wm8350.o
+316
drivers/gpio/gpio-vt8500.c
··· 1 + /* drivers/gpio/gpio-vt8500.c 2 + * 3 + * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz> 4 + * Based on arch/arm/mach-vt8500/gpio.c: 5 + * - Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> 6 + * 7 + * This software is licensed under the terms of the GNU General Public 8 + * License version 2, as published by the Free Software Foundation, and 9 + * may be copied, distributed, and modified under those terms. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + */ 17 + 18 + #include <linux/module.h> 19 + #include <linux/err.h> 20 + #include <linux/io.h> 21 + #include <linux/gpio.h> 22 + #include <linux/platform_device.h> 23 + #include <linux/bitops.h> 24 + #include <linux/of.h> 25 + #include <linux/of_address.h> 26 + #include <linux/of_irq.h> 27 + #include <linux/of_device.h> 28 + 29 + /* 30 + We handle GPIOs by bank, each bank containing up to 32 GPIOs covered 31 + by one set of registers (although not all may be valid). 32 + 33 + Because different SoC's have different register offsets, we pass the 34 + register offsets as data in vt8500_gpio_dt_ids[]. 35 + 36 + A value of NO_REG is used to indicate that this register is not 37 + supported. Only used for ->en at the moment. 38 + */ 39 + 40 + #define NO_REG 0xFFFF 41 + 42 + /* 43 + * struct vt8500_gpio_bank_regoffsets 44 + * @en: offset to enable register of the bank 45 + * @dir: offset to direction register of the bank 46 + * @data_out: offset to the data out register of the bank 47 + * @data_in: offset to the data in register of the bank 48 + * @ngpio: highest valid pin in this bank 49 + */ 50 + 51 + struct vt8500_gpio_bank_regoffsets { 52 + unsigned int en; 53 + unsigned int dir; 54 + unsigned int data_out; 55 + unsigned int data_in; 56 + unsigned char ngpio; 57 + }; 58 + 59 + struct vt8500_gpio_data { 60 + unsigned int num_banks; 61 + struct vt8500_gpio_bank_regoffsets banks[]; 62 + }; 63 + 64 + #define VT8500_BANK(__en, __dir, __out, __in, __ngpio) \ 65 + { \ 66 + .en = __en, \ 67 + .dir = __dir, \ 68 + .data_out = __out, \ 69 + .data_in = __in, \ 70 + .ngpio = __ngpio, \ 71 + } 72 + 73 + static struct vt8500_gpio_data vt8500_data = { 74 + .num_banks = 7, 75 + .banks = { 76 + VT8500_BANK(0x00, 0x20, 0x40, 0x60, 26), 77 + VT8500_BANK(0x04, 0x24, 0x44, 0x64, 28), 78 + VT8500_BANK(0x08, 0x28, 0x48, 0x68, 31), 79 + VT8500_BANK(0x0C, 0x2C, 0x4C, 0x6C, 19), 80 + VT8500_BANK(0x10, 0x30, 0x50, 0x70, 19), 81 + VT8500_BANK(0x14, 0x34, 0x54, 0x74, 23), 82 + VT8500_BANK(NO_REG, 0x3C, 0x5C, 0x7C, 9), 83 + }, 84 + }; 85 + 86 + static struct vt8500_gpio_data wm8505_data = { 87 + .num_banks = 10, 88 + .banks = { 89 + VT8500_BANK(0x40, 0x68, 0x90, 0xB8, 8), 90 + VT8500_BANK(0x44, 0x6C, 0x94, 0xBC, 32), 91 + VT8500_BANK(0x48, 0x70, 0x98, 0xC0, 6), 92 + VT8500_BANK(0x4C, 0x74, 0x9C, 0xC4, 16), 93 + VT8500_BANK(0x50, 0x78, 0xA0, 0xC8, 25), 94 + VT8500_BANK(0x54, 0x7C, 0xA4, 0xCC, 5), 95 + VT8500_BANK(0x58, 0x80, 0xA8, 0xD0, 5), 96 + VT8500_BANK(0x5C, 0x84, 0xAC, 0xD4, 12), 97 + VT8500_BANK(0x60, 0x88, 0xB0, 0xD8, 16), 98 + VT8500_BANK(0x64, 0x8C, 0xB4, 0xDC, 22), 99 + }, 100 + }; 101 + 102 + /* 103 + * No information about which bits are valid so we just make 104 + * them all available until its figured out. 105 + */ 106 + static struct vt8500_gpio_data wm8650_data = { 107 + .num_banks = 9, 108 + .banks = { 109 + VT8500_BANK(0x40, 0x80, 0xC0, 0x00, 32), 110 + VT8500_BANK(0x44, 0x84, 0xC4, 0x04, 32), 111 + VT8500_BANK(0x48, 0x88, 0xC8, 0x08, 32), 112 + VT8500_BANK(0x4C, 0x8C, 0xCC, 0x0C, 32), 113 + VT8500_BANK(0x50, 0x90, 0xD0, 0x10, 32), 114 + VT8500_BANK(0x54, 0x94, 0xD4, 0x14, 32), 115 + VT8500_BANK(0x58, 0x98, 0xD8, 0x18, 32), 116 + VT8500_BANK(0x5C, 0x9C, 0xDC, 0x1C, 32), 117 + VT8500_BANK(0x7C, 0xBC, 0xFC, 0x3C, 32), 118 + }, 119 + }; 120 + 121 + struct vt8500_gpio_chip { 122 + struct gpio_chip chip; 123 + 124 + const struct vt8500_gpio_bank_regoffsets *regs; 125 + void __iomem *base; 126 + }; 127 + 128 + 129 + #define to_vt8500(__chip) container_of(__chip, struct vt8500_gpio_chip, chip) 130 + 131 + static int vt8500_gpio_request(struct gpio_chip *chip, unsigned offset) 132 + { 133 + u32 val; 134 + struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip); 135 + 136 + if (vt8500_chip->regs->en == NO_REG) 137 + return 0; 138 + 139 + val = readl_relaxed(vt8500_chip->base + vt8500_chip->regs->en); 140 + val |= BIT(offset); 141 + writel_relaxed(val, vt8500_chip->base + vt8500_chip->regs->en); 142 + 143 + return 0; 144 + } 145 + 146 + static void vt8500_gpio_free(struct gpio_chip *chip, unsigned offset) 147 + { 148 + struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip); 149 + u32 val; 150 + 151 + if (vt8500_chip->regs->en == NO_REG) 152 + return; 153 + 154 + val = readl_relaxed(vt8500_chip->base + vt8500_chip->regs->en); 155 + val &= ~BIT(offset); 156 + writel_relaxed(val, vt8500_chip->base + vt8500_chip->regs->en); 157 + } 158 + 159 + static int vt8500_gpio_direction_input(struct gpio_chip *chip, unsigned offset) 160 + { 161 + struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip); 162 + 163 + u32 val = readl_relaxed(vt8500_chip->base + vt8500_chip->regs->dir); 164 + val &= ~BIT(offset); 165 + writel_relaxed(val, vt8500_chip->base + vt8500_chip->regs->dir); 166 + 167 + return 0; 168 + } 169 + 170 + static int vt8500_gpio_direction_output(struct gpio_chip *chip, unsigned offset, 171 + int value) 172 + { 173 + struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip); 174 + 175 + u32 val = readl_relaxed(vt8500_chip->base + vt8500_chip->regs->dir); 176 + val |= BIT(offset); 177 + writel_relaxed(val, vt8500_chip->base + vt8500_chip->regs->dir); 178 + 179 + if (value) { 180 + val = readl_relaxed(vt8500_chip->base + 181 + vt8500_chip->regs->data_out); 182 + val |= BIT(offset); 183 + writel_relaxed(val, vt8500_chip->base + 184 + vt8500_chip->regs->data_out); 185 + } 186 + return 0; 187 + } 188 + 189 + static int vt8500_gpio_get_value(struct gpio_chip *chip, unsigned offset) 190 + { 191 + struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip); 192 + 193 + return (readl_relaxed(vt8500_chip->base + vt8500_chip->regs->data_in) >> 194 + offset) & 1; 195 + } 196 + 197 + static void vt8500_gpio_set_value(struct gpio_chip *chip, unsigned offset, 198 + int value) 199 + { 200 + struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip); 201 + 202 + u32 val = readl_relaxed(vt8500_chip->base + 203 + vt8500_chip->regs->data_out); 204 + if (value) 205 + val |= BIT(offset); 206 + else 207 + val &= ~BIT(offset); 208 + 209 + writel_relaxed(val, vt8500_chip->base + vt8500_chip->regs->data_out); 210 + } 211 + 212 + static int vt8500_of_xlate(struct gpio_chip *gc, 213 + const struct of_phandle_args *gpiospec, u32 *flags) 214 + { 215 + /* bank if specificed in gpiospec->args[0] */ 216 + if (flags) 217 + *flags = gpiospec->args[2]; 218 + 219 + return gpiospec->args[1]; 220 + } 221 + 222 + static int vt8500_add_chips(struct platform_device *pdev, void __iomem *base, 223 + const struct vt8500_gpio_data *data) 224 + { 225 + struct vt8500_gpio_chip *vtchip; 226 + struct gpio_chip *chip; 227 + int i; 228 + int pin_cnt = 0; 229 + 230 + vtchip = devm_kzalloc(&pdev->dev, 231 + sizeof(struct vt8500_gpio_chip) * data->num_banks, 232 + GFP_KERNEL); 233 + if (!vtchip) { 234 + pr_err("%s: failed to allocate chip memory\n", __func__); 235 + return -ENOMEM; 236 + } 237 + 238 + for (i = 0; i < data->num_banks; i++) { 239 + vtchip[i].base = base; 240 + vtchip[i].regs = &data->banks[i]; 241 + 242 + chip = &vtchip[i].chip; 243 + 244 + chip->of_xlate = vt8500_of_xlate; 245 + chip->of_gpio_n_cells = 3; 246 + chip->of_node = pdev->dev.of_node; 247 + 248 + chip->request = vt8500_gpio_request; 249 + chip->free = vt8500_gpio_free; 250 + chip->direction_input = vt8500_gpio_direction_input; 251 + chip->direction_output = vt8500_gpio_direction_output; 252 + chip->get = vt8500_gpio_get_value; 253 + chip->set = vt8500_gpio_set_value; 254 + chip->can_sleep = 0; 255 + chip->base = pin_cnt; 256 + chip->ngpio = data->banks[i].ngpio; 257 + 258 + pin_cnt += data->banks[i].ngpio; 259 + 260 + gpiochip_add(chip); 261 + } 262 + return 0; 263 + } 264 + 265 + static struct of_device_id vt8500_gpio_dt_ids[] = { 266 + { .compatible = "via,vt8500-gpio", .data = &vt8500_data, }, 267 + { .compatible = "wm,wm8505-gpio", .data = &wm8505_data, }, 268 + { .compatible = "wm,wm8650-gpio", .data = &wm8650_data, }, 269 + { /* Sentinel */ }, 270 + }; 271 + 272 + static int __devinit vt8500_gpio_probe(struct platform_device *pdev) 273 + { 274 + void __iomem *gpio_base; 275 + struct device_node *np; 276 + const struct of_device_id *of_id = 277 + of_match_device(vt8500_gpio_dt_ids, &pdev->dev); 278 + 279 + if (!of_id) { 280 + dev_err(&pdev->dev, "Failed to find gpio controller\n"); 281 + return -ENODEV; 282 + } 283 + 284 + np = pdev->dev.of_node; 285 + if (!np) { 286 + dev_err(&pdev->dev, "Missing GPIO description in devicetree\n"); 287 + return -EFAULT; 288 + } 289 + 290 + gpio_base = of_iomap(np, 0); 291 + if (!gpio_base) { 292 + dev_err(&pdev->dev, "Unable to map GPIO registers\n"); 293 + of_node_put(np); 294 + return -ENOMEM; 295 + } 296 + 297 + vt8500_add_chips(pdev, gpio_base, of_id->data); 298 + 299 + return 0; 300 + } 301 + 302 + static struct platform_driver vt8500_gpio_driver = { 303 + .probe = vt8500_gpio_probe, 304 + .driver = { 305 + .name = "vt8500-gpio", 306 + .owner = THIS_MODULE, 307 + .of_match_table = vt8500_gpio_dt_ids, 308 + }, 309 + }; 310 + 311 + module_platform_driver(vt8500_gpio_driver); 312 + 313 + MODULE_DESCRIPTION("VT8500 GPIO Driver"); 314 + MODULE_AUTHOR("Tony Prisk <linux@prisktech.co.nz>"); 315 + MODULE_LICENSE("GPL v2"); 316 + MODULE_DEVICE_TABLE(of, vt8500_gpio_dt_ids);
+8 -1
drivers/rtc/rtc-vt8500.c
··· 23 23 #include <linux/bcd.h> 24 24 #include <linux/platform_device.h> 25 25 #include <linux/slab.h> 26 + #include <linux/of.h> 26 27 27 28 /* 28 29 * Register definitions ··· 303 302 return 0; 304 303 } 305 304 305 + static const struct of_device_id wmt_dt_ids[] = { 306 + { .compatible = "via,vt8500-rtc", }, 307 + {} 308 + }; 309 + 306 310 static struct platform_driver vt8500_rtc_driver = { 307 311 .probe = vt8500_rtc_probe, 308 312 .remove = __devexit_p(vt8500_rtc_remove), 309 313 .driver = { 310 314 .name = "vt8500-rtc", 311 315 .owner = THIS_MODULE, 316 + .of_match_table = of_match_ptr(wmt_dt_ids), 312 317 }, 313 318 }; 314 319 ··· 322 315 323 316 MODULE_AUTHOR("Alexey Charkov <alchark@gmail.com>"); 324 317 MODULE_DESCRIPTION("VIA VT8500 SoC Realtime Clock Driver (RTC)"); 325 - MODULE_LICENSE("GPL"); 318 + MODULE_LICENSE("GPL v2"); 326 319 MODULE_ALIAS("platform:vt8500-rtc");
+53 -5
drivers/tty/serial/vt8500_serial.c
··· 34 34 #include <linux/slab.h> 35 35 #include <linux/clk.h> 36 36 #include <linux/platform_device.h> 37 + #include <linux/of.h> 37 38 38 39 /* 39 40 * UART Register offsets ··· 77 76 #define RX_FIFO_INTS (RXFAF | RXFF | RXOVER | PER | FER | RXTOUT) 78 77 #define TX_FIFO_INTS (TXFAE | TXFE | TXUDR) 79 78 79 + #define VT8500_MAX_PORTS 6 80 + 80 81 struct vt8500_port { 81 82 struct uart_port uart; 82 83 char name[16]; 83 84 struct clk *clk; 84 85 unsigned int ier; 85 86 }; 87 + 88 + /* 89 + * we use this variable to keep track of which ports 90 + * have been allocated as we can't use pdev->id in 91 + * devicetree 92 + */ 93 + static unsigned long vt8500_ports_in_use; 86 94 87 95 static inline void vt8500_write(struct uart_port *port, unsigned int val, 88 96 unsigned int off) ··· 441 431 return 0; 442 432 } 443 433 444 - static struct vt8500_port *vt8500_uart_ports[4]; 434 + static struct vt8500_port *vt8500_uart_ports[VT8500_MAX_PORTS]; 445 435 static struct uart_driver vt8500_uart_driver; 446 436 447 437 #ifdef CONFIG_SERIAL_VT8500_CONSOLE ··· 558 548 { 559 549 struct vt8500_port *vt8500_port; 560 550 struct resource *mmres, *irqres; 551 + struct device_node *np = pdev->dev.of_node; 561 552 int ret; 553 + int port; 562 554 563 555 mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0); 564 556 irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0); ··· 571 559 if (!vt8500_port) 572 560 return -ENOMEM; 573 561 562 + if (np) 563 + port = of_alias_get_id(np, "serial"); 564 + if (port > VT8500_MAX_PORTS) 565 + port = -1; 566 + else 567 + port = -1; 568 + 569 + if (port < 0) { 570 + /* calculate the port id */ 571 + port = find_first_zero_bit(&vt8500_ports_in_use, 572 + sizeof(vt8500_ports_in_use)); 573 + } 574 + 575 + if (port > VT8500_MAX_PORTS) 576 + return -ENODEV; 577 + 578 + /* reserve the port id */ 579 + if (test_and_set_bit(port, &vt8500_ports_in_use)) { 580 + /* port already in use - shouldn't really happen */ 581 + return -EBUSY; 582 + } 583 + 574 584 vt8500_port->uart.type = PORT_VT8500; 575 585 vt8500_port->uart.iotype = UPIO_MEM; 576 586 vt8500_port->uart.mapbase = mmres->start; 577 587 vt8500_port->uart.irq = irqres->start; 578 588 vt8500_port->uart.fifosize = 16; 579 589 vt8500_port->uart.ops = &vt8500_uart_pops; 580 - vt8500_port->uart.line = pdev->id; 590 + vt8500_port->uart.line = port; 581 591 vt8500_port->uart.dev = &pdev->dev; 582 592 vt8500_port->uart.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; 583 - vt8500_port->uart.uartclk = 24000000; 593 + 594 + vt8500_port->clk = of_clk_get(pdev->dev.of_node, 0); 595 + if (vt8500_port->clk) { 596 + vt8500_port->uart.uartclk = clk_get_rate(vt8500_port->clk); 597 + } else { 598 + /* use the default of 24Mhz if not specified and warn */ 599 + pr_warn("%s: serial clock source not specified\n", __func__); 600 + vt8500_port->uart.uartclk = 24000000; 601 + } 584 602 585 603 snprintf(vt8500_port->name, sizeof(vt8500_port->name), 586 604 "VT8500 UART%d", pdev->id); ··· 621 579 goto err; 622 580 } 623 581 624 - vt8500_uart_ports[pdev->id] = vt8500_port; 582 + vt8500_uart_ports[port] = vt8500_port; 625 583 626 584 uart_add_one_port(&vt8500_uart_driver, &vt8500_port->uart); 627 585 ··· 645 603 return 0; 646 604 } 647 605 606 + static const struct of_device_id wmt_dt_ids[] = { 607 + { .compatible = "via,vt8500-uart", }, 608 + {} 609 + }; 610 + 648 611 static struct platform_driver vt8500_platform_driver = { 649 612 .probe = vt8500_serial_probe, 650 613 .remove = __devexit_p(vt8500_serial_remove), 651 614 .driver = { 652 615 .name = "vt8500_serial", 653 616 .owner = THIS_MODULE, 617 + .of_match_table = of_match_ptr(wmt_dt_ids), 654 618 }, 655 619 }; 656 620 ··· 690 642 691 643 MODULE_AUTHOR("Alexey Charkov <alchark@gmail.com>"); 692 644 MODULE_DESCRIPTION("Driver for vt8500 serial device"); 693 - MODULE_LICENSE("GPL"); 645 + MODULE_LICENSE("GPL v2");
+3 -3
drivers/video/Kconfig
··· 1788 1788 1789 1789 config FB_VT8500 1790 1790 bool "VT8500 LCD Driver" 1791 - depends on (FB = y) && ARM && ARCH_VT8500 && VTWM_VERSION_VT8500 1791 + depends on (FB = y) && ARM && ARCH_VT8500 1792 1792 select FB_WMT_GE_ROPS 1793 1793 select FB_SYS_IMAGEBLIT 1794 1794 help ··· 1797 1797 1798 1798 config FB_WM8505 1799 1799 bool "WM8505 frame buffer support" 1800 - depends on (FB = y) && ARM && ARCH_VT8500 && VTWM_VERSION_WM8505 1800 + depends on (FB = y) && ARM && ARCH_VT8500 1801 1801 select FB_WMT_GE_ROPS 1802 1802 select FB_SYS_IMAGEBLIT 1803 1803 help 1804 - This is the framebuffer driver for WonderMedia WM8505 1804 + This is the framebuffer driver for WonderMedia WM8505/WM8650 1805 1805 integrated LCD controller. 1806 1806 1807 1807 source "drivers/video/geode/Kconfig"
+68 -11
drivers/video/vt8500lcdfb.c
··· 35 35 #include "vt8500lcdfb.h" 36 36 #include "wmt_ge_rops.h" 37 37 38 + #ifdef CONFIG_OF 39 + #include <linux/of.h> 40 + #include <linux/of_fdt.h> 41 + #include <linux/memblock.h> 42 + #endif 43 + 44 + 38 45 #define to_vt8500lcd_info(__info) container_of(__info, \ 39 46 struct vt8500lcd_info, fb) 40 47 ··· 277 270 { 278 271 struct vt8500lcd_info *fbi; 279 272 struct resource *res; 280 - struct vt8500fb_platform_data *pdata = pdev->dev.platform_data; 281 273 void *addr; 282 274 int irq, ret; 275 + 276 + struct fb_videomode of_mode; 277 + struct device_node *np; 278 + u32 bpp; 279 + dma_addr_t fb_mem_phys; 280 + unsigned long fb_mem_len; 281 + void *fb_mem_virt; 283 282 284 283 ret = -ENOMEM; 285 284 fbi = NULL; 286 285 287 - fbi = kzalloc(sizeof(struct vt8500lcd_info) + sizeof(u32) * 16, 288 - GFP_KERNEL); 286 + fbi = devm_kzalloc(&pdev->dev, sizeof(struct vt8500lcd_info) 287 + + sizeof(u32) * 16, GFP_KERNEL); 289 288 if (!fbi) { 290 289 dev_err(&pdev->dev, "Failed to initialize framebuffer device\n"); 291 290 ret = -ENOMEM; ··· 346 333 goto failed_free_res; 347 334 } 348 335 349 - fbi->fb.fix.smem_start = pdata->video_mem_phys; 350 - fbi->fb.fix.smem_len = pdata->video_mem_len; 351 - fbi->fb.screen_base = pdata->video_mem_virt; 336 + np = of_parse_phandle(pdev->dev.of_node, "default-mode", 0); 337 + if (!np) { 338 + pr_err("%s: No display description in Device Tree\n", __func__); 339 + ret = -EINVAL; 340 + goto failed_free_res; 341 + } 342 + 343 + /* 344 + * This code is copied from Sascha Hauer's of_videomode helper 345 + * and can be replaced with a call to the helper once mainlined 346 + */ 347 + ret = 0; 348 + ret |= of_property_read_u32(np, "hactive", &of_mode.xres); 349 + ret |= of_property_read_u32(np, "vactive", &of_mode.yres); 350 + ret |= of_property_read_u32(np, "hback-porch", &of_mode.left_margin); 351 + ret |= of_property_read_u32(np, "hfront-porch", &of_mode.right_margin); 352 + ret |= of_property_read_u32(np, "hsync-len", &of_mode.hsync_len); 353 + ret |= of_property_read_u32(np, "vback-porch", &of_mode.upper_margin); 354 + ret |= of_property_read_u32(np, "vfront-porch", &of_mode.lower_margin); 355 + ret |= of_property_read_u32(np, "vsync-len", &of_mode.vsync_len); 356 + ret |= of_property_read_u32(np, "bpp", &bpp); 357 + if (ret) { 358 + pr_err("%s: Unable to read display properties\n", __func__); 359 + goto failed_free_res; 360 + } 361 + of_mode.vmode = FB_VMODE_NONINTERLACED; 362 + 363 + /* try allocating the framebuffer */ 364 + fb_mem_len = of_mode.xres * of_mode.yres * 2 * (bpp / 8); 365 + fb_mem_virt = dma_alloc_coherent(&pdev->dev, fb_mem_len, &fb_mem_phys, 366 + GFP_KERNEL); 367 + if (!fb_mem_virt) { 368 + pr_err("%s: Failed to allocate framebuffer\n", __func__); 369 + return -ENOMEM; 370 + }; 371 + 372 + fbi->fb.fix.smem_start = fb_mem_phys; 373 + fbi->fb.fix.smem_len = fb_mem_len; 374 + fbi->fb.screen_base = fb_mem_virt; 352 375 353 376 fbi->palette_size = PAGE_ALIGN(512); 354 377 fbi->palette_cpu = dma_alloc_coherent(&pdev->dev, ··· 419 370 goto failed_free_irq; 420 371 } 421 372 422 - fb_videomode_to_var(&fbi->fb.var, &pdata->mode); 423 - fbi->fb.var.bits_per_pixel = pdata->bpp; 424 - fbi->fb.var.xres_virtual = pdata->xres_virtual; 425 - fbi->fb.var.yres_virtual = pdata->yres_virtual; 373 + fb_videomode_to_var(&fbi->fb.var, &of_mode); 374 + 375 + fbi->fb.var.xres_virtual = of_mode.xres; 376 + fbi->fb.var.yres_virtual = of_mode.yres * 2; 377 + fbi->fb.var.bits_per_pixel = bpp; 426 378 427 379 ret = vt8500lcd_set_par(&fbi->fb); 428 380 if (ret) { ··· 498 448 return 0; 499 449 } 500 450 451 + static const struct of_device_id via_dt_ids[] = { 452 + { .compatible = "via,vt8500-fb", }, 453 + {} 454 + }; 455 + 501 456 static struct platform_driver vt8500lcd_driver = { 502 457 .probe = vt8500lcd_probe, 503 458 .remove = __devexit_p(vt8500lcd_remove), 504 459 .driver = { 505 460 .owner = THIS_MODULE, 506 461 .name = "vt8500-lcd", 462 + .of_match_table = of_match_ptr(via_dt_ids), 507 463 }, 508 464 }; 509 465 ··· 517 461 518 462 MODULE_AUTHOR("Alexey Charkov <alchark@gmail.com>"); 519 463 MODULE_DESCRIPTION("LCD controller driver for VIA VT8500"); 520 - MODULE_LICENSE("GPL"); 464 + MODULE_LICENSE("GPL v2"); 465 + MODULE_DEVICE_TABLE(of, via_dt_ids);
+82 -15
drivers/video/wm8505fb.c
··· 28 28 #include <linux/dma-mapping.h> 29 29 #include <linux/platform_device.h> 30 30 #include <linux/wait.h> 31 + #include <linux/of.h> 32 + #include <linux/of_fdt.h> 33 + #include <linux/memblock.h> 31 34 32 35 #include <mach/vt8500fb.h> 33 36 ··· 62 59 writel(fbi->fb.fix.smem_start, fbi->regbase + WMT_GOVR_FBADDR); 63 60 writel(fbi->fb.fix.smem_start, fbi->regbase + WMT_GOVR_FBADDR1); 64 61 65 - /* Set in-memory picture format to RGB 32bpp */ 66 - writel(0x1c, fbi->regbase + WMT_GOVR_COLORSPACE); 62 + /* 63 + * Set in-memory picture format to RGB 64 + * 0x31C sets the correct color mode (RGB565) for WM8650 65 + * Bit 8+9 (0x300) are ignored on WM8505 as reserved 66 + */ 67 + writel(0x31c, fbi->regbase + WMT_GOVR_COLORSPACE); 67 68 writel(1, fbi->regbase + WMT_GOVR_COLORSPACE1); 68 69 69 70 /* Virtual buffer size */ ··· 134 127 info->var.blue.msb_right = 0; 135 128 info->fix.visual = FB_VISUAL_TRUECOLOR; 136 129 info->fix.line_length = info->var.xres_virtual << 2; 130 + } else if (info->var.bits_per_pixel == 16) { 131 + info->var.red.offset = 11; 132 + info->var.red.length = 5; 133 + info->var.red.msb_right = 0; 134 + info->var.green.offset = 5; 135 + info->var.green.length = 6; 136 + info->var.green.msb_right = 0; 137 + info->var.blue.offset = 0; 138 + info->var.blue.length = 5; 139 + info->var.blue.msb_right = 0; 140 + info->fix.visual = FB_VISUAL_TRUECOLOR; 141 + info->fix.line_length = info->var.xres_virtual << 1; 137 142 } 138 143 139 144 wm8505fb_set_timing(info); ··· 265 246 struct wm8505fb_info *fbi; 266 247 struct resource *res; 267 248 void *addr; 268 - struct vt8500fb_platform_data *pdata; 269 249 int ret; 270 250 271 - pdata = pdev->dev.platform_data; 251 + struct fb_videomode of_mode; 252 + struct device_node *np; 253 + u32 bpp; 254 + dma_addr_t fb_mem_phys; 255 + unsigned long fb_mem_len; 256 + void *fb_mem_virt; 272 257 273 258 ret = -ENOMEM; 274 259 fbi = NULL; 275 260 276 - fbi = kzalloc(sizeof(struct wm8505fb_info) + sizeof(u32) * 16, 277 - GFP_KERNEL); 261 + fbi = devm_kzalloc(&pdev->dev, sizeof(struct wm8505fb_info) + 262 + sizeof(u32) * 16, GFP_KERNEL); 278 263 if (!fbi) { 279 264 dev_err(&pdev->dev, "Failed to initialize framebuffer device\n"); 280 265 ret = -ENOMEM; ··· 328 305 goto failed_free_res; 329 306 } 330 307 331 - fb_videomode_to_var(&fbi->fb.var, &pdata->mode); 308 + np = of_parse_phandle(pdev->dev.of_node, "default-mode", 0); 309 + if (!np) { 310 + pr_err("%s: No display description in Device Tree\n", __func__); 311 + ret = -EINVAL; 312 + goto failed_free_res; 313 + } 314 + 315 + /* 316 + * This code is copied from Sascha Hauer's of_videomode helper 317 + * and can be replaced with a call to the helper once mainlined 318 + */ 319 + ret = 0; 320 + ret |= of_property_read_u32(np, "hactive", &of_mode.xres); 321 + ret |= of_property_read_u32(np, "vactive", &of_mode.yres); 322 + ret |= of_property_read_u32(np, "hback-porch", &of_mode.left_margin); 323 + ret |= of_property_read_u32(np, "hfront-porch", &of_mode.right_margin); 324 + ret |= of_property_read_u32(np, "hsync-len", &of_mode.hsync_len); 325 + ret |= of_property_read_u32(np, "vback-porch", &of_mode.upper_margin); 326 + ret |= of_property_read_u32(np, "vfront-porch", &of_mode.lower_margin); 327 + ret |= of_property_read_u32(np, "vsync-len", &of_mode.vsync_len); 328 + ret |= of_property_read_u32(np, "bpp", &bpp); 329 + if (ret) { 330 + pr_err("%s: Unable to read display properties\n", __func__); 331 + goto failed_free_res; 332 + } 333 + 334 + of_mode.vmode = FB_VMODE_NONINTERLACED; 335 + fb_videomode_to_var(&fbi->fb.var, &of_mode); 332 336 333 337 fbi->fb.var.nonstd = 0; 334 338 fbi->fb.var.activate = FB_ACTIVATE_NOW; 335 339 336 340 fbi->fb.var.height = -1; 337 341 fbi->fb.var.width = -1; 338 - fbi->fb.var.xres_virtual = pdata->xres_virtual; 339 - fbi->fb.var.yres_virtual = pdata->yres_virtual; 340 - fbi->fb.var.bits_per_pixel = pdata->bpp; 341 342 342 - fbi->fb.fix.smem_start = pdata->video_mem_phys; 343 - fbi->fb.fix.smem_len = pdata->video_mem_len; 344 - fbi->fb.screen_base = pdata->video_mem_virt; 345 - fbi->fb.screen_size = pdata->video_mem_len; 343 + /* try allocating the framebuffer */ 344 + fb_mem_len = of_mode.xres * of_mode.yres * 2 * (bpp / 8); 345 + fb_mem_virt = dma_alloc_coherent(&pdev->dev, fb_mem_len, &fb_mem_phys, 346 + GFP_KERNEL); 347 + if (!fb_mem_virt) { 348 + pr_err("%s: Failed to allocate framebuffer\n", __func__); 349 + return -ENOMEM; 350 + }; 351 + 352 + fbi->fb.var.xres_virtual = of_mode.xres; 353 + fbi->fb.var.yres_virtual = of_mode.yres * 2; 354 + fbi->fb.var.bits_per_pixel = bpp; 355 + 356 + fbi->fb.fix.smem_start = fb_mem_phys; 357 + fbi->fb.fix.smem_len = fb_mem_len; 358 + fbi->fb.screen_base = fb_mem_virt; 359 + fbi->fb.screen_size = fb_mem_len; 346 360 347 361 if (fb_alloc_cmap(&fbi->fb.cmap, 256, 0) < 0) { 348 362 dev_err(&pdev->dev, "Failed to allocate color map\n"); ··· 455 395 return 0; 456 396 } 457 397 398 + static const struct of_device_id wmt_dt_ids[] = { 399 + { .compatible = "wm,wm8505-fb", }, 400 + {} 401 + }; 402 + 458 403 static struct platform_driver wm8505fb_driver = { 459 404 .probe = wm8505fb_probe, 460 405 .remove = __devexit_p(wm8505fb_remove), 461 406 .driver = { 462 407 .owner = THIS_MODULE, 463 408 .name = DRIVER_NAME, 409 + .of_match_table = of_match_ptr(wmt_dt_ids), 464 410 }, 465 411 }; 466 412 ··· 474 408 475 409 MODULE_AUTHOR("Ed Spiridonov <edo.rus@gmail.com>"); 476 410 MODULE_DESCRIPTION("Framebuffer driver for WMT WM8505"); 477 - MODULE_LICENSE("GPL"); 411 + MODULE_LICENSE("GPL v2"); 412 + MODULE_DEVICE_TABLE(of, wmt_dt_ids);
+8 -1
drivers/video/wmt_ge_rops.c
··· 158 158 return 0; 159 159 } 160 160 161 + static const struct of_device_id wmt_dt_ids[] = { 162 + { .compatible = "wm,prizm-ge-rops", }, 163 + { /* sentinel */ } 164 + }; 165 + 161 166 static struct platform_driver wmt_ge_rops_driver = { 162 167 .probe = wmt_ge_rops_probe, 163 168 .remove = __devexit_p(wmt_ge_rops_remove), 164 169 .driver = { 165 170 .owner = THIS_MODULE, 166 171 .name = "wmt_ge_rops", 172 + .of_match_table = of_match_ptr(wmt_dt_ids), 167 173 }, 168 174 }; 169 175 ··· 178 172 MODULE_AUTHOR("Alexey Charkov <alchark@gmail.com"); 179 173 MODULE_DESCRIPTION("Accelerators for raster operations using " 180 174 "WonderMedia Graphics Engine"); 181 - MODULE_LICENSE("GPL"); 175 + MODULE_LICENSE("GPL v2"); 176 + MODULE_DEVICE_TABLE(of, wmt_dt_ids);