Commit 2a9f23d8 authored by Arnd Bergmann's avatar Arnd Bergmann

Merge branch 'at91-3.4-cleanup2-DT2' of git://github.com/at91linux/linux-at91 into next/dt

* 'at91-3.4-cleanup2-DT2' of git://github.com/at91linux/linux-at91: (23 commits)
  ARM: at91: dt: enable usb ehci for sam9g45 and sam9x5
  ARM: at91: usb ehci add dt support
  ARM: at91: dt: enable usb ohci for sam9g20, sam9g45 amd sam9x5
  ARM: at91: usb ohci add dt support
  ARM: at91: add Shutdown Controller (SHDWC) DT support
  ARM: at91: add ram controller DT support
  ARM: at91: add RSTC (Reset Controller) dt support
  ARM: at91: always enable sam9 restart
  ARM: at91: add pmc DT support
  ARM: at91/dt: add specific DT soc init
  ARM: at91/dt: add Calao DAB-MMX daugther board support for USB-A9G20
  ARM: at91: sam9x5 add i2c DT support
  ARM: at91: sam9g45 add i2c DT support
  ARM: at91: usb_a9g20 add DT i2c support
  ARM: at91: sam9g20 add i2c DT support
  i2c/gpio: add DT support
  ARM: at91: sam9x5 add nand support
  atmel/nand: add DT support
  of/mtd/nand: add generic bindings and helpers
  of: introduce helper to manage boolean
  ...
