Commit 15a1e1ba authored by Olof Johansson's avatar Olof Johansson

Merge branch 'marvell/dt' into late2/dt

* marvell/dt: (41 commits)
  ARM: Kirkwood: Replace mrvl with marvell
  ARM: Kirkwood: Describe GoFlex Net LEDs and SATA in DT.
  ARM: Kirkwood: Describe Dreamplug LEDs in DT.
  ARM: Kirkwood: Describe iConnects LEDs in DT.
  ARM: Kirkwood: Describe iConnects temperature sensor in DT.
  ARM: Kirkwood: Describe IB62x0 LEDs in DT.
  ARM: Kirkwood: Describe IB62x0 gpio-keys in DT.
  ARM: Kirkwood: Describe DNS32? gpio-keys in DT.
  ARM: Kirkwood: Move common portions into a kirkwood-dnskw.dtsi
  ARM: Kirkwood: Replace DNS-320/DNS-325 leds with dt bindings
  ARM: Kirkwood: Describe DNS325 temperature sensor in DT.
  ARM: Kirkwood: Use DT to configure SATA device.
  ARM: kirkwood: use devicetree for SPI on dreamplug
  ARM: kirkwood: Add LS-XHL and LS-CHLv2 support
  ARM: Kirkwood: Initial DTS support for Kirkwood GoFlex Net
  ARM: Kirkwood: Add basic device tree support for QNAP TS219.
  ATA: sata_mv: Add device tree support
  ARM: Orion: DTify the watchdog timer.
  ARM: Orion: Add arch support needed for I2C via DT.
  ARM: kirkwood: use devicetree for orion-spi
  ...
