ipq806x: add support for ruijie_rg-mtfi-m520 (#3025)

Signed-off-by: AmadeusGhost <42570690+AmadeusGhost@users.noreply.github.com>
This commit is contained in:
AmadeusGhost 2020-02-11 17:26:50 +08:00 committed by GitHub
parent cd3bbb525f
commit 464fb0c122
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 1530 additions and 2 deletions

View File

@ -33,6 +33,10 @@ netgear,r7800)
ucidef_set_led_switch "wan" "WAN" "${boardname}:white:wan" "switch0" "0x20"
ucidef_set_led_ide "esata" "eSATA" "${boardname}:white:esata"
;;
ruijie,rg-mtfi-m520)
ucidef_set_led_wlan "wlan2g" "WLAN2G" "${boardname}:green:wlan2g" "phy1tpt"
ucidef_set_led_wlan "wlan5g" "WLAN5G" "${boardname}:green:wlan5g" "phy0tpt"
;;
tplink,c2600)
ucidef_set_led_usbport "usb1" "USB 1" "${boardname}:white:usb_2" "usb1-port1" "usb2-port1"
ucidef_set_led_usbport "usb2" "USB 2" "${boardname}:white:usb_4" "usb3-port1" "usb4-port1"

View File

@ -48,6 +48,13 @@ qcom,ipq8064-db149)
ucidef_add_switch "switch0" \
"1:lan" "2:lan" "3:lan" "4:lan" "6u@eth1" "5:wan" "0u@eth0"
;;
ruijie,rg-mtfi-m520)
hw_mac_addr=$(mtd_get_mac_ascii PRODUCTINFO ethaddr)
ucidef_add_switch "switch0" \
"1:lan" "6@eth1" "5:wan" "0@eth0"
ucidef_set_interface_macaddr "wan" "$hw_mac_addr"
ucidef_set_interface_macaddr "lan" "$(macaddr_add $hw_mac_addr 1)"
;;
zyxel,nbg6817)
hw_mac_addr=$(mtd_get_mac_ascii 0:APPSBLENV ethaddr)
ucidef_add_switch "switch0" \

View File

@ -77,6 +77,22 @@ ath10kcal_patch_mac_crc() {
board=$(board_name)
case "$FIRMWARE" in
"ath10k/cal-pci-0000:01:00.0.bin")
case "$board" in
ruijie,rg-mtfi-m520)
ath10kcal_extract "ART" 4096 2116
ath10kcal_patch_mac_crc $(macaddr_add $(mtd_get_mac_ascii PRODUCTINFO ethaddr) +2)
;;
esac
;;
"ath10k/cal-pci-0001:01:00.0.bin")
case "$board" in
ruijie,rg-mtfi-m520)
ath10kcal_extract "ART" 20480 2116
ath10kcal_patch_mac_crc $(macaddr_add $(mtd_get_mac_ascii PRODUCTINFO ethaddr) +3)
;;
esac
;;
"ath10k/pre-cal-pci-0000:01:00.0.bin")
case $board in
buffalo,wxr-2533dhp)

View File

@ -0,0 +1,15 @@
#!/bin/sh
. /lib/functions.sh
preinit_set_mac_address() {
case $(board_name) in
ruijie,rg-mtfi-m520)
base_mac=$(mtd_get_mac_ascii PRODUCTINFO ethaddr)
ip link set dev eth0 address $(macaddr_add "$base_mac" +1)
ip link set dev eth1 address $(macaddr_add "$base_mac" +2)
;;
esac
}
boot_hook_add preinit_main preinit_set_mac_address

View File

@ -22,6 +22,7 @@ platform_do_upgrade() {
netgear,r7800 |\
qcom,ipq8064-ap148 |\
qcom,ipq8064-ap161 |\
ruijie,rg-mtfi-m520 |\
zyxel,nbg6817)
nand_do_upgrade "$ARGV"
;;
@ -47,6 +48,9 @@ platform_do_upgrade() {
platform_nand_pre_upgrade() {
case "$(board_name)" in
ruijie,rg-mtfi-m520)
ruijie_do_upgrade "$1"
;;
zyxel,nbg6817)
zyxel_do_upgrade "$1"
;;

View File

@ -0,0 +1,53 @@
#
# Copyright (C) 2016 lede-project.org
# Copyright (C) 2020 AnYun
#
ruijie_do_flash() {
local tar_file=$1
local kernel=$2
local rootfs=$3
# keep sure its unbound
losetup --detach-all || {
echo Failed to detach all loop devices. Skip this try.
reboot -f
}
# use the first found directory in the tar archive
local board_dir=$(tar tf $tar_file | grep -m 1 '^sysupgrade-.*/$')
board_dir=${board_dir%/}
echo "flashing kernel to $kernel"
tar xf $tar_file ${board_dir}/kernel -O > $kernel
echo "flashing rootfs to $rootfs"
tar xf $tar_file ${board_dir}/root -O > $rootfs
# Cleanup
losetup -d /dev/loop0 >/dev/null 2>&1
sync
umount -a
reboot -f
}
ruijie_do_upgrade() {
local tar_file="$1"
local board=$(board_name)
local kernel=
local rootfs=
case "$board" in
ruijie,rg-mtfi-m520)
kernel="/dev/mmcblk0p2"
rootfs="/dev/mmcblk0p3"
;;
*)
return 1
;;
esac
ruijie_do_flash $tar_file $kernel $rootfs
return 0
}

View File

@ -1,3 +1,4 @@
CONFIG_AHCI_IPQ=y
CONFIG_ALIGNMENT_TRAP=y
# CONFIG_AMBA_PL08X is not set
# CONFIG_APQ_GCC_8084 is not set

View File

@ -1,3 +1,4 @@
CONFIG_AHCI_IPQ=y
CONFIG_ALIGNMENT_TRAP=y
# CONFIG_APQ_GCC_8084 is not set
# CONFIG_APQ_MMCC_8084 is not set

View File

@ -0,0 +1,395 @@
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
#include "qcom-ipq8064-v2.0.dtsi"
#include <dt-bindings/input/input.h>
/ {
model = "Ruijie RG-MTFi-M520";
compatible = "ruijie,rg-mtfi-m520", "qcom,ipq8064";
memory@0 {
reg = <0x42000000 0x7e000000>;
device_type = "memory";
};
reserved-memory {
#address-cells = <1>;
#size-cells = <1>;
ranges;
rsvd@41200000 {
reg = <0x41200000 0x300000>;
no-map;
};
};
aliases {
serial0 = &gsbi4_serial;
mdio-gpio0 = &mdio0;
sdcc1 = &sdcc1;
};
chosen {
bootargs = "root=/dev/mmcblk0p3 rootfstype=squashfs,ext4 rootwait noinitrd";
stdout-path = "serial0:115200n8";
};
soc {
pinmux@800000 {
button_pins: button_pins {
mux {
pins = "gpio54";
function = "gpio";
drive-strength = <2>;
bias-pull-up;
};
};
i2c4_pins: i2c4_pinmux {
mux {
pins = "gpio12", "gpio13";
function = "gsbi4";
drive-strength = <12>;
bias-disable;
};
};
led_pins: led_pins {
mux {
pins = "gpio7", "gpio8", "gpio9", "gpio53";
function = "gpio";
drive-strength = <2>;
bias-pull-down;
};
};
mdio0_pins: mdio0_pins {
mux {
pins = "gpio0", "gpio1";
function = "gpio";
drive-strength = <8>;
bias-disable;
};
clk {
pins = "gpio1";
input-disable;
};
};
rgmii2_pins: rgmii2_pins {
mux {
pins = "gpio27", "gpio28", "gpio29", "gpio30", "gpio31", "gpio32",
"gpio51", "gpio52", "gpio59", "gpio60", "gpio61", "gpio62";
function = "rgmii2";
drive-strength = <8>;
bias-disable;
};
tx {
pins = "gpio27", "gpio28", "gpio29", "gpio30", "gpio31", "gpio32";
input-disable;
};
};
sdcc1_pins: sdcc1_pinmux {
mux {
pins = "gpio38", "gpio39", "gpio40", "gpio41", "gpio42",
"gpio43", "gpio44", "gpio45", "gpio46", "gpio47";
function = "sdc1";
};
cmd {
pins = "gpio45";
drive-strength = <10>;
bias-pull-up;
};
data {
pins = "gpio38", "gpio39", "gpio40", "gpio41",
"gpio43", "gpio44", "gpio46", "gpio47";
drive-strength = <10>;
bias-pull-up;
};
clk {
pins = "gpio42";
drive-strength = <16>;
bias-disable;
};
};
spi_pins: spi_pins {
mux {
pins = "gpio18", "gpio19", "gpio21";
function = "gsbi5";
drive-strength = <10>;
bias-none;
};
cs {
pins = "gpio20";
drive-strength = <12>;
};
};
};
gsbi@16300000 {
qcom,mode = <GSBI_PROT_I2C_UART>;
status = "ok";
serial@16340000 {
status = "ok";
};
/*
* The i2c device on gsbi4 should not be enabled.
* On ipq806x designs gsbi4 i2c is meant for exclusive
* RPM usage. Turning this on in kernel manifests as
* i2c failure for the RPM.
*/
};
gsbi5: gsbi@1a200000 {
qcom,mode = <GSBI_PROT_SPI>;
status = "ok";
spi4: spi@1a280000 {
status = "ok";
pinctrl-0 = <&spi_pins>;
pinctrl-names = "default";
cs-gpios = <&qcom_pinmux 20 GPIO_ACTIVE_HIGH>;
flash: m25p80@0 {
compatible = "jedec,spi-nor";
#address-cells = <1>;
#size-cells = <1>;
spi-max-frequency = <51200000>;
reg = <0>;
SBL1@0 {
label = "SBL1";
reg = <0x0 0x10000>;
read-only;
};
MIBIB@10000 {
label = "MIBIB";
reg = <0x10000 0x10000>;
read-only;
};
SBL2@20000 {
label = "SBL2";
reg = <0x20000 0x20000>;
read-only;
};
SBL3@40000 {
label = "SBL3";
reg = <0x40000 0x30000>;
read-only;
};
DDRCONFIG@70000 {
label = "DDRCONFIG";
reg = <0x70000 0x10000>;
read-only;
};
PRODUCTINFO: PRODUCTINFO@80000 {
label = "PRODUCTINFO";
reg = <0x80000 0x10000>;
read-only;
};
TZ@90000 {
label = "TZ";
reg = <0x90000 0x30000>;
read-only;
};
RPM@c0000 {
label = "RPM";
reg = <0xc0000 0x20000>;
read-only;
};
APPSBL@e0000 {
label = "APPSBL";
reg = <0xe0000 0x80000>;
read-only;
};
APPSBLENV@160000 {
label = "APPSBLENV";
reg = <0x160000 0x10000>;
read-only;
};
BOOTCONFIG@170000 {
label = "BOOTCONFIG";
reg = <0x170000 0x10000>;
read-only;
};
ART@180000 {
label = "ART";
reg = <0x180000 0x40000>;
read-only;
};
};
};
};
sata-phy@1b400000 {
status = "ok";
};
sata@29000000 {
ports-implemented = <0x1>;
status = "ok";
};
phy@100f8800 { /* USB3 port 1 HS phy */
status = "ok";
};
phy@100f8830 { /* USB3 port 1 SS phy */
status = "ok";
};
phy@110f8800 { /* USB3 port 0 HS phy */
status = "ok";
};
phy@110f8830 { /* USB3 port 0 SS phy */
status = "ok";
};
usb30@0 {
status = "ok";
};
usb30@1 {
status = "ok";
};
pcie0: pci@1b500000 {
status = "ok";
reset-gpio = <&qcom_pinmux 3 GPIO_ACTIVE_LOW>;
pinctrl-0 = <&pcie0_pins>;
pinctrl-names = "default";
};
pcie1: pci@1b700000 {
status = "ok";
reset-gpio = <&qcom_pinmux 48 GPIO_ACTIVE_LOW>;
pinctrl-0 = <&pcie1_pins>;
pinctrl-names = "default";
force_gen1 = <1>;
};
mdio0: mdio {
compatible = "virtual,mdio-gpio";
#address-cells = <1>;
#size-cells = <0>;
gpios = <&qcom_pinmux 1 GPIO_ACTIVE_HIGH &qcom_pinmux 0 GPIO_ACTIVE_HIGH>;
pinctrl-0 = <&mdio0_pins>;
pinctrl-names = "default";
phy0: ethernet-phy@0 {
reg = <0>;
qca,ar8327-initvals = <
0x00004 0x7600000 /* PAD0_MODE */
0x00008 0x1000000 /* PAD5_MODE */
0x0000c 0x80 /* PAD6_MODE */
0x000e4 0x6a545 /* MAC_POWER_SEL */
0x000e0 0xc74164de /* SGMII_CTRL */
0x0007c 0x4e /* PORT0_STATUS */
0x00094 0x4e /* PORT6_STATUS */
>;
};
phy4: ethernet-phy@4 {
reg = <4>;
};
};
gmac1: ethernet@37200000 {
status = "ok";
phy-mode = "rgmii";
qcom,id = <1>;
pinctrl-0 = <&rgmii2_pins>;
pinctrl-names = "default";
mtd-mac-address-ascii = <&PRODUCTINFO 0x86a>;
fixed-link {
speed = <1000>;
full-duplex;
};
};
gmac2: ethernet@37400000 {
status = "ok";
phy-mode = "sgmii";
qcom,id = <2>;
mtd-mac-address-ascii = <&PRODUCTINFO 0x86a>;
mtd-mac-address-increment = <1>;
mtd-mac-address-increment-byte = <0>;
fixed-link {
speed = <1000>;
full-duplex;
};
};
amba {
sdcc1: sdcc@12400000 {
status = "okay";
pinctrl-0 = <&sdcc1_pins>;
pinctrl-names = "default";
};
};
};
keys {
compatible = "gpio-keys";
pinctrl-0 = <&button_pins>;
pinctrl-names = "default";
reset {
label = "reset";
gpios = <&qcom_pinmux 54 GPIO_ACTIVE_LOW>;
linux,code = <KEY_RESTART>;
};
};
leds {
compatible = "gpio-leds";
pinctrl-0 = <&led_pins>;
pinctrl-names = "default";
usb_1 {
label = "m520:green:usb_1";
gpios = <&qcom_pinmux 7 GPIO_ACTIVE_HIGH>;
};
usb_3 {
label = "m520:green:usb_3";
gpios = <&qcom_pinmux 8 GPIO_ACTIVE_HIGH>;
};
status_green {
label = "m520:green:status";
gpios = <&qcom_pinmux 9 GPIO_ACTIVE_LOW>;
};
};
};
&adm_dma {
status = "ok";
};

View File

@ -0,0 +1,395 @@
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
#include "qcom-ipq8064-v2.0.dtsi"
#include <dt-bindings/input/input.h>
/ {
model = "Ruijie RG-MTFi-M520";
compatible = "ruijie,rg-mtfi-m520", "qcom,ipq8064";
memory@0 {
reg = <0x42000000 0x7e000000>;
device_type = "memory";
};
reserved-memory {
#address-cells = <1>;
#size-cells = <1>;
ranges;
rsvd@41200000 {
reg = <0x41200000 0x300000>;
no-map;
};
};
aliases {
serial0 = &gsbi4_serial;
mdio-gpio0 = &mdio0;
sdcc1 = &sdcc1;
};
chosen {
bootargs = "root=/dev/mmcblk0p3 rootfstype=squashfs,ext4 rootwait noinitrd";
stdout-path = "serial0:115200n8";
};
soc {
pinmux@800000 {
button_pins: button_pins {
mux {
pins = "gpio54";
function = "gpio";
drive-strength = <2>;
bias-pull-up;
};
};
i2c4_pins: i2c4_pinmux {
mux {
pins = "gpio12", "gpio13";
function = "gsbi4";
drive-strength = <12>;
bias-disable;
};
};
led_pins: led_pins {
mux {
pins = "gpio7", "gpio8", "gpio9", "gpio53";
function = "gpio";
drive-strength = <2>;
bias-pull-down;
};
};
mdio0_pins: mdio0_pins {
mux {
pins = "gpio0", "gpio1";
function = "gpio";
drive-strength = <8>;
bias-disable;
};
clk {
pins = "gpio1";
input-disable;
};
};
rgmii2_pins: rgmii2_pins {
mux {
pins = "gpio27", "gpio28", "gpio29", "gpio30", "gpio31", "gpio32",
"gpio51", "gpio52", "gpio59", "gpio60", "gpio61", "gpio62";
function = "rgmii2";
drive-strength = <8>;
bias-disable;
};
tx {
pins = "gpio27", "gpio28", "gpio29", "gpio30", "gpio31", "gpio32";
input-disable;
};
};
sdcc1_pins: sdcc1_pinmux {
mux {
pins = "gpio38", "gpio39", "gpio40", "gpio41", "gpio42",
"gpio43", "gpio44", "gpio45", "gpio46", "gpio47";
function = "sdc1";
};
cmd {
pins = "gpio45";
drive-strength = <10>;
bias-pull-up;
};
data {
pins = "gpio38", "gpio39", "gpio40", "gpio41",
"gpio43", "gpio44", "gpio46", "gpio47";
drive-strength = <10>;
bias-pull-up;
};
clk {
pins = "gpio42";
drive-strength = <16>;
bias-disable;
};
};
spi_pins: spi_pins {
mux {
pins = "gpio18", "gpio19", "gpio21";
function = "gsbi5";
drive-strength = <10>;
bias-none;
};
cs {
pins = "gpio20";
drive-strength = <12>;
};
};
};
gsbi@16300000 {
qcom,mode = <GSBI_PROT_I2C_UART>;
status = "ok";
serial@16340000 {
status = "ok";
};
/*
* The i2c device on gsbi4 should not be enabled.
* On ipq806x designs gsbi4 i2c is meant for exclusive
* RPM usage. Turning this on in kernel manifests as
* i2c failure for the RPM.
*/
};
gsbi5: gsbi@1a200000 {
qcom,mode = <GSBI_PROT_SPI>;
status = "ok";
spi4: spi@1a280000 {
status = "ok";
pinctrl-0 = <&spi_pins>;
pinctrl-names = "default";
cs-gpios = <&qcom_pinmux 20 GPIO_ACTIVE_HIGH>;
flash: m25p80@0 {
compatible = "jedec,spi-nor";
#address-cells = <1>;
#size-cells = <1>;
spi-max-frequency = <51200000>;
reg = <0>;
SBL1@0 {
label = "SBL1";
reg = <0x0 0x10000>;
read-only;
};
MIBIB@10000 {
label = "MIBIB";
reg = <0x10000 0x10000>;
read-only;
};
SBL2@20000 {
label = "SBL2";
reg = <0x20000 0x20000>;
read-only;
};
SBL3@40000 {
label = "SBL3";
reg = <0x40000 0x30000>;
read-only;
};
DDRCONFIG@70000 {
label = "DDRCONFIG";
reg = <0x70000 0x10000>;
read-only;
};
PRODUCTINFO: PRODUCTINFO@80000 {
label = "PRODUCTINFO";
reg = <0x80000 0x10000>;
read-only;
};
TZ@90000 {
label = "TZ";
reg = <0x90000 0x30000>;
read-only;
};
RPM@c0000 {
label = "RPM";
reg = <0xc0000 0x20000>;
read-only;
};
APPSBL@e0000 {
label = "APPSBL";
reg = <0xe0000 0x80000>;
read-only;
};
APPSBLENV@160000 {
label = "APPSBLENV";
reg = <0x160000 0x10000>;
read-only;
};
BOOTCONFIG@170000 {
label = "BOOTCONFIG";
reg = <0x170000 0x10000>;
read-only;
};
ART@180000 {
label = "ART";
reg = <0x180000 0x40000>;
read-only;
};
};
};
};
sata-phy@1b400000 {
status = "ok";
};
sata@29000000 {
ports-implemented = <0x1>;
status = "ok";
};
phy@100f8800 { /* USB3 port 1 HS phy */
status = "ok";
};
phy@100f8830 { /* USB3 port 1 SS phy */
status = "ok";
};
phy@110f8800 { /* USB3 port 0 HS phy */
status = "ok";
};
phy@110f8830 { /* USB3 port 0 SS phy */
status = "ok";
};
usb30@0 {
status = "ok";
};
usb30@1 {
status = "ok";
};
pcie0: pci@1b500000 {
status = "ok";
reset-gpio = <&qcom_pinmux 3 GPIO_ACTIVE_LOW>;
pinctrl-0 = <&pcie0_pins>;
pinctrl-names = "default";
};
pcie1: pci@1b700000 {
status = "ok";
reset-gpio = <&qcom_pinmux 48 GPIO_ACTIVE_LOW>;
pinctrl-0 = <&pcie1_pins>;
pinctrl-names = "default";
force_gen1 = <1>;
};
mdio0: mdio {
compatible = "virtual,mdio-gpio";
#address-cells = <1>;
#size-cells = <0>;
gpios = <&qcom_pinmux 1 GPIO_ACTIVE_HIGH &qcom_pinmux 0 GPIO_ACTIVE_HIGH>;
pinctrl-0 = <&mdio0_pins>;
pinctrl-names = "default";
phy0: ethernet-phy@0 {
reg = <0>;
qca,ar8327-initvals = <
0x00004 0x7600000 /* PAD0_MODE */
0x00008 0x1000000 /* PAD5_MODE */
0x0000c 0x80 /* PAD6_MODE */
0x000e4 0x6a545 /* MAC_POWER_SEL */
0x000e0 0xc74164de /* SGMII_CTRL */
0x0007c 0x4e /* PORT0_STATUS */
0x00094 0x4e /* PORT6_STATUS */
>;
};
phy4: ethernet-phy@4 {
reg = <4>;
};
};
gmac1: ethernet@37200000 {
status = "ok";
phy-mode = "rgmii";
qcom,id = <1>;
pinctrl-0 = <&rgmii2_pins>;
pinctrl-names = "default";
mtd-mac-address-ascii = <&PRODUCTINFO 0x86a>;
fixed-link {
speed = <1000>;
full-duplex;
};
};
gmac2: ethernet@37400000 {
status = "ok";
phy-mode = "sgmii";
qcom,id = <2>;
mtd-mac-address-ascii = <&PRODUCTINFO 0x86a>;
mtd-mac-address-increment = <1>;
mtd-mac-address-increment-byte = <0>;
fixed-link {
speed = <1000>;
full-duplex;
};
};
amba {
sdcc1: sdcc@12400000 {
status = "okay";
pinctrl-0 = <&sdcc1_pins>;
pinctrl-names = "default";
};
};
};
keys {
compatible = "gpio-keys";
pinctrl-0 = <&button_pins>;
pinctrl-names = "default";
reset {
label = "reset";
gpios = <&qcom_pinmux 54 GPIO_ACTIVE_LOW>;
linux,code = <KEY_RESTART>;
};
};
leds {
compatible = "gpio-leds";
pinctrl-0 = <&led_pins>;
pinctrl-names = "default";
usb_1 {
label = "m520:green:usb_1";
gpios = <&qcom_pinmux 7 GPIO_ACTIVE_HIGH>;
};
usb_3 {
label = "m520:green:usb_3";
gpios = <&qcom_pinmux 8 GPIO_ACTIVE_HIGH>;
};
status_green {
label = "m520:green:status";
gpios = <&qcom_pinmux 9 GPIO_ACTIVE_LOW>;
};
};
};
&adm_dma {
status = "ok";
};

