Merge Official Source

Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
Tianling Shen 2021-12-28 05:23:03 +08:00
commit ff4cbb40f2
No known key found for this signature in database
GPG Key ID: 6850B6345C862176
163 changed files with 4665 additions and 11611 deletions

View File

@ -7,10 +7,10 @@ ifdef CONFIG_TESTING_KERNEL
endif
LINUX_VERSION-5.4 = .167
LINUX_VERSION-5.10 = .87
LINUX_VERSION-5.10 = .88
LINUX_KERNEL_HASH-5.4.167 = b4e43116217ee02009aba7eab3081e64560b81ce42bc6096fcd81257f470a5a7
LINUX_KERNEL_HASH-5.10.87 = 03128b70f3063433cfab4ff4c7da288d7c045fe1eafa2a59081df4032fece64b
LINUX_KERNEL_HASH-5.10.88 = 6f8631b6c382a2b0cfeff1e5f8805c8e1cfbe8d714b6e65f5bb79733c99068eb
remove_uri_prefix=$(subst git://,,$(subst http://,,$(subst https://,,$(1))))
sanitize_uri=$(call qstrip,$(subst @,_,$(subst :,_,$(subst .,_,$(subst -,_,$(subst /,_,$(1)))))))

View File

@ -245,7 +245,7 @@ get_partitions() { # <device> <filename>
local type="$1"
local lba="$(( $(hex_le32_to_cpu $4) * 0x100000000 + $(hex_le32_to_cpu $3) ))"
local end="$(( $(hex_le32_to_cpu $6) * 0x100000000 + $(hex_le32_to_cpu $5) ))"
local num="$(( $end - $lba ))"
local num="$(( $end - $lba + 1 ))"
[ "$type" = "00000000000000000000000000000000" ] && continue

View File

@ -0,0 +1,42 @@
# SPDX-License-Identifier: GPL-2.0
include $(TOPDIR)/rules.mk
PKG_VERSION:=2.2
PKG_RELEASE:=$(AUTORELEASE)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=$(PROJECT_GIT)/project/bcm63xx/atf.git
PKG_SOURCE_DATE:=2021-12-24
PKG_SOURCE_VERSION:=e6d46baf3fae79f693f90bf34f7284c3dfc64aef
PKG_MIRROR_HASH:=9d5d04f572b1b6ddc6eb3064b9cb09f5fe982e82d350790041d35316349af124
PKG_MAINTAINER:=Rafał Miłecki <rafal@milecki.pl>
include $(INCLUDE_DIR)/trusted-firmware-a.mk
include $(INCLUDE_DIR)/package.mk
define Trusted-Firmware-A/Default
PLAT:=bcm
DEFAULT:=y
endef
define Trusted-Firmware-A/bcm4908
BUILD_TARGET:=bcm4908
NAME:=BCM4908
BRCM_CHIP=4908
TFA_IMAGE:=bl31.bin
endef
TFA_TARGETS:= \
bcm4908
TFA_MAKE_FLAGS += \
BRCM_CHIP=$(BRCM_CHIP)
define Package/trusted-firmware-a/install
$(INSTALL_DIR) $(STAGING_DIR_IMAGE)
$(INSTALL_DATA) $(PKG_BUILD_DIR)/build/$(PLAT)/release/$(TFA_IMAGE) $(STAGING_DIR_IMAGE)/
endef
$(eval $(call BuildPackage/Trusted-Firmware-A))

View File

@ -1,47 +0,0 @@
#
# Copyright (C) 2018 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=amd64-microcode
PKG_VERSION:=20191218
PKG_RELEASE:=1
PKG_SOURCE:=amd64-microcode_3.$(PKG_VERSION).$(PKG_RELEASE).tar.xz
PKG_SOURCE_URL:=@DEBIAN/pool/non-free/a/amd64-microcode/
PKG_HASH:=f469b79348097c5f04641b67a39d0ee5a2a1916c9556281626c04f2275d4132d
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-3.$(PKG_VERSION).$(PKG_RELEASE)
PKG_LICENSE_FILE:=LICENSE.amd-ucode
PKG_FLAGS:=nonshared
include $(INCLUDE_DIR)/package.mk
define Package/amd64-microcode
SECTION:=firmware
CATEGORY:=Firmware
URL:=$(PKG_SOURCE_URL)
DEPENDS:=@TARGET_x86
TITLE:=AMD64 CPU microcode
endef
define Build/Prepare
rm -rf $(PKG_BUILD_DIR)
mkdir -p $(PKG_BUILD_DIR)
$(TAR) -C $(BUILD_DIR) -xJf $(DL_DIR)/$(PKG_SOURCE)
endef
define Build/Compile
endef
define Package/amd64-microcode/install
$(INSTALL_DIR) $(1)/lib/firmware/amd-ucode
$(INSTALL_DATA) $(PKG_BUILD_DIR)/*.bin $(1)/lib/firmware/amd-ucode
endef
$(eval $(call BuildPackage,amd64-microcode))

View File

@ -8,12 +8,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=linux-firmware
PKG_VERSION:=20210511
PKG_VERSION:=20211216
PKG_RELEASE:=1
PKG_SOURCE_URL:=@KERNEL/linux/kernel/firmware
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_HASH:=2aa6ae8b9808408f9811ac38f00c188e53e984a2b3990254f6c9c02c1ab13417
PKG_HASH:=eeddb4e6bef31fd1a3757f12ccc324929bbad97855c0b9ec5ed780f74de1837d
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>

View File

@ -0,0 +1,29 @@
Package/amd64-microcode = $(call Package/firmware-default,AMD64 CPU microcode,@TARGET_x86)
define Package/amd64-microcode/install
$(INSTALL_DIR) $(1)/lib/firmware/amd-ucode
$(CP) \
$(PKG_BUILD_DIR)/amd-ucode/*.bin \
$(1)/lib/firmware/amd-ucode
endef
$(eval $(call BuildPackage,amd64-microcode))
Package/amdgpu-firmware = $(call Package/firmware-default,AMDGPU Video Driver firmware)
define Package/amdgpu-firmware/install
$(INSTALL_DIR) $(1)/lib/firmware/amdgpu
$(CP) \
$(PKG_BUILD_DIR)/amdgpu/*.bin \
$(1)/lib/firmware/amdgpu
endef
$(eval $(call BuildPackage,amdgpu-firmware))
Package/radeon-firmware = $(call Package/firmware-default,Radeon Video Driver firmware)
define Package/radeon-firmware/install
$(INSTALL_DIR) $(1)/lib/firmware/radeon
$(CP) \
$(PKG_BUILD_DIR)/radeon/*.bin \
$(1)/lib/firmware/radeon
endef
$(eval $(call BuildPackage,radeon-firmware))

View File

@ -1,9 +0,0 @@
Package/amdgpu-firmware = $(call Package/firmware-default,AMDGPU Video Driver firmware)
define Package/amdgpu-firmware/install
$(INSTALL_DIR) $(1)/lib/firmware/amdgpu
$(CP) \
$(PKG_BUILD_DIR)/amdgpu/*.bin \
$(1)/lib/firmware/amdgpu
endef
$(eval $(call BuildPackage,amdgpu-firmware))

View File

@ -1,9 +0,0 @@
Package/radeon-firmware = $(call Package/firmware-default,Radeon Video Driver firmware)
define Package/radeon-firmware/install
$(INSTALL_DIR) $(1)/lib/firmware/radeon
$(CP) \
$(PKG_BUILD_DIR)/radeon/*.bin \
$(1)/lib/firmware/radeon
endef
$(eval $(call BuildPackage,radeon-firmware))

View File

@ -89,16 +89,10 @@ Package/rtl8723bu-firmware = $(call Package/firmware-default,RealTek RTL8723BU f
define Package/rtl8723bu-firmware/install
$(INSTALL_DIR) $(1)/lib/firmware/rtlwifi
$(INSTALL_DATA) $(PKG_BUILD_DIR)/rtlwifi/rtl8723bu_nic.bin $(1)/lib/firmware/rtlwifi
ln -s rtl8723bu_nic.bin $(1)/lib/firmware/rtlwifi/rtl8723bs_nic.bin
endef
$(eval $(call BuildPackage,rtl8723bu-firmware))
Package/rtl8723bs-firmware = $(call Package/firmware-default,RealTek RTL8723BS firmware)
define Package/rtl8723bs-firmware/install
$(INSTALL_DIR) $(1)/lib/firmware/rtlwifi
$(INSTALL_DATA) $(PKG_BUILD_DIR)/rtlwifi/rtl8723bs*.bin $(1)/lib/firmware/rtlwifi
endef
$(eval $(call BuildPackage,rtl8723bs-firmware))
Package/rtl8821ae-firmware = $(call Package/firmware-default,RealTek RTL8821AE firmware)
define Package/rtl8821ae-firmware/install
$(INSTALL_DIR) $(1)/lib/firmware/rtlwifi

View File

@ -419,9 +419,15 @@ config-$(call config_package,rsi91x-sdio) += RSI_SDIO
config-$(CONFIG_LEDS_TRIGGERS) += MAC80211_LEDS
C_DEFINES=
ifeq ($(BUILD_VARIANT),smallbuffers)
C_DEFINES+= -DCONFIG_ATH10K_SMALLBUFFERS
endif
MAKE_OPTS:= -C "$(PKG_BUILD_DIR)" \
$(KERNEL_MAKE_FLAGS) \
EXTRA_CFLAGS="-I$(PKG_BUILD_DIR)/include $(IREMAP_CFLAGS)" \
EXTRA_CFLAGS="-I$(PKG_BUILD_DIR)/include $(IREMAP_CFLAGS) $(C_DEFINES)" \
KLIB_BUILD="$(LINUX_DIR)" \
MODPROBE=true \
KLIB=$(TARGET_MODULES_DIR) \

View File

@ -1,5 +1,5 @@
PKG_DRIVERS += \
ath ath5k ath6kl ath6kl-sdio ath6kl-usb ath9k ath9k-common ath9k-htc ath10k \
ath ath5k ath6kl ath6kl-sdio ath6kl-usb ath9k ath9k-common ath9k-htc ath10k ath10k-smallbuffers \
carl9170 owl-loader ar5523 wil6210
PKG_CONFIG_DEPENDS += \
@ -55,6 +55,7 @@ config-$(CONFIG_ATH10K_THERMAL) += ATH10K_THERMAL
config-$(call config_package,ath9k-htc) += ATH9K_HTC
config-$(call config_package,ath10k) += ATH10K ATH10K_PCI
config-$(call config_package,ath10k-smallbuffers) += ATH10K ATH10K_PCI ATH10K_SMALLBUFFERS
config-$(call config_package,ath5k) += ATH5K
ifdef CONFIG_TARGET_ath25
@ -260,6 +261,7 @@ define KernelPackage/ath10k
$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath10k/ath10k_core.ko \
$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath10k/ath10k_pci.ko
AUTOLOAD:=$(call AutoProbe,ath10k_pci)
VARIANT:=regular
endef
define KernelPackage/ath10k/description
@ -273,15 +275,21 @@ define KernelPackage/ath10k/config
config ATH10K_LEDS
bool "Enable LED support"
default y
depends on PACKAGE_kmod-ath10k
depends on PACKAGE_kmod-ath10k || PACKAGE_kmod-ath10k-smallbuffers
config ATH10K_THERMAL
bool "Enable thermal sensors and throttling support"
default y
depends on PACKAGE_kmod-ath10k
depends on PACKAGE_kmod-ath10k || PACKAGE_kmod-ath10k-smallbuffers
endef
define KernelPackage/ath10k-smallbuffers
$(call KernelPackage/ath10k)
TITLE+= (small buffers for low-RAM devices)
VARIANT:=smallbuffers
endef
define KernelPackage/carl9170
$(call KernelPackage/mac80211/Default)
TITLE:=Driver for Atheros AR9170 USB sticks

View File

@ -0,0 +1,64 @@
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -235,7 +235,11 @@ enum htt_rx_ring_flags {
};
#define HTT_RX_RING_SIZE_MIN 128
+#ifndef CONFIG_ATH10K_SMALLBUFFERS
#define HTT_RX_RING_SIZE_MAX 2048
+#else
+#define HTT_RX_RING_SIZE_MAX 512
+#endif
#define HTT_RX_RING_SIZE HTT_RX_RING_SIZE_MAX
#define HTT_RX_RING_FILL_LEVEL (((HTT_RX_RING_SIZE) / 2) - 1)
#define HTT_RX_RING_FILL_LEVEL_DUAL_MAC (HTT_RX_RING_SIZE - 1)
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -131,7 +131,11 @@ static const struct ce_attr pci_host_ce_
.flags = CE_ATTR_FLAGS,
.src_nentries = 0,
.src_sz_max = 2048,
+#ifndef CONFIG_ATH10K_SMALLBUFFERS
.dest_nentries = 512,
+#else
+ .dest_nentries = 128,
+#endif
.recv_cb = ath10k_pci_htt_htc_rx_cb,
},
@@ -140,7 +144,11 @@ static const struct ce_attr pci_host_ce_
.flags = CE_ATTR_FLAGS,
.src_nentries = 0,
.src_sz_max = 2048,
+#ifndef CONFIG_ATH10K_SMALLBUFFERS
.dest_nentries = 128,
+#else
+ .dest_nentries = 64,
+#endif
.recv_cb = ath10k_pci_htc_rx_cb,
},
@@ -167,7 +175,11 @@ static const struct ce_attr pci_host_ce_
.flags = CE_ATTR_FLAGS,
.src_nentries = 0,
.src_sz_max = 512,
+#ifndef CONFIG_ATH10K_SMALLBUFFERS
.dest_nentries = 512,
+#else
+ .dest_nentries = 128,
+#endif
.recv_cb = ath10k_pci_htt_rx_cb,
},
@@ -192,7 +204,11 @@ static const struct ce_attr pci_host_ce_
.flags = CE_ATTR_FLAGS,
.src_nentries = 0,
.src_sz_max = 2048,
+#ifndef CONFIG_ATH10K_SMALLBUFFERS
.dest_nentries = 128,
+#else
+ .dest_nentries = 96,
+#endif
.recv_cb = ath10k_pci_pktlog_rx_cb,
},

View File

@ -13,7 +13,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -3827,7 +3827,7 @@ struct ieee80211_txq *ieee80211_next_txq
@@ -3820,7 +3820,7 @@ struct ieee80211_txq *ieee80211_next_txq
{
struct ieee80211_local *local = hw_to_local(hw);
struct airtime_sched_info *air_sched;
@ -22,7 +22,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
struct ieee80211_txq *ret = NULL;
struct airtime_info *air_info;
struct txq_info *txqi = NULL;
@@ -3954,7 +3954,7 @@ void ieee80211_update_airtime_weight(str
@@ -3947,7 +3947,7 @@ void ieee80211_update_airtime_weight(str
u64 weight_sum = 0;
if (unlikely(!now))
@ -31,7 +31,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
lockdep_assert_held(&air_sched->lock);
@@ -3980,7 +3980,7 @@ void ieee80211_schedule_txq(struct ieee8
@@ -3973,7 +3973,7 @@ void ieee80211_schedule_txq(struct ieee8
struct ieee80211_local *local = hw_to_local(hw);
struct txq_info *txqi = to_txq_info(txq);
struct airtime_sched_info *air_sched;
@ -40,7 +40,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
struct airtime_info *air_info;
u8 ac = txq->ac;
bool was_active;
@@ -4038,7 +4038,7 @@ static void __ieee80211_unschedule_txq(s
@@ -4031,7 +4031,7 @@ static void __ieee80211_unschedule_txq(s
if (!purge)
airtime_set_active(air_sched, air_info,
@ -49,7 +49,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
rb_erase_cached(&txqi->schedule_order,
&air_sched->active_txqs);
@@ -4126,7 +4126,7 @@ bool ieee80211_txq_may_transmit(struct i
@@ -4119,7 +4119,7 @@ bool ieee80211_txq_may_transmit(struct i
if (RB_EMPTY_NODE(&txqi->schedule_order))
goto out;

View File

@ -12,8 +12,7 @@ PKG_VERSION:=1.10.1
PKG_RELEASE:=$(AUTORELEASE)
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=http://www.us.tcpdump.org/release/ \
http://www.tcpdump.org/release/
PKG_SOURCE_URL:=http://www.tcpdump.org/release/
PKG_HASH:=ed285f4accaf05344f90975757b3dbfe772ba41d1c401c2648b7fa45b711bdd4
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>

View File

@ -38,13 +38,20 @@ wps_catch_credentials() {
done
}
if [ "$ACTION" = "pressed" -a "$BUTTON" = "wps" ]; then
wps_done=0
ubusobjs="$( ubus -S list hostapd.* )"
for ubusobj in $ubusobjs; do
ubus -S call $ubusobj wps_start && wps_done=1
done
[ $wps_done = 0 ] || return 0
if [ "$ACTION" = "released" ] && [ "$BUTTON" = "wps" ]; then
# If the button was pressed for 3 seconds or more, trigger WPS on
# wpa_supplicant only, no matter if hostapd is running or not. If
# was pressed for less than 3 seconds, try triggering on
# hostapd. If there is no hostapd instance to trigger it on or WPS
# is not enabled on them, trigger it on wpa_supplicant.
if [ "$SEEN" -lt 3 ] ; then
wps_done=0
ubusobjs="$( ubus -S list hostapd.* )"
for ubusobj in $ubusobjs; do
ubus -S call $ubusobj wps_start && wps_done=1
done
[ $wps_done = 0 ] || return 0
fi
wps_done=0
ubusobjs="$( ubus -S list wpa_supplicant.* )"
for ubusobj in $ubusobjs; do

View File

@ -61,6 +61,9 @@ void hostapd_ubus_notify_bss_transition_response(
const u8 *candidate_list, u16 candidate_list_len);
void hostapd_ubus_add(struct hapd_interfaces *interfaces);
void hostapd_ubus_free(struct hapd_interfaces *interfaces);
int hostapd_ubus_notify_bss_transition_query(
struct hostapd_data *hapd, const u8 *addr, u8 dialog_token, u8 reason,
const u8 *candidate_list, u16 candidate_list_len);
#else
@ -125,6 +128,13 @@ static inline void hostapd_ubus_add(struct hapd_interfaces *interfaces)
static inline void hostapd_ubus_free(struct hapd_interfaces *interfaces)
{
}
static inline int hostapd_ubus_notify_bss_transition_query(
struct hostapd_data *hapd, const u8 *addr, u8 dialog_token, u8 reason,
const u8 *candidate_list, u16 candidate_list_len)
{
return 0;
}
#endif
#endif

View File

@ -12,8 +12,7 @@ PKG_VERSION:=4.9.3
PKG_RELEASE:=3
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=http://www.us.tcpdump.org/release/ \
http://www.tcpdump.org/release/
PKG_SOURCE_URL:=http://www.tcpdump.org/release/
PKG_HASH:=2cd47cb3d460b6ff75f4a9940f594317ad456cfbf2bd2c8e5151e16559db6410
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>

View File

@ -65,6 +65,8 @@ _proto_mbim_setup() {
echo "mbim[$$]" "Reading capabilities"
umbim $DBG -n -d $device caps || {
echo "mbim[$$]" "Failed to read modem caps"
tid=$((tid + 1))
umbim $DBG -t $tid -d "$device" disconnect
proto_notify_error "$interface" PIN_FAILED
return 1
}
@ -74,6 +76,8 @@ _proto_mbim_setup() {
echo "mbim[$$]" "Sending pin"
umbim $DBG -n -t $tid -d $device unlock "$pincode" || {
echo "mbim[$$]" "Unable to verify PIN"
tid=$((tid + 1))
umbim $DBG -t $tid -d "$device" disconnect
proto_notify_error "$interface" PIN_FAILED
proto_block_restart "$interface"
return 1
@ -82,8 +86,11 @@ _proto_mbim_setup() {
tid=$((tid + 1))
echo "mbim[$$]" "Checking pin"
umbim $DBG -n -t $tid -d $device pinstate || {
umbim $DBG -n -t $tid -d $device pinstate
[ $? -eq 2 ] && {
echo "mbim[$$]" "PIN required"
tid=$((tid + 1))
umbim $DBG -t $tid -d "$device" disconnect
proto_notify_error "$interface" PIN_FAILED
proto_block_restart "$interface"
return 1
@ -93,6 +100,8 @@ _proto_mbim_setup() {
echo "mbim[$$]" "Checking subscriber"
umbim $DBG -n -t $tid -d $device subscriber || {
echo "mbim[$$]" "Subscriber init failed"
tid=$((tid + 1))
umbim $DBG -t $tid -d "$device" disconnect
proto_notify_error "$interface" NO_SUBSCRIBER
return 1
}
@ -101,6 +110,8 @@ _proto_mbim_setup() {
echo "mbim[$$]" "Register with network"
umbim $DBG -n -t $tid -d $device registration || {
echo "mbim[$$]" "Subscriber registration failed"
tid=$((tid + 1))
umbim $DBG -t $tid -d "$device" disconnect
proto_notify_error "$interface" NO_REGISTRATION
return 1
}
@ -109,6 +120,8 @@ _proto_mbim_setup() {
echo "mbim[$$]" "Attach to network"
umbim $DBG -n -t $tid -d $device attach || {
echo "mbim[$$]" "Failed to attach to network"
tid=$((tid + 1))
umbim $DBG -t $tid -d "$device" disconnect
proto_notify_error "$interface" ATTACH_FAILED
return 1
}
@ -141,6 +154,7 @@ _proto_mbim_setup() {
json_add_string proto "dhcpv6"
json_add_string extendprefix 1
proto_add_dynamic_defaults
json_close_object
ubus call network add_dynamic "$(json_dump)"
}
@ -169,7 +183,7 @@ proto_mbim_teardown() {
echo "mbim[$$]" "Stopping network"
[ -n "$tid" ] && {
umbim $DBG -t$tid -d "$device" disconnect
umbim $DBG -t $tid -d "$device" disconnect
uci_revert_state network $interface tid
}

View File

@ -1,343 +0,0 @@
# CONFIG_40x is not set
CONFIG_44x=y
CONFIG_460EX=y
CONFIG_4xx=y
CONFIG_4xx_SOC=y
# CONFIG_ADVANCED_OPTIONS is not set
CONFIG_APM821xx=y
CONFIG_APOLLO3G=y
# CONFIG_ARCHES is not set
CONFIG_ARCH_32BIT_OFF_T=y
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y
CONFIG_ARCH_HAS_DMA_COHERENT_TO_PFN=y
CONFIG_ARCH_HAS_DMA_PREP_COHERENT=y
CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
CONFIG_ARCH_HAS_FORTIFY_SOURCE=y
CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
CONFIG_ARCH_HAS_KCOV=y
CONFIG_ARCH_HAS_MEMBARRIER_CALLBACKS=y
CONFIG_ARCH_HAS_PHYS_TO_DMA=y
CONFIG_ARCH_HAS_PMEM_API=y
CONFIG_ARCH_HAS_PTE_SPECIAL=y
CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y
CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU=y
CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE=y
CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE=y
CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_KEEP_MEMBLOCK=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y
CONFIG_ARCH_MMAP_RND_BITS=11
CONFIG_ARCH_MMAP_RND_BITS_MAX=17
CONFIG_ARCH_MMAP_RND_BITS_MIN=11
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=17
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11
CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
CONFIG_ARCH_SUPPORTS_UPROBES=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_ARCH_USE_BUILTIN_BSWAP=y
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
CONFIG_ARCH_WEAK_RELEASE_ACQUIRE=y
CONFIG_AUDIT_ARCH=y
# CONFIG_BAMBOO is not set
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_BLK_MQ_PCI=y
CONFIG_BLK_PM=y
CONFIG_BLUESTONE=y
CONFIG_BOOKE=y
CONFIG_BOOKE_WDT=y
# CONFIG_CANYONLANDS is not set
CONFIG_CC_HAS_KASAN_GENERIC=y
CONFIG_CLONE_BACKWARDS=y
CONFIG_CMDLINE="rootfstype=squashfs noinitrd"
CONFIG_CMDLINE_BOOL=y
CONFIG_COMPAT_32BIT_TIME=y
CONFIG_CPU_BIG_ENDIAN=y
CONFIG_CRC16=y
# CONFIG_CRC32_SARWATE is not set
CONFIG_CRC32_SLICEBY8=y
CONFIG_CRYPTO_ACOMP2=y
CONFIG_CRYPTO_AEAD=y
CONFIG_CRYPTO_AEAD2=y
CONFIG_CRYPTO_AUTHENC=y
CONFIG_CRYPTO_CCM=y
CONFIG_CRYPTO_CFB=y
CONFIG_CRYPTO_CTR=y
CONFIG_CRYPTO_DEFLATE=y
CONFIG_CRYPTO_DEV_PPC4XX=y
CONFIG_CRYPTO_DRBG=y
CONFIG_CRYPTO_DRBG_HMAC=y
CONFIG_CRYPTO_DRBG_MENU=y
CONFIG_CRYPTO_ECB=y
CONFIG_CRYPTO_ESSIV=y
CONFIG_CRYPTO_GCM=y
CONFIG_CRYPTO_GF128MUL=y
CONFIG_CRYPTO_GHASH=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_HW=y
CONFIG_CRYPTO_JITTERENTROPY=y
CONFIG_CRYPTO_LIB_SHA256=y
CONFIG_CRYPTO_LZO=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
CONFIG_CRYPTO_MD5_PPC=y
CONFIG_CRYPTO_NULL=y
CONFIG_CRYPTO_NULL2=y
CONFIG_CRYPTO_OFB=y
CONFIG_CRYPTO_RNG=y
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_RNG_DEFAULT=y
CONFIG_CRYPTO_SEQIV=y
CONFIG_CRYPTO_SHA1_PPC=y
CONFIG_CRYPTO_SHA256=y
CONFIG_DATA_SHIFT=12
CONFIG_DEBUG_MISC=y
CONFIG_DMA_DIRECT_REMAP=y
CONFIG_DMA_REMAP=y
CONFIG_DTC=y
# CONFIG_E200 is not set
CONFIG_EARLY_PRINTK=y
# CONFIG_EBONY is not set
CONFIG_EDAC_ATOMIC_SCRUB=y
CONFIG_EDAC_SUPPORT=y
# CONFIG_EIGER is not set
CONFIG_ETEXT_SHIFT=12
CONFIG_EXTRA_TARGETS="uImage"
CONFIG_FIXED_PHY=y
CONFIG_FORCE_PCI=y
CONFIG_FREEZER=y
# CONFIG_FSL_LBC is not set
CONFIG_FW_LOADER_PAGED_BUF=y
CONFIG_GCC_PLUGINS=y
# CONFIG_GCC_PLUGIN_CYC_COMPLEXITY is not set
# CONFIG_GCC_PLUGIN_LATENT_ENTROPY is not set
# CONFIG_GCC_PLUGIN_RANDSTRUCT is not set
# CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF is not set
# CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL is not set
# CONFIG_GCC_PLUGIN_STRUCTLEAK_USER is not set
CONFIG_GENERIC_ALLOCATOR=y
CONFIG_GENERIC_ATOMIC64=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CMOS_UPDATE=y
CONFIG_GENERIC_CPU=y
CONFIG_GENERIC_CPU_AUTOPROBE=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_GENERIC_MSI_IRQ=y
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_GENERIC_STRNCPY_FROM_USER=y
CONFIG_GENERIC_STRNLEN_USER=y
CONFIG_GENERIC_TIME_VSYSCALL=y
# CONFIG_GEN_RTC is not set
# CONFIG_GLACIER is not set
CONFIG_GPIOLIB=y
CONFIG_GPIO_GENERIC=y
CONFIG_GPIO_GENERIC_PLATFORM=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT_MAP=y
CONFIG_HAVE_ARCH_AUDITSYSCALL=y
CONFIG_HAVE_ARCH_JUMP_LABEL=y
CONFIG_HAVE_ARCH_KASAN=y
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_HAVE_ARCH_NVRAM_OPS=y
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_ASM_MODVERSIONS=y
CONFIG_HAVE_CBPF_JIT=y
CONFIG_HAVE_COPY_THREAD_TLS=y
CONFIG_HAVE_C_RECORDMCOUNT=y
CONFIG_HAVE_DEBUG_KMEMLEAK=y
CONFIG_HAVE_DEBUG_STACKOVERFLOW=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_FAST_GUP=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_FUNCTION_ERROR_INJECTION=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_IDE=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y
CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
CONFIG_HAVE_KPROBES_ON_FTRACE=y
CONFIG_HAVE_LD_DEAD_CODE_DATA_ELIMINATION=y
CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
CONFIG_HAVE_MMU_GATHER_PAGE_SIZE=y
CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
CONFIG_HAVE_NET_DSA=y
CONFIG_HAVE_OPROFILE=y
CONFIG_HAVE_PCI=y
CONFIG_HAVE_PERF_EVENTS=y
CONFIG_HAVE_PERF_REGS=y
CONFIG_HAVE_PERF_USER_STACK_DUMP=y
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
CONFIG_HAVE_RSEQ=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_HAVE_VIRT_CPU_ACCOUNTING=y
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_PPC4XX=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_IBM_IIC=y
CONFIG_IBM_EMAC=y
CONFIG_IBM_EMAC_EMAC4=y
CONFIG_IBM_EMAC_POLL_WEIGHT=32
CONFIG_IBM_EMAC_RGMII=y
CONFIG_IBM_EMAC_RXB=128
CONFIG_IBM_EMAC_RX_COPY_THRESHOLD=256
CONFIG_IBM_EMAC_TAH=y
CONFIG_IBM_EMAC_TXB=128
# CONFIG_ICON is not set
CONFIG_ILLEGAL_POINTER_VALUE=0
CONFIG_IRQCHIP=y
CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_IRQ_WORK=y
CONFIG_ISA_DMA_API=y
# CONFIG_JFFS2_FS is not set
# CONFIG_KATMAI is not set
CONFIG_KERNEL_START=0xc0000000
CONFIG_LEDS_TRIGGER_MTD=y
CONFIG_LEDS_TRIGGER_PATTERN=y
CONFIG_LIBFDT=y
CONFIG_LOCK_DEBUGGING_SUPPORT=y
CONFIG_LOWMEM_SIZE=0x30000000
CONFIG_LZO_COMPRESS=y
CONFIG_LZO_DECOMPRESS=y
# CONFIG_MATH_EMULATION is not set
CONFIG_MDIO_BUS=y
CONFIG_MDIO_DEVICE=y
CONFIG_MEMFD_CREATE=y
CONFIG_MIGRATION=y
CONFIG_MODULES_USE_ELF_RELA=y
CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS=y
CONFIG_MTD_CFI_ADV_OPTIONS=y
# CONFIG_MTD_CFI_GEOMETRY is not set
# CONFIG_MTD_SPLIT_SQUASHFS_ROOT is not set
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_NEED_PER_CPU_KM=y
CONFIG_NEED_SG_DMA_LENGTH=y
CONFIG_NOT_COHERENT_CACHE=y
CONFIG_NO_HZ=y
CONFIG_NO_HZ_COMMON=y
CONFIG_NO_HZ_IDLE=y
CONFIG_NR_IRQS=512
CONFIG_NVMEM=y
CONFIG_NVMEM_SYSFS=y
CONFIG_OF=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_EARLY_FLATTREE=y
CONFIG_OF_FLATTREE=y
CONFIG_OF_GPIO=y
CONFIG_OF_IRQ=y
CONFIG_OF_KOBJ=y
CONFIG_OF_MDIO=y
CONFIG_OF_NET=y
CONFIG_OLD_SIGACTION=y
CONFIG_OLD_SIGSUSPEND=y
# CONFIG_OVERLAY_FS_XINO_AUTO is not set
CONFIG_PACKING=y
CONFIG_PAGE_OFFSET=0xc0000000
CONFIG_PCI=y
CONFIG_PCIEAER=y
CONFIG_PCIEPORTBUS=y
CONFIG_PCIE_PME=y
CONFIG_PCI_DISABLE_COMMON_QUIRKS=y
CONFIG_PCI_DOMAINS=y
CONFIG_PCI_MSI=y
CONFIG_PGTABLE_LEVELS=2
CONFIG_PHYLIB=y
CONFIG_PHYSICAL_START=0x00000000
CONFIG_PHYS_64BIT=y
CONFIG_PHYS_ADDR_T_64BIT=y
CONFIG_PM=y
CONFIG_PM_AUTOSLEEP=y
CONFIG_PM_SLEEP=y
CONFIG_PM_WAKELOCKS=y
CONFIG_PM_WAKELOCKS_GC=y
CONFIG_PM_WAKELOCKS_LIMIT=100
CONFIG_PPC=y
CONFIG_PPC32=y
CONFIG_PPC44x_SIMPLE=y
CONFIG_PPC4xx_CPM=y
CONFIG_PPC4xx_GPIO=y
CONFIG_PPC4xx_MSI=y
CONFIG_PPC4xx_PCI_EXPRESS=y
# CONFIG_PPC64 is not set
# CONFIG_PPC_47x is not set
# CONFIG_PPC_85xx is not set
# CONFIG_PPC_8xx is not set
CONFIG_PPC_ADV_DEBUG_DACS=2
CONFIG_PPC_ADV_DEBUG_DAC_RANGE=y
CONFIG_PPC_ADV_DEBUG_DVCS=2
CONFIG_PPC_ADV_DEBUG_IACS=4
CONFIG_PPC_ADV_DEBUG_REGS=y
# CONFIG_PPC_BOOK3S_601 is not set
# CONFIG_PPC_BOOK3S_6xx is not set
CONFIG_PPC_DCR=y
CONFIG_PPC_DCR_NATIVE=y
# CONFIG_PPC_EARLY_DEBUG is not set
CONFIG_PPC_FPU=y
CONFIG_PPC_INDIRECT_PCI=y
# CONFIG_PPC_IRQ_SOFT_MASK_DEBUG is not set
CONFIG_PPC_MMU_NOHASH=y
CONFIG_PPC_MMU_NOHASH_32=y
CONFIG_PPC_MSI_BITMAP=y
CONFIG_PPC_PAGE_SHIFT=12
# CONFIG_PPC_PTDUMP is not set
CONFIG_PPC_UDBG_16550=y
CONFIG_PPC_WERROR=y
CONFIG_PTE_64BIT=y
# CONFIG_RAINIER is not set
CONFIG_RAS=y
CONFIG_REGULATOR=y
CONFIG_RSEQ=y
# CONFIG_SAM440EP is not set
# CONFIG_SCOM_DEBUGFS is not set
# CONFIG_SEQUOIA is not set
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_FSL=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_MCTRL_GPIO=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SGL_ALLOC=y
CONFIG_SIMPLE_GPIO=y
CONFIG_SPARSE_IRQ=y
CONFIG_SRCU=y
CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y
CONFIG_SWPHY=y
CONFIG_SYSCTL_EXCEPTION_TRACE=y
# CONFIG_TAISHAN is not set
CONFIG_TASK_SIZE=0xc0000000
CONFIG_THREAD_INFO_IN_TASK=y
CONFIG_THREAD_SHIFT=13
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TINY_SRCU=y
CONFIG_USB_SUPPORT=y
CONFIG_VDSO32=y
# CONFIG_VIRTIO_MENU is not set
# CONFIG_VIRT_CPU_ACCOUNTING_NATIVE is not set
# CONFIG_WARP is not set
CONFIG_WATCHDOG_CORE=y
# CONFIG_XILINX_SYSACE is not set
# CONFIG_XILINX_VIRTEX440_GENERIC_BOARD is not set
CONFIG_XZ_DEC_BCJ=y
CONFIG_XZ_DEC_POWERPC=y
# CONFIG_YOSEMITE is not set
CONFIG_ZLIB_DEFLATE=y
CONFIG_ZLIB_INFLATE=y

View File

@ -421,31 +421,6 @@
#size-cells = <0>;
};
MSI: ppc4xx-msi@c10000000 {
compatible = "amcc,ppc4xx-msi", "ppc4xx-msi";
reg = <0xc 0x10000000 0x100
0xc 0x10000000 0x100>;
sdr-base = <0x36C>;
msi-data = <0x00004440>;
msi-mask = <0x0000ffe0>;
interrupts =<0 1 2 3 4 5 6 7>;
interrupt-parent = <&MSI>;
#interrupt-cells = <1>;
#address-cells = <0>;
#size-cells = <0>;
msi-available-ranges = <0x0 0x100>;
interrupt-map =
<0 &UIC3 0x18 IRQ_TYPE_EDGE_RISING>,
<1 &UIC3 0x19 IRQ_TYPE_EDGE_RISING>,
<2 &UIC3 0x1a IRQ_TYPE_EDGE_RISING>,
<3 &UIC3 0x1b IRQ_TYPE_EDGE_RISING>,
<4 &UIC3 0x1c IRQ_TYPE_EDGE_RISING>,
<5 &UIC3 0x1d IRQ_TYPE_EDGE_RISING>,
<6 &UIC3 0x1e IRQ_TYPE_EDGE_RISING>,
<7 &UIC3 0x1f IRQ_TYPE_EDGE_RISING>;
status = "disabled";
};
PCIE0: pciex@d00000000 {
device_type = "pci"; /* see ppc4xx_pci_find_bridge */
#interrupt-cells = <1>;

View File

@ -244,7 +244,3 @@
};
};
};
&MSI {
status = "okay";
};

View File

@ -205,7 +205,3 @@
};
};
};
&MSI {
status = "okay";
};

View File

@ -207,10 +207,6 @@
status = "okay";
};
&MSI {
status = "okay";
};
&IIC0 {
status = "okay";

View File

@ -177,24 +177,13 @@
nand {
nand-is-boot-medium;
partition0,0@0 {
label = "NAND 128MiB 3,3V 8-bit";
reg = <0x00000000 0x08000000>;
read-only;
};
partition0,1@0 {
partition@0 {
label = "uboot";
reg = <0x00000000 0x00180000>;
read-only;
};
partition0,2@180000 {
label = "device-tree";
reg = <0x00180000 0x00020000>;
};
partition0,3@180000 {
partition@180000 {
label = "kernel";
reg = <0x00180000 0x00380000>;
/*
@ -208,52 +197,54 @@
*/
};
partition0,4@500000 {
partition@500000 {
label = "ubi";
reg = <0x00500000 0x014e0000>;
};
partition0,5@19e0000 {
/*
* Netgear's u-boot in the fw_recovery mode (can be
* triggered by holding the reset button, or if
* "bootm" fails) will not flash past this point
* (= 0x19E0000).
*/
partition@19e0000 {
label = "config";
reg = <0x019e0000 0x00080000>;
read-only;
};
partition0,6@1a60000 {
partition@1a60000 {
label = "pot";
reg = <0x01a60000 0x00080000>;
read-only;
};
partition0,7@1ae0000 {
partition@1ae0000 {
label = "traffic_meter";
reg = <0x01ae0000 0x00300000>;
read-only;
};
partition0,8@1de0000 {
partition@1de0000 {
label = "language";
reg = <0x01de0000 0x001c0000>;
read-only;
};
partition0,9@1fa0000 {
partition@1fa0000 {
label = "ecos";
reg = <0x01fa0000 0x06020000>;
read-only;
};
partition0,10@7fc0000 {
partition@7fc0000 {
label = "wifi_data";
reg = <0x07fc0000 0x00040000>;
read-only;
};
partition0,11@180000 {
label = "firmware";
reg = <0x00180000 0x01860000>;
read-only;
};
};
};
};
@ -523,7 +514,3 @@
};
};
};
&MSI {
status = "okay";
};

View File

@ -123,9 +123,11 @@
usbpwr: usb-regulator {
compatible = "regulator-fixed";
regulator-name = "Power USB Core";
gpios = <&GPIO1 2 GPIO_ACTIVE_LOW>;
gpios = <&GPIO1 2 GPIO_ACTIVE_HIGH>;
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
regulator-boot-on; /* uboot sets this */
enable-active-high;
};
sata1pwr: sata1-regulator {

View File

@ -0,0 +1,29 @@
From 88ca61467a0897c79b1fbf8f5c30691b43b52613 Mon Sep 17 00:00:00 2001
From: Christian Lamparter <chunkeey@gmail.com>
Date: Sun, 26 Dec 2021 22:36:29 +0200
Subject: [PATCH] dwc2: temporary force to be powered up all times
the APM821xx's onchip dwc2 misbehaves with 5.4 and 5.10
when a USB device gets connected. Instead of announcing
and setting up the USB devices it crashes and burns with:
[ 22.023476] dwc2 4bff80000.usbotg: dwc2_restore_global_registers: no global registers to restore
[ 22.032245] dwc2 4bff80000.usbotg: dwc2_exit_partial_power_down: failed to restore registers
[ 22.040647] dwc2 4bff80000.usbotg: exit partial_power_down failed
[ 22.058765] dwc2 4bff80000.usbotg: HC died; cleaning up
This is all seemingly fixed with dwc2 from a 5.16-rc6.
Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
---
--- a/drivers/usb/dwc2/params.c
+++ b/drivers/usb/dwc2/params.c
@@ -137,6 +137,7 @@ static void dwc2_set_amcc_params(struct
struct dwc2_core_params *p = &hsotg->params;
p->ahbcfg = GAHBCFG_HBSTLEN_INCR16 << GAHBCFG_HBSTLEN_SHIFT;
+ p->power_down = DWC2_POWER_DOWN_PARAM_NONE;
}
static void dwc2_set_stm32f4x9_fsotg_params(struct dwc2_hsotg *hsotg)

View File

@ -13,7 +13,7 @@ produce a noisy warning.
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -274,6 +274,7 @@ static void xhci_pci_quirks(struct devic
@@ -276,6 +276,7 @@ static void xhci_pci_quirks(struct devic
pdev->device == 0x0015) {
xhci->quirks |= XHCI_RESET_ON_RESUME;
xhci->quirks |= XHCI_ZERO_64B_REGS;

View File

@ -1,99 +0,0 @@
From 3913dbe4b3256ead342572f7aba726a60ab5fd43 Mon Sep 17 00:00:00 2001
Message-Id: <3913dbe4b3256ead342572f7aba726a60ab5fd43.1577917078.git.chunkeey@gmail.com>
From: Christian Lamparter <chunkeey@gmail.com>
Date: Wed, 1 Jan 2020 22:28:28 +0100
Subject: [PATCH 1/2] crypto: crypto4xx - reduce memory fragmentation
To: linux-crypto@vger.kernel.org
Cc: Herbert Xu <herbert@gondor.apana.org.au>
With recent kernels (>5.2), the driver fails to probe, as the
allocation of the driver's scatter buffer fails with -ENOMEM.
This happens in crypto4xx_build_sdr(). Where the driver tries
to get 512KiB (=PPC4XX_SD_BUFFER_SIZE * PPC4XX_NUM_SD) of
continuous memory. This big chunk is by design, since the driver
uses this circumstance in the crypto4xx_copy_pkt_to_dst() to
its advantage:
"all scatter-buffers are all neatly organized in one big
continuous ringbuffer; So scatterwalk_map_and_copy() can be
instructed to copy a range of buffers in one go."
The PowerPC arch does not have support for DMA_CMA. Hence,
this patch reorganizes the order in which the memory
allocations are done. Since the driver itself is responsible
for some of the issues.
Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
---
drivers/crypto/amcc/crypto4xx_core.c | 27 +++++++++++++--------------
1 file changed, 13 insertions(+), 14 deletions(-)
--- a/drivers/crypto/amcc/crypto4xx_core.c
+++ b/drivers/crypto/amcc/crypto4xx_core.c
@@ -286,7 +286,8 @@ static u32 crypto4xx_build_gdr(struct cr
static inline void crypto4xx_destroy_gdr(struct crypto4xx_device *dev)
{
- dma_free_coherent(dev->core_dev->device,
+ if (dev->gdr)
+ dma_free_coherent(dev->core_dev->device,
sizeof(struct ce_gd) * PPC4XX_NUM_GD,
dev->gdr, dev->gdr_pa);
}
@@ -354,13 +355,6 @@ static u32 crypto4xx_build_sdr(struct cr
{
int i;
- /* alloc memory for scatter descriptor ring */
- dev->sdr = dma_alloc_coherent(dev->core_dev->device,
- sizeof(struct ce_sd) * PPC4XX_NUM_SD,
- &dev->sdr_pa, GFP_ATOMIC);
- if (!dev->sdr)
- return -ENOMEM;
-
dev->scatter_buffer_va =
dma_alloc_coherent(dev->core_dev->device,
PPC4XX_SD_BUFFER_SIZE * PPC4XX_NUM_SD,
@@ -368,6 +362,13 @@ static u32 crypto4xx_build_sdr(struct cr
if (!dev->scatter_buffer_va)
return -ENOMEM;
+ /* alloc memory for scatter descriptor ring */
+ dev->sdr = dma_alloc_coherent(dev->core_dev->device,
+ sizeof(struct ce_sd) * PPC4XX_NUM_SD,
+ &dev->sdr_pa, GFP_ATOMIC);
+ if (!dev->sdr)
+ return -ENOMEM;
+
for (i = 0; i < PPC4XX_NUM_SD; i++) {
dev->sdr[i].ptr = dev->scatter_buffer_pa +
PPC4XX_SD_BUFFER_SIZE * i;
@@ -1439,16 +1440,15 @@ static int crypto4xx_probe(struct platfo
spin_lock_init(&core_dev->lock);
INIT_LIST_HEAD(&core_dev->dev->alg_list);
ratelimit_default_init(&core_dev->dev->aead_ratelimit);
+ rc = crypto4xx_build_sdr(core_dev->dev);
+ if (rc)
+ goto err_build_sdr;
rc = crypto4xx_build_pdr(core_dev->dev);
if (rc)
- goto err_build_pdr;
+ goto err_build_sdr;
rc = crypto4xx_build_gdr(core_dev->dev);
if (rc)
- goto err_build_pdr;
-
- rc = crypto4xx_build_sdr(core_dev->dev);
- if (rc)
goto err_build_sdr;
/* Init tasklet for bottom half processing */
@@ -1493,7 +1493,6 @@ err_iomap:
err_build_sdr:
crypto4xx_destroy_sdr(core_dev->dev);
crypto4xx_destroy_gdr(core_dev->dev);
-err_build_pdr:
crypto4xx_destroy_pdr(core_dev->dev);
kfree(core_dev->dev);
err_alloc_dev:

View File

@ -1,72 +0,0 @@
From 5bacaaea8a228bc46f402595b1694ef9128f3599 Mon Sep 17 00:00:00 2001
Message-Id: <5bacaaea8a228bc46f402595b1694ef9128f3599.1577917078.git.chunkeey@gmail.com>
In-Reply-To: <3913dbe4b3256ead342572f7aba726a60ab5fd43.1577917078.git.chunkeey@gmail.com>
References: <3913dbe4b3256ead342572f7aba726a60ab5fd43.1577917078.git.chunkeey@gmail.com>
From: Christian Lamparter <chunkeey@gmail.com>
Date: Wed, 1 Jan 2020 22:54:54 +0100
Subject: [PATCH 2/2] crypto: crypto4xx - use GFP_KERNEL for big allocations
To: linux-crypto@vger.kernel.org
Cc: Herbert Xu <herbert@gondor.apana.org.au>
The driver should use GFP_KERNEL for the bigger allocation
during the driver's crypto4xx_probe() and not GFP_ATOMIC in
my opinion.
Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
---
drivers/crypto/amcc/crypto4xx_core.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
--- a/drivers/crypto/amcc/crypto4xx_core.c
+++ b/drivers/crypto/amcc/crypto4xx_core.c
@@ -169,7 +169,7 @@ static u32 crypto4xx_build_pdr(struct cr
int i;
dev->pdr = dma_alloc_coherent(dev->core_dev->device,
sizeof(struct ce_pd) * PPC4XX_NUM_PD,
- &dev->pdr_pa, GFP_ATOMIC);
+ &dev->pdr_pa, GFP_KERNEL);
if (!dev->pdr)
return -ENOMEM;
@@ -185,13 +185,13 @@ static u32 crypto4xx_build_pdr(struct cr
dev->shadow_sa_pool = dma_alloc_coherent(dev->core_dev->device,
sizeof(union shadow_sa_buf) * PPC4XX_NUM_PD,
&dev->shadow_sa_pool_pa,
- GFP_ATOMIC);
+ GFP_KERNEL);
if (!dev->shadow_sa_pool)
return -ENOMEM;
dev->shadow_sr_pool = dma_alloc_coherent(dev->core_dev->device,
sizeof(struct sa_state_record) * PPC4XX_NUM_PD,
- &dev->shadow_sr_pool_pa, GFP_ATOMIC);
+ &dev->shadow_sr_pool_pa, GFP_KERNEL);
if (!dev->shadow_sr_pool)
return -ENOMEM;
for (i = 0; i < PPC4XX_NUM_PD; i++) {
@@ -277,7 +277,7 @@ static u32 crypto4xx_build_gdr(struct cr
{
dev->gdr = dma_alloc_coherent(dev->core_dev->device,
sizeof(struct ce_gd) * PPC4XX_NUM_GD,
- &dev->gdr_pa, GFP_ATOMIC);
+ &dev->gdr_pa, GFP_KERNEL);
if (!dev->gdr)
return -ENOMEM;
@@ -358,14 +358,14 @@ static u32 crypto4xx_build_sdr(struct cr
dev->scatter_buffer_va =
dma_alloc_coherent(dev->core_dev->device,
PPC4XX_SD_BUFFER_SIZE * PPC4XX_NUM_SD,
- &dev->scatter_buffer_pa, GFP_ATOMIC);
+ &dev->scatter_buffer_pa, GFP_KERNEL);
if (!dev->scatter_buffer_va)
return -ENOMEM;
/* alloc memory for scatter descriptor ring */
dev->sdr = dma_alloc_coherent(dev->core_dev->device,
sizeof(struct ce_sd) * PPC4XX_NUM_SD,
- &dev->sdr_pa, GFP_ATOMIC);
+ &dev->sdr_pa, GFP_KERNEL);
if (!dev->sdr)
return -ENOMEM;

View File

@ -1,30 +0,0 @@
--- a/arch/powerpc/platforms/44x/Kconfig
+++ b/arch/powerpc/platforms/44x/Kconfig
@@ -121,6 +121,17 @@ config CANYONLANDS
help
This option enables support for the AMCC PPC460EX evaluation board.
+config APOLLO3G
+ bool "Apollo3G"
+ depends on 44x
+ default n
+ select PPC44x_SIMPLE
+ select APM821xx
+ select IBM_EMAC_RGMII
+ select 460EX
+ help
+ This option enables support for the AMCC Apollo 3G board.
+
config GLACIER
bool "Glacier"
depends on 44x
--- a/arch/powerpc/platforms/44x/ppc44x_simple.c
+++ b/arch/powerpc/platforms/44x/ppc44x_simple.c
@@ -47,6 +47,7 @@ machine_device_initcall(ppc44x_simple, p
* board.c file for it rather than adding it to this list.
*/
static char *board[] __initdata = {
+ "amcc,apollo3g",
"amcc,arches",
"amcc,bamboo",
"apm,bluestone",

View File

@ -1,51 +0,0 @@
--- a/arch/powerpc/platforms/4xx/pci.c
+++ b/arch/powerpc/platforms/4xx/pci.c
@@ -1060,15 +1060,24 @@ static int __init apm821xx_pciex_init_po
u32 val;
/*
- * Do a software reset on PCIe ports.
- * This code is to fix the issue that pci drivers doesn't re-assign
- * bus number for PCIE devices after Uboot
- * scanned and configured all the buses (eg. PCIE NIC IntelPro/1000
- * PT quad port, SAS LSI 1064E)
+ * Only reset the PHY when no link is currently established.
+ * This is for the Atheros PCIe board which has problems to establish
+ * the link (again) after this PHY reset. All other currently tested
+ * PCIe boards don't show this problem.
*/
-
- mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x0);
- mdelay(10);
+ val = mfdcri(SDR0, port->sdr_base + PESDRn_LOOP);
+ if (!(val & 0x00001000)) {
+ /*
+ * Do a software reset on PCIe ports.
+ * This code is to fix the issue that pci drivers doesn't re-assign
+ * bus number for PCIE devices after Uboot
+ * scanned and configured all the buses (eg. PCIE NIC IntelPro/1000
+ * PT quad port, SAS LSI 1064E)
+ */
+
+ mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x0);
+ mdelay(10);
+ }
if (port->endpoint)
val = PTYPE_LEGACY_ENDPOINT << 20;
@@ -1085,9 +1094,12 @@ static int __init apm821xx_pciex_init_po
mtdcri(SDR0, PESDR0_460EX_L0DRV, 0x00000130);
mtdcri(SDR0, PESDR0_460EX_L0CLK, 0x00000006);
- mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x10000000);
- mdelay(50);
- mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x30000000);
+ val = mfdcri(SDR0, port->sdr_base + PESDRn_LOOP);
+ if (!(val & 0x00001000)) {
+ mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x10000000);
+ mdelay(50);
+ mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x30000000);
+ }
mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET,
mfdcri(SDR0, port->sdr_base + PESDRn_RCSSET) |

View File

@ -1,14 +0,0 @@
--- a/arch/powerpc/platforms/4xx/pci.c
+++ b/arch/powerpc/platforms/4xx/pci.c
@@ -1902,9 +1902,9 @@ static void __init ppc4xx_configure_pcie
* if it works
*/
out_le32(mbase + PECFG_PIM0LAL, 0x00000000);
- out_le32(mbase + PECFG_PIM0LAH, 0x00000000);
+ out_le32(mbase + PECFG_PIM0LAH, 0x00000008);
out_le32(mbase + PECFG_PIM1LAL, 0x00000000);
- out_le32(mbase + PECFG_PIM1LAH, 0x00000000);
+ out_le32(mbase + PECFG_PIM1LAH, 0x0000000c);
out_le32(mbase + PECFG_PIM01SAH, 0xffff0000);
out_le32(mbase + PECFG_PIM01SAL, 0x00000000);

View File

@ -1,53 +0,0 @@
From a0dc613140bab907a3d5787a7ae7b0638bf674d0 Mon Sep 17 00:00:00 2001
From: Christian Lamparter <chunkeey@gmail.com>
Date: Thu, 23 Jun 2016 20:28:20 +0200
Subject: [PATCH] usb: xhci: force MSI for uPD720201 and
uPD720202
The APM82181 does not support MSI-X. When probed, it will
produce a noisy warning.
---
drivers/usb/host/pci-quirks.c | 362 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 362 insertions(+)
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -297,6 +297,7 @@ static void xhci_pci_quirks(struct devic
pdev->device == 0x0015) {
xhci->quirks |= XHCI_RESET_ON_RESUME;
xhci->quirks |= XHCI_ZERO_64B_REGS;
+ xhci->quirks |= XHCI_FORCE_MSI;
}
if (pdev->vendor == PCI_VENDOR_ID_VIA)
xhci->quirks |= XHCI_RESET_ON_RESUME;
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -427,10 +427,14 @@ static int xhci_try_enable_msi(struct us
free_irq(hcd->irq, hcd);
hcd->irq = 0;
- ret = xhci_setup_msix(xhci);
- if (ret)
- /* fall back to msi*/
+ if (xhci->quirks & XHCI_FORCE_MSI) {
ret = xhci_setup_msi(xhci);
+ } else {
+ ret = xhci_setup_msix(xhci);
+ if (ret)
+ /* fall back to msi*/
+ ret = xhci_setup_msi(xhci);
+ }
if (!ret) {
hcd->msi_enabled = 1;
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1887,6 +1887,7 @@ struct xhci_hcd {
struct xhci_hub usb2_rhub;
struct xhci_hub usb3_rhub;
/* support xHCI 1.0 spec USB2 hardware LPM */
+#define XHCI_FORCE_MSI (1 << 24)
unsigned hw_lpm_support:1;
/* Broken Suspend flag for SNPS Suspend resume issue */
unsigned broken_suspend:1;

View File

@ -1,65 +0,0 @@
From 694f9bfb8efaef8a33e8992015ff9d0866faf4a2 Mon Sep 17 00:00:00 2001
From: Christian Lamparter <chunkeey@gmail.com>
Date: Sun, 17 Dec 2017 17:27:15 +0100
Subject: [PATCH 1/2] hwmon: tc654 add detection routine
This patch adds a detection routine for the TC654/TC655
chips. Both IDs are listed in the Datasheet.
Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
---
drivers/hwmon/tc654.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
--- a/drivers/hwmon/tc654.c
+++ b/drivers/hwmon/tc654.c
@@ -55,6 +55,11 @@ enum tc654_regs {
/* Register data is read (and cached) at most once per second. */
#define TC654_UPDATE_INTERVAL HZ
+/* Manufacturer and Version Identification Register Values */
+#define TC654_MFR_ID_MICROCHIP 0x84
+#define TC654_VER_ID 0x00
+#define TC655_VER_ID 0x01
+
struct tc654_data {
struct i2c_client *client;
@@ -482,6 +487,29 @@ static const struct i2c_device_id tc654_
{}
};
+static int
+tc654_detect(struct i2c_client *new_client, struct i2c_board_info *info)
+{
+ struct i2c_adapter *adapter = new_client->adapter;
+ int manufacturer, product;
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -ENODEV;
+
+ manufacturer = i2c_smbus_read_byte_data(new_client, TC654_REG_MFR_ID);
+ if (manufacturer != TC654_MFR_ID_MICROCHIP)
+ return -ENODEV;
+
+ product = i2c_smbus_read_byte_data(new_client, TC654_REG_VER_ID);
+ if (!((product == TC654_VER_ID) || (product == TC655_VER_ID)))
+ return -ENODEV;
+
+ strlcpy(info->type, product == TC654_VER_ID ? "tc654" : "tc655",
+ I2C_NAME_SIZE);
+ return 0;
+}
+
+
MODULE_DEVICE_TABLE(i2c, tc654_id);
static struct i2c_driver tc654_driver = {
@@ -490,6 +518,7 @@ static struct i2c_driver tc654_driver =
},
.probe = tc654_probe,
.id_table = tc654_id,
+ .detect = tc654_detect,
};
module_i2c_driver(tc654_driver);

View File

@ -1,174 +0,0 @@
From 9cb27801b5cbad2e1aaf45aac428cb2fac5e1372 Mon Sep 17 00:00:00 2001
From: Christian Lamparter <chunkeey@gmail.com>
Date: Sun, 17 Dec 2017 17:29:13 +0100
Subject: [PATCH] hwmon: tc654: add thermal_cooling device
This patch adds a thermaL_cooling device to the tc654 driver.
This allows the chip to be used for DT-based cooling.
Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
---
drivers/hwmon/tc654.c | 103 +++++++++++++++++++++++++++++++++++-------
1 file changed, 86 insertions(+), 17 deletions(-)
--- a/drivers/hwmon/tc654.c
+++ b/drivers/hwmon/tc654.c
@@ -15,6 +15,7 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/slab.h>
+#include <linux/thermal.h>
#include <linux/util_macros.h>
enum tc654_regs {
@@ -132,6 +133,9 @@ struct tc654_data {
* writable register used to control the duty
* cycle of the V OUT output.
*/
+
+ /* optional cooling device */
+ struct thermal_cooling_device *cdev;
};
/* helper to grab and cache data, at most one time per second */
@@ -367,36 +371,30 @@ static ssize_t pwm_mode_store(struct dev
static const int tc654_pwm_map[16] = { 77, 88, 102, 112, 124, 136, 148, 160,
172, 184, 196, 207, 219, 231, 243, 255};
+static int get_pwm(struct tc654_data *data)
+{
+ if (data->config & TC654_REG_CONFIG_SDM)
+ return 0;
+ else
+ return tc654_pwm_map[data->duty_cycle];
+}
+
static ssize_t pwm_show(struct device *dev, struct device_attribute *da,
char *buf)
{
struct tc654_data *data = tc654_update_client(dev);
- int pwm;
if (IS_ERR(data))
return PTR_ERR(data);
- if (data->config & TC654_REG_CONFIG_SDM)
- pwm = 0;
- else
- pwm = tc654_pwm_map[data->duty_cycle];
-
- return sprintf(buf, "%d\n", pwm);
+ return sprintf(buf, "%d\n", get_pwm(data));
}
-static ssize_t pwm_store(struct device *dev, struct device_attribute *da,
- const char *buf, size_t count)
+static int _set_pwm(struct tc654_data *data, unsigned long val)
{
- struct tc654_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
- unsigned long val;
int ret;
- if (kstrtoul(buf, 10, &val))
- return -EINVAL;
- if (val > 255)
- return -EINVAL;
-
mutex_lock(&data->update_lock);
if (val == 0)
@@ -416,6 +414,22 @@ static ssize_t pwm_store(struct device *
out:
mutex_unlock(&data->update_lock);
+ return ret;
+}
+
+static ssize_t pwm_store(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct tc654_data *data = dev_get_drvdata(dev);
+ unsigned long val;
+ int ret;
+
+ if (kstrtoul(buf, 10, &val))
+ return -EINVAL;
+ if (val > 255)
+ return -EINVAL;
+
+ ret = _set_pwm(data, val);
return ret < 0 ? ret : count;
}
@@ -447,6 +461,47 @@ static struct attribute *tc654_attrs[] =
ATTRIBUTE_GROUPS(tc654);
+/* cooling device */
+
+static int tc654_get_max_state(struct thermal_cooling_device *cdev,
+ unsigned long *state)
+{
+ *state = 255;
+ return 0;
+}
+
+static int tc654_get_cur_state(struct thermal_cooling_device *cdev,
+ unsigned long *state)
+{
+ struct tc654_data *data = tc654_update_client(cdev->devdata);
+
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
+ *state = get_pwm(data);
+ return 0;
+}
+
+static int tc654_set_cur_state(struct thermal_cooling_device *cdev,
+ unsigned long state)
+{
+ struct tc654_data *data = tc654_update_client(cdev->devdata);
+
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
+ if (state > 255)
+ return -EINVAL;
+
+ return _set_pwm(data, state);
+}
+
+static const struct thermal_cooling_device_ops tc654_fan_cool_ops = {
+ .get_max_state = tc654_get_max_state,
+ .get_cur_state = tc654_get_cur_state,
+ .set_cur_state = tc654_set_cur_state,
+};
+
/*
* device probe and removal
*/
@@ -478,7 +533,21 @@ static int tc654_probe(struct i2c_client
hwmon_dev =
devm_hwmon_device_register_with_groups(dev, client->name, data,
tc654_groups);
- return PTR_ERR_OR_ZERO(hwmon_dev);
+ if (IS_ERR(hwmon_dev))
+ return PTR_ERR(hwmon_dev);
+
+#if IS_ENABLED(CONFIG_OF)
+ /* Optional cooling device register for Device tree platforms */
+ data->cdev = thermal_of_cooling_device_register(client->dev.of_node,
+ "tc654", hwmon_dev,
+ &tc654_fan_cool_ops);
+#else /* CONFIG_OF */
+ /* Optional cooling device register for non Device tree platforms */
+ data->cdev = thermal_cooling_device_register("tc654", hwmon_dev,
+ &tc654_fan_cool_ops);
+#endif /* CONFIG_OF */
+
+ return PTR_ERR_OR_ZERO(data->cdev);
}
static const struct i2c_device_id tc654_id[] = {

View File

@ -1,29 +0,0 @@
From c9395ad54e2cabb87d408becc37566f3d8248933 Mon Sep 17 00:00:00 2001
From: Christian Lamparter <chunkeey@gmail.com>
Date: Sun, 1 Dec 2019 02:08:23 +0100
Subject: [PATCH] powerpc: bootwrapper: force gzip as mkimage's compression
method
Due to CONFIG_KERNEL_XZ symbol, the bootwrapper code tries to
instruct the mkimage to use the xz compression, which isn't
supported. This patch forces the gzip compression, which is
supported and doesn't matter because the generated uImage for
the apm821xx target gets ignored as the OpenWrt toolchain will
do separate U-Boot kernel images for each device individually.
Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
---
arch/powerpc/boot/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -254,7 +254,7 @@ compressor-$(CONFIG_KERNEL_LZO) := lzo
# args (to if_changed): 1 = (this rule), 2 = platform, 3 = dts 4=dtb 5=initrd
quiet_cmd_wrap = WRAP $@
- cmd_wrap =$(CONFIG_SHELL) $(wrapper) -Z $(compressor-y) -c -o $@ -p $2 \
+ cmd_wrap =$(CONFIG_SHELL) $(wrapper) -Z gzip -c -o $@ -p $2 \
$(CROSSWRAP) $(if $3, -s $3)$(if $4, -d $4)$(if $5, -i $5) \
vmlinux

View File

@ -10,6 +10,7 @@ BOARDNAME:=Atheros AR231x/AR5312
FEATURES:=squashfs low_mem small_flash
KERNEL_PATCHVER:=5.4
KERNEL_TESTING_PATCHVER:=5.10
define Target/Description
Build firmware images for Atheros SoC boards

View File

@ -0,0 +1,127 @@
CONFIG_ADM6996_PHY=y
CONFIG_AR2315_WDT=y
CONFIG_AR8216_PHY=y
CONFIG_ARCH_32BIT_OFF_T=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_MMAP_RND_BITS_MAX=15
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_ATH25=y
CONFIG_BLK_MQ_PCI=y
CONFIG_CEVT_R4K=y
CONFIG_CLONE_BACKWARDS=y
CONFIG_CMDLINE="console=ttyS0,9600 rootfstype=squashfs,jffs2"
CONFIG_CMDLINE_BOOL=y
# CONFIG_CMDLINE_OVERRIDE is not set
# CONFIG_COMMON_CLK is not set
CONFIG_COMPAT_32BIT_TIME=y
CONFIG_CPU_BIG_ENDIAN=y
CONFIG_CPU_GENERIC_DUMP_TLB=y
CONFIG_CPU_HAS_PREFETCH=y
CONFIG_CPU_HAS_SYNC=y
CONFIG_CPU_MIPS32=y
CONFIG_CPU_MIPS32_R1=y
CONFIG_CPU_MIPSR1=y
CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
CONFIG_CPU_R4K_CACHE_TLB=y
CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
CONFIG_CPU_SUPPORTS_HIGHMEM=y
CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2
CONFIG_CRYPTO_RNG2=y
CONFIG_CSRC_R4K=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_EARLY_PRINTK=y
CONFIG_ETHERNET_PACKET_MANGLE=y
CONFIG_FORCE_PCI=y
CONFIG_FW_LOADER_PAGED_BUF=y
CONFIG_GENERIC_ATOMIC64=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CMOS_UPDATE=y
CONFIG_GENERIC_CPU_AUTOPROBE=y
CONFIG_GENERIC_GETTIMEOFDAY=y
CONFIG_GENERIC_IOMAP=y
CONFIG_GENERIC_IRQ_CHIP=y
CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_LIB_ASHLDI3=y
CONFIG_GENERIC_LIB_ASHRDI3=y
CONFIG_GENERIC_LIB_CMPDI2=y
CONFIG_GENERIC_LIB_LSHRDI3=y
CONFIG_GENERIC_LIB_UCMPDI2=y
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_GENERIC_SCHED_CLOCK=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GPIOLIB=y
CONFIG_GPIO_AR2315=y
CONFIG_GPIO_AR5312=y
CONFIG_HANDLE_DOMAIN_IRQ=y
CONFIG_HARDWARE_WATCHPOINTS=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT_MAP=y
CONFIG_HW_RANDOM=y
CONFIG_HZ_PERIODIC=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_IP17XX_PHY=y
CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_IRQ_MIPS_CPU=y
CONFIG_IRQ_WORK=y
CONFIG_LEDS_GPIO=y
CONFIG_LOCK_DEBUGGING_SUPPORT=y
CONFIG_MDIO_BUS=y
CONFIG_MDIO_DEVICE=y
CONFIG_MDIO_DEVRES=y
CONFIG_MEMFD_CREATE=y
CONFIG_MIGRATION=y
CONFIG_MIPS=y
CONFIG_MIPS_ASID_BITS=8
CONFIG_MIPS_ASID_SHIFT=0
CONFIG_MIPS_CLOCK_VSYSCALL=y
# CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND is not set
CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER=y
CONFIG_MIPS_EBPF_JIT=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
CONFIG_MIPS_LD_CAN_LINK_VDSO=y
CONFIG_MODULES_USE_ELF_REL=y
CONFIG_MTD_AR2315=y
CONFIG_MTD_CFI_ADV_OPTIONS=y
# CONFIG_MTD_CFI_GEOMETRY is not set
# CONFIG_MTD_CFI_INTELEXT is not set
CONFIG_MTD_MYLOADER_PARTS=y
CONFIG_MTD_PHYSMAP=y
CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-3
CONFIG_MTD_REDBOOT_PARTS=y
CONFIG_MVSWITCH_PHY=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_NEED_PER_CPU_KM=y
CONFIG_NET_AR231X=y
CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
# CONFIG_OF is not set
CONFIG_PCI=y
CONFIG_PCI_AR2315=y
CONFIG_PCI_DISABLE_COMMON_QUIRKS=y
CONFIG_PCI_DOMAINS=y
CONFIG_PCI_DRIVERS_LEGACY=y
CONFIG_PERF_USE_VMALLOC=y
CONFIG_PGTABLE_LEVELS=2
CONFIG_PHYLIB=y
CONFIG_SERIAL_8250_NR_UARTS=1
CONFIG_SERIAL_8250_RUNTIME_UARTS=1
CONFIG_SERIAL_MCTRL_GPIO=y
CONFIG_SOC_AR2315=y
CONFIG_SOC_AR5312=y
CONFIG_SRCU=y
# CONFIG_SWAP is not set
CONFIG_SWCONFIG=y
CONFIG_SYSCTL_EXCEPTION_TRACE=y
CONFIG_SYS_HAS_CPU_MIPS32_R1=y
CONFIG_SYS_HAS_EARLY_PRINTK=y
CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
CONFIG_TARGET_ISA_REV=1
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TINY_SRCU=y
CONFIG_USB_SUPPORT=y

View File

@ -3,25 +3,10 @@ CONFIG_AR2315_WDT=y
CONFIG_AR8216_PHY=y
CONFIG_ARCH_32BIT_OFF_T=y
CONFIG_ARCH_CLOCKSOURCE_DATA=y
CONFIG_ARCH_HAS_DMA_COHERENT_TO_PFN=y
CONFIG_ARCH_HAS_DMA_PREP_COHERENT=y
CONFIG_ARCH_HAS_DMA_WRITE_COMBINE=y
CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
CONFIG_ARCH_HAS_PHYS_TO_DMA=y
CONFIG_ARCH_HAS_PTE_SPECIAL=y
CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE=y
CONFIG_ARCH_HAS_UNCACHED_SEGMENT=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_MMAP_RND_BITS_MAX=15
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
CONFIG_ARCH_SUPPORTS_UPROBES=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_ARCH_USE_BUILTIN_BSWAP=y
CONFIG_ARCH_USE_MEMREMAP_PROT=y
CONFIG_ARCH_USE_QUEUED_RWLOCKS=y
CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y
CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT=y
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
CONFIG_ATH25=y
CONFIG_BLK_MQ_PCI=y
CONFIG_CEVT_R4K=y
@ -42,16 +27,13 @@ CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
CONFIG_CPU_R4K_CACHE_TLB=y
CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
CONFIG_CPU_SUPPORTS_HIGHMEM=y
CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2
CONFIG_CRYPTO_RNG2=y
CONFIG_CSRC_R4K=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NONCOHERENT_CACHE_SYNC=y
CONFIG_EARLY_PRINTK=y
CONFIG_EFI_EARLYCON=y
CONFIG_ETHERNET_PACKET_MANGLE=y
CONFIG_FONT_8x16=y
CONFIG_FONT_AUTOSELECT=y
CONFIG_FONT_SUPPORT=y
CONFIG_FORCE_PCI=y
CONFIG_FW_LOADER_PAGED_BUF=y
CONFIG_GENERIC_ATOMIC64=y
@ -80,40 +62,6 @@ CONFIG_HARDWARE_WATCHPOINTS=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT_MAP=y
CONFIG_HAVE_ARCH_COMPILER_H=y
CONFIG_HAVE_ARCH_JUMP_LABEL=y
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_ASM_MODVERSIONS=y
CONFIG_HAVE_CBPF_JIT=y
CONFIG_HAVE_CONTEXT_TRACKING=y
CONFIG_HAVE_COPY_THREAD_TLS=y
CONFIG_HAVE_C_RECORDMCOUNT=y
CONFIG_HAVE_DEBUG_KMEMLEAK=y
CONFIG_HAVE_DEBUG_STACKOVERFLOW=y
CONFIG_HAVE_DMA_CONTIGUOUS=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FAST_GUP=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_GENERIC_VDSO=y
CONFIG_HAVE_IDE=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y
CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
CONFIG_HAVE_LD_DEAD_CODE_DATA_ELIMINATION=y
CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
CONFIG_HAVE_NET_DSA=y
CONFIG_HAVE_OPROFILE=y
CONFIG_HAVE_PCI=y
CONFIG_HAVE_PERF_EVENTS=y
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
CONFIG_HAVE_RSEQ=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
CONFIG_HW_RANDOM=y
CONFIG_HZ_PERIODIC=y
CONFIG_INITRAMFS_SOURCE=""
@ -131,10 +79,10 @@ CONFIG_MIGRATION=y
CONFIG_MIPS=y
CONFIG_MIPS_ASID_BITS=8
CONFIG_MIPS_ASID_SHIFT=0
CONFIG_MIPS_CBPF_JIT=y
CONFIG_MIPS_CLOCK_VSYSCALL=y
# CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND is not set
CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER=y
CONFIG_MIPS_EBPF_JIT=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
CONFIG_MODULES_USE_ELF_REL=y
CONFIG_MTD_AR2315=y

View File

@ -0,0 +1,212 @@
--- a/arch/mips/ath25/Kconfig
+++ b/arch/mips/ath25/Kconfig
@@ -2,6 +2,7 @@
config SOC_AR5312
bool "Atheros AR5312/AR2312+ SoC support"
depends on ATH25
+ select GPIO_AR5312
default y
config SOC_AR2315
--- a/arch/mips/ath25/ar5312.c
+++ b/arch/mips/ath25/ar5312.c
@@ -23,6 +23,7 @@
#include <linux/platform_device.h>
#include <linux/mtd/physmap.h>
#include <linux/reboot.h>
+#include <linux/gpio.h>
#include <asm/bootinfo.h>
#include <asm/reboot.h>
#include <asm/time.h>
@@ -178,6 +179,22 @@ static struct platform_device ar5312_phy
.num_resources = 1,
};
+static struct resource ar5312_gpio_res[] = {
+ {
+ .name = "ar5312-gpio",
+ .flags = IORESOURCE_MEM,
+ .start = AR5312_GPIO_BASE,
+ .end = AR5312_GPIO_BASE + AR5312_GPIO_SIZE - 1,
+ },
+};
+
+static struct platform_device ar5312_gpio = {
+ .name = "ar5312-gpio",
+ .id = -1,
+ .resource = ar5312_gpio_res,
+ .num_resources = ARRAY_SIZE(ar5312_gpio_res),
+};
+
static void __init ar5312_flash_init(void)
{
void __iomem *flashctl_base;
@@ -245,6 +262,8 @@ void __init ar5312_init_devices(void)
platform_device_register(&ar5312_physmap_flash);
+ platform_device_register(&ar5312_gpio);
+
switch (ath25_soc) {
case ATH25_SOC_AR5312:
if (!ath25_board.radio)
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -142,6 +142,13 @@ config GPIO_AMDPT
driver for GPIO functionality on Promontory IOHub
Require ACPI ASL code to enumerate as a platform device.
+config GPIO_AR5312
+ bool "AR5312 SoC GPIO support"
+ default y if SOC_AR5312
+ depends on SOC_AR5312
+ help
+ Say yes here to enable GPIO support for Atheros AR5312/AR2312+ SoCs.
+
config GPIO_ASPEED
tristate "Aspeed GPIO support"
depends on (ARCH_ASPEED || COMPILE_TEST) && OF_GPIO
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_GPIO_ALTERA) += gpio-alt
obj-$(CONFIG_GPIO_AMD8111) += gpio-amd8111.o
obj-$(CONFIG_GPIO_AMD_FCH) += gpio-amd-fch.o
obj-$(CONFIG_GPIO_AMDPT) += gpio-amdpt.o
+obj-$(CONFIG_GPIO_AR5312) += gpio-ar5312.o
obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o
obj-$(CONFIG_GPIO_ASPEED) += gpio-aspeed.o
obj-$(CONFIG_GPIO_ASPEED_SGPIO) += gpio-aspeed-sgpio.o
--- /dev/null
+++ b/drivers/gpio/gpio-ar5312.c
@@ -0,0 +1,121 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved.
+ * Copyright (C) 2006 FON Technology, SL.
+ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
+ * Copyright (C) 2006-2009 Felix Fietkau <nbd@nbd.name>
+ * Copyright (C) 2012 Alexandros C. Couloumbis <alex@ozo.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+
+#define DRIVER_NAME "ar5312-gpio"
+
+#define AR5312_GPIO_DO 0x00 /* output register */
+#define AR5312_GPIO_DI 0x04 /* intput register */
+#define AR5312_GPIO_CR 0x08 /* control register */
+
+#define AR5312_GPIO_CR_M(x) (1 << (x)) /* mask for i/o */
+#define AR5312_GPIO_CR_O(x) (0 << (x)) /* mask for output */
+#define AR5312_GPIO_CR_I(x) (1 << (x)) /* mask for input */
+#define AR5312_GPIO_CR_INT(x) (1 << ((x)+8)) /* mask for interrupt */
+#define AR5312_GPIO_CR_UART(x) (1 << ((x)+16)) /* uart multiplex */
+
+#define AR5312_GPIO_NUM 8
+
+static void __iomem *ar5312_mem;
+
+static inline u32 ar5312_gpio_reg_read(unsigned reg)
+{
+ return __raw_readl(ar5312_mem + reg);
+}
+
+static inline void ar5312_gpio_reg_write(unsigned reg, u32 val)
+{
+ __raw_writel(val, ar5312_mem + reg);
+}
+
+static inline void ar5312_gpio_reg_mask(unsigned reg, u32 mask, u32 val)
+{
+ ar5312_gpio_reg_write(reg, (ar5312_gpio_reg_read(reg) & ~mask) | val);
+}
+
+static int ar5312_gpio_get_val(struct gpio_chip *chip, unsigned gpio)
+{
+ return (ar5312_gpio_reg_read(AR5312_GPIO_DI) >> gpio) & 1;
+}
+
+static void ar5312_gpio_set_val(struct gpio_chip *chip, unsigned gpio, int val)
+{
+ u32 reg = ar5312_gpio_reg_read(AR5312_GPIO_DO);
+
+ reg = val ? reg | (1 << gpio) : reg & ~(1 << gpio);
+ ar5312_gpio_reg_write(AR5312_GPIO_DO, reg);
+}
+
+static int ar5312_gpio_dir_in(struct gpio_chip *chip, unsigned gpio)
+{
+ ar5312_gpio_reg_mask(AR5312_GPIO_CR, 0, 1 << gpio);
+ return 0;
+}
+
+static int ar5312_gpio_dir_out(struct gpio_chip *chip, unsigned gpio, int val)
+{
+ ar5312_gpio_reg_mask(AR5312_GPIO_CR, 1 << gpio, 0);
+ ar5312_gpio_set_val(chip, gpio, val);
+ return 0;
+}
+
+static struct gpio_chip ar5312_gpio_chip = {
+ .label = DRIVER_NAME,
+ .direction_input = ar5312_gpio_dir_in,
+ .direction_output = ar5312_gpio_dir_out,
+ .set = ar5312_gpio_set_val,
+ .get = ar5312_gpio_get_val,
+ .base = 0,
+ .ngpio = AR5312_GPIO_NUM,
+};
+
+static int ar5312_gpio_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct resource *res;
+ int ret;
+
+ if (ar5312_mem)
+ return -EBUSY;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ ar5312_mem = devm_ioremap_resource(dev, res);
+ if (IS_ERR(ar5312_mem))
+ return PTR_ERR(ar5312_mem);
+
+ ar5312_gpio_chip.parent = dev;
+ ret = gpiochip_add(&ar5312_gpio_chip);
+ if (ret) {
+ dev_err(dev, "failed to add gpiochip\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static struct platform_driver ar5312_gpio_driver = {
+ .probe = ar5312_gpio_probe,
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ }
+};
+
+static int __init ar5312_gpio_init(void)
+{
+ return platform_driver_register(&ar5312_gpio_driver);
+}
+subsys_initcall(ar5312_gpio_init);
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -219,6 +219,7 @@ config ATH25
select CEVT_R4K
select CSRC_R4K
select DMA_NONCOHERENT
+ select GPIOLIB
select IRQ_MIPS_CPU
select IRQ_DOMAIN
select SYS_HAS_CPU_MIPS32_R1

View File

@ -0,0 +1,363 @@
--- a/arch/mips/ath25/Kconfig
+++ b/arch/mips/ath25/Kconfig
@@ -8,6 +8,7 @@ config SOC_AR5312
config SOC_AR2315
bool "Atheros AR2315+ SoC support"
depends on ATH25
+ select GPIO_AR2315
default y
config PCI_AR2315
--- a/arch/mips/ath25/ar2315.c
+++ b/arch/mips/ath25/ar2315.c
@@ -22,6 +22,8 @@
#include <linux/memblock.h>
#include <linux/platform_device.h>
#include <linux/reboot.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
#include <asm/bootinfo.h>
#include <asm/reboot.h>
#include <asm/time.h>
@@ -165,11 +167,42 @@ void __init ar2315_arch_init_irq(void)
ar2315_misc_irq_domain = domain;
}
+static struct resource ar2315_gpio_res[] = {
+ {
+ .name = "ar2315-gpio",
+ .flags = IORESOURCE_MEM,
+ .start = AR2315_RST_BASE + AR2315_GPIO,
+ .end = AR2315_RST_BASE + AR2315_GPIO + 0x10 - 1,
+ },
+ {
+ .name = "ar2315-gpio",
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "ar2315-gpio-irq-base",
+ .flags = IORESOURCE_IRQ,
+ .start = AR231X_GPIO_IRQ_BASE,
+ .end = AR231X_GPIO_IRQ_BASE,
+ }
+};
+
+static struct platform_device ar2315_gpio = {
+ .id = -1,
+ .name = "ar2315-gpio",
+ .resource = ar2315_gpio_res,
+ .num_resources = ARRAY_SIZE(ar2315_gpio_res)
+};
+
void __init ar2315_init_devices(void)
{
/* Find board configuration */
ath25_find_config(AR2315_SPI_READ_BASE, AR2315_SPI_READ_SIZE);
+ ar2315_gpio_res[1].start = irq_create_mapping(ar2315_misc_irq_domain,
+ AR2315_MISC_IRQ_GPIO);
+ ar2315_gpio_res[1].end = ar2315_gpio_res[1].start;
+ platform_device_register(&ar2315_gpio);
+
ath25_add_wmac(0, AR2315_WLAN0_BASE, AR2315_IRQ_WLAN0);
}
@@ -185,8 +218,8 @@ static void ar2315_restart(char *command
/* Cold reset does not work on the AR2315/6, use the GPIO reset bits
* a workaround. Give it some time to attempt a gpio based hardware
* reset (atheros reference design workaround) */
-
- /* TODO: implement the GPIO reset workaround */
+ gpio_request_one(AR2315_RESET_GPIO, GPIOF_OUT_INIT_LOW, "Reset");
+ mdelay(100);
/* Some boards (e.g. Senao EOC-2610) don't implement the reset logic
* workaround. Attempt to jump to the mips reset location -
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -142,6 +142,13 @@ config GPIO_AMDPT
driver for GPIO functionality on Promontory IOHub
Require ACPI ASL code to enumerate as a platform device.
+config GPIO_AR2315
+ bool "AR2315 SoC GPIO support"
+ default y if SOC_AR2315
+ depends on SOC_AR2315
+ help
+ Say yes here to enable GPIO support for Atheros AR2315+ SoCs.
+
config GPIO_AR5312
bool "AR5312 SoC GPIO support"
default y if SOC_AR5312
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_GPIO_ALTERA) += gpio-alt
obj-$(CONFIG_GPIO_AMD8111) += gpio-amd8111.o
obj-$(CONFIG_GPIO_AMD_FCH) += gpio-amd-fch.o
obj-$(CONFIG_GPIO_AMDPT) += gpio-amdpt.o
+obj-$(CONFIG_GPIO_AR2315) += gpio-ar2315.o
obj-$(CONFIG_GPIO_AR5312) += gpio-ar5312.o
obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o
obj-$(CONFIG_GPIO_ASPEED) += gpio-aspeed.o
--- /dev/null
+++ b/drivers/gpio/gpio-ar2315.c
@@ -0,0 +1,233 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved.
+ * Copyright (C) 2006 FON Technology, SL.
+ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
+ * Copyright (C) 2006 Felix Fietkau <nbd@nbd.name>
+ * Copyright (C) 2012 Alexandros C. Couloumbis <alex@ozo.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+
+#define DRIVER_NAME "ar2315-gpio"
+
+#define AR2315_GPIO_DI 0x0000
+#define AR2315_GPIO_DO 0x0008
+#define AR2315_GPIO_DIR 0x0010
+#define AR2315_GPIO_INT 0x0018
+
+#define AR2315_GPIO_DIR_M(x) (1 << (x)) /* mask for i/o */
+#define AR2315_GPIO_DIR_O(x) (1 << (x)) /* output */
+#define AR2315_GPIO_DIR_I(x) (0) /* input */
+
+#define AR2315_GPIO_INT_NUM_M 0x3F /* mask for GPIO num */
+#define AR2315_GPIO_INT_TRIG(x) ((x) << 6) /* interrupt trigger */
+#define AR2315_GPIO_INT_TRIG_M (0x3 << 6) /* mask for int trig */
+
+#define AR2315_GPIO_INT_TRIG_OFF 0 /* Triggerring off */
+#define AR2315_GPIO_INT_TRIG_LOW 1 /* Low Level Triggered */
+#define AR2315_GPIO_INT_TRIG_HIGH 2 /* High Level Triggered */
+#define AR2315_GPIO_INT_TRIG_EDGE 3 /* Edge Triggered */
+
+#define AR2315_GPIO_NUM 22
+
+static u32 ar2315_gpio_intmask;
+static u32 ar2315_gpio_intval;
+static unsigned ar2315_gpio_irq_base;
+static void __iomem *ar2315_mem;
+
+static inline u32 ar2315_gpio_reg_read(unsigned reg)
+{
+ return __raw_readl(ar2315_mem + reg);
+}
+
+static inline void ar2315_gpio_reg_write(unsigned reg, u32 val)
+{
+ __raw_writel(val, ar2315_mem + reg);
+}
+
+static inline void ar2315_gpio_reg_mask(unsigned reg, u32 mask, u32 val)
+{
+ ar2315_gpio_reg_write(reg, (ar2315_gpio_reg_read(reg) & ~mask) | val);
+}
+
+static void ar2315_gpio_irq_handler(struct irq_desc *desc)
+{
+ u32 pend;
+ int bit = -1;
+
+ /* only do one gpio interrupt at a time */
+ pend = ar2315_gpio_reg_read(AR2315_GPIO_DI);
+ pend ^= ar2315_gpio_intval;
+ pend &= ar2315_gpio_intmask;
+
+ if (pend) {
+ bit = fls(pend) - 1;
+ pend &= ~(1 << bit);
+ ar2315_gpio_intval ^= (1 << bit);
+ }
+
+ /* Enable interrupt with edge detection */
+ if ((ar2315_gpio_reg_read(AR2315_GPIO_DIR) & AR2315_GPIO_DIR_M(bit)) !=
+ AR2315_GPIO_DIR_I(bit))
+ return;
+
+ if (bit >= 0)
+ generic_handle_irq(ar2315_gpio_irq_base + bit);
+}
+
+static void ar2315_gpio_int_setup(unsigned gpio, int trig)
+{
+ u32 reg = ar2315_gpio_reg_read(AR2315_GPIO_INT);
+
+ reg &= ~(AR2315_GPIO_INT_NUM_M | AR2315_GPIO_INT_TRIG_M);
+ reg |= gpio | AR2315_GPIO_INT_TRIG(trig);
+ ar2315_gpio_reg_write(AR2315_GPIO_INT, reg);
+}
+
+static void ar2315_gpio_irq_unmask(struct irq_data *d)
+{
+ unsigned gpio = d->irq - ar2315_gpio_irq_base;
+ u32 dir = ar2315_gpio_reg_read(AR2315_GPIO_DIR);
+
+ /* Enable interrupt with edge detection */
+ if ((dir & AR2315_GPIO_DIR_M(gpio)) != AR2315_GPIO_DIR_I(gpio))
+ return;
+
+ ar2315_gpio_intmask |= (1 << gpio);
+ ar2315_gpio_int_setup(gpio, AR2315_GPIO_INT_TRIG_EDGE);
+}
+
+static void ar2315_gpio_irq_mask(struct irq_data *d)
+{
+ unsigned gpio = d->irq - ar2315_gpio_irq_base;
+
+ /* Disable interrupt */
+ ar2315_gpio_intmask &= ~(1 << gpio);
+ ar2315_gpio_int_setup(gpio, AR2315_GPIO_INT_TRIG_OFF);
+}
+
+static struct irq_chip ar2315_gpio_irq_chip = {
+ .name = DRIVER_NAME,
+ .irq_unmask = ar2315_gpio_irq_unmask,
+ .irq_mask = ar2315_gpio_irq_mask,
+};
+
+static void ar2315_gpio_irq_init(unsigned irq)
+{
+ unsigned i;
+
+ ar2315_gpio_intval = ar2315_gpio_reg_read(AR2315_GPIO_DI);
+ for (i = 0; i < AR2315_GPIO_NUM; i++) {
+ unsigned _irq = ar2315_gpio_irq_base + i;
+
+ irq_set_chip_and_handler(_irq, &ar2315_gpio_irq_chip,
+ handle_level_irq);
+ }
+ irq_set_chained_handler(irq, ar2315_gpio_irq_handler);
+}
+
+static int ar2315_gpio_get_val(struct gpio_chip *chip, unsigned gpio)
+{
+ return (ar2315_gpio_reg_read(AR2315_GPIO_DI) >> gpio) & 1;
+}
+
+static void ar2315_gpio_set_val(struct gpio_chip *chip, unsigned gpio, int val)
+{
+ u32 reg = ar2315_gpio_reg_read(AR2315_GPIO_DO);
+
+ reg = val ? reg | (1 << gpio) : reg & ~(1 << gpio);
+ ar2315_gpio_reg_write(AR2315_GPIO_DO, reg);
+}
+
+static int ar2315_gpio_dir_in(struct gpio_chip *chip, unsigned gpio)
+{
+ ar2315_gpio_reg_mask(AR2315_GPIO_DIR, 1 << gpio, 0);
+ return 0;
+}
+
+static int ar2315_gpio_dir_out(struct gpio_chip *chip, unsigned gpio, int val)
+{
+ ar2315_gpio_reg_mask(AR2315_GPIO_DIR, 0, 1 << gpio);
+ ar2315_gpio_set_val(chip, gpio, val);
+ return 0;
+}
+
+static int ar2315_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
+{
+ return ar2315_gpio_irq_base + gpio;
+}
+
+static struct gpio_chip ar2315_gpio_chip = {
+ .label = DRIVER_NAME,
+ .direction_input = ar2315_gpio_dir_in,
+ .direction_output = ar2315_gpio_dir_out,
+ .set = ar2315_gpio_set_val,
+ .get = ar2315_gpio_get_val,
+ .to_irq = ar2315_gpio_to_irq,
+ .base = 0,
+ .ngpio = AR2315_GPIO_NUM,
+};
+
+static int ar2315_gpio_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct resource *res;
+ unsigned irq;
+ int ret;
+
+ if (ar2315_mem)
+ return -EBUSY;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
+ "ar2315-gpio-irq-base");
+ if (!res) {
+ dev_err(dev, "not found GPIO IRQ base\n");
+ return -ENXIO;
+ }
+ ar2315_gpio_irq_base = res->start;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, DRIVER_NAME);
+ if (!res) {
+ dev_err(dev, "not found IRQ number\n");
+ return -ENXIO;
+ }
+ irq = res->start;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, DRIVER_NAME);
+ ar2315_mem = devm_ioremap_resource(dev, res);
+ if (IS_ERR(ar2315_mem))
+ return PTR_ERR(ar2315_mem);
+
+ ar2315_gpio_chip.parent = dev;
+ ret = gpiochip_add(&ar2315_gpio_chip);
+ if (ret) {
+ dev_err(dev, "failed to add gpiochip\n");
+ return ret;
+ }
+
+ ar2315_gpio_irq_init(irq);
+
+ return 0;
+}
+
+static struct platform_driver ar2315_gpio_driver = {
+ .probe = ar2315_gpio_probe,
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ }
+};
+
+static int __init ar2315_gpio_init(void)
+{
+ return platform_driver_register(&ar2315_gpio_driver);
+}
+subsys_initcall(ar2315_gpio_init);
--- a/arch/mips/ath25/devices.h
+++ b/arch/mips/ath25/devices.h
@@ -4,6 +4,11 @@
#include <linux/cpu.h>
+#define AR231X_GPIO_IRQ_BASE 0x30
+
+/* GPIO number for AR2315/16 reset issue workaround */
+#define AR2315_RESET_GPIO 5
+
#define ATH25_REG_MS(_val, _field) (((_val) & _field##_M) >> _field##_S)
#define ATH25_IRQ_CPU_CLOCK (MIPS_CPU_IRQ_BASE + 7) /* C0_CAUSE: 0x8000 */
--- a/arch/mips/ath25/ar2315_regs.h
+++ b/arch/mips/ath25/ar2315_regs.h
@@ -315,6 +315,9 @@
#define AR2315_MEM_CFG_BANKADDR_BITS_M 0x00000018
#define AR2315_MEM_CFG_BANKADDR_BITS_S 3
+/* GPIO MMR base address */
+#define AR2315_GPIO 0x0088
+
/*
* Local Bus Interface Registers
*/

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,631 @@
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -114,6 +114,10 @@ config MTD_BCM47XXSFLASH
registered by bcma as platform devices. This enables driver for
serial flash memories.
+config MTD_AR2315
+ tristate "Atheros AR2315+ SPI Flash support"
+ depends on SOC_AR2315
+
config MTD_SLRAM
tristate "Uncached system RAM"
help
--- a/drivers/mtd/devices/Makefile
+++ b/drivers/mtd/devices/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataf
obj-$(CONFIG_MTD_MCHP23K256) += mchp23k256.o
obj-$(CONFIG_MTD_SPEAR_SMI) += spear_smi.o
obj-$(CONFIG_MTD_SST25L) += sst25l.o
+obj-$(CONFIG_MTD_AR2315) += ar2315.o
obj-$(CONFIG_MTD_BCM47XXSFLASH) += bcm47xxsflash.o
obj-$(CONFIG_MTD_ST_SPI_FSM) += st_spi_fsm.o
obj-$(CONFIG_MTD_POWERNV_FLASH) += powernv_flash.o
--- /dev/null
+++ b/drivers/mtd/devices/ar2315.c
@@ -0,0 +1,456 @@
+
+/*
+ * MTD driver for the SPI Flash Memory support on Atheros AR2315
+ *
+ * Copyright (c) 2005-2006 Atheros Communications Inc.
+ * Copyright (C) 2006-2007 FON Technology, SL.
+ * Copyright (C) 2006-2007 Imre Kaloz <kaloz@openwrt.org>
+ * Copyright (C) 2006-2009 Felix Fietkau <nbd@nbd.name>
+ * Copyright (C) 2012 Alexandros C. Couloumbis <alex@ozo.com>
+ *
+ * This code is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/mutex.h>
+
+#include "ar2315_spiflash.h"
+
+#define DRIVER_NAME "ar2315-spiflash"
+
+#define busy_wait(_priv, _condition, _wait) do { \
+ while (_condition) { \
+ if (_wait > 1) \
+ msleep(_wait); \
+ else if ((_wait == 1) && need_resched()) \
+ schedule(); \
+ else \
+ udelay(1); \
+ } \
+} while (0)
+
+enum {
+ FLASH_NONE,
+ FLASH_1MB,
+ FLASH_2MB,
+ FLASH_4MB,
+ FLASH_8MB,
+ FLASH_16MB,
+};
+
+/* Flash configuration table */
+struct flashconfig {
+ u32 byte_cnt;
+ u32 sector_cnt;
+ u32 sector_size;
+};
+
+static const struct flashconfig flashconfig_tbl[] = {
+ [FLASH_NONE] = { 0, 0, 0},
+ [FLASH_1MB] = { STM_1MB_BYTE_COUNT, STM_1MB_SECTOR_COUNT,
+ STM_1MB_SECTOR_SIZE},
+ [FLASH_2MB] = { STM_2MB_BYTE_COUNT, STM_2MB_SECTOR_COUNT,
+ STM_2MB_SECTOR_SIZE},
+ [FLASH_4MB] = { STM_4MB_BYTE_COUNT, STM_4MB_SECTOR_COUNT,
+ STM_4MB_SECTOR_SIZE},
+ [FLASH_8MB] = { STM_8MB_BYTE_COUNT, STM_8MB_SECTOR_COUNT,
+ STM_8MB_SECTOR_SIZE},
+ [FLASH_16MB] = { STM_16MB_BYTE_COUNT, STM_16MB_SECTOR_COUNT,
+ STM_16MB_SECTOR_SIZE}
+};
+
+/* Mapping of generic opcodes to STM serial flash opcodes */
+enum {
+ SPI_WRITE_ENABLE,
+ SPI_WRITE_DISABLE,
+ SPI_RD_STATUS,
+ SPI_WR_STATUS,
+ SPI_RD_DATA,
+ SPI_FAST_RD_DATA,
+ SPI_PAGE_PROGRAM,
+ SPI_SECTOR_ERASE,
+ SPI_BULK_ERASE,
+ SPI_DEEP_PWRDOWN,
+ SPI_RD_SIG,
+};
+
+struct opcodes {
+ __u16 code;
+ __s8 tx_cnt;
+ __s8 rx_cnt;
+};
+
+static const struct opcodes stm_opcodes[] = {
+ [SPI_WRITE_ENABLE] = {STM_OP_WR_ENABLE, 1, 0},
+ [SPI_WRITE_DISABLE] = {STM_OP_WR_DISABLE, 1, 0},
+ [SPI_RD_STATUS] = {STM_OP_RD_STATUS, 1, 1},
+ [SPI_WR_STATUS] = {STM_OP_WR_STATUS, 1, 0},
+ [SPI_RD_DATA] = {STM_OP_RD_DATA, 4, 4},
+ [SPI_FAST_RD_DATA] = {STM_OP_FAST_RD_DATA, 5, 0},
+ [SPI_PAGE_PROGRAM] = {STM_OP_PAGE_PGRM, 8, 0},
+ [SPI_SECTOR_ERASE] = {STM_OP_SECTOR_ERASE, 4, 0},
+ [SPI_BULK_ERASE] = {STM_OP_BULK_ERASE, 1, 0},
+ [SPI_DEEP_PWRDOWN] = {STM_OP_DEEP_PWRDOWN, 1, 0},
+ [SPI_RD_SIG] = {STM_OP_RD_SIG, 4, 1},
+};
+
+/* Driver private data structure */
+struct spiflash_priv {
+ struct mtd_info mtd;
+ void __iomem *readaddr; /* memory mapped data for read */
+ void __iomem *mmraddr; /* memory mapped register space */
+ struct mutex lock; /* serialize registers access */
+};
+
+#define to_spiflash(_mtd) container_of(_mtd, struct spiflash_priv, mtd)
+
+enum {
+ FL_READY,
+ FL_READING,
+ FL_ERASING,
+ FL_WRITING
+};
+
+/*****************************************************************************/
+
+static u32
+spiflash_read_reg(struct spiflash_priv *priv, int reg)
+{
+ return ioread32(priv->mmraddr + reg);
+}
+
+static void
+spiflash_write_reg(struct spiflash_priv *priv, int reg, u32 data)
+{
+ iowrite32(data, priv->mmraddr + reg);
+}
+
+static u32
+spiflash_wait_busy(struct spiflash_priv *priv)
+{
+ u32 reg;
+
+ busy_wait(priv, (reg = spiflash_read_reg(priv, SPI_FLASH_CTL)) &
+ SPI_CTL_BUSY, 0);
+ return reg;
+}
+
+static u32
+spiflash_sendcmd(struct spiflash_priv *priv, int opcode, u32 addr)
+{
+ const struct opcodes *op;
+ u32 reg, mask;
+
+ op = &stm_opcodes[opcode];
+ reg = spiflash_wait_busy(priv);
+ spiflash_write_reg(priv, SPI_FLASH_OPCODE,
+ ((u32)op->code) | (addr << 8));
+
+ reg &= ~SPI_CTL_TX_RX_CNT_MASK;
+ reg |= SPI_CTL_START | op->tx_cnt | (op->rx_cnt << 4);
+
+ spiflash_write_reg(priv, SPI_FLASH_CTL, reg);
+ spiflash_wait_busy(priv);
+
+ if (!op->rx_cnt)
+ return 0;
+
+ reg = spiflash_read_reg(priv, SPI_FLASH_DATA);
+
+ switch (op->rx_cnt) {
+ case 1:
+ mask = 0x000000ff;
+ break;
+ case 2:
+ mask = 0x0000ffff;
+ break;
+ case 3:
+ mask = 0x00ffffff;
+ break;
+ default:
+ mask = 0xffffffff;
+ break;
+ }
+ reg &= mask;
+
+ return reg;
+}
+
+/*
+ * Probe SPI flash device
+ * Function returns 0 for failure.
+ * and flashconfig_tbl array index for success.
+ */
+static int
+spiflash_probe_chip(struct platform_device *pdev, struct spiflash_priv *priv)
+{
+ u32 sig = spiflash_sendcmd(priv, SPI_RD_SIG, 0);
+ int flash_size;
+
+ switch (sig) {
+ case STM_8MBIT_SIGNATURE:
+ flash_size = FLASH_1MB;
+ break;
+ case STM_16MBIT_SIGNATURE:
+ flash_size = FLASH_2MB;
+ break;
+ case STM_32MBIT_SIGNATURE:
+ flash_size = FLASH_4MB;
+ break;
+ case STM_64MBIT_SIGNATURE:
+ flash_size = FLASH_8MB;
+ break;
+ case STM_128MBIT_SIGNATURE:
+ flash_size = FLASH_16MB;
+ break;
+ default:
+ dev_warn(&pdev->dev, "read of flash device signature failed!\n");
+ return 0;
+ }
+
+ return flash_size;
+}
+
+static void
+spiflash_wait_complete(struct spiflash_priv *priv, unsigned int timeout)
+{
+ busy_wait(priv, spiflash_sendcmd(priv, SPI_RD_STATUS, 0) &
+ SPI_STATUS_WIP, timeout);
+}
+
+static int
+spiflash_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+ struct spiflash_priv *priv = to_spiflash(mtd);
+ const struct opcodes *op;
+ u32 temp, reg;
+
+ if (instr->addr + instr->len > mtd->size)
+ return -EINVAL;
+
+ mutex_lock(&priv->lock);
+
+ spiflash_sendcmd(priv, SPI_WRITE_ENABLE, 0);
+ reg = spiflash_wait_busy(priv);
+
+ op = &stm_opcodes[SPI_SECTOR_ERASE];
+ temp = ((u32)instr->addr << 8) | (u32)(op->code);
+ spiflash_write_reg(priv, SPI_FLASH_OPCODE, temp);
+
+ reg &= ~SPI_CTL_TX_RX_CNT_MASK;
+ reg |= op->tx_cnt | SPI_CTL_START;
+ spiflash_write_reg(priv, SPI_FLASH_CTL, reg);
+
+ spiflash_wait_complete(priv, 20);
+
+ mutex_unlock(&priv->lock);
+
+ return 0;
+}
+
+static int
+spiflash_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
+ u_char *buf)
+{
+ struct spiflash_priv *priv = to_spiflash(mtd);
+
+ if (!len)
+ return 0;
+
+ if (from + len > mtd->size)
+ return -EINVAL;
+
+ *retlen = len;
+
+ mutex_lock(&priv->lock);
+
+ memcpy_fromio(buf, priv->readaddr + from, len);
+
+ mutex_unlock(&priv->lock);
+
+ return 0;
+}
+
+static int
+spiflash_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
+ const u8 *buf)
+{
+ struct spiflash_priv *priv = to_spiflash(mtd);
+ u32 opcode, bytes_left;
+
+ *retlen = 0;
+
+ if (!len)
+ return 0;
+
+ if (to + len > mtd->size)
+ return -EINVAL;
+
+ bytes_left = len;
+
+ do {
+ u32 read_len, reg, page_offset, spi_data = 0;
+
+ read_len = min(bytes_left, sizeof(u32));
+
+ /* 32-bit writes cannot span across a page boundary
+ * (256 bytes). This types of writes require two page
+ * program operations to handle it correctly. The STM part
+ * will write the overflow data to the beginning of the
+ * current page as opposed to the subsequent page.
+ */
+ page_offset = (to & (STM_PAGE_SIZE - 1)) + read_len;
+
+ if (page_offset > STM_PAGE_SIZE)
+ read_len -= (page_offset - STM_PAGE_SIZE);
+
+ mutex_lock(&priv->lock);
+
+ spiflash_sendcmd(priv, SPI_WRITE_ENABLE, 0);
+ spi_data = 0;
+ switch (read_len) {
+ case 4:
+ spi_data |= buf[3] << 24;
+ /* fall through */
+ case 3:
+ spi_data |= buf[2] << 16;
+ /* fall through */
+ case 2:
+ spi_data |= buf[1] << 8;
+ /* fall through */
+ case 1:
+ spi_data |= buf[0] & 0xff;
+ break;
+ default:
+ break;
+ }
+
+ spiflash_write_reg(priv, SPI_FLASH_DATA, spi_data);
+ opcode = stm_opcodes[SPI_PAGE_PROGRAM].code |
+ (to & 0x00ffffff) << 8;
+ spiflash_write_reg(priv, SPI_FLASH_OPCODE, opcode);
+
+ reg = spiflash_read_reg(priv, SPI_FLASH_CTL);
+ reg &= ~SPI_CTL_TX_RX_CNT_MASK;
+ reg |= (read_len + 4) | SPI_CTL_START;
+ spiflash_write_reg(priv, SPI_FLASH_CTL, reg);
+
+ spiflash_wait_complete(priv, 1);
+
+ mutex_unlock(&priv->lock);
+
+ bytes_left -= read_len;
+ to += read_len;
+ buf += read_len;
+
+ *retlen += read_len;
+ } while (bytes_left != 0);
+
+ return 0;
+}
+
+#if defined CONFIG_MTD_REDBOOT_PARTS || CONFIG_MTD_MYLOADER_PARTS
+static const char * const part_probe_types[] = {
+ "cmdlinepart", "RedBoot", "MyLoader", NULL
+};
+#endif
+
+static int
+spiflash_probe(struct platform_device *pdev)
+{
+ struct spiflash_priv *priv;
+ struct mtd_info *mtd;
+ struct resource *res;
+ int index;
+ int result = 0;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ mutex_init(&priv->lock);
+ mtd = &priv->mtd;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ priv->mmraddr = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(priv->mmraddr)) {
+ dev_warn(&pdev->dev, "failed to map flash MMR\n");
+ return PTR_ERR(priv->mmraddr);
+ }
+
+ index = spiflash_probe_chip(pdev, priv);
+ if (!index) {
+ dev_warn(&pdev->dev, "found no flash device\n");
+ return -ENODEV;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ priv->readaddr = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(priv->readaddr)) {
+ dev_warn(&pdev->dev, "failed to map flash read mem\n");
+ return PTR_ERR(priv->readaddr);
+ }
+
+ platform_set_drvdata(pdev, priv);
+ mtd->name = "spiflash";
+ mtd->type = MTD_NORFLASH;
+ mtd->flags = (MTD_CAP_NORFLASH|MTD_WRITEABLE);
+ mtd->size = flashconfig_tbl[index].byte_cnt;
+ mtd->erasesize = flashconfig_tbl[index].sector_size;
+ mtd->writesize = 1;
+ mtd->numeraseregions = 0;
+ mtd->eraseregions = NULL;
+ mtd->_erase = spiflash_erase;
+ mtd->_read = spiflash_read;
+ mtd->_write = spiflash_write;
+ mtd->owner = THIS_MODULE;
+
+ dev_info(&pdev->dev, "%lld Kbytes flash detected\n", mtd->size >> 10);
+
+#if defined CONFIG_MTD_REDBOOT_PARTS || CONFIG_MTD_MYLOADER_PARTS
+ /* parse redboot partitions */
+
+ result = mtd_device_parse_register(mtd, part_probe_types,
+ NULL, NULL, 0);
+#endif
+
+ return result;
+}
+
+static int
+spiflash_remove(struct platform_device *pdev)
+{
+ struct spiflash_priv *priv = platform_get_drvdata(pdev);
+
+ mtd_device_unregister(&priv->mtd);
+
+ return 0;
+}
+
+static struct platform_driver spiflash_driver = {
+ .driver.name = DRIVER_NAME,
+ .probe = spiflash_probe,
+ .remove = spiflash_remove,
+};
+
+module_platform_driver(spiflash_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("OpenWrt.org");
+MODULE_AUTHOR("Atheros Communications Inc");
+MODULE_DESCRIPTION("MTD driver for SPI Flash on Atheros AR2315+ SOC");
+MODULE_ALIAS("platform:" DRIVER_NAME);
+
--- /dev/null
+++ b/drivers/mtd/devices/ar2315_spiflash.h
@@ -0,0 +1,106 @@
+/*
+ * Atheros AR2315 SPI Flash Memory support header file.
+ *
+ * Copyright (c) 2005, Atheros Communications Inc.
+ * Copyright (C) 2006 FON Technology, SL.
+ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
+ * Copyright (C) 2006-2009 Felix Fietkau <nbd@nbd.name>
+ *
+ * This code is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#ifndef __AR2315_SPIFLASH_H
+#define __AR2315_SPIFLASH_H
+
+#define STM_PAGE_SIZE 256
+
+#define SFI_WRITE_BUFFER_SIZE 4
+#define SFI_FLASH_ADDR_MASK 0x00ffffff
+
+#define STM_8MBIT_SIGNATURE 0x13
+#define STM_M25P80_BYTE_COUNT 1048576
+#define STM_M25P80_SECTOR_COUNT 16
+#define STM_M25P80_SECTOR_SIZE 0x10000
+
+#define STM_16MBIT_SIGNATURE 0x14
+#define STM_M25P16_BYTE_COUNT 2097152
+#define STM_M25P16_SECTOR_COUNT 32
+#define STM_M25P16_SECTOR_SIZE 0x10000
+
+#define STM_32MBIT_SIGNATURE 0x15
+#define STM_M25P32_BYTE_COUNT 4194304
+#define STM_M25P32_SECTOR_COUNT 64
+#define STM_M25P32_SECTOR_SIZE 0x10000
+
+#define STM_64MBIT_SIGNATURE 0x16
+#define STM_M25P64_BYTE_COUNT 8388608
+#define STM_M25P64_SECTOR_COUNT 128
+#define STM_M25P64_SECTOR_SIZE 0x10000
+
+#define STM_128MBIT_SIGNATURE 0x17
+#define STM_M25P128_BYTE_COUNT 16777216
+#define STM_M25P128_SECTOR_COUNT 256
+#define STM_M25P128_SECTOR_SIZE 0x10000
+
+#define STM_1MB_BYTE_COUNT STM_M25P80_BYTE_COUNT
+#define STM_1MB_SECTOR_COUNT STM_M25P80_SECTOR_COUNT
+#define STM_1MB_SECTOR_SIZE STM_M25P80_SECTOR_SIZE
+#define STM_2MB_BYTE_COUNT STM_M25P16_BYTE_COUNT
+#define STM_2MB_SECTOR_COUNT STM_M25P16_SECTOR_COUNT
+#define STM_2MB_SECTOR_SIZE STM_M25P16_SECTOR_SIZE
+#define STM_4MB_BYTE_COUNT STM_M25P32_BYTE_COUNT
+#define STM_4MB_SECTOR_COUNT STM_M25P32_SECTOR_COUNT
+#define STM_4MB_SECTOR_SIZE STM_M25P32_SECTOR_SIZE
+#define STM_8MB_BYTE_COUNT STM_M25P64_BYTE_COUNT
+#define STM_8MB_SECTOR_COUNT STM_M25P64_SECTOR_COUNT
+#define STM_8MB_SECTOR_SIZE STM_M25P64_SECTOR_SIZE
+#define STM_16MB_BYTE_COUNT STM_M25P128_BYTE_COUNT
+#define STM_16MB_SECTOR_COUNT STM_M25P128_SECTOR_COUNT
+#define STM_16MB_SECTOR_SIZE STM_M25P128_SECTOR_SIZE
+
+/*
+ * ST Microelectronics Opcodes for Serial Flash
+ */
+
+#define STM_OP_WR_ENABLE 0x06 /* Write Enable */
+#define STM_OP_WR_DISABLE 0x04 /* Write Disable */
+#define STM_OP_RD_STATUS 0x05 /* Read Status */
+#define STM_OP_WR_STATUS 0x01 /* Write Status */
+#define STM_OP_RD_DATA 0x03 /* Read Data */
+#define STM_OP_FAST_RD_DATA 0x0b /* Fast Read Data */
+#define STM_OP_PAGE_PGRM 0x02 /* Page Program */
+#define STM_OP_SECTOR_ERASE 0xd8 /* Sector Erase */
+#define STM_OP_BULK_ERASE 0xc7 /* Bulk Erase */
+#define STM_OP_DEEP_PWRDOWN 0xb9 /* Deep Power-Down Mode */
+#define STM_OP_RD_SIG 0xab /* Read Electronic Signature */
+
+#define STM_STATUS_WIP 0x01 /* Write-In-Progress */
+#define STM_STATUS_WEL 0x02 /* Write Enable Latch */
+#define STM_STATUS_BP0 0x04 /* Block Protect 0 */
+#define STM_STATUS_BP1 0x08 /* Block Protect 1 */
+#define STM_STATUS_BP2 0x10 /* Block Protect 2 */
+#define STM_STATUS_SRWD 0x80 /* Status Register Write Disable */
+
+/*
+ * SPI Flash Interface Registers
+ */
+
+#define SPI_FLASH_CTL 0x00
+#define SPI_FLASH_OPCODE 0x04
+#define SPI_FLASH_DATA 0x08
+
+#define SPI_CTL_START 0x00000100
+#define SPI_CTL_BUSY 0x00010000
+#define SPI_CTL_TXCNT_MASK 0x0000000f
+#define SPI_CTL_RXCNT_MASK 0x000000f0
+#define SPI_CTL_TX_RX_CNT_MASK 0x000000ff
+#define SPI_CTL_SIZE_MASK 0x00060000
+
+#define SPI_CTL_CLK_SEL_MASK 0x03000000
+#define SPI_OPCODE_MASK 0x000000ff
+
+#define SPI_STATUS_WIP STM_STATUS_WIP
+
+#endif
--- a/arch/mips/ath25/ar2315.c
+++ b/arch/mips/ath25/ar2315.c
@@ -218,6 +218,28 @@ static struct platform_device ar2315_gpi
.num_resources = ARRAY_SIZE(ar2315_gpio_res)
};
+static struct resource ar2315_spiflash_res[] = {
+ {
+ .name = "spiflash_read",
+ .flags = IORESOURCE_MEM,
+ .start = AR2315_SPI_READ_BASE,
+ .end = AR2315_SPI_READ_BASE + AR2315_SPI_READ_SIZE - 1,
+ },
+ {
+ .name = "spiflash_mmr",
+ .flags = IORESOURCE_MEM,
+ .start = AR2315_SPI_MMR_BASE,
+ .end = AR2315_SPI_MMR_BASE + AR2315_SPI_MMR_SIZE - 1,
+ },
+};
+
+static struct platform_device ar2315_spiflash = {
+ .id = 0,
+ .name = "ar2315-spiflash",
+ .resource = ar2315_spiflash_res,
+ .num_resources = ARRAY_SIZE(ar2315_spiflash_res)
+};
+
void __init ar2315_init_devices(void)
{
/* Find board configuration */
@@ -228,6 +250,8 @@ void __init ar2315_init_devices(void)
ar2315_gpio_res[1].end = ar2315_gpio_res[1].start;
platform_device_register(&ar2315_gpio);
+ platform_device_register(&ar2315_spiflash);
+
ar2315_eth_data.macaddr = ath25_board.config->enet0_mac;
ath25_add_ethernet(0, AR2315_ENET0_BASE, "eth0_mii",
AR2315_ENET0_MII_BASE, AR2315_IRQ_ENET0,

View File

@ -0,0 +1,277 @@
--- /dev/null
+++ b/drivers/watchdog/ar2315-wtd.c
@@ -0,0 +1,209 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (C) 2008 John Crispin <blogic@openwrt.org>
+ * Based on EP93xx and ifxmips wdt driver
+ */
+
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/types.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/fs.h>
+#include <linux/ioport.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+
+#define DRIVER_NAME "ar2315-wdt"
+
+#define CLOCK_RATE 40000000
+#define HEARTBEAT(x) (x < 1 || x > 90 ? 20 : x)
+
+#define WDT_REG_TIMER 0x00
+#define WDT_REG_CTRL 0x04
+
+#define WDT_CTRL_ACT_NONE 0x00000000 /* No action */
+#define WDT_CTRL_ACT_NMI 0x00000001 /* NMI on watchdog */
+#define WDT_CTRL_ACT_RESET 0x00000002 /* reset on watchdog */
+
+static int wdt_timeout = 20;
+static int started;
+static int in_use;
+static void __iomem *wdt_base;
+
+static inline void ar2315_wdt_wr(unsigned reg, u32 val)
+{
+ iowrite32(val, wdt_base + reg);
+}
+
+static void
+ar2315_wdt_enable(void)
+{
+ ar2315_wdt_wr(WDT_REG_TIMER, wdt_timeout * CLOCK_RATE);
+}
+
+static ssize_t
+ar2315_wdt_write(struct file *file, const char __user *data, size_t len,
+ loff_t *ppos)
+{
+ if (len)
+ ar2315_wdt_enable();
+ return len;
+}
+
+static int
+ar2315_wdt_open(struct inode *inode, struct file *file)
+{
+ if (in_use)
+ return -EBUSY;
+ ar2315_wdt_enable();
+ in_use = 1;
+ started = 1;
+ return nonseekable_open(inode, file);
+}
+
+static int
+ar2315_wdt_release(struct inode *inode, struct file *file)
+{
+ in_use = 0;
+ return 0;
+}
+
+static irqreturn_t
+ar2315_wdt_interrupt(int irq, void *dev)
+{
+ struct platform_device *pdev = (struct platform_device *)dev;
+
+ if (started) {
+ dev_crit(&pdev->dev, "watchdog expired, rebooting system\n");
+ emergency_restart();
+ } else {
+ ar2315_wdt_wr(WDT_REG_CTRL, 0);
+ ar2315_wdt_wr(WDT_REG_TIMER, 0);
+ }
+ return IRQ_HANDLED;
+}
+
+static struct watchdog_info ident = {
+ .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
+ .identity = "ar2315 Watchdog",
+};
+
+static long
+ar2315_wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ int new_wdt_timeout;
+ int ret = -ENOIOCTLCMD;
+
+ switch (cmd) {
+ case WDIOC_GETSUPPORT:
+ ret = copy_to_user((void __user *)arg, &ident, sizeof(ident)) ?
+ -EFAULT : 0;
+ break;
+ case WDIOC_KEEPALIVE:
+ ar2315_wdt_enable();
+ ret = 0;
+ break;
+ case WDIOC_SETTIMEOUT:
+ ret = get_user(new_wdt_timeout, (int __user *)arg);
+ if (ret)
+ break;
+ wdt_timeout = HEARTBEAT(new_wdt_timeout);
+ ar2315_wdt_enable();
+ break;
+ case WDIOC_GETTIMEOUT:
+ ret = put_user(wdt_timeout, (int __user *)arg);
+ break;
+ }
+ return ret;
+}
+
+static const struct file_operations ar2315_wdt_fops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .write = ar2315_wdt_write,
+ .unlocked_ioctl = ar2315_wdt_ioctl,
+ .open = ar2315_wdt_open,
+ .release = ar2315_wdt_release,
+};
+
+static struct miscdevice ar2315_wdt_miscdev = {
+ .minor = WATCHDOG_MINOR,
+ .name = "watchdog",
+ .fops = &ar2315_wdt_fops,
+};
+
+static int
+ar2315_wdt_probe(struct platform_device *dev)
+{
+ struct resource *mem_res, *irq_res;
+ int ret = 0;
+
+ if (wdt_base)
+ return -EBUSY;
+
+ irq_res = platform_get_resource(dev, IORESOURCE_IRQ, 0);
+ if (!irq_res) {
+ dev_err(&dev->dev, "no IRQ resource\n");
+ return -ENOENT;
+ }
+
+ mem_res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ wdt_base = devm_ioremap_resource(&dev->dev, mem_res);
+ if (IS_ERR(wdt_base))
+ return PTR_ERR(wdt_base);
+
+ ret = devm_request_irq(&dev->dev, irq_res->start, ar2315_wdt_interrupt,
+ 0, DRIVER_NAME, dev);
+ if (ret) {
+ dev_err(&dev->dev, "failed to register inetrrupt\n");
+ goto out;
+ }
+
+ ret = misc_register(&ar2315_wdt_miscdev);
+ if (ret)
+ dev_err(&dev->dev, "failed to register miscdev\n");
+
+out:
+ return ret;
+}
+
+static int
+ar2315_wdt_remove(struct platform_device *dev)
+{
+ misc_deregister(&ar2315_wdt_miscdev);
+ return 0;
+}
+
+static struct platform_driver ar2315_wdt_driver = {
+ .probe = ar2315_wdt_probe,
+ .remove = ar2315_wdt_remove,
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+module_platform_driver(ar2315_wdt_driver);
+
+MODULE_DESCRIPTION("Atheros AR2315 hardware watchdog driver");
+MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRIVER_NAME);
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -1873,6 +1873,13 @@ config PIC32_DMT
To compile this driver as a loadable module, choose M here.
The module will be called pic32-dmt.
+config AR2315_WDT
+ tristate "Atheros AR2315+ WiSoCs Watchdog Timer"
+ depends on ATH25
+ help
+ Hardware driver for the built-in watchdog timer on the Atheros
+ AR2315/AR2316 WiSoCs.
+
# PARISC Architecture
# POWERPC Architecture
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -164,6 +164,7 @@ obj-$(CONFIG_WDT_MTX1) += mtx-1_wdt.o
obj-$(CONFIG_PNX833X_WDT) += pnx833x_wdt.o
obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o
obj-$(CONFIG_AR7_WDT) += ar7_wdt.o
+obj-$(CONFIG_AR2315_WDT) += ar2315-wtd.o
obj-$(CONFIG_TXX9_WDT) += txx9wdt.o
obj-$(CONFIG_OCTEON_WDT) += octeon-wdt.o
octeon-wdt-y := octeon-wdt-main.o octeon-wdt-nmi.o
--- a/arch/mips/ath25/ar2315.c
+++ b/arch/mips/ath25/ar2315.c
@@ -218,6 +218,24 @@ static struct platform_device ar2315_gpi
.num_resources = ARRAY_SIZE(ar2315_gpio_res)
};
+static struct resource ar2315_wdt_res[] = {
+ {
+ .flags = IORESOURCE_MEM,
+ .start = AR2315_RST_BASE + AR2315_WDT_TIMER,
+ .end = AR2315_RST_BASE + AR2315_WDT_TIMER + 8 - 1,
+ },
+ {
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device ar2315_wdt = {
+ .id = 0,
+ .name = "ar2315-wdt",
+ .resource = ar2315_wdt_res,
+ .num_resources = ARRAY_SIZE(ar2315_wdt_res)
+};
+
static struct resource ar2315_spiflash_res[] = {
{
.name = "spiflash_read",
@@ -250,6 +268,11 @@ void __init ar2315_init_devices(void)
ar2315_gpio_res[1].end = ar2315_gpio_res[1].start;
platform_device_register(&ar2315_gpio);
+ ar2315_wdt_res[1].start = irq_create_mapping(ar2315_misc_irq_domain,
+ AR2315_MISC_IRQ_WATCHDOG);
+ ar2315_wdt_res[1].end = ar2315_wdt_res[1].start;
+ platform_device_register(&ar2315_wdt);
+
platform_device_register(&ar2315_spiflash);
ar2315_eth_data.macaddr = ath25_board.config->enet0_mac;

View File

@ -0,0 +1,60 @@
--- a/drivers/mtd/parsers/redboot.c
+++ b/drivers/mtd/parsers/redboot.c
@@ -16,6 +16,8 @@
#include <linux/mtd/partitions.h>
#include <linux/module.h>
+#define BOARD_CONFIG_PART "boardconfig"
+
struct fis_image_desc {
unsigned char name[16]; // Null terminated name
uint32_t flash_base; // Address within FLASH of image
@@ -72,6 +74,7 @@ static int parse_redboot_partitions(stru
const struct mtd_partition **pparts,
struct mtd_part_parser_data *data)
{
+ unsigned long max_offset = 0;
int nrparts = 0;
struct fis_image_desc *buf;
struct mtd_partition *parts;
@@ -239,14 +242,15 @@ static int parse_redboot_partitions(stru
}
}
#endif
- parts = kzalloc(sizeof(*parts)*nrparts + nulllen + namelen, GFP_KERNEL);
+ parts = kzalloc(sizeof(*parts) * (nrparts + 1) + nulllen + namelen +
+ sizeof(BOARD_CONFIG_PART), GFP_KERNEL);
if (!parts) {
ret = -ENOMEM;
goto out;
}
- nullname = (char *)&parts[nrparts];
+ nullname = (char *)&parts[nrparts + 1];
#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED
if (nulllen > 0) {
strcpy(nullname, nullstring);
@@ -265,6 +269,8 @@ static int parse_redboot_partitions(stru
}
#endif
for ( ; i<nrparts; i++) {
+ if (max_offset < buf[i].flash_base + buf[i].size)
+ max_offset = buf[i].flash_base + buf[i].size;
parts[i].size = fl->img->size;
parts[i].offset = fl->img->flash_base;
parts[i].name = names;
@@ -298,6 +304,13 @@ static int parse_redboot_partitions(stru
fl = fl->next;
kfree(tmp_fl);
}
+ if (master->size - max_offset >= master->erasesize) {
+ parts[nrparts].size = master->size - max_offset;
+ parts[nrparts].offset = max_offset;
+ parts[nrparts].name = names;
+ strcpy(names, BOARD_CONFIG_PART);
+ nrparts++;
+ }
ret = nrparts;
*pparts = parts;
out:

View File

@ -1,6 +1,6 @@
--- a/drivers/mtd/parsers/redboot.c
+++ b/drivers/mtd/parsers/redboot.c
@@ -90,12 +90,18 @@ static int parse_redboot_partitions(stru
@@ -93,12 +93,18 @@ static int parse_redboot_partitions(stru
parse_redboot_of(master);
@ -19,7 +19,7 @@
return -EIO;
}
offset -= master->erasesize;
@@ -108,10 +114,6 @@ static int parse_redboot_partitions(stru
@@ -111,10 +117,6 @@ static int parse_redboot_partitions(stru
goto nogood;
}
}
@ -30,12 +30,12 @@
printk(KERN_NOTICE "Searching for RedBoot partition table in %s at offset 0x%lx\n",
master->name, offset);
@@ -184,6 +186,11 @@ static int parse_redboot_partitions(stru
@@ -187,6 +189,11 @@ static int parse_redboot_partitions(stru
}
if (i == numslots) {
/* Didn't find it */
+ if (offset + master->erasesize < master->size) {
+ /* not at the end of the flash yet, maybe next block :) */
+ /* not at the end of the flash yet, maybe next block */
+ directory++;
+ goto restart;
+ }

View File

@ -0,0 +1,72 @@
--- a/drivers/mtd/parsers/redboot.c
+++ b/drivers/mtd/parsers/redboot.c
@@ -70,6 +70,22 @@ static void parse_redboot_of(struct mtd_
directory = dirblock;
}
+static uint32_t mtd_get_offset_erasesize(struct mtd_info *mtd, uint64_t offset)
+{
+ struct mtd_erase_region_info *regions = mtd->eraseregions;
+ int i;
+
+ for (i = 0; i < mtd->numeraseregions; i++) {
+ if (regions[i].offset +
+ regions[i].numblocks * regions[i].erasesize <= offset)
+ continue;
+
+ return regions[i].erasesize;
+ }
+
+ return mtd->erasesize;
+}
+
static int parse_redboot_partitions(struct mtd_info *master,
const struct mtd_partition **pparts,
struct mtd_part_parser_data *data)
@@ -86,6 +102,7 @@ static int parse_redboot_partitions(stru
int namelen = 0;
int nulllen = 0;
int numslots;
+ int first_slot;
unsigned long offset;
#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED
static char nullstring[] = "unallocated";
@@ -200,7 +217,10 @@ static int parse_redboot_partitions(stru
goto out;
}
- for (i = 0; i < numslots; i++) {
+ first_slot = (buf[i].flash_base & (master->erasesize - 1)) /
+ sizeof(struct fis_image_desc);
+
+ for (i = first_slot; i < first_slot + numslots; i++) {
struct fis_list *new_fl, **prev;
if (buf[i].name[0] == 0xff) {
@@ -276,12 +296,13 @@ static int parse_redboot_partitions(stru
}
#endif
for ( ; i<nrparts; i++) {
- if (max_offset < buf[i].flash_base + buf[i].size)
- max_offset = buf[i].flash_base + buf[i].size;
parts[i].size = fl->img->size;
parts[i].offset = fl->img->flash_base;
parts[i].name = names;
+ if (max_offset < parts[i].offset + parts[i].size)
+ max_offset = parts[i].offset + parts[i].size;
+
strcpy(names, fl->img->name);
#ifdef CONFIG_MTD_REDBOOT_PARTS_READONLY
if (!memcmp(names, "RedBoot", 8) ||
@@ -311,7 +332,9 @@ static int parse_redboot_partitions(stru
fl = fl->next;
kfree(tmp_fl);
}
- if (master->size - max_offset >= master->erasesize) {
+
+ if (master->size - max_offset >=
+ mtd_get_offset_erasesize(master, max_offset)) {
parts[nrparts].size = master->size - max_offset;
parts[nrparts].offset = max_offset;
parts[nrparts].name = names;

View File

@ -0,0 +1,71 @@
--- a/arch/mips/ath25/Makefile
+++ b/arch/mips/ath25/Makefile
@@ -8,7 +8,7 @@
# Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org>
#
-obj-y += board.o prom.o devices.o
+obj-y += board.o prom.o devices.o reset.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
--- /dev/null
+++ b/arch/mips/ath25/reset.c
@@ -0,0 +1,57 @@
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <ath25_platform.h>
+#include "devices.h"
+
+static int __init
+ar231x_init_reset(void)
+{
+ struct platform_device *pdev;
+ struct gpio_keys_platform_data pdata;
+ struct gpio_keys_button *p;
+ int err;
+
+ if (ath25_board.config->reset_config_gpio == 0xffff)
+ return -ENODEV;
+
+ p = kzalloc(sizeof(*p), GFP_KERNEL);
+ if (!p)
+ goto err;
+
+ p->desc = "reset";
+ p->type = EV_KEY;
+ p->code = KEY_RESTART;
+ p->debounce_interval = 60;
+ p->gpio = ath25_board.config->reset_config_gpio;
+
+ memset(&pdata, 0, sizeof(pdata));
+ pdata.poll_interval = 20;
+ pdata.buttons = p;
+ pdata.nbuttons = 1;
+
+ pdev = platform_device_alloc("gpio-keys-polled", 0);
+ if (!pdev)
+ goto err_free;
+
+ err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+ if (err)
+ goto err_put_pdev;
+
+ err = platform_device_add(pdev);
+ if (err)
+ goto err_put_pdev;
+
+ return 0;
+
+err_put_pdev:
+ platform_device_put(pdev);
+err_free:
+ kfree(p);
+err:
+ return -ENOMEM;
+}
+
+device_initcall(ar231x_init_reset);

View File

@ -0,0 +1,111 @@
--- a/drivers/net/ethernet/atheros/ar231x/ar231x.c
+++ b/drivers/net/ethernet/atheros/ar231x/ar231x.c
@@ -135,6 +135,7 @@ static int ar231x_mdiobus_write(struct m
static int ar231x_mdiobus_reset(struct mii_bus *bus);
static int ar231x_mdiobus_probe(struct net_device *dev);
static void ar231x_adjust_link(struct net_device *dev);
+static bool no_phy;
#ifndef ERR
#define ERR(fmt, args...) printk("%s: " fmt, __func__, ##args)
@@ -166,6 +167,32 @@ static const struct net_device_ops ar231
#endif
};
+static int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id)
+{
+ int phy_reg;
+
+ /**
+ * Grab the bits from PHYIR1, and put them
+ * in the upper half.
+ */
+ phy_reg = mdiobus_read(bus, addr, MII_PHYSID1);
+
+ if (phy_reg < 0)
+ return -EIO;
+
+ *phy_id = (phy_reg & 0xffff) << 16;
+
+ /* Grab the bits from PHYIR2, and put them in the lower half */
+ phy_reg = mdiobus_read(bus, addr, MII_PHYSID2);
+
+ if (phy_reg < 0)
+ return -EIO;
+
+ *phy_id |= (phy_reg & 0xffff);
+
+ return 0;
+}
+
static int ar231x_probe(struct platform_device *pdev)
{
struct net_device *dev;
@@ -273,6 +300,24 @@ static int ar231x_probe(struct platform_
mdiobus_register(sp->mii_bus);
+ /**
+ * Workaround for Micrel switch, which is only available on
+ * one PHY and cannot be configured through MDIO.
+ */
+ if (!no_phy) {
+ u32 phy_id = 0;
+
+ get_phy_id(sp->mii_bus, 1, &phy_id);
+ if (phy_id == 0x00221450)
+ no_phy = true;
+ }
+ if (no_phy) {
+ sp->link = 1;
+ netif_carrier_on(dev);
+ return 0;
+ }
+ no_phy = true;
+
if (ar231x_mdiobus_probe(dev) != 0) {
printk(KERN_ERR "%s: mdiobus_probe failed\n", dev->name);
rx_tasklet_cleanup(dev);
@@ -326,8 +371,10 @@ static int ar231x_remove(struct platform
rx_tasklet_cleanup(dev);
ar231x_init_cleanup(dev);
unregister_netdev(dev);
- mdiobus_unregister(sp->mii_bus);
- mdiobus_free(sp->mii_bus);
+ if (sp->mii_bus) {
+ mdiobus_unregister(sp->mii_bus);
+ mdiobus_free(sp->mii_bus);
+ }
kfree(dev);
return 0;
}
@@ -870,7 +917,8 @@ static int ar231x_open(struct net_device
sp->eth_regs->mac_control |= MAC_CONTROL_RE;
- phy_start(sp->phy_dev);
+ if (sp->phy_dev)
+ phy_start(sp->phy_dev);
return 0;
}
@@ -951,7 +999,8 @@ static int ar231x_close(struct net_devic
#endif
- phy_stop(sp->phy_dev);
+ if (sp->phy_dev)
+ phy_stop(sp->phy_dev);
return 0;
}
@@ -995,6 +1044,9 @@ static int ar231x_ioctl(struct net_devic
{
struct ar231x_private *sp = netdev_priv(dev);
+ if (!sp->phy_dev)
+ return -ENODEV;
+
switch (cmd) {
case SIOCGMIIPHY:
case SIOCGMIIREG:

View File

@ -0,0 +1,116 @@
--- a/arch/mips/ath25/ar2315.c
+++ b/arch/mips/ath25/ar2315.c
@@ -24,6 +24,7 @@
#include <linux/reboot.h>
#include <linux/delay.h>
#include <linux/gpio.h>
+#include <linux/leds.h>
#include <asm/bootinfo.h>
#include <asm/reboot.h>
#include <asm/time.h>
@@ -258,6 +259,50 @@ static struct platform_device ar2315_spi
.num_resources = ARRAY_SIZE(ar2315_spiflash_res)
};
+#ifdef CONFIG_LEDS_GPIO
+static struct gpio_led ar2315_leds[6];
+static struct gpio_led_platform_data ar2315_led_data = {
+ .leds = (void *)ar2315_leds,
+};
+
+static struct platform_device ar2315_gpio_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = (void *)&ar2315_led_data,
+ }
+};
+
+static void __init ar2315_init_gpio_leds(void)
+{
+ static char led_names[6][6];
+ int i, led = 0;
+
+ ar2315_led_data.num_leds = 0;
+ for (i = 1; i < 8; i++) {
+ if ((i == AR2315_RESET_GPIO) ||
+ (i == ath25_board.config->reset_config_gpio))
+ continue;
+
+ if (i == ath25_board.config->sys_led_gpio)
+ strcpy(led_names[led], "wlan");
+ else
+ sprintf(led_names[led], "gpio%d", i);
+
+ ar2315_leds[led].name = led_names[led];
+ ar2315_leds[led].gpio = i;
+ ar2315_leds[led].active_low = 0;
+ led++;
+ }
+ ar2315_led_data.num_leds = led;
+ platform_device_register(&ar2315_gpio_leds);
+}
+#else
+static inline void ar2315_init_gpio_leds(void)
+{
+}
+#endif
+
void __init ar2315_init_devices(void)
{
/* Find board configuration */
@@ -268,6 +313,8 @@ void __init ar2315_init_devices(void)
ar2315_gpio_res[1].end = ar2315_gpio_res[1].start;
platform_device_register(&ar2315_gpio);
+ ar2315_init_gpio_leds();
+
ar2315_wdt_res[1].start = irq_create_mapping(ar2315_misc_irq_domain,
AR2315_MISC_IRQ_WATCHDOG);
ar2315_wdt_res[1].end = ar2315_wdt_res[1].start;
--- a/arch/mips/ath25/ar5312.c
+++ b/arch/mips/ath25/ar5312.c
@@ -24,6 +24,7 @@
#include <linux/mtd/physmap.h>
#include <linux/reboot.h>
#include <linux/gpio.h>
+#include <linux/leds.h>
#include <asm/bootinfo.h>
#include <asm/reboot.h>
#include <asm/time.h>
@@ -229,6 +230,23 @@ static struct platform_device ar5312_gpi
.num_resources = ARRAY_SIZE(ar5312_gpio_res),
};
+#ifdef CONFIG_LEDS_GPIO
+static struct gpio_led ar5312_leds[] = {
+ { .name = "wlan", .gpio = 0, .active_low = 1, },
+};
+
+static const struct gpio_led_platform_data ar5312_led_data = {
+ .num_leds = ARRAY_SIZE(ar5312_leds),
+ .leds = (void *)ar5312_leds,
+};
+
+static struct platform_device ar5312_gpio_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev.platform_data = (void *)&ar5312_led_data,
+};
+#endif
+
static void __init ar5312_flash_init(void)
{
void __iomem *flashctl_base;
@@ -299,6 +317,11 @@ void __init ar5312_init_devices(void)
platform_device_register(&ar5312_gpio);
+#ifdef CONFIG_LEDS_GPIO
+ ar5312_leds[0].gpio = config->sys_led_gpio;
+ platform_device_register(&ar5312_gpio_leds);
+#endif
+
/* Fix up MAC addresses if necessary */
if (is_broadcast_ether_addr(config->enet0_mac))
ether_addr_copy(config->enet0_mac, config->enet1_mac);

View File

@ -0,0 +1,23 @@
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -95,6 +95,10 @@ config IP17XX_PHY
tristate "Driver for IC+ IP17xx switches"
select SWCONFIG
+config MVSWITCH_PHY
+ tristate "Driver for Marvell 88E6060 switches"
+ select ETHERNET_PACKET_MANGLE
+
config PSB6970_PHY
tristate "Lantiq XWAY Tantos (PSB6970) Ethernet switch"
select SWCONFIG
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_ADM6996_PHY) += adm6996.o
obj-$(CONFIG_AR8216_PHY) += ar8216.o ar8327.o
obj-$(CONFIG_SWCONFIG_B53) += b53/
obj-$(CONFIG_IP17XX_PHY) += ip17xx.o
+obj-$(CONFIG_MVSWITCH_PHY) += mvswitch.o
obj-$(CONFIG_PSB6970_PHY) += psb6970.o
obj-$(CONFIG_RTL8306_PHY) += rtl8306.o
obj-$(CONFIG_RTL8366_SMI) += rtl8366_smi.o

View File

@ -0,0 +1,23 @@
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -284,6 +284,10 @@ config IP17XX_PHY
tristate "Driver for IC+ IP17xx switches"
select SWCONFIG
+config MVSWITCH_PHY
+ tristate "Driver for Marvell 88E6060 switches"
+ select ETHERNET_PACKET_MANGLE
+
config PSB6970_PHY
tristate "Lantiq XWAY Tantos (PSB6970) Ethernet switch"
select SWCONFIG
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_ADM6996_PHY) += adm6996.o
obj-$(CONFIG_AR8216_PHY) += ar8216.o ar8327.o
obj-$(CONFIG_SWCONFIG_B53) += b53/
obj-$(CONFIG_IP17XX_PHY) += ip17xx.o
+obj-$(CONFIG_MVSWITCH_PHY) += mvswitch.o
obj-$(CONFIG_PSB6970_PHY) += psb6970.o
obj-$(CONFIG_RTL8306_PHY) += rtl8306.o
obj-$(CONFIG_RTL8366_SMI) += rtl8366_smi.o

View File

@ -1,251 +0,0 @@
CONFIG_AG71XX=y
# CONFIG_AG71XX_DEBUG is not set
CONFIG_AG71XX_DEBUG_FS=y
CONFIG_AR8216_PHY=y
CONFIG_AR8216_PHY_LEDS=y
CONFIG_ARCH_32BIT_OFF_T=y
CONFIG_ARCH_CLOCKSOURCE_DATA=y
CONFIG_ARCH_HAS_DMA_COHERENT_TO_PFN=y
CONFIG_ARCH_HAS_DMA_PREP_COHERENT=y
CONFIG_ARCH_HAS_DMA_WRITE_COMBINE=y
CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
CONFIG_ARCH_HAS_RESET_CONTROLLER=y
CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE=y
CONFIG_ARCH_HAS_UNCACHED_SEGMENT=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_MMAP_RND_BITS_MAX=15
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
CONFIG_ARCH_SUPPORTS_UPROBES=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_ARCH_USE_BUILTIN_BSWAP=y
CONFIG_ARCH_USE_MEMREMAP_PROT=y
CONFIG_ARCH_USE_QUEUED_RWLOCKS=y
CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y
CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT=y
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
CONFIG_AT803X_PHY=y
CONFIG_ATH79=y
CONFIG_ATH79_WDT=y
CONFIG_BLK_MQ_PCI=y
CONFIG_CEVT_R4K=y
CONFIG_CLKDEV_LOOKUP=y
CONFIG_CLONE_BACKWARDS=y
CONFIG_CMDLINE="rootfstype=squashfs,jffs2"
CONFIG_CMDLINE_BOOL=y
# CONFIG_CMDLINE_OVERRIDE is not set
CONFIG_COMMON_CLK=y
# CONFIG_COMMON_CLK_BOSTON is not set
CONFIG_COMPAT_32BIT_TIME=y
CONFIG_CPU_BIG_ENDIAN=y
CONFIG_CPU_GENERIC_DUMP_TLB=y
CONFIG_CPU_HAS_LOAD_STORE_LR=y
CONFIG_CPU_HAS_PREFETCH=y
CONFIG_CPU_HAS_RIXI=y
CONFIG_CPU_HAS_SYNC=y
CONFIG_CPU_MIPS32=y
CONFIG_CPU_MIPS32_R2=y
CONFIG_CPU_MIPSR2=y
CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
CONFIG_CPU_R4K_CACHE_TLB=y
CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
CONFIG_CPU_SUPPORTS_HIGHMEM=y
CONFIG_CPU_SUPPORTS_MSA=y
CONFIG_CRYPTO_RNG2=y
CONFIG_CSRC_R4K=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NONCOHERENT_CACHE_SYNC=y
CONFIG_DTC=y
CONFIG_EARLY_PRINTK=y
CONFIG_EFI_EARLYCON=y
CONFIG_ETHERNET_PACKET_MANGLE=y
CONFIG_FIXED_PHY=y
CONFIG_FONT_8x16=y
CONFIG_FONT_AUTOSELECT=y
CONFIG_FONT_SUPPORT=y
CONFIG_FW_LOADER_PAGED_BUF=y
CONFIG_GENERIC_ATOMIC64=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CMOS_UPDATE=y
CONFIG_GENERIC_CPU_AUTOPROBE=y
CONFIG_GENERIC_GETTIMEOFDAY=y
CONFIG_GENERIC_IOMAP=y
CONFIG_GENERIC_IRQ_CHIP=y
CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_LIB_ASHLDI3=y
CONFIG_GENERIC_LIB_ASHRDI3=y
CONFIG_GENERIC_LIB_CMPDI2=y
CONFIG_GENERIC_LIB_LSHRDI3=y
CONFIG_GENERIC_LIB_UCMPDI2=y
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_GENERIC_PHY=y
CONFIG_GENERIC_PINCONF=y
CONFIG_GENERIC_PINCTRL_GROUPS=y
CONFIG_GENERIC_PINMUX_FUNCTIONS=y
CONFIG_GENERIC_SCHED_CLOCK=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GPIOLIB=y
CONFIG_GPIOLIB_IRQCHIP=y
CONFIG_GPIO_74X164=y
CONFIG_GPIO_ATH79=y
CONFIG_GPIO_GENERIC=y
# CONFIG_GPIO_LATCH is not set
CONFIG_HANDLE_DOMAIN_IRQ=y
CONFIG_HARDWARE_WATCHPOINTS=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT_MAP=y
CONFIG_HAVE_ARCH_COMPILER_H=y
CONFIG_HAVE_ARCH_JUMP_LABEL=y
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_ASM_MODVERSIONS=y
CONFIG_HAVE_CLK=y
CONFIG_HAVE_CLK_PREPARE=y
CONFIG_HAVE_CONTEXT_TRACKING=y
CONFIG_HAVE_COPY_THREAD_TLS=y
CONFIG_HAVE_C_RECORDMCOUNT=y
CONFIG_HAVE_DEBUG_KMEMLEAK=y
CONFIG_HAVE_DEBUG_STACKOVERFLOW=y
CONFIG_HAVE_DMA_CONTIGUOUS=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FAST_GUP=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_GENERIC_VDSO=y
CONFIG_HAVE_IDE=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y
CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
CONFIG_HAVE_KVM=y
CONFIG_HAVE_LD_DEAD_CODE_DATA_ELIMINATION=y
CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
CONFIG_HAVE_NET_DSA=y
CONFIG_HAVE_OPROFILE=y
CONFIG_HAVE_PCI=y
CONFIG_HAVE_PERF_EVENTS=y
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
CONFIG_HAVE_RSEQ=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
CONFIG_HZ_PERIODIC=y
CONFIG_IMAGE_CMDLINE_HACK=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_IRQCHIP=y
CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_IRQ_MIPS_CPU=y
CONFIG_IRQ_WORK=y
CONFIG_LEDS_GPIO=y
# CONFIG_LEDS_RESET is not set
CONFIG_LIBFDT=y
CONFIG_LOCK_DEBUGGING_SUPPORT=y
CONFIG_MDIO_BITBANG=y
CONFIG_MDIO_BUS=y
CONFIG_MDIO_DEVICE=y
CONFIG_MDIO_GPIO=y
CONFIG_MEMFD_CREATE=y
# CONFIG_MFD_RB4XX_CPLD is not set
CONFIG_MFD_SYSCON=y
CONFIG_MIGRATION=y
CONFIG_MIPS=y
CONFIG_MIPS_ASID_BITS=8
CONFIG_MIPS_ASID_SHIFT=0
CONFIG_MIPS_CLOCK_VSYSCALL=y
# CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND is not set
# CONFIG_MIPS_CMDLINE_DTB_EXTEND is not set
# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set
CONFIG_MIPS_CMDLINE_FROM_DTB=y
# CONFIG_MIPS_ELF_APPENDED_DTB is not set
CONFIG_MIPS_L1_CACHE_SHIFT=5
# CONFIG_MIPS_NO_APPENDED_DTB is not set
CONFIG_MIPS_RAW_APPENDED_DTB=y
CONFIG_MIPS_SPRAM=y
CONFIG_MODULES_USE_ELF_REL=y
CONFIG_MTD_CFI_ADV_OPTIONS=y
CONFIG_MTD_CFI_GEOMETRY=y
# CONFIG_MTD_CFI_I2 is not set
# CONFIG_MTD_CFI_INTELEXT is not set
CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set
# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set
# CONFIG_MTD_NAND_RB91X is not set
CONFIG_MTD_PARSER_CYBERTAN=y
CONFIG_MTD_PHYSMAP=y
CONFIG_MTD_SPI_NOR=y
CONFIG_MTD_SPLIT_ELF_FW=y
CONFIG_MTD_SPLIT_LZMA_FW=y
CONFIG_MTD_SPLIT_SEAMA_FW=y
CONFIG_MTD_SPLIT_TPLINK_FW=y
CONFIG_MTD_SPLIT_UIMAGE_FW=y
CONFIG_MTD_SPLIT_WRGG_FW=y
CONFIG_MTD_VIRT_CONCAT=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_NEED_PER_CPU_KM=y
CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
CONFIG_NVMEM=y
CONFIG_OF=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_EARLY_FLATTREE=y
CONFIG_OF_FLATTREE=y
CONFIG_OF_GPIO=y
CONFIG_OF_IRQ=y
CONFIG_OF_KOBJ=y
CONFIG_OF_MDIO=y
CONFIG_OF_NET=y
CONFIG_PCI=y
CONFIG_PCI_AR71XX=y
CONFIG_PCI_AR724X=y
CONFIG_PCI_DISABLE_COMMON_QUIRKS=y
CONFIG_PCI_DOMAINS=y
CONFIG_PCI_DRIVERS_LEGACY=y
CONFIG_PERF_USE_VMALLOC=y
CONFIG_PGTABLE_LEVELS=2
CONFIG_PHYLIB=y
# CONFIG_PHY_AR7100_USB is not set
# CONFIG_PHY_AR7200_USB is not set
# CONFIG_PHY_ATH79_USB is not set
CONFIG_PINCTRL=y
CONFIG_RATIONAL=y
CONFIG_REGMAP=y
CONFIG_REGMAP_MMIO=y
CONFIG_REGULATOR=y
CONFIG_RESET_ATH79=y
CONFIG_RESET_CONTROLLER=y
CONFIG_SERIAL_8250_NR_UARTS=1
CONFIG_SERIAL_8250_RUNTIME_UARTS=1
CONFIG_SERIAL_AR933X=y
CONFIG_SERIAL_AR933X_CONSOLE=y
CONFIG_SERIAL_AR933X_NR_UARTS=2
CONFIG_SERIAL_MCTRL_GPIO=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SPI=y
CONFIG_SPI_AR934X=y
CONFIG_SPI_ATH79=y
CONFIG_SPI_BITBANG=y
CONFIG_SPI_GPIO=y
CONFIG_SPI_MASTER=y
CONFIG_SPI_MEM=y
# CONFIG_SPI_RB4XX is not set
CONFIG_SRCU=y
CONFIG_SWCONFIG=y
CONFIG_SWCONFIG_LEDS=y
CONFIG_SWPHY=y
CONFIG_SYSCTL_EXCEPTION_TRACE=y
CONFIG_SYS_HAS_CPU_MIPS32_R2=y
CONFIG_SYS_HAS_EARLY_PRINTK=y
CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
CONFIG_SYS_SUPPORTS_MIPS16=y
CONFIG_SYS_SUPPORTS_ZBOOT=y
CONFIG_SYS_SUPPORTS_ZBOOT_UART_PROM=y
CONFIG_TARGET_ISA_REV=2
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TINY_SRCU=y
CONFIG_USB_SUPPORT=y
CONFIG_USE_OF=y

View File

@ -103,6 +103,7 @@ define Device/ubnt-xm
IMAGE_SIZE := 7448k
UBNT_BOARD := XM
UBNT_CHIP := ar7240
UBNT_REVISION := 42.$(UBNT_REVISION)
UBNT_TYPE := XM
UBNT_VERSION := 6.0.0
KERNEL := kernel-bin | append-dtb | relocate-kernel | lzma | uImage lzma

View File

@ -1,192 +0,0 @@
From: Paul Burton <paul.burton@mips.com>
Date: Wed, 9 Oct 2019 23:09:45 +0000
Subject: MIPS: cmdline: Clean up boot_command_line initialization
Our current code to initialize boot_command_line is a mess. Some of this
is due to the addition of too many options over the years, and some of
this is due to workarounds for early_init_dt_scan_chosen() performing
actions specific to options from other architectures that probably
shouldn't be in generic code.
Clean this up by introducing a new bootcmdline_init() function that
simplifies the initialization somewhat. The major changes are:
- Because bootcmdline_init() is a function it can return early in the
CONFIG_CMDLINE_OVERRIDE case.
- We clear boot_command_line rather than inheriting whatever
early_init_dt_scan_chosen() may have left us. This means we no longer
need to set boot_command_line to a space character in an attempt to
prevent early_init_dt_scan_chosen() from copying CONFIG_CMDLINE into
boot_command_line without us knowing about it.
- Indirection via USE_PROM_CMDLINE, USE_DTB_CMDLINE, EXTEND_WITH_PROM &
BUILTIN_EXTEND_WITH_PROM macros is removed; they seemingly served only
to obfuscate the code.
- The logic is cleaner, clearer & commented.
Two minor drawbacks of this approach are:
1) We call of_scan_flat_dt(), which means we scan through the DT again.
The overhead is fairly minimal & shouldn't be noticeable.
2) cmdline_scan_chosen() duplicates a small amount of the logic from
early_init_dt_scan_chosen(). Alternatives might be to allow the
generic FDT code to keep & expose a copy of the arguments taken from
the /chosen node's bootargs property, or to introduce a function like
early_init_dt_scan_chosen() that retrieves them without modification
to handle CONFIG_CMDLINE. Neither of these sounds particularly
cleaner though, and this way we at least keep the extra work in
arch/mips.
Origin: upstream, https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=7784cac697351f0cc0a4bb619594c0c99348c5aa
Signed-off-by: Paul Burton <paul.burton@mips.com>
Cc: linux-mips@vger.kernel.org
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -538,11 +538,88 @@ static void __init check_kernel_sections
}
}
-#define USE_PROM_CMDLINE IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER)
-#define USE_DTB_CMDLINE IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB)
-#define EXTEND_WITH_PROM IS_ENABLED(CONFIG_MIPS_CMDLINE_DTB_EXTEND)
-#define BUILTIN_EXTEND_WITH_PROM \
- IS_ENABLED(CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND)
+static void __init bootcmdline_append(const char *s, size_t max)
+{
+ if (!s[0] || !max)
+ return;
+
+ if (boot_command_line[0])
+ strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
+
+ strlcat(boot_command_line, s, max);
+}
+
+static int __init bootcmdline_scan_chosen(unsigned long node, const char *uname,
+ int depth, void *data)
+{
+ bool *dt_bootargs = data;
+ const char *p;
+ int l;
+
+ if (depth != 1 || !data ||
+ (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0))
+ return 0;
+
+ p = of_get_flat_dt_prop(node, "bootargs", &l);
+ if (p != NULL && l > 0) {
+ bootcmdline_append(p, min(l, COMMAND_LINE_SIZE));
+ *dt_bootargs = true;
+ }
+
+ return 1;
+}
+
+static void __init bootcmdline_init(char **cmdline_p)
+{
+ bool dt_bootargs = false;
+
+ /*
+ * If CMDLINE_OVERRIDE is enabled then initializing the command line is
+ * trivial - we simply use the built-in command line unconditionally &
+ * unmodified.
+ */
+ if (IS_ENABLED(CONFIG_CMDLINE_OVERRIDE)) {
+ strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
+ return;
+ }
+
+ /*
+ * If the user specified a built-in command line &
+ * MIPS_CMDLINE_BUILTIN_EXTEND, then the built-in command line is
+ * prepended to arguments from the bootloader or DT so we'll copy them
+ * to the start of boot_command_line here. Otherwise, empty
+ * boot_command_line to undo anything early_init_dt_scan_chosen() did.
+ */
+ if (IS_ENABLED(CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND))
+ strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
+ else
+ boot_command_line[0] = 0;
+
+ /*
+ * If we're configured to take boot arguments from DT, look for those
+ * now.
+ */
+ if (IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB))
+ of_scan_flat_dt(bootcmdline_scan_chosen, &dt_bootargs);
+
+ /*
+ * If we didn't get any arguments from DT (regardless of whether that's
+ * because we weren't configured to look for them, or because we looked
+ * & found none) then we'll take arguments from the bootloader.
+ * plat_mem_setup() should have filled arcs_cmdline with arguments from
+ * the bootloader.
+ */
+ if (IS_ENABLED(CONFIG_MIPS_CMDLINE_DTB_EXTEND) || !dt_bootargs)
+ bootcmdline_append(arcs_cmdline, COMMAND_LINE_SIZE);
+
+ /*
+ * If the user specified a built-in command line & we didn't already
+ * prepend it, we append it to boot_command_line here.
+ */
+ if (IS_ENABLED(CONFIG_CMDLINE_BOOL) &&
+ !IS_ENABLED(CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND))
+ bootcmdline_append(builtin_cmdline, COMMAND_LINE_SIZE);
+}
/*
* arch_mem_init - initialize memory management subsystem
@@ -570,48 +647,12 @@ static void __init arch_mem_init(char **
{
extern void plat_mem_setup(void);
- /*
- * Initialize boot_command_line to an innocuous but non-empty string in
- * order to prevent early_init_dt_scan_chosen() from copying
- * CONFIG_CMDLINE into it without our knowledge. We handle
- * CONFIG_CMDLINE ourselves below & don't want to duplicate its
- * content because repeating arguments can be problematic.
- */
- strlcpy(boot_command_line, " ", COMMAND_LINE_SIZE);
-
/* call board setup routine */
plat_mem_setup();
memblock_set_bottom_up(true);
-#if defined(CONFIG_CMDLINE_BOOL) && defined(CONFIG_CMDLINE_OVERRIDE)
- strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
-#else
- if ((USE_PROM_CMDLINE && arcs_cmdline[0]) ||
- (USE_DTB_CMDLINE && !boot_command_line[0]))
- strlcpy(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE);
-
- if (EXTEND_WITH_PROM && arcs_cmdline[0]) {
- if (boot_command_line[0])
- strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
- strlcat(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE);
- }
-
-#if defined(CONFIG_CMDLINE_BOOL)
- if (builtin_cmdline[0]) {
- if (boot_command_line[0])
- strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
- strlcat(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
- }
-
- if (BUILTIN_EXTEND_WITH_PROM && arcs_cmdline[0]) {
- if (boot_command_line[0])
- strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
- strlcat(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE);
- }
-#endif
-#endif
+ bootcmdline_init(cmdline_p);
strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
-
*cmdline_p = command_line;
parse_early_param();

View File

@ -1,32 +0,0 @@
From 5f5c9858af167f842ee8df053920b98387a71af1 Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
Date: Mon, 5 Mar 2018 11:41:25 +0100
Subject: [PATCH 02/27] watchdog: ath79: fix maximum timeout
If the userland tries to set a timeout higher than the max_timeout,
then we should fallback to max_timeout.
Signed-off-by: John Crispin <john@phrozen.org>
---
drivers/watchdog/ath79_wdt.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
--- a/drivers/watchdog/ath79_wdt.c
+++ b/drivers/watchdog/ath79_wdt.c
@@ -111,10 +111,14 @@ static inline void ath79_wdt_disable(voi
static int ath79_wdt_set_timeout(int val)
{
- if (val < 1 || val > max_timeout)
+ if (val < 1)
return -EINVAL;
- timeout = val;
+ if (val > max_timeout)
+ timeout = max_timeout;
+ else
+ timeout = val;
+
ath79_wdt_keepalive();
return 0;

View File

@ -1,186 +0,0 @@
From ecbd9c87f073f097d9fe56390353e64e963e866a Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
Date: Tue, 6 Mar 2018 10:03:03 +0100
Subject: [PATCH 03/27] leds: add reset-controller based driver
Signed-off-by: John Crispin <john@phrozen.org>
---
drivers/leds/Kconfig | 11 ++++
drivers/leds/Makefile | 1 +
drivers/leds/leds-reset.c | 137 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 149 insertions(+)
create mode 100644 drivers/leds/leds-reset.c
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -824,6 +824,17 @@ config LEDS_LM36274
Say Y to enable the LM36274 LED driver for TI LMU devices.
This supports the LED device LM36274.
+config LEDS_RESET
+ tristate "LED support for reset-controller API"
+ depends on LEDS_CLASS
+ depends on RESET_CONTROLLER
+ help
+ This option enables support for LEDs connected to pins driven by reset
+ controllers. Yes, DNI actual built HW like that.
+
+ To compile this driver as a module, choose M here: the module
+ will be called leds-reset.
+
comment "LED Triggers"
source "drivers/leds/trigger/Kconfig"
--- /dev/null
+++ b/drivers/leds/leds-reset.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2018 John Crispin <john@phrozen.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/err.h>
+#include <linux/reset.h>
+#include <linux/kernel.h>
+#include <linux/leds.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+
+struct reset_led_data {
+ struct led_classdev cdev;
+ struct reset_control *rst;
+};
+
+static inline struct reset_led_data *
+ cdev_to_reset_led_data(struct led_classdev *led_cdev)
+{
+ return container_of(led_cdev, struct reset_led_data, cdev);
+}
+
+static void reset_led_set(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ struct reset_led_data *led_dat = cdev_to_reset_led_data(led_cdev);
+
+ if (value == LED_OFF)
+ reset_control_assert(led_dat->rst);
+ else
+ reset_control_deassert(led_dat->rst);
+}
+
+struct reset_leds_priv {
+ int num_leds;
+ struct reset_led_data leds[];
+};
+
+static inline int sizeof_reset_leds_priv(int num_leds)
+{
+ return sizeof(struct reset_leds_priv) +
+ (sizeof(struct reset_led_data) * num_leds);
+}
+
+static struct reset_leds_priv *reset_leds_create(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct fwnode_handle *child;
+ struct reset_leds_priv *priv;
+ int count, ret;
+
+ count = device_get_child_node_count(dev);
+ if (!count)
+ return ERR_PTR(-ENODEV);
+
+ priv = devm_kzalloc(dev, sizeof_reset_leds_priv(count), GFP_KERNEL);
+ if (!priv)
+ return ERR_PTR(-ENOMEM);
+
+ device_for_each_child_node(dev, child) {
+ struct reset_led_data *led = &priv->leds[priv->num_leds];
+ struct device_node *np = to_of_node(child);
+
+ ret = fwnode_property_read_string(child, "label", &led->cdev.name);
+ if (!led->cdev.name) {
+ fwnode_handle_put(child);
+ return ERR_PTR(-EINVAL);
+ }
+ led->rst = __of_reset_control_get(np, NULL, 0, 0, 0, true);
+ if (IS_ERR(led->rst))
+ return ERR_PTR(-EINVAL);
+
+ fwnode_property_read_string(child, "linux,default-trigger",
+ &led->cdev.default_trigger);
+
+ led->cdev.brightness_set = reset_led_set;
+ ret = devm_led_classdev_register(&pdev->dev, &led->cdev);
+ if (ret < 0)
+ return ERR_PTR(ret);
+ led->cdev.dev->of_node = np;
+ priv->num_leds++;
+ }
+
+ return priv;
+}
+
+static const struct of_device_id of_reset_leds_match[] = {
+ { .compatible = "reset-leds", },
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, of_reset_leds_match);
+
+static int reset_led_probe(struct platform_device *pdev)
+{
+ struct reset_leds_priv *priv;
+
+ priv = reset_leds_create(pdev);
+ if (IS_ERR(priv))
+ return PTR_ERR(priv);
+
+ platform_set_drvdata(pdev, priv);
+
+ return 0;
+}
+
+static void reset_led_shutdown(struct platform_device *pdev)
+{
+ struct reset_leds_priv *priv = platform_get_drvdata(pdev);
+ int i;
+
+ for (i = 0; i < priv->num_leds; i++) {
+ struct reset_led_data *led = &priv->leds[i];
+
+ if (!(led->cdev.flags & LED_RETAIN_AT_SHUTDOWN))
+ reset_led_set(&led->cdev, LED_OFF);
+ }
+}
+
+static struct platform_driver reset_led_driver = {
+ .probe = reset_led_probe,
+ .shutdown = reset_led_shutdown,
+ .driver = {
+ .name = "leds-reset",
+ .of_match_table = of_reset_leds_match,
+ },
+};
+
+module_platform_driver(reset_led_driver);
+
+MODULE_AUTHOR("John Crispin <john@phrozen.org>");
+MODULE_DESCRIPTION("reset controller LED driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:leds-reset");
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -85,6 +85,7 @@ obj-$(CONFIG_LEDS_LM3601X) += leds-lm36
obj-$(CONFIG_LEDS_TI_LMU_COMMON) += leds-ti-lmu-common.o
obj-$(CONFIG_LEDS_LM3697) += leds-lm3697.o
obj-$(CONFIG_LEDS_LM36274) += leds-lm36274.o
+obj-$(CONFIG_LEDS_RESET) += leds-reset.o
# LED SPI Drivers
obj-$(CONFIG_LEDS_CR0014114) += leds-cr0014114.o

View File

@ -1,333 +0,0 @@
From 08c9d6ceef01893678a5d2e8a15517c745417f21 Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
Date: Tue, 6 Mar 2018 10:04:05 +0100
Subject: [PATCH 04/27] phy: add ath79 usb phys
Signed-off-by: John Crispin <john@phrozen.org>
---
drivers/phy/Kconfig | 16 ++++++
drivers/phy/Makefile | 2 +
drivers/phy/phy-ar7100-usb.c | 124 +++++++++++++++++++++++++++++++++++++++++++
drivers/phy/phy-ar7200-usb.c | 108 +++++++++++++++++++++++++++++++++++++
4 files changed, 250 insertions(+)
create mode 100644 drivers/phy/phy-ar7100-usb.c
create mode 100644 drivers/phy/phy-ar7200-usb.c
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -24,6 +24,22 @@ config GENERIC_PHY_MIPI_DPHY
Provides a number of helpers a core functions for MIPI D-PHY
drivers to us.
+config PHY_AR7100_USB
+ tristate "Atheros AR7100 USB PHY driver"
+ depends on ATH79 || COMPILE_TEST
+ default y if USB_EHCI_HCD_PLATFORM
+ select GENERIC_PHY
+ help
+ Enable this to support the USB PHY on Atheros AR7100 SoCs.
+
+config PHY_AR7200_USB
+ tristate "Atheros AR7200 USB PHY driver"
+ depends on ATH79 || COMPILE_TEST
+ default y if USB_EHCI_HCD_PLATFORM
+ select GENERIC_PHY
+ help
+ Enable this to support the USB PHY on Atheros AR7200 SoCs.
+
config PHY_LPC18XX_USB_OTG
tristate "NXP LPC18xx/43xx SoC USB OTG PHY driver"
depends on OF && (ARCH_LPC18XX || COMPILE_TEST)
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -4,6 +4,8 @@
#
obj-$(CONFIG_GENERIC_PHY) += phy-core.o
+obj-$(CONFIG_PHY_AR7100_USB) += phy-ar7100-usb.o
+obj-$(CONFIG_PHY_AR7200_USB) += phy-ar7200-usb.o
obj-$(CONFIG_GENERIC_PHY_MIPI_DPHY) += phy-core-mipi-dphy.o
obj-$(CONFIG_PHY_LPC18XX_USB_OTG) += phy-lpc18xx-usb-otg.o
obj-$(CONFIG_PHY_XGENE) += phy-xgene.o
--- /dev/null
+++ b/drivers/phy/phy-ar7100-usb.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2018 John Crispin <john@phrozen.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/phy/phy.h>
+#include <linux/delay.h>
+#include <linux/reset.h>
+#include <linux/of_gpio.h>
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+
+struct ar7100_usb_phy {
+ struct reset_control *rst_phy;
+ struct reset_control *rst_host;
+ struct reset_control *rst_ohci_dll;
+ void __iomem *io_base;
+ struct phy *phy;
+ int gpio;
+};
+
+static int ar7100_usb_phy_power_off(struct phy *phy)
+{
+ struct ar7100_usb_phy *priv = phy_get_drvdata(phy);
+ int err = 0;
+
+ err |= reset_control_assert(priv->rst_host);
+ err |= reset_control_assert(priv->rst_phy);
+ err |= reset_control_assert(priv->rst_ohci_dll);
+
+ return err;
+}
+
+static int ar7100_usb_phy_power_on(struct phy *phy)
+{
+ struct ar7100_usb_phy *priv = phy_get_drvdata(phy);
+ int err = 0;
+
+ err |= ar7100_usb_phy_power_off(phy);
+ mdelay(100);
+ err |= reset_control_deassert(priv->rst_ohci_dll);
+ err |= reset_control_deassert(priv->rst_phy);
+ err |= reset_control_deassert(priv->rst_host);
+ mdelay(500);
+ iowrite32(0xf0000, priv->io_base + AR71XX_USB_CTRL_REG_CONFIG);
+ iowrite32(0x20c00, priv->io_base + AR71XX_USB_CTRL_REG_FLADJ);
+
+ return err;
+}
+
+static const struct phy_ops ar7100_usb_phy_ops = {
+ .power_on = ar7100_usb_phy_power_on,
+ .power_off = ar7100_usb_phy_power_off,
+ .owner = THIS_MODULE,
+};
+
+static int ar7100_usb_phy_probe(struct platform_device *pdev)
+{
+ struct phy_provider *phy_provider;
+ struct resource *res;
+ struct ar7100_usb_phy *priv;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ priv->io_base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(priv->io_base))
+ return PTR_ERR(priv->io_base);
+
+ priv->rst_phy = devm_reset_control_get(&pdev->dev, "usb-phy");
+ if (IS_ERR(priv->rst_phy)) {
+ dev_err(&pdev->dev, "phy reset is missing\n");
+ return PTR_ERR(priv->rst_phy);
+ }
+
+ priv->rst_host = devm_reset_control_get(&pdev->dev, "usb-host");
+ if (IS_ERR(priv->rst_host)) {
+ dev_err(&pdev->dev, "host reset is missing\n");
+ return PTR_ERR(priv->rst_host);
+ }
+
+ priv->rst_ohci_dll = devm_reset_control_get(&pdev->dev, "usb-ohci-dll");
+ if (IS_ERR(priv->rst_ohci_dll)) {
+ dev_err(&pdev->dev, "ohci-dll reset is missing\n");
+ return PTR_ERR(priv->rst_host);
+ }
+
+ priv->phy = devm_phy_create(&pdev->dev, NULL, &ar7100_usb_phy_ops);
+ if (IS_ERR(priv->phy)) {
+ dev_err(&pdev->dev, "failed to create PHY\n");
+ return PTR_ERR(priv->phy);
+ }
+
+ priv->gpio = of_get_gpio(pdev->dev.of_node, 0);
+ if (priv->gpio >= 0) {
+ int ret = devm_gpio_request(&pdev->dev, priv->gpio, dev_name(&pdev->dev));
+
+ if (ret) {
+ dev_err(&pdev->dev, "failed to request gpio\n");
+ return ret;
+ }
+ gpio_export_with_name(priv->gpio, 0, dev_name(&pdev->dev));
+ gpio_set_value(priv->gpio, 1);
+ }
+
+ phy_set_drvdata(priv->phy, priv);
+
+ phy_provider = devm_of_phy_provider_register(&pdev->dev, of_phy_simple_xlate);
+
+
+ return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static const struct of_device_id ar7100_usb_phy_of_match[] = {
+ { .compatible = "qca,ar7100-usb-phy" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, ar7100_usb_phy_of_match);
+
+static struct platform_driver ar7100_usb_phy_driver = {
+ .probe = ar7100_usb_phy_probe,
+ .driver = {
+ .of_match_table = ar7100_usb_phy_of_match,
+ .name = "ar7100-usb-phy",
+ }
+};
+module_platform_driver(ar7100_usb_phy_driver);
+
+MODULE_DESCRIPTION("ATH79 USB PHY driver");
+MODULE_AUTHOR("Alban Bedel <albeu@free.fr>");
+MODULE_LICENSE("GPL");
--- /dev/null
+++ b/drivers/phy/phy-ar7200-usb.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2015 Alban Bedel <albeu@free.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/phy/phy.h>
+#include <linux/reset.h>
+#include <linux/of_gpio.h>
+
+struct ar7200_usb_phy {
+ struct reset_control *rst_phy;
+ struct reset_control *rst_phy_analog;
+ struct reset_control *suspend_override;
+ struct phy *phy;
+ int gpio;
+};
+
+static int ar7200_usb_phy_power_on(struct phy *phy)
+{
+ struct ar7200_usb_phy *priv = phy_get_drvdata(phy);
+ int err = 0;
+
+ if (priv->suspend_override)
+ err = reset_control_assert(priv->suspend_override);
+ if (priv->rst_phy)
+ err |= reset_control_deassert(priv->rst_phy);
+ if (priv->rst_phy_analog)
+ err |= reset_control_deassert(priv->rst_phy_analog);
+
+ return err;
+}
+
+static int ar7200_usb_phy_power_off(struct phy *phy)
+{
+ struct ar7200_usb_phy *priv = phy_get_drvdata(phy);
+ int err = 0;
+
+ if (priv->suspend_override)
+ err = reset_control_deassert(priv->suspend_override);
+ if (priv->rst_phy)
+ err |= reset_control_assert(priv->rst_phy);
+ if (priv->rst_phy_analog)
+ err |= reset_control_assert(priv->rst_phy_analog);
+
+ return err;
+}
+
+static const struct phy_ops ar7200_usb_phy_ops = {
+ .power_on = ar7200_usb_phy_power_on,
+ .power_off = ar7200_usb_phy_power_off,
+ .owner = THIS_MODULE,
+};
+
+static int ar7200_usb_phy_probe(struct platform_device *pdev)
+{
+ struct phy_provider *phy_provider;
+ struct ar7200_usb_phy *priv;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->rst_phy = devm_reset_control_get(&pdev->dev, "usb-phy");
+ if (IS_ERR(priv->rst_phy)) {
+ if (PTR_ERR(priv->rst_phy) != -EPROBE_DEFER)
+ dev_err(&pdev->dev, "phy reset is missing\n");
+ return PTR_ERR(priv->rst_phy);
+ }
+
+ priv->rst_phy_analog = devm_reset_control_get_optional(
+ &pdev->dev, "usb-phy-analog");
+ if (IS_ERR(priv->rst_phy_analog)) {
+ if (PTR_ERR(priv->rst_phy_analog) == -ENOENT)
+ priv->rst_phy_analog = NULL;
+ else
+ return PTR_ERR(priv->rst_phy_analog);
+ }
+
+ priv->suspend_override = devm_reset_control_get_optional(
+ &pdev->dev, "usb-suspend-override");
+ if (IS_ERR(priv->suspend_override)) {
+ if (PTR_ERR(priv->suspend_override) == -ENOENT)
+ priv->suspend_override = NULL;
+ else
+ return PTR_ERR(priv->suspend_override);
+ }
+
+ priv->phy = devm_phy_create(&pdev->dev, NULL, &ar7200_usb_phy_ops);
+ if (IS_ERR(priv->phy)) {
+ dev_err(&pdev->dev, "failed to create PHY\n");
+ return PTR_ERR(priv->phy);
+ }
+
+ priv->gpio = of_get_gpio(pdev->dev.of_node, 0);
+ if (priv->gpio >= 0) {
+ int ret = devm_gpio_request(&pdev->dev, priv->gpio, dev_name(&pdev->dev));
+
+ if (ret) {
+ dev_err(&pdev->dev, "failed to request gpio\n");
+ return ret;
+ }
+ gpio_export_with_name(priv->gpio, 0, dev_name(&pdev->dev));
+ gpio_set_value(priv->gpio, 1);
+ }
+
+ phy_set_drvdata(priv->phy, priv);
+
+ phy_provider = devm_of_phy_provider_register(&pdev->dev, of_phy_simple_xlate);
+
+ return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static const struct of_device_id ar7200_usb_phy_of_match[] = {
+ { .compatible = "qca,ar7200-usb-phy" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, ar7200_usb_phy_of_match);
+
+static struct platform_driver ar7200_usb_phy_driver = {
+ .probe = ar7200_usb_phy_probe,
+ .driver = {
+ .of_match_table = ar7200_usb_phy_of_match,
+ .name = "ar7200-usb-phy",
+ }
+};
+module_platform_driver(ar7200_usb_phy_driver);
+
+MODULE_DESCRIPTION("ATH79 USB PHY driver");
+MODULE_AUTHOR("Alban Bedel <albeu@free.fr>");
+MODULE_LICENSE("GPL");

View File

@ -1,24 +0,0 @@
From 2201818e5bd33f389beceb3943fdfcf5a698fc5b Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
Date: Tue, 6 Mar 2018 10:01:43 +0100
Subject: [PATCH 05/27] usb: add more OF/quirk properties
Signed-off-by: John Crispin <john@phrozen.org>
---
drivers/usb/host/ehci-platform.c | 5 +++++
1 file changed, 5 insertions(+)
--- a/drivers/usb/host/ehci-platform.c
+++ b/drivers/usb/host/ehci-platform.c
@@ -269,6 +269,11 @@ static int ehci_platform_probe(struct pl
ehci = hcd_to_ehci(hcd);
if (pdata == &ehci_platform_defaults && dev->dev.of_node) {
+ of_property_read_u32(dev->dev.of_node, "caps-offset", &pdata->caps_offset);
+
+ if (of_property_read_bool(dev->dev.of_node, "has-synopsys-hc-bug"))
+ pdata->has_synopsys_hc_bug = 1;
+
if (of_property_read_bool(dev->dev.of_node, "big-endian-regs"))
ehci->big_endian_mmio = 1;

View File

@ -1,168 +0,0 @@
From f3eacff2310a60348a755c50a8da6fc251fc8587 Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
Date: Tue, 6 Mar 2018 09:55:13 +0100
Subject: [PATCH 07/33] irqchip/irq-ath79-intc: add irq cascade driver for
QCA9556 SoCs
Signed-off-by: John Crispin <john@phrozen.org>
---
drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-ath79-intc.c | 142 +++++++++++++++++++++++++++++++++++++++
2 files changed, 143 insertions(+)
create mode 100644 drivers/irqchip/irq-ath79-intc.c
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -4,6 +4,7 @@ obj-$(CONFIG_IRQCHIP) += irqchip.o
obj-$(CONFIG_AL_FIC) += irq-al-fic.o
obj-$(CONFIG_ALPINE_MSI) += irq-alpine-msi.o
obj-$(CONFIG_ATH79) += irq-ath79-cpu.o
+obj-$(CONFIG_ATH79) += irq-ath79-intc.o
obj-$(CONFIG_ATH79) += irq-ath79-misc.o
obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2835.o
obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2836.o
--- /dev/null
+++ b/drivers/irqchip/irq-ath79-intc.c
@@ -0,0 +1,142 @@
+/*
+ * Atheros AR71xx/AR724x/AR913x specific interrupt handling
+ *
+ * Copyright (C) 2018 John Crispin <john@phrozen.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irqchip.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/irqdomain.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+
+#define ATH79_MAX_INTC_CASCADE 3
+
+struct ath79_intc {
+ struct irq_chip chip;
+ u32 irq;
+ u32 pending_mask;
+ u32 int_status;
+ u32 irq_mask[ATH79_MAX_INTC_CASCADE];
+ u32 irq_wb_chan[ATH79_MAX_INTC_CASCADE];
+};
+
+static void ath79_intc_irq_handler(struct irq_desc *desc)
+{
+ struct irq_domain *domain = irq_desc_get_handler_data(desc);
+ struct ath79_intc *intc = domain->host_data;
+ u32 pending;
+
+ pending = ath79_reset_rr(intc->int_status);
+ pending &= intc->pending_mask;
+
+ if (pending) {
+ int i;
+
+ for (i = 0; i < domain->hwirq_max; i++)
+ if (pending & intc->irq_mask[i]) {
+ if (intc->irq_wb_chan[i] != 0xffffffff)
+ ath79_ddr_wb_flush(intc->irq_wb_chan[i]);
+ generic_handle_irq(irq_find_mapping(domain, i));
+ }
+ } else {
+ spurious_interrupt();
+ }
+}
+
+static void ath79_intc_irq_enable(struct irq_data *d)
+{
+ struct ath79_intc *intc = d->domain->host_data;
+ enable_irq(intc->irq);
+}
+
+static void ath79_intc_irq_disable(struct irq_data *d)
+{
+ struct ath79_intc *intc = d->domain->host_data;
+ disable_irq(intc->irq);
+}
+
+static int ath79_intc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
+{
+ struct ath79_intc *intc = d->host_data;
+
+ irq_set_chip_and_handler(irq, &intc->chip, handle_level_irq);
+
+ return 0;
+}
+
+static const struct irq_domain_ops ath79_irq_domain_ops = {
+ .xlate = irq_domain_xlate_onecell,
+ .map = ath79_intc_map,
+};
+
+static int __init ath79_intc_of_init(
+ struct device_node *node, struct device_node *parent)
+{
+ struct irq_domain *domain;
+ struct ath79_intc *intc;
+ int cnt, cntwb, i, err;
+
+ cnt = of_property_count_u32_elems(node, "qca,pending-bits");
+ if (cnt > ATH79_MAX_INTC_CASCADE)
+ panic("Too many INTC pending bits\n");
+
+ intc = kzalloc(sizeof(*intc), GFP_KERNEL);
+ if (!intc)
+ panic("Failed to allocate INTC memory\n");
+ intc->chip = dummy_irq_chip;
+ intc->chip.name = "INTC";
+ intc->chip.irq_disable = ath79_intc_irq_disable;
+ intc->chip.irq_enable = ath79_intc_irq_enable;
+
+ if (of_property_read_u32(node, "qca,int-status-addr", &intc->int_status) < 0) {
+ panic("Missing address of interrupt status register\n");
+ }
+
+ of_property_read_u32_array(node, "qca,pending-bits", intc->irq_mask, cnt);
+ for (i = 0; i < cnt; i++) {
+ intc->pending_mask |= intc->irq_mask[i];
+ intc->irq_wb_chan[i] = 0xffffffff;
+ }
+
+ cntwb = of_count_phandle_with_args(
+ node, "qca,ddr-wb-channels", "#qca,ddr-wb-channel-cells");
+
+ for (i = 0; i < cntwb; i++) {
+ struct of_phandle_args args;
+ u32 irq = i;
+
+ of_property_read_u32_index(
+ node, "qca,ddr-wb-channel-interrupts", i, &irq);
+ if (irq >= ATH79_MAX_INTC_CASCADE)
+ continue;
+
+ err = of_parse_phandle_with_args(
+ node, "qca,ddr-wb-channels",
+ "#qca,ddr-wb-channel-cells",
+ i, &args);
+ if (err)
+ return err;
+
+ intc->irq_wb_chan[irq] = args.args[0];
+ }
+
+ intc->irq = irq_of_parse_and_map(node, 0);
+ if (!intc->irq)
+ panic("Failed to get INTC IRQ");
+
+ domain = irq_domain_add_linear(node, cnt, &ath79_irq_domain_ops, intc);
+ irq_set_chained_handler_and_data(intc->irq, ath79_intc_irq_handler, domain);
+
+ return 0;
+}
+IRQCHIP_DECLARE(ath79_intc, "qca,ar9340-intc",
+ ath79_intc_of_init);

View File

@ -1,23 +0,0 @@
From e029f998594f151008ecbfa024e2957edd2a5189 Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
Date: Tue, 6 Mar 2018 09:58:19 +0100
Subject: [PATCH 08/33] irqchip/irq-ath79-cpu: drop !OF init helper
Signed-off-by: John Crispin <john@phrozen.org>
---
drivers/irqchip/irq-ath79-cpu.c | 7 -------
1 file changed, 7 deletions(-)
--- a/drivers/irqchip/irq-ath79-cpu.c
+++ b/drivers/irqchip/irq-ath79-cpu.c
@@ -85,10 +85,3 @@ static int __init ar79_cpu_intc_of_init(
}
IRQCHIP_DECLARE(ar79_cpu_intc, "qca,ar7100-cpu-intc",
ar79_cpu_intc_of_init);
-
-void __init ath79_cpu_irq_init(unsigned irq_wb_chan2, unsigned irq_wb_chan3)
-{
- irq_wb_chan[2] = irq_wb_chan2;
- irq_wb_chan[3] = irq_wb_chan3;
- mips_cpu_irq_init();
-}

View File

@ -1,57 +0,0 @@
From 4a4f869ec58ed8910b9b2e68d0eee50957e9bb20 Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
Date: Mon, 25 Jun 2018 15:52:10 +0200
Subject: [PATCH 17/33] dt-bindings: PCI: qcom,ar7100: adds binding doc
With the driver being converted from platform_data to pure OF, we need to
also add some docs.
Cc: Rob Herring <robh+dt@kernel.org>
Cc: devicetree@vger.kernel.org
Signed-off-by: John Crispin <john@phrozen.org>
---
.../devicetree/bindings/pci/qcom,ar7100-pci.txt | 38 ++++++++++++++++++++++
1 file changed, 38 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pci/qcom,ar7100-pci.txt
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/qcom,ar7100-pci.txt
@@ -0,0 +1,38 @@
+* Qualcomm Atheros AR7100 PCI express root complex
+
+Required properties:
+- compatible: should contain "qcom,ar7100-pci" to identify the core.
+- reg: Should contain the register ranges as listed in the reg-names property.
+- reg-names: Definition: Must include the following entries
+ - "cfg_base" IO Memory
+- #address-cells: set to <3>
+- #size-cells: set to <2>
+- ranges: ranges for the PCI memory and I/O regions
+- interrupt-map-mask and interrupt-map: standard PCI
+ properties to define the mapping of the PCIe interface to interrupt
+ numbers.
+- #interrupt-cells: set to <1>
+- interrupt-controller: define to enable the builtin IRQ cascade.
+
+Optional properties:
+- interrupt-parent: phandle to the MIPS IRQ controller
+
+* Example for ar7100
+ pcie-controller@180c0000 {
+ compatible = "qca,ar7100-pci";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ bus-range = <0x0 0x0>;
+ reg = <0x17010000 0x100>;
+ reg-names = "cfg_base";
+ ranges = <0x2000000 0 0x10000000 0x10000000 0 0x07000000
+ 0x1000000 0 0x00000000 0x00000000 0 0x00000001>;
+ interrupt-parent = <&cpuintc>;
+ interrupts = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ interrupt-map-mask = <0 0 0 1>;
+ interrupt-map = <0 0 0 0 &pcie0 0>;
+ };

View File

@ -1,202 +0,0 @@
From 1855ab6b1d27f5b38a648baf57ff6a534afec26d Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
Date: Sat, 23 Jun 2018 15:07:23 +0200
Subject: [PATCH 18/33] MIPS: pci-ar71xx: convert to OF
With the ath79 target getting converted to pure OF, we can drop all the
platform data code and add the missing OF bits to the driver. We also add
a irq domain for the PCI/e controllers cascade, thus making it usable from
dts files.
Signed-off-by: John Crispin <john@phrozen.org>
---
arch/mips/pci/pci-ar71xx.c | 82 +++++++++++++++++++++++-----------------------
1 file changed, 41 insertions(+), 41 deletions(-)
--- a/arch/mips/pci/pci-ar71xx.c
+++ b/arch/mips/pci/pci-ar71xx.c
@@ -15,8 +15,11 @@
#include <linux/pci.h>
#include <linux/pci_regs.h>
#include <linux/interrupt.h>
+#include <linux/irqchip/chained_irq.h>
#include <linux/init.h>
#include <linux/platform_device.h>
+#include <linux/of_irq.h>
+#include <linux/of_pci.h>
#include <asm/mach-ath79/ar71xx_regs.h>
#include <asm/mach-ath79/ath79.h>
@@ -46,12 +49,13 @@
#define AR71XX_PCI_IRQ_COUNT 5
struct ar71xx_pci_controller {
+ struct device_node *np;
void __iomem *cfg_base;
int irq;
- int irq_base;
struct pci_controller pci_ctrl;
struct resource io_res;
struct resource mem_res;
+ struct irq_domain *domain;
};
/* Byte lane enable bits */
@@ -225,29 +229,30 @@ static struct pci_ops ar71xx_pci_ops = {
static void ar71xx_pci_irq_handler(struct irq_desc *desc)
{
- struct ar71xx_pci_controller *apc;
void __iomem *base = ath79_reset_base;
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ struct ar71xx_pci_controller *apc = irq_desc_get_handler_data(desc);
u32 pending;
- apc = irq_desc_get_handler_data(desc);
-
+ chained_irq_enter(chip, desc);
pending = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_STATUS) &
__raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
if (pending & AR71XX_PCI_INT_DEV0)
- generic_handle_irq(apc->irq_base + 0);
+ generic_handle_irq(irq_linear_revmap(apc->domain, 1));
else if (pending & AR71XX_PCI_INT_DEV1)
- generic_handle_irq(apc->irq_base + 1);
+ generic_handle_irq(irq_linear_revmap(apc->domain, 2));
else if (pending & AR71XX_PCI_INT_DEV2)
- generic_handle_irq(apc->irq_base + 2);
+ generic_handle_irq(irq_linear_revmap(apc->domain, 3));
else if (pending & AR71XX_PCI_INT_CORE)
- generic_handle_irq(apc->irq_base + 4);
+ generic_handle_irq(irq_linear_revmap(apc->domain, 4));
else
spurious_interrupt();
+ chained_irq_exit(chip, desc);
}
static void ar71xx_pci_irq_unmask(struct irq_data *d)
@@ -258,7 +263,7 @@ static void ar71xx_pci_irq_unmask(struct
u32 t;
apc = irq_data_get_irq_chip_data(d);
- irq = d->irq - apc->irq_base;
+ irq = irq_linear_revmap(apc->domain, d->irq);
t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
__raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE);
@@ -275,7 +280,7 @@ static void ar71xx_pci_irq_mask(struct i
u32 t;
apc = irq_data_get_irq_chip_data(d);
- irq = d->irq - apc->irq_base;
+ irq = irq_linear_revmap(apc->domain, d->irq);
t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
__raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE);
@@ -291,24 +296,31 @@ static struct irq_chip ar71xx_pci_irq_ch
.irq_mask_ack = ar71xx_pci_irq_mask,
};
+static int ar71xx_pci_irq_map(struct irq_domain *d,
+ unsigned int irq, irq_hw_number_t hw)
+{
+ struct ar71xx_pci_controller *apc = d->host_data;
+
+ irq_set_chip_and_handler(irq, &ar71xx_pci_irq_chip, handle_level_irq);
+ irq_set_chip_data(irq, apc);
+
+ return 0;
+}
+
+static const struct irq_domain_ops ar71xx_pci_domain_ops = {
+ .xlate = irq_domain_xlate_onecell,
+ .map = ar71xx_pci_irq_map,
+};
+
static void ar71xx_pci_irq_init(struct ar71xx_pci_controller *apc)
{
void __iomem *base = ath79_reset_base;
- int i;
__raw_writel(0, base + AR71XX_RESET_REG_PCI_INT_ENABLE);
__raw_writel(0, base + AR71XX_RESET_REG_PCI_INT_STATUS);
- BUILD_BUG_ON(ATH79_PCI_IRQ_COUNT < AR71XX_PCI_IRQ_COUNT);
-
- apc->irq_base = ATH79_PCI_IRQ_BASE;
- for (i = apc->irq_base;
- i < apc->irq_base + AR71XX_PCI_IRQ_COUNT; i++) {
- irq_set_chip_and_handler(i, &ar71xx_pci_irq_chip,
- handle_level_irq);
- irq_set_chip_data(i, apc);
- }
-
+ apc->domain = irq_domain_add_linear(apc->np, AR71XX_PCI_IRQ_COUNT,
+ &ar71xx_pci_domain_ops, apc);
irq_set_chained_handler_and_data(apc->irq, ar71xx_pci_irq_handler,
apc);
}
@@ -325,6 +337,11 @@ static void ar71xx_pci_reset(void)
mdelay(100);
}
+static const struct of_device_id ar71xx_pci_ids[] = {
+ { .compatible = "qca,ar7100-pci" },
+ {},
+};
+
static int ar71xx_pci_probe(struct platform_device *pdev)
{
struct ar71xx_pci_controller *apc;
@@ -345,26 +362,6 @@ static int ar71xx_pci_probe(struct platf
if (apc->irq < 0)
return -EINVAL;
- res = platform_get_resource_byname(pdev, IORESOURCE_IO, "io_base");
- if (!res)
- return -EINVAL;
-
- apc->io_res.parent = res;
- apc->io_res.name = "PCI IO space";
- apc->io_res.start = res->start;
- apc->io_res.end = res->end;
- apc->io_res.flags = IORESOURCE_IO;
-
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mem_base");
- if (!res)
- return -EINVAL;
-
- apc->mem_res.parent = res;
- apc->mem_res.name = "PCI memory space";
- apc->mem_res.start = res->start;
- apc->mem_res.end = res->end;
- apc->mem_res.flags = IORESOURCE_MEM;
-
ar71xx_pci_reset();
/* setup COMMAND register */
@@ -377,9 +374,11 @@ static int ar71xx_pci_probe(struct platf
ar71xx_pci_irq_init(apc);
+ apc->np = pdev->dev.of_node;
apc->pci_ctrl.pci_ops = &ar71xx_pci_ops;
apc->pci_ctrl.mem_resource = &apc->mem_res;
apc->pci_ctrl.io_resource = &apc->io_res;
+ pci_load_of_ranges(&apc->pci_ctrl, pdev->dev.of_node);
register_pci_controller(&apc->pci_ctrl);
@@ -390,6 +389,7 @@ static struct platform_driver ar71xx_pci
.probe = ar71xx_pci_probe,
.driver = {
.name = "ar71xx-pci",
+ .of_match_table = of_match_ptr(ar71xx_pci_ids),
},
};

View File

@ -1,61 +0,0 @@
From ea27764bc3ef2a05decf3ae05edffc289cd0d93c Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
Date: Mon, 25 Jun 2018 15:52:02 +0200
Subject: [PATCH 19/33] dt-bindings: PCI: qcom,ar7240: adds binding doc
With the driver being converted from platform_data to pure OF, we need to
also add some docs.
Cc: Rob Herring <robh+dt@kernel.org>
Cc: devicetree@vger.kernel.org
Signed-off-by: John Crispin <john@phrozen.org>
---
.../devicetree/bindings/pci/qcom,ar7240-pci.txt | 42 ++++++++++++++++++++++
1 file changed, 42 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pci/qcom,ar7240-pci.txt
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/qcom,ar7240-pci.txt
@@ -0,0 +1,42 @@
+* Qualcomm Atheros AR724X PCI express root complex
+
+Required properties:
+- compatible: should contain "qcom,ar7240-pci" to identify the core.
+- reg: Should contain the register ranges as listed in the reg-names property.
+- reg-names: Definition: Must include the following entries
+ - "crp_base" Configuration registers
+ - "ctrl_base" Control registers
+ - "cfg_base" IO Memory
+- #address-cells: set to <3>
+- #size-cells: set to <2>
+- ranges: ranges for the PCI memory and I/O regions
+- interrupt-map-mask and interrupt-map: standard PCI
+ properties to define the mapping of the PCIe interface to interrupt
+ numbers.
+- #interrupt-cells: set to <1>
+- interrupt-parent: phandle to the MIPS IRQ controller
+
+Optional properties:
+- interrupt-controller: define to enable the builtin IRQ cascade.
+
+* Example for qca9557
+ pcie-controller@180c0000 {
+ compatible = "qcom,ar7240-pci";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ bus-range = <0x0 0x0>;
+ reg = <0x180c0000 0x1000>,
+ <0x180f0000 0x100>,
+ <0x14000000 0x1000>;
+ reg-names = "crp_base", "ctrl_base", "cfg_base";
+ ranges = <0x2000000 0 0x10000000 0x10000000 0 0x04000000
+ 0x1000000 0 0x00000000 0x00000000 0 0x00000001>;
+ interrupt-parent = <&intc2>;
+ interrupts = <1>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ interrupt-map-mask = <0 0 0 1>;
+ interrupt-map = <0 0 0 0 &pcie0 0>;
+ };

View File

@ -1,205 +0,0 @@
From a522ee0199d5d3ea114ca2e211f6ac398d3e8e0b Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
Date: Sat, 23 Jun 2018 15:07:37 +0200
Subject: [PATCH 20/33] MIPS: pci-ar724x: convert to OF
With the ath79 target getting converted to pure OF, we can drop all the
platform data code and add the missing OF bits to the driver. We also add
a irq domain for the PCI/e controllers cascade, thus making it usable from
dts files.
Signed-off-by: John Crispin <john@phrozen.org>
---
arch/mips/pci/pci-ar724x.c | 88 ++++++++++++++++++++++------------------------
1 file changed, 42 insertions(+), 46 deletions(-)
--- a/arch/mips/pci/pci-ar724x.c
+++ b/arch/mips/pci/pci-ar724x.c
@@ -11,8 +11,11 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
+#include <linux/irqchip/chained_irq.h>
#include <asm/mach-ath79/ath79.h>
#include <asm/mach-ath79/ar71xx_regs.h>
+#include <linux/of_irq.h>
+#include <linux/of_pci.h>
#define AR724X_PCI_REG_APP 0x00
#define AR724X_PCI_REG_RESET 0x18
@@ -42,17 +45,20 @@ struct ar724x_pci_controller {
void __iomem *crp_base;
int irq;
- int irq_base;
bool link_up;
bool bar0_is_cached;
u32 bar0_value;
+ struct device_node *np;
struct pci_controller pci_controller;
+ struct irq_domain *domain;
struct resource io_res;
struct resource mem_res;
};
+static struct irq_chip ar724x_pci_irq_chip;
+
static inline bool ar724x_pci_check_link(struct ar724x_pci_controller *apc)
{
u32 reset;
@@ -228,35 +234,31 @@ static struct pci_ops ar724x_pci_ops = {
static void ar724x_pci_irq_handler(struct irq_desc *desc)
{
- struct ar724x_pci_controller *apc;
- void __iomem *base;
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ struct ar724x_pci_controller *apc = irq_desc_get_handler_data(desc);
u32 pending;
- apc = irq_desc_get_handler_data(desc);
- base = apc->ctrl_base;
-
- pending = __raw_readl(base + AR724X_PCI_REG_INT_STATUS) &
- __raw_readl(base + AR724X_PCI_REG_INT_MASK);
+ chained_irq_enter(chip, desc);
+ pending = __raw_readl(apc->ctrl_base + AR724X_PCI_REG_INT_STATUS) &
+ __raw_readl(apc->ctrl_base + AR724X_PCI_REG_INT_MASK);
if (pending & AR724X_PCI_INT_DEV0)
- generic_handle_irq(apc->irq_base + 0);
-
+ generic_handle_irq(irq_linear_revmap(apc->domain, 1));
else
spurious_interrupt();
+ chained_irq_exit(chip, desc);
}
static void ar724x_pci_irq_unmask(struct irq_data *d)
{
struct ar724x_pci_controller *apc;
void __iomem *base;
- int offset;
u32 t;
apc = irq_data_get_irq_chip_data(d);
base = apc->ctrl_base;
- offset = apc->irq_base - d->irq;
- switch (offset) {
+ switch (irq_linear_revmap(apc->domain, d->irq)) {
case 0:
t = __raw_readl(base + AR724X_PCI_REG_INT_MASK);
__raw_writel(t | AR724X_PCI_INT_DEV0,
@@ -270,14 +272,12 @@ static void ar724x_pci_irq_mask(struct i
{
struct ar724x_pci_controller *apc;
void __iomem *base;
- int offset;
u32 t;
apc = irq_data_get_irq_chip_data(d);
base = apc->ctrl_base;
- offset = apc->irq_base - d->irq;
- switch (offset) {
+ switch (irq_linear_revmap(apc->domain, d->irq)) {
case 0:
t = __raw_readl(base + AR724X_PCI_REG_INT_MASK);
__raw_writel(t & ~AR724X_PCI_INT_DEV0,
@@ -302,26 +302,34 @@ static struct irq_chip ar724x_pci_irq_ch
.irq_mask_ack = ar724x_pci_irq_mask,
};
+static int ar724x_pci_irq_map(struct irq_domain *d,
+ unsigned int irq, irq_hw_number_t hw)
+{
+ struct ar724x_pci_controller *apc = d->host_data;
+
+ irq_set_chip_and_handler(irq, &ar724x_pci_irq_chip, handle_level_irq);
+ irq_set_chip_data(irq, apc);
+
+ return 0;
+}
+
+static const struct irq_domain_ops ar724x_pci_domain_ops = {
+ .xlate = irq_domain_xlate_onecell,
+ .map = ar724x_pci_irq_map,
+};
+
static void ar724x_pci_irq_init(struct ar724x_pci_controller *apc,
int id)
{
void __iomem *base;
- int i;
base = apc->ctrl_base;
__raw_writel(0, base + AR724X_PCI_REG_INT_MASK);
__raw_writel(0, base + AR724X_PCI_REG_INT_STATUS);
- apc->irq_base = ATH79_PCI_IRQ_BASE + (id * AR724X_PCI_IRQ_COUNT);
-
- for (i = apc->irq_base;
- i < apc->irq_base + AR724X_PCI_IRQ_COUNT; i++) {
- irq_set_chip_and_handler(i, &ar724x_pci_irq_chip,
- handle_level_irq);
- irq_set_chip_data(i, apc);
- }
-
+ apc->domain = irq_domain_add_linear(apc->np, 2,
+ &ar724x_pci_domain_ops, apc);
irq_set_chained_handler_and_data(apc->irq, ar724x_pci_irq_handler,
apc);
}
@@ -391,29 +399,11 @@ static int ar724x_pci_probe(struct platf
if (apc->irq < 0)
return -EINVAL;
- res = platform_get_resource_byname(pdev, IORESOURCE_IO, "io_base");
- if (!res)
- return -EINVAL;
-
- apc->io_res.parent = res;
- apc->io_res.name = "PCI IO space";
- apc->io_res.start = res->start;
- apc->io_res.end = res->end;
- apc->io_res.flags = IORESOURCE_IO;
-
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mem_base");
- if (!res)
- return -EINVAL;
-
- apc->mem_res.parent = res;
- apc->mem_res.name = "PCI memory space";
- apc->mem_res.start = res->start;
- apc->mem_res.end = res->end;
- apc->mem_res.flags = IORESOURCE_MEM;
-
+ apc->np = pdev->dev.of_node;
apc->pci_controller.pci_ops = &ar724x_pci_ops;
apc->pci_controller.io_resource = &apc->io_res;
apc->pci_controller.mem_resource = &apc->mem_res;
+ pci_load_of_ranges(&apc->pci_controller, pdev->dev.of_node);
/*
* Do the full PCIE Root Complex Initialization Sequence if the PCIe
@@ -435,10 +425,16 @@ static int ar724x_pci_probe(struct platf
return 0;
}
+static const struct of_device_id ar724x_pci_ids[] = {
+ { .compatible = "qcom,ar7240-pci" },
+ {},
+};
+
static struct platform_driver ar724x_pci_driver = {
.probe = ar724x_pci_probe,
.driver = {
.name = "ar724x-pci",
+ .of_match_table = of_match_ptr(ar724x_pci_ids),
},
};

View File

@ -1,93 +0,0 @@
From 3fc8585cf76022dba7496627074d42af88c30718 Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
Date: Sat, 23 Jun 2018 15:16:55 +0200
Subject: [PATCH 32/33] MIPS: ath79: sanitize symbols
We no longer need to select which SoCs are supported as the whole arch
code is always built. So lets drop all the SoC symbols
Signed-off-by: John Crispin <john@phrozen.org>
---
arch/mips/Kconfig | 2 ++
arch/mips/ath79/Kconfig | 44 +++++---------------------------------------
arch/mips/pci/Makefile | 2 +-
3 files changed, 8 insertions(+), 40 deletions(-)
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -220,6 +220,8 @@ config ATH79
select SYS_SUPPORTS_BIG_ENDIAN
select SYS_SUPPORTS_MIPS16
select SYS_SUPPORTS_ZBOOT_UART_PROM
+ select HAVE_PCI
+ select USB_ARCH_HAS_EHCI
select USE_OF
select USB_EHCI_ROOT_HUB_TT if USB_EHCI_HCD_PLATFORM
help
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -1,48 +1,14 @@
# SPDX-License-Identifier: GPL-2.0
if ATH79
-config SOC_AR71XX
- select HAVE_PCI
- def_bool n
-
-config SOC_AR724X
- select HAVE_PCI
- select PCI_AR724X if PCI
- def_bool n
-
-config SOC_AR913X
- def_bool n
-
-config SOC_AR933X
- def_bool n
-
-config SOC_AR934X
- select HAVE_PCI
- select PCI_AR724X if PCI
- def_bool n
-
-config SOC_QCA955X
- select HAVE_PCI
- select PCI_AR724X if PCI
+config PCI_AR71XX
+ bool "PCI support for AR7100 type SoCs"
+ depends on PCI
def_bool n
config PCI_AR724X
- def_bool n
-
-config ATH79_DEV_GPIO_BUTTONS
- def_bool n
-
-config ATH79_DEV_LEDS_GPIO
- def_bool n
-
-config ATH79_DEV_SPI
- def_bool n
-
-config ATH79_DEV_USB
- def_bool n
-
-config ATH79_DEV_WMAC
- depends on (SOC_AR913X || SOC_AR933X || SOC_AR934X || SOC_QCA955X)
+ bool "PCI support for AR724x type SoCs"
+ depends on PCI
def_bool n
endif
--- a/arch/mips/pci/Makefile
+++ b/arch/mips/pci/Makefile
@@ -23,7 +23,7 @@ obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o
ops-bcm63xx.o
obj-$(CONFIG_MIPS_ALCHEMY) += pci-alchemy.o
obj-$(CONFIG_PCI_AR2315) += pci-ar2315.o
-obj-$(CONFIG_SOC_AR71XX) += pci-ar71xx.o
+obj-$(CONFIG_PCI_AR71XX) += pci-ar71xx.o
obj-$(CONFIG_PCI_AR724X) += pci-ar724x.o
obj-$(CONFIG_MIPS_PCI_VIRTIO) += pci-virtio-guest.o
obj-$(CONFIG_PCI_XTALK_BRIDGE) += pci-xtalk-bridge.o

View File

@ -1,70 +0,0 @@
From c4e197bbcecc7233aa9e553e7047fa50e4e1fe77 Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
Date: Mon, 25 Jun 2018 15:52:34 +0200
Subject: [PATCH 33/33] spi: ath79: drop pdata support
The target is being converted to pure OF. We can therefore drop all of the
platform data code from the driver.
Cc: linux-spi@vger.kernel.org
Acked-by: Mark Brown <broonie@kernel.org>
Signed-off-by: John Crispin <john@phrozen.org>
---
include/linux/platform_data/spi-ath79.h | 16 -------------------
drivers/spi/spi-ath79.c | 8 --------
2 files changed, 27 deletions(-)
delete mode 100644 arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
--- a/include/linux/platform_data/spi-ath79.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Platform data definition for Atheros AR71XX/AR724X/AR913X SPI controller
- *
- * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
- */
-
-#ifndef _ATH79_SPI_PLATFORM_H
-#define _ATH79_SPI_PLATFORM_H
-
-struct ath79_spi_platform_data {
- unsigned bus_num;
- unsigned num_chipselect;
-};
-
-#endif /* _ATH79_SPI_PLATFORM_H */
--- a/drivers/spi/spi-ath79.c
+++ b/drivers/spi/spi-ath79.c
@@ -19,7 +19,6 @@
#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/err.h>
-#include <linux/platform_data/spi-ath79.h>
#define DRV_NAME "ath79-spi"
@@ -138,7 +137,6 @@ static int ath79_spi_probe(struct platfo
{
struct spi_master *master;
struct ath79_spi *sp;
- struct ath79_spi_platform_data *pdata;
unsigned long rate;
int ret;
@@ -152,15 +150,9 @@ static int ath79_spi_probe(struct platfo
master->dev.of_node = pdev->dev.of_node;
platform_set_drvdata(pdev, sp);
- pdata = dev_get_platdata(&pdev->dev);
-
master->use_gpio_descriptors = true;
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
master->flags = SPI_MASTER_GPIO_SS;
- if (pdata) {
- master->bus_num = pdata->bus_num;
- master->num_chipselect = pdata->num_chipselect;
- }
sp->bitbang.master = master;
sp->bitbang.chipselect = ath79_spi_chipselect;

View File

@ -1,27 +0,0 @@
--- a/arch/mips/ath79/common.c
+++ b/arch/mips/ath79/common.c
@@ -31,11 +31,13 @@ EXPORT_SYMBOL_GPL(ath79_ddr_freq);
enum ath79_soc_type ath79_soc;
unsigned int ath79_soc_rev;
+EXPORT_SYMBOL_GPL(ath79_soc_rev);
void __iomem *ath79_pll_base;
void __iomem *ath79_reset_base;
EXPORT_SYMBOL_GPL(ath79_reset_base);
-static void __iomem *ath79_ddr_base;
+void __iomem *ath79_ddr_base;
+EXPORT_SYMBOL_GPL(ath79_ddr_base);
static void __iomem *ath79_ddr_wb_flush_base;
static void __iomem *ath79_ddr_pci_win_base;
--- a/arch/mips/include/asm/mach-ath79/ath79.h
+++ b/arch/mips/include/asm/mach-ath79/ath79.h
@@ -149,6 +149,7 @@ void ath79_ddr_wb_flush(unsigned int reg
void ath79_ddr_set_pci_windows(void);
extern void __iomem *ath79_pll_base;
+extern void __iomem *ath79_ddr_base;
extern void __iomem *ath79_reset_base;
static inline void ath79_pll_wr(unsigned reg, u32 val)

View File

@ -1,165 +0,0 @@
From 4267880319bc1a2270d352e0ded6d6386242a7ef Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Tue, 12 Aug 2014 20:49:27 +0200
Subject: [PATCH 24/53] GPIO: add named gpio exports
Signed-off-by: John Crispin <blogic@openwrt.org>
---
drivers/gpio/gpiolib-of.c | 68 +++++++++++++++++++++++++++++++++++++++++
drivers/gpio/gpiolib-sysfs.c | 10 +++++-
include/asm-generic/gpio.h | 6 ++++
include/linux/gpio/consumer.h | 8 +++++
4 files changed, 91 insertions(+), 1 deletion(-)
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -19,6 +19,8 @@
#include <linux/pinctrl/pinctrl.h>
#include <linux/slab.h>
#include <linux/gpio/machine.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
#include "gpiolib.h"
#include "gpiolib-of.h"
@@ -915,3 +917,68 @@ void of_gpiochip_remove(struct gpio_chip
{
of_node_put(chip->of_node);
}
+
+static struct of_device_id gpio_export_ids[] = {
+ { .compatible = "gpio-export" },
+ { /* sentinel */ }
+};
+
+static int of_gpio_export_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct device_node *cnp;
+ u32 val;
+ int nb = 0;
+
+ for_each_child_of_node(np, cnp) {
+ const char *name = NULL;
+ int gpio;
+ bool dmc;
+ int max_gpio = 1;
+ int i;
+
+ of_property_read_string(cnp, "gpio-export,name", &name);
+
+ if (!name)
+ max_gpio = of_gpio_count(cnp);
+
+ for (i = 0; i < max_gpio; i++) {
+ unsigned flags = 0;
+ enum of_gpio_flags of_flags;
+
+ gpio = of_get_gpio_flags(cnp, i, &of_flags);
+ if (!gpio_is_valid(gpio))
+ return gpio;
+
+ if (of_flags == OF_GPIO_ACTIVE_LOW)
+ flags |= GPIOF_ACTIVE_LOW;
+
+ if (!of_property_read_u32(cnp, "gpio-export,output", &val))
+ flags |= val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
+ else
+ flags |= GPIOF_IN;
+
+ if (devm_gpio_request_one(&pdev->dev, gpio, flags, name ? name : of_node_full_name(np)))
+ continue;
+
+ dmc = of_property_read_bool(cnp, "gpio-export,direction_may_change");
+ gpio_export_with_name(gpio, dmc, name);
+ nb++;
+ }
+ }
+
+ dev_info(&pdev->dev, "%d gpio(s) exported\n", nb);
+
+ return 0;
+}
+
+static struct platform_driver gpio_export_driver = {
+ .driver = {
+ .name = "gpio-export",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(gpio_export_ids),
+ },
+ .probe = of_gpio_export_probe,
+};
+
+module_platform_driver(gpio_export_driver);
--- a/drivers/gpio/gpiolib-sysfs.c
+++ b/drivers/gpio/gpiolib-sysfs.c
@@ -571,7 +571,7 @@ static struct class gpio_class = {
*
* Returns zero on success, else an error.
*/
-int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
+int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name)
{
struct gpio_chip *chip;
struct gpio_device *gdev;
@@ -633,6 +633,8 @@ int gpiod_export(struct gpio_desc *desc,
offset = gpio_chip_hwgpio(desc);
if (chip->names && chip->names[offset])
ioname = chip->names[offset];
+ if (name)
+ ioname = name;
dev = device_create_with_groups(&gpio_class, &gdev->dev,
MKDEV(0, 0), data, gpio_groups,
@@ -654,6 +656,12 @@ err_unlock:
gpiod_dbg(desc, "%s: status %d\n", __func__, status);
return status;
}
+EXPORT_SYMBOL_GPL(__gpiod_export);
+
+int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
+{
+ return __gpiod_export(desc, direction_may_change, NULL);
+}
EXPORT_SYMBOL_GPL(gpiod_export);
static int match_export(struct device *dev, const void *desc)
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -127,6 +127,12 @@ static inline int gpio_export(unsigned g
return gpiod_export(gpio_to_desc(gpio), direction_may_change);
}
+int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name);
+static inline int gpio_export_with_name(unsigned gpio, bool direction_may_change, const char *name)
+{
+ return __gpiod_export(gpio_to_desc(gpio), direction_may_change, name);
+}
+
static inline int gpio_export_link(struct device *dev, const char *name,
unsigned gpio)
{
--- a/include/linux/gpio/consumer.h
+++ b/include/linux/gpio/consumer.h
@@ -668,6 +668,7 @@ static inline void devm_acpi_dev_remove_
#if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_GPIO_SYSFS)
+int _gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name);
int gpiod_export(struct gpio_desc *desc, bool direction_may_change);
int gpiod_export_link(struct device *dev, const char *name,
struct gpio_desc *desc);
@@ -675,6 +676,13 @@ void gpiod_unexport(struct gpio_desc *de
#else /* CONFIG_GPIOLIB && CONFIG_GPIO_SYSFS */
+static inline int _gpiod_export(struct gpio_desc *desc,
+ bool direction_may_change,
+ const char *name)
+{
+ return -ENOSYS;
+}
+
static inline int gpiod_export(struct gpio_desc *desc,
bool direction_may_change)
{

View File

@ -1,139 +0,0 @@
--- a/arch/mips/pci/pci-ar71xx.c
+++ b/arch/mips/pci/pci-ar71xx.c
@@ -51,11 +51,9 @@
struct ar71xx_pci_controller {
struct device_node *np;
void __iomem *cfg_base;
- int irq;
struct pci_controller pci_ctrl;
struct resource io_res;
struct resource mem_res;
- struct irq_domain *domain;
};
/* Byte lane enable bits */
@@ -227,104 +225,6 @@ static struct pci_ops ar71xx_pci_ops = {
.write = ar71xx_pci_write_config,
};
-static void ar71xx_pci_irq_handler(struct irq_desc *desc)
-{
- void __iomem *base = ath79_reset_base;
- struct irq_chip *chip = irq_desc_get_chip(desc);
- struct ar71xx_pci_controller *apc = irq_desc_get_handler_data(desc);
- u32 pending;
-
- chained_irq_enter(chip, desc);
- pending = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_STATUS) &
- __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
-
- if (pending & AR71XX_PCI_INT_DEV0)
- generic_handle_irq(irq_linear_revmap(apc->domain, 1));
-
- else if (pending & AR71XX_PCI_INT_DEV1)
- generic_handle_irq(irq_linear_revmap(apc->domain, 2));
-
- else if (pending & AR71XX_PCI_INT_DEV2)
- generic_handle_irq(irq_linear_revmap(apc->domain, 3));
-
- else if (pending & AR71XX_PCI_INT_CORE)
- generic_handle_irq(irq_linear_revmap(apc->domain, 4));
-
- else
- spurious_interrupt();
- chained_irq_exit(chip, desc);
-}
-
-static void ar71xx_pci_irq_unmask(struct irq_data *d)
-{
- struct ar71xx_pci_controller *apc;
- unsigned int irq;
- void __iomem *base = ath79_reset_base;
- u32 t;
-
- apc = irq_data_get_irq_chip_data(d);
- irq = irq_linear_revmap(apc->domain, d->irq);
-
- t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
- __raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE);
-
- /* flush write */
- __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
-}
-
-static void ar71xx_pci_irq_mask(struct irq_data *d)
-{
- struct ar71xx_pci_controller *apc;
- unsigned int irq;
- void __iomem *base = ath79_reset_base;
- u32 t;
-
- apc = irq_data_get_irq_chip_data(d);
- irq = irq_linear_revmap(apc->domain, d->irq);
-
- t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
- __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE);
-
- /* flush write */
- __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
-}
-
-static struct irq_chip ar71xx_pci_irq_chip = {
- .name = "AR71XX PCI",
- .irq_mask = ar71xx_pci_irq_mask,
- .irq_unmask = ar71xx_pci_irq_unmask,
- .irq_mask_ack = ar71xx_pci_irq_mask,
-};
-
-static int ar71xx_pci_irq_map(struct irq_domain *d,
- unsigned int irq, irq_hw_number_t hw)
-{
- struct ar71xx_pci_controller *apc = d->host_data;
-
- irq_set_chip_and_handler(irq, &ar71xx_pci_irq_chip, handle_level_irq);
- irq_set_chip_data(irq, apc);
-
- return 0;
-}
-
-static const struct irq_domain_ops ar71xx_pci_domain_ops = {
- .xlate = irq_domain_xlate_onecell,
- .map = ar71xx_pci_irq_map,
-};
-
-static void ar71xx_pci_irq_init(struct ar71xx_pci_controller *apc)
-{
- void __iomem *base = ath79_reset_base;
-
- __raw_writel(0, base + AR71XX_RESET_REG_PCI_INT_ENABLE);
- __raw_writel(0, base + AR71XX_RESET_REG_PCI_INT_STATUS);
-
- apc->domain = irq_domain_add_linear(apc->np, AR71XX_PCI_IRQ_COUNT,
- &ar71xx_pci_domain_ops, apc);
- irq_set_chained_handler_and_data(apc->irq, ar71xx_pci_irq_handler,
- apc);
-}
-
static void ar71xx_pci_reset(void)
{
ath79_device_reset_set(AR71XX_RESET_PCI_BUS | AR71XX_RESET_PCI_CORE);
@@ -358,10 +258,6 @@ static int ar71xx_pci_probe(struct platf
if (IS_ERR(apc->cfg_base))
return PTR_ERR(apc->cfg_base);
- apc->irq = platform_get_irq(pdev, 0);
- if (apc->irq < 0)
- return -EINVAL;
-
ar71xx_pci_reset();
/* setup COMMAND register */
@@ -372,8 +268,6 @@ static int ar71xx_pci_probe(struct platf
/* clear bus errors */
ar71xx_pci_check_error(apc, 1);
- ar71xx_pci_irq_init(apc);
-
apc->np = pdev->dev.of_node;
apc->pci_ctrl.pci_ops = &ar71xx_pci_ops;
apc->pci_ctrl.mem_resource = &apc->mem_res;

View File

@ -1,21 +0,0 @@
commit f3ffac90bc7266b7d917616f3233f58e8c08a196
Author: Christian Lamparter <chunkeey@gmail.com>
Date: Fri Aug 10 23:24:47 2018 +0200
ath79: gmac: add parsers for rxd(v)- and tx(d|en)-delay for AR9344
Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
@@ -1226,6 +1226,10 @@
#define AR934X_ETH_CFG_RDV_DELAY BIT(16)
#define AR934X_ETH_CFG_RDV_DELAY_MASK 0x3
#define AR934X_ETH_CFG_RDV_DELAY_SHIFT 16
+#define AR934X_ETH_CFG_TXD_DELAY_MASK 0x3
+#define AR934X_ETH_CFG_TXD_DELAY_SHIFT 18
+#define AR934X_ETH_CFG_TXE_DELAY_MASK 0x3
+#define AR934X_ETH_CFG_TXE_DELAY_SHIFT 20
/*
* QCA953X GMAC Interface

View File

@ -1,90 +0,0 @@
From 60efe35257b063ce584968f9f80b437030ce6ba6 Mon Sep 17 00:00:00 2001
From: David Bauer <mail@david-bauer.net>
Date: Mon, 18 Mar 2019 00:54:06 +0100
Subject: [PATCH] MIPS: ath79: add missing QCA955x GMAC registers
This adds missing GMAC register definitions for the Qualcomm Atheros
QCA955X series MIPS SoCs.
They originate from the platforms U-Boot code and the AVM FRITZ!WLAN
Repeater 450E's GPL tarball.
Signed-off-by: David Bauer <mail@david-bauer.net>
---
.../mips/include/asm/mach-ath79/ar71xx_regs.h | 54 +++++++++++++++++++
1 file changed, 54 insertions(+)
--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
@@ -1246,7 +1246,12 @@
*/
#define QCA955X_GMAC_REG_ETH_CFG 0x00
+#define QCA955X_GMAC_REG_SGMII_RESET 0x14
#define QCA955X_GMAC_REG_SGMII_SERDES 0x18
+#define QCA955X_GMAC_REG_MR_AN_CONTROL 0x1c
+#define QCA955X_GMAC_REG_MR_AN_STATUS 0x20
+#define QCA955X_GMAC_REG_SGMII_CONFIG 0x34
+#define QCA955X_GMAC_REG_SGMII_DEBUG 0x58
#define QCA955X_ETH_CFG_RGMII_EN BIT(0)
#define QCA955X_ETH_CFG_MII_GE0 BIT(1)
@@ -1268,9 +1273,58 @@
#define QCA955X_ETH_CFG_TXE_DELAY_MASK 0x3
#define QCA955X_ETH_CFG_TXE_DELAY_SHIFT 20
+#define QCA955X_SGMII_RESET_RX_CLK_N_RESET 0
+#define QCA955X_SGMII_RESET_RX_CLK_N BIT(0)
+#define QCA955X_SGMII_RESET_TX_CLK_N BIT(1)
+#define QCA955X_SGMII_RESET_RX_125M_N BIT(2)
+#define QCA955X_SGMII_RESET_TX_125M_N BIT(3)
+#define QCA955X_SGMII_RESET_HW_RX_125M_N BIT(4)
+
#define QCA955X_SGMII_SERDES_LOCK_DETECT_STATUS BIT(15)
#define QCA955X_SGMII_SERDES_RES_CALIBRATION_SHIFT 23
#define QCA955X_SGMII_SERDES_RES_CALIBRATION_MASK 0xf
+
+#define QCA955X_MR_AN_CONTROL_SPEED_SEL1 BIT(6)
+#define QCA955X_MR_AN_CONTROL_DUPLEX_MODE BIT(8)
+#define QCA955X_MR_AN_CONTROL_RESTART_AN BIT(9)
+#define QCA955X_MR_AN_CONTROL_POWER_DOWN BIT(11)
+#define QCA955X_MR_AN_CONTROL_AN_ENABLE BIT(12)
+#define QCA955X_MR_AN_CONTROL_SPEED_SEL0 BIT(13)
+#define QCA955X_MR_AN_CONTROL_LOOPBACK BIT(14)
+#define QCA955X_MR_AN_CONTROL_PHY_RESET BIT(15)
+
+#define QCA955X_MR_AN_STATUS_EXT_CAP BIT(0)
+#define QCA955X_MR_AN_STATUS_LINK_UP BIT(2)
+#define QCA955X_MR_AN_STATUS_AN_ABILITY BIT(3)
+#define QCA955X_MR_AN_STATUS_REMOTE_FAULT BIT(4)
+#define QCA955X_MR_AN_STATUS_AN_COMPLETE BIT(5)
+#define QCA955X_MR_AN_STATUS_NO_PREAMBLE BIT(6)
+#define QCA955X_MR_AN_STATUS_BASE_PAGE BIT(7)
+
+#define QCA955X_SGMII_CONFIG_MODE_CTRL_SHIFT 0
+#define QCA955X_SGMII_CONFIG_MODE_CTRL_MASK 0x7
+#define QCA955X_SGMII_CONFIG_ENABLE_SGMII_TX_PAUSE BIT(3)
+#define QCA955X_SGMII_CONFIG_MR_REG4_CHANGED BIT(4)
+#define QCA955X_SGMII_CONFIG_FORCE_SPEED BIT(5)
+#define QCA955X_SGMII_CONFIG_SPEED_SHIFT 6
+#define QCA955X_SGMII_CONFIG_SPEED_MASK 0xc0
+#define QCA955X_SGMII_CONFIG_REMOTE_PHY_LOOPBACK BIT(8)
+#define QCA955X_SGMII_CONFIG_NEXT_PAGE_LOADED BIT(9)
+#define QCA955X_SGMII_CONFIG_MDIO_ENABLE BIT(10)
+#define QCA955X_SGMII_CONFIG_MDIO_PULSE BIT(11)
+#define QCA955X_SGMII_CONFIG_MDIO_COMPLETE BIT(12)
+#define QCA955X_SGMII_CONFIG_PRBS_ENABLE BIT(13)
+#define QCA955X_SGMII_CONFIG_BERT_ENABLE BIT(14)
+
+#define QCA955X_SGMII_DEBUG_TX_STATE_MASK 0xff
+#define QCA955X_SGMII_DEBUG_TX_STATE_SHIFT 0
+#define QCA955X_SGMII_DEBUG_RX_STATE_MASK 0xff00
+#define QCA955X_SGMII_DEBUG_RX_STATE_SHIFT 8
+#define QCA955X_SGMII_DEBUG_RX_SYNC_STATE_MASK 0xff0000
+#define QCA955X_SGMII_DEBUG_RX_SYNC_STATE_SHIFT 16
+#define QCA955X_SGMII_DEBUG_ARB_STATE_MASK 0xf000000
+#define QCA955X_SGMII_DEBUG_ARB_STATE_SHIFT 24
+
/*
* QCA956X GMAC Interface
*/

View File

@ -1,52 +0,0 @@
--- a/arch/mips/ath79/clock.c
+++ b/arch/mips/ath79/clock.c
@@ -40,6 +40,7 @@ static const char * const clk_names[ATH7
[ATH79_CLK_AHB] = "ahb",
[ATH79_CLK_REF] = "ref",
[ATH79_CLK_MDIO] = "mdio",
+ [ATH79_CLK_UART1] = "uart1",
};
static const char * __init ath79_clk_name(int type)
@@ -344,6 +345,9 @@ static void __init ar934x_clocks_init(vo
if (clk_ctrl & AR934X_PLL_SWITCH_CLOCK_CONTROL_MDIO_CLK_SEL)
ath79_set_clk(ATH79_CLK_MDIO, 100 * 1000 * 1000);
+ if (clk_ctrl & AR934X_PLL_SWITCH_CLOCK_CONTROL_UART1_CLK_SEL)
+ ath79_set_clk(ATH79_CLK_UART1, 100 * 1000 * 1000);
+
iounmap(dpll_base);
}
@@ -649,6 +653,9 @@ static void __init ath79_clocks_init_dt(
if (!clks[ATH79_CLK_MDIO])
clks[ATH79_CLK_MDIO] = clks[ATH79_CLK_REF];
+ if (!clks[ATH79_CLK_UART1])
+ clks[ATH79_CLK_UART1] = clks[ATH79_CLK_REF];
+
if (of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data)) {
pr_err("%pOF: could not register clk provider\n", np);
goto err_iounmap;
--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
@@ -348,6 +348,7 @@
#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24)
#define AR934X_PLL_SWITCH_CLOCK_CONTROL_MDIO_CLK_SEL BIT(6)
+#define AR934X_PLL_SWITCH_CLOCK_CONTROL_UART1_CLK_SEL BIT(7)
#define QCA953X_PLL_CPU_CONFIG_REG 0x00
#define QCA953X_PLL_DDR_CONFIG_REG 0x04
--- a/include/dt-bindings/clock/ath79-clk.h
+++ b/include/dt-bindings/clock/ath79-clk.h
@@ -11,7 +11,8 @@
#define ATH79_CLK_AHB 2
#define ATH79_CLK_REF 3
#define ATH79_CLK_MDIO 4
+#define ATH79_CLK_UART1 5
-#define ATH79_CLK_END 5
+#define ATH79_CLK_END 6
#endif /* __DT_BINDINGS_ATH79_CLK_H */

View File

@ -1,18 +0,0 @@
HACK: register the GPIO driver earlier to ensure that gpio_request calls
from mach files succeed.
--- a/drivers/gpio/gpio-ath79.c
+++ b/drivers/gpio/gpio-ath79.c
@@ -310,7 +310,11 @@ static struct platform_driver ath79_gpio
.probe = ath79_gpio_probe,
};
-module_platform_driver(ath79_gpio_driver);
+static int __init ath79_gpio_init(void)
+{
+ return platform_driver_register(&ath79_gpio_driver);
+}
+postcore_initcall(ath79_gpio_init);
MODULE_DESCRIPTION("Atheros AR71XX/AR724X/AR913X GPIO API support");
MODULE_LICENSE("GPL v2");

View File

@ -1,9 +0,0 @@
--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
@@ -1376,5 +1376,6 @@
#define QCA956X_SGMII_CONFIG_MODE_CTRL_SHIFT 0
#define QCA956X_SGMII_CONFIG_MODE_CTRL_MASK 0x7
+#define QCA956X_SGMII_CONFIG_MODE_CTRL_SGMII_MAC 0x2
#endif /* __ASM_MACH_AR71XX_REGS_H */

View File

@ -1,283 +0,0 @@
From 7e161c423a232ef7ddf6c11b09ebe471dd5a23cf Mon Sep 17 00:00:00 2001
From: Chuanhong Guo <gch981213@gmail.com>
Date: Wed, 5 Feb 2020 18:25:37 +0800
Subject: [PATCH v4 1/2] spi: add driver for ar934x spi controller
This patch adds driver for SPI controller found in Qualcomm Atheros
AR934x/QCA95xx SoCs.
This controller is a superset of the already supported qca,ar7100-spi.
Besides the bit-bang mode in spi-ath79.c, this new controller added
a new "shift register" mode, allowing faster spi operations.
Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
---
drivers/spi/Kconfig | 7 ++
drivers/spi/Makefile | 1 +
drivers/spi/spi-ar934x.c | 235 +++++++++++++++++++++++++++++++++++++++
3 files changed, 243 insertions(+)
create mode 100644 drivers/spi/spi-ar934x.c
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -62,6 +62,13 @@ config SPI_ALTERA
help
This is the driver for the Altera SPI Controller.
+config SPI_AR934X
+ tristate "Qualcomm Atheros AR934X/QCA95XX SPI controller driver"
+ depends on ATH79 || COMPILE_TEST
+ help
+ This enables support for the SPI controller present on the
+ Qualcomm Atheros AR934X/QCA95XX SoCs.
+
config SPI_ATH79
tristate "Atheros AR71XX/AR724X/AR913X SPI controller driver"
depends on ATH79 || COMPILE_TEST
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_SPI_LOOPBACK_TEST) += spi-
# SPI master controller drivers (bus)
obj-$(CONFIG_SPI_ALTERA) += spi-altera.o
+obj-$(CONFIG_SPI_AR934X) += spi-ar934x.o
obj-$(CONFIG_SPI_ARMADA_3700) += spi-armada-3700.o
obj-$(CONFIG_SPI_ATMEL) += spi-atmel.o
obj-$(CONFIG_SPI_ATMEL_QUADSPI) += atmel-quadspi.o
--- /dev/null
+++ b/drivers/spi/spi-ar934x.c
@@ -0,0 +1,235 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// SPI controller driver for Qualcomm Atheros AR934x/QCA95xx SoCs
+//
+// Copyright (C) 2020 Chuanhong Guo <gch981213@gmail.com>
+//
+// Based on spi-mt7621.c:
+// Copyright (C) 2011 Sergiy <piratfm@gmail.com>
+// Copyright (C) 2011-2013 Gabor Juhos <juhosg@openwrt.org>
+// Copyright (C) 2014-2015 Felix Fietkau <nbd@nbd.name>
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/spi/spi.h>
+
+#define DRIVER_NAME "spi-ar934x"
+
+#define AR934X_SPI_REG_FS 0x00
+#define AR934X_SPI_ENABLE BIT(0)
+
+#define AR934X_SPI_REG_IOC 0x08
+#define AR934X_SPI_IOC_INITVAL 0x70000
+
+#define AR934X_SPI_REG_CTRL 0x04
+#define AR934X_SPI_CLK_MASK GENMASK(5, 0)
+
+#define AR934X_SPI_DATAOUT 0x10
+
+#define AR934X_SPI_REG_SHIFT_CTRL 0x14
+#define AR934X_SPI_SHIFT_EN BIT(31)
+#define AR934X_SPI_SHIFT_CS(n) BIT(28 + (n))
+#define AR934X_SPI_SHIFT_TERM 26
+#define AR934X_SPI_SHIFT_VAL(cs, term, count) \
+ (AR934X_SPI_SHIFT_EN | AR934X_SPI_SHIFT_CS(cs) | \
+ (term) << AR934X_SPI_SHIFT_TERM | (count))
+
+#define AR934X_SPI_DATAIN 0x18
+
+struct ar934x_spi {
+ struct spi_controller *ctlr;
+ void __iomem *base;
+ struct clk *clk;
+ unsigned int clk_freq;
+};
+
+static inline int ar934x_spi_clk_div(struct ar934x_spi *sp, unsigned int freq)
+{
+ int div = DIV_ROUND_UP(sp->clk_freq, freq * 2) - 1;
+
+ if (div < 0)
+ return 0;
+ else if (div > AR934X_SPI_CLK_MASK)
+ return -EINVAL;
+ else
+ return div;
+}
+
+static int ar934x_spi_setup(struct spi_device *spi)
+{
+ struct ar934x_spi *sp = spi_controller_get_devdata(spi->master);
+
+ if ((spi->max_speed_hz == 0) ||
+ (spi->max_speed_hz > (sp->clk_freq / 2))) {
+ spi->max_speed_hz = sp->clk_freq / 2;
+ } else if (spi->max_speed_hz < (sp->clk_freq / 128)) {
+ dev_err(&spi->dev, "spi clock is too low\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int ar934x_spi_transfer_one_message(struct spi_controller *master,
+ struct spi_message *m)
+{
+ struct ar934x_spi *sp = spi_controller_get_devdata(master);
+ struct spi_transfer *t = NULL;
+ struct spi_device *spi = m->spi;
+ unsigned long trx_done, trx_cur;
+ int stat = 0;
+ u8 term = 0;
+ int div, i;
+ u32 reg;
+ const u8 *tx_buf;
+ u8 *buf;
+
+ m->actual_length = 0;
+ list_for_each_entry(t, &m->transfers, transfer_list) {
+ if (t->speed_hz)
+ div = ar934x_spi_clk_div(sp, t->speed_hz);
+ else
+ div = ar934x_spi_clk_div(sp, spi->max_speed_hz);
+ if (div < 0) {
+ stat = -EIO;
+ goto msg_done;
+ }
+
+ reg = ioread32(sp->base + AR934X_SPI_REG_CTRL);
+ reg &= ~AR934X_SPI_CLK_MASK;
+ reg |= div;
+ iowrite32(reg, sp->base + AR934X_SPI_REG_CTRL);
+ iowrite32(0, sp->base + AR934X_SPI_DATAOUT);
+
+ for (trx_done = 0; trx_done < t->len; trx_done += 4) {
+ trx_cur = t->len - trx_done;
+ if (trx_cur > 4)
+ trx_cur = 4;
+ else if (list_is_last(&t->transfer_list, &m->transfers))
+ term = 1;
+
+ if (t->tx_buf) {
+ tx_buf = t->tx_buf + trx_done;
+ reg = tx_buf[0];
+ for (i = 1; i < trx_cur; i++)
+ reg = reg << 8 | tx_buf[i];
+ iowrite32(reg, sp->base + AR934X_SPI_DATAOUT);
+ }
+
+ reg = AR934X_SPI_SHIFT_VAL(spi->chip_select, term,
+ trx_cur * 8);
+ iowrite32(reg, sp->base + AR934X_SPI_REG_SHIFT_CTRL);
+ stat = readl_poll_timeout(
+ sp->base + AR934X_SPI_REG_SHIFT_CTRL, reg,
+ !(reg & AR934X_SPI_SHIFT_EN), 0, 5);
+ if (stat < 0)
+ goto msg_done;
+
+ if (t->rx_buf) {
+ reg = ioread32(sp->base + AR934X_SPI_DATAIN);
+ buf = t->rx_buf + trx_done;
+ for (i = 0; i < trx_cur; i++) {
+ buf[trx_cur - i - 1] = reg & 0xff;
+ reg >>= 8;
+ }
+ }
+ }
+ m->actual_length += t->len;
+ }
+
+msg_done:
+ m->status = stat;
+ spi_finalize_current_message(master);
+
+ return 0;
+}
+
+static const struct of_device_id ar934x_spi_match[] = {
+ { .compatible = "qca,ar934x-spi" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ar934x_spi_match);
+
+static int ar934x_spi_probe(struct platform_device *pdev)
+{
+ struct spi_controller *ctlr;
+ struct ar934x_spi *sp;
+ void __iomem *base;
+ struct clk *clk;
+ int ret;
+
+ base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(clk)) {
+ dev_err(&pdev->dev, "failed to get clock\n");
+ return PTR_ERR(clk);
+ }
+
+ ret = clk_prepare_enable(clk);
+ if (ret)
+ return ret;
+
+ ctlr = spi_alloc_master(&pdev->dev, sizeof(*sp));
+ if (!ctlr) {
+ dev_info(&pdev->dev, "failed to allocate spi controller\n");
+ return -ENOMEM;
+ }
+
+ /* disable flash mapping and expose spi controller registers */
+ iowrite32(AR934X_SPI_ENABLE, base + AR934X_SPI_REG_FS);
+ /* restore pins to default state: CSn=1 DO=CLK=0 */
+ iowrite32(AR934X_SPI_IOC_INITVAL, base + AR934X_SPI_REG_IOC);
+
+ ctlr->mode_bits = SPI_LSB_FIRST;
+ ctlr->setup = ar934x_spi_setup;
+ ctlr->transfer_one_message = ar934x_spi_transfer_one_message;
+ ctlr->bits_per_word_mask = SPI_BPW_MASK(8);
+ ctlr->dev.of_node = pdev->dev.of_node;
+ ctlr->num_chipselect = 3;
+
+ dev_set_drvdata(&pdev->dev, ctlr);
+
+ sp = spi_controller_get_devdata(ctlr);
+ sp->base = base;
+ sp->clk = clk;
+ sp->clk_freq = clk_get_rate(clk);
+ sp->ctlr = ctlr;
+
+ return devm_spi_register_controller(&pdev->dev, ctlr);
+}
+
+static int ar934x_spi_remove(struct platform_device *pdev)
+{
+ struct spi_controller *ctlr;
+ struct ar934x_spi *sp;
+
+ ctlr = dev_get_drvdata(&pdev->dev);
+ sp = spi_controller_get_devdata(ctlr);
+
+ clk_disable_unprepare(sp->clk);
+
+ return 0;
+}
+
+static struct platform_driver ar934x_spi_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ .of_match_table = ar934x_spi_match,
+ },
+ .probe = ar934x_spi_probe,
+ .remove = ar934x_spi_remove,
+};
+
+module_platform_driver(ar934x_spi_driver);
+
+MODULE_DESCRIPTION("SPI controller driver for Qualcomm Atheros AR934x/QCA95xx");
+MODULE_AUTHOR("Chuanhong Guo <gch981213@gmail.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRIVER_NAME);

View File

@ -1,267 +0,0 @@
From patchwork Fri Feb 21 21:23:31 2020
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
X-Patchwork-Id: 1198835
Date: Fri, 21 Feb 2020 22:23:31 +0100
From: Daniel Golle <daniel@makrotopia.org>
To: linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Jiri Slaby <jslaby@suse.com>, Petr =?utf-8?q?=C5=A0tetiar?= <ynezz@true.cz>,
Chuanhong Guo <gch981213@gmail.com>, Piotr Dymacz <pepe2k@gmail.com>
Subject: [PATCH v2] serial: ar933x_uart: add RS485 support
Message-ID: <20200221212331.GA21467@makrotopia.org>
MIME-Version: 1.0
Content-Disposition: inline
Sender: linux-kernel-owner@vger.kernel.org
Precedence: bulk
List-ID: <linux-kernel.vger.kernel.org>
X-Mailing-List: linux-kernel@vger.kernel.org
Emulate half-duplex operation and use mctrl_gpio to add support for
RS485 tranceiver with transmit/receive switch hooked to RTS GPIO line.
This is needed to make use of the RS485 port found on Teltonika RUT955.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
v2: use bool to indicate ongoing half-duplex send, use it afterwards
to decide whether we've just been in a send operation.
drivers/tty/serial/Kconfig | 1 +
drivers/tty/serial/ar933x_uart.c | 113 +++++++++++++++++++++++++++++--
2 files changed, 108 insertions(+), 6 deletions(-)
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1280,6 +1280,7 @@ config SERIAL_AR933X
tristate "AR933X serial port support"
depends on HAVE_CLK && ATH79
select SERIAL_CORE
+ select SERIAL_MCTRL_GPIO if GPIOLIB
help
If you have an Atheros AR933X SOC based board and want to use the
built-in UART of the SoC, say Y to this option.
--- a/drivers/tty/serial/ar933x_uart.c
+++ b/drivers/tty/serial/ar933x_uart.c
@@ -13,6 +13,7 @@
#include <linux/console.h>
#include <linux/sysrq.h>
#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_platform.h>
@@ -29,6 +30,8 @@
#include <asm/mach-ath79/ar933x_uart.h>
+#include "serial_mctrl_gpio.h"
+
#define DRIVER_NAME "ar933x-uart"
#define AR933X_UART_MAX_SCALE 0xff
@@ -47,6 +50,8 @@ struct ar933x_uart_port {
unsigned int min_baud;
unsigned int max_baud;
struct clk *clk;
+ struct mctrl_gpios *gpios;
+ struct gpio_desc *rts_gpiod;
};
static inline unsigned int ar933x_uart_read(struct ar933x_uart_port *up,
@@ -100,6 +105,18 @@ static inline void ar933x_uart_stop_tx_i
ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
}
+static inline void ar933x_uart_start_rx_interrupt(struct ar933x_uart_port *up)
+{
+ up->ier |= AR933X_UART_INT_RX_VALID;
+ ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
+}
+
+static inline void ar933x_uart_stop_rx_interrupt(struct ar933x_uart_port *up)
+{
+ up->ier &= ~AR933X_UART_INT_RX_VALID;
+ ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
+}
+
static inline void ar933x_uart_putc(struct ar933x_uart_port *up, int ch)
{
unsigned int rdata;
@@ -125,11 +142,21 @@ static unsigned int ar933x_uart_tx_empty
static unsigned int ar933x_uart_get_mctrl(struct uart_port *port)
{
- return TIOCM_CAR;
+ struct ar933x_uart_port *up =
+ container_of(port, struct ar933x_uart_port, port);
+ int ret = TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
+
+ mctrl_gpio_get(up->gpios, &ret);
+
+ return ret;
}
static void ar933x_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
+ struct ar933x_uart_port *up =
+ container_of(port, struct ar933x_uart_port, port);
+
+ mctrl_gpio_set(up->gpios, mctrl);
}
static void ar933x_uart_start_tx(struct uart_port *port)
@@ -140,6 +167,37 @@ static void ar933x_uart_start_tx(struct
ar933x_uart_start_tx_interrupt(up);
}
+static void ar933x_uart_wait_tx_complete(struct ar933x_uart_port *up)
+{
+ unsigned int status;
+ unsigned int timeout = 60000;
+
+ /* Wait up to 60ms for the character(s) to be sent. */
+ do {
+ status = ar933x_uart_read(up, AR933X_UART_CS_REG);
+ if (--timeout == 0)
+ break;
+ udelay(1);
+ } while (status & AR933X_UART_CS_TX_BUSY);
+
+ if (timeout == 0)
+ dev_err(up->port.dev, "waiting for TX timed out\n");
+}
+
+static void ar933x_uart_rx_flush(struct ar933x_uart_port *up)
+{
+ unsigned int status;
+
+ /* clear RX_VALID interrupt */
+ ar933x_uart_write(up, AR933X_UART_INT_REG, AR933X_UART_INT_RX_VALID);
+
+ /* remove characters from the RX FIFO */
+ do {
+ ar933x_uart_write(up, AR933X_UART_DATA_REG, AR933X_UART_DATA_RX_CSR);
+ status = ar933x_uart_read(up, AR933X_UART_DATA_REG);
+ } while (status & AR933X_UART_DATA_RX_CSR);
+}
+
static void ar933x_uart_stop_tx(struct uart_port *port)
{
struct ar933x_uart_port *up =
@@ -153,8 +211,7 @@ static void ar933x_uart_stop_rx(struct u
struct ar933x_uart_port *up =
container_of(port, struct ar933x_uart_port, port);
- up->ier &= ~AR933X_UART_INT_RX_VALID;
- ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
+ ar933x_uart_stop_rx_interrupt(up);
}
static void ar933x_uart_break_ctl(struct uart_port *port, int break_state)
@@ -336,11 +393,20 @@ static void ar933x_uart_rx_chars(struct
static void ar933x_uart_tx_chars(struct ar933x_uart_port *up)
{
struct circ_buf *xmit = &up->port.state->xmit;
+ struct serial_rs485 *rs485conf = &up->port.rs485;
int count;
+ bool half_duplex_send = false;
if (uart_tx_stopped(&up->port))
return;
+ if ((rs485conf->flags & SER_RS485_ENABLED) &&
+ (up->port.x_char || !uart_circ_empty(xmit))) {
+ ar933x_uart_stop_rx_interrupt(up);
+ gpiod_set_value(up->rts_gpiod, !!(rs485conf->flags & SER_RS485_RTS_ON_SEND));
+ half_duplex_send = true;
+ }
+
count = up->port.fifosize;
do {
unsigned int rdata;
@@ -368,8 +434,14 @@ static void ar933x_uart_tx_chars(struct
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
uart_write_wakeup(&up->port);
- if (!uart_circ_empty(xmit))
+ if (!uart_circ_empty(xmit)) {
ar933x_uart_start_tx_interrupt(up);
+ } else if (half_duplex_send) {
+ ar933x_uart_wait_tx_complete(up);
+ ar933x_uart_rx_flush(up);
+ ar933x_uart_start_rx_interrupt(up);
+ gpiod_set_value(up->rts_gpiod, !!(rs485conf->flags & SER_RS485_RTS_AFTER_SEND));
+ }
}
static irqreturn_t ar933x_uart_interrupt(int irq, void *dev_id)
@@ -427,8 +499,7 @@ static int ar933x_uart_startup(struct ua
AR933X_UART_CS_TX_READY_ORIDE | AR933X_UART_CS_RX_READY_ORIDE);
/* Enable RX interrupts */
- up->ier = AR933X_UART_INT_RX_VALID;
- ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
+ ar933x_uart_start_rx_interrupt(up);
spin_unlock_irqrestore(&up->port.lock, flags);
@@ -511,6 +582,21 @@ static const struct uart_ops ar933x_uart
.verify_port = ar933x_uart_verify_port,
};
+static int ar933x_config_rs485(struct uart_port *port,
+ struct serial_rs485 *rs485conf)
+{
+ struct ar933x_uart_port *up =
+ container_of(port, struct ar933x_uart_port, port);
+
+ if ((rs485conf->flags & SER_RS485_ENABLED) &&
+ !up->rts_gpiod) {
+ dev_err(port->dev, "RS485 needs rts-gpio\n");
+ return 1;
+ }
+ port->rs485 = *rs485conf;
+ return 0;
+}
+
#ifdef CONFIG_SERIAL_AR933X_CONSOLE
static struct ar933x_uart_port *
ar933x_console_ports[CONFIG_SERIAL_AR933X_NR_UARTS];
@@ -680,6 +766,8 @@ static int ar933x_uart_probe(struct plat
goto err_disable_clk;
}
+ uart_get_rs485_mode(&pdev->dev, &port->rs485);
+
port->mapbase = mem_res->start;
port->line = id;
port->irq = irq_res->start;
@@ -690,6 +778,7 @@ static int ar933x_uart_probe(struct plat
port->regshift = 2;
port->fifosize = AR933X_UART_FIFO_SIZE;
port->ops = &ar933x_uart_ops;
+ port->rs485_config = ar933x_config_rs485;
baud = ar933x_uart_get_baud(port->uartclk, AR933X_UART_MAX_SCALE, 1);
up->min_baud = max_t(unsigned int, baud, AR933X_UART_MIN_BAUD);
@@ -697,6 +786,18 @@ static int ar933x_uart_probe(struct plat
baud = ar933x_uart_get_baud(port->uartclk, 0, AR933X_UART_MAX_STEP);
up->max_baud = min_t(unsigned int, baud, AR933X_UART_MAX_BAUD);
+ up->gpios = mctrl_gpio_init(port, 0);
+ if (IS_ERR(up->gpios) && PTR_ERR(up->gpios) != -ENOSYS)
+ return PTR_ERR(up->gpios);
+
+ up->rts_gpiod = mctrl_gpio_to_gpiod(up->gpios, UART_GPIO_RTS);
+
+ if ((port->rs485.flags & SER_RS485_ENABLED) &&
+ !up->rts_gpiod) {
+ dev_err(&pdev->dev, "lacking rts-gpio, disabling RS485\n");
+ port->rs485.flags &= ~SER_RS485_ENABLED;
+ }
+
#ifdef CONFIG_SERIAL_AR933X_CONSOLE
ar933x_console_ports[up->port.line] = up;
#endif

View File

@ -1,130 +0,0 @@
From: David Bauer <mail@david-bauer.net>
Date: Sat, 11 Apr 2020 14:03:12 +0200
Subject: MIPS: pci-ar724x: add QCA9550 reset sequence
The QCA9550 family of SoCs have a slightly different reset
sequence compared to older chips.
Normally the bootloader performs this sequence, however
some bootloader implementation expect the operating system
to clear the reset.
Also get the resets from OF to support handling of the second
PCIe root-complex on the QCA9558.
Signed-off-by: David Bauer <mail@david-bauer.net>
--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
@@ -391,6 +391,7 @@
#define QCA955X_PLL_CPU_CONFIG_REG 0x00
#define QCA955X_PLL_DDR_CONFIG_REG 0x04
#define QCA955X_PLL_CLK_CTRL_REG 0x08
+#define QCA955X_PLL_PCIE_CONFIG_REG 0x0c
#define QCA955X_PLL_ETH_XMII_CONTROL_REG 0x28
#define QCA955X_PLL_ETH_SGMII_CONTROL_REG 0x48
#define QCA955X_PLL_ETH_SGMII_SERDES_REG 0x4c
@@ -476,6 +477,9 @@
#define QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_CPUPLL BIT(21)
#define QCA956X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24)
+#define QCA955X_PLL_PCIE_CONFIG_PLL_PWD BIT(30)
+#define QCA955X_PLL_PCIE_CONFIG_PLL_BYPASS BIT(16)
+
#define QCA956X_PLL_SWITCH_CLOCK_SPARE_I2C_CLK_SELB BIT(5)
#define QCA956X_PLL_SWITCH_CLOCK_SPARE_MDIO_CLK_SEL0_1 BIT(6)
#define QCA956X_PLL_SWITCH_CLOCK_SPARE_UART1_CLK_SEL BIT(7)
--- a/arch/mips/pci/pci-ar724x.c
+++ b/arch/mips/pci/pci-ar724x.c
@@ -8,6 +8,7 @@
#include <linux/irq.h>
#include <linux/pci.h>
+#include <linux/reset.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
@@ -55,6 +56,9 @@ struct ar724x_pci_controller {
struct irq_domain *domain;
struct resource io_res;
struct resource mem_res;
+
+ struct reset_control *hc_reset;
+ struct reset_control *phy_reset;
};
static struct irq_chip ar724x_pci_irq_chip;
@@ -340,18 +344,30 @@ static void ar724x_pci_hw_init(struct ar
int wait = 0;
/* deassert PCIe host controller and PCIe PHY reset */
- ath79_device_reset_clear(AR724X_RESET_PCIE);
- ath79_device_reset_clear(AR724X_RESET_PCIE_PHY);
+ reset_control_deassert(apc->hc_reset);
+ reset_control_deassert(apc->phy_reset);
- /* remove the reset of the PCIE PLL */
- ppl = ath79_pll_rr(AR724X_PLL_REG_PCIE_CONFIG);
- ppl &= ~AR724X_PLL_REG_PCIE_CONFIG_PPL_RESET;
- ath79_pll_wr(AR724X_PLL_REG_PCIE_CONFIG, ppl);
-
- /* deassert bypass for the PCIE PLL */
- ppl = ath79_pll_rr(AR724X_PLL_REG_PCIE_CONFIG);
- ppl &= ~AR724X_PLL_REG_PCIE_CONFIG_PPL_BYPASS;
- ath79_pll_wr(AR724X_PLL_REG_PCIE_CONFIG, ppl);
+ if (of_device_is_compatible(apc->np, "qcom,qca9550-pci")) {
+ /* remove the reset of the PCIE PLL */
+ ppl = ath79_pll_rr(QCA955X_PLL_PCIE_CONFIG_REG);
+ ppl &= ~QCA955X_PLL_PCIE_CONFIG_PLL_PWD;
+ ath79_pll_wr(QCA955X_PLL_PCIE_CONFIG_REG, ppl);
+
+ /* deassert bypass for the PCIE PLL */
+ ppl = ath79_pll_rr(QCA955X_PLL_PCIE_CONFIG_REG);
+ ppl &= ~QCA955X_PLL_PCIE_CONFIG_PLL_BYPASS;
+ ath79_pll_wr(QCA955X_PLL_PCIE_CONFIG_REG, ppl);
+ } else {
+ /* remove the reset of the PCIE PLL */
+ ppl = ath79_pll_rr(AR724X_PLL_REG_PCIE_CONFIG);
+ ppl &= ~AR724X_PLL_REG_PCIE_CONFIG_PPL_RESET;
+ ath79_pll_wr(AR724X_PLL_REG_PCIE_CONFIG, ppl);
+
+ /* deassert bypass for the PCIE PLL */
+ ppl = ath79_pll_rr(AR724X_PLL_REG_PCIE_CONFIG);
+ ppl &= ~AR724X_PLL_REG_PCIE_CONFIG_PPL_BYPASS;
+ ath79_pll_wr(AR724X_PLL_REG_PCIE_CONFIG, ppl);
+ }
/* set PCIE Application Control to ready */
app = __raw_readl(apc->ctrl_base + AR724X_PCI_REG_APP);
@@ -399,6 +415,14 @@ static int ar724x_pci_probe(struct platf
if (apc->irq < 0)
return -EINVAL;
+ apc->hc_reset = devm_reset_control_get_exclusive(&pdev->dev, "hc");
+ if (IS_ERR(apc->hc_reset))
+ return PTR_ERR(apc->hc_reset);
+
+ apc->phy_reset = devm_reset_control_get_exclusive(&pdev->dev, "phy");
+ if (IS_ERR(apc->phy_reset))
+ return PTR_ERR(apc->phy_reset);
+
apc->np = pdev->dev.of_node;
apc->pci_controller.pci_ops = &ar724x_pci_ops;
apc->pci_controller.io_resource = &apc->io_res;
@@ -409,7 +433,7 @@ static int ar724x_pci_probe(struct platf
* Do the full PCIE Root Complex Initialization Sequence if the PCIe
* host controller is in reset.
*/
- if (ath79_reset_rr(AR724X_RESET_REG_RESET_MODULE) & AR724X_RESET_PCIE)
+ if (reset_control_status(apc->hc_reset))
ar724x_pci_hw_init(apc);
apc->link_up = ar724x_pci_check_link(apc);
@@ -427,6 +451,7 @@ static int ar724x_pci_probe(struct platf
static const struct of_device_id ar724x_pci_ids[] = {
{ .compatible = "qcom,ar7240-pci" },
+ { .compatible = "qcom,qca9550-pci" },
{},
};

View File

@ -1,27 +0,0 @@
--- a/drivers/mtd/parsers/Makefile
+++ b/drivers/mtd/parsers/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_MTD_OF_PARTS) += ofpart.o
ofpart-y += ofpart_core.o
ofpart-$(CONFIG_MTD_OF_PARTS_BCM4908) += ofpart_bcm4908.o
ofpart-$(CONFIG_MTD_OF_PARTS_LINKSYS_NS)+= ofpart_linksys_ns.o
+obj-$(CONFIG_MTD_PARSER_CYBERTAN) += parser_cybertan.o
obj-$(CONFIG_MTD_PARSER_IMAGETAG) += parser_imagetag.o
obj-$(CONFIG_MTD_AFS_PARTS) += afs.o
obj-$(CONFIG_MTD_PARSER_TRX) += parser_trx.o
--- a/drivers/mtd/parsers/Kconfig
+++ b/drivers/mtd/parsers/Kconfig
@@ -102,6 +102,14 @@ config MTD_OF_PARTS_LINKSYS_NS
two "firmware" partitions. Currently used firmware has to be detected
using CFE environment variable.
+config MTD_PARSER_CYBERTAN
+ tristate "Parser for Cybertan format partitions"
+ depends on MTD && (ATH79 || COMPILE_TEST)
+ help
+ Cybertan has a proprietory header than encompasses a Broadcom trx
+ header. This driver will parse the header and take care of the
+ special offsets that result in the extra headers.
+
config MTD_PARSER_IMAGETAG
tristate "Parser for BCM963XX Image Tag format partitions"
depends on BCM63XX || BMIPS_GENERIC || COMPILE_TEST

View File

@ -1,68 +0,0 @@
From 8d8cdb4a6ccee5b62cc0dc64651c3946364514dc Mon Sep 17 00:00:00 2001
From: Luiz Angelo Daros de Luca <luizluca@gmail.com>
Date: Mon, 10 Feb 2020 16:11:27 -0300
Subject: [PATCH] spi: ath79: Implement the spi_mem interface
Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
---
drivers/spi/spi-ath79.c | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
--- a/drivers/spi/spi-ath79.c
+++ b/drivers/spi/spi-ath79.c
@@ -15,6 +15,7 @@
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/spi/spi.h>
+#include <linux/spi/spi-mem.h>
#include <linux/spi/spi_bitbang.h>
#include <linux/bitops.h>
#include <linux/clk.h>
@@ -133,6 +134,39 @@ static u32 ath79_spi_txrx_mode0(struct s
return ath79_spi_rr(sp, AR71XX_SPI_REG_RDS);
}
+static int ath79_exec_mem_op(struct spi_mem *mem,
+ const struct spi_mem_op *op)
+{
+ struct ath79_spi *sp = ath79_spidev_to_sp(mem->spi);
+
+ /* Ensures that reading is performed on device connected
+ to hardware cs0 */
+ if (mem->spi->chip_select || mem->spi->cs_gpiod)
+ return -ENOTSUPP;
+
+ /* Only use for fast-read op. */
+ if (op->cmd.opcode != 0x0b || op->data.dir != SPI_MEM_DATA_IN ||
+ op->addr.nbytes != 3 || op->dummy.nbytes != 1)
+ return -ENOTSUPP;
+
+ /* disable GPIO mode */
+ ath79_spi_wr(sp, AR71XX_SPI_REG_FS, 0);
+
+ memcpy_fromio(op->data.buf.in, sp->base + op->addr.val, op->data.nbytes);
+
+ /* enable GPIO mode */
+ ath79_spi_wr(sp, AR71XX_SPI_REG_FS, AR71XX_SPI_FS_GPIO);
+
+ /* restore IOC register */
+ ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
+
+ return 0;
+}
+
+static const struct spi_controller_mem_ops ath79_mem_ops = {
+ .exec_op = ath79_exec_mem_op,
+};
+
static int ath79_spi_probe(struct platform_device *pdev)
{
struct spi_master *master;
@@ -164,6 +198,7 @@ static int ath79_spi_probe(struct platfo
ret = PTR_ERR(sp->base);
goto err_put_master;
}
+ master->mem_ops = &ath79_mem_ops;
sp->clk = devm_clk_get(&pdev->dev, "ahb");
if (IS_ERR(sp->clk)) {

View File

@ -1,26 +0,0 @@
From e2e9f6d9f9bd7449ff113c157b639ce1a24b9d3f Mon Sep 17 00:00:00 2001
From: David Bauer <mail@david-bauer.net>
Date: Sat, 24 Apr 2021 16:14:48 +0200
Subject: [PATCH 2/2] spi: ath79: set number of chipselect lines
All chipsets from AR7100 up to QCA9563 have three dedicated chipselect
lines for the integrated SPI controller. Remove the number of
chipselects from the platform data, as there is no need to manually set
this to a different value.
Signed-off-by: David Bauer <mail@david-bauer.net>
---
drivers/spi/spi-ath79.c | 2 +-
include/linux/platform_data/spi-ath79.h | 1 -
2 files changed, 1 insertion(+), 2 deletions(-)
--- a/drivers/spi/spi-ath79.c
+++ b/drivers/spi/spi-ath79.c
@@ -187,6 +187,7 @@ static int ath79_spi_probe(struct platfo
master->use_gpio_descriptors = true;
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
master->flags = SPI_MASTER_GPIO_SS;
+ master->num_chipselect = 3;
sp->bitbang.master = master;
sp->bitbang.chipselect = ath79_spi_chipselect;

View File

@ -1,28 +0,0 @@
--- a/drivers/net/ethernet/atheros/Kconfig
+++ b/drivers/net/ethernet/atheros/Kconfig
@@ -17,13 +17,7 @@ config NET_VENDOR_ATHEROS
if NET_VENDOR_ATHEROS
-config AG71XX
- tristate "Atheros AR7XXX/AR9XXX built-in ethernet mac support"
- depends on ATH79
- select PHYLIB
- help
- If you wish to compile a kernel for AR7XXX/91XXX and enable
- ethernet support, then you should always answer Y to this.
+source "drivers/net/ethernet/atheros/ag71xx/Kconfig"
config ATL2
tristate "Atheros L2 Fast Ethernet support"
--- a/drivers/net/ethernet/atheros/Makefile
+++ b/drivers/net/ethernet/atheros/Makefile
@@ -3,7 +3,7 @@
# Makefile for the Atheros network device drivers.
#
-obj-$(CONFIG_AG71XX) += ag71xx.o
+obj-$(CONFIG_AG71XX) += ag71xx/
obj-$(CONFIG_ATL1) += atlx/
obj-$(CONFIG_ATL2) += atlx/
obj-$(CONFIG_ATL1E) += atl1e/

View File

@ -1,16 +0,0 @@
--- a/drivers/net/phy/at803x.c
+++ b/drivers/net/phy/at803x.c
@@ -404,6 +404,13 @@ static int at803x_aneg_done(struct phy_d
if (!(phy_read(phydev, AT803X_PSSR) & AT803X_PSSR_MR_AN_COMPLETE)) {
phydev_warn(phydev, "803x_aneg_done: SGMII link is not ok\n");
aneg_done = 0;
+#ifdef CONFIG_OF_MDIO
+ if (phydev->mdio.dev.of_node &&
+ of_property_read_bool(phydev->mdio.dev.of_node,
+ "at803x-override-sgmii-link-check")) {
+ aneg_done = 1;
+ }
+#endif
}
/* switch back to copper page */
phy_write(phydev, AT803X_REG_CHIP_CONFIG, ccr | AT803X_BT_BX_REG_SEL);

View File

@ -1,12 +0,0 @@
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -80,8 +80,8 @@ obj-y += scsi/
obj-y += nvme/
obj-$(CONFIG_ATA) += ata/
obj-$(CONFIG_TARGET_CORE) += target/
-obj-$(CONFIG_MTD) += mtd/
obj-$(CONFIG_SPI) += spi/
+obj-$(CONFIG_MTD) += mtd/
obj-$(CONFIG_SPMI) += spmi/
obj-$(CONFIG_HSI) += hsi/
obj-$(CONFIG_SLIMBUS) += slimbus/

View File

@ -1,25 +0,0 @@
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -544,4 +544,12 @@ config MTD_NAND_DISKONCHIP_BBTWRITE
load time (assuming you build diskonchip as a module) with the module
parameter "inftl_bbt_write=1".
+config MTD_NAND_AR934X
+ tristate "Support for NAND controller on Qualcomm Atheros AR934x/QCA955x SoCs"
+ depends on ATH79 || COMPILE_TEST
+ depends on HAS_IOMEM
+ help
+ Enables support for NAND controller on Qualcomm Atheros SoCs.
+ This controller is found on AR934x and QCA955x SoCs.
+
endif # MTD_RAW_NAND
--- a/drivers/mtd/nand/raw/Makefile
+++ b/drivers/mtd/nand/raw/Makefile
@@ -57,6 +57,7 @@ obj-$(CONFIG_MTD_NAND_MXIC) += mxic_nan
obj-$(CONFIG_MTD_NAND_TEGRA) += tegra_nand.o
obj-$(CONFIG_MTD_NAND_STM32_FMC2) += stm32_fmc2_nand.o
obj-$(CONFIG_MTD_NAND_MESON) += meson_nand.o
+obj-$(CONFIG_MTD_NAND_AR934X) += ar934x_nand.o
nand-objs := nand_base.o nand_legacy.o nand_bbt.o nand_timings.o nand_ids.o
nand-objs += nand_onfi.o

View File

@ -1,28 +0,0 @@
From: Nick Hainke <vincent@systemli.org>
Date: Sun, 25 Oct 2020 00:52:47 +0200
Subject: [PATCH] ath79: fix block protection clearing
The block protection bits of macronix do not match the implementation.
The chip has 3 BP bits. Bit 5 is actually the third BP but here the
5th bit is SR_TB. Therefore the patch adds SR_TB to the mask. In the
4.19er kernel the whole register was simply set to 0.
The wrong implementation did not remove the block protection. This led
to jffs2 errors in the form of:
"jffs2: Newly-erased block contained word 0x19852003 at offset 0x..."
This caused inconsistent memory and other errors.
Suggested-by: David Bauer <mail@david-bauer.net>
Signed-off-by: Nick Hainke <vincent@systemli.org>
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -1987,7 +1987,7 @@ static int sr2_bit7_quad_enable(struct s
static int spi_nor_clear_sr_bp(struct spi_nor *nor)
{
int ret;
- u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
+ u8 mask = SR_TB | SR_BP2 | SR_BP1 | SR_BP0;
if (nor->flags & SNOR_F_HAS_4BIT_BP)
mask |= SR_BP3;

View File

@ -1,98 +0,0 @@
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/mangle-port.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2012 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * This file was derived from: inlude/asm-mips/mach-generic/mangle-port.h
+ * Copyright (C) 2003, 2004 Ralf Baechle
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef __ASM_MACH_ATH79_MANGLE_PORT_H
+#define __ASM_MACH_ATH79_MANGLE_PORT_H
+
+#ifdef CONFIG_PCI_AR71XX
+extern unsigned long (ath79_pci_swizzle_b)(unsigned long port);
+extern unsigned long (ath79_pci_swizzle_w)(unsigned long port);
+#else
+#define ath79_pci_swizzle_b(port) (port)
+#define ath79_pci_swizzle_w(port) (port)
+#endif
+
+#define __swizzle_addr_b(port) ath79_pci_swizzle_b(port)
+#define __swizzle_addr_w(port) ath79_pci_swizzle_w(port)
+#define __swizzle_addr_l(port) (port)
+#define __swizzle_addr_q(port) (port)
+
+# define ioswabb(a, x) (x)
+# define __mem_ioswabb(a, x) (x)
+# define ioswabw(a, x) (x)
+# define __mem_ioswabw(a, x) cpu_to_le16(x)
+# define ioswabl(a, x) (x)
+# define __mem_ioswabl(a, x) cpu_to_le32(x)
+# define ioswabq(a, x) (x)
+# define __mem_ioswabq(a, x) cpu_to_le64(x)
+
+#endif /* __ASM_MACH_ATH79_MANGLE_PORT_H */
--- a/arch/mips/pci/pci-ar71xx.c
+++ b/arch/mips/pci/pci-ar71xx.c
@@ -68,6 +68,45 @@ static const u32 ar71xx_pci_read_mask[8]
0, 0xff, 0xffff, 0, 0xffffffff, 0, 0, 0
};
+static unsigned long (*__ath79_pci_swizzle_b)(unsigned long port);
+static unsigned long (*__ath79_pci_swizzle_w)(unsigned long port);
+
+static inline bool ar71xx_is_pci_addr(unsigned long port)
+{
+ unsigned long phys = CPHYSADDR(port);
+
+ return (phys >= AR71XX_PCI_MEM_BASE &&
+ phys < AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE);
+}
+
+static unsigned long ar71xx_pci_swizzle_b(unsigned long port)
+{
+ return ar71xx_is_pci_addr(port) ? port ^ 3 : port;
+}
+
+static unsigned long ar71xx_pci_swizzle_w(unsigned long port)
+{
+ return ar71xx_is_pci_addr(port) ? port ^ 2 : port;
+}
+
+unsigned long ath79_pci_swizzle_b(unsigned long port)
+{
+ if (__ath79_pci_swizzle_b)
+ return __ath79_pci_swizzle_b(port);
+
+ return port;
+}
+EXPORT_SYMBOL(ath79_pci_swizzle_b);
+
+unsigned long ath79_pci_swizzle_w(unsigned long port)
+{
+ if (__ath79_pci_swizzle_w)
+ return __ath79_pci_swizzle_w(port);
+
+ return port;
+}
+EXPORT_SYMBOL(ath79_pci_swizzle_w);
+
static inline u32 ar71xx_pci_get_ble(int where, int size, int local)
{
u32 t;
@@ -276,6 +315,9 @@ static int ar71xx_pci_probe(struct platf
register_pci_controller(&apc->pci_ctrl);
+ __ath79_pci_swizzle_b = ar71xx_pci_swizzle_b;
+ __ath79_pci_swizzle_w = ar71xx_pci_swizzle_w;
+
return 0;
}

View File

@ -1,32 +0,0 @@
--- a/drivers/net/phy/mdio-bitbang.c
+++ b/drivers/net/phy/mdio-bitbang.c
@@ -152,7 +152,7 @@ static int mdiobb_cmd_addr(struct mdiobb
static int mdiobb_read(struct mii_bus *bus, int phy, int reg)
{
struct mdiobb_ctrl *ctrl = bus->priv;
- int ret, i;
+ int ret;
if (reg & MII_ADDR_C45) {
reg = mdiobb_cmd_addr(ctrl, phy, reg);
@@ -162,19 +162,7 @@ static int mdiobb_read(struct mii_bus *b
ctrl->ops->set_mdio_dir(ctrl, 0);
- /* check the turnaround bit: the PHY should be driving it to zero, if this
- * PHY is listed in phy_ignore_ta_mask as having broken TA, skip that
- */
- if (mdiobb_get_bit(ctrl) != 0 &&
- !(bus->phy_ignore_ta_mask & (1 << phy))) {
- /* PHY didn't drive TA low -- flush any bits it
- * may be trying to send.
- */
- for (i = 0; i < 32; i++)
- mdiobb_get_bit(ctrl);
-
- return 0xffff;
- }
+ mdiobb_get_bit(ctrl);
ret = mdiobb_get_num(ctrl, 16);
mdiobb_get_bit(ctrl);

View File

@ -1,61 +0,0 @@
From 66e584435ac0de6e0abeb6d7166fe4fe25d6bb73 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jogo@openwrt.org>
Date: Tue, 16 Jun 2015 13:15:08 +0200
Subject: [PATCH] phy/mdio-bitbang: prevent rescheduling during command
It seems some phys have some maximum timings for accessing the MDIO line,
resulting in bit errors under cpu stress. Prevent this from happening by
disabling interrupts when sending commands.
Signed-off-by: Jonas Gorski <jogo@openwrt.org>
---
drivers/net/phy/mdio-bitbang.c | 9 +++++++++
1 file changed, 9 insertions(+)
--- a/drivers/net/phy/mdio-bitbang.c
+++ b/drivers/net/phy/mdio-bitbang.c
@@ -14,6 +14,7 @@
* Vitaly Bordug <vbordug@ru.mvista.com>
*/
+#include <linux/irqflags.h>
#include <linux/module.h>
#include <linux/mdio-bitbang.h>
#include <linux/types.h>
@@ -153,7 +154,9 @@ static int mdiobb_read(struct mii_bus *b
{
struct mdiobb_ctrl *ctrl = bus->priv;
int ret;
+ unsigned long flags;
+ local_irq_save(flags);
if (reg & MII_ADDR_C45) {
reg = mdiobb_cmd_addr(ctrl, phy, reg);
mdiobb_cmd(ctrl, MDIO_C45_READ, phy, reg);
@@ -166,13 +169,17 @@ static int mdiobb_read(struct mii_bus *b
ret = mdiobb_get_num(ctrl, 16);
mdiobb_get_bit(ctrl);
+ local_irq_restore(flags);
+
return ret;
}
static int mdiobb_write(struct mii_bus *bus, int phy, int reg, u16 val)
{
struct mdiobb_ctrl *ctrl = bus->priv;
+ unsigned long flags;
+ local_irq_save(flags);
if (reg & MII_ADDR_C45) {
reg = mdiobb_cmd_addr(ctrl, phy, reg);
mdiobb_cmd(ctrl, MDIO_C45_WRITE, phy, reg);
@@ -187,6 +194,8 @@ static int mdiobb_write(struct mii_bus *
ctrl->ops->set_mdio_dir(ctrl, 0);
mdiobb_get_bit(ctrl);
+ local_irq_restore(flags);
+
return 0;
}

View File

@ -1,869 +0,0 @@
--- a/arch/mips/include/asm/checksum.h
+++ b/arch/mips/include/asm/checksum.h
@@ -134,26 +134,30 @@ static inline __sum16 ip_fast_csum(const
const unsigned int *stop = word + ihl;
unsigned int csum;
int carry;
+ unsigned int w;
- csum = word[0];
- csum += word[1];
- carry = (csum < word[1]);
+ csum = net_hdr_word(word++);
+
+ w = net_hdr_word(word++);
+ csum += w;
+ carry = (csum < w);
csum += carry;
- csum += word[2];
- carry = (csum < word[2]);
+ w = net_hdr_word(word++);
+ csum += w;
+ carry = (csum < w);
csum += carry;
- csum += word[3];
- carry = (csum < word[3]);
+ w = net_hdr_word(word++);
+ csum += w;
+ carry = (csum < w);
csum += carry;
- word += 4;
do {
- csum += *word;
- carry = (csum < *word);
+ w = net_hdr_word(word++);
+ csum += w;
+ carry = (csum < w);
csum += carry;
- word++;
} while (word != stop);
return csum_fold(csum);
@@ -214,73 +218,6 @@ static inline __sum16 ip_compute_csum(co
return csum_fold(csum_partial(buff, len, 0));
}
-#define _HAVE_ARCH_IPV6_CSUM
-static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
- const struct in6_addr *daddr,
- __u32 len, __u8 proto,
- __wsum sum)
-{
- __wsum tmp;
-
- __asm__(
- " .set push # csum_ipv6_magic\n"
- " .set noreorder \n"
- " .set noat \n"
- " addu %0, %5 # proto (long in network byte order)\n"
- " sltu $1, %0, %5 \n"
- " addu %0, $1 \n"
-
- " addu %0, %6 # csum\n"
- " sltu $1, %0, %6 \n"
- " lw %1, 0(%2) # four words source address\n"
- " addu %0, $1 \n"
- " addu %0, %1 \n"
- " sltu $1, %0, %1 \n"
-
- " lw %1, 4(%2) \n"
- " addu %0, $1 \n"
- " addu %0, %1 \n"
- " sltu $1, %0, %1 \n"
-
- " lw %1, 8(%2) \n"
- " addu %0, $1 \n"
- " addu %0, %1 \n"
- " sltu $1, %0, %1 \n"
-
- " lw %1, 12(%2) \n"
- " addu %0, $1 \n"
- " addu %0, %1 \n"
- " sltu $1, %0, %1 \n"
-
- " lw %1, 0(%3) \n"
- " addu %0, $1 \n"
- " addu %0, %1 \n"
- " sltu $1, %0, %1 \n"
-
- " lw %1, 4(%3) \n"
- " addu %0, $1 \n"
- " addu %0, %1 \n"
- " sltu $1, %0, %1 \n"
-
- " lw %1, 8(%3) \n"
- " addu %0, $1 \n"
- " addu %0, %1 \n"
- " sltu $1, %0, %1 \n"
-
- " lw %1, 12(%3) \n"
- " addu %0, $1 \n"
- " addu %0, %1 \n"
- " sltu $1, %0, %1 \n"
-
- " addu %0, $1 # Add final carry\n"
- " .set pop"
- : "=&r" (sum), "=&r" (tmp)
- : "r" (saddr), "r" (daddr),
- "0" (htonl(len)), "r" (htonl(proto)), "r" (sum));
-
- return csum_fold(sum);
-}
-
#include <asm-generic/checksum.h>
#endif /* CONFIG_GENERIC_CSUM */
--- a/include/uapi/linux/ip.h
+++ b/include/uapi/linux/ip.h
@@ -103,7 +103,7 @@ struct iphdr {
__be32 saddr;
__be32 daddr;
/*The options start here. */
-};
+} __attribute__((packed, aligned(2)));
struct ip_auth_hdr {
--- a/include/uapi/linux/ipv6.h
+++ b/include/uapi/linux/ipv6.h
@@ -131,7 +131,7 @@ struct ipv6hdr {
struct in6_addr saddr;
struct in6_addr daddr;
-};
+} __attribute__((packed, aligned(2)));
/* index values for the variables in ipv6_devconf */
--- a/include/uapi/linux/tcp.h
+++ b/include/uapi/linux/tcp.h
@@ -55,7 +55,7 @@ struct tcphdr {
__be16 window;
__sum16 check;
__be16 urg_ptr;
-};
+} __attribute__((packed, aligned(2)));
/*
* The union cast uses a gcc extension to avoid aliasing problems
@@ -65,7 +65,7 @@ struct tcphdr {
union tcp_word_hdr {
struct tcphdr hdr;
__be32 words[5];
-};
+} __attribute__((packed, aligned(2)));
#define tcp_flag_word(tp) ( ((union tcp_word_hdr *)(tp))->words [3])
--- a/include/uapi/linux/udp.h
+++ b/include/uapi/linux/udp.h
@@ -25,7 +25,7 @@ struct udphdr {
__be16 dest;
__be16 len;
__sum16 check;
-};
+} __attribute__((packed, aligned(2)));
/* UDP socket options */
#define UDP_CORK 1 /* Never send partially complete segments */
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -266,8 +266,8 @@ nf_ct_get_tuple(const struct sk_buff *sk
switch (l3num) {
case NFPROTO_IPV4:
- tuple->src.u3.ip = ap[0];
- tuple->dst.u3.ip = ap[1];
+ tuple->src.u3.ip = net_hdr_word(ap++);
+ tuple->dst.u3.ip = net_hdr_word(ap);
break;
case NFPROTO_IPV6:
memcpy(tuple->src.u3.ip6, ap, sizeof(tuple->src.u3.ip6));
--- a/include/uapi/linux/icmp.h
+++ b/include/uapi/linux/icmp.h
@@ -82,7 +82,7 @@ struct icmphdr {
} frag;
__u8 reserved[4];
} un;
-};
+} __attribute__((packed, aligned(2)));
/*
--- a/include/uapi/linux/in6.h
+++ b/include/uapi/linux/in6.h
@@ -43,7 +43,7 @@ struct in6_addr {
#define s6_addr16 in6_u.u6_addr16
#define s6_addr32 in6_u.u6_addr32
#endif
-};
+} __attribute__((packed, aligned(2)));
#endif /* __UAPI_DEF_IN6_ADDR */
#if __UAPI_DEF_SOCKADDR_IN6
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -35,6 +35,7 @@
#include <linux/ipsec.h>
#include <linux/times.h>
#include <linux/slab.h>
+#include <asm/unaligned.h>
#include <linux/uaccess.h>
#include <linux/ipv6.h>
#include <linux/icmpv6.h>
@@ -864,10 +865,10 @@ static void tcp_v6_send_response(const s
topt = (__be32 *)(t1 + 1);
if (tsecr) {
- *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
- (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP);
- *topt++ = htonl(tsval);
- *topt++ = htonl(tsecr);
+ put_unaligned_be32((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
+ (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP, topt++);
+ put_unaligned_be32(tsval, topt++);
+ put_unaligned_be32(tsecr, topt++);
}
#ifdef CONFIG_TCP_MD5SIG
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -6,6 +6,7 @@
#define ipv6_optlen(p) (((p)->hdrlen+1) << 3)
#define ipv6_authlen(p) (((p)->hdrlen+2) << 2)
+
/*
* This structure contains configuration options per IPv6 link.
*/
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -476,7 +476,7 @@ int ipv6_recv_error(struct sock *sk, str
ipv6_iface_scope_id(&sin->sin6_addr,
IP6CB(skb)->iif);
} else {
- ipv6_addr_set_v4mapped(*(__be32 *)(nh + serr->addr_offset),
+ ipv6_addr_set_v4mapped(net_hdr_word(nh + serr->addr_offset),
&sin->sin6_addr);
sin->sin6_scope_id = 0;
}
@@ -830,12 +830,12 @@ int ip6_datagram_send_ctl(struct net *ne
}
if (fl6->flowlabel&IPV6_FLOWINFO_MASK) {
- if ((fl6->flowlabel^*(__be32 *)CMSG_DATA(cmsg))&~IPV6_FLOWINFO_MASK) {
+ if ((fl6->flowlabel^net_hdr_word(CMSG_DATA(cmsg)))&~IPV6_FLOWINFO_MASK) {
err = -EINVAL;
goto exit_f;
}
}
- fl6->flowlabel = IPV6_FLOWINFO_MASK & *(__be32 *)CMSG_DATA(cmsg);
+ fl6->flowlabel = IPV6_FLOWINFO_MASK & net_hdr_word(CMSG_DATA(cmsg));
break;
case IPV6_2292HOPOPTS:
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -751,7 +751,7 @@ static bool ipv6_hop_jumbo(struct sk_buf
goto drop;
}
- pkt_len = ntohl(*(__be32 *)(nh + optoff + 2));
+ pkt_len = ntohl(net_hdr_word(nh + optoff + 2));
if (pkt_len <= IPV6_MAXPLEN) {
__IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2);
--- a/include/linux/types.h
+++ b/include/linux/types.h
@@ -225,5 +225,11 @@ struct callback_head {
typedef void (*rcu_callback_t)(struct rcu_head *head);
typedef void (*call_rcu_func_t)(struct rcu_head *head, rcu_callback_t func);
+struct net_hdr_word {
+ u32 words[1];
+} __attribute__((packed, aligned(2)));
+
+#define net_hdr_word(_p) (((struct net_hdr_word *) (_p))->words[0])
+
#endif /* __ASSEMBLY__ */
#endif /* _LINUX_TYPES_H */
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1441,8 +1441,8 @@ struct sk_buff *inet_gro_receive(struct
if (unlikely(ip_fast_csum((u8 *)iph, 5)))
goto out_unlock;
- id = ntohl(*(__be32 *)&iph->id);
- flush = (u16)((ntohl(*(__be32 *)iph) ^ skb_gro_len(skb)) | (id & ~IP_DF));
+ id = ntohl(net_hdr_word(&iph->id));
+ flush = (u16)((ntohl(net_hdr_word(iph)) ^ skb_gro_len(skb)) | (id & ~IP_DF));
id >>= 16;
list_for_each_entry(p, head, list) {
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -460,48 +460,53 @@ static void tcp_options_write(__be32 *pt
u16 options = opts->options; /* mungable copy */
if (unlikely(OPTION_MD5 & options)) {
- *ptr++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
- (TCPOPT_MD5SIG << 8) | TCPOLEN_MD5SIG);
+ net_hdr_word(ptr++) =
+ htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
+ (TCPOPT_MD5SIG << 8) | TCPOLEN_MD5SIG);
/* overload cookie hash location */
opts->hash_location = (__u8 *)ptr;
ptr += 4;
}
if (unlikely(opts->mss)) {
- *ptr++ = htonl((TCPOPT_MSS << 24) |
- (TCPOLEN_MSS << 16) |
- opts->mss);
+ net_hdr_word(ptr++) =
+ htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) |
+ opts->mss);
}
if (likely(OPTION_TS & options)) {
if (unlikely(OPTION_SACK_ADVERTISE & options)) {
- *ptr++ = htonl((TCPOPT_SACK_PERM << 24) |
- (TCPOLEN_SACK_PERM << 16) |
- (TCPOPT_TIMESTAMP << 8) |
- TCPOLEN_TIMESTAMP);
+ net_hdr_word(ptr++) =
+ htonl((TCPOPT_SACK_PERM << 24) |
+ (TCPOLEN_SACK_PERM << 16) |
+ (TCPOPT_TIMESTAMP << 8) |
+ TCPOLEN_TIMESTAMP);
options &= ~OPTION_SACK_ADVERTISE;
} else {
- *ptr++ = htonl((TCPOPT_NOP << 24) |
- (TCPOPT_NOP << 16) |
- (TCPOPT_TIMESTAMP << 8) |
- TCPOLEN_TIMESTAMP);
+ net_hdr_word(ptr++) =
+ htonl((TCPOPT_NOP << 24) |
+ (TCPOPT_NOP << 16) |
+ (TCPOPT_TIMESTAMP << 8) |
+ TCPOLEN_TIMESTAMP);
}
- *ptr++ = htonl(opts->tsval);
- *ptr++ = htonl(opts->tsecr);
+ net_hdr_word(ptr++) = htonl(opts->tsval);
+ net_hdr_word(ptr++) = htonl(opts->tsecr);
}
if (unlikely(OPTION_SACK_ADVERTISE & options)) {
- *ptr++ = htonl((TCPOPT_NOP << 24) |
- (TCPOPT_NOP << 16) |
- (TCPOPT_SACK_PERM << 8) |
- TCPOLEN_SACK_PERM);
+ net_hdr_word(ptr++) =
+ htonl((TCPOPT_NOP << 24) |
+ (TCPOPT_NOP << 16) |
+ (TCPOPT_SACK_PERM << 8) |
+ TCPOLEN_SACK_PERM);
}
if (unlikely(OPTION_WSCALE & options)) {
- *ptr++ = htonl((TCPOPT_NOP << 24) |
- (TCPOPT_WINDOW << 16) |
- (TCPOLEN_WINDOW << 8) |
- opts->ws);
+ net_hdr_word(ptr++) =
+ htonl((TCPOPT_NOP << 24) |
+ (TCPOPT_WINDOW << 16) |
+ (TCPOLEN_WINDOW << 8) |
+ opts->ws);
}
if (unlikely(opts->num_sack_blocks)) {
@@ -509,16 +514,17 @@ static void tcp_options_write(__be32 *pt
tp->duplicate_sack : tp->selective_acks;
int this_sack;
- *ptr++ = htonl((TCPOPT_NOP << 24) |
- (TCPOPT_NOP << 16) |
- (TCPOPT_SACK << 8) |
- (TCPOLEN_SACK_BASE + (opts->num_sack_blocks *
+ net_hdr_word(ptr++) =
+ htonl((TCPOPT_NOP << 24) |
+ (TCPOPT_NOP << 16) |
+ (TCPOPT_SACK << 8) |
+ (TCPOLEN_SACK_BASE + (opts->num_sack_blocks *
TCPOLEN_SACK_PERBLOCK)));
for (this_sack = 0; this_sack < opts->num_sack_blocks;
++this_sack) {
- *ptr++ = htonl(sp[this_sack].start_seq);
- *ptr++ = htonl(sp[this_sack].end_seq);
+ net_hdr_word(ptr++) = htonl(sp[this_sack].start_seq);
+ net_hdr_word(ptr++) = htonl(sp[this_sack].end_seq);
}
tp->rx_opt.dsack = 0;
@@ -531,13 +537,14 @@ static void tcp_options_write(__be32 *pt
if (foc->exp) {
len = TCPOLEN_EXP_FASTOPEN_BASE + foc->len;
- *ptr = htonl((TCPOPT_EXP << 24) | (len << 16) |
+ net_hdr_word(ptr) =
+ htonl((TCPOPT_EXP << 24) | (len << 16) |
TCPOPT_FASTOPEN_MAGIC);
p += TCPOLEN_EXP_FASTOPEN_BASE;
} else {
len = TCPOLEN_FASTOPEN_BASE + foc->len;
- *p++ = TCPOPT_FASTOPEN;
- *p++ = len;
+ net_hdr_word(p++) = TCPOPT_FASTOPEN;
+ net_hdr_word(p++) = len;
}
memcpy(p, foc->val, foc->len);
--- a/include/uapi/linux/igmp.h
+++ b/include/uapi/linux/igmp.h
@@ -33,7 +33,7 @@ struct igmphdr {
__u8 code; /* For newer IGMP */
__sum16 csum;
__be32 group;
-};
+} __attribute__((packed, aligned(2)));
/* V3 group record types [grec_type] */
#define IGMPV3_MODE_IS_INCLUDE 1
@@ -49,7 +49,7 @@ struct igmpv3_grec {
__be16 grec_nsrcs;
__be32 grec_mca;
__be32 grec_src[0];
-};
+} __attribute__((packed, aligned(2)));
struct igmpv3_report {
__u8 type;
@@ -58,7 +58,7 @@ struct igmpv3_report {
__be16 resv2;
__be16 ngrec;
struct igmpv3_grec grec[0];
-};
+} __attribute__((packed, aligned(2)));
struct igmpv3_query {
__u8 type;
@@ -79,7 +79,7 @@ struct igmpv3_query {
__u8 qqic;
__be16 nsrcs;
__be32 srcs[0];
-};
+} __attribute__((packed, aligned(2)));
#define IGMP_HOST_MEMBERSHIP_QUERY 0x11 /* From RFC1112 */
#define IGMP_HOST_MEMBERSHIP_REPORT 0x12 /* Ditto */
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -212,7 +212,7 @@ __be32 __skb_flow_get_ports(const struct
ports = __skb_header_pointer(skb, thoff + poff,
sizeof(_ports), data, hlen, &_ports);
if (ports)
- return *ports;
+ return (__be32)net_hdr_word(ports);
}
return 0;
--- a/include/uapi/linux/icmpv6.h
+++ b/include/uapi/linux/icmpv6.h
@@ -77,7 +77,7 @@ struct icmp6hdr {
#define icmp6_addrconf_other icmp6_dataun.u_nd_ra.other
#define icmp6_rt_lifetime icmp6_dataun.u_nd_ra.rt_lifetime
#define icmp6_router_pref icmp6_dataun.u_nd_ra.router_pref
-};
+} __attribute__((packed, aligned(2)));
#define ICMPV6_ROUTER_PREF_LOW 0x3
--- a/include/net/ndisc.h
+++ b/include/net/ndisc.h
@@ -92,7 +92,7 @@ struct ra_msg {
struct icmp6hdr icmph;
__be32 reachable_time;
__be32 retrans_timer;
-};
+} __attribute__((packed, aligned(2)));
struct rd_msg {
struct icmp6hdr icmph;
@@ -371,10 +371,10 @@ static inline u32 ndisc_hashfn(const voi
{
const u32 *p32 = pkey;
- return (((p32[0] ^ hash32_ptr(dev)) * hash_rnd[0]) +
- (p32[1] * hash_rnd[1]) +
- (p32[2] * hash_rnd[2]) +
- (p32[3] * hash_rnd[3]));
+ return (((net_hdr_word(&p32[0]) ^ hash32_ptr(dev)) * hash_rnd[0]) +
+ (net_hdr_word(&p32[1]) * hash_rnd[1]) +
+ (net_hdr_word(&p32[2]) * hash_rnd[2]) +
+ (net_hdr_word(&p32[3]) * hash_rnd[3]));
}
static inline struct neighbour *__ipv6_neigh_lookup_noref(struct net_device *dev, const void *pkey)
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -155,7 +155,7 @@ next_knode:
data = skb_header_pointer(skb, toff, 4, &hdata);
if (!data)
goto out;
- if ((*data ^ key->val) & key->mask) {
+ if ((net_hdr_word(data) ^ key->val) & key->mask) {
n = rcu_dereference_bh(n->next);
goto next_knode;
}
@@ -206,8 +206,8 @@ check_terminal:
&hdata);
if (!data)
goto out;
- sel = ht->divisor & u32_hash_fold(*data, &n->sel,
- n->fshift);
+ sel = ht->divisor & u32_hash_fold(net_hdr_word(data),
+ &n->sel, n->fshift);
}
if (!(n->sel.flags & (TC_U32_VAROFFSET | TC_U32_OFFSET | TC_U32_EAT)))
goto next_ht;
--- a/net/ipv6/ip6_offload.c
+++ b/net/ipv6/ip6_offload.c
@@ -240,7 +240,7 @@ INDIRECT_CALLABLE_SCOPE struct sk_buff *
continue;
iph2 = (struct ipv6hdr *)(p->data + off);
- first_word = *(__be32 *)iph ^ *(__be32 *)iph2;
+ first_word = net_hdr_word(iph) ^ net_hdr_word(iph2);
/* All fields must match except length and Traffic Class.
* XXX skbs on the gro_list have all been parsed and pulled
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -47,7 +47,7 @@ struct prefix_info {
__be32 reserved2;
struct in6_addr prefix;
-};
+} __attribute__((packed, aligned(2)));
#include <linux/ipv6.h>
#include <linux/netdevice.h>
--- a/include/net/inet_ecn.h
+++ b/include/net/inet_ecn.h
@@ -140,9 +140,9 @@ static inline int IP6_ECN_set_ce(struct
if (INET_ECN_is_not_ect(ipv6_get_dsfield(iph)))
return 0;
- from = *(__be32 *)iph;
+ from = net_hdr_word(iph);
to = from | htonl(INET_ECN_CE << 20);
- *(__be32 *)iph = to;
+ net_hdr_word(iph) = to;
if (skb->ip_summed == CHECKSUM_COMPLETE)
skb->csum = csum_add(csum_sub(skb->csum, (__force __wsum)from),
(__force __wsum)to);
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -146,7 +146,7 @@ struct frag_hdr {
__u8 reserved;
__be16 frag_off;
__be32 identification;
-};
+} __attribute__((packed, aligned(2)));
#define IP6_MF 0x0001
#define IP6_OFFSET 0xFFF8
@@ -557,8 +557,8 @@ static inline void __ipv6_addr_set_half(
}
#endif
#endif
- addr[0] = wh;
- addr[1] = wl;
+ net_hdr_word(&addr[0]) = wh;
+ net_hdr_word(&addr[1]) = wl;
}
static inline void ipv6_addr_set(struct in6_addr *addr,
@@ -617,6 +617,8 @@ static inline bool ipv6_prefix_equal(con
const __be32 *a1 = addr1->s6_addr32;
const __be32 *a2 = addr2->s6_addr32;
unsigned int pdw, pbi;
+ /* Used for last <32-bit fraction of prefix */
+ u32 pbia1, pbia2;
/* check complete u32 in prefix */
pdw = prefixlen >> 5;
@@ -625,7 +627,9 @@ static inline bool ipv6_prefix_equal(con
/* check incomplete u32 in prefix */
pbi = prefixlen & 0x1f;
- if (pbi && ((a1[pdw] ^ a2[pdw]) & htonl((0xffffffff) << (32 - pbi))))
+ pbia1 = net_hdr_word(&a1[pdw]);
+ pbia2 = net_hdr_word(&a2[pdw]);
+ if (pbi && ((pbia1 ^ pbia2) & htonl((0xffffffff) << (32 - pbi))))
return false;
return true;
@@ -741,13 +745,13 @@ static inline void ipv6_addr_set_v4mappe
*/
static inline int __ipv6_addr_diff32(const void *token1, const void *token2, int addrlen)
{
- const __be32 *a1 = token1, *a2 = token2;
+ const struct in6_addr *a1 = token1, *a2 = token2;
int i;
addrlen >>= 2;
for (i = 0; i < addrlen; i++) {
- __be32 xb = a1[i] ^ a2[i];
+ __be32 xb = a1->s6_addr32[i] ^ a2->s6_addr32[i];
if (xb)
return i * 32 + 31 - __fls(ntohl(xb));
}
@@ -934,17 +938,18 @@ static inline int ip6_multipath_hash_pol
static inline void ip6_flow_hdr(struct ipv6hdr *hdr, unsigned int tclass,
__be32 flowlabel)
{
- *(__be32 *)hdr = htonl(0x60000000 | (tclass << 20)) | flowlabel;
+ net_hdr_word((__be32 *)hdr) =
+ htonl(0x60000000 | (tclass << 20)) | flowlabel;
}
static inline __be32 ip6_flowinfo(const struct ipv6hdr *hdr)
{
- return *(__be32 *)hdr & IPV6_FLOWINFO_MASK;
+ return net_hdr_word((__be32 *)hdr) & IPV6_FLOWINFO_MASK;
}
static inline __be32 ip6_flowlabel(const struct ipv6hdr *hdr)
{
- return *(__be32 *)hdr & IPV6_FLOWLABEL_MASK;
+ return net_hdr_word((__be32 *)hdr) & IPV6_FLOWLABEL_MASK;
}
static inline u8 ip6_tclass(__be32 flowinfo)
--- a/include/net/secure_seq.h
+++ b/include/net/secure_seq.h
@@ -3,6 +3,7 @@
#define _NET_SECURE_SEQ
#include <linux/types.h>
+#include <linux/in6.h>
u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport);
u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
--- a/include/uapi/linux/in.h
+++ b/include/uapi/linux/in.h
@@ -84,7 +84,7 @@ enum {
/* Internet address. */
struct in_addr {
__be32 s_addr;
-};
+} __attribute__((packed, aligned(2)));
#endif
#define IP_TOS 1
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -140,7 +140,7 @@ static __be32 addr_bit_set(const void *t
* See include/asm-generic/bitops/le.h.
*/
return (__force __be32)(1 << ((~fn_bit ^ BITOP_BE32_SWIZZLE) & 0x1f)) &
- addr[fn_bit >> 5];
+ net_hdr_word(&addr[fn_bit >> 5]);
}
struct fib6_info *fib6_info_alloc(gfp_t gfp_flags, bool with_fib6_nh)
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -415,7 +415,7 @@ static void tcp_sack(const struct sk_buf
/* Fast path for timestamp-only option */
if (length == TCPOLEN_TSTAMP_ALIGNED
- && *(__be32 *)ptr == htonl((TCPOPT_NOP << 24)
+ && net_hdr_word(ptr) == htonl((TCPOPT_NOP << 24)
| (TCPOPT_NOP << 16)
| (TCPOPT_TIMESTAMP << 8)
| TCPOLEN_TIMESTAMP))
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -162,8 +162,8 @@ int xfrm_parse_spi(struct sk_buff *skb,
if (!pskb_may_pull(skb, hlen))
return -EINVAL;
- *spi = *(__be32 *)(skb_transport_header(skb) + offset);
- *seq = *(__be32 *)(skb_transport_header(skb) + offset_seq);
+ *spi = net_hdr_word(skb_transport_header(skb) + offset);
+ *seq = net_hdr_word(skb_transport_header(skb) + offset_seq);
return 0;
}
EXPORT_SYMBOL(xfrm_parse_spi);
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -3976,14 +3976,16 @@ static bool tcp_parse_aligned_timestamp(
{
const __be32 *ptr = (const __be32 *)(th + 1);
- if (*ptr == htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16)
- | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP)) {
+ if (net_hdr_word(ptr) ==
+ htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
+ (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP)) {
tp->rx_opt.saw_tstamp = 1;
++ptr;
- tp->rx_opt.rcv_tsval = ntohl(*ptr);
+ tp->rx_opt.rcv_tsval = get_unaligned_be32(ptr);
++ptr;
- if (*ptr)
- tp->rx_opt.rcv_tsecr = ntohl(*ptr) - tp->tsoffset;
+ if (net_hdr_word(ptr))
+ tp->rx_opt.rcv_tsecr = get_unaligned_be32(ptr) -
+ tp->tsoffset;
else
tp->rx_opt.rcv_tsecr = 0;
return true;
--- a/include/uapi/linux/if_pppox.h
+++ b/include/uapi/linux/if_pppox.h
@@ -51,6 +51,7 @@ struct pppoe_addr {
*/
struct pptp_addr {
__u16 call_id;
+ __u16 pad;
struct in_addr sin_addr;
};
--- a/net/ipv6/netfilter/nf_log_ipv6.c
+++ b/net/ipv6/netfilter/nf_log_ipv6.c
@@ -63,9 +63,9 @@ static void dump_ipv6_packet(struct net
/* Max length: 44 "LEN=65535 TC=255 HOPLIMIT=255 FLOWLBL=FFFFF " */
nf_log_buf_add(m, "LEN=%zu TC=%u HOPLIMIT=%u FLOWLBL=%u ",
ntohs(ih->payload_len) + sizeof(struct ipv6hdr),
- (ntohl(*(__be32 *)ih) & 0x0ff00000) >> 20,
+ (ntohl(net_hdr_word(ih)) & 0x0ff00000) >> 20,
ih->hop_limit,
- (ntohl(*(__be32 *)ih) & 0x000fffff));
+ (ntohl(net_hdr_word(ih)) & 0x000fffff));
fragment = 0;
ptr = ip6hoff + sizeof(struct ipv6hdr);
--- a/include/net/neighbour.h
+++ b/include/net/neighbour.h
@@ -275,8 +275,10 @@ static inline bool neigh_key_eq128(const
const u32 *n32 = (const u32 *)n->primary_key;
const u32 *p32 = pkey;
- return ((n32[0] ^ p32[0]) | (n32[1] ^ p32[1]) |
- (n32[2] ^ p32[2]) | (n32[3] ^ p32[3])) == 0;
+ return ((n32[0] ^ net_hdr_word(&p32[0])) |
+ (n32[1] ^ net_hdr_word(&p32[1])) |
+ (n32[2] ^ net_hdr_word(&p32[2])) |
+ (n32[3] ^ net_hdr_word(&p32[3]))) == 0;
}
static inline struct neighbour *___neigh_lookup_noref(
--- a/include/uapi/linux/netfilter_arp/arp_tables.h
+++ b/include/uapi/linux/netfilter_arp/arp_tables.h
@@ -70,7 +70,7 @@ struct arpt_arp {
__u8 flags;
/* Inverse flags */
__u16 invflags;
-};
+} __attribute__((aligned(4)));
/* Values for "flag" field in struct arpt_ip (general arp structure).
* No flags defined yet.
--- a/net/core/utils.c
+++ b/net/core/utils.c
@@ -460,8 +460,14 @@ void inet_proto_csum_replace16(__sum16 *
bool pseudohdr)
{
__be32 diff[] = {
- ~from[0], ~from[1], ~from[2], ~from[3],
- to[0], to[1], to[2], to[3],
+ ~net_hdr_word(&from[0]),
+ ~net_hdr_word(&from[1]),
+ ~net_hdr_word(&from[2]),
+ ~net_hdr_word(&from[3]),
+ net_hdr_word(&to[0]),
+ net_hdr_word(&to[1]),
+ net_hdr_word(&to[2]),
+ net_hdr_word(&to[3]),
};
if (skb->ip_summed != CHECKSUM_PARTIAL) {
*sum = csum_fold(csum_partial(diff, sizeof(diff),
--- a/include/linux/etherdevice.h
+++ b/include/linux/etherdevice.h
@@ -489,7 +489,7 @@ static inline bool is_etherdev_addr(cons
* @b: Pointer to Ethernet header
*
* Compare two Ethernet headers, returns 0 if equal.
- * This assumes that the network header (i.e., IP header) is 4-byte
+ * This assumes that the network header (i.e., IP header) is 2-byte
* aligned OR the platform can handle unaligned access. This is the
* case for all packets coming into netif_receive_skb or similar
* entry points.
@@ -512,11 +512,12 @@ static inline unsigned long compare_ethe
fold |= *(unsigned long *)(a + 6) ^ *(unsigned long *)(b + 6);
return fold;
#else
- u32 *a32 = (u32 *)((u8 *)a + 2);
- u32 *b32 = (u32 *)((u8 *)b + 2);
+ const u16 *a16 = a;
+ const u16 *b16 = b;
- return (*(u16 *)a ^ *(u16 *)b) | (a32[0] ^ b32[0]) |
- (a32[1] ^ b32[1]) | (a32[2] ^ b32[2]);
+ return (a16[0] ^ b16[0]) | (a16[1] ^ b16[1]) | (a16[2] ^ b16[2]) |
+ (a16[3] ^ b16[3]) | (a16[4] ^ b16[4]) | (a16[5] ^ b16[5]) |
+ (a16[6] ^ b16[6]);
#endif
}
--- a/net/ipv4/tcp_offload.c
+++ b/net/ipv4/tcp_offload.c
@@ -223,7 +223,7 @@ struct sk_buff *tcp_gro_receive(struct l
th2 = tcp_hdr(p);
- if (*(u32 *)&th->source ^ *(u32 *)&th2->source) {
+ if (net_hdr_word(&th->source) ^ net_hdr_word(&th2->source)) {
NAPI_GRO_CB(p)->same_flow = 0;
continue;
}
@@ -241,8 +241,8 @@ found:
~(TCP_FLAG_CWR | TCP_FLAG_FIN | TCP_FLAG_PSH));
flush |= (__force int)(th->ack_seq ^ th2->ack_seq);
for (i = sizeof(*th); i < thlen; i += 4)
- flush |= *(u32 *)((u8 *)th + i) ^
- *(u32 *)((u8 *)th2 + i);
+ flush |= net_hdr_word((u8 *)th + i) ^
+ net_hdr_word((u8 *)th2 + i);
/* When we receive our second frame we can made a decision on if we
* continue this flow as an atomic flow with a fixed ID or if we use
--- a/net/ipv6/netfilter/ip6table_mangle.c
+++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -47,7 +47,7 @@ ip6t_mangle_out(struct sk_buff *skb, con
hop_limit = ipv6_hdr(skb)->hop_limit;
/* flowlabel and prio (includes version, which shouldn't change either */
- flowlabel = *((u_int32_t *)ipv6_hdr(skb));
+ flowlabel = net_hdr_word(ipv6_hdr(skb));
ret = ip6t_do_table(skb, state, state->net->ipv6.ip6table_mangle);
@@ -56,7 +56,7 @@ ip6t_mangle_out(struct sk_buff *skb, con
!ipv6_addr_equal(&ipv6_hdr(skb)->daddr, &daddr) ||
skb->mark != mark ||
ipv6_hdr(skb)->hop_limit != hop_limit ||
- flowlabel != *((u_int32_t *)ipv6_hdr(skb)))) {
+ flowlabel != net_hdr_word(ipv6_hdr(skb)))) {
err = ip6_route_me_harder(state->net, state->sk, skb);
if (err < 0)
ret = NF_DROP_ERR(err);

View File

@ -1,72 +0,0 @@
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -2012,5 +2012,13 @@ config RAVE_SP_CORE
Select this to get support for the Supervisory Processor
device found on several devices in RAVE line of hardware.
+config MFD_RB4XX_CPLD
+ tristate "CPLD driver for Mikrotik RB4xx series boards"
+ select MFD_CORE
+ depends on ATH79 || COMPILE_TEST
+ help
+ Enables support for the CPLD chip (NAND & GPIO) on Mikrotik
+ Routerboard RB4xx series.
+
endmenu
endif
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -256,3 +256,4 @@ obj-$(CONFIG_MFD_ROHM_BD70528) += rohm-b
obj-$(CONFIG_MFD_ROHM_BD718XX) += rohm-bd718x7.o
obj-$(CONFIG_MFD_STMFX) += stmfx.o
+obj-$(CONFIG_MFD_RB4XX_CPLD) += rb4xx-cpld.o
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -1408,6 +1408,12 @@ config GPIO_SODAVILLE
help
Say Y here to support Intel Sodaville GPIO.
+config GPIO_RB4XX
+ tristate "GPIO expander for Mikrotik RB4xx series boards"
+ depends on MFD_RB4XX_CPLD
+ help
+ GPIO driver for Mikrotik Routerboard RB4xx series.
+
endmenu
menu "SPI GPIO expanders"
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -113,6 +113,7 @@ obj-$(CONFIG_GPIO_PL061) += gpio-pl061.
obj-$(CONFIG_GPIO_PMIC_EIC_SPRD) += gpio-pmic-eic-sprd.o
obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o
obj-$(CONFIG_GPIO_RASPBERRYPI_EXP) += gpio-raspberrypi-exp.o
+obj-$(CONFIG_GPIO_RB4XX) += gpio-rb4xx.o
obj-$(CONFIG_GPIO_RC5T583) += gpio-rc5t583.o
obj-$(CONFIG_GPIO_RCAR) += gpio-rcar.o
obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -552,4 +552,11 @@ config MTD_NAND_AR934X
Enables support for NAND controller on Qualcomm Atheros SoCs.
This controller is found on AR934x and QCA955x SoCs.
+config MTD_NAND_RB4XX
+ tristate "Support for NAND driver for Mikrotik RB4xx series boards"
+ depends on MFD_RB4XX_CPLD
+ help
+ Enables support for the NAND flash chip on Mikrotik Routerboard
+ RB4xx series.
+
endif # MTD_RAW_NAND
--- a/drivers/mtd/nand/raw/Makefile
+++ b/drivers/mtd/nand/raw/Makefile
@@ -58,6 +58,7 @@ obj-$(CONFIG_MTD_NAND_TEGRA) += tegra_n
obj-$(CONFIG_MTD_NAND_STM32_FMC2) += stm32_fmc2_nand.o
obj-$(CONFIG_MTD_NAND_MESON) += meson_nand.o
obj-$(CONFIG_MTD_NAND_AR934X) += ar934x_nand.o
+obj-$(CONFIG_MTD_NAND_RB4XX) += nand_rb4xx.o
nand-objs := nand_base.o nand_legacy.o nand_bbt.o nand_timings.o nand_ids.o
nand-objs += nand_onfi.o

View File

@ -1,59 +0,0 @@
From b3797d1a92afe97c173b00fdb7824cedba24eef0 Mon Sep 17 00:00:00 2001
From: Chuanhong Guo <gch981213@gmail.com>
Date: Sun, 20 Sep 2020 01:00:45 +0800
Subject: [PATCH] ath79: ar8216: make switch register access atomic
due to some unknown reason these register accesses sometimes fail
on the integrated switch without this patch.
THIS ONLY WORKS ON ATH79 AND MAY BREAK THE DRIVER ON OTHER PLATFORMS!
The mdio bus on ath79 works in polling mode and doesn't rely on
any interrupt. This patch breaks the driver on any mdio master
with interrupts used.
---
--- a/drivers/net/phy/ar8216.c
+++ b/drivers/net/phy/ar8216.c
@@ -252,6 +252,7 @@ ar8xxx_mii_write32(struct ar8xxx_priv *p
u32
ar8xxx_read(struct ar8xxx_priv *priv, int reg)
{
+ unsigned long flags;
struct mii_bus *bus = priv->mii_bus;
u16 r1, r2, page;
u32 val;
@@ -259,11 +260,13 @@ ar8xxx_read(struct ar8xxx_priv *priv, in
split_addr((u32) reg, &r1, &r2, &page);
mutex_lock(&bus->mdio_lock);
+ local_irq_save(flags);
bus->write(bus, 0x18, 0, page);
wait_for_page_switch();
val = ar8xxx_mii_read32(priv, 0x10 | r2, r1);
+ local_irq_restore(flags);
mutex_unlock(&bus->mdio_lock);
return val;
@@ -272,17 +275,20 @@ ar8xxx_read(struct ar8xxx_priv *priv, in
void
ar8xxx_write(struct ar8xxx_priv *priv, int reg, u32 val)
{
+ unsigned long flags;
struct mii_bus *bus = priv->mii_bus;
u16 r1, r2, page;
split_addr((u32) reg, &r1, &r2, &page);
mutex_lock(&bus->mdio_lock);
+ local_irq_save(flags);
bus->write(bus, 0x18, 0, page);
wait_for_page_switch();
ar8xxx_mii_write32(priv, 0x10 | r2, r1, val);
+ local_irq_restore(flags);
mutex_unlock(&bus->mdio_lock);
}

View File

@ -1,44 +0,0 @@
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -559,4 +559,8 @@ config MTD_NAND_RB4XX
Enables support for the NAND flash chip on Mikrotik Routerboard
RB4xx series.
+config MTD_NAND_RB91X
+ tristate "MikroTik RB91x NAND driver support"
+ depends on ATH79 && MTD_RAW_NAND
+
endif # MTD_RAW_NAND
--- a/drivers/mtd/nand/raw/Makefile
+++ b/drivers/mtd/nand/raw/Makefile
@@ -59,6 +59,7 @@ obj-$(CONFIG_MTD_NAND_STM32_FMC2) += stm
obj-$(CONFIG_MTD_NAND_MESON) += meson_nand.o
obj-$(CONFIG_MTD_NAND_AR934X) += ar934x_nand.o
obj-$(CONFIG_MTD_NAND_RB4XX) += nand_rb4xx.o
+obj-$(CONFIG_MTD_NAND_RB91X) += rb91x_nand.o
nand-objs := nand_base.o nand_legacy.o nand_bbt.o nand_timings.o nand_ids.o
nand-objs += nand_onfi.o
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -130,6 +130,10 @@ config GPIO_ATH79
Select this option to enable GPIO driver for
Atheros AR71XX/AR724X/AR913X SoC devices.
+config GPIO_LATCH
+ tristate "MikroTik RouterBOARD GPIO latch support"
+ depends on ATH79
+
config GPIO_RASPBERRYPI_EXP
tristate "Raspberry Pi 3 GPIO Expander"
default RASPBERRYPI_FIRMWARE
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -67,6 +67,7 @@ obj-$(CONFIG_GPIO_IT87) += gpio-it87.o
obj-$(CONFIG_GPIO_IXP4XX) += gpio-ixp4xx.o
obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o
obj-$(CONFIG_GPIO_KEMPLD) += gpio-kempld.o
+obj-$(CONFIG_GPIO_LATCH) += gpio-latch.o
obj-$(CONFIG_GPIO_LOONGSON1) += gpio-loongson1.o
obj-$(CONFIG_GPIO_LOONGSON) += gpio-loongson.o
obj-$(CONFIG_GPIO_LP3943) += gpio-lp3943.o

View File

@ -22,7 +22,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -286,6 +286,7 @@ static void xhci_pci_quirks(struct devic
@@ -288,6 +288,7 @@ static void xhci_pci_quirks(struct devic
if (pdev->vendor == PCI_VENDOR_ID_VIA && pdev->device == 0x3483) {
xhci->quirks |= XHCI_LPM_SUPPORT;
xhci->quirks |= XHCI_EP_CTX_BROKEN_DCS;

View File

@ -254,7 +254,7 @@ Signed-off-by: Maxime Ripard <maxime@cerno.tech>
* clk_get_parent - return the parent of a clk
* @clk: the clk whose parent gets returned
*
@@ -3811,6 +3931,7 @@ __clk_register(struct device *dev, struc
@@ -3820,6 +3940,7 @@ __clk_register(struct device *dev, struc
goto fail_parents;
INIT_HLIST_HEAD(&core->clks);

View File

@ -82,7 +82,7 @@ Link: https://patchwork.freedesktop.org/patch/msgid/20201211114237.213288-2-tomi
.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -898,7 +898,6 @@ static void ast_crtc_atomic_destroy_stat
@@ -901,7 +901,6 @@ static void ast_crtc_atomic_destroy_stat
static const struct drm_crtc_funcs ast_crtc_funcs = {
.reset = ast_crtc_reset,

View File

@ -9,6 +9,7 @@ DEVICE_VARS += PKGTB_ITS
define Image/Prepare
cp bootfs-generic.its $(KDIR)/
sed -i "s=\$$$${images_dir}=$(STAGING_DIR_IMAGE)=" $(KDIR)/bootfs-generic.its
sed -i "s=\$$$${dts_dir}=$(DTS_DIR)=" $(KDIR)/bootfs-generic.its
endef

Some files were not shown because too many files have changed in this diff Show More