Merge Official Source
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
commit
ff4cbb40f2
@ -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)))))))
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
42
package/boot/arm-trusted-firmware-bcm63xx/Makefile
Normal file
42
package/boot/arm-trusted-firmware-bcm63xx/Makefile
Normal 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))
|
||||
@ -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))
|
||||
@ -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>
|
||||
|
||||
|
||||
29
package/firmware/linux-firmware/amd.mk
Normal file
29
package/firmware/linux-firmware/amd.mk
Normal 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))
|
||||
@ -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))
|
||||
@ -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))
|
||||
@ -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
|
||||
|
||||
@ -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) \
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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,
|
||||
},
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
@ -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>;
|
||||
|
||||
@ -244,7 +244,3 @@
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&MSI {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@ -205,7 +205,3 @@
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&MSI {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@ -207,10 +207,6 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&MSI {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&IIC0 {
|
||||
status = "okay";
|
||||
|
||||
|
||||
@ -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";
|
||||
};
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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)
|
||||
@ -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;
|
||||
|
||||
@ -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:
|
||||
@ -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;
|
||||
|
||||
@ -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",
|
||||
@ -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) |
|
||||
@ -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);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
@ -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);
|
||||
@ -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[] = {
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
127
target/linux/ath25/config-5.10
Normal file
127
target/linux/ath25/config-5.10
Normal 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
|
||||
@ -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
|
||||
|
||||
212
target/linux/ath25/patches-5.10/107-ar5312_gpio.patch
Normal file
212
target/linux/ath25/patches-5.10/107-ar5312_gpio.patch
Normal 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
|
||||
363
target/linux/ath25/patches-5.10/108-ar2315_gpio.patch
Normal file
363
target/linux/ath25/patches-5.10/108-ar2315_gpio.patch
Normal 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
|
||||
*/
|
||||
1735
target/linux/ath25/patches-5.10/110-ar2313_ethernet.patch
Normal file
1735
target/linux/ath25/patches-5.10/110-ar2313_ethernet.patch
Normal file
File diff suppressed because it is too large
Load Diff
631
target/linux/ath25/patches-5.10/120-spiflash.patch
Normal file
631
target/linux/ath25/patches-5.10/120-spiflash.patch
Normal 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,
|
||||
277
target/linux/ath25/patches-5.10/130-watchdog.patch
Normal file
277
target/linux/ath25/patches-5.10/130-watchdog.patch
Normal 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;
|
||||
@ -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:
|
||||
@ -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;
|
||||
+ }
|
||||
@ -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;
|
||||
71
target/linux/ath25/patches-5.10/210-reset_button.patch
Normal file
71
target/linux/ath25/patches-5.10/210-reset_button.patch
Normal 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);
|
||||
111
target/linux/ath25/patches-5.10/220-enet_micrel_workaround.patch
Normal file
111
target/linux/ath25/patches-5.10/220-enet_micrel_workaround.patch
Normal 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:
|
||||
116
target/linux/ath25/patches-5.10/330-board_leds.patch
Normal file
116
target/linux/ath25/patches-5.10/330-board_leds.patch
Normal 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);
|
||||
23
target/linux/ath25/patches-5.10/700-swconfig_mvswitch.patch
Normal file
23
target/linux/ath25/patches-5.10/700-swconfig_mvswitch.patch
Normal 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
|
||||
23
target/linux/ath25/patches-5.4/700-swconfig_mvswitch.patch
Normal file
23
target/linux/ath25/patches-5.4/700-swconfig_mvswitch.patch
Normal 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
|
||||
@ -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
|
||||
@ -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
|
||||
|
||||
@ -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();
|
||||
@ -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;
|
||||
@ -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
|
||||
@ -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");
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
@ -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();
|
||||
-}
|
||||
@ -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>;
|
||||
+ };
|
||||
@ -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),
|
||||
},
|
||||
};
|
||||
|
||||
@ -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>;
|
||||
+ };
|
||||
@ -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),
|
||||
},
|
||||
};
|
||||
|
||||
@ -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
|
||||
@ -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;
|
||||
@ -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)
|
||||
@ -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)
|
||||
{
|
||||
@ -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;
|
||||
@ -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
|
||||
@ -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
|
||||
*/
|
||||
@ -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 */
|
||||
@ -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");
|
||||
@ -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 */
|
||||
@ -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);
|
||||
@ -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
|
||||
@ -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" },
|
||||
{},
|
||||
};
|
||||
|
||||
@ -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
|
||||
@ -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)) {
|
||||
@ -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;
|
||||
@ -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/
|
||||
@ -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);
|
||||
@ -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/
|
||||
@ -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
|
||||
@ -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;
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
@ -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
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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
Loading…
Reference in New Issue
Block a user