View File

@ -260,6 +260,25 @@ define Device/qcom_ipq8064-db149
endef
TARGET_DEVICES += qcom_ipq8064-db149
define Device/ruijie_rg-mtfi-m520
DEVICE_VENDOR := Ruijie
DEVICE_MODEL := RG-MTFi-M520
DEVICE_DTS := qcom-ipq8064-mtfi-m520
KERNEL_SIZE := 4096k
BLOCKSIZE := 64k
BOARD_NAME := rg-mtfi-m520
KERNEL_SUFFIX := -uImage
KERNEL = kernel-bin | append-dtb | uImage none | pad-to $${KERNEL_SIZE}
KERNEL_NAME := zImage
IMAGES := factory.bin sysupgrade.bin mmcblk0p2-kernel.bin mmcblk0p3-rootfs.bin
IMAGE/factory.bin := qsdk-ipq-factory-nor
IMAGE/sysupgrade.bin/squashfs := append-rootfs | pad-to $$$${BLOCKSIZE} | sysupgrade-tar rootfs=$$$$@ | append-metadata
IMAGE/mmcblk0p2-kernel.bin := append-kernel | pad-to $$$${KERNEL_SIZE}
IMAGE/mmcblk0p3-rootfs.bin := append-rootfs | pad-rootfs
DEVICE_PACKAGES := ath10k-firmware-qca988x-ct blockd e2fsprogs f2fs-tools kmod-fs-ext4 kmod-fs-f2fs losetup
endef
TARGET_DEVICES += ruijie_rg-mtfi-m520
define Device/tplink_c2600
$(call Device/TpSafeImage)
DEVICE_VENDOR := TP-Link

View File

@ -10,7 +10,7 @@ Signed-off-by: John Crispin <john@phrozen.org>
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -699,6 +699,18 @@ dtb-$(CONFIG_ARCH_QCOM) += \
@@ -699,6 +699,19 @@ dtb-$(CONFIG_ARCH_QCOM) += \
qcom-apq8084-mtp.dtb \
qcom-ipq4019-ap.dk01.1-c1.dtb \
qcom-ipq8064-ap148.dtb \
@ -19,6 +19,7 @@ Signed-off-by: John Crispin <john@phrozen.org>
+ qcom-ipq8064-d7800.dtb \
+ qcom-ipq8064-db149.dtb \
+ qcom-ipq8064-ea8500.dtb \
+ qcom-ipq8064-mtfi-m520.dtb \
+ qcom-ipq8064-r7500.dtb \
+ qcom-ipq8064-r7500v2.dtb \
+ qcom-ipq8064-wg2600hp.dtb \

View File

@ -0,0 +1,308 @@
From c5ea64dcf7b5d45e402e78b9f291d521669b7b80 Mon Sep 17 00:00:00 2001
From: Kumar Gala <galak@codeaurora.org>
Date: Fri, 30 May 2014 15:35:40 -0500
Subject: [PATCH] ata: Add Qualcomm ARM SoC AHCI SATA host controller driver
Add support for the Qualcomm AHCI SATA controller that exists on several
SoC and specifically the IPQ806x family of chips. The IPQ806x SATA support
requires the associated IPQ806x SATA PHY Driver to be enabled as well.
Signed-off-by: Kumar Gala <galak@codeaurora.org>
Signed-off-by: Gokul Sriram Palanisamy <gpalan@codeaurora.org>
---
drivers/ata/ahci.h | 2 +-
drivers/ata/ahci_ipq.c | 248 ++++++++++++++++++++++++++++++++++++++
drivers/ata/Kconfig | 8 ++++++++
drivers/ata/Makefile | 1 +
4 files changed, 258 insertions(+), 1 deletions(-)
create mode 100644 drivers/ata/ahci_ipq.c
--- a/drivers/ata/ahci.h
+++ b/drivers/ata/ahci.h
@@ -54,7 +54,7 @@
enum {
AHCI_MAX_PORTS = 32,
- AHCI_MAX_CLKS = 5,
+ AHCI_MAX_CLKS = 6,
AHCI_MAX_SG = 168, /* hardware max is 64K */
AHCI_DMA_BOUNDARY = 0xffffffff,
AHCI_MAX_CMDS = 32,
--- a/dev/null
+++ b/drivers/ata/ahci_ipq.c
@@ -0,0 +1,248 @@
+/* Copyright (c) 2015 - 2017, The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pm.h>
+#include <linux/device.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/libata.h>
+#include <linux/ahci_platform.h>
+#include <linux/acpi.h>
+#include <linux/pci_ids.h>
+#include "libata.h"
+#include "ahci.h"
+
+#define IPQ_DRV_NAME "ahci-ipq"
+
+struct ipq_ahci_priv {
+ struct platform_device *ahci_pdev;
+ struct ahci_host_priv *hpriv;
+ void *preg_reset;
+ int pstate;
+};
+
+struct ipq_ahci_priv *ipqpriv;
+
+static const struct ata_port_info ipq_ahci_port_info = {
+ .flags = AHCI_FLAG_COMMON,
+ .pio_mask = ATA_PIO4,
+ .udma_mask = ATA_UDMA6,
+ .port_ops = &ahci_platform_ops,
+};
+
+static struct scsi_host_template ahci_platform_sht = {
+ AHCI_SHT(IPQ_DRV_NAME),
+};
+
+#define SATA_PWR_STATE_DOWN 0x1
+#define SATA_PWR_STATE_UP 0x2
+#define SATA_RESET 0x00902c1c
+
+static void ipq_ahci_hard_reset(struct device *dev)
+{
+ u32 reg;
+
+ reg = readl_relaxed(ipqpriv->preg_reset);
+ writel_relaxed(reg | BIT(0), ipqpriv->preg_reset);
+ /* To make sure the write is complete before we move on */
+ mb();
+
+ reg = readl_relaxed(ipqpriv->preg_reset);
+ writel_relaxed(reg & (~BIT(0)), ipqpriv->preg_reset);
+ /* To make sure the write is complete before we move on */
+ mb();
+}
+
+static int ipq_ahci_suspend(struct device *dev)
+{
+ struct ata_host *host = dev_get_drvdata(dev);
+ struct device_type *apt = &ata_port_type;
+ const struct dev_pm_ops *pm = apt->pm;
+ struct ata_port *ap;
+ int ret = 0, i;
+
+ if (ipqpriv->pstate == SATA_PWR_STATE_UP) {
+ for (i = 0; i < host->n_ports; i++) {
+ ap = host->ports[i];
+ /* Issue Port PM Suspend */
+ ret = pm->runtime_suspend(&ap->tdev);
+ if (ret) {
+ dev_err(dev, "SATA controller port suspend failed\n");
+ return ret;
+ }
+ }
+
+ /* Issue Contoller PM Suspend */
+ ret = ahci_platform_suspend_host(dev);
+ if (ret) {
+ dev_err(dev, "SATA controller host suspend failed\n");
+ return ret;
+ }
+
+ for (i = 0; i < ipqpriv->hpriv->nports; i++) {
+ if (!ipqpriv->hpriv->phys[i])
+ continue;
+
+ phy_power_off(ipqpriv->hpriv->phys[i]);
+ phy_exit(ipqpriv->hpriv->phys[i]);
+ }
+
+ ahci_platform_disable_clks(ipqpriv->hpriv);
+ ipqpriv->pstate = SATA_PWR_STATE_DOWN;
+ } else {
+ dev_warn(dev, "SATA device already in suspended state");
+ }
+
+ return ret;
+}
+
+static int ipq_ahci_resume(struct device *dev)
+{
+ struct ata_host *host = dev_get_drvdata(dev);
+ struct device_type *apt = &ata_port_type;
+ const struct dev_pm_ops *pm = apt->pm;
+ struct ata_port *ap;
+ int ret = 0, i;
+
+ if (ipqpriv->pstate == SATA_PWR_STATE_DOWN) {
+
+ ahci_platform_enable_clks(ipqpriv->hpriv);
+
+ /* Issue SATA clock hard reset */
+ ipq_ahci_hard_reset(dev);
+
+ for (i = 0; i < ipqpriv->hpriv->nports; i++) {
+ if (!ipqpriv->hpriv->phys[i])
+ continue;
+
+ phy_init(ipqpriv->hpriv->phys[i]);
+ phy_power_on(ipqpriv->hpriv->phys[i]);
+ }
+
+ /* Issue Contoller PM Resume */
+ ret = ahci_platform_resume_host(dev);
+ if (ret) {
+ dev_err(dev, "SATA controller resume failed\n");
+ return ret;
+ }
+
+ for (i = 0; i < host->n_ports; i++) {
+ /* Issue Port PM Resume */
+ ap = host->ports[i];
+ ret = pm->runtime_resume(&ap->tdev);
+ if (ret) {
+ dev_err(dev, "SATA controller port resume failed\n");
+ return ret;
+ }
+ }
+ ipqpriv->pstate = SATA_PWR_STATE_UP;
+ } else {
+ dev_warn(dev, "SATA device already in resume state");
+ }
+
+ return ret;
+}
+
+static int ipq_ahci_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct ahci_host_priv *hpriv;
+ int rc;
+
+ hpriv = ahci_platform_get_resources(pdev);
+ if (IS_ERR(hpriv))
+ return PTR_ERR(hpriv);
+
+ rc = ahci_platform_enable_resources(hpriv);
+ if (rc)
+ return rc;
+
+ of_property_read_u32(dev->of_node,
+ "ports-implemented", &hpriv->force_port_map);
+
+ rc = ahci_platform_init_host(pdev, hpriv, &ipq_ahci_port_info,
+ &ahci_platform_sht);
+
+ if (rc)
+ goto disable_resources;
+
+ ipqpriv = devm_kzalloc(dev, sizeof(*ipqpriv), GFP_KERNEL);
+ if (!ipqpriv) {
+ dev_err(dev, "can't alloc ahci_host_priv\n");
+ rc = -ENOMEM;
+ goto disable_resources;
+ }
+
+ ipqpriv->ahci_pdev = pdev;
+ ipqpriv->hpriv = hpriv;
+ ipqpriv->pstate = SATA_PWR_STATE_UP;
+
+ ipqpriv->preg_reset = devm_ioremap(dev, SATA_RESET,
+ sizeof(*(ipqpriv->preg_reset)));
+
+ if (IS_ERR(ipqpriv->preg_reset)) {
+ dev_err(dev, "can't ioremap for preg_reset\n");
+ rc = -ENOMEM;
+ goto disable_resources;
+ }
+
+ return 0;
+
+ disable_resources:
+ ahci_platform_disable_resources(hpriv);
+ return rc;
+}
+
+int ipq_ahci_remove(struct platform_device *pdev)
+{
+ ata_platform_remove_one(pdev);
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(ipq_ahci_pm_ops, ahci_platform_suspend,
+ ahci_platform_resume);
+
+static const struct of_device_id ipq_ahci_of_match[] = {
+ { .compatible = "qcom,ipq806x-ahci", },
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, ipq_ahci_of_match);
+
+static const struct acpi_device_id ahci_acpi_match[] = {
+ { ACPI_DEVICE_CLASS(PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff) },
+ {},
+};
+
+MODULE_DEVICE_TABLE(acpi, ahci_acpi_match);
+
+static struct platform_driver ipq_ahci_driver = {
+ .probe = ipq_ahci_probe,
+ .remove = ipq_ahci_remove,
+ .driver = {
+ .name = IPQ_DRV_NAME,
+ .of_match_table = ipq_ahci_of_match,
+ .acpi_match_table = ahci_acpi_match,
+ .pm = &ipq_ahci_pm_ops,
+ },
+};
+
+module_platform_driver(ipq_ahci_driver);
+
+MODULE_DESCRIPTION("IPQ806x AHCI SATA platform driver");
+MODULE_ALIAS("platform:ahci-ipq");
+MODULE_LICENSE("Dual BSD/GPL");
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -162,6 +162,14 @@ config AHCI_IMX
If unsure, say N.
+config AHCI_IPQ
+ tristate "Qualcomm Atheros IPQ806X AHCI SATA support"
+ help
+ This option enables support for the IPQ806X SoC's
+ onboard AHCI SATA.
+
+ If unsure, say N.
+
config AHCI_CEVA
tristate "CEVA AHCI SATA support"
depends on OF
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -18,6 +18,7 @@
obj-$(CONFIG_AHCI_DA850) += ahci_da850.o libahci.o libahci_platform.o
obj-$(CONFIG_AHCI_DM816) += ahci_dm816.o libahci.o libahci_platform.o
obj-$(CONFIG_AHCI_IMX) += ahci_imx.o libahci.o libahci_platform.o
+obj-$(CONFIG_AHCI_IPQ) += ahci_ipq.o libahci.o libahci_platform.o
obj-$(CONFIG_AHCI_MTK) += ahci_mtk.o libahci.o libahci_platform.o
obj-$(CONFIG_AHCI_MVEBU) += ahci_mvebu.o libahci.o libahci_platform.o
obj-$(CONFIG_AHCI_OCTEON) += ahci_octeon.o

View File

@ -10,7 +10,7 @@ Signed-off-by: John Crispin <john@phrozen.org>
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -791,6 +791,18 @@ dtb-$(CONFIG_ARCH_QCOM) += \
@@ -791,6 +791,19 @@ dtb-$(CONFIG_ARCH_QCOM) += \
qcom-ipq4019-ap.dk07.1-c1.dtb \
qcom-ipq4019-ap.dk07.1-c2.dtb \
qcom-ipq8064-ap148.dtb \
@ -19,6 +19,7 @@ Signed-off-by: John Crispin <john@phrozen.org>
+ qcom-ipq8064-d7800.dtb \
+ qcom-ipq8064-db149.dtb \
+ qcom-ipq8064-ea8500.dtb \
+ qcom-ipq8064-mtfi-m520.dtb \
+ qcom-ipq8064-r7500.dtb \
+ qcom-ipq8064-r7500v2.dtb \
+ qcom-ipq8064-wg2600hp.dtb \

View File

@ -0,0 +1,308 @@
From c5ea64dcf7b5d45e402e78b9f291d521669b7b80 Mon Sep 17 00:00:00 2001
From: Kumar Gala <galak@codeaurora.org>
Date: Fri, 30 May 2014 15:35:40 -0500
Subject: [PATCH] ata: Add Qualcomm ARM SoC AHCI SATA host controller driver
Add support for the Qualcomm AHCI SATA controller that exists on several
SoC and specifically the IPQ806x family of chips. The IPQ806x SATA support
requires the associated IPQ806x SATA PHY Driver to be enabled as well.
Signed-off-by: Kumar Gala <galak@codeaurora.org>
Signed-off-by: Gokul Sriram Palanisamy <gpalan@codeaurora.org>
---
drivers/ata/ahci.h | 2 +-
drivers/ata/ahci_ipq.c | 248 ++++++++++++++++++++++++++++++++++++++
drivers/ata/Kconfig | 8 ++++++++
drivers/ata/Makefile | 1 +
4 files changed, 258 insertions(+), 1 deletions(-)
create mode 100644 drivers/ata/ahci_ipq.c
--- a/drivers/ata/ahci.h
+++ b/drivers/ata/ahci.h
@@ -54,7 +54,7 @@
enum {
AHCI_MAX_PORTS = 32,
- AHCI_MAX_CLKS = 5,
+ AHCI_MAX_CLKS = 6,
AHCI_MAX_SG = 168, /* hardware max is 64K */
AHCI_DMA_BOUNDARY = 0xffffffff,
AHCI_MAX_CMDS = 32,
--- a/dev/null
+++ b/drivers/ata/ahci_ipq.c
@@ -0,0 +1,248 @@
+/* Copyright (c) 2015 - 2017, The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pm.h>
+#include <linux/device.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/libata.h>
+#include <linux/ahci_platform.h>
+#include <linux/acpi.h>
+#include <linux/pci_ids.h>
+#include "libata.h"
+#include "ahci.h"
+
+#define IPQ_DRV_NAME "ahci-ipq"
+
+struct ipq_ahci_priv {
+ struct platform_device *ahci_pdev;
+ struct ahci_host_priv *hpriv;
+ void *preg_reset;
+ int pstate;
+};
+
+struct ipq_ahci_priv *ipqpriv;
+
+static const struct ata_port_info ipq_ahci_port_info = {
+ .flags = AHCI_FLAG_COMMON,
+ .pio_mask = ATA_PIO4,
+ .udma_mask = ATA_UDMA6,
+ .port_ops = &ahci_platform_ops,
+};
+
+static struct scsi_host_template ahci_platform_sht = {
+ AHCI_SHT(IPQ_DRV_NAME),
+};
+
+#define SATA_PWR_STATE_DOWN 0x1
+#define SATA_PWR_STATE_UP 0x2
+#define SATA_RESET 0x00902c1c
+
+static void ipq_ahci_hard_reset(struct device *dev)
+{
+ u32 reg;
+
+ reg = readl_relaxed(ipqpriv->preg_reset);
+ writel_relaxed(reg | BIT(0), ipqpriv->preg_reset);
+ /* To make sure the write is complete before we move on */
+ mb();
+
+ reg = readl_relaxed(ipqpriv->preg_reset);
+ writel_relaxed(reg & (~BIT(0)), ipqpriv->preg_reset);
+ /* To make sure the write is complete before we move on */
+ mb();
+}
+
+static int ipq_ahci_suspend(struct device *dev)
+{
+ struct ata_host *host = dev_get_drvdata(dev);
+ struct device_type *apt = &ata_port_type;
+ const struct dev_pm_ops *pm = apt->pm;
+ struct ata_port *ap;
+ int ret = 0, i;
+
+ if (ipqpriv->pstate == SATA_PWR_STATE_UP) {
+ for (i = 0; i < host->n_ports; i++) {
+ ap = host->ports[i];
+ /* Issue Port PM Suspend */
+ ret = pm->runtime_suspend(&ap->tdev);
+ if (ret) {
+ dev_err(dev, "SATA controller port suspend failed\n");
+ return ret;
+ }
+ }
+
+ /* Issue Contoller PM Suspend */
+ ret = ahci_platform_suspend_host(dev);
+ if (ret) {
+ dev_err(dev, "SATA controller host suspend failed\n");
+ return ret;
+ }
+
+ for (i = 0; i < ipqpriv->hpriv->nports; i++) {
+ if (!ipqpriv->hpriv->phys[i])
+ continue;
+
+ phy_power_off(ipqpriv->hpriv->phys[i]);
+ phy_exit(ipqpriv->hpriv->phys[i]);
+ }
+
+ ahci_platform_disable_clks(ipqpriv->hpriv);
+ ipqpriv->pstate = SATA_PWR_STATE_DOWN;
+ } else {
+ dev_warn(dev, "SATA device already in suspended state");
+ }
+
+ return ret;
+}
+
+static int ipq_ahci_resume(struct device *dev)
+{
+ struct ata_host *host = dev_get_drvdata(dev);
+ struct device_type *apt = &ata_port_type;
+ const struct dev_pm_ops *pm = apt->pm;
+ struct ata_port *ap;
+ int ret = 0, i;
+
+ if (ipqpriv->pstate == SATA_PWR_STATE_DOWN) {
+
+ ahci_platform_enable_clks(ipqpriv->hpriv);
+
+ /* Issue SATA clock hard reset */
+ ipq_ahci_hard_reset(dev);
+
+ for (i = 0; i < ipqpriv->hpriv->nports; i++) {
+ if (!ipqpriv->hpriv->phys[i])
+ continue;
+
+ phy_init(ipqpriv->hpriv->phys[i]);
+ phy_power_on(ipqpriv->hpriv->phys[i]);
+ }
+
+ /* Issue Contoller PM Resume */
+ ret = ahci_platform_resume_host(dev);
+ if (ret) {
+ dev_err(dev, "SATA controller resume failed\n");
+ return ret;
+ }
+
+ for (i = 0; i < host->n_ports; i++) {
+ /* Issue Port PM Resume */
+ ap = host->ports[i];
+ ret = pm->runtime_resume(&ap->tdev);
+ if (ret) {
+ dev_err(dev, "SATA controller port resume failed\n");
+ return ret;
+ }
+ }
+ ipqpriv->pstate = SATA_PWR_STATE_UP;
+ } else {
+ dev_warn(dev, "SATA device already in resume state");
+ }
+
+ return ret;
+}
+
+static int ipq_ahci_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct ahci_host_priv *hpriv;
+ int rc;
+
+ hpriv = ahci_platform_get_resources(pdev);
+ if (IS_ERR(hpriv))
+ return PTR_ERR(hpriv);
+
+ rc = ahci_platform_enable_resources(hpriv);
+ if (rc)
+ return rc;
+
+ of_property_read_u32(dev->of_node,
+ "ports-implemented", &hpriv->force_port_map);
+
+ rc = ahci_platform_init_host(pdev, hpriv, &ipq_ahci_port_info,
+ &ahci_platform_sht);
+
+ if (rc)
+ goto disable_resources;
+
+ ipqpriv = devm_kzalloc(dev, sizeof(*ipqpriv), GFP_KERNEL);
+ if (!ipqpriv) {
+ dev_err(dev, "can't alloc ahci_host_priv\n");
+ rc = -ENOMEM;
+ goto disable_resources;
+ }
+
+ ipqpriv->ahci_pdev = pdev;
+ ipqpriv->hpriv = hpriv;
+ ipqpriv->pstate = SATA_PWR_STATE_UP;
+
+ ipqpriv->preg_reset = devm_ioremap(dev, SATA_RESET,
+ sizeof(*(ipqpriv->preg_reset)));
+
+ if (IS_ERR(ipqpriv->preg_reset)) {
+ dev_err(dev, "can't ioremap for preg_reset\n");
+ rc = -ENOMEM;
+ goto disable_resources;
+ }
+
+ return 0;
+
+ disable_resources:
+ ahci_platform_disable_resources(hpriv);
+ return rc;
+}
+
+int ipq_ahci_remove(struct platform_device *pdev)
+{
+ ata_platform_remove_one(pdev);
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(ipq_ahci_pm_ops, ahci_platform_suspend,
+ ahci_platform_resume);
+
+static const struct of_device_id ipq_ahci_of_match[] = {
+ { .compatible = "qcom,ipq806x-ahci", },
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, ipq_ahci_of_match);
+
+static const struct acpi_device_id ahci_acpi_match[] = {
+ { ACPI_DEVICE_CLASS(PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff) },
+ {},
+};
+
+MODULE_DEVICE_TABLE(acpi, ahci_acpi_match);
+
+static struct platform_driver ipq_ahci_driver = {
+ .probe = ipq_ahci_probe,
+ .remove = ipq_ahci_remove,
+ .driver = {
+ .name = IPQ_DRV_NAME,
+ .of_match_table = ipq_ahci_of_match,
+ .acpi_match_table = ahci_acpi_match,
+ .pm = &ipq_ahci_pm_ops,
+ },
+};
+
+module_platform_driver(ipq_ahci_driver);
+
+MODULE_DESCRIPTION("IPQ806x AHCI SATA platform driver");
+MODULE_ALIAS("platform:ahci-ipq");
+MODULE_LICENSE("Dual BSD/GPL");
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -162,6 +162,14 @@ config AHCI_IMX
If unsure, say N.
+config AHCI_IPQ
+ tristate "Qualcomm Atheros IPQ806X AHCI SATA support"
+ help
+ This option enables support for the IPQ806X SoC's
+ onboard AHCI SATA.
+
+ If unsure, say N.
+
config AHCI_CEVA
tristate "CEVA AHCI SATA support"
depends on OF
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -18,6 +18,7 @@
obj-$(CONFIG_AHCI_DA850) += ahci_da850.o libahci.o libahci_platform.o
obj-$(CONFIG_AHCI_DM816) += ahci_dm816.o libahci.o libahci_platform.o
obj-$(CONFIG_AHCI_IMX) += ahci_imx.o libahci.o libahci_platform.o
+obj-$(CONFIG_AHCI_IPQ) += ahci_ipq.o libahci.o libahci_platform.o
obj-$(CONFIG_AHCI_MTK) += ahci_mtk.o libahci.o libahci_platform.o
obj-$(CONFIG_AHCI_MVEBU) += ahci_mvebu.o libahci.o libahci_platform.o
obj-$(CONFIG_AHCI_OCTEON) += ahci_octeon.o