parents cdc3df6f 62c5553a
...@@ -30,3 +30,63 @@ One interrupt per TC channel in a TC block: ...@@ -30,3 +30,63 @@ One interrupt per TC channel in a TC block:
reg = <0xfffdc000 0x100>; reg = <0xfffdc000 0x100>;
interrupts = <26 4 27 4 28 4>; interrupts = <26 4 27 4 28 4>;
}; };
RSTC Reset Controller required properties:
- compatible: Should be "atmel,<chip>-rstc".
<chip> can be "at91sam9260" or "at91sam9g45"
- reg: Should contain registers location and length
Example:
rstc@fffffd00 {
compatible = "atmel,at91sam9260-rstc";
reg = <0xfffffd00 0x10>;
};
RAMC SDRAM/DDR Controller required properties:
- compatible: Should be "atmel,at91sam9260-sdramc",
"atmel,at91sam9g45-ddramc",
- reg: Should contain registers location and length
For at91sam9263 and at91sam9g45 you must specify 2 entries.
Examples:
ramc0: ramc@ffffe800 {
compatible = "atmel,at91sam9g45-ddramc";
reg = <0xffffe800 0x200>;
};
ramc0: ramc@ffffe400 {
compatible = "atmel,at91sam9g45-ddramc";
reg = <0xffffe400 0x200
0xffffe600 0x200>;
};
SHDWC Shutdown Controller
required properties:
- compatible: Should be "atmel,<chip>-shdwc".
<chip> can be "at91sam9260", "at91sam9rl" or "at91sam9x5".
- reg: Should contain registers location and length
optional properties:
- atmel,wakeup-mode: String, operation mode of the wakeup mode.
Supported values are: "none", "high", "low", "any".
- atmel,wakeup-counter: Counter on Wake-up 0 (between 0x0 and 0xf).
optional at91sam9260 properties:
- atmel,wakeup-rtt-timer: boolean to enable Real-time Timer Wake-up.
optional at91sam9rl properties:
- atmel,wakeup-rtc-timer: boolean to enable Real-time Clock Wake-up.
- atmel,wakeup-rtt-timer: boolean to enable Real-time Timer Wake-up.
optional at91sam9x5 properties:
- atmel,wakeup-rtc-timer: boolean to enable Real-time Clock Wake-up.
Example:
rstc@fffffd00 {
compatible = "atmel,at91sam9260-rstc";
reg = <0xfffffd00 0x10>;
};
* Power Management Controller (PMC)
Required properties:
- compatible: Should be "atmel,at91rm9200-pmc"
- reg: Should contain PMC registers location and length
Examples:
pmc: pmc@fffffc00 {
compatible = "atmel,at91rm9200-pmc";
reg = <0xfffffc00 0x100>;
};
Device-Tree bindings for i2c gpio driver
Required properties:
- compatible = "i2c-gpio";
- gpios: sda and scl gpio
Optional properties:
- i2c-gpio,sda-open-drain: sda as open drain
- i2c-gpio,scl-open-drain: scl as open drain
- i2c-gpio,scl-output-only: scl as output only
- i2c-gpio,delay-us: delay between GPIO operations (may depend on each platform)
- i2c-gpio,timeout-ms: timeout to get data
Example nodes:
i2c@0 {
compatible = "i2c-gpio";
gpios = <&pioA 23 0 /* sda */
&pioA 24 0 /* scl */
>;
i2c-gpio,sda-open-drain;
i2c-gpio,scl-open-drain;
i2c-gpio,delay-us = <2>; /* ~100 kHz */
#address-cells = <1>;
#size-cells = <0>;
rv3029c2@56 {
compatible = "rv3029c2";
reg = <0x56>;
};
};
Atmel NAND flash
Required properties:
- compatible : "atmel,at91rm9200-nand".
- reg : should specify localbus address and size used for the chip,
and if availlable the ECC.
- atmel,nand-addr-offset : offset for the address latch.
- atmel,nand-cmd-offset : offset for the command latch.
- #address-cells, #size-cells : Must be present if the device has sub-nodes
representing partitions.
- gpios : specifies the gpio pins to control the NAND device. detect is an
optional gpio and may be set to 0 if not present.
Optional properties:
- nand-ecc-mode : String, operation mode of the NAND ecc mode, soft by default.
Supported values are: "none", "soft", "hw", "hw_syndrome", "hw_oob_first",
"soft_bch".
- nand-bus-width : 8 or 16 bus width if not present 8
- nand-on-flash-bbt: boolean to enable on flash bbt option if not present false
Examples:
nand0: nand@40000000,0 {
compatible = "atmel,at91rm9200-nand";
#address-cells = <1>;
#size-cells = <1>;
reg = <0x40000000 0x10000000
0xffffe800 0x200
>;
atmel,nand-addr-offset = <21>;
atmel,nand-cmd-offset = <22>;
nand-on-flash-bbt;
nand-ecc-mode = "soft";
gpios = <&pioC 13 0
&pioC 14 0
0
>;
partition@0 {
...
};
};
* MTD generic binding
- nand-ecc-mode : String, operation mode of the NAND ecc mode.
Supported values are: "none", "soft", "hw", "hw_syndrome", "hw_oob_first",
"soft_bch".
- nand-bus-width : 8 or 16 bus width if not present 8
- nand-on-flash-bbt: boolean to enable on flash bbt option if not present false
Atmel SOC USB controllers
OHCI
Required properties:
- compatible: Should be "atmel,at91rm9200-ohci" for USB controllers
used in host mode.
- num-ports: Number of ports.
- atmel,vbus-gpio: If present, specifies a gpio that needs to be
activated for the bus to be powered.
- atmel,oc-gpio: If present, specifies a gpio that needs to be
activated for the overcurrent detection.
usb0: ohci@00500000 {
compatible = "atmel,at91rm9200-ohci", "usb-ohci";
reg = <0x00500000 0x100000>;
interrupts = <20 4>;
num-ports = <2>;
};
EHCI
Required properties:
- compatible: Should be "atmel,at91sam9g45-ehci" for USB controllers
used in host mode.
usb1: ehci@00800000 {
compatible = "atmel,at91sam9g45-ehci", "usb-ehci";
reg = <0x00800000 0x100000>;
interrupts = <22 4>;
};
...@@ -59,6 +59,26 @@ aic: interrupt-controller@fffff000 { ...@@ -59,6 +59,26 @@ aic: interrupt-controller@fffff000 {
reg = <0xfffff000 0x200>; reg = <0xfffff000 0x200>;
}; };
ramc0: ramc@ffffea00 {
compatible = "atmel,at91sam9260-sdramc";
reg = <0xffffea00 0x200>;
};
pmc: pmc@fffffc00 {
compatible = "atmel,at91rm9200-pmc";
reg = <0xfffffc00 0x100>;
};
rstc@fffffd00 {
compatible = "atmel,at91sam9260-rstc";
reg = <0xfffffd00 0x10>;
};
shdwc@fffffd10 {
compatible = "atmel,at91sam9260-shdwc";
reg = <0xfffffd10 0x10>;
};
pit: timer@fffffd30 { pit: timer@fffffd30 {
compatible = "atmel,at91sam9260-pit"; compatible = "atmel,at91sam9260-pit";
reg = <0xfffffd30 0xf>; reg = <0xfffffd30 0xf>;
...@@ -172,5 +192,41 @@ macb0: ethernet@fffc4000 { ...@@ -172,5 +192,41 @@ macb0: ethernet@fffc4000 {
status = "disabled"; status = "disabled";
}; };
}; };
nand0: nand@40000000 {
compatible = "atmel,at91rm9200-nand";
#address-cells = <1>;
#size-cells = <1>;
reg = <0x40000000 0x10000000
0xffffe800 0x200
>;
atmel,nand-addr-offset = <21>;
atmel,nand-cmd-offset = <22>;
gpios = <&pioC 13 0
&pioC 14 0
0
>;
status = "disabled";
};
usb0: ohci@00500000 {
compatible = "atmel,at91rm9200-ohci", "usb-ohci";
reg = <0x00500000 0x100000>;
interrupts = <20 4>;
status = "disabled";
};
};
i2c@0 {
compatible = "i2c-gpio";
gpios = <&pioA 23 0 /* sda */
&pioA 24 0 /* scl */
>;
i2c-gpio,sda-open-drain;
i2c-gpio,scl-open-drain;
i2c-gpio,delay-us = <2>; /* ~100 kHz */
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
}; };
}; };
...@@ -15,7 +15,7 @@ / { ...@@ -15,7 +15,7 @@ / {
compatible = "atmel,at91sam9g25ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9"; compatible = "atmel,at91sam9g25ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9";
chosen { chosen {
bootargs = "128M console=ttyS0,115200 mtdparts=atmel_nand:8M(bootstrap/uboot/kernel)ro,-(rootfs) root=/dev/mtdblock1 rw rootfstype=ubifs ubi.mtd=1 root=ubi0:rootfs"; bootargs = "128M console=ttyS0,115200 root=/dev/mtdblock1 rw rootfstype=ubifs ubi.mtd=1 root=ubi0:rootfs";
}; };
ahb { ahb {
...@@ -33,5 +33,17 @@ macb0: ethernet@f802c000 { ...@@ -33,5 +33,17 @@ macb0: ethernet@f802c000 {
status = "okay"; status = "okay";
}; };
}; };
usb0: ohci@00600000 {
status = "okay";
num-ports = <2>;
atmel,vbus-gpio = <&pioD 19 0
&pioD 20 0
>;
};
usb1: ehci@00700000 {
status = "okay";
};
}; };
}; };
...@@ -60,6 +60,22 @@ aic: interrupt-controller@fffff000 { ...@@ -60,6 +60,22 @@ aic: interrupt-controller@fffff000 {
reg = <0xfffff000 0x200>; reg = <0xfffff000 0x200>;
}; };
ramc0: ramc@ffffe400 {
compatible = "atmel,at91sam9g45-ddramc";
reg = <0xffffe400 0x200
0xffffe600 0x200>;
};
pmc: pmc@fffffc00 {
compatible = "atmel,at91rm9200-pmc";
reg = <0xfffffc00 0x100>;
};
rstc@fffffd00 {
compatible = "atmel,at91sam9g45-rstc";
reg = <0xfffffd00 0x10>;
};
pit: timer@fffffd30 { pit: timer@fffffd30 {
compatible = "atmel,at91sam9260-pit"; compatible = "atmel,at91sam9260-pit";
reg = <0xfffffd30 0xf>; reg = <0xfffffd30 0xf>;
...@@ -67,6 +83,11 @@ pit: timer@fffffd30 { ...@@ -67,6 +83,11 @@ pit: timer@fffffd30 {
}; };
shdwc@fffffd10 {
compatible = "atmel,at91sam9rl-shdwc";
reg = <0xfffffd10 0x10>;
};
tcb0: timer@fff7c000 { tcb0: timer@fff7c000 {
compatible = "atmel,at91rm9200-tcb"; compatible = "atmel,at91rm9200-tcb";
reg = <0xfff7c000 0x100>; reg = <0xfff7c000 0x100>;
...@@ -180,5 +201,48 @@ macb0: ethernet@fffbc000 { ...@@ -180,5 +201,48 @@ macb0: ethernet@fffbc000 {
status = "disabled"; status = "disabled";
}; };
}; };
nand0: nand@40000000 {
compatible = "atmel,at91rm9200-nand";
#address-cells = <1>;
#size-cells = <1>;
reg = <0x40000000 0x10000000
0xffffe200 0x200
>;
atmel,nand-addr-offset = <21>;
atmel,nand-cmd-offset = <22>;
gpios = <&pioC 8 0
&pioC 14 0
0
>;
status = "disabled";
};
usb0: ohci@00700000 {
compatible = "atmel,at91rm9200-ohci", "usb-ohci";
reg = <0x00700000 0x100000>;
interrupts = <22 4>;
status = "disabled";
};
usb1: ehci@00800000 {
compatible = "atmel,at91sam9g45-ehci", "usb-ehci";
reg = <0x00800000 0x100000>;
interrupts = <22 4>;
status = "disabled";
};
};
i2c@0 {
compatible = "i2c-gpio";
gpios = <&pioA 20 0 /* sda */
&pioA 21 0 /* scl */
>;
i2c-gpio,sda-open-drain;
i2c-gpio,scl-open-drain;
i2c-gpio,delay-us = <5>; /* ~100 kHz */
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
}; };
}; };
...@@ -14,13 +14,24 @@ / { ...@@ -14,13 +14,24 @@ / {
compatible = "atmel,at91sam9m10g45ek", "atmel,at91sam9g45", "atmel,at91sam9"; compatible = "atmel,at91sam9m10g45ek", "atmel,at91sam9g45", "atmel,at91sam9";
chosen { chosen {
bootargs = "mem=64M console=ttyS0,115200 mtdparts=atmel_nand:4M(bootstrap/uboot/kernel)ro,60M(rootfs),-(data) root=/dev/mtdblock1 rw rootfstype=jffs2"; bootargs = "mem=64M console=ttyS0,115200 root=/dev/mtdblock1 rw rootfstype=jffs2";
}; };
memory@70000000 { memory@70000000 {
reg = <0x70000000 0x4000000>; reg = <0x70000000 0x4000000>;
}; };
clocks {
#address-cells = <1>;
#size-cells = <1>;
ranges;
main_clock: clock@0 {
compatible = "atmel,osc", "fixed-clock";
clock-frequency = <12000000>;
};
};
ahb { ahb {
apb { apb {
dbgu: serial@ffffee00 { dbgu: serial@ffffee00 {
...@@ -36,6 +47,39 @@ macb0: ethernet@fffbc000 { ...@@ -36,6 +47,39 @@ macb0: ethernet@fffbc000 {
status = "okay"; status = "okay";
}; };
}; };
nand0: nand@40000000 {
nand-bus-width = <8>;
nand-ecc-mode = "soft";
nand-on-flash-bbt;
status = "okay";
boot@0 {
label = "bootstrap/uboot/kernel";
reg = <0x0 0x400000>;
};
rootfs@400000 {
label = "rootfs";
reg = <0x400000 0x3C00000>;
};
data@4000000 {
label = "data";
reg = <0x4000000 0xC000000>;
};
};
usb0: ohci@00700000 {
status = "okay";
num-ports = <2>;
atmel,vbus-gpio = <&pioD 1 0
&pioD 3 0>;
};
usb1: ehci@00800000 {
status = "okay";
};
}; };
leds { leds {
......
...@@ -58,6 +58,26 @@ aic: interrupt-controller@fffff000 { ...@@ -58,6 +58,26 @@ aic: interrupt-controller@fffff000 {
reg = <0xfffff000 0x200>; reg = <0xfffff000 0x200>;
}; };
ramc0: ramc@ffffe800 {
compatible = "atmel,at91sam9g45-ddramc";
reg = <0xffffe800 0x200>;
};
pmc: pmc@fffffc00 {
compatible = "atmel,at91rm9200-pmc";
reg = <0xfffffc00 0x100>;
};
rstc@fffffe00 {
compatible = "atmel,at91sam9g45-rstc";
reg = <0xfffffe00 0x10>;
};
shdwc@fffffe10 {
compatible = "atmel,at91sam9x5-shdwc";
reg = <0xfffffe10 0x10>;
};
pit: timer@fffffe30 { pit: timer@fffffe30 {
compatible = "atmel,at91sam9260-pit"; compatible = "atmel,at91sam9260-pit";
reg = <0xfffffe30 0xf>; reg = <0xfffffe30 0xf>;
...@@ -172,5 +192,73 @@ macb1: ethernet@f8030000 { ...@@ -172,5 +192,73 @@ macb1: ethernet@f8030000 {
status = "disabled"; status = "disabled";
}; };
}; };
nand0: nand@40000000 {
compatible = "atmel,at91rm9200-nand";
#address-cells = <1>;
#size-cells = <1>;
reg = <0x40000000 0x10000000
>;
atmel,nand-addr-offset = <21>;
atmel,nand-cmd-offset = <22>;
gpios = <&pioC 8 0
&pioC 14 0
0
>;
status = "disabled";
};
usb0: ohci@00600000 {
compatible = "atmel,at91rm9200-ohci", "usb-ohci";
reg = <0x00600000 0x100000>;
interrupts = <22 4>;
status = "disabled";
};
usb1: ehci@00700000 {
compatible = "atmel,at91sam9g45-ehci", "usb-ehci";
reg = <0x00700000 0x100000>;
interrupts = <22 4>;
status = "disabled";
};
};
i2c@0 {
compatible = "i2c-gpio";
gpios = <&pioA 30 0 /* sda */
&pioA 31 0 /* scl */
>;
i2c-gpio,sda-open-drain;
i2c-gpio,scl-open-drain;
i2c-gpio,delay-us = <2>; /* ~100 kHz */
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
};
i2c@1 {
compatible = "i2c-gpio";
gpios = <&pioC 0 0 /* sda */
&pioC 1 0 /* scl */
>;
i2c-gpio,sda-open-drain;
i2c-gpio,scl-open-drain;
i2c-gpio,delay-us = <2>; /* ~100 kHz */
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
};
i2c@2 {
compatible = "i2c-gpio";
gpios = <&pioB 4 0 /* sda */
&pioB 5 0 /* scl */
>;
i2c-gpio,sda-open-drain;
i2c-gpio,scl-open-drain;
i2c-gpio,delay-us = <2>; /* ~100 kHz */
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
}; };
}; };
...@@ -12,6 +12,51 @@ memory@20000000 { ...@@ -12,6 +12,51 @@ memory@20000000 {
reg = <0x20000000 0x8000000>; reg = <0x20000000 0x8000000>;
}; };
clocks {
#address-cells = <1>;
#size-cells = <1>;
ranges;
main_clock: clock@0 {
compatible = "atmel,osc", "fixed-clock";
clock-frequency = <12000000>;
};
};
ahb {
nand0: nand@40000000 {
nand-bus-width = <8>;
nand-ecc-mode = "soft";
nand-on-flash-bbt;
status = "okay";
at91bootstrap@0 {
label = "at91bootstrap";
reg = <0x0 0x40000>;
};
uboot@40000 {
label = "u-boot";
reg = <0x40000 0x80000>;
};
ubootenv@c0000 {
label = "U-Boot Env";
reg = <0xc0000 0x140000>;
};
kernel@200000 {
label = "kernel";
reg = <0x200000 0x600000>;
};
rootfs@800000 {
label = "rootfs";
reg = <0x800000 0x1f800000>;
};
};
};
leds { leds {
compatible = "gpio-leds"; compatible = "gpio-leds";
......
/*
* calao-dab-mmx.dtsi - Device Tree Include file for Calao DAB-MMX Daughter Board
*
* Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
*
* Licensed under GPLv2.
*/
/ {
ahb {
apb {
usart1: serial@fffb4000 {
status = "okay";
};
usart3: serial@fffd0000 {
status = "okay";
};
};
};
i2c-gpio@0 {
status = "okay";
};
leds {
compatible = "gpio-leds";
user_led1 {
label = "user_led1";
gpios = <&pioB 20 1>;
};
/*
* led already used by mother board but active as high
* user_led2 {
* label = "user_led2";
* gpios = <&pioB 21 1>;
* };
*/
user_led3 {
label = "user_led3";
gpios = <&pioB 22 1>;
};
user_led4 {
label = "user_led4";
gpios = <&pioB 23 1>;
};
red {
label = "red";
gpios = <&pioB 24 1>;
};
orange {
label = "orange";
gpios = <&pioB 30 1>;
};
green {
label = "green";
gpios = <&pioB 31 1>;
};
};
gpio_keys {
compatible = "gpio-keys";
#address-cells = <1>;
#size-cells = <0>;
user_pb1 {
label = "user_pb1";
gpios = <&pioB 25 1>;
linux,code = <0x100>;
};
user_pb2 {
label = "user_pb2";
gpios = <&pioB 13 1>;
linux,code = <0x101>;
};
user_pb3 {
label = "user_pb3";
gpios = <&pioA 26 1>;
linux,code = <0x102>;
};
user_pb4 {
label = "user_pb4";
gpios = <&pioC 9 1>;
linux,code = <0x103>;
};
};
};
...@@ -13,13 +13,24 @@ / { ...@@ -13,13 +13,24 @@ / {
compatible = "calao,usb-a9g20", "atmel,at91sam9g20", "atmel,at91sam9"; compatible = "calao,usb-a9g20", "atmel,at91sam9g20", "atmel,at91sam9";
chosen { chosen {
bootargs = "mem=64M console=ttyS0,115200 mtdparts=atmel_nand:128k(at91bootstrap),256k(barebox)ro,128k(bareboxenv),128k(bareboxenv2),4M(kernel),120M(rootfs),-(data) root=/dev/mtdblock5 rw rootfstype=ubifs"; bootargs = "mem=64M console=ttyS0,115200 root=/dev/mtdblock5 rw rootfstype=ubifs";
}; };
memory@20000000 { memory@20000000 {
reg = <0x20000000 0x4000000>; reg = <0x20000000 0x4000000>;
}; };
clocks {
#address-cells = <1>;
#size-cells = <1>;
ranges;
main_clock: clock@0 {
compatible = "atmel,osc", "fixed-clock";
clock-frequency = <12000000>;
};
};
ahb { ahb {
apb { apb {
dbgu: serial@fffff200 { dbgu: serial@fffff200 {
...@@ -31,6 +42,53 @@ macb0: ethernet@fffc4000 { ...@@ -31,6 +42,53 @@ macb0: ethernet@fffc4000 {
status = "okay"; status = "okay";
}; };
}; };
nand0: nand@40000000 {
nand-bus-width = <8>;
nand-ecc-mode = "soft";
nand-on-flash-bbt;
status = "okay";
at91bootstrap@0 {
label = "at91bootstrap";
reg = <0x0 0x20000>;
};
barebox@20000 {
label = "barebox";
reg = <0x20000 0x40000>;
};
bareboxenv@60000 {
label = "bareboxenv";
reg = <0x60000 0x20000>;
};
bareboxenv2@80000 {
label = "bareboxenv2";
reg = <0x80000 0x20000>;
};
kernel@a0000 {
label = "kernel";
reg = <0xa0000 0x400000>;
};
rootfs@4a0000 {
label = "rootfs";
reg = <0x4a0000 0x7800000>;
};
data@7ca0000 {
label = "data";
reg = <0x7ca0000 0x8360000>;
};
};
usb0: ohci@00500000 {
num-ports = <2>;
status = "okay";
};
}; };
leds { leds {
...@@ -55,4 +113,13 @@ user_pb { ...@@ -55,4 +113,13 @@ user_pb {
gpio-key,wakeup; gpio-key,wakeup;
}; };
}; };
i2c@0 {
status = "okay";
rv3029c2@56 {
compatible = "rv3029c2";
reg = <0x56>;
};
};
}; };
...@@ -74,6 +74,8 @@ CONFIG_LEGACY_PTY_COUNT=16 ...@@ -74,6 +74,8 @@ CONFIG_LEGACY_PTY_COUNT=16
CONFIG_SERIAL_ATMEL=y CONFIG_SERIAL_ATMEL=y
CONFIG_SERIAL_ATMEL_CONSOLE=y CONFIG_SERIAL_ATMEL_CONSOLE=y
CONFIG_HW_RANDOM=y CONFIG_HW_RANDOM=y
CONFIG_I2C=y
CONFIG_I2C_GPIO=y
CONFIG_SPI=y CONFIG_SPI=y
CONFIG_SPI_ATMEL=y CONFIG_SPI_ATMEL=y
CONFIG_SPI_SPIDEV=y CONFIG_SPI_SPIDEV=y
...@@ -105,6 +107,7 @@ CONFIG_LEDS_TRIGGERS=y ...@@ -105,6 +107,7 @@ CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=y CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y
CONFIG_RTC_CLASS=y CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_RV3029C2=y
CONFIG_RTC_DRV_AT91SAM9=y CONFIG_RTC_DRV_AT91SAM9=y
CONFIG_EXT2_FS=y CONFIG_EXT2_FS=y
CONFIG_MSDOS_FS=y CONFIG_MSDOS_FS=y
......
...@@ -20,9 +20,11 @@ config HAVE_AT91_USART5 ...@@ -20,9 +20,11 @@ config HAVE_AT91_USART5
config AT91_SAM9_ALT_RESET config AT91_SAM9_ALT_RESET
bool bool
default !ARCH_AT91X40
config AT91_SAM9G45_RESET config AT91_SAM9G45_RESET
bool bool
default !ARCH_AT91X40
menu "Atmel AT91 System-on-Chip" menu "Atmel AT91 System-on-Chip"
...@@ -45,7 +47,6 @@ config ARCH_AT91SAM9260 ...@@ -45,7 +47,6 @@ config ARCH_AT91SAM9260
select HAVE_AT91_USART4 select HAVE_AT91_USART4
select HAVE_AT91_USART5 select HAVE_AT91_USART5
select HAVE_NET_MACB select HAVE_NET_MACB
select AT91_SAM9_ALT_RESET
config ARCH_AT91SAM9261 config ARCH_AT91SAM9261
bool "AT91SAM9261" bool "AT91SAM9261"
...@@ -53,7 +54,6 @@ config ARCH_AT91SAM9261 ...@@ -53,7 +54,6 @@ config ARCH_AT91SAM9261
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select HAVE_FB_ATMEL select HAVE_FB_ATMEL
select HAVE_AT91_DBGU0 select HAVE_AT91_DBGU0
select AT91_SAM9_ALT_RESET
config ARCH_AT91SAM9G10 config ARCH_AT91SAM9G10
bool "AT91SAM9G10" bool "AT91SAM9G10"
...@@ -61,7 +61,6 @@ config ARCH_AT91SAM9G10 ...@@ -61,7 +61,6 @@ config ARCH_AT91SAM9G10
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select HAVE_AT91_DBGU0 select HAVE_AT91_DBGU0
select HAVE_FB_ATMEL select HAVE_FB_ATMEL
select AT91_SAM9_ALT_RESET
config ARCH_AT91SAM9263 config ARCH_AT91SAM9263
bool "AT91SAM9263" bool "AT91SAM9263"
...@@ -70,7 +69,6 @@ config ARCH_AT91SAM9263 ...@@ -70,7 +69,6 @@ config ARCH_AT91SAM9263
select HAVE_FB_ATMEL select HAVE_FB_ATMEL
select HAVE_NET_MACB select HAVE_NET_MACB
select HAVE_AT91_DBGU1 select HAVE_AT91_DBGU1
select AT91_SAM9_ALT_RESET
config ARCH_AT91SAM9RL config ARCH_AT91SAM9RL
bool "AT91SAM9RL" bool "AT91SAM9RL"
...@@ -79,7 +77,6 @@ config ARCH_AT91SAM9RL ...@@ -79,7 +77,6 @@ config ARCH_AT91SAM9RL
select HAVE_AT91_USART3 select HAVE_AT91_USART3
select HAVE_FB_ATMEL select HAVE_FB_ATMEL
select HAVE_AT91_DBGU0 select HAVE_AT91_DBGU0
select AT91_SAM9_ALT_RESET
config ARCH_AT91SAM9G20 config ARCH_AT91SAM9G20
bool "AT91SAM9G20" bool "AT91SAM9G20"
...@@ -90,7 +87,6 @@ config ARCH_AT91SAM9G20 ...@@ -90,7 +87,6 @@ config ARCH_AT91SAM9G20
select HAVE_AT91_USART4 select HAVE_AT91_USART4
select HAVE_AT91_USART5 select HAVE_AT91_USART5
select HAVE_NET_MACB select HAVE_NET_MACB
select AT91_SAM9_ALT_RESET
config ARCH_AT91SAM9G45 config ARCH_AT91SAM9G45
bool "AT91SAM9G45" bool "AT91SAM9G45"
...@@ -100,7 +96,6 @@ config ARCH_AT91SAM9G45 ...@@ -100,7 +96,6 @@ config ARCH_AT91SAM9G45
select HAVE_FB_ATMEL select HAVE_FB_ATMEL
select HAVE_NET_MACB select HAVE_NET_MACB
select HAVE_AT91_DBGU1 select HAVE_AT91_DBGU1
select AT91_SAM9G45_RESET
config ARCH_AT91SAM9X5 config ARCH_AT91SAM9X5
bool "AT91SAM9x5 family" bool "AT91SAM9x5 family"
...@@ -109,7 +104,6 @@ config ARCH_AT91SAM9X5 ...@@ -109,7 +104,6 @@ config ARCH_AT91SAM9X5
select HAVE_FB_ATMEL select HAVE_FB_ATMEL
select HAVE_NET_MACB select HAVE_NET_MACB
select HAVE_AT91_DBGU0 select HAVE_AT91_DBGU0
select AT91_SAM9G45_RESET
config ARCH_AT91X40 config ARCH_AT91X40
bool "AT91x40" bool "AT91x40"
......
...@@ -216,6 +216,7 @@ static struct clk_lookup periph_clocks_lookups[] = { ...@@ -216,6 +216,7 @@ static struct clk_lookup periph_clocks_lookups[] = {
CLKDEV_CON_DEV_ID("t0_clk", "fffdc000.timer", &tc3_clk), CLKDEV_CON_DEV_ID("t0_clk", "fffdc000.timer", &tc3_clk),
CLKDEV_CON_DEV_ID("t1_clk", "fffdc000.timer", &tc4_clk), CLKDEV_CON_DEV_ID("t1_clk", "fffdc000.timer", &tc4_clk),
CLKDEV_CON_DEV_ID("t2_clk", "fffdc000.timer", &tc5_clk), CLKDEV_CON_DEV_ID("t2_clk", "fffdc000.timer", &tc5_clk),
CLKDEV_CON_DEV_ID("hclk", "500000.ohci", &ohci_clk),
/* fake hclk clock */ /* fake hclk clock */
CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk),
CLKDEV_CON_ID("pioA", &pioA_clk), CLKDEV_CON_ID("pioA", &pioA_clk),
......
...@@ -232,6 +232,8 @@ static struct clk_lookup periph_clocks_lookups[] = { ...@@ -232,6 +232,8 @@ static struct clk_lookup periph_clocks_lookups[] = {
/* more tc lookup table for DT entries */ /* more tc lookup table for DT entries */
CLKDEV_CON_DEV_ID("t0_clk", "fff7c000.timer", &tcb0_clk), CLKDEV_CON_DEV_ID("t0_clk", "fff7c000.timer", &tcb0_clk),
CLKDEV_CON_DEV_ID("t0_clk", "fffd4000.timer", &tcb0_clk), CLKDEV_CON_DEV_ID("t0_clk", "fffd4000.timer", &tcb0_clk),
CLKDEV_CON_DEV_ID("hclk", "700000.ohci", &uhphs_clk),
CLKDEV_CON_DEV_ID("ehci_clk", "800000.ehci", &uhphs_clk),
/* fake hclk clock */ /* fake hclk clock */
CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &uhphs_clk), CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &uhphs_clk),
CLKDEV_CON_ID("pioA", &pioA_clk), CLKDEV_CON_ID("pioA", &pioA_clk),
......
...@@ -131,7 +131,7 @@ static struct clk dma1_clk = { ...@@ -131,7 +131,7 @@ static struct clk dma1_clk = {
.type = CLK_TYPE_PERIPHERAL, .type = CLK_TYPE_PERIPHERAL,
}; };
static struct clk uhphs_clk = { static struct clk uhphs_clk = {
.name = "uhphs_clk", .name = "uhphs",
.pmc_mask = 1 << AT91SAM9X5_ID_UHPHS, .pmc_mask = 1 << AT91SAM9X5_ID_UHPHS,
.type = CLK_TYPE_PERIPHERAL, .type = CLK_TYPE_PERIPHERAL,
}; };
...@@ -230,6 +230,9 @@ static struct clk_lookup periph_clocks_lookups[] = { ...@@ -230,6 +230,9 @@ static struct clk_lookup periph_clocks_lookups[] = {
/* additional fake clock for macb_hclk */ /* additional fake clock for macb_hclk */
CLKDEV_CON_DEV_ID("hclk", "f802c000.ethernet", &macb0_clk), CLKDEV_CON_DEV_ID("hclk", "f802c000.ethernet", &macb0_clk),
CLKDEV_CON_DEV_ID("hclk", "f8030000.ethernet", &macb1_clk), CLKDEV_CON_DEV_ID("hclk", "f8030000.ethernet", &macb1_clk),
CLKDEV_CON_DEV_ID("hclk", "600000.ohci", &uhphs_clk),
CLKDEV_CON_DEV_ID("ohci_clk", "600000.ohci", &uhphs_clk),
CLKDEV_CON_DEV_ID("ehci_clk", "700000.ehci", &uhphs_clk),
}; };
/* /*
...@@ -299,25 +302,14 @@ static void __init at91sam9x5_map_io(void) ...@@ -299,25 +302,14 @@ static void __init at91sam9x5_map_io(void)
at91_init_sram(0, AT91SAM9X5_SRAM_BASE, AT91SAM9X5_SRAM_SIZE); at91_init_sram(0, AT91SAM9X5_SRAM_BASE, AT91SAM9X5_SRAM_SIZE);
} }
static void __init at91sam9x5_ioremap_registers(void)
{
at91_ioremap_ramc(0, AT91SAM9X5_BASE_DDRSDRC0, 512);
}
void __init at91sam9x5_initialize(void) void __init at91sam9x5_initialize(void)
{ {
arm_pm_restart = at91sam9g45_restart;
at91_extern_irq = (1 << AT91SAM9X5_ID_IRQ0); at91_extern_irq = (1 << AT91SAM9X5_ID_IRQ0);
/* Register GPIO subsystem (using DT) */ /* Register GPIO subsystem (using DT) */
at91_gpio_init(NULL, 0); at91_gpio_init(NULL, 0);
} }
/* --------------------------------------------------------------------
* AT91SAM9x5 devices (temporary before modification of code)
* -------------------------------------------------------------------- */
void __init at91_add_device_nand(struct atmel_nand_data *data) {}
/* -------------------------------------------------------------------- /* --------------------------------------------------------------------
* Interrupt initialization * Interrupt initialization
* -------------------------------------------------------------------- */ * -------------------------------------------------------------------- */
...@@ -362,7 +354,6 @@ static unsigned int at91sam9x5_default_irq_priority[NR_AIC_IRQS] __initdata = { ...@@ -362,7 +354,6 @@ static unsigned int at91sam9x5_default_irq_priority[NR_AIC_IRQS] __initdata = {
struct at91_init_soc __initdata at91sam9x5_soc = { struct at91_init_soc __initdata at91sam9x5_soc = {
.map_io = at91sam9x5_map_io, .map_io = at91sam9x5_map_io,
.default_irq_priority = at91sam9x5_default_irq_priority, .default_irq_priority = at91sam9x5_default_irq_priority,
.ioremap_registers = at91sam9x5_ioremap_registers,
.register_clocks = at91sam9x5_register_clocks, .register_clocks = at91sam9x5_register_clocks,
.init = at91sam9x5_initialize, .init = at91sam9x5_initialize,
}; };
...@@ -138,6 +138,7 @@ static struct atmel_nand_data __initdata afeb9260_nand_data = { ...@@ -138,6 +138,7 @@ static struct atmel_nand_data __initdata afeb9260_nand_data = {
.rdy_pin = AT91_PIN_PC13, .rdy_pin = AT91_PIN_PC13,
.enable_pin = AT91_PIN_PC14, .enable_pin = AT91_PIN_PC14,
.bus_width_16 = 0, .bus_width_16 = 0,
.ecc_mode = NAND_ECC_SOFT,
.parts = afeb9260_nand_partition, .parts = afeb9260_nand_partition,
.num_parts = ARRAY_SIZE(afeb9260_nand_partition), .num_parts = ARRAY_SIZE(afeb9260_nand_partition),
.det_pin = -EINVAL, .det_pin = -EINVAL,
......
...@@ -140,6 +140,7 @@ static struct atmel_nand_data __initdata cam60_nand_data = { ...@@ -140,6 +140,7 @@ static struct atmel_nand_data __initdata cam60_nand_data = {
.det_pin = -EINVAL, .det_pin = -EINVAL,
.rdy_pin = AT91_PIN_PA9, .rdy_pin = AT91_PIN_PA9,
.enable_pin = AT91_PIN_PA7, .enable_pin = AT91_PIN_PA7,
.ecc_mode = NAND_ECC_SOFT,
.parts = cam60_nand_partition, .parts = cam60_nand_partition,
.num_parts = ARRAY_SIZE(cam60_nand_partition), .num_parts = ARRAY_SIZE(cam60_nand_partition),
}; };
......
...@@ -117,6 +117,7 @@ static struct atmel_nand_data __initdata cpu9krea_nand_data = { ...@@ -117,6 +117,7 @@ static struct atmel_nand_data __initdata cpu9krea_nand_data = {
.enable_pin = AT91_PIN_PC14, .enable_pin = AT91_PIN_PC14,
.bus_width_16 = 0, .bus_width_16 = 0,
.det_pin = -EINVAL, .det_pin = -EINVAL,
.ecc_mode = NAND_ECC_SOFT,
}; };
#ifdef CONFIG_MACH_CPU9260 #ifdef CONFIG_MACH_CPU9260
......
...@@ -19,10 +19,7 @@ ...@@ -19,10 +19,7 @@
#include <linux/of_irq.h> #include <linux/of_irq.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <mach/hardware.h>
#include <mach/board.h> #include <mach/board.h>
#include <mach/system_rev.h>
#include <mach/at91sam9_smc.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/irq.h> #include <asm/irq.h>
...@@ -30,58 +27,9 @@ ...@@ -30,58 +27,9 @@
#include <asm/mach/map.h> #include <asm/mach/map.h>
#include <asm/mach/irq.h> #include <asm/mach/irq.h>
#include "sam9_smc.h"
#include "generic.h" #include "generic.h"
static void __init ek_init_early(void)
{
/* Initialize processor: 12.000 MHz crystal */
at91_initialize(12000000);
}
/* det_pin is not connected */
static struct atmel_nand_data __initdata ek_nand_data = {
.ale = 21,
.cle = 22,
.det_pin = -EINVAL,
.rdy_pin = AT91_PIN_PC8,
.enable_pin = AT91_PIN_PC14,
};
static struct sam9_smc_config __initdata ek_nand_smc_config = {
.ncs_read_setup = 0,
.nrd_setup = 2,
.ncs_write_setup = 0,
.nwe_setup = 2,
.ncs_read_pulse = 4,
.nrd_pulse = 4,
.ncs_write_pulse = 4,
.nwe_pulse = 4,
.read_cycle = 7,
.write_cycle = 7,
.mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE,
.tdf_cycles = 3,
};
static void __init ek_add_device_nand(void)
{
ek_nand_data.bus_width_16 = board_have_nand_16bit();
/* setup bus-width (8 or 16) */
if (ek_nand_data.bus_width_16)
ek_nand_smc_config.mode |= AT91_SMC_DBW_16;
else
ek_nand_smc_config.mode |= AT91_SMC_DBW_8;
/* configure chip-select 3 (NAND) */
sam9_smc_configure(0, 3, &ek_nand_smc_config);
at91_add_device_nand(&ek_nand_data);
}
static const struct of_device_id irq_of_match[] __initconst = { static const struct of_device_id irq_of_match[] __initconst = {
{ .compatible = "atmel,at91rm9200-aic", .data = at91_aic_of_init }, { .compatible = "atmel,at91rm9200-aic", .data = at91_aic_of_init },
...@@ -98,9 +46,6 @@ static void __init at91_dt_init_irq(void) ...@@ -98,9 +46,6 @@ static void __init at91_dt_init_irq(void)
static void __init at91_dt_device_init(void) static void __init at91_dt_device_init(void)
{ {
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
/* NAND */
ek_add_device_nand();
} }
static const char *at91_dt_board_compat[] __initdata = { static const char *at91_dt_board_compat[] __initdata = {
...@@ -114,7 +59,7 @@ DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM (Device Tree)") ...@@ -114,7 +59,7 @@ DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM (Device Tree)")
/* Maintainer: Atmel */ /* Maintainer: Atmel */
.timer = &at91sam926x_timer, .timer = &at91sam926x_timer,
.map_io = at91_map_io, .map_io = at91_map_io,
.init_early = ek_init_early, .init_early = at91_dt_initialize,
.init_irq = at91_dt_init_irq, .init_irq = at91_dt_init_irq,
.init_machine = at91_dt_device_init, .init_machine = at91_dt_device_init,
.dt_compat = at91_dt_board_compat, .dt_compat = at91_dt_board_compat,
......
...@@ -108,6 +108,7 @@ static struct atmel_nand_data __initdata kb9202_nand_data = { ...@@ -108,6 +108,7 @@ static struct atmel_nand_data __initdata kb9202_nand_data = {
.det_pin = -EINVAL, .det_pin = -EINVAL,
.rdy_pin = AT91_PIN_PC29, .rdy_pin = AT91_PIN_PC29,
.enable_pin = AT91_PIN_PC28, .enable_pin = AT91_PIN_PC28,
.ecc_mode = NAND_ECC_SOFT,
.parts = kb9202_nand_partition, .parts = kb9202_nand_partition,
.num_parts = ARRAY_SIZE(kb9202_nand_partition), .num_parts = ARRAY_SIZE(kb9202_nand_partition),
}; };
......
...@@ -190,6 +190,7 @@ static struct atmel_nand_data __initdata neocore926_nand_data = { ...@@ -190,6 +190,7 @@ static struct atmel_nand_data __initdata neocore926_nand_data = {
.rdy_pin = AT91_PIN_PB19, .rdy_pin = AT91_PIN_PB19,
.rdy_pin_active_low = 1, .rdy_pin_active_low = 1,
.enable_pin = AT91_PIN_PD15, .enable_pin = AT91_PIN_PD15,
.ecc_mode = NAND_ECC_SOFT,
.parts = neocore926_nand_partition, .parts = neocore926_nand_partition,
.num_parts = ARRAY_SIZE(neocore926_nand_partition), .num_parts = ARRAY_SIZE(neocore926_nand_partition),
.det_pin = -EINVAL, .det_pin = -EINVAL,
......
...@@ -138,6 +138,8 @@ static struct atmel_nand_data __initdata ek_nand_data = { ...@@ -138,6 +138,8 @@ static struct atmel_nand_data __initdata ek_nand_data = {
.det_pin = -EINVAL, .det_pin = -EINVAL,
.rdy_pin = AT91_PIN_PC13, .rdy_pin = AT91_PIN_PC13,
.enable_pin = AT91_PIN_PC14, .enable_pin = AT91_PIN_PC14,
.ecc_mode = NAND_ECC_SOFT,
.on_flash_bbt = 1,
.parts = ek_nand_partition, .parts = ek_nand_partition,
.num_parts = ARRAY_SIZE(ek_nand_partition), .num_parts = ARRAY_SIZE(ek_nand_partition),
}; };
......
...@@ -150,6 +150,8 @@ static struct atmel_nand_data __initdata dk_nand_data = { ...@@ -150,6 +150,8 @@ static struct atmel_nand_data __initdata dk_nand_data = {
.det_pin = AT91_PIN_PB1, .det_pin = AT91_PIN_PB1,
.rdy_pin = AT91_PIN_PC2, .rdy_pin = AT91_PIN_PC2,
.enable_pin = -EINVAL, .enable_pin = -EINVAL,
.ecc_mode = NAND_ECC_SOFT,
.on_flash_bbt = 1,
.parts = dk_nand_partition, .parts = dk_nand_partition,
.num_parts = ARRAY_SIZE(dk_nand_partition), .num_parts = ARRAY_SIZE(dk_nand_partition),
}; };
......
...@@ -139,6 +139,7 @@ static struct atmel_nand_data __initdata ek_nand_data = { ...@@ -139,6 +139,7 @@ static struct atmel_nand_data __initdata ek_nand_data = {
.det_pin = -EINVAL, .det_pin = -EINVAL,
.rdy_pin = AT91_PIN_PC13, .rdy_pin = AT91_PIN_PC13,
.enable_pin = AT91_PIN_PC14, .enable_pin = AT91_PIN_PC14,
.ecc_mode = NAND_ECC_SOFT,
.parts = ek_nand_partition, .parts = ek_nand_partition,
.num_parts = ARRAY_SIZE(ek_nand_partition), .num_parts = ARRAY_SIZE(ek_nand_partition),
}; };
......
...@@ -181,6 +181,8 @@ static struct atmel_nand_data __initdata ek_nand_data = { ...@@ -181,6 +181,8 @@ static struct atmel_nand_data __initdata ek_nand_data = {
.det_pin = -EINVAL, .det_pin = -EINVAL,
.rdy_pin = AT91_PIN_PC13, .rdy_pin = AT91_PIN_PC13,
.enable_pin = AT91_PIN_PC14, .enable_pin = AT91_PIN_PC14,
.ecc_mode = NAND_ECC_SOFT,
.on_flash_bbt = 1,
.parts = ek_nand_partition, .parts = ek_nand_partition,
.num_parts = ARRAY_SIZE(ek_nand_partition), .num_parts = ARRAY_SIZE(ek_nand_partition),
}; };
......
...@@ -187,6 +187,8 @@ static struct atmel_nand_data __initdata ek_nand_data = { ...@@ -187,6 +187,8 @@ static struct atmel_nand_data __initdata ek_nand_data = {
.det_pin = -EINVAL, .det_pin = -EINVAL,
.rdy_pin = AT91_PIN_PC15, .rdy_pin = AT91_PIN_PC15,
.enable_pin = AT91_PIN_PC14, .enable_pin = AT91_PIN_PC14,
.ecc_mode = NAND_ECC_SOFT,
.on_flash_bbt = 1,
.parts = ek_nand_partition, .parts = ek_nand_partition,
.num_parts = ARRAY_SIZE(ek_nand_partition), .num_parts = ARRAY_SIZE(ek_nand_partition),
}; };
......
...@@ -187,6 +187,8 @@ static struct atmel_nand_data __initdata ek_nand_data = { ...@@ -187,6 +187,8 @@ static struct atmel_nand_data __initdata ek_nand_data = {
.det_pin = -EINVAL, .det_pin = -EINVAL,
.rdy_pin = AT91_PIN_PA22, .rdy_pin = AT91_PIN_PA22,
.enable_pin = AT91_PIN_PD15, .enable_pin = AT91_PIN_PD15,
.ecc_mode = NAND_ECC_SOFT,
.on_flash_bbt = 1,
.parts = ek_nand_partition, .parts = ek_nand_partition,
.num_parts = ARRAY_SIZE(ek_nand_partition), .num_parts = ARRAY_SIZE(ek_nand_partition),
}; };
......
...@@ -166,6 +166,8 @@ static struct atmel_nand_data __initdata ek_nand_data = { ...@@ -166,6 +166,8 @@ static struct atmel_nand_data __initdata ek_nand_data = {
.rdy_pin = AT91_PIN_PC13, .rdy_pin = AT91_PIN_PC13,
.enable_pin = AT91_PIN_PC14, .enable_pin = AT91_PIN_PC14,
.det_pin = -EINVAL, .det_pin = -EINVAL,
.ecc_mode = NAND_ECC_SOFT,
.on_flash_bbt = 1,
.parts = ek_nand_partition, .parts = ek_nand_partition,
.num_parts = ARRAY_SIZE(ek_nand_partition), .num_parts = ARRAY_SIZE(ek_nand_partition),
}; };
......
...@@ -148,6 +148,8 @@ static struct atmel_nand_data __initdata ek_nand_data = { ...@@ -148,6 +148,8 @@ static struct atmel_nand_data __initdata ek_nand_data = {
.rdy_pin = AT91_PIN_PC8, .rdy_pin = AT91_PIN_PC8,
.enable_pin = AT91_PIN_PC14, .enable_pin = AT91_PIN_PC14,
.det_pin = -EINVAL, .det_pin = -EINVAL,
.ecc_mode = NAND_ECC_SOFT,
.on_flash_bbt = 1,
.parts = ek_nand_partition, .parts = ek_nand_partition,
.num_parts = ARRAY_SIZE(ek_nand_partition), .num_parts = ARRAY_SIZE(ek_nand_partition),
}; };
......
...@@ -94,6 +94,8 @@ static struct atmel_nand_data __initdata ek_nand_data = { ...@@ -94,6 +94,8 @@ static struct atmel_nand_data __initdata ek_nand_data = {
.det_pin = -EINVAL, .det_pin = -EINVAL,
.rdy_pin = AT91_PIN_PD17, .rdy_pin = AT91_PIN_PD17,
.enable_pin = AT91_PIN_PB6, .enable_pin = AT91_PIN_PB6,
.ecc_mode = NAND_ECC_SOFT,
.on_flash_bbt = 1,
.parts = ek_nand_partition, .parts = ek_nand_partition,
.num_parts = ARRAY_SIZE(ek_nand_partition), .num_parts = ARRAY_SIZE(ek_nand_partition),
}; };
......
...@@ -110,6 +110,7 @@ static struct atmel_nand_data __initdata snapper9260_nand_data = { ...@@ -110,6 +110,7 @@ static struct atmel_nand_data __initdata snapper9260_nand_data = {
.bus_width_16 = 0, .bus_width_16 = 0,
.enable_pin = -EINVAL, .enable_pin = -EINVAL,
.det_pin = -EINVAL, .det_pin = -EINVAL,
.ecc_mode = NAND_ECC_SOFT,
}; };
static struct sam9_smc_config __initdata snapper9260_nand_smc_config = { static struct sam9_smc_config __initdata snapper9260_nand_smc_config = {
......
...@@ -86,6 +86,7 @@ static struct atmel_nand_data __initdata nand_data = { ...@@ -86,6 +86,7 @@ static struct atmel_nand_data __initdata nand_data = {
.enable_pin = AT91_PIN_PC14, .enable_pin = AT91_PIN_PC14,
.bus_width_16 = 0, .bus_width_16 = 0,
.det_pin = -EINVAL, .det_pin = -EINVAL,
.ecc_mode = NAND_ECC_SOFT,
}; };
static struct sam9_smc_config __initdata nand_smc_config = { static struct sam9_smc_config __initdata nand_smc_config = {
......
...@@ -198,6 +198,8 @@ static struct atmel_nand_data __initdata ek_nand_data = { ...@@ -198,6 +198,8 @@ static struct atmel_nand_data __initdata ek_nand_data = {
.det_pin = -EINVAL, .det_pin = -EINVAL,
.rdy_pin = AT91_PIN_PA22, .rdy_pin = AT91_PIN_PA22,
.enable_pin = AT91_PIN_PD15, .enable_pin = AT91_PIN_PD15,
.ecc_mode = NAND_ECC_SOFT,
.on_flash_bbt = 1,
.parts = ek_nand_partition, .parts = ek_nand_partition,
.num_parts = ARRAY_SIZE(ek_nand_partition), .num_parts = ARRAY_SIZE(ek_nand_partition),
}; };
......
...@@ -182,6 +182,7 @@ static struct atmel_nand_data __initdata yl9200_nand_data = { ...@@ -182,6 +182,7 @@ static struct atmel_nand_data __initdata yl9200_nand_data = {
.det_pin = -EINVAL, .det_pin = -EINVAL,
.rdy_pin = AT91_PIN_PC14, /* R/!B (Sheet10) */ .rdy_pin = AT91_PIN_PC14, /* R/!B (Sheet10) */
.enable_pin = AT91_PIN_PC15, /* !CE (Sheet10) */ .enable_pin = AT91_PIN_PC15, /* !CE (Sheet10) */
.ecc_mode = NAND_ECC_SOFT,
.parts = yl9200_nand_partition, .parts = yl9200_nand_partition,
.num_parts = ARRAY_SIZE(yl9200_nand_partition), .num_parts = ARRAY_SIZE(yl9200_nand_partition),
}; };
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/of_address.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/at91_pmc.h> #include <mach/at91_pmc.h>
...@@ -671,16 +672,12 @@ static void __init at91_upll_usbfs_clock_init(unsigned long main_clock) ...@@ -671,16 +672,12 @@ static void __init at91_upll_usbfs_clock_init(unsigned long main_clock)
uhpck.rate_hz /= 1 + ((at91_pmc_read(AT91_PMC_USB) & AT91_PMC_OHCIUSBDIV) >> 8); uhpck.rate_hz /= 1 + ((at91_pmc_read(AT91_PMC_USB) & AT91_PMC_OHCIUSBDIV) >> 8);
} }
int __init at91_clock_init(unsigned long main_clock) static int __init at91_pmc_init(unsigned long main_clock)
{ {
unsigned tmp, freq, mckr; unsigned tmp, freq, mckr;
int i; int i;
int pll_overclock = false; int pll_overclock = false;
at91_pmc_base = ioremap(AT91_PMC, 256);
if (!at91_pmc_base)
panic("Impossible to ioremap AT91_PMC 0x%x\n", AT91_PMC);
/* /*
* When the bootloader initialized the main oscillator correctly, * When the bootloader initialized the main oscillator correctly,
* there's no problem using the cycle counter. But if it didn't, * there's no problem using the cycle counter. But if it didn't,
...@@ -802,6 +799,55 @@ int __init at91_clock_init(unsigned long main_clock) ...@@ -802,6 +799,55 @@ int __init at91_clock_init(unsigned long main_clock)
return 0; return 0;
} }
#if defined(CONFIG_OF)
static struct of_device_id pmc_ids[] = {
{ .compatible = "atmel,at91rm9200-pmc" },
{ /*sentinel*/ }
};
static struct of_device_id osc_ids[] = {
{ .compatible = "atmel,osc" },
{ /*sentinel*/ }
};
int __init at91_dt_clock_init(void)
{
struct device_node *np;
u32 main_clock = 0;
np = of_find_matching_node(NULL, pmc_ids);
if (!np)
panic("unable to find compatible pmc node in dtb\n");
at91_pmc_base = of_iomap(np, 0);
if (!at91_pmc_base)
panic("unable to map pmc cpu registers\n");
of_node_put(np);
/* retrieve the freqency of fixed clocks from device tree */
np = of_find_matching_node(NULL, osc_ids);
if (np) {
u32 rate;
if (!of_property_read_u32(np, "clock-frequency", &rate))
main_clock = rate;
}
of_node_put(np);
return at91_pmc_init(main_clock);
}
#endif
int __init at91_clock_init(unsigned long main_clock)
{
at91_pmc_base = ioremap(AT91_PMC, 256);
if (!at91_pmc_base)
panic("Impossible to ioremap AT91_PMC 0x%x\n", AT91_PMC);
return at91_pmc_init(main_clock);
}
/* /*
* Several unused clocks may be active. Turn them off. * Several unused clocks may be active. Turn them off.
*/ */
......
...@@ -20,6 +20,7 @@ extern void __init at91_init_sram(int bank, unsigned long base, ...@@ -20,6 +20,7 @@ extern void __init at91_init_sram(int bank, unsigned long base,
extern void __init at91rm9200_set_type(int type); extern void __init at91rm9200_set_type(int type);
extern void __init at91_initialize(unsigned long main_clock); extern void __init at91_initialize(unsigned long main_clock);
extern void __init at91x40_initialize(unsigned long main_clock); extern void __init at91x40_initialize(unsigned long main_clock);
extern void __init at91_dt_initialize(void);
/* Interrupts */ /* Interrupts */
extern void __init at91_init_irq_default(void); extern void __init at91_init_irq_default(void);
...@@ -52,6 +53,7 @@ extern void __init at91sam9rl_set_console_clock(int id); ...@@ -52,6 +53,7 @@ extern void __init at91sam9rl_set_console_clock(int id);
extern void __init at91sam9g45_set_console_clock(int id); extern void __init at91sam9g45_set_console_clock(int id);
#ifdef CONFIG_AT91_PMC_UNIT #ifdef CONFIG_AT91_PMC_UNIT
extern int __init at91_clock_init(unsigned long main_clock); extern int __init at91_clock_init(unsigned long main_clock);
extern int __init at91_dt_clock_init(void);
#else #else
static int inline at91_clock_init(unsigned long main_clock) { return 0; } static int inline at91_clock_init(unsigned long main_clock) { return 0; }
#endif #endif
......
...@@ -36,9 +36,11 @@ extern void __iomem *at91_shdwc_base; ...@@ -36,9 +36,11 @@ extern void __iomem *at91_shdwc_base;
#define AT91_SHDW_WKMODE0_HIGH 1 #define AT91_SHDW_WKMODE0_HIGH 1
#define AT91_SHDW_WKMODE0_LOW 2 #define AT91_SHDW_WKMODE0_LOW 2
#define AT91_SHDW_WKMODE0_ANYLEVEL 3 #define AT91_SHDW_WKMODE0_ANYLEVEL 3
#define AT91_SHDW_CPTWK0 (0xf << 4) /* Counter On Wake Up 0 */ #define AT91_SHDW_CPTWK0_MAX 0xf /* Maximum Counter On Wake Up 0 */
#define AT91_SHDW_CPTWK0 (AT91_SHDW_CPTWK0_MAX << 4) /* Counter On Wake Up 0 */
#define AT91_SHDW_CPTWK0_(x) ((x) << 4) #define AT91_SHDW_CPTWK0_(x) ((x) << 4)
#define AT91_SHDW_RTTWKEN (1 << 16) /* Real Time Timer Wake-up Enable */ #define AT91_SHDW_RTTWKEN (1 << 16) /* Real Time Timer Wake-up Enable */
#define AT91_SHDW_RTCWKEN (1 << 17) /* Real Time Clock Wake-up Enable */
#define AT91_SHDW_SR 0x08 /* Shut Down Status Register */ #define AT91_SHDW_SR 0x08 /* Shut Down Status Register */
#define AT91_SHDW_WAKEUP0 (1 << 0) /* Wake-up 0 Status */ #define AT91_SHDW_WAKEUP0 (1 << 0) /* Wake-up 0 Status */
......
...@@ -54,11 +54,6 @@ ...@@ -54,11 +54,6 @@
#define AT91SAM9X5_BASE_USART1 0xf8020000 #define AT91SAM9X5_BASE_USART1 0xf8020000
#define AT91SAM9X5_BASE_USART2 0xf8024000 #define AT91SAM9X5_BASE_USART2 0xf8024000
/*
* System Peripherals
*/
#define AT91SAM9X5_BASE_DDRSDRC0 0xffffe800
/* /*
* Base addresses for early serial code (uncompress.h) * Base addresses for early serial code (uncompress.h)
*/ */
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include <sound/atmel-ac97c.h> #include <sound/atmel-ac97c.h>
#include <linux/serial.h> #include <linux/serial.h>
#include <linux/platform_data/macb.h> #include <linux/platform_data/macb.h>
#include <linux/platform_data/atmel.h>
/* USB Device */ /* USB Device */
struct at91_udc_data { struct at91_udc_data {
...@@ -98,20 +99,6 @@ extern void __init at91_add_device_usbh(struct at91_usbh_data *data); ...@@ -98,20 +99,6 @@ extern void __init at91_add_device_usbh(struct at91_usbh_data *data);
extern void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data); extern void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data);
extern void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data); extern void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data);
/* NAND / SmartMedia */
struct atmel_nand_data {
int enable_pin; /* chip enable */
int det_pin; /* card detect */
int rdy_pin; /* ready/busy */
u8 rdy_pin_active_low; /* rdy_pin value is inverted */
u8 ale; /* address line number connected to ALE */
u8 cle; /* address line number connected to CLE */
u8 bus_width_16; /* buswidth is 16 bit */
u8 correction_cap; /* PMECC correction capability */
u16 sector_size; /* Sector size for PMECC */
struct mtd_partition *parts;
unsigned int num_parts;
};
extern void __init at91_add_device_nand(struct atmel_nand_data *data); extern void __init at91_add_device_nand(struct atmel_nand_data *data);
/* I2C*/ /* I2C*/
......
...@@ -197,19 +197,6 @@ extern void at91_slow_clock(void __iomem *pmc, void __iomem *ramc0, ...@@ -197,19 +197,6 @@ extern void at91_slow_clock(void __iomem *pmc, void __iomem *ramc0,
extern u32 at91_slow_clock_sz; extern u32 at91_slow_clock_sz;
#endif #endif
void __iomem *at91_ramc_base[2];
void __init at91_ioremap_ramc(int id, u32 addr, u32 size)
{
if (id < 0 || id > 1) {
pr_emerg("Wrong RAM controller id (%d), cannot continue\n", id);
BUG();
}
at91_ramc_base[id] = ioremap(addr, size);
if (!at91_ramc_base[id])
panic("Impossible to ioremap ramc.%d 0x%x\n", id, addr);
}
static int at91_pm_enter(suspend_state_t state) static int at91_pm_enter(suspend_state_t state)
{ {
at91_gpio_suspend(); at91_gpio_suspend();
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/of_address.h>
#include <asm/mach/map.h> #include <asm/mach/map.h>
...@@ -51,6 +52,19 @@ void __init at91_init_interrupts(unsigned int *priority) ...@@ -51,6 +52,19 @@ void __init at91_init_interrupts(unsigned int *priority)
at91_gpio_irq_setup(); at91_gpio_irq_setup();
} }
void __iomem *at91_ramc_base[2];
void __init at91_ioremap_ramc(int id, u32 addr, u32 size)
{
if (id < 0 || id > 1) {
pr_emerg("Wrong RAM controller id (%d), cannot continue\n", id);
BUG();
}
at91_ramc_base[id] = ioremap(addr, size);
if (!at91_ramc_base[id])
panic("Impossible to ioremap ramc.%d 0x%x\n", id, addr);
}
static struct map_desc sram_desc[2] __initdata; static struct map_desc sram_desc[2] __initdata;
void __init at91_init_sram(int bank, unsigned long base, unsigned int length) void __init at91_init_sram(int bank, unsigned long base, unsigned int length)
...@@ -285,6 +299,150 @@ void __init at91_ioremap_matrix(u32 base_addr) ...@@ -285,6 +299,150 @@ void __init at91_ioremap_matrix(u32 base_addr)
panic("Impossible to ioremap at91_matrix_base\n"); panic("Impossible to ioremap at91_matrix_base\n");
} }
#if defined(CONFIG_OF)
static struct of_device_id rstc_ids[] = {
{ .compatible = "atmel,at91sam9260-rstc", .data = at91sam9_alt_restart },
{ .compatible = "atmel,at91sam9g45-rstc", .data = at91sam9g45_restart },
{ /*sentinel*/ }
};
static void at91_dt_rstc(void)
{
struct device_node *np;
const struct of_device_id *of_id;
np = of_find_matching_node(NULL, rstc_ids);
if (!np)
panic("unable to find compatible rstc node in dtb\n");
at91_rstc_base = of_iomap(np, 0);
if (!at91_rstc_base)
panic("unable to map rstc cpu registers\n");
of_id = of_match_node(rstc_ids, np);
if (!of_id)
panic("AT91: rtsc no restart function availlable\n");
arm_pm_restart = of_id->data;
of_node_put(np);
}
static struct of_device_id ramc_ids[] = {
{ .compatible = "atmel,at91sam9260-sdramc" },
{ .compatible = "atmel,at91sam9g45-ddramc" },
{ /*sentinel*/ }
};
static void at91_dt_ramc(void)
{
struct device_node *np;
np = of_find_matching_node(NULL, ramc_ids);
if (!np)
panic("unable to find compatible ram conroller node in dtb\n");
at91_ramc_base[0] = of_iomap(np, 0);
if (!at91_ramc_base[0])
panic("unable to map ramc[0] cpu registers\n");
/* the controller may have 2 banks */
at91_ramc_base[1] = of_iomap(np, 1);
of_node_put(np);
}
static struct of_device_id shdwc_ids[] = {
{ .compatible = "atmel,at91sam9260-shdwc", },
{ .compatible = "atmel,at91sam9rl-shdwc", },
{ .compatible = "atmel,at91sam9x5-shdwc", },
{ /*sentinel*/ }
};
static const char *shdwc_wakeup_modes[] = {
[AT91_SHDW_WKMODE0_NONE] = "none",
[AT91_SHDW_WKMODE0_HIGH] = "high",
[AT91_SHDW_WKMODE0_LOW] = "low",
[AT91_SHDW_WKMODE0_ANYLEVEL] = "any",
};
const int at91_dtget_shdwc_wakeup_mode(struct device_node *np)
{
const char *pm;
int err, i;
err = of_property_read_string(np, "atmel,wakeup-mode", &pm);
if (err < 0)
return AT91_SHDW_WKMODE0_ANYLEVEL;
for (i = 0; i < ARRAY_SIZE(shdwc_wakeup_modes); i++)
if (!strcasecmp(pm, shdwc_wakeup_modes[i]))
return i;
return -ENODEV;
}
static void at91_dt_shdwc(void)
{
struct device_node *np;
int wakeup_mode;
u32 reg;
u32 mode = 0;
np = of_find_matching_node(NULL, shdwc_ids);
if (!np) {
pr_debug("AT91: unable to find compatible shutdown (shdwc) conroller node in dtb\n");
return;
}
at91_shdwc_base = of_iomap(np, 0);
if (!at91_shdwc_base)
panic("AT91: unable to map shdwc cpu registers\n");
wakeup_mode = at91_dtget_shdwc_wakeup_mode(np);
if (wakeup_mode < 0) {
pr_warn("AT91: shdwc unknown wakeup mode\n");
goto end;
}
if (!of_property_read_u32(np, "atmel,wakeup-counter", &reg)) {
if (reg > AT91_SHDW_CPTWK0_MAX) {
pr_warn("AT91: shdwc wakeup conter 0x%x > 0x%x reduce it to 0x%x\n",
reg, AT91_SHDW_CPTWK0_MAX, AT91_SHDW_CPTWK0_MAX);
reg = AT91_SHDW_CPTWK0_MAX;
}
mode |= AT91_SHDW_CPTWK0_(reg);
}
if (of_property_read_bool(np, "atmel,wakeup-rtc-timer"))
mode |= AT91_SHDW_RTCWKEN;
if (of_property_read_bool(np, "atmel,wakeup-rtt-timer"))
mode |= AT91_SHDW_RTTWKEN;
at91_shdwc_write(AT91_SHDW_MR, wakeup_mode | mode);
end:
pm_power_off = at91sam9_poweroff;
of_node_put(np);
}
void __init at91_dt_initialize(void)
{
at91_dt_rstc();
at91_dt_ramc();
at91_dt_shdwc();
/* Init clock subsystem */
at91_dt_clock_init();
/* Register the processor-specific clocks */
at91_boot_soc.register_clocks();
at91_boot_soc.init();
}
#endif
void __init at91_initialize(unsigned long main_clock) void __init at91_initialize(unsigned long main_clock)
{ {
at91_boot_soc.ioremap_registers(); at91_boot_soc.ioremap_registers();
......
...@@ -97,6 +97,7 @@ static struct atmel_nand_data atngw100mkii_nand_data __initdata = { ...@@ -97,6 +97,7 @@ static struct atmel_nand_data atngw100mkii_nand_data __initdata = {
.rdy_pin = GPIO_PIN_PB(28), .rdy_pin = GPIO_PIN_PB(28),
.enable_pin = GPIO_PIN_PE(23), .enable_pin = GPIO_PIN_PE(23),
.bus_width_16 = true, .bus_width_16 = true,
.ecc_mode = NAND_ECC_SOFT,
.parts = nand_partitions, .parts = nand_partitions,
.num_parts = ARRAY_SIZE(nand_partitions), .num_parts = ARRAY_SIZE(nand_partitions),
}; };
......
...@@ -95,6 +95,7 @@ static struct atmel_nand_data atstk1006_nand_data __initdata = { ...@@ -95,6 +95,7 @@ static struct atmel_nand_data atstk1006_nand_data __initdata = {
.ale = 22, .ale = 22,
.rdy_pin = GPIO_PIN_PB(30), .rdy_pin = GPIO_PIN_PB(30),
.enable_pin = GPIO_PIN_PB(29), .enable_pin = GPIO_PIN_PB(29),
.ecc_mode = NAND_ECC_SOFT,
.parts = nand_partitions, .parts = nand_partitions,
.num_parts = ARRAY_SIZE(num_partitions), .num_parts = ARRAY_SIZE(num_partitions),
}; };
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/serial.h> #include <linux/serial.h>
#include <linux/platform_data/macb.h> #include <linux/platform_data/macb.h>
#include <linux/platform_data/atmel_nand.h>
#define GPIO_PIN_NONE (-1) #define GPIO_PIN_NONE (-1)
...@@ -116,18 +117,6 @@ struct platform_device * ...@@ -116,18 +117,6 @@ struct platform_device *
at32_add_device_cf(unsigned int id, unsigned int extint, at32_add_device_cf(unsigned int id, unsigned int extint,
struct cf_platform_data *data); struct cf_platform_data *data);
/* NAND / SmartMedia */
struct atmel_nand_data {
int enable_pin; /* chip enable */
int det_pin; /* card detect */
int rdy_pin; /* ready/busy */
u8 rdy_pin_active_low; /* rdy_pin value is inverted */
u8 ale; /* address line number connected to ALE */
u8 cle; /* address line number connected to CLE */
u8 bus_width_16; /* buswidth is 16 bit */
struct mtd_partition *parts;
unsigned int num_parts;
};
struct platform_device * struct platform_device *
at32_add_device_nand(unsigned int id, struct atmel_nand_data *data); at32_add_device_nand(unsigned int id, struct atmel_nand_data *data);
......
...@@ -14,8 +14,15 @@ ...@@ -14,8 +14,15 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/gpio.h>
#include <asm/gpio.h> #include <linux/of_gpio.h>
#include <linux/of_i2c.h>
struct i2c_gpio_private_data {
struct i2c_adapter adap;
struct i2c_algo_bit_data bit_data;
struct i2c_gpio_platform_data pdata;
};
/* Toggle SDA by changing the direction of the pin */ /* Toggle SDA by changing the direction of the pin */
static void i2c_gpio_setsda_dir(void *data, int state) static void i2c_gpio_setsda_dir(void *data, int state)
...@@ -78,24 +85,62 @@ static int i2c_gpio_getscl(void *data) ...@@ -78,24 +85,62 @@ static int i2c_gpio_getscl(void *data)
return gpio_get_value(pdata->scl_pin); return gpio_get_value(pdata->scl_pin);
} }
static int __devinit of_i2c_gpio_probe(struct device_node *np,
struct i2c_gpio_platform_data *pdata)
{
u32 reg;
if (of_gpio_count(np) < 2)
return -ENODEV;
pdata->sda_pin = of_get_gpio(np, 0);
pdata->scl_pin = of_get_gpio(np, 1);
if (!gpio_is_valid(pdata->sda_pin) || !gpio_is_valid(pdata->scl_pin)) {
pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n",
np->full_name, pdata->sda_pin, pdata->scl_pin);
return -ENODEV;
}
of_property_read_u32(np, "i2c-gpio,delay-us", &pdata->udelay);
if (!of_property_read_u32(np, "i2c-gpio,timeout-ms", &reg))
pdata->timeout = msecs_to_jiffies(reg);
pdata->sda_is_open_drain =
of_property_read_bool(np, "i2c-gpio,sda-open-drain");
pdata->scl_is_open_drain =
of_property_read_bool(np, "i2c-gpio,scl-open-drain");
pdata->scl_is_output_only =
of_property_read_bool(np, "i2c-gpio,scl-output-only");
return 0;
}
static int __devinit i2c_gpio_probe(struct platform_device *pdev) static int __devinit i2c_gpio_probe(struct platform_device *pdev)
{ {
struct i2c_gpio_private_data *priv;
struct i2c_gpio_platform_data *pdata; struct i2c_gpio_platform_data *pdata;
struct i2c_algo_bit_data *bit_data; struct i2c_algo_bit_data *bit_data;
struct i2c_adapter *adap; struct i2c_adapter *adap;
int ret; int ret;
pdata = pdev->dev.platform_data; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
if (!pdata) if (!priv)
return -ENXIO; return -ENOMEM;
adap = &priv->adap;
ret = -ENOMEM; bit_data = &priv->bit_data;
adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL); pdata = &priv->pdata;
if (!adap)
goto err_alloc_adap; if (pdev->dev.of_node) {
bit_data = kzalloc(sizeof(struct i2c_algo_bit_data), GFP_KERNEL); ret = of_i2c_gpio_probe(pdev->dev.of_node, pdata);
if (!bit_data) if (ret)
goto err_alloc_bit_data; return ret;
} else {
if (!pdev->dev.platform_data)
return -ENXIO;
memcpy(pdata, pdev->dev.platform_data, sizeof(*pdata));
}
ret = gpio_request(pdata->sda_pin, "sda"); ret = gpio_request(pdata->sda_pin, "sda");
if (ret) if (ret)
...@@ -143,6 +188,7 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev) ...@@ -143,6 +188,7 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
adap->algo_data = bit_data; adap->algo_data = bit_data;
adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
adap->dev.parent = &pdev->dev; adap->dev.parent = &pdev->dev;
adap->dev.of_node = pdev->dev.of_node;
/* /*
* If "dev->id" is negative we consider it as zero. * If "dev->id" is negative we consider it as zero.
...@@ -154,7 +200,9 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev) ...@@ -154,7 +200,9 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
if (ret) if (ret)
goto err_add_bus; goto err_add_bus;
platform_set_drvdata(pdev, adap); of_i2c_register_devices(adap);
platform_set_drvdata(pdev, priv);
dev_info(&pdev->dev, "using pins %u (SDA) and %u (SCL%s)\n", dev_info(&pdev->dev, "using pins %u (SDA) and %u (SCL%s)\n",
pdata->sda_pin, pdata->scl_pin, pdata->sda_pin, pdata->scl_pin,
...@@ -168,34 +216,40 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev) ...@@ -168,34 +216,40 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
err_request_scl: err_request_scl:
gpio_free(pdata->sda_pin); gpio_free(pdata->sda_pin);
err_request_sda: err_request_sda:
kfree(bit_data);
err_alloc_bit_data:
kfree(adap);
err_alloc_adap:
return ret; return ret;
} }
static int __devexit i2c_gpio_remove(struct platform_device *pdev) static int __devexit i2c_gpio_remove(struct platform_device *pdev)
{ {
struct i2c_gpio_private_data *priv;
struct i2c_gpio_platform_data *pdata; struct i2c_gpio_platform_data *pdata;
struct i2c_adapter *adap; struct i2c_adapter *adap;
adap = platform_get_drvdata(pdev); priv = platform_get_drvdata(pdev);
pdata = pdev->dev.platform_data; adap = &priv->adap;
pdata = &priv->pdata;
i2c_del_adapter(adap); i2c_del_adapter(adap);
gpio_free(pdata->scl_pin); gpio_free(pdata->scl_pin);
gpio_free(pdata->sda_pin); gpio_free(pdata->sda_pin);
kfree(adap->algo_data);
kfree(adap);
return 0; return 0;
} }
#if defined(CONFIG_OF)
static const struct of_device_id i2c_gpio_dt_ids[] = {
{ .compatible = "i2c-gpio", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, i2c_gpio_dt_ids);
#endif
static struct platform_driver i2c_gpio_driver = { static struct platform_driver i2c_gpio_driver = {
.driver = { .driver = {
.name = "i2c-gpio", .name = "i2c-gpio",
.owner = THIS_MODULE, .owner = THIS_MODULE,
.of_match_table = of_match_ptr(i2c_gpio_dt_ids),
}, },
.probe = i2c_gpio_probe, .probe = i2c_gpio_probe,
.remove = __devexit_p(i2c_gpio_remove), .remove = __devexit_p(i2c_gpio_remove),
......
...@@ -27,6 +27,10 @@ ...@@ -27,6 +27,10 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
#include <linux/of_mtd.h>
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h> #include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h> #include <linux/mtd/partitions.h>
...@@ -34,22 +38,10 @@ ...@@ -34,22 +38,10 @@
#include <linux/dmaengine.h> #include <linux/dmaengine.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/platform_data/atmel.h>
#include <mach/board.h>
#include <mach/cpu.h> #include <mach/cpu.h>
#ifdef CONFIG_MTD_NAND_ATMEL_ECC_HW
#define hard_ecc 1
#else
#define hard_ecc 0
#endif
#ifdef CONFIG_MTD_NAND_ATMEL_ECC_NONE
#define no_ecc 1
#else
#define no_ecc 0
#endif
static int use_dma = 1; static int use_dma = 1;
module_param(use_dma, int, 0); module_param(use_dma, int, 0);
...@@ -95,7 +87,7 @@ struct atmel_nand_host { ...@@ -95,7 +87,7 @@ struct atmel_nand_host {
struct mtd_info mtd; struct mtd_info mtd;
void __iomem *io_base; void __iomem *io_base;
dma_addr_t io_phys; dma_addr_t io_phys;
struct atmel_nand_data *board; struct atmel_nand_data board;
struct device *dev; struct device *dev;
void __iomem *ecc; void __iomem *ecc;
...@@ -113,8 +105,8 @@ static int cpu_has_dma(void) ...@@ -113,8 +105,8 @@ static int cpu_has_dma(void)
*/ */
static void atmel_nand_enable(struct atmel_nand_host *host) static void atmel_nand_enable(struct atmel_nand_host *host)
{ {
if (gpio_is_valid(host->board->enable_pin)) if (gpio_is_valid(host->board.enable_pin))
gpio_set_value(host->board->enable_pin, 0); gpio_set_value(host->board.enable_pin, 0);
} }
/* /*
...@@ -122,8 +114,8 @@ static void atmel_nand_enable(struct atmel_nand_host *host) ...@@ -122,8 +114,8 @@ static void atmel_nand_enable(struct atmel_nand_host *host)
*/ */
static void atmel_nand_disable(struct atmel_nand_host *host) static void atmel_nand_disable(struct atmel_nand_host *host)
{ {
if (gpio_is_valid(host->board->enable_pin)) if (gpio_is_valid(host->board.enable_pin))
gpio_set_value(host->board->enable_pin, 1); gpio_set_value(host->board.enable_pin, 1);
} }
/* /*
...@@ -144,9 +136,9 @@ static void atmel_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl ...@@ -144,9 +136,9 @@ static void atmel_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl
return; return;
if (ctrl & NAND_CLE) if (ctrl & NAND_CLE)
writeb(cmd, host->io_base + (1 << host->board->cle)); writeb(cmd, host->io_base + (1 << host->board.cle));
else else
writeb(cmd, host->io_base + (1 << host->board->ale)); writeb(cmd, host->io_base + (1 << host->board.ale));
} }
/* /*
...@@ -157,8 +149,8 @@ static int atmel_nand_device_ready(struct mtd_info *mtd) ...@@ -157,8 +149,8 @@ static int atmel_nand_device_ready(struct mtd_info *mtd)
struct nand_chip *nand_chip = mtd->priv; struct nand_chip *nand_chip = mtd->priv;
struct atmel_nand_host *host = nand_chip->priv; struct atmel_nand_host *host = nand_chip->priv;
return gpio_get_value(host->board->rdy_pin) ^ return gpio_get_value(host->board.rdy_pin) ^
!!host->board->rdy_pin_active_low; !!host->board.rdy_pin_active_low;
} }
/* /*
...@@ -273,7 +265,7 @@ static void atmel_read_buf(struct mtd_info *mtd, u8 *buf, int len) ...@@ -273,7 +265,7 @@ static void atmel_read_buf(struct mtd_info *mtd, u8 *buf, int len)
if (atmel_nand_dma_op(mtd, buf, len, 1) == 0) if (atmel_nand_dma_op(mtd, buf, len, 1) == 0)
return; return;
if (host->board->bus_width_16) if (host->board.bus_width_16)
atmel_read_buf16(mtd, buf, len); atmel_read_buf16(mtd, buf, len);
else else
atmel_read_buf8(mtd, buf, len); atmel_read_buf8(mtd, buf, len);
...@@ -289,7 +281,7 @@ static void atmel_write_buf(struct mtd_info *mtd, const u8 *buf, int len) ...@@ -289,7 +281,7 @@ static void atmel_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
if (atmel_nand_dma_op(mtd, (void *)buf, len, 0) == 0) if (atmel_nand_dma_op(mtd, (void *)buf, len, 0) == 0)
return; return;
if (host->board->bus_width_16) if (host->board.bus_width_16)
atmel_write_buf16(mtd, buf, len); atmel_write_buf16(mtd, buf, len);
else else
atmel_write_buf8(mtd, buf, len); atmel_write_buf8(mtd, buf, len);
...@@ -481,6 +473,56 @@ static void atmel_nand_hwctl(struct mtd_info *mtd, int mode) ...@@ -481,6 +473,56 @@ static void atmel_nand_hwctl(struct mtd_info *mtd, int mode)
} }
} }
#if defined(CONFIG_OF)
static int __devinit atmel_of_init_port(struct atmel_nand_host *host,
struct device_node *np)
{
u32 val;
int ecc_mode;
struct atmel_nand_data *board = &host->board;
enum of_gpio_flags flags;
if (of_property_read_u32(np, "atmel,nand-addr-offset", &val) == 0) {
if (val >= 32) {
dev_err(host->dev, "invalid addr-offset %u\n", val);
return -EINVAL;
}
board->ale = val;
}
if (of_property_read_u32(np, "atmel,nand-cmd-offset", &val) == 0) {
if (val >= 32) {
dev_err(host->dev, "invalid cmd-offset %u\n", val);
return -EINVAL;
}
board->cle = val;
}
ecc_mode = of_get_nand_ecc_mode(np);
board->ecc_mode = ecc_mode < 0 ? NAND_ECC_SOFT : ecc_mode;
board->on_flash_bbt = of_get_nand_on_flash_bbt(np);
if (of_get_nand_bus_width(np) == 16)
board->bus_width_16 = 1;
board->rdy_pin = of_get_gpio_flags(np, 0, &flags);
board->rdy_pin_active_low = (flags == OF_GPIO_ACTIVE_LOW);
board->enable_pin = of_get_gpio(np, 1);
board->det_pin = of_get_gpio(np, 2);
return 0;
}
#else
static int __devinit atmel_of_init_port(struct atmel_nand_host *host,
struct device_node *np)
{
return -EINVAL;
}
#endif
/* /*
* Probe for the NAND device. * Probe for the NAND device.
*/ */
...@@ -491,6 +533,7 @@ static int __init atmel_nand_probe(struct platform_device *pdev) ...@@ -491,6 +533,7 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
struct nand_chip *nand_chip; struct nand_chip *nand_chip;
struct resource *regs; struct resource *regs;
struct resource *mem; struct resource *mem;
struct mtd_part_parser_data ppdata = {};
int res; int res;
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
...@@ -517,8 +560,15 @@ static int __init atmel_nand_probe(struct platform_device *pdev) ...@@ -517,8 +560,15 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
mtd = &host->mtd; mtd = &host->mtd;
nand_chip = &host->nand_chip; nand_chip = &host->nand_chip;
host->board = pdev->dev.platform_data;
host->dev = &pdev->dev; host->dev = &pdev->dev;
if (pdev->dev.of_node) {
res = atmel_of_init_port(host, pdev->dev.of_node);
if (res)
goto err_nand_ioremap;
} else {
memcpy(&host->board, pdev->dev.platform_data,
sizeof(struct atmel_nand_data));
}
nand_chip->priv = host; /* link the private data structures */ nand_chip->priv = host; /* link the private data structures */
mtd->priv = nand_chip; mtd->priv = nand_chip;
...@@ -529,26 +579,25 @@ static int __init atmel_nand_probe(struct platform_device *pdev) ...@@ -529,26 +579,25 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
nand_chip->IO_ADDR_W = host->io_base; nand_chip->IO_ADDR_W = host->io_base;
nand_chip->cmd_ctrl = atmel_nand_cmd_ctrl; nand_chip->cmd_ctrl = atmel_nand_cmd_ctrl;
if (gpio_is_valid(host->board->rdy_pin)) if (gpio_is_valid(host->board.rdy_pin))
nand_chip->dev_ready = atmel_nand_device_ready; nand_chip->dev_ready = atmel_nand_device_ready;
nand_chip->ecc.mode = host->board.ecc_mode;
regs = platform_get_resource(pdev, IORESOURCE_MEM, 1); regs = platform_get_resource(pdev, IORESOURCE_MEM, 1);
if (!regs && hard_ecc) { if (!regs && nand_chip->ecc.mode == NAND_ECC_HW) {
printk(KERN_ERR "atmel_nand: can't get I/O resource " printk(KERN_ERR "atmel_nand: can't get I/O resource "
"regs\nFalling back on software ECC\n"); "regs\nFalling back on software ECC\n");
nand_chip->ecc.mode = NAND_ECC_SOFT;
} }
nand_chip->ecc.mode = NAND_ECC_SOFT; /* enable ECC */ if (nand_chip->ecc.mode == NAND_ECC_HW) {
if (no_ecc)
nand_chip->ecc.mode = NAND_ECC_NONE;
if (hard_ecc && regs) {
host->ecc = ioremap(regs->start, resource_size(regs)); host->ecc = ioremap(regs->start, resource_size(regs));
if (host->ecc == NULL) { if (host->ecc == NULL) {
printk(KERN_ERR "atmel_nand: ioremap failed\n"); printk(KERN_ERR "atmel_nand: ioremap failed\n");
res = -EIO; res = -EIO;
goto err_ecc_ioremap; goto err_ecc_ioremap;
} }
nand_chip->ecc.mode = NAND_ECC_HW;
nand_chip->ecc.calculate = atmel_nand_calculate; nand_chip->ecc.calculate = atmel_nand_calculate;
nand_chip->ecc.correct = atmel_nand_correct; nand_chip->ecc.correct = atmel_nand_correct;
nand_chip->ecc.hwctl = atmel_nand_hwctl; nand_chip->ecc.hwctl = atmel_nand_hwctl;
...@@ -558,7 +607,7 @@ static int __init atmel_nand_probe(struct platform_device *pdev) ...@@ -558,7 +607,7 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
nand_chip->chip_delay = 20; /* 20us command delay time */ nand_chip->chip_delay = 20; /* 20us command delay time */
if (host->board->bus_width_16) /* 16-bit bus width */ if (host->board.bus_width_16) /* 16-bit bus width */
nand_chip->options |= NAND_BUSWIDTH_16; nand_chip->options |= NAND_BUSWIDTH_16;
nand_chip->read_buf = atmel_read_buf; nand_chip->read_buf = atmel_read_buf;
...@@ -567,15 +616,15 @@ static int __init atmel_nand_probe(struct platform_device *pdev) ...@@ -567,15 +616,15 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, host); platform_set_drvdata(pdev, host);
atmel_nand_enable(host); atmel_nand_enable(host);
if (gpio_is_valid(host->board->det_pin)) { if (gpio_is_valid(host->board.det_pin)) {
if (gpio_get_value(host->board->det_pin)) { if (gpio_get_value(host->board.det_pin)) {
printk(KERN_INFO "No SmartMedia card inserted.\n"); printk(KERN_INFO "No SmartMedia card inserted.\n");
res = -ENXIO; res = -ENXIO;
goto err_no_card; goto err_no_card;
} }
} }
if (on_flash_bbt) { if (host->board.on_flash_bbt || on_flash_bbt) {
printk(KERN_INFO "atmel_nand: Use On Flash BBT\n"); printk(KERN_INFO "atmel_nand: Use On Flash BBT\n");
nand_chip->bbt_options |= NAND_BBT_USE_FLASH; nand_chip->bbt_options |= NAND_BBT_USE_FLASH;
} }
...@@ -650,8 +699,9 @@ static int __init atmel_nand_probe(struct platform_device *pdev) ...@@ -650,8 +699,9 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
} }
mtd->name = "atmel_nand"; mtd->name = "atmel_nand";
res = mtd_device_parse_register(mtd, NULL, 0, ppdata.of_node = pdev->dev.of_node;
host->board->parts, host->board->num_parts); res = mtd_device_parse_register(mtd, NULL, &ppdata,
host->board.parts, host->board.num_parts);
if (!res) if (!res)
return res; return res;
...@@ -695,11 +745,21 @@ static int __exit atmel_nand_remove(struct platform_device *pdev) ...@@ -695,11 +745,21 @@ static int __exit atmel_nand_remove(struct platform_device *pdev)
return 0; return 0;
} }
#if defined(CONFIG_OF)
static const struct of_device_id atmel_nand_dt_ids[] = {
{ .compatible = "atmel,at91rm9200-nand" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, atmel_nand_dt_ids);
#endif
static struct platform_driver atmel_nand_driver = { static struct platform_driver atmel_nand_driver = {
.remove = __exit_p(atmel_nand_remove), .remove = __exit_p(atmel_nand_remove),
.driver = { .driver = {
.name = "atmel_nand", .name = "atmel_nand",
.owner = THIS_MODULE, .owner = THIS_MODULE,
.of_match_table = of_match_ptr(atmel_nand_dt_ids),
}, },
}; };
......
...@@ -90,4 +90,8 @@ config OF_PCI_IRQ ...@@ -90,4 +90,8 @@ config OF_PCI_IRQ
help help
OpenFirmware PCI IRQ routing helpers OpenFirmware PCI IRQ routing helpers
config OF_MTD
depends on MTD
def_bool y
endmenu # OF endmenu # OF
...@@ -12,3 +12,4 @@ obj-$(CONFIG_OF_SELFTEST) += selftest.o ...@@ -12,3 +12,4 @@ obj-$(CONFIG_OF_SELFTEST) += selftest.o
obj-$(CONFIG_OF_MDIO) += of_mdio.o obj-$(CONFIG_OF_MDIO) += of_mdio.o
obj-$(CONFIG_OF_PCI) += of_pci.o obj-$(CONFIG_OF_PCI) += of_pci.o
obj-$(CONFIG_OF_PCI_IRQ) += of_pci_irq.o obj-$(CONFIG_OF_PCI_IRQ) += of_pci_irq.o
obj-$(CONFIG_OF_MTD) += of_mtd.o
/*
* Copyright 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
*
* OF helpers for mtd.
*
* This file is released under the GPLv2
*
*/
#include <linux/kernel.h>
#include <linux/of_mtd.h>
#include <linux/mtd/nand.h>
#include <linux/export.h>
/**
* It maps 'enum nand_ecc_modes_t' found in include/linux/mtd/nand.h
* into the device tree binding of 'nand-ecc', so that MTD
* device driver can get nand ecc from device tree.
*/
static const char *nand_ecc_modes[] = {
[NAND_ECC_NONE] = "none",
[NAND_ECC_SOFT] = "soft",
[NAND_ECC_HW] = "hw",
[NAND_ECC_HW_SYNDROME] = "hw_syndrome",
[NAND_ECC_HW_OOB_FIRST] = "hw_oob_first",
[NAND_ECC_SOFT_BCH] = "soft_bch",
};
/**
* of_get_nand_ecc_mode - Get nand ecc mode for given device_node
* @np: Pointer to the given device_node
*
* The function gets ecc mode string from property 'nand-ecc-mode',
* and return its index in nand_ecc_modes table, or errno in error case.
*/
const int of_get_nand_ecc_mode(struct device_node *np)
{
const char *pm;
int err, i;
err = of_property_read_string(np, "nand-ecc-mode", &pm);
if (err < 0)
return err;
for (i = 0; i < ARRAY_SIZE(nand_ecc_modes); i++)
if (!strcasecmp(pm, nand_ecc_modes[i]))
return i;
return -ENODEV;
}
EXPORT_SYMBOL_GPL(of_get_nand_ecc_mode);
/**
* of_get_nand_bus_width - Get nand bus witdh for given device_node
* @np: Pointer to the given device_node
*
* return bus width option, or errno in error case.
*/
int of_get_nand_bus_width(struct device_node *np)
{
u32 val;
if (of_property_read_u32(np, "nand-bus-width", &val))
return 8;
switch(val) {
case 8:
case 16:
return val;
default:
return -EIO;
}
}
EXPORT_SYMBOL_GPL(of_get_nand_bus_width);
/**
* of_get_nand_on_flash_bbt - Get nand on flash bbt for given device_node
* @np: Pointer to the given device_node
*
* return true if present false other wise
*/
bool of_get_nand_on_flash_bbt(struct device_node *np)
{
return of_property_read_bool(np, "nand-on-flash-bbt");
}
EXPORT_SYMBOL_GPL(of_get_nand_on_flash_bbt);
...@@ -65,7 +65,7 @@ config USB_ARCH_HAS_EHCI ...@@ -65,7 +65,7 @@ config USB_ARCH_HAS_EHCI
default y if PPC_MPC512x default y if PPC_MPC512x
default y if ARCH_IXP4XX default y if ARCH_IXP4XX
default y if ARCH_W90X900 default y if ARCH_W90X900
default y if ARCH_AT91SAM9G45 default y if ARCH_AT91
default y if ARCH_MXC default y if ARCH_MXC
default y if ARCH_OMAP3 default y if ARCH_OMAP3
default y if ARCH_CNS3XXX default y if ARCH_CNS3XXX
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/of_platform.h>
/* interface and function clocks */ /* interface and function clocks */
static struct clk *iclk, *fclk; static struct clk *iclk, *fclk;
...@@ -115,6 +116,8 @@ static const struct hc_driver ehci_atmel_hc_driver = { ...@@ -115,6 +116,8 @@ static const struct hc_driver ehci_atmel_hc_driver = {
.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
}; };
static u64 at91_ehci_dma_mask = DMA_BIT_MASK(32);
static int __devinit ehci_atmel_drv_probe(struct platform_device *pdev) static int __devinit ehci_atmel_drv_probe(struct platform_device *pdev)
{ {
struct usb_hcd *hcd; struct usb_hcd *hcd;
...@@ -137,6 +140,13 @@ static int __devinit ehci_atmel_drv_probe(struct platform_device *pdev) ...@@ -137,6 +140,13 @@ static int __devinit ehci_atmel_drv_probe(struct platform_device *pdev)
goto fail_create_hcd; goto fail_create_hcd;
} }
/* Right now device-tree probed devices don't get dma_mask set.
* Since shared usb code relies on it, set it here for now.
* Once we have dma capability bindings this can go away.
*/
if (!pdev->dev.dma_mask)
pdev->dev.dma_mask = &at91_ehci_dma_mask;
hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
if (!hcd) { if (!hcd) {
retval = -ENOMEM; retval = -ENOMEM;
...@@ -225,9 +235,21 @@ static int __devexit ehci_atmel_drv_remove(struct platform_device *pdev) ...@@ -225,9 +235,21 @@ static int __devexit ehci_atmel_drv_remove(struct platform_device *pdev)
return 0; return 0;
} }
#ifdef CONFIG_OF
static const struct of_device_id atmel_ehci_dt_ids[] = {
{ .compatible = "atmel,at91sam9g45-ehci" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, atmel_ehci_dt_ids);
#endif
static struct platform_driver ehci_atmel_driver = { static struct platform_driver ehci_atmel_driver = {
.probe = ehci_atmel_drv_probe, .probe = ehci_atmel_drv_probe,
.remove = __devexit_p(ehci_atmel_drv_remove), .remove = __devexit_p(ehci_atmel_drv_remove),
.shutdown = usb_hcd_platform_shutdown, .shutdown = usb_hcd_platform_shutdown,
.driver.name = "atmel-ehci", .driver = {
.name = "atmel-ehci",
.of_match_table = of_match_ptr(atmel_ehci_dt_ids),
},
}; };
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/of_platform.h>
#include <linux/of_gpio.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <asm/gpio.h> #include <asm/gpio.h>
...@@ -477,13 +479,109 @@ static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data) ...@@ -477,13 +479,109 @@ static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
#ifdef CONFIG_OF
static const struct of_device_id at91_ohci_dt_ids[] = {
{ .compatible = "atmel,at91rm9200-ohci" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, at91_ohci_dt_ids);
static u64 at91_ohci_dma_mask = DMA_BIT_MASK(32);
static int __devinit ohci_at91_of_init(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
int i, ret, gpio;
enum of_gpio_flags flags;
struct at91_usbh_data *pdata;
u32 ports;
if (!np)
return 0;
/* Right now device-tree probed devices don't get dma_mask set.
* Since shared usb code relies on it, set it here for now.
* Once we have dma capability bindings this can go away.
*/
if (!pdev->dev.dma_mask)
pdev->dev.dma_mask = &at91_ohci_dma_mask;
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return -ENOMEM;
if (!of_property_read_u32(np, "num-ports", &ports))
pdata->ports = ports;
for (i = 0; i < 2; i++) {
gpio = of_get_named_gpio_flags(np, "atmel,vbus-gpio", i, &flags);
pdata->vbus_pin[i] = gpio;
if (!gpio_is_valid(gpio))
continue;
pdata->vbus_pin_active_low[i] = flags & OF_GPIO_ACTIVE_LOW;
ret = gpio_request(gpio, "ohci_vbus");
if (ret) {
dev_warn(&pdev->dev, "can't request vbus gpio %d", gpio);
continue;
}
ret = gpio_direction_output(gpio, !(flags & OF_GPIO_ACTIVE_LOW) ^ 1);
if (ret)
dev_warn(&pdev->dev, "can't put vbus gpio %d as output %d",
!(flags & OF_GPIO_ACTIVE_LOW) ^ 1, gpio);
}
for (i = 0; i < 2; i++) {
gpio = of_get_named_gpio_flags(np, "atmel,oc-gpio", i, &flags);
pdata->overcurrent_pin[i] = gpio;
if (!gpio_is_valid(gpio))
continue;
ret = gpio_request(gpio, "ohci_overcurrent");
if (ret) {
dev_err(&pdev->dev, "can't request overcurrent gpio %d", gpio);
continue;
}
ret = gpio_direction_input(gpio);
if (ret) {
dev_err(&pdev->dev, "can't configure overcurrent gpio %d as input", gpio);
continue;
}
ret = request_irq(gpio_to_irq(gpio),
ohci_hcd_at91_overcurrent_irq,
IRQF_SHARED, "ohci_overcurrent", pdev);
if (ret) {
gpio_free(gpio);
dev_warn(& pdev->dev, "cannot get GPIO IRQ for overcurrent\n");
}
}
pdev->dev.platform_data = pdata;
return 0;
}
#else
static int __devinit ohci_at91_of_init(struct platform_device *pdev)
{
return 0;
}
#endif
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
static int ohci_hcd_at91_drv_probe(struct platform_device *pdev) static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
{ {
struct at91_usbh_data *pdata = pdev->dev.platform_data; struct at91_usbh_data *pdata;
int i; int i;
i = ohci_at91_of_init(pdev);
if (i)
return i;
pdata = pdev->dev.platform_data;
if (pdata) { if (pdata) {
for (i = 0; i < ARRAY_SIZE(pdata->vbus_pin); i++) { for (i = 0; i < ARRAY_SIZE(pdata->vbus_pin); i++) {
if (!gpio_is_valid(pdata->vbus_pin[i])) if (!gpio_is_valid(pdata->vbus_pin[i]))
...@@ -596,5 +694,6 @@ static struct platform_driver ohci_hcd_at91_driver = { ...@@ -596,5 +694,6 @@ static struct platform_driver ohci_hcd_at91_driver = {
.driver = { .driver = {
.name = "at91_ohci", .name = "at91_ohci",
.owner = THIS_MODULE, .owner = THIS_MODULE,
.of_match_table = of_match_ptr(at91_ohci_dt_ids),
}, },
}; };
...@@ -342,6 +342,22 @@ static inline int of_machine_is_compatible(const char *compat) ...@@ -342,6 +342,22 @@ static inline int of_machine_is_compatible(const char *compat)
#define of_match_node(_matches, _node) NULL #define of_match_node(_matches, _node) NULL
#endif /* CONFIG_OF */ #endif /* CONFIG_OF */
/**
* of_property_read_bool - Findfrom a property
* @np: device node from which the property value is to be read.
* @propname: name of the property to be searched.
*
* Search for a property in a device node.
* Returns true if the property exist false otherwise.
*/
static inline bool of_property_read_bool(const struct device_node *np,
const char *propname)
{
struct property *prop = of_find_property(np, propname, NULL);
return prop ? true : false;
}
static inline int of_property_read_u32(const struct device_node *np, static inline int of_property_read_u32(const struct device_node *np,
const char *propname, const char *propname,
u32 *out_value) u32 *out_value)
......
/*
* Copyright 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
*
* OF helpers for mtd.
*
* This file is released under the GPLv2
*/
#ifndef __LINUX_OF_MTD_H
#define __LINUX_OF_NET_H
#ifdef CONFIG_OF_MTD
#include <linux/of.h>
extern const int of_get_nand_ecc_mode(struct device_node *np);
int of_get_nand_bus_width(struct device_node *np);
bool of_get_nand_on_flash_bbt(struct device_node *np);
#endif
#endif /* __LINUX_OF_MTD_H */
/*
* atmel platform data
*
* GPL v2 Only
*/
#ifndef __ATMEL_NAND_H__
#define __ATMEL_NAND_H__
#include <linux/mtd/nand.h>
/* NAND / SmartMedia */
struct atmel_nand_data {
int enable_pin; /* chip enable */
int det_pin; /* card detect */
int rdy_pin; /* ready/busy */
u8 rdy_pin_active_low; /* rdy_pin value is inverted */
u8 ale; /* address line number connected to ALE */
u8 cle; /* address line number connected to CLE */
u8 bus_width_16; /* buswidth is 16 bit */
u8 ecc_mode; /* ecc mode */
u8 on_flash_bbt; /* bbt on flash */
struct mtd_partition *parts;
unsigned int num_parts;
};
#endif /* __ATMEL_NAND_H__ */
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