parents 28a33cbc f39c1101
......@@ -38,3 +38,23 @@ Example:
reg-names = "mux status", "mux mask";
mrvl,intc-nr-irqs = <2>;
};
* Marvell Orion Interrupt controller
Required properties
- compatible : Should be "marvell,orion-intc".
- #interrupt-cells: Specifies the number of cells needed to encode an
interrupt source. Supported value is <1>.
- interrupt-controller : Declare this node to be an interrupt controller.
- reg : Interrupt mask address. A list of 4 byte ranges, one per controller.
One entry in the list represents 32 interrupts.
Example:
intc: interrupt-controller {
compatible = "marvell,orion-intc", "marvell,intc";
interrupt-controller;
#interrupt-cells = <1>;
reg = <0xfed20204 0x04>,
<0xfed20214 0x04>;
};
* Marvell Orion SATA
Required Properties:
- compatibility : "marvell,orion-sata"
- reg : Address range of controller
- interrupts : Interrupt controller is using
- nr-ports : Number of SATA ports in use.
Example:
sata@80000 {
compatible = "marvell,orion-sata";
reg = <0x80000 0x5000>;
interrupts = <21>;
nr-ports = <2>;
}
......@@ -27,3 +27,26 @@ Example:
interrupt-controller;
#interrupt-cells = <1>;
};
* Marvell Orion GPIO Controller
Required properties:
- compatible : Should be "marvell,orion-gpio"
- reg : Address and length of the register set for controller.
- gpio-controller : So we know this is a gpio controller.
- ngpio : How many gpios this controller has.
- interrupts : Up to 4 Interrupts for the controller.
Optional properties:
- mask-offset : For SMP Orions, offset for Nth CPU
Example:
gpio0: gpio@10100 {
compatible = "marvell,orion-gpio";
#gpio-cells = <2>;
gpio-controller;
reg = <0x10100 0x40>;
ngpio = <32>;
interrupts = <35>, <36>, <37>, <38>;
};
NAND support for Marvell Orion SoC platforms
Required properties:
- compatible : "mrvl,orion-nand".
- compatible : "marvell,orion-nand".
- reg : Base physical address of the NAND and length of memory mapped
region
......@@ -24,7 +24,7 @@ nand@f4000000 {
ale = <1>;
bank-width = <1>;
chip-delay = <25>;
compatible = "mrvl,orion-nand";
compatible = "marvell,orion-nand";
reg = <0xf4000000 0x400>;
partition@0 {
......
Marvell Orion SPI device
Required properties:
- compatible : should be "marvell,orion-spi".
- reg : offset and length of the register set for the device
- cell-index : Which of multiple SPI controllers is this.
Optional properties:
- interrupts : Is currently not used.
Example:
spi@10600 {
compatible = "marvell,orion-spi";
#address-cells = <1>;
#size-cells = <0>;
cell-index = <0>;
reg = <0x10600 0x28>;
interrupts = <23>;
status = "disabled";
};
* Marvell Orion Watchdog Time
Required Properties:
- Compatibility : "marvell,orion-wdt"
- reg : Address of the timer registers
Example:
wdt@20300 {
compatible = "marvell,orion-wdt";
reg = <0x20300 0x28>;
status = "okay";
};
......@@ -1105,6 +1105,7 @@ config PLAT_ORION
bool
select CLKSRC_MMIO
select GENERIC_IRQ_CHIP
select IRQ_DOMAIN
select COMMON_CLK
config PLAT_PXA
......
/dts-v1/;
/include/ "kirkwood.dtsi"
/include/ "kirkwood-dnskw.dtsi"
/ {
model = "D-Link DNS-320 NAS (Rev A1)";
compatible = "dlink,dns-320-a1", "dlink,dns-320", "dlink,dns-kirkwood", "mrvl,kirkwood-88f6281", "mrvl,kirkwood";
compatible = "dlink,dns-320-a1", "dlink,dns-320", "dlink,dns-kirkwood", "marvell,kirkwood-88f6281", "marvell,kirkwood";
memory {
device_type = "memory";
......@@ -15,6 +15,31 @@ chosen {
bootargs = "console=ttyS0,115200n8 earlyprintk";
};
gpio-leds {
compatible = "gpio-leds";
blue-power {
label = "dns320:blue:power";
gpios = <&gpio0 26 1>; /* GPIO 26 Active Low */
linux,default-trigger = "default-on";
};
blue-usb {
label = "dns320:blue:usb";
gpios = <&gpio1 11 1>; /* GPIO 43 Active Low */
};
orange-l_hdd {
label = "dns320:orange:l_hdd";
gpios = <&gpio0 28 1>; /* GPIO 28 Active Low */
};
orange-r_hdd {
label = "dns320:orange:r_hdd";
gpios = <&gpio0 27 1>; /* GPIO 27 Active Low */
};
orange-usb {
label = "dns320:orange:usb";
gpios = <&gpio1 3 1>; /* GPIO 35 Active Low */
};
};
ocp@f1000000 {
serial@12000 {
clock-frequency = <166666667>;
......@@ -25,40 +50,5 @@ serial@12100 {
clock-frequency = <166666667>;
status = "okay";
};
nand@3000000 {
status = "okay";
partition@0 {
label = "u-boot";
reg = <0x0000000 0x100000>;
read-only;
};
partition@100000 {
label = "uImage";
reg = <0x0100000 0x500000>;
};
partition@600000 {
label = "ramdisk";
reg = <0x0600000 0x500000>;
};
partition@b00000 {
label = "image";
reg = <0x0b00000 0x6600000>;
};
partition@7100000 {
label = "mini firmware";
reg = <0x7100000 0xa00000>;
};
partition@7b00000 {
label = "config";
reg = <0x7b00000 0x500000>;
};
};
};
};
/dts-v1/;
/include/ "kirkwood.dtsi"
/include/ "kirkwood-dnskw.dtsi"
/ {
model = "D-Link DNS-325 NAS (Rev A1)";
compatible = "dlink,dns-325-a1", "dlink,dns-325", "dlink,dns-kirkwood", "mrvl,kirkwood-88f6281", "mrvl,kirkwood";
compatible = "dlink,dns-325-a1", "dlink,dns-325", "dlink,dns-kirkwood", "marvell,kirkwood-88f6281", "marvell,kirkwood";
memory {
device_type = "memory";
......@@ -15,45 +15,43 @@ chosen {
bootargs = "console=ttyS0,115200n8 earlyprintk";
};
ocp@f1000000 {
serial@12000 {
clock-frequency = <200000000>;
status = "okay";
gpio-leds {
compatible = "gpio-leds";
white-power {
label = "dns325:white:power";
gpios = <&gpio0 26 1>; /* GPIO 26 Active Low */
linux,default-trigger = "default-on";
};
white-usb {
label = "dns325:white:usb";
gpios = <&gpio1 11 1>; /* GPIO 43 Active Low */
};
red-l_hdd {
label = "dns325:red:l_hdd";
gpios = <&gpio0 28 1>; /* GPIO 28 Active Low */
};
red-r_hdd {
label = "dns325:red:r_hdd";
gpios = <&gpio0 27 1>; /* GPIO 27 Active Low */
};
red-usb {
label = "dns325:red:usb";
gpios = <&gpio0 29 1>; /* GPIO 29 Active Low */
};
};
nand@3000000 {
ocp@f1000000 {
i2c@11000 {
status = "okay";
partition@0 {
label = "u-boot";
reg = <0x0000000 0x100000>;
read-only;
};
partition@100000 {
label = "uImage";
reg = <0x0100000 0x500000>;
};
partition@600000 {
label = "ramdisk";
reg = <0x0600000 0x500000>;
};
partition@b00000 {
label = "image";
reg = <0x0b00000 0x6600000>;
};
partition@7100000 {
label = "mini firmware";
reg = <0x7100000 0xa00000>;
};
partition@7b00000 {
label = "config";
reg = <0x7b00000 0x500000>;
lm75: lm75@48 {
compatible = "national,lm75";
reg = <0x48>;
};
};
serial@12000 {
clock-frequency = <200000000>;
status = "okay";
};
};
};
/include/ "kirkwood.dtsi"
/ {
model = "D-Link DNS NASes (kirkwood-based)";
compatible = "dlink,dns-kirkwood", "marvell,kirkwood-88f6281", "marvell,kirkwood";
gpio_keys {
compatible = "gpio-keys";
#address-cells = <1>;
#size-cells = <0>;
button@1 {
label = "Power button";
linux,code = <116>;
gpios = <&gpio1 2 1>;
};
button@2 {
label = "USB unmount button";
linux,code = <161>;
gpios = <&gpio1 15 1>;
};
button@3 {
label = "Reset button";
linux,code = <0x198>;
gpios = <&gpio1 16 1>;
};
};
ocp@f1000000 {
sata@80000 {
status = "okay";
nr-ports = <2>;
};
nand@3000000 {
status = "okay";
partition@0 {
label = "u-boot";
reg = <0x0000000 0x100000>;
read-only;
};
partition@100000 {
label = "uImage";
reg = <0x0100000 0x500000>;
};
partition@600000 {
label = "ramdisk";
reg = <0x0600000 0x500000>;
};
partition@b00000 {
label = "image";
reg = <0x0b00000 0x6600000>;
};
partition@7100000 {
label = "mini firmware";
reg = <0x7100000 0xa00000>;
};
partition@7b00000 {
label = "config";
reg = <0x7b00000 0x500000>;
};
};
};
};
......@@ -4,7 +4,7 @@
/ {
model = "Globalscale Technologies Dreamplug";
compatible = "globalscale,dreamplug-003-ds2001", "globalscale,dreamplug", "mrvl,kirkwood-88f6281", "mrvl,kirkwood";
compatible = "globalscale,dreamplug-003-ds2001", "globalscale,dreamplug", "marvell,kirkwood-88f6281", "marvell,kirkwood";
memory {
device_type = "memory";
......@@ -20,5 +20,55 @@ serial@12000 {
clock-frequency = <200000000>;
status = "ok";
};
spi@10600 {
status = "okay";
m25p40@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "mx25l1606e";
reg = <0>;
spi-max-frequency = <50000000>;
mode = <0>;
partition@0 {
reg = <0x0 0x80000>;
label = "u-boot";
};
partition@100000 {
reg = <0x100000 0x10000>;
label = "u-boot env";
};
partition@180000 {
reg = <0x180000 0x10000>;
label = "dtb";
};
};
};
sata@80000 {
status = "okay";
nr-ports = <1>;
};
};
gpio-leds {
compatible = "gpio-leds";
bluetooth {
label = "dreamplug:blue:bluetooth";
gpios = <&gpio1 15 1>;
};
wifi {
label = "dreamplug:green:wifi";
gpios = <&gpio1 16 1>;
};
wifi-ap {
label = "dreamplug:green:wifi_ap";
gpios = <&gpio1 17 1>;
};
};
};
/dts-v1/;
/include/ "kirkwood.dtsi"
/ {
model = "Seagate GoFlex Net";
compatible = "seagate,goflexnet", "marvell,kirkwood-88f6281", "marvell,kirkwood";
memory {
device_type = "memory";
reg = <0x00000000 0x8000000>;
};
chosen {
bootargs = "console=ttyS0,115200n8 earlyprintk root=/dev/sda1 rootdelay=10";
};
ocp@f1000000 {
serial@12000 {
clock-frequency = <200000000>;
status = "ok";
};
nand@3000000 {
status = "okay";
partition@0 {
label = "u-boot";
reg = <0x0000000 0x100000>;
read-only;
};
partition@100000 {
label = "uImage";
reg = <0x0100000 0x400000>;
};
partition@500000 {
label = "pogoplug";
reg = <0x0500000 0x2000000>;
};
partition@2500000 {
label = "root";
reg = <0x02500000 0xd800000>;
};
};
sata@80000 {
status = "okay";
nr-ports = <2>;
};
};
gpio-leds {
compatible = "gpio-leds";
health {
label = "status:green:health";
gpios = <&gpio1 14 1>;
linux,default-trigger = "default-on";
};
fault {
label = "status:orange:fault";
gpios = <&gpio1 15 1>;
};
left0 {
label = "status:white:left0";
gpios = <&gpio1 10 0>;
};
left1 {
label = "status:white:left1";
gpios = <&gpio1 11 0>;
};
left2 {
label = "status:white:left2";
gpios = <&gpio1 12 0>;
};
left3 {
label = "status:white:left3";
gpios = <&gpio1 13 0>;
};
right0 {
label = "status:white:right0";
gpios = <&gpio1 6 0>;
};
right1 {
label = "status:white:right1";
gpios = <&gpio1 7 0>;
};
right2 {
label = "status:white:right2";
gpios = <&gpio1 8 0>;
};
right3 {
label = "status:white:right3";
gpios = <&gpio1 9 0>;
};
};
};
......@@ -4,7 +4,7 @@
/ {
model = "RaidSonic ICY BOX IB-NAS62x0 (Rev B)";
compatible = "raidsonic,ib-nas6210-b", "raidsonic,ib-nas6220-b", "raidsonic,ib-nas6210", "raidsonic,ib-nas6220", "raidsonic,ib-nas62x0", "mrvl,kirkwood-88f6281", "mrvl,kirkwood";
compatible = "raidsonic,ib-nas6210-b", "raidsonic,ib-nas6220-b", "raidsonic,ib-nas6210", "raidsonic,ib-nas6220", "raidsonic,ib-nas62x0", "marvell,kirkwood-88f6281", "marvell,kirkwood";
memory {
device_type = "memory";
......@@ -21,6 +21,11 @@ serial@12000 {
status = "okay";
};
sata@80000 {
status = "okay";
nr-ports = <2>;
};
nand@3000000 {
status = "okay";
......@@ -41,4 +46,37 @@ partition@700000 {
};
};
gpio_keys {
compatible = "gpio-keys";
#address-cells = <1>;
#size-cells = <0>;
button@1 {
label = "USB Copy";
linux,code = <133>;
gpios = <&gpio0 29 1>;
};
button@2 {
label = "Reset";
linux,code = <0x198>;
gpios = <&gpio0 28 1>;
};
};
gpio-leds {
compatible = "gpio-leds";
green-os {
label = "ib62x0:green:os";
gpios = <&gpio0 25 0>;
linux,default-trigger = "default-on";
};
red-os {
label = "ib62x0:red:os";
gpios = <&gpio0 22 0>;
};
usb-copy {
label = "ib62x0:red:usb_copy";
gpios = <&gpio0 27 0>;
};
};
};
......@@ -4,7 +4,7 @@
/ {
model = "Iomega Iconnect";
compatible = "iom,iconnect-1.1", "iom,iconnect", "mrvl,kirkwood-88f6281", "mrvl,kirkwood";
compatible = "iom,iconnect-1.1", "iom,iconnect", "marvell,kirkwood-88f6281", "marvell,kirkwood";
memory {
device_type = "memory";
......@@ -18,9 +18,51 @@ chosen {
};
ocp@f1000000 {
i2c@11000 {
status = "okay";
lm63: lm63@4c {
compatible = "national,lm63";
reg = <0x4c>;
};
};
serial@12000 {
clock-frequency = <200000000>;
status = "ok";
};
};
gpio-leds {
compatible = "gpio-leds";
led-level {
label = "led_level";
gpios = <&gpio1 9 0>;
linux,default-trigger = "default-on";
};
power-blue {
label = "power:blue";
gpios = <&gpio1 11 0>;
linux,default-trigger = "timer";
};
usb1 {
label = "usb1:blue";
gpios = <&gpio1 12 0>;
};
usb2 {
label = "usb2:blue";
gpios = <&gpio1 13 0>;
};
usb3 {
label = "usb3:blue";
gpios = <&gpio1 14 0>;
};
usb4 {
label = "usb4:blue";
gpios = <&gpio1 15 0>;
};
otb {
label = "otb:blue";
gpios = <&gpio1 16 0>;
};
};
};
/dts-v1/;
/include/ "kirkwood-lsxl.dtsi"
/ {
model = "Buffalo Linkstation LS-CHLv2";
compatible = "buffalo,lschlv2", "buffalo,lsxl", "marvell,kirkwood-88f6281", "marvell,kirkwood";
memory {
device_type = "memory";
reg = <0x00000000 0x4000000>;
};
ocp@f1000000 {
serial@12000 {
clock-frequency = <166666667>;
status = "okay";
};
};
};
/dts-v1/;
/include/ "kirkwood-lsxl.dtsi"
/ {
model = "Buffalo Linkstation LS-XHL";
compatible = "buffalo,lsxhl", "buffalo,lsxl", "marvell,kirkwood-88f6281", "marvell,kirkwood";
memory {
device_type = "memory";
reg = <0x00000000 0x10000000>;
};
ocp@f1000000 {
serial@12000 {
clock-frequency = <200000000>;
status = "okay";
};
};
};
/include/ "kirkwood.dtsi"
/ {
chosen {
bootargs = "console=ttyS0,115200n8 earlyprintk";
};
ocp@f1000000 {
sata@80000 {
status = "okay";
nr-ports = <1>;
};
spi@10600 {
status = "okay";
m25p40@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "m25p40";
reg = <0>;
spi-max-frequency = <25000000>;
mode = <0>;
partition@0 {
reg = <0x0 0x60000>;
label = "uboot";
read-only;
};
partition@60000 {
reg = <0x60000 0x10000>;
label = "dtb";
read-only;
};
partition@70000 {
reg = <0x70000 0x10000>;
label = "uboot_env";
};
};
};
};
gpio_keys {
compatible = "gpio-keys";
#address-cells = <1>;
#size-cells = <0>;
button@1 {
label = "Function Button";
linux,code = <132>;
gpios = <&gpio1 9 1>;
};
button@2 {
label = "Power-on Switch";
linux,code = <116>;
gpios = <&gpio1 10 1>;
};
button@3 {
label = "Power-auto Switch";
linux,code = <142>;
gpios = <&gpio1 11 1>;
};
};
gpio_leds {
compatible = "gpio-leds";
led@1 {
label = "lschlv2:blue:func";
gpios = <&gpio1 4 1>;
};
led@2 {
label = "lschlv2:red:alarm";
gpios = <&gpio1 5 1>;
};
led@3 {
label = "lschlv2:amber:info";
gpios = <&gpio1 6 1>;
};
led@4 {
label = "lschlv2:blue:power";
gpios = <&gpio1 7 1>;
linux,default-trigger = "default-on";
};
led@5 {
label = "lschlv2:red:func";
gpios = <&gpio1 16 1>;
};
};
};
/dts-v1/;
/include/ "kirkwood-ts219.dtsi"
/ {
gpio_keys {
compatible = "gpio-keys";
#address-cells = <1>;
#size-cells = <0>;
button@1 {
label = "USB Copy";
linux,code = <133>;
gpios = <&gpio0 15 1>;
};
button@2 {
label = "Reset";
linux,code = <0x198>;
gpios = <&gpio0 16 1>;
};
};
};
\ No newline at end of file
/dts-v1/;
/include/ "kirkwood-ts219.dtsi"
/ {
gpio_keys {
compatible = "gpio-keys";
#address-cells = <1>;
#size-cells = <0>;
button@1 {
label = "USB Copy";
linux,code = <133>;
gpios = <&gpio1 11 1>;
};
button@2 {
label = "Reset";
linux,code = <0x198>;
gpios = <&gpio1 5 1>;
};
};
};
\ No newline at end of file
/include/ "kirkwood.dtsi"
/ {
model = "QNAP TS219 family";
compatible = "qnap,ts219", "marvell,kirkwood";
memory {
device_type = "memory";
reg = <0x00000000 0x20000000>;
};
chosen {
bootargs = "console=ttyS0,115200n8";
};
ocp@f1000000 {
i2c@11000 {
status = "okay";
clock-frequency = <400000>;
s35390a: s35390a@30 {
compatible = "s35390a";
reg = <0x30>;
};
};
serial@12000 {
clock-frequency = <200000000>;
status = "okay";
};
serial@12100 {
clock-frequency = <200000000>;
status = "okay";
};
spi@10600 {
status = "okay";
m25p128@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "m25p128";
reg = <0>;
spi-max-frequency = <20000000>;
mode = <0>;
partition@0000000 {
reg = <0x00000000 0x00080000>;
label = "U-Boot";
};
partition@00200000 {
reg = <0x00200000 0x00200000>;
label = "Kernel";
};
partition@00400000 {
reg = <0x00400000 0x00900000>;
label = "RootFS1";
};
partition@00d00000 {
reg = <0x00d00000 0x00300000>;
label = "RootFS2";
};
partition@00040000 {
reg = <0x00080000 0x00040000>;
label = "U-Boot Config";
};
partition@000c0000 {
reg = <0x000c0000 0x00140000>;
label = "NAS Config";
};
};
};
sata@80000 {
status = "okay";
nr-ports = <2>;
};
};
};
/include/ "skeleton.dtsi"
/ {
compatible = "mrvl,kirkwood";
compatible = "marvell,kirkwood";
interrupt-parent = <&intc>;
intc: interrupt-controller {
compatible = "marvell,orion-intc", "marvell,intc";
interrupt-controller;
#interrupt-cells = <1>;
reg = <0xf1020204 0x04>,
<0xf1020214 0x04>;
};
ocp@f1000000 {
compatible = "simple-bus";
......@@ -9,6 +18,24 @@ ocp@f1000000 {
#address-cells = <1>;
#size-cells = <1>;
gpio0: gpio@10100 {
compatible = "marvell,orion-gpio";
#gpio-cells = <2>;
gpio-controller;
reg = <0x10100 0x40>;
ngpio = <32>;
interrupts = <35>, <36>, <37>, <38>;
};
gpio1: gpio@10140 {
compatible = "marvell,orion-gpio";
#gpio-cells = <2>;
gpio-controller;
reg = <0x10140 0x40>;
ngpio = <18>;
interrupts = <39>, <40>, <41>;
};
serial@12000 {
compatible = "ns16550a";
reg = <0x12000 0x100>;
......@@ -28,22 +55,55 @@ serial@12100 {
};
rtc@10300 {
compatible = "mrvl,kirkwood-rtc", "mrvl,orion-rtc";
compatible = "marvell,kirkwood-rtc", "marvell,orion-rtc";
reg = <0x10300 0x20>;
interrupts = <53>;
};
spi@10600 {
compatible = "marvell,orion-spi";
#address-cells = <1>;
#size-cells = <0>;
cell-index = <0>;
interrupts = <23>;
reg = <0x10600 0x28>;
status = "disabled";
};
wdt@20300 {
compatible = "marvell,orion-wdt";
reg = <0x20300 0x28>;
status = "okay";
};
sata@80000 {
compatible = "marvell,orion-sata";
reg = <0x80000 0x5000>;
interrupts = <21>;
status = "disabled";
};
nand@3000000 {
#address-cells = <1>;
#size-cells = <1>;
cle = <0>;
ale = <1>;
bank-width = <1>;
compatible = "mrvl,orion-nand";
compatible = "marvell,orion-nand";
reg = <0x3000000 0x400>;
chip-delay = <25>;
/* set partition map and/or chip-delay in board dts */
status = "disabled";
};
i2c@11000 {
compatible = "marvell,mv64xxx-i2c";
reg = <0x11000 0x20>;
#address-cells = <1>;
#size-cells = <0>;
interrupts = <29>;
clock-frequency = <100000>;
status = "disabled";
};
};
};
......@@ -101,8 +101,8 @@ void __init dove_ehci1_init(void)
****************************************************************************/
void __init dove_ge00_init(struct mv643xx_eth_platform_data *eth_data)
{
orion_ge00_init(eth_data,
DOVE_GE00_PHYS_BASE, IRQ_DOVE_GE00_SUM, 0);
orion_ge00_init(eth_data, DOVE_GE00_PHYS_BASE,
IRQ_DOVE_GE00_SUM, IRQ_DOVE_GE00_ERR);
}
/*****************************************************************************
......
......@@ -20,22 +20,6 @@
#include <mach/bridge-regs.h>
#include "common.h"
static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
{
int irqoff;
BUG_ON(irq < IRQ_DOVE_GPIO_0_7 || irq > IRQ_DOVE_HIGH_GPIO);
irqoff = irq <= IRQ_DOVE_GPIO_16_23 ? irq - IRQ_DOVE_GPIO_0_7 :
3 + irq - IRQ_DOVE_GPIO_24_31;
orion_gpio_irq_handler(irqoff << 3);
if (irq == IRQ_DOVE_HIGH_GPIO) {
orion_gpio_irq_handler(40);
orion_gpio_irq_handler(48);
orion_gpio_irq_handler(56);
}
}
static void pmu_irq_mask(struct irq_data *d)
{
int pin = irq_to_pmu(d->irq);
......@@ -90,6 +74,27 @@ static void pmu_irq_handler(unsigned int irq, struct irq_desc *desc)
}
}
static int __initdata gpio0_irqs[4] = {
IRQ_DOVE_GPIO_0_7,
IRQ_DOVE_GPIO_8_15,
IRQ_DOVE_GPIO_16_23,
IRQ_DOVE_GPIO_24_31,
};
static int __initdata gpio1_irqs[4] = {
IRQ_DOVE_HIGH_GPIO,
0,
0,
0,
};
static int __initdata gpio2_irqs[4] = {
0,
0,
0,
0,
};
void __init dove_init_irq(void)
{
int i;
......@@ -100,19 +105,14 @@ void __init dove_init_irq(void)
/*
* Initialize gpiolib for GPIOs 0-71.
*/
orion_gpio_init(0, 32, DOVE_GPIO_LO_VIRT_BASE, 0,
IRQ_DOVE_GPIO_START);
irq_set_chained_handler(IRQ_DOVE_GPIO_0_7, gpio_irq_handler);
irq_set_chained_handler(IRQ_DOVE_GPIO_8_15, gpio_irq_handler);
irq_set_chained_handler(IRQ_DOVE_GPIO_16_23, gpio_irq_handler);
irq_set_chained_handler(IRQ_DOVE_GPIO_24_31, gpio_irq_handler);
orion_gpio_init(32, 32, DOVE_GPIO_HI_VIRT_BASE, 0,
IRQ_DOVE_GPIO_START + 32);
irq_set_chained_handler(IRQ_DOVE_HIGH_GPIO, gpio_irq_handler);
orion_gpio_init(64, 8, DOVE_GPIO2_VIRT_BASE, 0,
IRQ_DOVE_GPIO_START + 64);
orion_gpio_init(NULL, 0, 32, (void __iomem *)DOVE_GPIO_LO_VIRT_BASE, 0,
IRQ_DOVE_GPIO_START, gpio0_irqs);
orion_gpio_init(NULL, 32, 32, (void __iomem *)DOVE_GPIO_HI_VIRT_BASE, 0,
IRQ_DOVE_GPIO_START + 32, gpio1_irqs);
orion_gpio_init(NULL, 64, 8, (void __iomem *)DOVE_GPIO2_VIRT_BASE, 0,
IRQ_DOVE_GPIO_START + 64, gpio2_irqs);
/*
* Mask and clear PMU interrupts
......
......@@ -80,6 +80,35 @@ config MACH_IB62X0_DT
RaidSonic IB-NAS6210 & IB-NAS6220 devices, using
Flattened Device Tree.
config MACH_TS219_DT
bool "Device Tree for QNAP TS-11X, TS-21X NAS"
select ARCH_KIRKWOOD_DT
select ARM_APPENDED_DTB
select ARM_ATAG_DTB_COMPAT
help
Say 'Y' here if you want your kernel to support the QNAP
TS-110, TS-119, TS-119P+, TS-210, TS-219, TS-219P and
TS-219P+ Turbo NAS devices using Fattened Device Tree.
There are two different Device Tree descriptions, depending
on if the device is based on an if the board uses the MV6281
or MV6282. If you have the wrong one, the buttons will not
work.
config MACH_GOFLEXNET_DT
bool "Seagate GoFlex Net (Flattened Device Tree)"
select ARCH_KIRKWOOD_DT
help
Say 'Y' here if you want your kernel to support the
Seagate GoFlex Net (Flattened Device Tree).
config MACH_LSXL_DT
bool "Buffalo Linkstation LS-XHL, LS-CHLv2 (Flattened Device Tree)"
select ARCH_KIRKWOOD_DT
help
Say 'Y' here if you want your kernel to support the
Buffalo Linkstation LS-XHL & LS-CHLv2 devices, using
Flattened Device Tree.
config MACH_TS219
bool "QNAP TS-110, TS-119, TS-119P+, TS-210, TS-219, TS-219P and TS-219P+ Turbo NAS"
help
......
......@@ -25,3 +25,6 @@ obj-$(CONFIG_MACH_DREAMPLUG_DT) += board-dreamplug.o
obj-$(CONFIG_MACH_ICONNECT_DT) += board-iconnect.o
obj-$(CONFIG_MACH_DLINK_KIRKWOOD_DT) += board-dnskw.o
obj-$(CONFIG_MACH_IB62X0_DT) += board-ib62x0.o
obj-$(CONFIG_MACH_TS219_DT) += board-ts219.o tsx1x-common.o
obj-$(CONFIG_MACH_GOFLEXNET_DT) += board-goflexnet.o
obj-$(CONFIG_MACH_LSXL_DT) += board-lsxl.o
......@@ -7,3 +7,7 @@ dtb-$(CONFIG_MACH_DLINK_KIRKWOOD_DT) += kirkwood-dns320.dtb
dtb-$(CONFIG_MACH_DLINK_KIRKWOOD_DT) += kirkwood-dns325.dtb
dtb-$(CONFIG_MACH_ICONNECT_DT) += kirkwood-iconnect.dtb
dtb-$(CONFIG_MACH_IB62X0_DT) += kirkwood-ib62x0.dtb
dtb-$(CONFIG_MACH_TS219_DT) += kirkwood-qnap-ts219.dtb
dtb-$(CONFIG_MACH_GOFLEXNET_DT) += kirkwood-goflexnet.dtb
dbt-$(CONFIG_MACH_LSXL_DT) += kirkwood-lschlv2.dtb
dbt-$(CONFIG_MACH_LSXL_DT) += kirkwood-lsxhl.dtb
......@@ -14,13 +14,11 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/ata_platform.h>
#include <linux/mv643xx_eth.h>
#include <linux/of.h>
#include <linux/gpio.h>
#include <linux/input.h>
#include <linux/gpio_keys.h>
#include <linux/gpio-fan.h>
#include <linux/leds.h>
#include <asm/mach-types.h>
......@@ -35,10 +33,6 @@ static struct mv643xx_eth_platform_data dnskw_ge00_data = {
.phy_addr = MV643XX_ETH_PHY_ADDR(8),
};
static struct mv_sata_platform_data dnskw_sata_data = {
.n_ports = 2,
};
static unsigned int dnskw_mpp_config[] __initdata = {
MPP13_UART1_TXD, /* Custom ... */
MPP14_UART1_RXD, /* ... Controller (DNS-320 only) */
......@@ -73,132 +67,6 @@ static unsigned int dnskw_mpp_config[] __initdata = {
0
};
static struct gpio_led dns325_led_pins[] = {
{
.name = "dns325:white:power",
.gpio = 26,
.active_low = 1,
.default_trigger = "default-on",
},
{
.name = "dns325:white:usb",
.gpio = 43,
.active_low = 1,
},
{
.name = "dns325:red:l_hdd",
.gpio = 28,
.active_low = 1,
},
{
.name = "dns325:red:r_hdd",
.gpio = 27,
.active_low = 1,
},
{
.name = "dns325:red:usb",
.gpio = 29,
.active_low = 1,
},
};
static struct gpio_led_platform_data dns325_led_data = {
.num_leds = ARRAY_SIZE(dns325_led_pins),
.leds = dns325_led_pins,
};
static struct platform_device dns325_led_device = {
.name = "leds-gpio",
.id = -1,
.dev = {
.platform_data = &dns325_led_data,
},
};
static struct gpio_led dns320_led_pins[] = {
{
.name = "dns320:blue:power",
.gpio = 26,
.active_low = 1,
.default_trigger = "default-on",
},
{
.name = "dns320:blue:usb",
.gpio = 43,
.active_low = 1,
},
{
.name = "dns320:orange:l_hdd",
.gpio = 28,
.active_low = 1,
},
{
.name = "dns320:orange:r_hdd",
.gpio = 27,
.active_low = 1,
},
{
.name = "dns320:orange:usb",
.gpio = 35,
.active_low = 1,
},
};
static struct gpio_led_platform_data dns320_led_data = {
.num_leds = ARRAY_SIZE(dns320_led_pins),
.leds = dns320_led_pins,
};
static struct platform_device dns320_led_device = {
.name = "leds-gpio",
.id = -1,
.dev = {
.platform_data = &dns320_led_data,
},
};
static struct i2c_board_info dns325_i2c_board_info[] __initdata = {
{
I2C_BOARD_INFO("lm75", 0x48),
},
/* Something at 0x0c also */
};
static struct gpio_keys_button dnskw_button_pins[] = {
{
.code = KEY_POWER,
.gpio = 34,
.desc = "Power button",
.active_low = 1,
},
{
.code = KEY_EJECTCD,
.gpio = 47,
.desc = "USB unmount button",
.active_low = 1,
},
{
.code = KEY_RESTART,
.gpio = 48,
.desc = "Reset button",
.active_low = 1,
},
};
static struct gpio_keys_platform_data dnskw_button_data = {
.buttons = dnskw_button_pins,
.nbuttons = ARRAY_SIZE(dnskw_button_pins),
};
static struct platform_device dnskw_button_device = {
.name = "gpio-keys",
.id = -1,
.num_resources = 0,
.dev = {
.platform_data = &dnskw_button_data,
}
};
/* Fan: ADDA AD045HB-G73 40mm 6000rpm@5v */
static struct gpio_fan_speed dnskw_fan_speed[] = {
{ 0, 0 },
......@@ -245,20 +113,9 @@ void __init dnskw_init(void)
kirkwood_ehci_init();
kirkwood_ge00_init(&dnskw_ge00_data);
kirkwood_sata_init(&dnskw_sata_data);
kirkwood_i2c_init();
platform_device_register(&dnskw_button_device);
platform_device_register(&dnskw_fan_device);
if (of_machine_is_compatible("dlink,dns-325")) {
i2c_register_board_info(0, dns325_i2c_board_info,
ARRAY_SIZE(dns325_i2c_board_info));
platform_device_register(&dns325_led_device);
} else if (of_machine_is_compatible("dlink,dns-320"))
platform_device_register(&dns320_led_device);
/* Register power-off GPIO. */
if (gpio_request(36, "dnskw:power:off") == 0
&& gpio_direction_output(36, 0) == 0)
......
......@@ -14,7 +14,6 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/mtd/partitions.h>
#include <linux/ata_platform.h>
#include <linux/mv643xx_eth.h>
#include <linux/of.h>
......@@ -23,7 +22,6 @@
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/gpio.h>
#include <linux/leds.h>
#include <linux/mtd/physmap.h>
#include <linux/spi/flash.h>
#include <linux/spi/spi.h>
......@@ -36,42 +34,6 @@
#include "common.h"
#include "mpp.h"
struct mtd_partition dreamplug_partitions[] = {
{
.name = "u-boot",
.size = SZ_512K,
.offset = 0,
},
{
.name = "u-boot env",
.size = SZ_64K,
.offset = SZ_512K + SZ_512K,
},
{
.name = "dtb",
.size = SZ_64K,
.offset = SZ_512K + SZ_512K + SZ_512K,
},
};
static const struct flash_platform_data dreamplug_spi_slave_data = {
.type = "mx25l1606e",
.name = "spi_flash",
.parts = dreamplug_partitions,
.nr_parts = ARRAY_SIZE(dreamplug_partitions),
};
static struct spi_board_info __initdata dreamplug_spi_slave_info[] = {
{
.modalias = "m25p80",
.platform_data = &dreamplug_spi_slave_data,
.irq = -1,
.max_speed_hz = 50000000,
.bus_num = 0,
.chip_select = 0,
},
};
static struct mv643xx_eth_platform_data dreamplug_ge00_data = {
.phy_addr = MV643XX_ETH_PHY_ADDR(0),
};
......@@ -80,45 +42,10 @@ static struct mv643xx_eth_platform_data dreamplug_ge01_data = {
.phy_addr = MV643XX_ETH_PHY_ADDR(1),
};
static struct mv_sata_platform_data dreamplug_sata_data = {
.n_ports = 1,
};
static struct mvsdio_platform_data dreamplug_mvsdio_data = {
/* unfortunately the CD signal has not been connected */
};
static struct gpio_led dreamplug_led_pins[] = {
{
.name = "dreamplug:blue:bluetooth",
.gpio = 47,
.active_low = 1,
},
{
.name = "dreamplug:green:wifi",
.gpio = 48,
.active_low = 1,
},
{
.name = "dreamplug:green:wifi_ap",
.gpio = 49,
.active_low = 1,
},
};
static struct gpio_led_platform_data dreamplug_led_data = {
.leds = dreamplug_led_pins,
.num_leds = ARRAY_SIZE(dreamplug_led_pins),
};
static struct platform_device dreamplug_leds = {
.name = "leds-gpio",
.id = -1,
.dev = {
.platform_data = &dreamplug_led_data,
}
};
static unsigned int dreamplug_mpp_config[] __initdata = {
MPP0_SPI_SCn,
MPP1_SPI_MOSI,
......@@ -137,15 +64,8 @@ void __init dreamplug_init(void)
*/
kirkwood_mpp_conf(dreamplug_mpp_config);
spi_register_board_info(dreamplug_spi_slave_info,
ARRAY_SIZE(dreamplug_spi_slave_info));
kirkwood_spi_init();
kirkwood_ehci_init();
kirkwood_ge00_init(&dreamplug_ge00_data);
kirkwood_ge01_init(&dreamplug_ge01_data);
kirkwood_sata_init(&dreamplug_sata_data);
kirkwood_sdio_init(&dreamplug_mvsdio_data);
platform_device_register(&dreamplug_leds);
}
......@@ -18,6 +18,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <mach/bridge-regs.h>
#include <plat/irq.h>
#include "common.h"
static struct of_device_id kirkwood_dt_match_table[] __initdata = {
......@@ -25,6 +26,16 @@ static struct of_device_id kirkwood_dt_match_table[] __initdata = {
{ }
};
struct of_dev_auxdata kirkwood_auxdata_lookup[] __initdata = {
OF_DEV_AUXDATA("marvell,orion-spi", 0xf1010600, "orion_spi.0", NULL),
OF_DEV_AUXDATA("marvell,mv64xxx-i2c", 0xf1011000, "mv64xxx_i2c.0",
NULL),
OF_DEV_AUXDATA("marvell,orion-wdt", 0xf1020300, "orion_wdt", NULL),
OF_DEV_AUXDATA("marvell,orion-sata", 0xf1080000, "sata_mv.0", NULL),
OF_DEV_AUXDATA("marvell,orion-nand", 0xf4000000, "orion_nand", NULL),
{},
};
static void __init kirkwood_dt_init(void)
{
pr_info("Kirkwood: %s, TCLK=%d.\n", kirkwood_id(), kirkwood_tclk);
......@@ -47,7 +58,6 @@ static void __init kirkwood_dt_init(void)
kirkwood_clk_init();
/* internal devices that every board has */
kirkwood_wdt_init();
kirkwood_xor0_init();
kirkwood_xor1_init();
kirkwood_crypto_init();
......@@ -68,7 +78,17 @@ static void __init kirkwood_dt_init(void)
if (of_machine_is_compatible("raidsonic,ib-nas62x0"))
ib62x0_init();
of_platform_populate(NULL, kirkwood_dt_match_table, NULL, NULL);
if (of_machine_is_compatible("qnap,ts219"))
qnap_dt_ts219_init();
if (of_machine_is_compatible("seagate,goflexnet"))
goflexnet_init();
if (of_machine_is_compatible("buffalo,lsxl"))
lsxl_init();
of_platform_populate(NULL, kirkwood_dt_match_table,
kirkwood_auxdata_lookup, NULL);
}
static const char *kirkwood_dt_board_compat[] = {
......@@ -77,6 +97,9 @@ static const char *kirkwood_dt_board_compat[] = {
"dlink,dns-325",
"iom,iconnect",
"raidsonic,ib-nas62x0",
"qnap,ts219",
"seagate,goflexnet",
"buffalo,lsxl",
NULL
};
......@@ -84,7 +107,7 @@ DT_MACHINE_START(KIRKWOOD_DT, "Marvell Kirkwood (Flattened Device Tree)")
/* Maintainer: Jason Cooper <jason@lakedaemon.net> */
.map_io = kirkwood_map_io,
.init_early = kirkwood_init_early,
.init_irq = kirkwood_init_irq,
.init_irq = orion_dt_init_irq,
.timer = &kirkwood_timer,
.init_machine = kirkwood_dt_init,
.restart = kirkwood_restart,
......
/*
* Copyright 2012 (C), Jason Cooper <jason@lakedaemon.net>
*
* arch/arm/mach-kirkwood/board-goflexnet.c
*
* Seagate GoFlext Net Board Init for drivers not converted to
* flattened device tree yet.
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*
* Copied and modified for Seagate GoFlex Net support by
* Joshua Coombs <josh.coombs@gmail.com> based on ArchLinux ARM's
* GoFlex kernel patches.
*
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/ata_platform.h>
#include <linux/mv643xx_eth.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_fdt.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/gpio.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <mach/kirkwood.h>
#include <mach/bridge-regs.h>
#include <plat/mvsdio.h>
#include "common.h"
#include "mpp.h"
static struct mv643xx_eth_platform_data goflexnet_ge00_data = {
.phy_addr = MV643XX_ETH_PHY_ADDR(0),
};
static unsigned int goflexnet_mpp_config[] __initdata = {
MPP29_GPIO, /* USB Power Enable */
MPP47_GPIO, /* LED Orange */
MPP46_GPIO, /* LED Green */
MPP45_GPIO, /* LED Left Capacity 3 */
MPP44_GPIO, /* LED Left Capacity 2 */
MPP43_GPIO, /* LED Left Capacity 1 */
MPP42_GPIO, /* LED Left Capacity 0 */
MPP41_GPIO, /* LED Right Capacity 3 */
MPP40_GPIO, /* LED Right Capacity 2 */
MPP39_GPIO, /* LED Right Capacity 1 */
MPP38_GPIO, /* LED Right Capacity 0 */
0
};
void __init goflexnet_init(void)
{
/*
* Basic setup. Needs to be called early.
*/
kirkwood_mpp_conf(goflexnet_mpp_config);
if (gpio_request(29, "USB Power Enable") != 0 ||
gpio_direction_output(29, 1) != 0)
pr_err("can't setup GPIO 29 (USB Power Enable)\n");
kirkwood_ehci_init();
kirkwood_ge00_init(&goflexnet_ge00_data);
}
......@@ -18,9 +18,7 @@
#include <linux/ata_platform.h>
#include <linux/mv643xx_eth.h>
#include <linux/gpio.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>
#include <linux/leds.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/kirkwood.h>
......@@ -33,10 +31,6 @@ static struct mv643xx_eth_platform_data ib62x0_ge00_data = {
.phy_addr = MV643XX_ETH_PHY_ADDR(8),
};
static struct mv_sata_platform_data ib62x0_sata_data = {
.n_ports = 2,
};
static unsigned int ib62x0_mpp_config[] __initdata = {
MPP0_NF_IO2,
MPP1_NF_IO3,
......@@ -55,69 +49,6 @@ static unsigned int ib62x0_mpp_config[] __initdata = {
0
};
static struct gpio_led ib62x0_led_pins[] = {
{
.name = "ib62x0:green:os",
.default_trigger = "default-on",
.gpio = 25,
.active_low = 0,
},
{
.name = "ib62x0:red:os",
.default_trigger = "none",
.gpio = 22,
.active_low = 0,
},
{
.name = "ib62x0:red:usb_copy",
.default_trigger = "none",
.gpio = 27,
.active_low = 0,
},
};
static struct gpio_led_platform_data ib62x0_led_data = {
.leds = ib62x0_led_pins,
.num_leds = ARRAY_SIZE(ib62x0_led_pins),
};
static struct platform_device ib62x0_led_device = {
.name = "leds-gpio",
.id = -1,
.dev = {
.platform_data = &ib62x0_led_data,
}
};
static struct gpio_keys_button ib62x0_button_pins[] = {
{
.code = KEY_COPY,
.gpio = 29,
.desc = "USB Copy",
.active_low = 1,
},
{
.code = KEY_RESTART,
.gpio = 28,
.desc = "Reset",
.active_low = 1,
},
};
static struct gpio_keys_platform_data ib62x0_button_data = {
.buttons = ib62x0_button_pins,
.nbuttons = ARRAY_SIZE(ib62x0_button_pins),
};
static struct platform_device ib62x0_button_device = {
.name = "gpio-keys",
.id = -1,
.num_resources = 0,
.dev = {
.platform_data = &ib62x0_button_data,
}
};
static void ib62x0_power_off(void)
{
gpio_set_value(IB62X0_GPIO_POWER_OFF, 1);
......@@ -132,9 +63,6 @@ void __init ib62x0_init(void)
kirkwood_ehci_init();
kirkwood_ge00_init(&ib62x0_ge00_data);
kirkwood_sata_init(&ib62x0_sata_data);
platform_device_register(&ib62x0_led_device);
platform_device_register(&ib62x0_button_device);
if (gpio_request(IB62X0_GPIO_POWER_OFF, "ib62x0:power:off") == 0 &&
gpio_direction_output(IB62X0_GPIO_POWER_OFF, 0) == 0)
pm_power_off = ib62x0_power_off;
......
......@@ -19,8 +19,6 @@
#include <linux/mtd/partitions.h>
#include <linux/mv643xx_eth.h>
#include <linux/gpio.h>
#include <linux/leds.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/gpio_keys.h>
#include <asm/mach/arch.h>
......@@ -32,50 +30,6 @@ static struct mv643xx_eth_platform_data iconnect_ge00_data = {
.phy_addr = MV643XX_ETH_PHY_ADDR(11),
};
static struct gpio_led iconnect_led_pins[] = {
{
.name = "led_level",
.gpio = 41,
.default_trigger = "default-on",
}, {
.name = "power:blue",
.gpio = 42,
.default_trigger = "timer",
}, {
.name = "power:red",
.gpio = 43,
}, {
.name = "usb1:blue",
.gpio = 44,
}, {
.name = "usb2:blue",
.gpio = 45,
}, {
.name = "usb3:blue",
.gpio = 46,
}, {
.name = "usb4:blue",
.gpio = 47,
}, {
.name = "otb:blue",
.gpio = 48,
},
};
static struct gpio_led_platform_data iconnect_led_data = {
.leds = iconnect_led_pins,
.num_leds = ARRAY_SIZE(iconnect_led_pins),
.gpio_blink_set = orion_gpio_led_blink_set,
};
static struct platform_device iconnect_leds = {
.name = "leds-gpio",
.id = -1,
.dev = {
.platform_data = &iconnect_led_data,
}
};
static unsigned int iconnect_mpp_config[] __initdata = {
MPP12_GPIO,
MPP35_GPIO,
......@@ -90,12 +44,6 @@ static unsigned int iconnect_mpp_config[] __initdata = {
0
};
static struct i2c_board_info __initdata iconnect_board_info[] = {
{
I2C_BOARD_INFO("lm63", 0x4c),
},
};
static struct mtd_partition iconnect_nand_parts[] = {
{
.name = "flash",
......@@ -142,15 +90,11 @@ void __init iconnect_init(void)
{
kirkwood_mpp_conf(iconnect_mpp_config);
kirkwood_nand_init(ARRAY_AND_SIZE(iconnect_nand_parts), 25);
kirkwood_i2c_init();
i2c_register_board_info(0, iconnect_board_info,
ARRAY_SIZE(iconnect_board_info));
kirkwood_ehci_init();
kirkwood_ge00_init(&iconnect_ge00_data);
platform_device_register(&iconnect_button_device);
platform_device_register(&iconnect_leds);
}
static int __init iconnect_pci_init(void)
......
/*
* Copyright 2012 (C), Michael Walle <michael@walle.cc>
*
* arch/arm/mach-kirkwood/board-lsxl.c
*
* Buffalo Linkstation LS-XHL and LS-CHLv2 init for drivers not
* converted to flattened device tree yet.
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/mtd/partitions.h>
#include <linux/ata_platform.h>
#include <linux/spi/flash.h>
#include <linux/spi/spi.h>
#include <linux/mv643xx_eth.h>
#include <linux/gpio.h>
#include <linux/gpio-fan.h>
#include <linux/input.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/kirkwood.h>
#include "common.h"
#include "mpp.h"
static struct mv643xx_eth_platform_data lsxl_ge00_data = {
.phy_addr = MV643XX_ETH_PHY_ADDR(0),
};
static struct mv643xx_eth_platform_data lsxl_ge01_data = {
.phy_addr = MV643XX_ETH_PHY_ADDR(8),
};
static unsigned int lsxl_mpp_config[] __initdata = {
MPP10_GPO, /* HDD Power Enable */
MPP11_GPIO, /* USB Vbus Enable */
MPP18_GPO, /* FAN High Enable# */
MPP19_GPO, /* FAN Low Enable# */
MPP36_GPIO, /* Function Blue LED */
MPP37_GPIO, /* Alarm LED */
MPP38_GPIO, /* Info LED */
MPP39_GPIO, /* Power LED */
MPP40_GPIO, /* Fan Lock */
MPP41_GPIO, /* Function Button */
MPP42_GPIO, /* Power Switch */
MPP43_GPIO, /* Power Auto Switch */
MPP48_GPIO, /* Function Red LED */
0
};
#define LSXL_GPIO_FAN_HIGH 18
#define LSXL_GPIO_FAN_LOW 19
#define LSXL_GPIO_FAN_LOCK 40
static struct gpio_fan_alarm lsxl_alarm = {
.gpio = LSXL_GPIO_FAN_LOCK,
};
static struct gpio_fan_speed lsxl_speeds[] = {
{
.rpm = 0,
.ctrl_val = 3,
}, {
.rpm = 1500,
.ctrl_val = 1,
}, {
.rpm = 3250,
.ctrl_val = 2,
}, {
.rpm = 5000,
.ctrl_val = 0,
}
};
static int lsxl_gpio_list[] = {
LSXL_GPIO_FAN_HIGH, LSXL_GPIO_FAN_LOW,
};
static struct gpio_fan_platform_data lsxl_fan_data = {
.num_ctrl = ARRAY_SIZE(lsxl_gpio_list),
.ctrl = lsxl_gpio_list,
.alarm = &lsxl_alarm,
.num_speed = ARRAY_SIZE(lsxl_speeds),
.speed = lsxl_speeds,
};
static struct platform_device lsxl_fan_device = {
.name = "gpio-fan",
.id = -1,
.num_resources = 0,
.dev = {
.platform_data = &lsxl_fan_data,
},
};
/*
* On the LS-XHL/LS-CHLv2, the shutdown process is following:
* - Userland monitors key events until the power switch goes to off position
* - The board reboots
* - U-boot starts and goes into an idle mode waiting for the user
* to move the switch to ON position
*
*/
static void lsxl_power_off(void)
{
kirkwood_restart('h', NULL);
}
#define LSXL_GPIO_HDD_POWER 10
#define LSXL_GPIO_USB_POWER 11
void __init lsxl_init(void)
{
/*
* Basic setup. Needs to be called early.
*/
kirkwood_mpp_conf(lsxl_mpp_config);
/* usb and sata power on */
gpio_set_value(LSXL_GPIO_USB_POWER, 1);
gpio_set_value(LSXL_GPIO_HDD_POWER, 1);
kirkwood_ehci_init();
kirkwood_ge00_init(&lsxl_ge00_data);
kirkwood_ge01_init(&lsxl_ge01_data);
platform_device_register(&lsxl_fan_device);
/* register power-off method */
pm_power_off = lsxl_power_off;
}
/*
*
* QNAP TS-11x/TS-21x Turbo NAS Board Setup via DT
*
* Copyright (C) 2012 Andrew Lunn <andrew@lunn.ch>
*
* Based on the board file ts219-setup.c:
*
* Copyright (C) 2009 Martin Michlmayr <tbm@cyrius.com>
* Copyright (C) 2008 Byron Bradley <byron.bbradley@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/mv643xx_eth.h>
#include <linux/ata_platform.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/kirkwood.h>
#include "common.h"
#include "mpp.h"
#include "tsx1x-common.h"
static struct mv643xx_eth_platform_data qnap_ts219_ge00_data = {
.phy_addr = MV643XX_ETH_PHY_ADDR(8),
};
static unsigned int qnap_ts219_mpp_config[] __initdata = {
MPP0_SPI_SCn,
MPP1_SPI_MOSI,
MPP2_SPI_SCK,
MPP3_SPI_MISO,
MPP4_SATA1_ACTn,
MPP5_SATA0_ACTn,
MPP8_TW0_SDA,
MPP9_TW0_SCK,
MPP10_UART0_TXD,
MPP11_UART0_RXD,
MPP13_UART1_TXD, /* PIC controller */
MPP14_UART1_RXD, /* PIC controller */
MPP15_GPIO, /* USB Copy button (on devices with 88F6281) */
MPP16_GPIO, /* Reset button (on devices with 88F6281) */
MPP36_GPIO, /* RAM: 0: 256 MB, 1: 512 MB */
MPP37_GPIO, /* Reset button (on devices with 88F6282) */
MPP43_GPIO, /* USB Copy button (on devices with 88F6282) */
MPP44_GPIO, /* Board ID: 0: TS-11x, 1: TS-21x */
0
};
void __init qnap_dt_ts219_init(void)
{
u32 dev, rev;
kirkwood_mpp_conf(qnap_ts219_mpp_config);
kirkwood_pcie_id(&dev, &rev);
if (dev == MV88F6282_DEV_ID)
qnap_ts219_ge00_data.phy_addr = MV643XX_ETH_PHY_ADDR(0);
kirkwood_ge00_init(&qnap_ts219_ge00_data);
kirkwood_ehci_init();
pm_power_off = qnap_tsx1x_power_off;
}
/* FIXME: Will not work with DT. Maybe use MPP40_GPIO? */
static int __init ts219_pci_init(void)
{
if (machine_is_ts219())
kirkwood_pcie_init(KW_PCIE0);
return 0;
}
subsys_initcall(ts219_pci_init);
......@@ -17,6 +17,7 @@
#include <linux/dma-mapping.h>
#include <linux/clk-provider.h>
#include <linux/spinlock.h>
#include <linux/mv643xx_i2c.h>
#include <net/dsa.h>
#include <asm/page.h>
#include <asm/timex.h>
......@@ -67,6 +68,14 @@ void __init kirkwood_map_io(void)
* CLK tree
****************************************************************************/
static void enable_sata0(void)
{
/* Enable PLL and IVREF */
writel(readl(SATA0_PHY_MODE_2) | 0xf, SATA0_PHY_MODE_2);
/* Enable PHY */
writel(readl(SATA0_IF_CTRL) & ~0x200, SATA0_IF_CTRL);
}
static void disable_sata0(void)
{
/* Disable PLL and IVREF */
......@@ -75,6 +84,14 @@ static void disable_sata0(void)
writel(readl(SATA0_IF_CTRL) | 0x200, SATA0_IF_CTRL);
}
static void enable_sata1(void)
{
/* Enable PLL and IVREF */
writel(readl(SATA1_PHY_MODE_2) | 0xf, SATA1_PHY_MODE_2);
/* Enable PHY */
writel(readl(SATA1_IF_CTRL) & ~0x200, SATA1_IF_CTRL);
}
static void disable_sata1(void)
{
/* Disable PLL and IVREF */
......@@ -107,23 +124,38 @@ static void disable_pcie1(void)
}
}
/* An extended version of the gated clk. This calls fn() before
* disabling the clock. We use this to turn off PHYs etc. */
/* An extended version of the gated clk. This calls fn_en()/fn_dis
* before enabling/disabling the clock. We use this to turn on/off
* PHYs etc. */
struct clk_gate_fn {
struct clk_gate gate;
void (*fn)(void);
void (*fn_en)(void);
void (*fn_dis)(void);
};
#define to_clk_gate_fn(_gate) container_of(_gate, struct clk_gate_fn, gate)
#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw)
static int clk_gate_fn_enable(struct clk_hw *hw)
{
struct clk_gate *gate = to_clk_gate(hw);
struct clk_gate_fn *gate_fn = to_clk_gate_fn(gate);
int ret;
ret = clk_gate_ops.enable(hw);
if (!ret && gate_fn->fn_en)
gate_fn->fn_en();
return ret;
}
static void clk_gate_fn_disable(struct clk_hw *hw)
{
struct clk_gate *gate = to_clk_gate(hw);
struct clk_gate_fn *gate_fn = to_clk_gate_fn(gate);
if (gate_fn->fn)
gate_fn->fn();
if (gate_fn->fn_dis)
gate_fn->fn_dis();
clk_gate_ops.disable(hw);
}
......@@ -135,7 +167,7 @@ static struct clk __init *clk_register_gate_fn(struct device *dev,
const char *parent_name, unsigned long flags,
void __iomem *reg, u8 bit_idx,
u8 clk_gate_flags, spinlock_t *lock,
void (*fn)(void))
void (*fn_en)(void), void (*fn_dis)(void))
{
struct clk_gate_fn *gate_fn;
struct clk *clk;
......@@ -159,11 +191,14 @@ static struct clk __init *clk_register_gate_fn(struct device *dev,
gate_fn->gate.flags = clk_gate_flags;
gate_fn->gate.lock = lock;
gate_fn->gate.hw.init = &init;
gate_fn->fn = fn;
gate_fn->fn_en = fn_en;
gate_fn->fn_dis = fn_dis;
/* ops is the gate ops, but with our disable function */
if (clk_gate_fn_ops.disable != clk_gate_fn_disable) {
/* ops is the gate ops, but with our enable/disable functions */
if (clk_gate_fn_ops.enable != clk_gate_fn_enable ||
clk_gate_fn_ops.disable != clk_gate_fn_disable) {
clk_gate_fn_ops = clk_gate_ops;
clk_gate_fn_ops.enable = clk_gate_fn_enable;
clk_gate_fn_ops.disable = clk_gate_fn_disable;
}
......@@ -187,11 +222,12 @@ static struct clk __init *kirkwood_register_gate(const char *name, u8 bit_idx)
static struct clk __init *kirkwood_register_gate_fn(const char *name,
u8 bit_idx,
void (*fn)(void))
void (*fn_en)(void),
void (*fn_dis)(void))
{
return clk_register_gate_fn(NULL, name, "tclk", 0,
(void __iomem *)CLOCK_GATING_CTRL,
bit_idx, 0, &gating_lock, fn);
bit_idx, 0, &gating_lock, fn_en, fn_dis);
}
static struct clk *ge0, *ge1;
......@@ -208,18 +244,18 @@ void __init kirkwood_clk_init(void)
ge0 = kirkwood_register_gate("ge0", CGC_BIT_GE0);
ge1 = kirkwood_register_gate("ge1", CGC_BIT_GE1);
sata0 = kirkwood_register_gate_fn("sata0", CGC_BIT_SATA0,
disable_sata0);
enable_sata0, disable_sata0);
sata1 = kirkwood_register_gate_fn("sata1", CGC_BIT_SATA1,
disable_sata1);
enable_sata1, disable_sata1);
usb0 = kirkwood_register_gate("usb0", CGC_BIT_USB0);
sdio = kirkwood_register_gate("sdio", CGC_BIT_SDIO);
crypto = kirkwood_register_gate("crypto", CGC_BIT_CRYPTO);
xor0 = kirkwood_register_gate("xor0", CGC_BIT_XOR0);
xor1 = kirkwood_register_gate("xor1", CGC_BIT_XOR1);
pex0 = kirkwood_register_gate_fn("pex0", CGC_BIT_PEX0,
disable_pcie0);
NULL, disable_pcie0);
pex1 = kirkwood_register_gate_fn("pex1", CGC_BIT_PEX1,
disable_pcie1);
NULL, disable_pcie1);
audio = kirkwood_register_gate("audio", CGC_BIT_AUDIO);
kirkwood_register_gate("tdm", CGC_BIT_TDM);
kirkwood_register_gate("tsu", CGC_BIT_TSU);
......@@ -241,6 +277,12 @@ void __init kirkwood_clk_init(void)
orion_clkdev_add("0", "pcie", pex0);
orion_clkdev_add("1", "pcie", pex1);
orion_clkdev_add(NULL, "kirkwood-i2s", audio);
orion_clkdev_add(NULL, MV64XXX_I2C_CTLR_NAME ".0", runit);
/* Marvell says runit is used by SPI, UART, NAND, TWSI, ...,
* so should never be gated.
*/
clk_prepare_enable(runit);
}
/*****************************************************************************
......
......@@ -58,6 +58,11 @@ void dreamplug_init(void);
#else
static inline void dreamplug_init(void) {};
#endif
#ifdef CONFIG_MACH_TS219_DT
void qnap_dt_ts219_init(void);
#else
static inline void qnap_dt_ts219_init(void) {};
#endif
#ifdef CONFIG_MACH_DLINK_KIRKWOOD_DT
void dnskw_init(void);
......@@ -77,6 +82,18 @@ void ib62x0_init(void);
static inline void ib62x0_init(void) {};
#endif
#ifdef CONFIG_MACH_GOFLEXNET_DT
void goflexnet_init(void);
#else
static inline void goflexnet_init(void) {};
#endif
#ifdef CONFIG_MACH_LSXL_DT
void lsxl_init(void);
#else
static inline void lsxl_init(void) {};
#endif
/* early init functions not converted to fdt yet */
char *kirkwood_id(void);
void kirkwood_l2_init(void);
......
......@@ -9,20 +9,23 @@
*/
#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <mach/bridge-regs.h>
#include <plat/irq.h>
#include "common.h"
static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
{
BUG_ON(irq < IRQ_KIRKWOOD_GPIO_LOW_0_7);
BUG_ON(irq > IRQ_KIRKWOOD_GPIO_HIGH_16_23);
static int __initdata gpio0_irqs[4] = {
IRQ_KIRKWOOD_GPIO_LOW_0_7,
IRQ_KIRKWOOD_GPIO_LOW_8_15,
IRQ_KIRKWOOD_GPIO_LOW_16_23,
IRQ_KIRKWOOD_GPIO_LOW_24_31,
};
orion_gpio_irq_handler((irq - IRQ_KIRKWOOD_GPIO_LOW_0_7) << 3);
}
static int __initdata gpio1_irqs[4] = {
IRQ_KIRKWOOD_GPIO_HIGH_0_7,
IRQ_KIRKWOOD_GPIO_HIGH_8_15,
IRQ_KIRKWOOD_GPIO_HIGH_16_23,
0,
};
void __init kirkwood_init_irq(void)
{
......@@ -32,17 +35,8 @@ void __init kirkwood_init_irq(void)
/*
* Initialize gpiolib for GPIOs 0-49.
*/
orion_gpio_init(0, 32, GPIO_LOW_VIRT_BASE, 0,
IRQ_KIRKWOOD_GPIO_START);
irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_0_7, gpio_irq_handler);
irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_8_15, gpio_irq_handler);
irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_16_23, gpio_irq_handler);
irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_24_31, gpio_irq_handler);
orion_gpio_init(32, 18, GPIO_HIGH_VIRT_BASE, 0,
IRQ_KIRKWOOD_GPIO_START + 32);
irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_HIGH_0_7, gpio_irq_handler);
irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_HIGH_8_15, gpio_irq_handler);
irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_HIGH_16_23,
gpio_irq_handler);
orion_gpio_init(NULL, 0, 32, (void __iomem *)GPIO_LOW_VIRT_BASE, 0,
IRQ_KIRKWOOD_GPIO_START, gpio0_irqs);
orion_gpio_init(NULL, 32, 18, (void __iomem *)GPIO_HIGH_VIRT_BASE, 0,
IRQ_KIRKWOOD_GPIO_START + 32, gpio1_irqs);
}
......@@ -9,19 +9,17 @@
*/
#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/irq.h>
#include <mach/bridge-regs.h>
#include <plat/irq.h>
#include "common.h"
static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
{
BUG_ON(irq < IRQ_MV78XX0_GPIO_0_7 || irq > IRQ_MV78XX0_GPIO_24_31);
orion_gpio_irq_handler((irq - IRQ_MV78XX0_GPIO_0_7) << 3);
}
static int __initdata gpio0_irqs[4] = {
IRQ_MV78XX0_GPIO_0_7,
IRQ_MV78XX0_GPIO_8_15,
IRQ_MV78XX0_GPIO_16_23,
IRQ_MV78XX0_GPIO_24_31,
};
void __init mv78xx0_init_irq(void)
{
......@@ -34,11 +32,7 @@ void __init mv78xx0_init_irq(void)
* registers for core #1 are at an offset of 0x18 from those of
* core #0.)
*/
orion_gpio_init(0, 32, GPIO_VIRT_BASE,
orion_gpio_init(NULL, 0, 32, (void __iomem *)GPIO_VIRT_BASE,
mv78xx0_core_index() ? 0x18 : 0,
IRQ_MV78XX0_GPIO_START);
irq_set_chained_handler(IRQ_MV78XX0_GPIO_0_7, gpio_irq_handler);
irq_set_chained_handler(IRQ_MV78XX0_GPIO_8_15, gpio_irq_handler);
irq_set_chained_handler(IRQ_MV78XX0_GPIO_16_23, gpio_irq_handler);
irq_set_chained_handler(IRQ_MV78XX0_GPIO_24_31, gpio_irq_handler);
IRQ_MV78XX0_GPIO_START, gpio0_irqs);
}
......@@ -11,19 +11,16 @@
*/
#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <mach/bridge-regs.h>
#include <plat/irq.h>
#include "common.h"
static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
{
BUG_ON(irq < IRQ_ORION5X_GPIO_0_7 || irq > IRQ_ORION5X_GPIO_24_31);
orion_gpio_irq_handler((irq - IRQ_ORION5X_GPIO_0_7) << 3);
}
static int __initdata gpio0_irqs[4] = {
IRQ_ORION5X_GPIO_0_7,
IRQ_ORION5X_GPIO_8_15,
IRQ_ORION5X_GPIO_16_23,
IRQ_ORION5X_GPIO_24_31,
};
void __init orion5x_init_irq(void)
{
......@@ -32,9 +29,6 @@ void __init orion5x_init_irq(void)
/*
* Initialize gpiolib for GPIOs 0-31.
*/
orion_gpio_init(0, 32, GPIO_VIRT_BASE, 0, IRQ_ORION5X_GPIO_START);
irq_set_chained_handler(IRQ_ORION5X_GPIO_0_7, gpio_irq_handler);
irq_set_chained_handler(IRQ_ORION5X_GPIO_8_15, gpio_irq_handler);
irq_set_chained_handler(IRQ_ORION5X_GPIO_16_23, gpio_irq_handler);
irq_set_chained_handler(IRQ_ORION5X_GPIO_24_31, gpio_irq_handler);
orion_gpio_init(NULL, 0, 32, (void __iomem *)GPIO_VIRT_BASE, 0,
IRQ_ORION5X_GPIO_START, gpio0_irqs);
}
......@@ -47,6 +47,7 @@ void __init orion_clkdev_init(struct clk *tclk)
orion_clkdev_add(NULL, MV643XX_ETH_NAME ".2", tclk);
orion_clkdev_add(NULL, MV643XX_ETH_NAME ".3", tclk);
orion_clkdev_add(NULL, "orion_wdt", tclk);
orion_clkdev_add(NULL, MV64XXX_I2C_CTLR_NAME ".0", tclk);
}
/* Fill in the resources structure and link it into the platform
......
......@@ -8,15 +8,22 @@
* warranty of any kind, whether express or implied.
*/
#define DEBUG
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/bitops.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/leds.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/of_address.h>
#include <plat/gpio.h>
/*
* GPIO unit register offsets.
......@@ -38,6 +45,7 @@ struct orion_gpio_chip {
unsigned long valid_output;
int mask_offset;
int secondary_irq_base;
struct irq_domain *domain;
};
static void __iomem *GPIO_OUT(struct orion_gpio_chip *ochip)
......@@ -222,10 +230,10 @@ static int orion_gpio_to_irq(struct gpio_chip *chip, unsigned pin)
struct orion_gpio_chip *ochip =
container_of(chip, struct orion_gpio_chip, chip);
return ochip->secondary_irq_base + pin;
return irq_create_mapping(ochip->domain,
ochip->secondary_irq_base + pin);
}
/*
* Orion-specific GPIO API extensions.
*/
......@@ -353,12 +361,10 @@ static int gpio_irq_set_type(struct irq_data *d, u32 type)
int pin;
u32 u;
pin = d->irq - gc->irq_base;
pin = d->hwirq - ochip->secondary_irq_base;
u = readl(GPIO_IO_CONF(ochip)) & (1 << pin);
if (!u) {
printk(KERN_ERR "orion gpio_irq_set_type failed "
"(irq %d, pin %d).\n", d->irq, pin);
return -EINVAL;
}
......@@ -397,17 +403,53 @@ static int gpio_irq_set_type(struct irq_data *d, u32 type)
u &= ~(1 << pin); /* rising */
writel(u, GPIO_IN_POL(ochip));
}
return 0;
}
void __init orion_gpio_init(int gpio_base, int ngpio,
u32 base, int mask_offset, int secondary_irq_base)
static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
{
struct orion_gpio_chip *ochip = irq_get_handler_data(irq);
u32 cause, type;
int i;
if (ochip == NULL)
return;
cause = readl(GPIO_DATA_IN(ochip)) & readl(GPIO_LEVEL_MASK(ochip));
cause |= readl(GPIO_EDGE_CAUSE(ochip)) & readl(GPIO_EDGE_MASK(ochip));
for (i = 0; i < ochip->chip.ngpio; i++) {
int irq;
irq = ochip->secondary_irq_base + i;
if (!(cause & (1 << i)))
continue;
type = irqd_get_trigger_type(irq_get_irq_data(irq));
if ((type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) {
/* Swap polarity (race with GPIO line) */
u32 polarity;
polarity = readl(GPIO_IN_POL(ochip));
polarity ^= 1 << i;
writel(polarity, GPIO_IN_POL(ochip));
}
generic_handle_irq(irq);
}
}
void __init orion_gpio_init(struct device_node *np,
int gpio_base, int ngpio,
void __iomem *base, int mask_offset,
int secondary_irq_base,
int irqs[4])
{
struct orion_gpio_chip *ochip;
struct irq_chip_generic *gc;
struct irq_chip_type *ct;
char gc_label[16];
int i;
if (orion_gpio_chip_count == ARRAY_SIZE(orion_gpio_chips))
return;
......@@ -426,6 +468,10 @@ void __init orion_gpio_init(int gpio_base, int ngpio,
ochip->chip.base = gpio_base;
ochip->chip.ngpio = ngpio;
ochip->chip.can_sleep = 0;
#ifdef CONFIG_OF
ochip->chip.of_node = np;
#endif
spin_lock_init(&ochip->lock);
ochip->base = (void __iomem *)base;
ochip->valid_input = 0;
......@@ -435,8 +481,6 @@ void __init orion_gpio_init(int gpio_base, int ngpio,
gpiochip_add(&ochip->chip);
orion_gpio_chip_count++;
/*
* Mask and clear GPIO interrupts.
*/
......@@ -444,16 +488,28 @@ void __init orion_gpio_init(int gpio_base, int ngpio,
writel(0, GPIO_EDGE_MASK(ochip));
writel(0, GPIO_LEVEL_MASK(ochip));
gc = irq_alloc_generic_chip("orion_gpio_irq", 2, secondary_irq_base,
/* Setup the interrupt handlers. Each chip can have up to 4
* interrupt handlers, with each handler dealing with 8 GPIO
* pins. */
for (i = 0; i < 4; i++) {
if (irqs[i]) {
irq_set_handler_data(irqs[i], ochip);
irq_set_chained_handler(irqs[i], gpio_irq_handler);
}
}
gc = irq_alloc_generic_chip("orion_gpio_irq", 2,
secondary_irq_base,
ochip->base, handle_level_irq);
gc->private = ochip;
ct = gc->chip_types;
ct->regs.mask = ochip->mask_offset + GPIO_LEVEL_MASK_OFF;
ct->type = IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW;
ct->chip.irq_mask = irq_gc_mask_clr_bit;
ct->chip.irq_unmask = irq_gc_mask_set_bit;
ct->chip.irq_set_type = gpio_irq_set_type;
ct->chip.name = ochip->chip.label;
ct++;
ct->regs.mask = ochip->mask_offset + GPIO_EDGE_MASK_OFF;
......@@ -464,41 +520,69 @@ void __init orion_gpio_init(int gpio_base, int ngpio,
ct->chip.irq_unmask = irq_gc_mask_set_bit;
ct->chip.irq_set_type = gpio_irq_set_type;
ct->handler = handle_edge_irq;
ct->chip.name = ochip->chip.label;
irq_setup_generic_chip(gc, IRQ_MSK(ngpio), IRQ_GC_INIT_MASK_CACHE,
IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE);
}
void orion_gpio_irq_handler(int pinoff)
{
struct orion_gpio_chip *ochip;
u32 cause, type;
int i;
ochip = orion_gpio_chip_find(pinoff);
if (ochip == NULL)
return;
cause = readl(GPIO_DATA_IN(ochip)) & readl(GPIO_LEVEL_MASK(ochip));
cause |= readl(GPIO_EDGE_CAUSE(ochip)) & readl(GPIO_EDGE_MASK(ochip));
for (i = 0; i < ochip->chip.ngpio; i++) {
int irq;
/* Setup irq domain on top of the generic chip. */
ochip->domain = irq_domain_add_legacy(np,
ochip->chip.ngpio,
ochip->secondary_irq_base,
ochip->secondary_irq_base,
&irq_domain_simple_ops,
ochip);
if (!ochip->domain)
panic("%s: couldn't allocate irq domain (DT).\n",
ochip->chip.label);
irq = ochip->secondary_irq_base + i;
orion_gpio_chip_count++;
}
if (!(cause & (1 << i)))
continue;
#ifdef CONFIG_OF
static void __init orion_gpio_of_init_one(struct device_node *np,
int irq_gpio_base)
{
int ngpio, gpio_base, mask_offset;
void __iomem *base;
int ret, i;
int irqs[4];
int secondary_irq_base;
ret = of_property_read_u32(np, "ngpio", &ngpio);
if (ret)
goto out;
ret = of_property_read_u32(np, "mask-offset", &mask_offset);
if (ret == -EINVAL)
mask_offset = 0;
else
goto out;
base = of_iomap(np, 0);
if (!base)
goto out;
secondary_irq_base = irq_gpio_base + (32 * orion_gpio_chip_count);
gpio_base = 32 * orion_gpio_chip_count;
/* Get the interrupt numbers. Each chip can have up to 4
* interrupt handlers, with each handler dealing with 8 GPIO
* pins. */
for (i = 0; i < 4; i++)
irqs[i] = irq_of_parse_and_map(np, i);
orion_gpio_init(np, gpio_base, ngpio, base, mask_offset,
secondary_irq_base, irqs);
return;
out:
pr_err("%s: %s: missing mandatory property\n", __func__, np->name);
}
type = irqd_get_trigger_type(irq_get_irq_data(irq));
if ((type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) {
/* Swap polarity (race with GPIO line) */
u32 polarity;
void __init orion_gpio_of_init(int irq_gpio_base)
{
struct device_node *np;
polarity = readl(GPIO_IN_POL(ochip));
polarity ^= 1 << i;
writel(polarity, GPIO_IN_POL(ochip));
}
generic_handle_irq(irq);
}
for_each_compatible_node(np, NULL, "marvell,orion-gpio")
orion_gpio_of_init_one(np, irq_gpio_base);
}
#endif
......@@ -13,7 +13,7 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/irqdomain.h>
/*
* Orion-specific GPIO API extensions.
*/
......@@ -27,13 +27,11 @@ int orion_gpio_led_blink_set(unsigned gpio, int state,
void orion_gpio_set_valid(unsigned pin, int mode);
/* Initialize gpiolib. */
void __init orion_gpio_init(int gpio_base, int ngpio,
u32 base, int mask_offset, int secondary_irq_base);
/*
* GPIO interrupt handling.
*/
void orion_gpio_irq_handler(int irqoff);
void __init orion_gpio_init(struct device_node *np,
int gpio_base, int ngpio,
void __iomem *base, int mask_offset,
int secondary_irq_base,
int irq[4]);
void __init orion_gpio_of_init(int irq_gpio_base);
#endif
......@@ -12,6 +12,5 @@
#define __PLAT_IRQ_H
void orion_irq_init(unsigned int irq_start, void __iomem *maskaddr);
void __init orion_dt_init_irq(void);
#endif
......@@ -11,8 +11,12 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/io.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <plat/irq.h>
#include <plat/gpio.h>
void __init orion_irq_init(unsigned int irq_start, void __iomem *maskaddr)
{
......@@ -32,3 +36,39 @@ void __init orion_irq_init(unsigned int irq_start, void __iomem *maskaddr)
irq_setup_generic_chip(gc, IRQ_MSK(32), IRQ_GC_INIT_MASK_CACHE,
IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE);
}
#ifdef CONFIG_OF
static int __init orion_add_irq_domain(struct device_node *np,
struct device_node *interrupt_parent)
{
int i = 0, irq_gpio;
void __iomem *base;
do {
base = of_iomap(np, i);
if (base) {
orion_irq_init(i * 32, base);
i++;
}
} while (base);
irq_domain_add_legacy(np, i * 32, 0, 0,
&irq_domain_simple_ops, NULL);
irq_gpio = i * 32;
orion_gpio_of_init(irq_gpio);
return 0;
}
static const struct of_device_id orion_irq_match[] = {
{ .compatible = "marvell,orion-intc",
.data = orion_add_irq_domain, },
{},
};
void __init orion_dt_init_irq(void)
{
of_irq_init(orion_irq_match);
}
#endif
......@@ -65,6 +65,8 @@
#include <linux/mbus.h>
#include <linux/bitops.h>
#include <linux/gfp.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
......@@ -4026,7 +4028,7 @@ static int mv_platform_probe(struct platform_device *pdev)
struct ata_host *host;
struct mv_host_priv *hpriv;
struct resource *res;
int n_ports = 0;
int n_ports = 0, irq = 0;
int rc;
#if defined(CONFIG_HAVE_CLK)
int port;
......@@ -4050,8 +4052,14 @@ static int mv_platform_probe(struct platform_device *pdev)
return -EINVAL;
/* allocate host */
mv_platform_data = pdev->dev.platform_data;
n_ports = mv_platform_data->n_ports;
if (pdev->dev.of_node) {
of_property_read_u32(pdev->dev.of_node, "nr-ports", &n_ports);
irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
} else {
mv_platform_data = pdev->dev.platform_data;
n_ports = mv_platform_data->n_ports;
irq = platform_get_irq(pdev, 0);
}
host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
......@@ -4109,8 +4117,7 @@ static int mv_platform_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "slots %u ports %d\n",
(unsigned)MV_MAX_Q_DEPTH, host->n_ports);
rc = ata_host_activate(host, platform_get_irq(pdev, 0), mv_interrupt,
IRQF_SHARED, &mv6_sht);
rc = ata_host_activate(host, irq, mv_interrupt, IRQF_SHARED, &mv6_sht);
if (!rc)
return 0;
......@@ -4205,15 +4212,24 @@ static int mv_platform_resume(struct platform_device *pdev)
#define mv_platform_resume NULL
#endif
#ifdef CONFIG_OF
static struct of_device_id mv_sata_dt_ids[] __devinitdata = {
{ .compatible = "marvell,orion-sata", },
{},
};
MODULE_DEVICE_TABLE(of, mv_sata_dt_ids);
#endif
static struct platform_driver mv_platform_driver = {
.probe = mv_platform_probe,
.remove = __devexit_p(mv_platform_remove),
.suspend = mv_platform_suspend,
.resume = mv_platform_resume,
.driver = {
.name = DRV_NAME,
.owner = THIS_MODULE,
},
.probe = mv_platform_probe,
.remove = __devexit_p(mv_platform_remove),
.suspend = mv_platform_suspend,
.resume = mv_platform_resume,
.driver = {
.name = DRV_NAME,
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(mv_sata_dt_ids),
},
};
......
......@@ -1098,6 +1098,10 @@ static int mv_probe(struct platform_device *pdev)
crypto_unregister_alg(&mv_aes_alg_ecb);
err_irq:
free_irq(irq, cp);
if (!IS_ERR(cp->clk)) {
clk_disable_unprepare(cp->clk);
clk_put(cp->clk);
}
err_thread:
kthread_stop(cp->queue_th);
err_unmap_sram:
......
......@@ -839,6 +839,10 @@ static int __init mvsd_probe(struct platform_device *pdev)
if (r)
release_resource(r);
if (mmc)
if (!IS_ERR_OR_NULL(host->clk)) {
clk_disable_unprepare(host->clk);
clk_put(host->clk);
}
mmc_free_host(mmc);
return ret;
......
......@@ -183,6 +183,10 @@ static int __init orion_nand_probe(struct platform_device *pdev)
return 0;
no_dev:
if (!IS_ERR(clk)) {
clk_disable_unprepare(clk);
clk_put(clk);
}
platform_set_drvdata(pdev, NULL);
iounmap(io_base);
no_res:
......@@ -214,7 +218,7 @@ static int __devexit orion_nand_remove(struct platform_device *pdev)
#ifdef CONFIG_OF
static struct of_device_id orion_nand_of_match_table[] = {
{ .compatible = "mrvl,orion-nand", },
{ .compatible = "marvell,orion-nand", },
{},
};
#endif
......
......@@ -2983,6 +2983,12 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
return 0;
out:
#if defined(CONFIG_HAVE_CLK)
if (!IS_ERR(mp->clk)) {
clk_disable_unprepare(mp->clk);
clk_put(mp->clk);
}
#endif
free_netdev(dev);
return err;
......
......@@ -297,7 +297,7 @@ static int __exit mv_rtc_remove(struct platform_device *pdev)
#ifdef CONFIG_OF
static struct of_device_id rtc_mv_of_match_table[] = {
{ .compatible = "mrvl,orion-rtc", },
{ .compatible = "marvell,orion-rtc", },
{}
};
#endif
......
......@@ -357,7 +357,7 @@ config SPI_STMP3XXX
config SPI_TEGRA
tristate "Nvidia Tegra SPI controller"
depends on ARCH_TEGRA && TEGRA_SYSTEM_DMA
depends on ARCH_TEGRA && (TEGRA_SYSTEM_DMA || TEGRA20_APB_DMA)
help
SPI driver for NVidia Tegra SoCs
......@@ -384,6 +384,13 @@ config SPI_TXX9
help
SPI driver for Toshiba TXx9 MIPS SoCs
config SPI_XCOMM
tristate "Analog Devices AD-FMCOMMS1-EBZ SPI-I2C-bridge driver"
depends on I2C
help
Support for the SPI-I2C bridge found on the Analog Devices
AD-FMCOMMS1-EBZ board.
config SPI_XILINX
tristate "Xilinx SPI controller common module"
depends on HAS_IOMEM && EXPERIMENTAL
......
......@@ -61,5 +61,6 @@ obj-$(CONFIG_SPI_TI_SSP) += spi-ti-ssp.o
obj-$(CONFIG_SPI_TLE62X0) += spi-tle62x0.o
obj-$(CONFIG_SPI_TOPCLIFF_PCH) += spi-topcliff-pch.o
obj-$(CONFIG_SPI_TXX9) += spi-txx9.o
obj-$(CONFIG_SPI_XCOMM) += spi-xcomm.o
obj-$(CONFIG_SPI_XILINX) += spi-xilinx.o
......@@ -129,7 +129,7 @@ static void bcm63xx_spi_setup_transfer(struct spi_device *spi,
/* Find the closest clock configuration */
for (i = 0; i < SPI_CLK_MASK; i++) {
if (hz <= bcm63xx_spi_freq_table[i][0]) {
if (hz >= bcm63xx_spi_freq_table[i][0]) {
clk_cfg = bcm63xx_spi_freq_table[i][1];
break;
}
......
......@@ -235,7 +235,8 @@ static int spi_gpio_setup(struct spi_device *spi)
status = gpio_request(cs, dev_name(&spi->dev));
if (status)
return status;
status = gpio_direction_output(cs, spi->mode & SPI_CS_HIGH);
status = gpio_direction_output(cs,
!(spi->mode & SPI_CS_HIGH));
}
}
if (!status)
......
......@@ -626,7 +626,7 @@ static void spi_imx_chipselect(struct spi_device *spi, int is_active)
int active = is_active != BITBANG_CS_INACTIVE;
int dev_is_lowactive = !(spi->mode & SPI_CS_HIGH);
if (gpio < 0)
if (!gpio_is_valid(gpio))
return;
gpio_set_value(gpio, dev_is_lowactive ^ active);
......@@ -688,8 +688,6 @@ static int spi_imx_setupxfer(struct spi_device *spi,
config.speed_hz = spi->max_speed_hz;
if (!config.bpw)
config.bpw = spi->bits_per_word;
if (!config.speed_hz)
config.speed_hz = spi->max_speed_hz;
/* Initialize the functions for transfer */
if (config.bpw <= 8) {
......@@ -738,7 +736,7 @@ static int spi_imx_setup(struct spi_device *spi)
dev_dbg(&spi->dev, "%s: mode %d, %u bpw, %d hz\n", __func__,
spi->mode, spi->bits_per_word, spi->max_speed_hz);
if (gpio >= 0)
if (gpio_is_valid(gpio))
gpio_direction_output(gpio, spi->mode & SPI_CS_HIGH ? 0 : 1);
spi_imx_chipselect(spi, BITBANG_CS_INACTIVE);
......@@ -791,11 +789,11 @@ static int __devinit spi_imx_probe(struct platform_device *pdev)
for (i = 0; i < master->num_chipselect; i++) {
int cs_gpio = of_get_named_gpio(np, "cs-gpios", i);
if (cs_gpio < 0 && mxc_platform_info)
if (!gpio_is_valid(cs_gpio) && mxc_platform_info)
cs_gpio = mxc_platform_info->chipselect[i];
spi_imx->chipselect[i] = cs_gpio;
if (cs_gpio < 0)
if (!gpio_is_valid(cs_gpio))
continue;
ret = gpio_request(spi_imx->chipselect[i], DRIVER_NAME);
......@@ -897,7 +895,7 @@ static int __devinit spi_imx_probe(struct platform_device *pdev)
release_mem_region(res->start, resource_size(res));
out_gpio_free:
while (--i >= 0) {
if (spi_imx->chipselect[i] >= 0)
if (gpio_is_valid(spi_imx->chipselect[i]))
gpio_free(spi_imx->chipselect[i]);
}
spi_master_put(master);
......@@ -922,7 +920,7 @@ static int __devexit spi_imx_remove(struct platform_device *pdev)
iounmap(spi_imx->base);
for (i = 0; i < master->num_chipselect; i++)
if (spi_imx->chipselect[i] >= 0)
if (gpio_is_valid(spi_imx->chipselect[i]))
gpio_free(spi_imx->chipselect[i]);
spi_master_put(master);
......
......@@ -388,7 +388,8 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
if (tx != NULL) {
wait_for_completion(&mcspi_dma->dma_tx_completion);
dma_unmap_single(&spi->dev, xfer->tx_dma, count, DMA_TO_DEVICE);
dma_unmap_single(mcspi->dev, xfer->tx_dma, count,
DMA_TO_DEVICE);
/* for TX_ONLY mode, be sure all words have shifted out */
if (rx == NULL) {
......@@ -403,7 +404,8 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
if (rx != NULL) {
wait_for_completion(&mcspi_dma->dma_rx_completion);
dma_unmap_single(&spi->dev, xfer->rx_dma, count, DMA_FROM_DEVICE);
dma_unmap_single(mcspi->dev, xfer->rx_dma, count,
DMA_FROM_DEVICE);
omap2_mcspi_set_enable(spi, 0);
if (l & OMAP2_MCSPI_CHCONF_TURBO) {
......@@ -1032,7 +1034,7 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master,
return 0;
}
static int __init omap2_mcspi_master_setup(struct omap2_mcspi *mcspi)
static int __devinit omap2_mcspi_master_setup(struct omap2_mcspi *mcspi)
{
struct spi_master *master = mcspi->master;
struct omap2_mcspi_regs *ctx = &mcspi->ctx;
......
......@@ -17,6 +17,7 @@
#include <linux/io.h>
#include <linux/spi/spi.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/clk.h>
#include <asm/unaligned.h>
......@@ -45,7 +46,6 @@ struct orion_spi {
void __iomem *base;
unsigned int max_speed;
unsigned int min_speed;
struct orion_spi_info *spi_info;
struct clk *clk;
};
......@@ -450,11 +450,10 @@ static int __init orion_spi_probe(struct platform_device *pdev)
struct spi_master *master;
struct orion_spi *spi;
struct resource *r;
struct orion_spi_info *spi_info;
unsigned long tclk_hz;
int status = 0;
spi_info = pdev->dev.platform_data;
const u32 *iprop;
int size;
master = spi_alloc_master(&pdev->dev, sizeof *spi);
if (master == NULL) {
......@@ -464,6 +463,12 @@ static int __init orion_spi_probe(struct platform_device *pdev)
if (pdev->id != -1)
master->bus_num = pdev->id;
if (pdev->dev.of_node) {
iprop = of_get_property(pdev->dev.of_node, "cell-index",
&size);
if (iprop && size == sizeof(*iprop))
master->bus_num = *iprop;
}
/* we support only mode 0, and no options */
master->mode_bits = 0;
......@@ -476,7 +481,6 @@ static int __init orion_spi_probe(struct platform_device *pdev)
spi = spi_master_get_devdata(master);
spi->master = master;
spi->spi_info = spi_info;
spi->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(spi->clk)) {
......@@ -511,6 +515,7 @@ static int __init orion_spi_probe(struct platform_device *pdev)
if (orion_spi_reset(spi) < 0)
goto out_rel_mem;
master->dev.of_node = pdev->dev.of_node;
status = spi_register_master(master);
if (status < 0)
goto out_rel_mem;
......@@ -552,10 +557,17 @@ static int __exit orion_spi_remove(struct platform_device *pdev)
MODULE_ALIAS("platform:" DRIVER_NAME);
static const struct of_device_id orion_spi_of_match_table[] __devinitdata = {
{ .compatible = "marvell,orion-spi", },
{}
};
MODULE_DEVICE_TABLE(of, orion_spi_of_match_table);
static struct platform_driver orion_spi_driver = {
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(orion_spi_of_match_table),
},
.remove = __exit_p(orion_spi_remove),
};
......
......@@ -489,6 +489,11 @@ static void giveback(struct pl022 *pl022)
pl022->cur_transfer = NULL;
pl022->cur_chip = NULL;
spi_finalize_current_message(pl022->master);
/* disable the SPI/SSP operation */
writew((readw(SSP_CR1(pl022->virtbase)) &
(~SSP_CR1_MASK_SSE)), SSP_CR1(pl022->virtbase));
}
/**
......@@ -2048,6 +2053,9 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id)
printk(KERN_INFO "pl022: mapped registers from 0x%08x to %p\n",
adev->res.start, pl022->virtbase);
pm_runtime_enable(dev);
pm_runtime_resume(dev);
pl022->clk = clk_get(&adev->dev, NULL);
if (IS_ERR(pl022->clk)) {
status = PTR_ERR(pl022->clk);
......@@ -2158,6 +2166,7 @@ pl022_remove(struct amba_device *adev)
clk_disable(pl022->clk);
clk_unprepare(pl022->clk);
clk_put(pl022->clk);
pm_runtime_disable(&adev->dev);
iounmap(pl022->virtbase);
amba_release_regions(adev);
tasklet_disable(&pl022->pump_transfers);
......@@ -2251,15 +2260,6 @@ static struct vendor_data vendor_st_pl023 = {
.loopback = false,
};
static struct vendor_data vendor_db5500_pl023 = {
.fifodepth = 32,
.max_bpw = 32,
.unidir = false,
.extended_cr = true,
.pl023 = true,
.loopback = true,
};
static struct amba_id pl022_ids[] = {
{
/*
......@@ -2291,11 +2291,6 @@ static struct amba_id pl022_ids[] = {
.mask = 0xffffffff,
.data = &vendor_st_pl023,
},
{
.id = 0x10080023,
.mask = 0xffffffff,
.data = &vendor_db5500_pl023,
},
{ 0, 0 },
};
......
......@@ -30,6 +30,7 @@
#include <linux/delay.h>
#include <linux/spi/spi.h>
#include <linux/dmaengine.h>
#include <mach/dma.h>
......@@ -162,12 +163,23 @@ struct spi_tegra_data {
* require transfers to be 4 byte aligned we need a bounce buffer
* for the generic case.
*/
int dma_req_len;
#if defined(CONFIG_TEGRA_SYSTEM_DMA)
struct tegra_dma_req rx_dma_req;
struct tegra_dma_channel *rx_dma;
#else
struct dma_chan *rx_dma;
struct dma_slave_config sconfig;
struct dma_async_tx_descriptor *rx_dma_desc;
dma_cookie_t rx_cookie;
#endif
u32 *rx_bb;
dma_addr_t rx_bb_phys;
};
#if !defined(CONFIG_TEGRA_SYSTEM_DMA)
static void tegra_spi_rx_dma_complete(void *args);
#endif
static inline unsigned long spi_tegra_readl(struct spi_tegra_data *tspi,
unsigned long reg)
......@@ -190,10 +202,24 @@ static void spi_tegra_go(struct spi_tegra_data *tspi)
val = spi_tegra_readl(tspi, SLINK_DMA_CTL);
val &= ~SLINK_DMA_BLOCK_SIZE(~0) & ~SLINK_DMA_EN;
val |= SLINK_DMA_BLOCK_SIZE(tspi->rx_dma_req.size / 4 - 1);
val |= SLINK_DMA_BLOCK_SIZE(tspi->dma_req_len / 4 - 1);
spi_tegra_writel(tspi, val, SLINK_DMA_CTL);
#if defined(CONFIG_TEGRA_SYSTEM_DMA)
tspi->rx_dma_req.size = tspi->dma_req_len;
tegra_dma_enqueue_req(tspi->rx_dma, &tspi->rx_dma_req);
#else
tspi->rx_dma_desc = dmaengine_prep_slave_single(tspi->rx_dma,
tspi->rx_bb_phys, tspi->dma_req_len,
DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT);
if (!tspi->rx_dma_desc) {
dev_err(&tspi->pdev->dev, "dmaengine slave prep failed\n");
return;
}
tspi->rx_dma_desc->callback = tegra_spi_rx_dma_complete;
tspi->rx_dma_desc->callback_param = tspi;
tspi->rx_cookie = dmaengine_submit(tspi->rx_dma_desc);
dma_async_issue_pending(tspi->rx_dma);
#endif
val |= SLINK_DMA_EN;
spi_tegra_writel(tspi, val, SLINK_DMA_CTL);
......@@ -221,7 +247,7 @@ static unsigned spi_tegra_fill_tx_fifo(struct spi_tegra_data *tspi,
spi_tegra_writel(tspi, val, SLINK_TX_FIFO);
}
tspi->rx_dma_req.size = len / tspi->cur_bytes_per_word * 4;
tspi->dma_req_len = len / tspi->cur_bytes_per_word * 4;
return len;
}
......@@ -318,9 +344,8 @@ static void spi_tegra_start_message(struct spi_device *spi,
spi_tegra_start_transfer(spi, t);
}
static void tegra_spi_rx_dma_complete(struct tegra_dma_req *req)
static void handle_spi_rx_dma_complete(struct spi_tegra_data *tspi)
{
struct spi_tegra_data *tspi = req->dev;
unsigned long flags;
struct spi_message *m;
struct spi_device *spi;
......@@ -380,6 +405,19 @@ static void tegra_spi_rx_dma_complete(struct tegra_dma_req *req)
spin_unlock_irqrestore(&tspi->lock, flags);
}
#if defined(CONFIG_TEGRA_SYSTEM_DMA)
static void tegra_spi_rx_dma_complete(struct tegra_dma_req *req)
{
struct spi_tegra_data *tspi = req->dev;
handle_spi_rx_dma_complete(tspi);
}
#else
static void tegra_spi_rx_dma_complete(void *args)
{
struct spi_tegra_data *tspi = args;
handle_spi_rx_dma_complete(tspi);
}
#endif
static int spi_tegra_setup(struct spi_device *spi)
{
......@@ -471,6 +509,9 @@ static int __devinit spi_tegra_probe(struct platform_device *pdev)
struct spi_tegra_data *tspi;
struct resource *r;
int ret;
#if !defined(CONFIG_TEGRA_SYSTEM_DMA)
dma_cap_mask_t mask;
#endif
master = spi_alloc_master(&pdev->dev, sizeof *tspi);
if (master == NULL) {
......@@ -522,12 +563,24 @@ static int __devinit spi_tegra_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&tspi->queue);
#if defined(CONFIG_TEGRA_SYSTEM_DMA)
tspi->rx_dma = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT);
if (!tspi->rx_dma) {
dev_err(&pdev->dev, "can not allocate rx dma channel\n");
ret = -ENODEV;
goto err3;
}
#else
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);
tspi->rx_dma = dma_request_channel(mask, NULL, NULL);
if (!tspi->rx_dma) {
dev_err(&pdev->dev, "can not allocate rx dma channel\n");
ret = -ENODEV;
goto err3;
}
#endif
tspi->rx_bb = dma_alloc_coherent(&pdev->dev, sizeof(u32) * BB_LEN,
&tspi->rx_bb_phys, GFP_KERNEL);
......@@ -537,6 +590,7 @@ static int __devinit spi_tegra_probe(struct platform_device *pdev)
goto err4;
}
#if defined(CONFIG_TEGRA_SYSTEM_DMA)
tspi->rx_dma_req.complete = tegra_spi_rx_dma_complete;
tspi->rx_dma_req.to_memory = 1;
tspi->rx_dma_req.dest_addr = tspi->rx_bb_phys;
......@@ -546,6 +600,23 @@ static int __devinit spi_tegra_probe(struct platform_device *pdev)
tspi->rx_dma_req.source_wrap = 4;
tspi->rx_dma_req.req_sel = spi_tegra_req_sels[pdev->id];
tspi->rx_dma_req.dev = tspi;
#else
/* Dmaengine Dma slave config */
tspi->sconfig.src_addr = tspi->phys + SLINK_RX_FIFO;
tspi->sconfig.dst_addr = tspi->phys + SLINK_RX_FIFO;
tspi->sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
tspi->sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
tspi->sconfig.slave_id = spi_tegra_req_sels[pdev->id];
tspi->sconfig.src_maxburst = 1;
tspi->sconfig.dst_maxburst = 1;
ret = dmaengine_device_control(tspi->rx_dma,
DMA_SLAVE_CONFIG, (unsigned long) &tspi->sconfig);
if (ret < 0) {
dev_err(&pdev->dev, "can not do slave configure for dma %d\n",
ret);
goto err4;
}
#endif
master->dev.of_node = pdev->dev.of_node;
ret = spi_register_master(master);
......@@ -559,7 +630,11 @@ static int __devinit spi_tegra_probe(struct platform_device *pdev)
dma_free_coherent(&pdev->dev, sizeof(u32) * BB_LEN,
tspi->rx_bb, tspi->rx_bb_phys);
err4:
#if defined(CONFIG_TEGRA_SYSTEM_DMA)
tegra_dma_free_channel(tspi->rx_dma);
#else
dma_release_channel(tspi->rx_dma);
#endif
err3:
clk_put(tspi->clk);
err2:
......@@ -581,7 +656,11 @@ static int __devexit spi_tegra_remove(struct platform_device *pdev)
tspi = spi_master_get_devdata(master);
spi_unregister_master(master);
#if defined(CONFIG_TEGRA_SYSTEM_DMA)
tegra_dma_free_channel(tspi->rx_dma);
#else
dma_release_channel(tspi->rx_dma);
#endif
dma_free_coherent(&pdev->dev, sizeof(u32) * BB_LEN,
tspi->rx_bb, tspi->rx_bb_phys);
......
/*
* Analog Devices AD-FMCOMMS1-EBZ board I2C-SPI bridge driver
*
* Copyright 2012 Analog Devices Inc.
* Author: Lars-Peter Clausen <lars@metafoo.de>
*
* Licensed under the GPL-2 or later.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/spi/spi.h>
#include <asm/unaligned.h>
#define SPI_XCOMM_SETTINGS_LEN_OFFSET 10
#define SPI_XCOMM_SETTINGS_3WIRE BIT(6)
#define SPI_XCOMM_SETTINGS_CS_HIGH BIT(5)
#define SPI_XCOMM_SETTINGS_SAMPLE_END BIT(4)
#define SPI_XCOMM_SETTINGS_CPHA BIT(3)
#define SPI_XCOMM_SETTINGS_CPOL BIT(2)
#define SPI_XCOMM_SETTINGS_CLOCK_DIV_MASK 0x3
#define SPI_XCOMM_SETTINGS_CLOCK_DIV_64 0x2
#define SPI_XCOMM_SETTINGS_CLOCK_DIV_16 0x1
#define SPI_XCOMM_SETTINGS_CLOCK_DIV_4 0x0
#define SPI_XCOMM_CMD_UPDATE_CONFIG 0x03
#define SPI_XCOMM_CMD_WRITE 0x04
#define SPI_XCOMM_CLOCK 48000000
struct spi_xcomm {
struct i2c_client *i2c;
uint16_t settings;
uint16_t chipselect;
unsigned int current_speed;
uint8_t buf[63];
};
static int spi_xcomm_sync_config(struct spi_xcomm *spi_xcomm, unsigned int len)
{
uint16_t settings;
uint8_t *buf = spi_xcomm->buf;
settings = spi_xcomm->settings;
settings |= len << SPI_XCOMM_SETTINGS_LEN_OFFSET;
buf[0] = SPI_XCOMM_CMD_UPDATE_CONFIG;
put_unaligned_be16(settings, &buf[1]);
put_unaligned_be16(spi_xcomm->chipselect, &buf[3]);
return i2c_master_send(spi_xcomm->i2c, buf, 5);
}
static void spi_xcomm_chipselect(struct spi_xcomm *spi_xcomm,
struct spi_device *spi, int is_active)
{
unsigned long cs = spi->chip_select;
uint16_t chipselect = spi_xcomm->chipselect;
if (is_active)
chipselect |= BIT(cs);
else
chipselect &= ~BIT(cs);
spi_xcomm->chipselect = chipselect;
}
static int spi_xcomm_setup_transfer(struct spi_xcomm *spi_xcomm,
struct spi_device *spi, struct spi_transfer *t, unsigned int *settings)
{
unsigned int speed;
if ((t->bits_per_word && t->bits_per_word != 8) || t->len > 62)
return -EINVAL;
speed = t->speed_hz ? t->speed_hz : spi->max_speed_hz;
if (speed != spi_xcomm->current_speed) {
unsigned int divider = DIV_ROUND_UP(SPI_XCOMM_CLOCK, speed);
if (divider >= 64)
*settings |= SPI_XCOMM_SETTINGS_CLOCK_DIV_64;
else if (divider >= 16)
*settings |= SPI_XCOMM_SETTINGS_CLOCK_DIV_16;
else
*settings |= SPI_XCOMM_SETTINGS_CLOCK_DIV_4;
spi_xcomm->current_speed = speed;
}
if (spi->mode & SPI_CPOL)
*settings |= SPI_XCOMM_SETTINGS_CPOL;
else
*settings &= ~SPI_XCOMM_SETTINGS_CPOL;
if (spi->mode & SPI_CPHA)
*settings &= ~SPI_XCOMM_SETTINGS_CPHA;
else
*settings |= SPI_XCOMM_SETTINGS_CPHA;
if (spi->mode & SPI_3WIRE)
*settings |= SPI_XCOMM_SETTINGS_3WIRE;
else
*settings &= ~SPI_XCOMM_SETTINGS_3WIRE;
return 0;
}
static int spi_xcomm_txrx_bufs(struct spi_xcomm *spi_xcomm,
struct spi_device *spi, struct spi_transfer *t)
{
int ret;
if (t->tx_buf) {
spi_xcomm->buf[0] = SPI_XCOMM_CMD_WRITE;
memcpy(spi_xcomm->buf + 1, t->tx_buf, t->len);
ret = i2c_master_send(spi_xcomm->i2c, spi_xcomm->buf, t->len + 1);
if (ret < 0)
return ret;
else if (ret != t->len + 1)
return -EIO;
} else if (t->rx_buf) {
ret = i2c_master_recv(spi_xcomm->i2c, t->rx_buf, t->len);
if (ret < 0)
return ret;
else if (ret != t->len)
return -EIO;
}
return t->len;
}
static int spi_xcomm_transfer_one(struct spi_master *master,
struct spi_message *msg)
{
struct spi_xcomm *spi_xcomm = spi_master_get_devdata(master);
unsigned int settings = spi_xcomm->settings;
struct spi_device *spi = msg->spi;
unsigned cs_change = 0;
struct spi_transfer *t;
bool is_first = true;
int status = 0;
bool is_last;
is_first = true;
spi_xcomm_chipselect(spi_xcomm, spi, true);
list_for_each_entry(t, &msg->transfers, transfer_list) {
if (!t->tx_buf && !t->rx_buf && t->len) {
status = -EINVAL;
break;
}
status = spi_xcomm_setup_transfer(spi_xcomm, spi, t, &settings);
if (status < 0)
break;
is_last = list_is_last(&t->transfer_list, &msg->transfers);
cs_change = t->cs_change;
if (cs_change ^ is_last)
settings |= BIT(5);
else
settings &= ~BIT(5);
if (t->rx_buf) {
spi_xcomm->settings = settings;
status = spi_xcomm_sync_config(spi_xcomm, t->len);
if (status < 0)
break;
} else if (settings != spi_xcomm->settings || is_first) {
spi_xcomm->settings = settings;
status = spi_xcomm_sync_config(spi_xcomm, 0);
if (status < 0)
break;
}
if (t->len) {
status = spi_xcomm_txrx_bufs(spi_xcomm, spi, t);
if (status < 0)
break;
if (status > 0)
msg->actual_length += status;
}
status = 0;
if (t->delay_usecs)
udelay(t->delay_usecs);
is_first = false;
}
if (status != 0 || !cs_change)
spi_xcomm_chipselect(spi_xcomm, spi, false);
msg->status = status;
spi_finalize_current_message(master);
return status;
}
static int spi_xcomm_setup(struct spi_device *spi)
{
if (spi->bits_per_word != 8)
return -EINVAL;
return 0;
}
static int __devinit spi_xcomm_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct spi_xcomm *spi_xcomm;
struct spi_master *master;
int ret;
master = spi_alloc_master(&i2c->dev, sizeof(*spi_xcomm));
if (!master)
return -ENOMEM;
spi_xcomm = spi_master_get_devdata(master);
spi_xcomm->i2c = i2c;
master->num_chipselect = 16;
master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_3WIRE;
master->flags = SPI_MASTER_HALF_DUPLEX;
master->setup = spi_xcomm_setup;
master->transfer_one_message = spi_xcomm_transfer_one;
master->dev.of_node = i2c->dev.of_node;
i2c_set_clientdata(i2c, master);
ret = spi_register_master(master);
if (ret < 0)
spi_master_put(master);
return ret;
}
static int __devexit spi_xcomm_remove(struct i2c_client *i2c)
{
struct spi_master *master = i2c_get_clientdata(i2c);
spi_unregister_master(master);
return 0;
}
static const struct i2c_device_id spi_xcomm_ids[] = {
{ "spi-xcomm" },
{ },
};
static struct i2c_driver spi_xcomm_driver = {
.driver = {
.name = "spi-xcomm",
.owner = THIS_MODULE,
},
.id_table = spi_xcomm_ids,
.probe = spi_xcomm_probe,
.remove = __devexit_p(spi_xcomm_remove),
};
module_i2c_driver(spi_xcomm_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
MODULE_DESCRIPTION("Analog Devices AD-FMCOMMS1-EBZ board I2C-SPI bridge driver");
......@@ -53,7 +53,7 @@ modalias_show(struct device *dev, struct device_attribute *a, char *buf)
{
const struct spi_device *spi = to_spi_device(dev);
return sprintf(buf, "%s\n", spi->modalias);
return sprintf(buf, "%s%s\n", SPI_MODULE_PREFIX, spi->modalias);
}
static struct device_attribute spi_dev_attrs[] = {
......
......@@ -298,6 +298,10 @@ static int __devinit ehci_orion_drv_probe(struct platform_device *pdev)
err4:
usb_put_hcd(hcd);
err3:
if (!IS_ERR(clk)) {
clk_disable_unprepare(clk);
clk_put(clk);
}
iounmap(regs);
err2:
release_mem_region(res->start, resource_size(res));
......
......@@ -25,6 +25,7 @@
#include <linux/io.h>
#include <linux/spinlock.h>
#include <linux/clk.h>
#include <linux/of.h>
#include <mach/bridge-regs.h>
/*
......@@ -295,6 +296,12 @@ static void orion_wdt_shutdown(struct platform_device *pdev)
orion_wdt_disable();
}
static const struct of_device_id orion_wdt_of_match_table[] __devinitdata = {
{ .compatible = "marvell,orion-wdt", },
{},
};
MODULE_DEVICE_TABLE(of, orion_wdt_of_match_table);
static struct platform_driver orion_wdt_driver = {
.probe = orion_wdt_probe,
.remove = __devexit_p(orion_wdt_remove),
......@@ -302,6 +309,7 @@ static struct platform_driver orion_wdt_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "orion_wdt",
.of_match_table = of_match_ptr(orion_wdt_of_match_table),
},
};
......
......@@ -231,6 +231,7 @@ enum ssp_chip_select {
struct dma_chan;
/**
* struct pl022_ssp_master - device.platform_data for SPI controller devices.
* @bus_id: identifier for this bus
* @num_chipselect: chipselects are used to distinguish individual
* SPI slaves, and are numbered from zero to num_chipselects - 1.
* each slave has a chipselect signal, but it's common that not
......@@ -259,19 +260,13 @@ struct pl022_ssp_controller {
* struct ssp_config_chip - spi_board_info.controller_data for SPI
* slave devices, copied to spi_device.controller_data.
*
* @lbm: used for test purpose to internally connect RX and TX
* @iface: Interface type(Motorola, TI, Microwire, Universal)
* @hierarchy: sets whether interface is master or slave
* @slave_tx_disable: SSPTXD is disconnected (in slave mode only)
* @clk_freq: Tune freq parameters of SSP(when in master mode)
* @endian_rx: Endianess of Data in Rx FIFO
* @endian_tx: Endianess of Data in Tx FIFO
* @data_size: Width of data element(4 to 32 bits)
* @com_mode: communication mode: polling, Interrupt or DMA
* @rx_lev_trig: Rx FIFO watermark level (for IT & DMA mode)
* @tx_lev_trig: Tx FIFO watermark level (for IT & DMA mode)
* @clk_phase: Motorola SPI interface Clock phase
* @clk_pol: Motorola SPI interface Clock polarity
* @ctrl_len: Microwire interface: Control length
* @wait_state: Microwire interface: Wait state
* @duplex: Microwire interface: Full/Half duplex
......@@ -279,8 +274,6 @@ struct pl022_ssp_controller {
* before sampling the incoming line
* @cs_control: function pointer to board-specific function to
* assert/deassert I/O port to control HW generation of devices chip-select.
* @dma_xfer_type: Type of DMA xfer (Mem-to-periph or Periph-to-Periph)
* @dma_config: DMA configuration for SSP controller and peripheral
*/
struct pl022_config_chip {
enum ssp_interface iface;
......
......@@ -458,7 +458,13 @@ static __devinit int kirkwood_i2s_dev_probe(struct platform_device *pdev)
}
clk_prepare_enable(priv->clk);
return snd_soc_register_dai(&pdev->dev, &kirkwood_i2s_dai);
err = snd_soc_register_dai(&pdev->dev, &kirkwood_i2s_dai);
if (!err)
return 0;
dev_err(&pdev->dev, "snd_soc_register_dai failed\n");
clk_disable_unprepare(priv->clk);
clk_put(priv->clk);
err_ioremap:
iounmap(priv->io);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment