ath79: add support for linux 4.19
The following patches are dropped because they are merged upstream: -0001-tty-serial-drop-QCA-pecific-SoC-symbols.patch -0006-usb-drop-deprecated-symbols.patch -0009-MIPS-ath79-add-lots-of-missing-registers.patch -0010-MIPS-ath79-add-support-for-QCA953x-QCA956x-TP9343.patch -0014-MIPS-ath79-finetune-cpu-overrides.patch -0015-MIPS-ath79-enable-uart-during-early_prink.patch -0016-MIPS-ath79-get-PCIe-controller-out-of-reset.patch This patch is dropped due to the introduction of spi-mem framework: -461-spi-ath79-add-fast-flash-read.patch Thank to Michael Marley @mamarley for his work on this patch: -910-unaligned_access_hacks.patch Signed-off-by: Chuanhong Guo <gch981213@gmail.com> [synchronized kernel config with make kernel_oldconfig] Signed-off-by: Petr Štetiar <ynezz@true.cz>
This commit is contained in:
		 Chuanhong Guo
					Chuanhong Guo
				
			
				
					committed by
					
						 Petr Štetiar
						Petr Štetiar
					
				
			
			
				
	
			
			
			 Petr Štetiar
						Petr Štetiar
					
				
			
						parent
						
							4eaa3626a8
						
					
				
				
					commit
					3771176c9e
				
			
							
								
								
									
										229
									
								
								target/linux/ath79/config-4.19
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										229
									
								
								target/linux/ath79/config-4.19
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,229 @@ | |||||||
|  | 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_BINFMT_ELF_STATE=y | ||||||
|  | CONFIG_ARCH_CLOCKSOURCE_DATA=y | ||||||
|  | CONFIG_ARCH_DISCARD_MEMBLOCK=y | ||||||
|  | CONFIG_ARCH_HAS_ELF_RANDOMIZE=y | ||||||
|  | CONFIG_ARCH_HAS_RESET_CONTROLLER=y | ||||||
|  | CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE=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_QUEUED_RWLOCKS=y | ||||||
|  | CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y | ||||||
|  | CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y | ||||||
|  | CONFIG_ATH79=y | ||||||
|  | CONFIG_ATH79_WDT=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_CPU_BIG_ENDIAN=y | ||||||
|  | CONFIG_CPU_GENERIC_DUMP_TLB=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_R4K_FPU=y | ||||||
|  | CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y | ||||||
|  | CONFIG_CPU_SUPPORTS_HIGHMEM=y | ||||||
|  | CONFIG_CPU_SUPPORTS_MSA=y | ||||||
|  | CONFIG_CRYPTO_RNG2=y | ||||||
|  | CONFIG_CRYPTO_WORKQUEUE=y | ||||||
|  | CONFIG_CSRC_R4K=y | ||||||
|  | CONFIG_DMA_DIRECT_OPS=y | ||||||
|  | CONFIG_DMA_NONCOHERENT=y | ||||||
|  | CONFIG_DMA_NONCOHERENT_CACHE_SYNC=y | ||||||
|  | CONFIG_DMA_NONCOHERENT_MMAP=y | ||||||
|  | CONFIG_DMA_NONCOHERENT_OPS=y | ||||||
|  | CONFIG_DTC=y | ||||||
|  | CONFIG_EARLY_PRINTK=y | ||||||
|  | CONFIG_ETHERNET_PACKET_MANGLE=y | ||||||
|  | CONFIG_FIXED_PHY=y | ||||||
|  | CONFIG_GENERIC_ATOMIC64=y | ||||||
|  | CONFIG_GENERIC_CLOCKEVENTS=y | ||||||
|  | CONFIG_GENERIC_CMOS_UPDATE=y | ||||||
|  | CONFIG_GENERIC_CPU_AUTOPROBE=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_SYSFS=y | ||||||
|  | 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_CBPF_JIT=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_FTRACE_MCOUNT_RECORD=y | ||||||
|  | CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y | ||||||
|  | CONFIG_HAVE_FUNCTION_TRACER=y | ||||||
|  | CONFIG_HAVE_GENERIC_DMA_COHERENT=y | ||||||
|  | CONFIG_HAVE_IDE=y | ||||||
|  | CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y | ||||||
|  | CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y | ||||||
|  | CONFIG_HAVE_KVM=y | ||||||
|  | CONFIG_HAVE_LATENCYTOP_SUPPORT=y | ||||||
|  | CONFIG_HAVE_LD_DEAD_CODE_DATA_ELIMINATION=y | ||||||
|  | CONFIG_HAVE_MEMBLOCK=y | ||||||
|  | CONFIG_HAVE_MEMBLOCK_NODE_MAP=y | ||||||
|  | CONFIG_HAVE_MOD_ARCH_SPECIFIC=y | ||||||
|  | CONFIG_HAVE_NET_DSA=y | ||||||
|  | CONFIG_HAVE_OPROFILE=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_HAS_PCI=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_SYSCON=y | ||||||
|  | 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_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_M25P80=y | ||||||
|  | # CONFIG_MTD_MAP_BANK_WIDTH_1 is not set | ||||||
|  | # CONFIG_MTD_MAP_BANK_WIDTH_4 is not set | ||||||
|  | CONFIG_MTD_PARSER_CYBERTAN=y | ||||||
|  | CONFIG_MTD_PHYSMAP=y | ||||||
|  | CONFIG_MTD_SPI_NOR=y | ||||||
|  | CONFIG_MTD_SPLIT_LZMA_FW=y | ||||||
|  | CONFIG_MTD_SPLIT_TPLINK_FW=y | ||||||
|  | CONFIG_MTD_SPLIT_UIMAGE_FW=y | ||||||
|  | CONFIG_MTD_TPLINK_PARTS=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_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_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_OF_PLATFORM=y | ||||||
|  | CONFIG_SPI=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_TICK_CPU_ACCOUNTING=y | ||||||
|  | CONFIG_TINY_SRCU=y | ||||||
|  | CONFIG_USB_SUPPORT=y | ||||||
|  | CONFIG_USE_OF=y | ||||||
| @@ -0,0 +1,32 @@ | |||||||
|  | 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 | ||||||
|  | @@ -115,10 +115,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; | ||||||
| @@ -0,0 +1,186 @@ | |||||||
|  | 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 | ||||||
|  | @@ -756,6 +756,17 @@ config LEDS_NIC78BX | ||||||
|  |  	  To compile this driver as a module, choose M here: the module | ||||||
|  |  	  will be called leds-nic78bx. | ||||||
|  |   | ||||||
|  | +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); | ||||||
|  | +		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_of_led_classdev_register(&pdev->dev, np, &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 | ||||||
|  | @@ -78,6 +78,7 @@ obj-$(CONFIG_LEDS_MT6323)		+= leds-mt632 | ||||||
|  |  obj-$(CONFIG_LEDS_LM3692X)		+= leds-lm3692x.o | ||||||
|  |  obj-$(CONFIG_LEDS_SC27XX_BLTC)		+= leds-sc27xx-bltc.o | ||||||
|  |  obj-$(CONFIG_LEDS_LM3601X)		+= leds-lm3601x.o | ||||||
|  | +obj-$(CONFIG_LEDS_RESET)		+= leds-reset.o | ||||||
|  |   | ||||||
|  |  # LED SPI Drivers | ||||||
|  |  obj-$(CONFIG_LEDS_CR0014114)		+= leds-cr0014114.o | ||||||
| @@ -0,0 +1,320 @@ | |||||||
|  | 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 | ||||||
|  | @@ -15,6 +15,22 @@ config GENERIC_PHY | ||||||
|  |  	  phy users can obtain reference to the PHY. All the users of this | ||||||
|  |  	  framework should select this config. | ||||||
|  |   | ||||||
|  | +config PHY_AR7100_USB | ||||||
|  | +	tristate "Atheros AR7100 USB PHY driver" | ||||||
|  | +	depends on ATH79 || COMPILE_TEST | ||||||
|  | +	default y if USB_EHCI_HCD_PLATFORM | ||||||
|  | +	select PHY_SIMPLE | ||||||
|  | +	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 PHY_SIMPLE | ||||||
|  | +	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_PHY_LPC18XX_USB_OTG)	+= phy-lpc18xx-usb-otg.o | ||||||
|  |  obj-$(CONFIG_PHY_XGENE)			+= phy-xgene.o | ||||||
|  |  obj-$(CONFIG_PHY_PISTACHIO_USB)		+= phy-pistachio-usb.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,123 @@ | ||||||
|  | +/* | ||||||
|  | + * 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	*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->rst_phy) | ||||||
|  | +		err = reset_control_deassert(priv->rst_phy); | ||||||
|  | +	if (!err && priv->suspend_override) | ||||||
|  | +		err = reset_control_assert(priv->suspend_override); | ||||||
|  | +	if (err && priv->rst_phy) | ||||||
|  | +		err = reset_control_assert(priv->rst_phy); | ||||||
|  | + | ||||||
|  | +	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); | ||||||
|  | + | ||||||
|  | +	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)) { | ||||||
|  | +		dev_err(&pdev->dev, "phy reset is missing\n"); | ||||||
|  | +		return PTR_ERR(priv->rst_phy); | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	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"); | ||||||
| @@ -0,0 +1,24 @@ | |||||||
|  | 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 | ||||||
|  | @@ -161,6 +161,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; | ||||||
|  |   | ||||||
| @@ -0,0 +1,168 @@ | |||||||
|  | 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 | ||||||
|  | @@ -3,6 +3,7 @@ obj-$(CONFIG_IRQCHIP)			+= irqchip.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); | ||||||
| @@ -0,0 +1,23 @@ | |||||||
|  | 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 | ||||||
|  | @@ -88,10 +88,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(); | ||||||
|  | -} | ||||||
| @@ -0,0 +1,24 @@ | |||||||
|  | From 0c8856211d26f84277f7fcb0b9595e5c646bc464 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: John Crispin <john@phrozen.org> | ||||||
|  | Date: Tue, 6 Mar 2018 10:00:55 +0100 | ||||||
|  | Subject: [PATCH 11/33] MIPS: ath79: select the PINCTRL subsystem | ||||||
|  |  | ||||||
|  | The pinmux on QCA SoCs is controlled by a single register. The | ||||||
|  | "pinctrl-single" driver can be used but requires the target | ||||||
|  | to select PINCTRL. | ||||||
|  |  | ||||||
|  | Signed-off-by: John Crispin <john@phrozen.org> | ||||||
|  | --- | ||||||
|  |  arch/mips/Kconfig | 1 + | ||||||
|  |  1 file changed, 1 insertion(+) | ||||||
|  |  | ||||||
|  | --- a/arch/mips/Kconfig | ||||||
|  | +++ b/arch/mips/Kconfig | ||||||
|  | @@ -288,6 +288,7 @@ config BCM63XX | ||||||
|  |  	select SYS_HAS_EARLY_PRINTK | ||||||
|  |  	select SWAP_IO_SPACE | ||||||
|  |  	select GPIOLIB | ||||||
|  | +	select PINCTRL | ||||||
|  |  	select HAVE_CLK | ||||||
|  |  	select MIPS_L1_CACHE_SHIFT_4 | ||||||
|  |  	select CLKDEV_LOOKUP | ||||||
| @@ -0,0 +1,57 @@ | |||||||
|  | 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>; | ||||||
|  | +	}; | ||||||
| @@ -0,0 +1,202 @@ | |||||||
|  | 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 | ||||||
|  | @@ -18,8 +18,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> | ||||||
|  | @@ -49,12 +52,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 */ | ||||||
|  | @@ -228,29 +232,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) | ||||||
|  | @@ -261,7 +266,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); | ||||||
|  | @@ -278,7 +283,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); | ||||||
|  | @@ -294,24 +299,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); | ||||||
|  |  } | ||||||
|  | @@ -328,6 +340,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; | ||||||
|  | @@ -348,26 +365,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 */ | ||||||
|  | @@ -380,9 +377,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); | ||||||
|  |   | ||||||
|  | @@ -393,6 +392,7 @@ static struct platform_driver ar71xx_pci | ||||||
|  |  	.probe = ar71xx_pci_probe, | ||||||
|  |  	.driver = { | ||||||
|  |  		.name = "ar71xx-pci", | ||||||
|  | +		.of_match_table = of_match_ptr(ar71xx_pci_ids), | ||||||
|  |  	}, | ||||||
|  |  }; | ||||||
|  |   | ||||||
| @@ -0,0 +1,61 @@ | |||||||
|  | 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>; | ||||||
|  | +	}; | ||||||
| @@ -0,0 +1,205 @@ | |||||||
|  | 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 | ||||||
|  | @@ -14,8 +14,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 | ||||||
|  | @@ -45,17 +48,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; | ||||||
|  | @@ -231,35 +237,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, | ||||||
|  | @@ -273,14 +275,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, | ||||||
|  | @@ -305,26 +305,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); | ||||||
|  |  } | ||||||
|  | @@ -394,29 +402,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 | ||||||
|  | @@ -438,10 +428,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), | ||||||
|  |  	}, | ||||||
|  |  }; | ||||||
|  |   | ||||||
| @@ -0,0 +1,243 @@ | |||||||
|  | From 288a8eb0d41f09fda242e05f8a7bd1f5b3489477 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Tue, 6 Mar 2018 13:19:26 +0100 | ||||||
|  | Subject: [PATCH 21/33] MIPS: ath79: add helpers for setting clocks and expose | ||||||
|  |  the ref clock | ||||||
|  |  | ||||||
|  | Preparation for transitioning the legacy clock setup code over | ||||||
|  | to OF. | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Signed-off-by: John Crispin <john@phrozen.org> | ||||||
|  | --- | ||||||
|  |  arch/mips/ath79/clock.c               | 128 ++++++++++++++++++---------------- | ||||||
|  |  include/dt-bindings/clock/ath79-clk.h |   3 +- | ||||||
|  |  2 files changed, 68 insertions(+), 63 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/arch/mips/ath79/clock.c | ||||||
|  | +++ b/arch/mips/ath79/clock.c | ||||||
|  | @@ -37,20 +37,46 @@ static struct clk_onecell_data clk_data | ||||||
|  |  	.clk_num = ARRAY_SIZE(clks), | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | -static struct clk *__init ath79_add_sys_clkdev( | ||||||
|  | -	const char *id, unsigned long rate) | ||||||
|  | +static const char * const clk_names[ATH79_CLK_END] = { | ||||||
|  | +	[ATH79_CLK_CPU] = "cpu", | ||||||
|  | +	[ATH79_CLK_DDR] = "ddr", | ||||||
|  | +	[ATH79_CLK_AHB] = "ahb", | ||||||
|  | +	[ATH79_CLK_REF] = "ref", | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  | +static const char * __init ath79_clk_name(int type) | ||||||
|  |  { | ||||||
|  | -	struct clk *clk; | ||||||
|  | -	int err; | ||||||
|  | +	BUG_ON(type >= ARRAY_SIZE(clk_names) || !clk_names[type]); | ||||||
|  | +	return clk_names[type]; | ||||||
|  | +} | ||||||
|  |   | ||||||
|  | -	clk = clk_register_fixed_rate(NULL, id, NULL, 0, rate); | ||||||
|  | +static void __init __ath79_set_clk(int type, const char *name, struct clk *clk) | ||||||
|  | +{ | ||||||
|  |  	if (IS_ERR(clk)) | ||||||
|  | -		panic("failed to allocate %s clock structure", id); | ||||||
|  | +		panic("failed to allocate %s clock structure", clk_names[type]); | ||||||
|  |   | ||||||
|  | -	err = clk_register_clkdev(clk, id, NULL); | ||||||
|  | -	if (err) | ||||||
|  | -		panic("unable to register %s clock device", id); | ||||||
|  | +	clks[type] = clk; | ||||||
|  | +	clk_register_clkdev(clk, name, NULL); | ||||||
|  | +} | ||||||
|  |   | ||||||
|  | +static struct clk * __init ath79_set_clk(int type, unsigned long rate) | ||||||
|  | +{ | ||||||
|  | +	const char *name = ath79_clk_name(type); | ||||||
|  | +	struct clk *clk; | ||||||
|  | + | ||||||
|  | +	clk = clk_register_fixed_rate(NULL, name, NULL, 0, rate); | ||||||
|  | +	__ath79_set_clk(type, name, clk); | ||||||
|  | +	return clk; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static struct clk * __init ath79_set_ff_clk(int type, const char *parent, | ||||||
|  | +					    unsigned int mult, unsigned int div) | ||||||
|  | +{ | ||||||
|  | +	const char *name = ath79_clk_name(type); | ||||||
|  | +	struct clk *clk; | ||||||
|  | + | ||||||
|  | +	clk = clk_register_fixed_factor(NULL, name, parent, 0, mult, div); | ||||||
|  | +	__ath79_set_clk(type, name, clk); | ||||||
|  |  	return clk; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | @@ -80,27 +106,15 @@ static void __init ar71xx_clocks_init(vo | ||||||
|  |  	div = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1) * 2; | ||||||
|  |  	ahb_rate = cpu_rate / div; | ||||||
|  |   | ||||||
|  | -	ath79_add_sys_clkdev("ref", ref_rate); | ||||||
|  | -	clks[ATH79_CLK_CPU] = ath79_add_sys_clkdev("cpu", cpu_rate); | ||||||
|  | -	clks[ATH79_CLK_DDR] = ath79_add_sys_clkdev("ddr", ddr_rate); | ||||||
|  | -	clks[ATH79_CLK_AHB] = ath79_add_sys_clkdev("ahb", ahb_rate); | ||||||
|  | +	ath79_set_clk(ATH79_CLK_REF, ref_rate); | ||||||
|  | +	ath79_set_clk(ATH79_CLK_CPU, cpu_rate); | ||||||
|  | +	ath79_set_clk(ATH79_CLK_DDR, ddr_rate); | ||||||
|  | +	ath79_set_clk(ATH79_CLK_AHB, ahb_rate); | ||||||
|  |   | ||||||
|  |  	clk_add_alias("wdt", NULL, "ahb", NULL); | ||||||
|  |  	clk_add_alias("uart", NULL, "ahb", NULL); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -static struct clk * __init ath79_reg_ffclk(const char *name, | ||||||
|  | -		const char *parent_name, unsigned int mult, unsigned int div) | ||||||
|  | -{ | ||||||
|  | -	struct clk *clk; | ||||||
|  | - | ||||||
|  | -	clk = clk_register_fixed_factor(NULL, name, parent_name, 0, mult, div); | ||||||
|  | -	if (IS_ERR(clk)) | ||||||
|  | -		panic("failed to allocate %s clock structure", name); | ||||||
|  | - | ||||||
|  | -	return clk; | ||||||
|  | -} | ||||||
|  | - | ||||||
|  |  static void __init ar724x_clk_init(struct clk *ref_clk, void __iomem *pll_base) | ||||||
|  |  { | ||||||
|  |  	u32 pll; | ||||||
|  | @@ -114,24 +128,19 @@ static void __init ar724x_clk_init(struc | ||||||
|  |  	ddr_div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1; | ||||||
|  |  	ahb_div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2; | ||||||
|  |   | ||||||
|  | -	clks[ATH79_CLK_CPU] = ath79_reg_ffclk("cpu", "ref", mult, div); | ||||||
|  | -	clks[ATH79_CLK_DDR] = ath79_reg_ffclk("ddr", "ref", mult, div * ddr_div); | ||||||
|  | -	clks[ATH79_CLK_AHB] = ath79_reg_ffclk("ahb", "ref", mult, div * ahb_div); | ||||||
|  | +	ath79_set_ff_clk(ATH79_CLK_CPU, "ref", mult, div); | ||||||
|  | +	ath79_set_ff_clk(ATH79_CLK_DDR, "ref", mult, div * ddr_div); | ||||||
|  | +	ath79_set_ff_clk(ATH79_CLK_AHB, "ref", mult, div * ahb_div); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static void __init ar724x_clocks_init(void) | ||||||
|  |  { | ||||||
|  |  	struct clk *ref_clk; | ||||||
|  |   | ||||||
|  | -	ref_clk = ath79_add_sys_clkdev("ref", AR724X_BASE_FREQ); | ||||||
|  | +	ref_clk = ath79_set_clk(ATH79_CLK_REF, AR724X_BASE_FREQ); | ||||||
|  |   | ||||||
|  |  	ar724x_clk_init(ref_clk, ath79_pll_base); | ||||||
|  |   | ||||||
|  | -	/* just make happy plat_time_init() from arch/mips/ath79/setup.c */ | ||||||
|  | -	clk_register_clkdev(clks[ATH79_CLK_CPU], "cpu", NULL); | ||||||
|  | -	clk_register_clkdev(clks[ATH79_CLK_DDR], "ddr", NULL); | ||||||
|  | -	clk_register_clkdev(clks[ATH79_CLK_AHB], "ahb", NULL); | ||||||
|  | - | ||||||
|  |  	clk_add_alias("wdt", NULL, "ahb", NULL); | ||||||
|  |  	clk_add_alias("uart", NULL, "ahb", NULL); | ||||||
|  |  } | ||||||
|  | @@ -186,12 +195,12 @@ static void __init ar9330_clk_init(struc | ||||||
|  |  		     AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK) + 1; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -	clks[ATH79_CLK_CPU] = ath79_reg_ffclk("cpu", "ref", | ||||||
|  | -					ninit_mul, ref_div * out_div * cpu_div); | ||||||
|  | -	clks[ATH79_CLK_DDR] = ath79_reg_ffclk("ddr", "ref", | ||||||
|  | -					ninit_mul, ref_div * out_div * ddr_div); | ||||||
|  | -	clks[ATH79_CLK_AHB] = ath79_reg_ffclk("ahb", "ref", | ||||||
|  | -					ninit_mul, ref_div * out_div * ahb_div); | ||||||
|  | +	ath79_set_ff_clk(ATH79_CLK_CPU, "ref", ninit_mul, | ||||||
|  | +			 ref_div * out_div * cpu_div); | ||||||
|  | +	ath79_set_ff_clk(ATH79_CLK_DDR, "ref", ninit_mul, | ||||||
|  | +			 ref_div * out_div * ddr_div); | ||||||
|  | +	ath79_set_ff_clk(ATH79_CLK_AHB, "ref", ninit_mul, | ||||||
|  | +			 ref_div * out_div * ahb_div); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static void __init ar933x_clocks_init(void) | ||||||
|  | @@ -206,15 +215,10 @@ static void __init ar933x_clocks_init(vo | ||||||
|  |  	else | ||||||
|  |  		ref_rate = (25 * 1000 * 1000); | ||||||
|  |   | ||||||
|  | -	ref_clk = ath79_add_sys_clkdev("ref", ref_rate); | ||||||
|  | +	ref_clk = ath79_set_clk(ATH79_CLK_REF, ref_rate); | ||||||
|  |   | ||||||
|  |  	ar9330_clk_init(ref_clk, ath79_pll_base); | ||||||
|  |   | ||||||
|  | -	/* just make happy plat_time_init() from arch/mips/ath79/setup.c */ | ||||||
|  | -	clk_register_clkdev(clks[ATH79_CLK_CPU], "cpu", NULL); | ||||||
|  | -	clk_register_clkdev(clks[ATH79_CLK_DDR], "ddr", NULL); | ||||||
|  | -	clk_register_clkdev(clks[ATH79_CLK_AHB], "ahb", NULL); | ||||||
|  | - | ||||||
|  |  	clk_add_alias("wdt", NULL, "ahb", NULL); | ||||||
|  |  	clk_add_alias("uart", NULL, "ref", NULL); | ||||||
|  |  } | ||||||
|  | @@ -344,10 +348,10 @@ static void __init ar934x_clocks_init(vo | ||||||
|  |  	else | ||||||
|  |  		ahb_rate = cpu_pll / (postdiv + 1); | ||||||
|  |   | ||||||
|  | -	ath79_add_sys_clkdev("ref", ref_rate); | ||||||
|  | -	clks[ATH79_CLK_CPU] = ath79_add_sys_clkdev("cpu", cpu_rate); | ||||||
|  | -	clks[ATH79_CLK_DDR] = ath79_add_sys_clkdev("ddr", ddr_rate); | ||||||
|  | -	clks[ATH79_CLK_AHB] = ath79_add_sys_clkdev("ahb", ahb_rate); | ||||||
|  | +	ath79_set_clk(ATH79_CLK_REF, ref_rate); | ||||||
|  | +	ath79_set_clk(ATH79_CLK_CPU, cpu_rate); | ||||||
|  | +	ath79_set_clk(ATH79_CLK_DDR, ddr_rate); | ||||||
|  | +	ath79_set_clk(ATH79_CLK_AHB, ahb_rate); | ||||||
|  |   | ||||||
|  |  	clk_add_alias("wdt", NULL, "ref", NULL); | ||||||
|  |  	clk_add_alias("uart", NULL, "ref", NULL); | ||||||
|  | @@ -431,10 +435,10 @@ static void __init qca953x_clocks_init(v | ||||||
|  |  	else | ||||||
|  |  		ahb_rate = cpu_pll / (postdiv + 1); | ||||||
|  |   | ||||||
|  | -	ath79_add_sys_clkdev("ref", ref_rate); | ||||||
|  | -	ath79_add_sys_clkdev("cpu", cpu_rate); | ||||||
|  | -	ath79_add_sys_clkdev("ddr", ddr_rate); | ||||||
|  | -	ath79_add_sys_clkdev("ahb", ahb_rate); | ||||||
|  | +	ath79_set_clk(ATH79_CLK_REF, ref_rate); | ||||||
|  | +	ath79_set_clk(ATH79_CLK_CPU, cpu_rate); | ||||||
|  | +	ath79_set_clk(ATH79_CLK_DDR, ddr_rate); | ||||||
|  | +	ath79_set_clk(ATH79_CLK_AHB, ahb_rate); | ||||||
|  |   | ||||||
|  |  	clk_add_alias("wdt", NULL, "ref", NULL); | ||||||
|  |  	clk_add_alias("uart", NULL, "ref", NULL); | ||||||
|  | @@ -516,10 +520,10 @@ static void __init qca955x_clocks_init(v | ||||||
|  |  	else | ||||||
|  |  		ahb_rate = cpu_pll / (postdiv + 1); | ||||||
|  |   | ||||||
|  | -	ath79_add_sys_clkdev("ref", ref_rate); | ||||||
|  | -	clks[ATH79_CLK_CPU] = ath79_add_sys_clkdev("cpu", cpu_rate); | ||||||
|  | -	clks[ATH79_CLK_DDR] = ath79_add_sys_clkdev("ddr", ddr_rate); | ||||||
|  | -	clks[ATH79_CLK_AHB] = ath79_add_sys_clkdev("ahb", ahb_rate); | ||||||
|  | +	ath79_set_clk(ATH79_CLK_REF, ref_rate); | ||||||
|  | +	ath79_set_clk(ATH79_CLK_CPU, cpu_rate); | ||||||
|  | +	ath79_set_clk(ATH79_CLK_DDR, ddr_rate); | ||||||
|  | +	ath79_set_clk(ATH79_CLK_AHB, ahb_rate); | ||||||
|  |   | ||||||
|  |  	clk_add_alias("wdt", NULL, "ref", NULL); | ||||||
|  |  	clk_add_alias("uart", NULL, "ref", NULL); | ||||||
|  | @@ -620,10 +624,10 @@ static void __init qca956x_clocks_init(v | ||||||
|  |  	else | ||||||
|  |  		ahb_rate = cpu_pll / (postdiv + 1); | ||||||
|  |   | ||||||
|  | -	ath79_add_sys_clkdev("ref", ref_rate); | ||||||
|  | -	ath79_add_sys_clkdev("cpu", cpu_rate); | ||||||
|  | -	ath79_add_sys_clkdev("ddr", ddr_rate); | ||||||
|  | -	ath79_add_sys_clkdev("ahb", ahb_rate); | ||||||
|  | +	ath79_set_clk(ATH79_CLK_REF, ref_rate); | ||||||
|  | +	ath79_set_clk(ATH79_CLK_CPU, cpu_rate); | ||||||
|  | +	ath79_set_clk(ATH79_CLK_DDR, ddr_rate); | ||||||
|  | +	ath79_set_clk(ATH79_CLK_AHB, ahb_rate); | ||||||
|  |   | ||||||
|  |  	clk_add_alias("wdt", NULL, "ref", NULL); | ||||||
|  |  	clk_add_alias("uart", NULL, "ref", NULL); | ||||||
|  | --- a/include/dt-bindings/clock/ath79-clk.h | ||||||
|  | +++ b/include/dt-bindings/clock/ath79-clk.h | ||||||
|  | @@ -13,7 +13,8 @@ | ||||||
|  |  #define ATH79_CLK_CPU		0 | ||||||
|  |  #define ATH79_CLK_DDR		1 | ||||||
|  |  #define ATH79_CLK_AHB		2 | ||||||
|  | +#define ATH79_CLK_REF		3 | ||||||
|  |   | ||||||
|  | -#define ATH79_CLK_END		3 | ||||||
|  | +#define ATH79_CLK_END		4 | ||||||
|  |   | ||||||
|  |  #endif /* __DT_BINDINGS_ATH79_CLK_H */ | ||||||
| @@ -0,0 +1,114 @@ | |||||||
|  | From 339c191a95e978353c9ba3aafab0261e14de109b Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Tue, 6 Mar 2018 13:22:43 +0100 | ||||||
|  | Subject: [PATCH 22/33] MIPS: ath79: move legacy "wdt" and "uart" clock aliases | ||||||
|  |  out of soc init | ||||||
|  |  | ||||||
|  | Preparation for reusing functions for DT | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Signed-off-by: John Crispin <john@phrozen.org> | ||||||
|  | --- | ||||||
|  |  arch/mips/ath79/clock.c | 38 +++++++++++++++++--------------------- | ||||||
|  |  1 file changed, 17 insertions(+), 21 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/arch/mips/ath79/clock.c | ||||||
|  | +++ b/arch/mips/ath79/clock.c | ||||||
|  | @@ -110,9 +110,6 @@ static void __init ar71xx_clocks_init(vo | ||||||
|  |  	ath79_set_clk(ATH79_CLK_CPU, cpu_rate); | ||||||
|  |  	ath79_set_clk(ATH79_CLK_DDR, ddr_rate); | ||||||
|  |  	ath79_set_clk(ATH79_CLK_AHB, ahb_rate); | ||||||
|  | - | ||||||
|  | -	clk_add_alias("wdt", NULL, "ahb", NULL); | ||||||
|  | -	clk_add_alias("uart", NULL, "ahb", NULL); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static void __init ar724x_clk_init(struct clk *ref_clk, void __iomem *pll_base) | ||||||
|  | @@ -140,9 +137,6 @@ static void __init ar724x_clocks_init(vo | ||||||
|  |  	ref_clk = ath79_set_clk(ATH79_CLK_REF, AR724X_BASE_FREQ); | ||||||
|  |   | ||||||
|  |  	ar724x_clk_init(ref_clk, ath79_pll_base); | ||||||
|  | - | ||||||
|  | -	clk_add_alias("wdt", NULL, "ahb", NULL); | ||||||
|  | -	clk_add_alias("uart", NULL, "ahb", NULL); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static void __init ar9330_clk_init(struct clk *ref_clk, void __iomem *pll_base) | ||||||
|  | @@ -218,9 +212,6 @@ static void __init ar933x_clocks_init(vo | ||||||
|  |  	ref_clk = ath79_set_clk(ATH79_CLK_REF, ref_rate); | ||||||
|  |   | ||||||
|  |  	ar9330_clk_init(ref_clk, ath79_pll_base); | ||||||
|  | - | ||||||
|  | -	clk_add_alias("wdt", NULL, "ahb", NULL); | ||||||
|  | -	clk_add_alias("uart", NULL, "ref", NULL); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static u32 __init ar934x_get_pll_freq(u32 ref, u32 ref_div, u32 nint, u32 nfrac, | ||||||
|  | @@ -353,9 +344,6 @@ static void __init ar934x_clocks_init(vo | ||||||
|  |  	ath79_set_clk(ATH79_CLK_DDR, ddr_rate); | ||||||
|  |  	ath79_set_clk(ATH79_CLK_AHB, ahb_rate); | ||||||
|  |   | ||||||
|  | -	clk_add_alias("wdt", NULL, "ref", NULL); | ||||||
|  | -	clk_add_alias("uart", NULL, "ref", NULL); | ||||||
|  | - | ||||||
|  |  	iounmap(dpll_base); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | @@ -439,9 +427,6 @@ static void __init qca953x_clocks_init(v | ||||||
|  |  	ath79_set_clk(ATH79_CLK_CPU, cpu_rate); | ||||||
|  |  	ath79_set_clk(ATH79_CLK_DDR, ddr_rate); | ||||||
|  |  	ath79_set_clk(ATH79_CLK_AHB, ahb_rate); | ||||||
|  | - | ||||||
|  | -	clk_add_alias("wdt", NULL, "ref", NULL); | ||||||
|  | -	clk_add_alias("uart", NULL, "ref", NULL); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static void __init qca955x_clocks_init(void) | ||||||
|  | @@ -524,9 +509,6 @@ static void __init qca955x_clocks_init(v | ||||||
|  |  	ath79_set_clk(ATH79_CLK_CPU, cpu_rate); | ||||||
|  |  	ath79_set_clk(ATH79_CLK_DDR, ddr_rate); | ||||||
|  |  	ath79_set_clk(ATH79_CLK_AHB, ahb_rate); | ||||||
|  | - | ||||||
|  | -	clk_add_alias("wdt", NULL, "ref", NULL); | ||||||
|  | -	clk_add_alias("uart", NULL, "ref", NULL); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static void __init qca956x_clocks_init(void) | ||||||
|  | @@ -628,13 +610,13 @@ static void __init qca956x_clocks_init(v | ||||||
|  |  	ath79_set_clk(ATH79_CLK_CPU, cpu_rate); | ||||||
|  |  	ath79_set_clk(ATH79_CLK_DDR, ddr_rate); | ||||||
|  |  	ath79_set_clk(ATH79_CLK_AHB, ahb_rate); | ||||||
|  | - | ||||||
|  | -	clk_add_alias("wdt", NULL, "ref", NULL); | ||||||
|  | -	clk_add_alias("uart", NULL, "ref", NULL); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  void __init ath79_clocks_init(void) | ||||||
|  |  { | ||||||
|  | +	const char *wdt; | ||||||
|  | +	const char *uart; | ||||||
|  | + | ||||||
|  |  	if (soc_is_ar71xx()) | ||||||
|  |  		ar71xx_clocks_init(); | ||||||
|  |  	else if (soc_is_ar724x() || soc_is_ar913x()) | ||||||
|  | @@ -651,6 +633,20 @@ void __init ath79_clocks_init(void) | ||||||
|  |  		qca956x_clocks_init(); | ||||||
|  |  	else | ||||||
|  |  		BUG(); | ||||||
|  | + | ||||||
|  | +	if (soc_is_ar71xx() || soc_is_ar724x() || soc_is_ar913x()) { | ||||||
|  | +		wdt = "ahb"; | ||||||
|  | +		uart = "ahb"; | ||||||
|  | +	} else if (soc_is_ar933x()) { | ||||||
|  | +		wdt = "ahb"; | ||||||
|  | +		uart = "ref"; | ||||||
|  | +	} else { | ||||||
|  | +		wdt = "ref"; | ||||||
|  | +		uart = "ref"; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	clk_add_alias("wdt", NULL, wdt, NULL); | ||||||
|  | +	clk_add_alias("uart", NULL, uart, NULL); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  unsigned long __init | ||||||
| @@ -0,0 +1,242 @@ | |||||||
|  | From 6350b2c36c522fecbc91a80b63f49319dafd2a72 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Tue, 6 Mar 2018 13:23:20 +0100 | ||||||
|  | Subject: [PATCH 23/33] MIPS: ath79: pass PLL base to clock init functions | ||||||
|  |  | ||||||
|  | Preparation for passing the mapped base via DT | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Signed-off-by: John Crispin <john@phrozen.org> | ||||||
|  | --- | ||||||
|  |  arch/mips/ath79/clock.c | 60 ++++++++++++++++++++++++------------------------- | ||||||
|  |  1 file changed, 30 insertions(+), 30 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/arch/mips/ath79/clock.c | ||||||
|  | +++ b/arch/mips/ath79/clock.c | ||||||
|  | @@ -80,7 +80,7 @@ static struct clk * __init ath79_set_ff_ | ||||||
|  |  	return clk; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -static void __init ar71xx_clocks_init(void) | ||||||
|  | +static void __init ar71xx_clocks_init(void __iomem *pll_base) | ||||||
|  |  { | ||||||
|  |  	unsigned long ref_rate; | ||||||
|  |  	unsigned long cpu_rate; | ||||||
|  | @@ -92,7 +92,7 @@ static void __init ar71xx_clocks_init(vo | ||||||
|  |   | ||||||
|  |  	ref_rate = AR71XX_BASE_FREQ; | ||||||
|  |   | ||||||
|  | -	pll = ath79_pll_rr(AR71XX_PLL_REG_CPU_CONFIG); | ||||||
|  | +	pll = __raw_readl(pll_base + AR71XX_PLL_REG_CPU_CONFIG); | ||||||
|  |   | ||||||
|  |  	div = ((pll >> AR71XX_PLL_FB_SHIFT) & AR71XX_PLL_FB_MASK) + 1; | ||||||
|  |  	freq = div * ref_rate; | ||||||
|  | @@ -130,13 +130,13 @@ static void __init ar724x_clk_init(struc | ||||||
|  |  	ath79_set_ff_clk(ATH79_CLK_AHB, "ref", mult, div * ahb_div); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -static void __init ar724x_clocks_init(void) | ||||||
|  | +static void __init ar724x_clocks_init(void __iomem *pll_base) | ||||||
|  |  { | ||||||
|  |  	struct clk *ref_clk; | ||||||
|  |   | ||||||
|  |  	ref_clk = ath79_set_clk(ATH79_CLK_REF, AR724X_BASE_FREQ); | ||||||
|  |   | ||||||
|  | -	ar724x_clk_init(ref_clk, ath79_pll_base); | ||||||
|  | +	ar724x_clk_init(ref_clk, pll_base); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static void __init ar9330_clk_init(struct clk *ref_clk, void __iomem *pll_base) | ||||||
|  | @@ -197,7 +197,7 @@ static void __init ar9330_clk_init(struc | ||||||
|  |  			 ref_div * out_div * ahb_div); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -static void __init ar933x_clocks_init(void) | ||||||
|  | +static void __init ar933x_clocks_init(void __iomem *pll_base) | ||||||
|  |  { | ||||||
|  |  	struct clk *ref_clk; | ||||||
|  |  	unsigned long ref_rate; | ||||||
|  | @@ -234,7 +234,7 @@ static u32 __init ar934x_get_pll_freq(u3 | ||||||
|  |  	return ret; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -static void __init ar934x_clocks_init(void) | ||||||
|  | +static void __init ar934x_clocks_init(void __iomem *pll_base) | ||||||
|  |  { | ||||||
|  |  	unsigned long ref_rate; | ||||||
|  |  	unsigned long cpu_rate; | ||||||
|  | @@ -265,7 +265,7 @@ static void __init ar934x_clocks_init(vo | ||||||
|  |  			  AR934X_SRIF_DPLL1_REFDIV_MASK; | ||||||
|  |  		frac = 1 << 18; | ||||||
|  |  	} else { | ||||||
|  | -		pll = ath79_pll_rr(AR934X_PLL_CPU_CONFIG_REG); | ||||||
|  | +		pll = __raw_readl(pll_base + AR934X_PLL_CPU_CONFIG_REG); | ||||||
|  |  		out_div = (pll >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & | ||||||
|  |  			AR934X_PLL_CPU_CONFIG_OUTDIV_MASK; | ||||||
|  |  		ref_div = (pll >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) & | ||||||
|  | @@ -292,7 +292,7 @@ static void __init ar934x_clocks_init(vo | ||||||
|  |  			  AR934X_SRIF_DPLL1_REFDIV_MASK; | ||||||
|  |  		frac = 1 << 18; | ||||||
|  |  	} else { | ||||||
|  | -		pll = ath79_pll_rr(AR934X_PLL_DDR_CONFIG_REG); | ||||||
|  | +		pll = __raw_readl(pll_base + AR934X_PLL_DDR_CONFIG_REG); | ||||||
|  |  		out_div = (pll >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & | ||||||
|  |  			  AR934X_PLL_DDR_CONFIG_OUTDIV_MASK; | ||||||
|  |  		ref_div = (pll >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) & | ||||||
|  | @@ -307,7 +307,7 @@ static void __init ar934x_clocks_init(vo | ||||||
|  |  	ddr_pll = ar934x_get_pll_freq(ref_rate, ref_div, nint, | ||||||
|  |  				      nfrac, frac, out_div); | ||||||
|  |   | ||||||
|  | -	clk_ctrl = ath79_pll_rr(AR934X_PLL_CPU_DDR_CLK_CTRL_REG); | ||||||
|  | +	clk_ctrl = __raw_readl(pll_base + AR934X_PLL_CPU_DDR_CLK_CTRL_REG); | ||||||
|  |   | ||||||
|  |  	postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SHIFT) & | ||||||
|  |  		  AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK; | ||||||
|  | @@ -347,7 +347,7 @@ static void __init ar934x_clocks_init(vo | ||||||
|  |  	iounmap(dpll_base); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -static void __init qca953x_clocks_init(void) | ||||||
|  | +static void __init qca953x_clocks_init(void __iomem *pll_base) | ||||||
|  |  { | ||||||
|  |  	unsigned long ref_rate; | ||||||
|  |  	unsigned long cpu_rate; | ||||||
|  | @@ -363,7 +363,7 @@ static void __init qca953x_clocks_init(v | ||||||
|  |  	else | ||||||
|  |  		ref_rate = 25 * 1000 * 1000; | ||||||
|  |   | ||||||
|  | -	pll = ath79_pll_rr(QCA953X_PLL_CPU_CONFIG_REG); | ||||||
|  | +	pll = __raw_readl(pll_base + QCA953X_PLL_CPU_CONFIG_REG); | ||||||
|  |  	out_div = (pll >> QCA953X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & | ||||||
|  |  		  QCA953X_PLL_CPU_CONFIG_OUTDIV_MASK; | ||||||
|  |  	ref_div = (pll >> QCA953X_PLL_CPU_CONFIG_REFDIV_SHIFT) & | ||||||
|  | @@ -377,7 +377,7 @@ static void __init qca953x_clocks_init(v | ||||||
|  |  	cpu_pll += frac * (ref_rate >> 6) / ref_div; | ||||||
|  |  	cpu_pll /= (1 << out_div); | ||||||
|  |   | ||||||
|  | -	pll = ath79_pll_rr(QCA953X_PLL_DDR_CONFIG_REG); | ||||||
|  | +	pll = __raw_readl(pll_base + QCA953X_PLL_DDR_CONFIG_REG); | ||||||
|  |  	out_div = (pll >> QCA953X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & | ||||||
|  |  		  QCA953X_PLL_DDR_CONFIG_OUTDIV_MASK; | ||||||
|  |  	ref_div = (pll >> QCA953X_PLL_DDR_CONFIG_REFDIV_SHIFT) & | ||||||
|  | @@ -391,7 +391,7 @@ static void __init qca953x_clocks_init(v | ||||||
|  |  	ddr_pll += frac * (ref_rate >> 6) / (ref_div << 4); | ||||||
|  |  	ddr_pll /= (1 << out_div); | ||||||
|  |   | ||||||
|  | -	clk_ctrl = ath79_pll_rr(QCA953X_PLL_CLK_CTRL_REG); | ||||||
|  | +	clk_ctrl = __raw_readl(pll_base + QCA953X_PLL_CLK_CTRL_REG); | ||||||
|  |   | ||||||
|  |  	postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & | ||||||
|  |  		  QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; | ||||||
|  | @@ -429,7 +429,7 @@ static void __init qca953x_clocks_init(v | ||||||
|  |  	ath79_set_clk(ATH79_CLK_AHB, ahb_rate); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -static void __init qca955x_clocks_init(void) | ||||||
|  | +static void __init qca955x_clocks_init(void __iomem *pll_base) | ||||||
|  |  { | ||||||
|  |  	unsigned long ref_rate; | ||||||
|  |  	unsigned long cpu_rate; | ||||||
|  | @@ -445,7 +445,7 @@ static void __init qca955x_clocks_init(v | ||||||
|  |  	else | ||||||
|  |  		ref_rate = 25 * 1000 * 1000; | ||||||
|  |   | ||||||
|  | -	pll = ath79_pll_rr(QCA955X_PLL_CPU_CONFIG_REG); | ||||||
|  | +	pll = __raw_readl(pll_base + QCA955X_PLL_CPU_CONFIG_REG); | ||||||
|  |  	out_div = (pll >> QCA955X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & | ||||||
|  |  		  QCA955X_PLL_CPU_CONFIG_OUTDIV_MASK; | ||||||
|  |  	ref_div = (pll >> QCA955X_PLL_CPU_CONFIG_REFDIV_SHIFT) & | ||||||
|  | @@ -459,7 +459,7 @@ static void __init qca955x_clocks_init(v | ||||||
|  |  	cpu_pll += frac * ref_rate / (ref_div * (1 << 6)); | ||||||
|  |  	cpu_pll /= (1 << out_div); | ||||||
|  |   | ||||||
|  | -	pll = ath79_pll_rr(QCA955X_PLL_DDR_CONFIG_REG); | ||||||
|  | +	pll = __raw_readl(pll_base + QCA955X_PLL_DDR_CONFIG_REG); | ||||||
|  |  	out_div = (pll >> QCA955X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & | ||||||
|  |  		  QCA955X_PLL_DDR_CONFIG_OUTDIV_MASK; | ||||||
|  |  	ref_div = (pll >> QCA955X_PLL_DDR_CONFIG_REFDIV_SHIFT) & | ||||||
|  | @@ -473,7 +473,7 @@ static void __init qca955x_clocks_init(v | ||||||
|  |  	ddr_pll += frac * ref_rate / (ref_div * (1 << 10)); | ||||||
|  |  	ddr_pll /= (1 << out_div); | ||||||
|  |   | ||||||
|  | -	clk_ctrl = ath79_pll_rr(QCA955X_PLL_CLK_CTRL_REG); | ||||||
|  | +	clk_ctrl = __raw_readl(pll_base + QCA955X_PLL_CLK_CTRL_REG); | ||||||
|  |   | ||||||
|  |  	postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & | ||||||
|  |  		  QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; | ||||||
|  | @@ -511,7 +511,7 @@ static void __init qca955x_clocks_init(v | ||||||
|  |  	ath79_set_clk(ATH79_CLK_AHB, ahb_rate); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -static void __init qca956x_clocks_init(void) | ||||||
|  | +static void __init qca956x_clocks_init(void __iomem *pll_base) | ||||||
|  |  { | ||||||
|  |  	unsigned long ref_rate; | ||||||
|  |  	unsigned long cpu_rate; | ||||||
|  | @@ -537,13 +537,13 @@ static void __init qca956x_clocks_init(v | ||||||
|  |  	else | ||||||
|  |  		ref_rate = 25 * 1000 * 1000; | ||||||
|  |   | ||||||
|  | -	pll = ath79_pll_rr(QCA956X_PLL_CPU_CONFIG_REG); | ||||||
|  | +	pll = __raw_readl(pll_base + QCA956X_PLL_CPU_CONFIG_REG); | ||||||
|  |  	out_div = (pll >> QCA956X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & | ||||||
|  |  		  QCA956X_PLL_CPU_CONFIG_OUTDIV_MASK; | ||||||
|  |  	ref_div = (pll >> QCA956X_PLL_CPU_CONFIG_REFDIV_SHIFT) & | ||||||
|  |  		  QCA956X_PLL_CPU_CONFIG_REFDIV_MASK; | ||||||
|  |   | ||||||
|  | -	pll = ath79_pll_rr(QCA956X_PLL_CPU_CONFIG1_REG); | ||||||
|  | +	pll = __raw_readl(pll_base + QCA956X_PLL_CPU_CONFIG1_REG); | ||||||
|  |  	nint = (pll >> QCA956X_PLL_CPU_CONFIG1_NINT_SHIFT) & | ||||||
|  |  	       QCA956X_PLL_CPU_CONFIG1_NINT_MASK; | ||||||
|  |  	hfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_H_SHIFT) & | ||||||
|  | @@ -556,12 +556,12 @@ static void __init qca956x_clocks_init(v | ||||||
|  |  	cpu_pll += (hfrac >> 13) * ref_rate / ref_div; | ||||||
|  |  	cpu_pll /= (1 << out_div); | ||||||
|  |   | ||||||
|  | -	pll = ath79_pll_rr(QCA956X_PLL_DDR_CONFIG_REG); | ||||||
|  | +	pll = __raw_readl(pll_base + QCA956X_PLL_DDR_CONFIG_REG); | ||||||
|  |  	out_div = (pll >> QCA956X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & | ||||||
|  |  		  QCA956X_PLL_DDR_CONFIG_OUTDIV_MASK; | ||||||
|  |  	ref_div = (pll >> QCA956X_PLL_DDR_CONFIG_REFDIV_SHIFT) & | ||||||
|  |  		  QCA956X_PLL_DDR_CONFIG_REFDIV_MASK; | ||||||
|  | -	pll = ath79_pll_rr(QCA956X_PLL_DDR_CONFIG1_REG); | ||||||
|  | +	pll = __raw_readl(pll_base + QCA956X_PLL_DDR_CONFIG1_REG); | ||||||
|  |  	nint = (pll >> QCA956X_PLL_DDR_CONFIG1_NINT_SHIFT) & | ||||||
|  |  	       QCA956X_PLL_DDR_CONFIG1_NINT_MASK; | ||||||
|  |  	hfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_H_SHIFT) & | ||||||
|  | @@ -574,7 +574,7 @@ static void __init qca956x_clocks_init(v | ||||||
|  |  	ddr_pll += (hfrac >> 13) * ref_rate / ref_div; | ||||||
|  |  	ddr_pll /= (1 << out_div); | ||||||
|  |   | ||||||
|  | -	clk_ctrl = ath79_pll_rr(QCA956X_PLL_CLK_CTRL_REG); | ||||||
|  | +	clk_ctrl = __raw_readl(pll_base + QCA956X_PLL_CLK_CTRL_REG); | ||||||
|  |   | ||||||
|  |  	postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & | ||||||
|  |  		  QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; | ||||||
|  | @@ -618,19 +618,19 @@ void __init ath79_clocks_init(void) | ||||||
|  |  	const char *uart; | ||||||
|  |   | ||||||
|  |  	if (soc_is_ar71xx()) | ||||||
|  | -		ar71xx_clocks_init(); | ||||||
|  | +		ar71xx_clocks_init(ath79_pll_base); | ||||||
|  |  	else if (soc_is_ar724x() || soc_is_ar913x()) | ||||||
|  | -		ar724x_clocks_init(); | ||||||
|  | +		ar724x_clocks_init(ath79_pll_base); | ||||||
|  |  	else if (soc_is_ar933x()) | ||||||
|  | -		ar933x_clocks_init(); | ||||||
|  | +		ar933x_clocks_init(ath79_pll_base); | ||||||
|  |  	else if (soc_is_ar934x()) | ||||||
|  | -		ar934x_clocks_init(); | ||||||
|  | +		ar934x_clocks_init(ath79_pll_base); | ||||||
|  |  	else if (soc_is_qca953x()) | ||||||
|  | -		qca953x_clocks_init(); | ||||||
|  | +		qca953x_clocks_init(ath79_pll_base); | ||||||
|  |  	else if (soc_is_qca955x()) | ||||||
|  | -		qca955x_clocks_init(); | ||||||
|  | +		qca955x_clocks_init(ath79_pll_base); | ||||||
|  |  	else if (soc_is_qca956x() || soc_is_tp9343()) | ||||||
|  | -		qca956x_clocks_init(); | ||||||
|  | +		qca956x_clocks_init(ath79_pll_base); | ||||||
|  |  	else | ||||||
|  |  		BUG(); | ||||||
|  |   | ||||||
| @@ -0,0 +1,229 @@ | |||||||
|  | From 5fadb2544ed0bb72ddddd846aa303bb9ed2d211c Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Tue, 6 Mar 2018 13:24:07 +0100 | ||||||
|  | Subject: [PATCH 24/33] MIPS: ath79: make specifying the reference clock in DT | ||||||
|  |  optional | ||||||
|  |  | ||||||
|  | It can be autodetected for many SoCs using the strapping options. | ||||||
|  | If the clock is specified in DT, the autodetected value is ignored | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Signed-off-by: John Crispin <john@phrozen.org> | ||||||
|  | --- | ||||||
|  |  arch/mips/ath79/clock.c | 84 +++++++++++++++++++++++-------------------------- | ||||||
|  |  1 file changed, 40 insertions(+), 44 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/arch/mips/ath79/clock.c | ||||||
|  | +++ b/arch/mips/ath79/clock.c | ||||||
|  | @@ -80,6 +80,18 @@ static struct clk * __init ath79_set_ff_ | ||||||
|  |  	return clk; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +static unsigned long __init ath79_setup_ref_clk(unsigned long rate) | ||||||
|  | +{ | ||||||
|  | +	struct clk *clk = clks[ATH79_CLK_REF]; | ||||||
|  | + | ||||||
|  | +	if (clk) | ||||||
|  | +		rate = clk_get_rate(clk); | ||||||
|  | +	else | ||||||
|  | +		clk = ath79_set_clk(ATH79_CLK_REF, rate); | ||||||
|  | + | ||||||
|  | +	return rate; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  static void __init ar71xx_clocks_init(void __iomem *pll_base) | ||||||
|  |  { | ||||||
|  |  	unsigned long ref_rate; | ||||||
|  | @@ -90,7 +102,7 @@ static void __init ar71xx_clocks_init(vo | ||||||
|  |  	u32 freq; | ||||||
|  |  	u32 div; | ||||||
|  |   | ||||||
|  | -	ref_rate = AR71XX_BASE_FREQ; | ||||||
|  | +	ref_rate = ath79_setup_ref_clk(AR71XX_BASE_FREQ); | ||||||
|  |   | ||||||
|  |  	pll = __raw_readl(pll_base + AR71XX_PLL_REG_CPU_CONFIG); | ||||||
|  |   | ||||||
|  | @@ -106,16 +118,17 @@ static void __init ar71xx_clocks_init(vo | ||||||
|  |  	div = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1) * 2; | ||||||
|  |  	ahb_rate = cpu_rate / div; | ||||||
|  |   | ||||||
|  | -	ath79_set_clk(ATH79_CLK_REF, ref_rate); | ||||||
|  |  	ath79_set_clk(ATH79_CLK_CPU, cpu_rate); | ||||||
|  |  	ath79_set_clk(ATH79_CLK_DDR, ddr_rate); | ||||||
|  |  	ath79_set_clk(ATH79_CLK_AHB, ahb_rate); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -static void __init ar724x_clk_init(struct clk *ref_clk, void __iomem *pll_base) | ||||||
|  | +static void __init ar724x_clocks_init(void __iomem *pll_base) | ||||||
|  |  { | ||||||
|  | -	u32 pll; | ||||||
|  |  	u32 mult, div, ddr_div, ahb_div; | ||||||
|  | +	u32 pll; | ||||||
|  | + | ||||||
|  | +	ath79_setup_ref_clk(AR71XX_BASE_FREQ); | ||||||
|  |   | ||||||
|  |  	pll = __raw_readl(pll_base + AR724X_PLL_REG_CPU_CONFIG); | ||||||
|  |   | ||||||
|  | @@ -130,17 +143,9 @@ static void __init ar724x_clk_init(struc | ||||||
|  |  	ath79_set_ff_clk(ATH79_CLK_AHB, "ref", mult, div * ahb_div); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -static void __init ar724x_clocks_init(void __iomem *pll_base) | ||||||
|  | -{ | ||||||
|  | -	struct clk *ref_clk; | ||||||
|  | - | ||||||
|  | -	ref_clk = ath79_set_clk(ATH79_CLK_REF, AR724X_BASE_FREQ); | ||||||
|  | - | ||||||
|  | -	ar724x_clk_init(ref_clk, pll_base); | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -static void __init ar9330_clk_init(struct clk *ref_clk, void __iomem *pll_base) | ||||||
|  | +static void __init ar933x_clocks_init(void __iomem *pll_base) | ||||||
|  |  { | ||||||
|  | +	unsigned long ref_rate; | ||||||
|  |  	u32 clock_ctrl; | ||||||
|  |  	u32 ref_div; | ||||||
|  |  	u32 ninit_mul; | ||||||
|  | @@ -149,6 +154,15 @@ static void __init ar9330_clk_init(struc | ||||||
|  |  	u32 cpu_div; | ||||||
|  |  	u32 ddr_div; | ||||||
|  |  	u32 ahb_div; | ||||||
|  | +	u32 t; | ||||||
|  | + | ||||||
|  | +	t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); | ||||||
|  | +	if (t & AR933X_BOOTSTRAP_REF_CLK_40) | ||||||
|  | +		ref_rate = (40 * 1000 * 1000); | ||||||
|  | +	else | ||||||
|  | +		ref_rate = (25 * 1000 * 1000); | ||||||
|  | + | ||||||
|  | +	ath79_setup_ref_clk(ref_rate); | ||||||
|  |   | ||||||
|  |  	clock_ctrl = __raw_readl(pll_base + AR933X_PLL_CLOCK_CTRL_REG); | ||||||
|  |  	if (clock_ctrl & AR933X_PLL_CLOCK_CTRL_BYPASS) { | ||||||
|  | @@ -197,23 +211,6 @@ static void __init ar9330_clk_init(struc | ||||||
|  |  			 ref_div * out_div * ahb_div); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -static void __init ar933x_clocks_init(void __iomem *pll_base) | ||||||
|  | -{ | ||||||
|  | -	struct clk *ref_clk; | ||||||
|  | -	unsigned long ref_rate; | ||||||
|  | -	u32 t; | ||||||
|  | - | ||||||
|  | -	t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); | ||||||
|  | -	if (t & AR933X_BOOTSTRAP_REF_CLK_40) | ||||||
|  | -		ref_rate = (40 * 1000 * 1000); | ||||||
|  | -	else | ||||||
|  | -		ref_rate = (25 * 1000 * 1000); | ||||||
|  | - | ||||||
|  | -	ref_clk = ath79_set_clk(ATH79_CLK_REF, ref_rate); | ||||||
|  | - | ||||||
|  | -	ar9330_clk_init(ref_clk, ath79_pll_base); | ||||||
|  | -} | ||||||
|  | - | ||||||
|  |  static u32 __init ar934x_get_pll_freq(u32 ref, u32 ref_div, u32 nint, u32 nfrac, | ||||||
|  |  				      u32 frac, u32 out_div) | ||||||
|  |  { | ||||||
|  | @@ -253,6 +250,8 @@ static void __init ar934x_clocks_init(vo | ||||||
|  |  	else | ||||||
|  |  		ref_rate = 25 * 1000 * 1000; | ||||||
|  |   | ||||||
|  | +	ref_rate = ath79_setup_ref_clk(ref_rate); | ||||||
|  | + | ||||||
|  |  	pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL2_REG); | ||||||
|  |  	if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) { | ||||||
|  |  		out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) & | ||||||
|  | @@ -339,7 +338,6 @@ static void __init ar934x_clocks_init(vo | ||||||
|  |  	else | ||||||
|  |  		ahb_rate = cpu_pll / (postdiv + 1); | ||||||
|  |   | ||||||
|  | -	ath79_set_clk(ATH79_CLK_REF, ref_rate); | ||||||
|  |  	ath79_set_clk(ATH79_CLK_CPU, cpu_rate); | ||||||
|  |  	ath79_set_clk(ATH79_CLK_DDR, ddr_rate); | ||||||
|  |  	ath79_set_clk(ATH79_CLK_AHB, ahb_rate); | ||||||
|  | @@ -363,6 +361,8 @@ static void __init qca953x_clocks_init(v | ||||||
|  |  	else | ||||||
|  |  		ref_rate = 25 * 1000 * 1000; | ||||||
|  |   | ||||||
|  | +	ref_rate = ath79_setup_ref_clk(ref_rate); | ||||||
|  | + | ||||||
|  |  	pll = __raw_readl(pll_base + QCA953X_PLL_CPU_CONFIG_REG); | ||||||
|  |  	out_div = (pll >> QCA953X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & | ||||||
|  |  		  QCA953X_PLL_CPU_CONFIG_OUTDIV_MASK; | ||||||
|  | @@ -423,7 +423,6 @@ static void __init qca953x_clocks_init(v | ||||||
|  |  	else | ||||||
|  |  		ahb_rate = cpu_pll / (postdiv + 1); | ||||||
|  |   | ||||||
|  | -	ath79_set_clk(ATH79_CLK_REF, ref_rate); | ||||||
|  |  	ath79_set_clk(ATH79_CLK_CPU, cpu_rate); | ||||||
|  |  	ath79_set_clk(ATH79_CLK_DDR, ddr_rate); | ||||||
|  |  	ath79_set_clk(ATH79_CLK_AHB, ahb_rate); | ||||||
|  | @@ -445,6 +444,8 @@ static void __init qca955x_clocks_init(v | ||||||
|  |  	else | ||||||
|  |  		ref_rate = 25 * 1000 * 1000; | ||||||
|  |   | ||||||
|  | +	ref_rate = ath79_setup_ref_clk(ref_rate); | ||||||
|  | + | ||||||
|  |  	pll = __raw_readl(pll_base + QCA955X_PLL_CPU_CONFIG_REG); | ||||||
|  |  	out_div = (pll >> QCA955X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & | ||||||
|  |  		  QCA955X_PLL_CPU_CONFIG_OUTDIV_MASK; | ||||||
|  | @@ -505,7 +506,6 @@ static void __init qca955x_clocks_init(v | ||||||
|  |  	else | ||||||
|  |  		ahb_rate = cpu_pll / (postdiv + 1); | ||||||
|  |   | ||||||
|  | -	ath79_set_clk(ATH79_CLK_REF, ref_rate); | ||||||
|  |  	ath79_set_clk(ATH79_CLK_CPU, cpu_rate); | ||||||
|  |  	ath79_set_clk(ATH79_CLK_DDR, ddr_rate); | ||||||
|  |  	ath79_set_clk(ATH79_CLK_AHB, ahb_rate); | ||||||
|  | @@ -537,6 +537,8 @@ static void __init qca956x_clocks_init(v | ||||||
|  |  	else | ||||||
|  |  		ref_rate = 25 * 1000 * 1000; | ||||||
|  |   | ||||||
|  | +	ref_rate = ath79_setup_ref_clk(ref_rate); | ||||||
|  | + | ||||||
|  |  	pll = __raw_readl(pll_base + QCA956X_PLL_CPU_CONFIG_REG); | ||||||
|  |  	out_div = (pll >> QCA956X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & | ||||||
|  |  		  QCA956X_PLL_CPU_CONFIG_OUTDIV_MASK; | ||||||
|  | @@ -606,7 +608,6 @@ static void __init qca956x_clocks_init(v | ||||||
|  |  	else | ||||||
|  |  		ahb_rate = cpu_pll / (postdiv + 1); | ||||||
|  |   | ||||||
|  | -	ath79_set_clk(ATH79_CLK_REF, ref_rate); | ||||||
|  |  	ath79_set_clk(ATH79_CLK_CPU, cpu_rate); | ||||||
|  |  	ath79_set_clk(ATH79_CLK_DDR, ddr_rate); | ||||||
|  |  	ath79_set_clk(ATH79_CLK_AHB, ahb_rate); | ||||||
|  | @@ -682,10 +683,8 @@ static void __init ath79_clocks_init_dt_ | ||||||
|  |  	void __iomem *pll_base; | ||||||
|  |   | ||||||
|  |  	ref_clk = of_clk_get(np, 0); | ||||||
|  | -	if (IS_ERR(ref_clk)) { | ||||||
|  | -		pr_err("%pOF: of_clk_get failed\n", np); | ||||||
|  | -		goto err; | ||||||
|  | -	} | ||||||
|  | +	if (!IS_ERR(ref_clk)) | ||||||
|  | +		clks[ATH79_CLK_REF] = ref_clk; | ||||||
|  |   | ||||||
|  |  	pll_base = of_iomap(np, 0); | ||||||
|  |  	if (!pll_base) { | ||||||
|  | @@ -694,9 +693,9 @@ static void __init ath79_clocks_init_dt_ | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	if (of_device_is_compatible(np, "qca,ar9130-pll")) | ||||||
|  | -		ar724x_clk_init(ref_clk, pll_base); | ||||||
|  | +		ar724x_clocks_init(pll_base); | ||||||
|  |  	else if (of_device_is_compatible(np, "qca,ar9330-pll")) | ||||||
|  | -		ar9330_clk_init(ref_clk, pll_base); | ||||||
|  | +		ar933x_clocks_init(pll_base); | ||||||
|  |  	else { | ||||||
|  |  		pr_err("%pOF: could not find any appropriate clk_init()\n", np); | ||||||
|  |  		goto err_iounmap; | ||||||
|  | @@ -714,9 +713,6 @@ err_iounmap: | ||||||
|  |   | ||||||
|  |  err_clk: | ||||||
|  |  	clk_put(ref_clk); | ||||||
|  | - | ||||||
|  | -err: | ||||||
|  | -	return; | ||||||
|  |  } | ||||||
|  |  CLK_OF_DECLARE(ar9130_clk, "qca,ar9130-pll", ath79_clocks_init_dt_ng); | ||||||
|  |  CLK_OF_DECLARE(ar9330_clk, "qca,ar9330-pll", ath79_clocks_init_dt_ng); | ||||||
| @@ -0,0 +1,77 @@ | |||||||
|  | From 6325626de001df98aebe51f3008b1aca05798d19 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Tue, 6 Mar 2018 13:26:27 +0100 | ||||||
|  | Subject: [PATCH 25/33] MIPS: ath79: support setting up clock via DT on all SoC | ||||||
|  |  types | ||||||
|  |  | ||||||
|  | Use the same functions as the legacy code | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Signed-off-by: John Crispin <john@phrozen.org> | ||||||
|  | --- | ||||||
|  |  arch/mips/ath79/clock.c | 39 ++++++++++++++++++++++----------------- | ||||||
|  |  1 file changed, 22 insertions(+), 17 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/arch/mips/ath79/clock.c | ||||||
|  | +++ b/arch/mips/ath79/clock.c | ||||||
|  | @@ -669,16 +669,6 @@ ath79_get_sys_clk_rate(const char *id) | ||||||
|  |  #ifdef CONFIG_OF | ||||||
|  |  static void __init ath79_clocks_init_dt(struct device_node *np) | ||||||
|  |  { | ||||||
|  | -	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -CLK_OF_DECLARE(ar7100, "qca,ar7100-pll", ath79_clocks_init_dt); | ||||||
|  | -CLK_OF_DECLARE(ar7240, "qca,ar7240-pll", ath79_clocks_init_dt); | ||||||
|  | -CLK_OF_DECLARE(ar9340, "qca,ar9340-pll", ath79_clocks_init_dt); | ||||||
|  | -CLK_OF_DECLARE(ar9550, "qca,qca9550-pll", ath79_clocks_init_dt); | ||||||
|  | - | ||||||
|  | -static void __init ath79_clocks_init_dt_ng(struct device_node *np) | ||||||
|  | -{ | ||||||
|  |  	struct clk *ref_clk; | ||||||
|  |  	void __iomem *pll_base; | ||||||
|  |   | ||||||
|  | @@ -692,14 +682,21 @@ static void __init ath79_clocks_init_dt_ | ||||||
|  |  		goto err_clk; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -	if (of_device_is_compatible(np, "qca,ar9130-pll")) | ||||||
|  | +	if (of_device_is_compatible(np, "qca,ar7100-pll")) | ||||||
|  | +		ar71xx_clocks_init(pll_base); | ||||||
|  | +	else if (of_device_is_compatible(np, "qca,ar7240-pll") || | ||||||
|  | +		 of_device_is_compatible(np, "qca,ar9130-pll")) | ||||||
|  |  		ar724x_clocks_init(pll_base); | ||||||
|  |  	else if (of_device_is_compatible(np, "qca,ar9330-pll")) | ||||||
|  |  		ar933x_clocks_init(pll_base); | ||||||
|  | -	else { | ||||||
|  | -		pr_err("%pOF: could not find any appropriate clk_init()\n", np); | ||||||
|  | -		goto err_iounmap; | ||||||
|  | -	} | ||||||
|  | +	else if (of_device_is_compatible(np, "qca,ar9340-pll")) | ||||||
|  | +		ar934x_clocks_init(pll_base); | ||||||
|  | +	else if (of_device_is_compatible(np, "qca,qca9530-pll")) | ||||||
|  | +		qca953x_clocks_init(pll_base); | ||||||
|  | +	else if (of_device_is_compatible(np, "qca,qca9550-pll")) | ||||||
|  | +		qca955x_clocks_init(pll_base); | ||||||
|  | +	else if (of_device_is_compatible(np, "qca,qca9560-pll")) | ||||||
|  | +		qca956x_clocks_init(pll_base); | ||||||
|  |   | ||||||
|  |  	if (of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data)) { | ||||||
|  |  		pr_err("%pOF: could not register clk provider\n", np); | ||||||
|  | @@ -714,6 +711,14 @@ err_iounmap: | ||||||
|  |  err_clk: | ||||||
|  |  	clk_put(ref_clk); | ||||||
|  |  } | ||||||
|  | -CLK_OF_DECLARE(ar9130_clk, "qca,ar9130-pll", ath79_clocks_init_dt_ng); | ||||||
|  | -CLK_OF_DECLARE(ar9330_clk, "qca,ar9330-pll", ath79_clocks_init_dt_ng); | ||||||
|  | + | ||||||
|  | +CLK_OF_DECLARE(ar7100_clk, "qca,ar7100-pll", ath79_clocks_init_dt); | ||||||
|  | +CLK_OF_DECLARE(ar7240_clk, "qca,ar7240-pll", ath79_clocks_init_dt); | ||||||
|  | +CLK_OF_DECLARE(ar9130_clk, "qca,ar9130-pll", ath79_clocks_init_dt); | ||||||
|  | +CLK_OF_DECLARE(ar9330_clk, "qca,ar9330-pll", ath79_clocks_init_dt); | ||||||
|  | +CLK_OF_DECLARE(ar9340_clk, "qca,ar9340-pll", ath79_clocks_init_dt); | ||||||
|  | +CLK_OF_DECLARE(ar9530_clk, "qca,qca9530-pll", ath79_clocks_init_dt); | ||||||
|  | +CLK_OF_DECLARE(ar9550_clk, "qca,qca9550-pll", ath79_clocks_init_dt); | ||||||
|  | +CLK_OF_DECLARE(ar9560_clk, "qca,qca9560-pll", ath79_clocks_init_dt); | ||||||
|  | + | ||||||
|  |  #endif | ||||||
| @@ -0,0 +1,59 @@ | |||||||
|  | From 78538d673801902108797f2c813e70cfbce280c9 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Tue, 6 Mar 2018 13:27:28 +0100 | ||||||
|  | Subject: [PATCH 26/33] MIPS: ath79: export switch MDIO reference clock | ||||||
|  |  | ||||||
|  | On AR934x, the MDIO reference clock can be configured to a fixed 100 MHz | ||||||
|  | clock. If that feature is not used, it defaults to the main reference | ||||||
|  | clock, like on all other SoC. | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Signed-off-by: John Crispin <john@phrozen.org> | ||||||
|  | --- | ||||||
|  |  arch/mips/ath79/clock.c               | 8 ++++++++ | ||||||
|  |  include/dt-bindings/clock/ath79-clk.h | 3 ++- | ||||||
|  |  2 files changed, 10 insertions(+), 1 deletion(-) | ||||||
|  |  | ||||||
|  | --- a/arch/mips/ath79/clock.c | ||||||
|  | +++ b/arch/mips/ath79/clock.c | ||||||
|  | @@ -42,6 +42,7 @@ static const char * const clk_names[ATH7 | ||||||
|  |  	[ATH79_CLK_DDR] = "ddr", | ||||||
|  |  	[ATH79_CLK_AHB] = "ahb", | ||||||
|  |  	[ATH79_CLK_REF] = "ref", | ||||||
|  | +	[ATH79_CLK_MDIO] = "mdio", | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  static const char * __init ath79_clk_name(int type) | ||||||
|  | @@ -342,6 +343,10 @@ static void __init ar934x_clocks_init(vo | ||||||
|  |  	ath79_set_clk(ATH79_CLK_DDR, ddr_rate); | ||||||
|  |  	ath79_set_clk(ATH79_CLK_AHB, ahb_rate); | ||||||
|  |   | ||||||
|  | +	clk_ctrl = __raw_readl(pll_base + AR934X_PLL_SWITCH_CLOCK_CONTROL_REG); | ||||||
|  | +	if (clk_ctrl & AR934X_PLL_SWITCH_CLOCK_CONTROL_MDIO_CLK_SEL) | ||||||
|  | +		ath79_set_clk(ATH79_CLK_MDIO, 100 * 1000 * 1000); | ||||||
|  | + | ||||||
|  |  	iounmap(dpll_base); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | @@ -698,6 +703,9 @@ static void __init ath79_clocks_init_dt( | ||||||
|  |  	else if (of_device_is_compatible(np, "qca,qca9560-pll")) | ||||||
|  |  		qca956x_clocks_init(pll_base); | ||||||
|  |   | ||||||
|  | +	if (!clks[ATH79_CLK_MDIO]) | ||||||
|  | +		clks[ATH79_CLK_MDIO] = 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/include/dt-bindings/clock/ath79-clk.h | ||||||
|  | +++ b/include/dt-bindings/clock/ath79-clk.h | ||||||
|  | @@ -14,7 +14,8 @@ | ||||||
|  |  #define ATH79_CLK_DDR		1 | ||||||
|  |  #define ATH79_CLK_AHB		2 | ||||||
|  |  #define ATH79_CLK_REF		3 | ||||||
|  | +#define ATH79_CLK_MDIO		4 | ||||||
|  |   | ||||||
|  | -#define ATH79_CLK_END		4 | ||||||
|  | +#define ATH79_CLK_END		5 | ||||||
|  |   | ||||||
|  |  #endif /* __DT_BINDINGS_ATH79_CLK_H */ | ||||||
| @@ -0,0 +1,233 @@ | |||||||
|  | From 3765b1f79593a0a9098ed15e48074c95403a53ee Mon Sep 17 00:00:00 2001 | ||||||
|  | From: John Crispin <john@phrozen.org> | ||||||
|  | Date: Sat, 23 Jun 2018 15:05:08 +0200 | ||||||
|  | Subject: [PATCH 27/33] MIPS: ath79: drop legacy IRQ code | ||||||
|  |  | ||||||
|  | With the target now being fully OF based, we can drop the legacy IRQ code. | ||||||
|  | All IRQs are now handled via the new irqchip drivers. | ||||||
|  |  | ||||||
|  | Signed-off-by: John Crispin <john@phrozen.org> | ||||||
|  | --- | ||||||
|  |  arch/mips/ath79/Makefile                 |   2 +- | ||||||
|  |  arch/mips/ath79/irq.c                    | 169 ------------------------------- | ||||||
|  |  arch/mips/ath79/setup.c                  |   6 ++ | ||||||
|  |  arch/mips/include/asm/mach-ath79/ath79.h |   4 - | ||||||
|  |  4 files changed, 7 insertions(+), 174 deletions(-) | ||||||
|  |  delete mode 100644 arch/mips/ath79/irq.c | ||||||
|  |  | ||||||
|  | --- a/arch/mips/ath79/Makefile | ||||||
|  | +++ b/arch/mips/ath79/Makefile | ||||||
|  | @@ -8,7 +8,7 @@ | ||||||
|  |  # under the terms of the GNU General Public License version 2 as published | ||||||
|  |  # by the Free Software Foundation. | ||||||
|  |   | ||||||
|  | -obj-y	:= prom.o setup.o irq.o common.o clock.o | ||||||
|  | +obj-y	:= prom.o setup.o common.o clock.o | ||||||
|  |   | ||||||
|  |  obj-$(CONFIG_EARLY_PRINTK)		+= early_printk.o | ||||||
|  |  obj-$(CONFIG_PCI)			+= pci.o | ||||||
|  | --- a/arch/mips/ath79/irq.c | ||||||
|  | +++ /dev/null | ||||||
|  | @@ -1,169 +0,0 @@ | ||||||
|  | -/* | ||||||
|  | - *  Atheros AR71xx/AR724x/AR913x specific interrupt handling | ||||||
|  | - * | ||||||
|  | - *  Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com> | ||||||
|  | - *  Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | ||||||
|  | - *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||||||
|  | - * | ||||||
|  | - *  Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP | ||||||
|  | - * | ||||||
|  | - *  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/kernel.h> | ||||||
|  | -#include <linux/init.h> | ||||||
|  | -#include <linux/interrupt.h> | ||||||
|  | -#include <linux/irqchip.h> | ||||||
|  | -#include <linux/of_irq.h> | ||||||
|  | - | ||||||
|  | -#include <asm/irq_cpu.h> | ||||||
|  | -#include <asm/mipsregs.h> | ||||||
|  | - | ||||||
|  | -#include <asm/mach-ath79/ath79.h> | ||||||
|  | -#include <asm/mach-ath79/ar71xx_regs.h> | ||||||
|  | -#include "common.h" | ||||||
|  | -#include "machtypes.h" | ||||||
|  | - | ||||||
|  | - | ||||||
|  | -static void ar934x_ip2_irq_dispatch(struct irq_desc *desc) | ||||||
|  | -{ | ||||||
|  | -	u32 status; | ||||||
|  | - | ||||||
|  | -	status = ath79_reset_rr(AR934X_RESET_REG_PCIE_WMAC_INT_STATUS); | ||||||
|  | - | ||||||
|  | -	if (status & AR934X_PCIE_WMAC_INT_PCIE_ALL) { | ||||||
|  | -		ath79_ddr_wb_flush(3); | ||||||
|  | -		generic_handle_irq(ATH79_IP2_IRQ(0)); | ||||||
|  | -	} else if (status & AR934X_PCIE_WMAC_INT_WMAC_ALL) { | ||||||
|  | -		ath79_ddr_wb_flush(4); | ||||||
|  | -		generic_handle_irq(ATH79_IP2_IRQ(1)); | ||||||
|  | -	} else { | ||||||
|  | -		spurious_interrupt(); | ||||||
|  | -	} | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -static void ar934x_ip2_irq_init(void) | ||||||
|  | -{ | ||||||
|  | -	int i; | ||||||
|  | - | ||||||
|  | -	for (i = ATH79_IP2_IRQ_BASE; | ||||||
|  | -	     i < ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT; i++) | ||||||
|  | -		irq_set_chip_and_handler(i, &dummy_irq_chip, | ||||||
|  | -					 handle_level_irq); | ||||||
|  | - | ||||||
|  | -	irq_set_chained_handler(ATH79_CPU_IRQ(2), ar934x_ip2_irq_dispatch); | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -static void qca955x_ip2_irq_dispatch(struct irq_desc *desc) | ||||||
|  | -{ | ||||||
|  | -	u32 status; | ||||||
|  | - | ||||||
|  | -	status = ath79_reset_rr(QCA955X_RESET_REG_EXT_INT_STATUS); | ||||||
|  | -	status &= QCA955X_EXT_INT_PCIE_RC1_ALL | QCA955X_EXT_INT_WMAC_ALL; | ||||||
|  | - | ||||||
|  | -	if (status == 0) { | ||||||
|  | -		spurious_interrupt(); | ||||||
|  | -		return; | ||||||
|  | -	} | ||||||
|  | - | ||||||
|  | -	if (status & QCA955X_EXT_INT_PCIE_RC1_ALL) { | ||||||
|  | -		/* TODO: flush DDR? */ | ||||||
|  | -		generic_handle_irq(ATH79_IP2_IRQ(0)); | ||||||
|  | -	} | ||||||
|  | - | ||||||
|  | -	if (status & QCA955X_EXT_INT_WMAC_ALL) { | ||||||
|  | -		/* TODO: flush DDR? */ | ||||||
|  | -		generic_handle_irq(ATH79_IP2_IRQ(1)); | ||||||
|  | -	} | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -static void qca955x_ip3_irq_dispatch(struct irq_desc *desc) | ||||||
|  | -{ | ||||||
|  | -	u32 status; | ||||||
|  | - | ||||||
|  | -	status = ath79_reset_rr(QCA955X_RESET_REG_EXT_INT_STATUS); | ||||||
|  | -	status &= QCA955X_EXT_INT_PCIE_RC2_ALL | | ||||||
|  | -		  QCA955X_EXT_INT_USB1 | | ||||||
|  | -		  QCA955X_EXT_INT_USB2; | ||||||
|  | - | ||||||
|  | -	if (status == 0) { | ||||||
|  | -		spurious_interrupt(); | ||||||
|  | -		return; | ||||||
|  | -	} | ||||||
|  | - | ||||||
|  | -	if (status & QCA955X_EXT_INT_USB1) { | ||||||
|  | -		/* TODO: flush DDR? */ | ||||||
|  | -		generic_handle_irq(ATH79_IP3_IRQ(0)); | ||||||
|  | -	} | ||||||
|  | - | ||||||
|  | -	if (status & QCA955X_EXT_INT_USB2) { | ||||||
|  | -		/* TODO: flush DDR? */ | ||||||
|  | -		generic_handle_irq(ATH79_IP3_IRQ(1)); | ||||||
|  | -	} | ||||||
|  | - | ||||||
|  | -	if (status & QCA955X_EXT_INT_PCIE_RC2_ALL) { | ||||||
|  | -		/* TODO: flush DDR? */ | ||||||
|  | -		generic_handle_irq(ATH79_IP3_IRQ(2)); | ||||||
|  | -	} | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -static void qca955x_irq_init(void) | ||||||
|  | -{ | ||||||
|  | -	int i; | ||||||
|  | - | ||||||
|  | -	for (i = ATH79_IP2_IRQ_BASE; | ||||||
|  | -	     i < ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT; i++) | ||||||
|  | -		irq_set_chip_and_handler(i, &dummy_irq_chip, | ||||||
|  | -					 handle_level_irq); | ||||||
|  | - | ||||||
|  | -	irq_set_chained_handler(ATH79_CPU_IRQ(2), qca955x_ip2_irq_dispatch); | ||||||
|  | - | ||||||
|  | -	for (i = ATH79_IP3_IRQ_BASE; | ||||||
|  | -	     i < ATH79_IP3_IRQ_BASE + ATH79_IP3_IRQ_COUNT; i++) | ||||||
|  | -		irq_set_chip_and_handler(i, &dummy_irq_chip, | ||||||
|  | -					 handle_level_irq); | ||||||
|  | - | ||||||
|  | -	irq_set_chained_handler(ATH79_CPU_IRQ(3), qca955x_ip3_irq_dispatch); | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -void __init arch_init_irq(void) | ||||||
|  | -{ | ||||||
|  | -	unsigned irq_wb_chan2 = -1; | ||||||
|  | -	unsigned irq_wb_chan3 = -1; | ||||||
|  | -	bool misc_is_ar71xx; | ||||||
|  | - | ||||||
|  | -	if (mips_machtype == ATH79_MACH_GENERIC_OF) { | ||||||
|  | -		irqchip_init(); | ||||||
|  | -		return; | ||||||
|  | -	} | ||||||
|  | - | ||||||
|  | -	if (soc_is_ar71xx() || soc_is_ar724x() || | ||||||
|  | -	    soc_is_ar913x() || soc_is_ar933x()) { | ||||||
|  | -		irq_wb_chan2 = 3; | ||||||
|  | -		irq_wb_chan3 = 2; | ||||||
|  | -	} else if (soc_is_ar934x()) { | ||||||
|  | -		irq_wb_chan3 = 2; | ||||||
|  | -	} | ||||||
|  | - | ||||||
|  | -	ath79_cpu_irq_init(irq_wb_chan2, irq_wb_chan3); | ||||||
|  | - | ||||||
|  | -	if (soc_is_ar71xx() || soc_is_ar913x()) | ||||||
|  | -		misc_is_ar71xx = true; | ||||||
|  | -	else if (soc_is_ar724x() || | ||||||
|  | -		 soc_is_ar933x() || | ||||||
|  | -		 soc_is_ar934x() || | ||||||
|  | -		 soc_is_qca955x()) | ||||||
|  | -		misc_is_ar71xx = false; | ||||||
|  | -	else | ||||||
|  | -		BUG(); | ||||||
|  | -	ath79_misc_irq_init( | ||||||
|  | -		ath79_reset_base + AR71XX_RESET_REG_MISC_INT_STATUS, | ||||||
|  | -		ATH79_CPU_IRQ(6), ATH79_MISC_IRQ_BASE, misc_is_ar71xx); | ||||||
|  | - | ||||||
|  | -	if (soc_is_ar934x()) | ||||||
|  | -		ar934x_ip2_irq_init(); | ||||||
|  | -	else if (soc_is_qca955x()) | ||||||
|  | -		qca955x_irq_init(); | ||||||
|  | -} | ||||||
|  | --- a/arch/mips/ath79/setup.c | ||||||
|  | +++ b/arch/mips/ath79/setup.c | ||||||
|  | @@ -19,6 +19,7 @@ | ||||||
|  |  #include <linux/clk.h> | ||||||
|  |  #include <linux/clk-provider.h> | ||||||
|  |  #include <linux/of_fdt.h> | ||||||
|  | +#include <linux/irqchip.h> | ||||||
|  |   | ||||||
|  |  #include <asm/bootinfo.h> | ||||||
|  |  #include <asm/idle.h> | ||||||
|  | @@ -311,6 +312,11 @@ void __init plat_time_init(void) | ||||||
|  |  	mips_hpt_frequency = cpu_clk_rate / 2; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +void __init arch_init_irq(void) | ||||||
|  | +{ | ||||||
|  | +	irqchip_init(); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  static int __init ath79_setup(void) | ||||||
|  |  { | ||||||
|  |  	if  (mips_machtype == ATH79_MACH_GENERIC_OF) | ||||||
|  | --- a/arch/mips/include/asm/mach-ath79/ath79.h | ||||||
|  | +++ b/arch/mips/include/asm/mach-ath79/ath79.h | ||||||
|  | @@ -178,8 +178,4 @@ static inline u32 ath79_reset_rr(unsigne | ||||||
|  |  void ath79_device_reset_set(u32 mask); | ||||||
|  |  void ath79_device_reset_clear(u32 mask); | ||||||
|  |   | ||||||
|  | -void ath79_cpu_irq_init(unsigned irq_wb_chan2, unsigned irq_wb_chan3); | ||||||
|  | -void ath79_misc_irq_init(void __iomem *regs, int irq, | ||||||
|  | -			int irq_base, bool is_ar71xx); | ||||||
|  | - | ||||||
|  |  #endif /* __ASM_MACH_ATH79_H */ | ||||||
							
								
								
									
										1048
									
								
								target/linux/ath79/patches-4.19/0028-MIPS-ath79-drop-machfiles.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1048
									
								
								target/linux/ath79/patches-4.19/0028-MIPS-ath79-drop-machfiles.patch
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -0,0 +1,379 @@ | |||||||
|  | From d0f1420702ed47a82572aaf39e7407055518d14e Mon Sep 17 00:00:00 2001 | ||||||
|  | From: John Crispin <john@phrozen.org> | ||||||
|  | Date: Sat, 23 Jun 2018 15:05:19 +0200 | ||||||
|  | Subject: [PATCH 29/33] MIPS: ath79: drop legacy pci code | ||||||
|  |  | ||||||
|  | With the target now being fully OF based, we can drop the legacy pci | ||||||
|  | platform code. The only bits that we need to keep is the fixup code | ||||||
|  | which we move to its own code file. | ||||||
|  |  | ||||||
|  | Signed-off-by: John Crispin <john@phrozen.org> | ||||||
|  | --- | ||||||
|  |  arch/mips/ath79/Makefile    |   1 - | ||||||
|  |  arch/mips/ath79/pci.c       | 273 -------------------------------------------- | ||||||
|  |  arch/mips/ath79/pci.h       |  35 ------ | ||||||
|  |  arch/mips/pci/Makefile      |   1 + | ||||||
|  |  arch/mips/pci/fixup-ath79.c |  21 ++++ | ||||||
|  |  5 files changed, 22 insertions(+), 309 deletions(-) | ||||||
|  |  delete mode 100644 arch/mips/ath79/pci.c | ||||||
|  |  delete mode 100644 arch/mips/ath79/pci.h | ||||||
|  |  create mode 100644 arch/mips/pci/fixup-ath79.c | ||||||
|  |  | ||||||
|  | --- a/arch/mips/ath79/Makefile | ||||||
|  | +++ b/arch/mips/ath79/Makefile | ||||||
|  | @@ -11,7 +11,6 @@ | ||||||
|  |  obj-y	:= prom.o setup.o common.o clock.o | ||||||
|  |   | ||||||
|  |  obj-$(CONFIG_EARLY_PRINTK)		+= early_printk.o | ||||||
|  | -obj-$(CONFIG_PCI)			+= pci.o | ||||||
|  |   | ||||||
|  |  # | ||||||
|  |  # Devices | ||||||
|  | --- a/arch/mips/ath79/pci.c | ||||||
|  | +++ /dev/null | ||||||
|  | @@ -1,273 +0,0 @@ | ||||||
|  | -/* | ||||||
|  | - *  Atheros AR71XX/AR724X specific PCI setup code | ||||||
|  | - * | ||||||
|  | - *  Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com> | ||||||
|  | - *  Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | ||||||
|  | - *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||||||
|  | - * | ||||||
|  | - *  Parts of this file are based on Atheros' 2.6.15 BSP | ||||||
|  | - * | ||||||
|  | - *  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/init.h> | ||||||
|  | -#include <linux/pci.h> | ||||||
|  | -#include <linux/resource.h> | ||||||
|  | -#include <linux/platform_device.h> | ||||||
|  | -#include <asm/mach-ath79/ar71xx_regs.h> | ||||||
|  | -#include <asm/mach-ath79/ath79.h> | ||||||
|  | -#include <asm/mach-ath79/irq.h> | ||||||
|  | -#include "pci.h" | ||||||
|  | - | ||||||
|  | -static int (*ath79_pci_plat_dev_init)(struct pci_dev *dev); | ||||||
|  | -static const struct ath79_pci_irq *ath79_pci_irq_map; | ||||||
|  | -static unsigned ath79_pci_nr_irqs; | ||||||
|  | - | ||||||
|  | -static const struct ath79_pci_irq ar71xx_pci_irq_map[] = { | ||||||
|  | -	{ | ||||||
|  | -		.slot	= 17, | ||||||
|  | -		.pin	= 1, | ||||||
|  | -		.irq	= ATH79_PCI_IRQ(0), | ||||||
|  | -	}, { | ||||||
|  | -		.slot	= 18, | ||||||
|  | -		.pin	= 1, | ||||||
|  | -		.irq	= ATH79_PCI_IRQ(1), | ||||||
|  | -	}, { | ||||||
|  | -		.slot	= 19, | ||||||
|  | -		.pin	= 1, | ||||||
|  | -		.irq	= ATH79_PCI_IRQ(2), | ||||||
|  | -	} | ||||||
|  | -}; | ||||||
|  | - | ||||||
|  | -static const struct ath79_pci_irq ar724x_pci_irq_map[] = { | ||||||
|  | -	{ | ||||||
|  | -		.slot	= 0, | ||||||
|  | -		.pin	= 1, | ||||||
|  | -		.irq	= ATH79_PCI_IRQ(0), | ||||||
|  | -	} | ||||||
|  | -}; | ||||||
|  | - | ||||||
|  | -static const struct ath79_pci_irq qca955x_pci_irq_map[] = { | ||||||
|  | -	{ | ||||||
|  | -		.bus	= 0, | ||||||
|  | -		.slot	= 0, | ||||||
|  | -		.pin	= 1, | ||||||
|  | -		.irq	= ATH79_PCI_IRQ(0), | ||||||
|  | -	}, | ||||||
|  | -	{ | ||||||
|  | -		.bus	= 1, | ||||||
|  | -		.slot	= 0, | ||||||
|  | -		.pin	= 1, | ||||||
|  | -		.irq	= ATH79_PCI_IRQ(1), | ||||||
|  | -	}, | ||||||
|  | -}; | ||||||
|  | - | ||||||
|  | -int pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin) | ||||||
|  | -{ | ||||||
|  | -	int irq = -1; | ||||||
|  | -	int i; | ||||||
|  | - | ||||||
|  | -	if (ath79_pci_nr_irqs == 0 || | ||||||
|  | -	    ath79_pci_irq_map == NULL) { | ||||||
|  | -		if (soc_is_ar71xx()) { | ||||||
|  | -			ath79_pci_irq_map = ar71xx_pci_irq_map; | ||||||
|  | -			ath79_pci_nr_irqs = ARRAY_SIZE(ar71xx_pci_irq_map); | ||||||
|  | -		} else if (soc_is_ar724x() || | ||||||
|  | -			   soc_is_ar9342() || | ||||||
|  | -			   soc_is_ar9344()) { | ||||||
|  | -			ath79_pci_irq_map = ar724x_pci_irq_map; | ||||||
|  | -			ath79_pci_nr_irqs = ARRAY_SIZE(ar724x_pci_irq_map); | ||||||
|  | -		} else if (soc_is_qca955x()) { | ||||||
|  | -			ath79_pci_irq_map = qca955x_pci_irq_map; | ||||||
|  | -			ath79_pci_nr_irqs = ARRAY_SIZE(qca955x_pci_irq_map); | ||||||
|  | -		} else { | ||||||
|  | -			pr_crit("pci %s: invalid irq map\n", | ||||||
|  | -				pci_name((struct pci_dev *) dev)); | ||||||
|  | -			return irq; | ||||||
|  | -		} | ||||||
|  | -	} | ||||||
|  | - | ||||||
|  | -	for (i = 0; i < ath79_pci_nr_irqs; i++) { | ||||||
|  | -		const struct ath79_pci_irq *entry; | ||||||
|  | - | ||||||
|  | -		entry = &ath79_pci_irq_map[i]; | ||||||
|  | -		if (entry->bus == dev->bus->number && | ||||||
|  | -		    entry->slot == slot && | ||||||
|  | -		    entry->pin == pin) { | ||||||
|  | -			irq = entry->irq; | ||||||
|  | -			break; | ||||||
|  | -		} | ||||||
|  | -	} | ||||||
|  | - | ||||||
|  | -	if (irq < 0) | ||||||
|  | -		pr_crit("pci %s: no irq found for pin %u\n", | ||||||
|  | -			pci_name((struct pci_dev *) dev), pin); | ||||||
|  | -	else | ||||||
|  | -		pr_info("pci %s: using irq %d for pin %u\n", | ||||||
|  | -			pci_name((struct pci_dev *) dev), irq, pin); | ||||||
|  | - | ||||||
|  | -	return irq; | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -int pcibios_plat_dev_init(struct pci_dev *dev) | ||||||
|  | -{ | ||||||
|  | -	if (ath79_pci_plat_dev_init) | ||||||
|  | -		return ath79_pci_plat_dev_init(dev); | ||||||
|  | - | ||||||
|  | -	return 0; | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -void __init ath79_pci_set_irq_map(unsigned nr_irqs, | ||||||
|  | -				  const struct ath79_pci_irq *map) | ||||||
|  | -{ | ||||||
|  | -	ath79_pci_nr_irqs = nr_irqs; | ||||||
|  | -	ath79_pci_irq_map = map; | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -void __init ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *dev)) | ||||||
|  | -{ | ||||||
|  | -	ath79_pci_plat_dev_init = func; | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -static struct platform_device * | ||||||
|  | -ath79_register_pci_ar71xx(void) | ||||||
|  | -{ | ||||||
|  | -	struct platform_device *pdev; | ||||||
|  | -	struct resource res[4]; | ||||||
|  | - | ||||||
|  | -	memset(res, 0, sizeof(res)); | ||||||
|  | - | ||||||
|  | -	res[0].name = "cfg_base"; | ||||||
|  | -	res[0].flags = IORESOURCE_MEM; | ||||||
|  | -	res[0].start = AR71XX_PCI_CFG_BASE; | ||||||
|  | -	res[0].end = AR71XX_PCI_CFG_BASE + AR71XX_PCI_CFG_SIZE - 1; | ||||||
|  | - | ||||||
|  | -	res[1].flags = IORESOURCE_IRQ; | ||||||
|  | -	res[1].start = ATH79_CPU_IRQ(2); | ||||||
|  | -	res[1].end = ATH79_CPU_IRQ(2); | ||||||
|  | - | ||||||
|  | -	res[2].name = "io_base"; | ||||||
|  | -	res[2].flags = IORESOURCE_IO; | ||||||
|  | -	res[2].start = 0; | ||||||
|  | -	res[2].end = 0; | ||||||
|  | - | ||||||
|  | -	res[3].name = "mem_base"; | ||||||
|  | -	res[3].flags = IORESOURCE_MEM; | ||||||
|  | -	res[3].start = AR71XX_PCI_MEM_BASE; | ||||||
|  | -	res[3].end = AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1; | ||||||
|  | - | ||||||
|  | -	pdev = platform_device_register_simple("ar71xx-pci", -1, | ||||||
|  | -					       res, ARRAY_SIZE(res)); | ||||||
|  | -	return pdev; | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -static struct platform_device * | ||||||
|  | -ath79_register_pci_ar724x(int id, | ||||||
|  | -			  unsigned long cfg_base, | ||||||
|  | -			  unsigned long ctrl_base, | ||||||
|  | -			  unsigned long crp_base, | ||||||
|  | -			  unsigned long mem_base, | ||||||
|  | -			  unsigned long mem_size, | ||||||
|  | -			  unsigned long io_base, | ||||||
|  | -			  int irq) | ||||||
|  | -{ | ||||||
|  | -	struct platform_device *pdev; | ||||||
|  | -	struct resource res[6]; | ||||||
|  | - | ||||||
|  | -	memset(res, 0, sizeof(res)); | ||||||
|  | - | ||||||
|  | -	res[0].name = "cfg_base"; | ||||||
|  | -	res[0].flags = IORESOURCE_MEM; | ||||||
|  | -	res[0].start = cfg_base; | ||||||
|  | -	res[0].end = cfg_base + AR724X_PCI_CFG_SIZE - 1; | ||||||
|  | - | ||||||
|  | -	res[1].name = "ctrl_base"; | ||||||
|  | -	res[1].flags = IORESOURCE_MEM; | ||||||
|  | -	res[1].start = ctrl_base; | ||||||
|  | -	res[1].end = ctrl_base + AR724X_PCI_CTRL_SIZE - 1; | ||||||
|  | - | ||||||
|  | -	res[2].flags = IORESOURCE_IRQ; | ||||||
|  | -	res[2].start = irq; | ||||||
|  | -	res[2].end = irq; | ||||||
|  | - | ||||||
|  | -	res[3].name = "mem_base"; | ||||||
|  | -	res[3].flags = IORESOURCE_MEM; | ||||||
|  | -	res[3].start = mem_base; | ||||||
|  | -	res[3].end = mem_base + mem_size - 1; | ||||||
|  | - | ||||||
|  | -	res[4].name = "io_base"; | ||||||
|  | -	res[4].flags = IORESOURCE_IO; | ||||||
|  | -	res[4].start = io_base; | ||||||
|  | -	res[4].end = io_base; | ||||||
|  | - | ||||||
|  | -	res[5].name = "crp_base"; | ||||||
|  | -	res[5].flags = IORESOURCE_MEM; | ||||||
|  | -	res[5].start = crp_base; | ||||||
|  | -	res[5].end = crp_base + AR724X_PCI_CRP_SIZE - 1; | ||||||
|  | - | ||||||
|  | -	pdev = platform_device_register_simple("ar724x-pci", id, | ||||||
|  | -					       res, ARRAY_SIZE(res)); | ||||||
|  | -	return pdev; | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -int __init ath79_register_pci(void) | ||||||
|  | -{ | ||||||
|  | -	struct platform_device *pdev = NULL; | ||||||
|  | - | ||||||
|  | -	if (soc_is_ar71xx()) { | ||||||
|  | -		pdev = ath79_register_pci_ar71xx(); | ||||||
|  | -	} else if (soc_is_ar724x()) { | ||||||
|  | -		pdev = ath79_register_pci_ar724x(-1, | ||||||
|  | -						 AR724X_PCI_CFG_BASE, | ||||||
|  | -						 AR724X_PCI_CTRL_BASE, | ||||||
|  | -						 AR724X_PCI_CRP_BASE, | ||||||
|  | -						 AR724X_PCI_MEM_BASE, | ||||||
|  | -						 AR724X_PCI_MEM_SIZE, | ||||||
|  | -						 0, | ||||||
|  | -						 ATH79_CPU_IRQ(2)); | ||||||
|  | -	} else if (soc_is_ar9342() || | ||||||
|  | -		   soc_is_ar9344()) { | ||||||
|  | -		u32 bootstrap; | ||||||
|  | - | ||||||
|  | -		bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP); | ||||||
|  | -		if ((bootstrap & AR934X_BOOTSTRAP_PCIE_RC) == 0) | ||||||
|  | -			return -ENODEV; | ||||||
|  | - | ||||||
|  | -		pdev = ath79_register_pci_ar724x(-1, | ||||||
|  | -						 AR724X_PCI_CFG_BASE, | ||||||
|  | -						 AR724X_PCI_CTRL_BASE, | ||||||
|  | -						 AR724X_PCI_CRP_BASE, | ||||||
|  | -						 AR724X_PCI_MEM_BASE, | ||||||
|  | -						 AR724X_PCI_MEM_SIZE, | ||||||
|  | -						 0, | ||||||
|  | -						 ATH79_IP2_IRQ(0)); | ||||||
|  | -	} else if (soc_is_qca9558()) { | ||||||
|  | -		pdev = ath79_register_pci_ar724x(0, | ||||||
|  | -						 QCA955X_PCI_CFG_BASE0, | ||||||
|  | -						 QCA955X_PCI_CTRL_BASE0, | ||||||
|  | -						 QCA955X_PCI_CRP_BASE0, | ||||||
|  | -						 QCA955X_PCI_MEM_BASE0, | ||||||
|  | -						 QCA955X_PCI_MEM_SIZE, | ||||||
|  | -						 0, | ||||||
|  | -						 ATH79_IP2_IRQ(0)); | ||||||
|  | - | ||||||
|  | -		pdev = ath79_register_pci_ar724x(1, | ||||||
|  | -						 QCA955X_PCI_CFG_BASE1, | ||||||
|  | -						 QCA955X_PCI_CTRL_BASE1, | ||||||
|  | -						 QCA955X_PCI_CRP_BASE1, | ||||||
|  | -						 QCA955X_PCI_MEM_BASE1, | ||||||
|  | -						 QCA955X_PCI_MEM_SIZE, | ||||||
|  | -						 1, | ||||||
|  | -						 ATH79_IP3_IRQ(2)); | ||||||
|  | -	} else { | ||||||
|  | -		/* No PCI support */ | ||||||
|  | -		return -ENODEV; | ||||||
|  | -	} | ||||||
|  | - | ||||||
|  | -	if (!pdev) | ||||||
|  | -		pr_err("unable to register PCI controller device\n"); | ||||||
|  | - | ||||||
|  | -	return pdev ? 0 : -ENODEV; | ||||||
|  | -} | ||||||
|  | --- a/arch/mips/ath79/pci.h | ||||||
|  | +++ /dev/null | ||||||
|  | @@ -1,35 +0,0 @@ | ||||||
|  | -/* | ||||||
|  | - *  Atheros AR71XX/AR724X PCI support | ||||||
|  | - * | ||||||
|  | - *  Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com> | ||||||
|  | - *  Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | ||||||
|  | - *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.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. | ||||||
|  | - */ | ||||||
|  | - | ||||||
|  | -#ifndef _ATH79_PCI_H | ||||||
|  | -#define _ATH79_PCI_H | ||||||
|  | - | ||||||
|  | -struct ath79_pci_irq { | ||||||
|  | -	int	bus; | ||||||
|  | -	u8	slot; | ||||||
|  | -	u8	pin; | ||||||
|  | -	int	irq; | ||||||
|  | -}; | ||||||
|  | - | ||||||
|  | -#ifdef CONFIG_PCI | ||||||
|  | -void ath79_pci_set_irq_map(unsigned nr_irqs, const struct ath79_pci_irq *map); | ||||||
|  | -void ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *dev)); | ||||||
|  | -int ath79_register_pci(void); | ||||||
|  | -#else | ||||||
|  | -static inline void | ||||||
|  | -ath79_pci_set_irq_map(unsigned nr_irqs, const struct ath79_pci_irq *map) {} | ||||||
|  | -static inline void | ||||||
|  | -ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *)) {} | ||||||
|  | -static inline int ath79_register_pci(void) { return 0; } | ||||||
|  | -#endif | ||||||
|  | - | ||||||
|  | -#endif /* _ATH79_PCI_H */ | ||||||
|  | --- a/arch/mips/pci/Makefile | ||||||
|  | +++ b/arch/mips/pci/Makefile | ||||||
|  | @@ -29,6 +29,7 @@ obj-$(CONFIG_MIPS_PCI_VIRTIO)	+= pci-vir | ||||||
|  |  # | ||||||
|  |  # These are still pretty much in the old state, watch, go blind. | ||||||
|  |  # | ||||||
|  | +obj-$(CONFIG_ATH79)		+= fixup-ath79.o | ||||||
|  |  obj-$(CONFIG_LASAT)		+= pci-lasat.o | ||||||
|  |  obj-$(CONFIG_MIPS_COBALT)	+= fixup-cobalt.o | ||||||
|  |  obj-$(CONFIG_LEMOTE_FULOONG2E)	+= fixup-fuloong2e.o ops-loongson2.o | ||||||
|  | --- /dev/null | ||||||
|  | +++ b/arch/mips/pci/fixup-ath79.c | ||||||
|  | @@ -0,0 +1,21 @@ | ||||||
|  | +/* | ||||||
|  | + *  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/pci.h> | ||||||
|  | +//#include <linux/of_irq.h> | ||||||
|  | +#include <linux/of_pci.h> | ||||||
|  | + | ||||||
|  | +int pcibios_plat_dev_init(struct pci_dev *dev) | ||||||
|  | +{ | ||||||
|  | +	return PCIBIOS_SUCCESSFUL; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | ||||||
|  | +{ | ||||||
|  | +	return of_irq_parse_and_map_pci(dev, slot, pin); | ||||||
|  | +} | ||||||
| @@ -0,0 +1,933 @@ | |||||||
|  | From dce930fba8ad3a90ccd164f199e57c2d61937ccd Mon Sep 17 00:00:00 2001 | ||||||
|  | From: John Crispin <john@phrozen.org> | ||||||
|  | Date: Sat, 23 Jun 2018 15:12:38 +0200 | ||||||
|  | Subject: [PATCH 30/33] MIPS: ath79: drop platform device registration code | ||||||
|  |  | ||||||
|  | With the target now being fully OF based, we can drop the legacy platform | ||||||
|  | device registration code. All devices and their drivers are now probed | ||||||
|  | via OF. | ||||||
|  |  | ||||||
|  | Signed-off-by: John Crispin <john@phrozen.org> | ||||||
|  | --- | ||||||
|  |  arch/mips/ath79/Makefile           |  10 -- | ||||||
|  |  arch/mips/ath79/common.h           |   2 - | ||||||
|  |  arch/mips/ath79/dev-common.c       | 159 ------------------------ | ||||||
|  |  arch/mips/ath79/dev-common.h       |  18 --- | ||||||
|  |  arch/mips/ath79/dev-gpio-buttons.c |  56 --------- | ||||||
|  |  arch/mips/ath79/dev-gpio-buttons.h |  23 ---- | ||||||
|  |  arch/mips/ath79/dev-leds-gpio.c    |  54 --------- | ||||||
|  |  arch/mips/ath79/dev-leds-gpio.h    |  21 ---- | ||||||
|  |  arch/mips/ath79/dev-spi.c          |  38 ------ | ||||||
|  |  arch/mips/ath79/dev-spi.h          |  22 ---- | ||||||
|  |  arch/mips/ath79/dev-usb.c          | 242 ------------------------------------- | ||||||
|  |  arch/mips/ath79/dev-usb.h          |  17 --- | ||||||
|  |  arch/mips/ath79/dev-wmac.c         | 155 ------------------------ | ||||||
|  |  arch/mips/ath79/dev-wmac.h         |  17 --- | ||||||
|  |  arch/mips/ath79/setup.c            |   1 - | ||||||
|  |  15 files changed, 835 deletions(-) | ||||||
|  |  delete mode 100644 arch/mips/ath79/dev-common.c | ||||||
|  |  delete mode 100644 arch/mips/ath79/dev-common.h | ||||||
|  |  delete mode 100644 arch/mips/ath79/dev-gpio-buttons.c | ||||||
|  |  delete mode 100644 arch/mips/ath79/dev-gpio-buttons.h | ||||||
|  |  delete mode 100644 arch/mips/ath79/dev-leds-gpio.c | ||||||
|  |  delete mode 100644 arch/mips/ath79/dev-leds-gpio.h | ||||||
|  |  delete mode 100644 arch/mips/ath79/dev-spi.c | ||||||
|  |  delete mode 100644 arch/mips/ath79/dev-spi.h | ||||||
|  |  delete mode 100644 arch/mips/ath79/dev-usb.c | ||||||
|  |  delete mode 100644 arch/mips/ath79/dev-usb.h | ||||||
|  |  delete mode 100644 arch/mips/ath79/dev-wmac.c | ||||||
|  |  delete mode 100644 arch/mips/ath79/dev-wmac.h | ||||||
|  |  | ||||||
|  | --- a/arch/mips/ath79/Makefile | ||||||
|  | +++ b/arch/mips/ath79/Makefile | ||||||
|  | @@ -11,13 +11,3 @@ | ||||||
|  |  obj-y	:= prom.o setup.o common.o clock.o | ||||||
|  |   | ||||||
|  |  obj-$(CONFIG_EARLY_PRINTK)		+= early_printk.o | ||||||
|  | - | ||||||
|  | -# | ||||||
|  | -# Devices | ||||||
|  | -# | ||||||
|  | -obj-y					+= dev-common.o | ||||||
|  | -obj-$(CONFIG_ATH79_DEV_GPIO_BUTTONS)	+= dev-gpio-buttons.o | ||||||
|  | -obj-$(CONFIG_ATH79_DEV_LEDS_GPIO)	+= dev-leds-gpio.o | ||||||
|  | -obj-$(CONFIG_ATH79_DEV_SPI)		+= dev-spi.o | ||||||
|  | -obj-$(CONFIG_ATH79_DEV_USB)		+= dev-usb.o | ||||||
|  | -obj-$(CONFIG_ATH79_DEV_WMAC)		+= dev-wmac.o | ||||||
|  | --- a/arch/mips/ath79/common.h | ||||||
|  | +++ b/arch/mips/ath79/common.h | ||||||
|  | @@ -24,6 +24,4 @@ unsigned long ath79_get_sys_clk_rate(con | ||||||
|  |   | ||||||
|  |  void ath79_ddr_ctrl_init(void); | ||||||
|  |   | ||||||
|  | -void ath79_gpio_init(void); | ||||||
|  | - | ||||||
|  |  #endif /* __ATH79_COMMON_H */ | ||||||
|  | --- a/arch/mips/ath79/dev-common.c | ||||||
|  | +++ /dev/null | ||||||
|  | @@ -1,159 +0,0 @@ | ||||||
|  | -/* | ||||||
|  | - *  Atheros AR71XX/AR724X/AR913X common devices | ||||||
|  | - * | ||||||
|  | - *  Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | ||||||
|  | - *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||||||
|  | - * | ||||||
|  | - *  Parts of this file are based on Atheros' 2.6.15 BSP | ||||||
|  | - * | ||||||
|  | - *  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/kernel.h> | ||||||
|  | -#include <linux/init.h> | ||||||
|  | -#include <linux/platform_device.h> | ||||||
|  | -#include <linux/platform_data/gpio-ath79.h> | ||||||
|  | -#include <linux/serial_8250.h> | ||||||
|  | -#include <linux/clk.h> | ||||||
|  | -#include <linux/err.h> | ||||||
|  | - | ||||||
|  | -#include <asm/mach-ath79/ath79.h> | ||||||
|  | -#include <asm/mach-ath79/ar71xx_regs.h> | ||||||
|  | -#include "common.h" | ||||||
|  | -#include "dev-common.h" | ||||||
|  | - | ||||||
|  | -static struct resource ath79_uart_resources[] = { | ||||||
|  | -	{ | ||||||
|  | -		.start	= AR71XX_UART_BASE, | ||||||
|  | -		.end	= AR71XX_UART_BASE + AR71XX_UART_SIZE - 1, | ||||||
|  | -		.flags	= IORESOURCE_MEM, | ||||||
|  | -	}, | ||||||
|  | -}; | ||||||
|  | - | ||||||
|  | -#define AR71XX_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP) | ||||||
|  | -static struct plat_serial8250_port ath79_uart_data[] = { | ||||||
|  | -	{ | ||||||
|  | -		.mapbase	= AR71XX_UART_BASE, | ||||||
|  | -		.irq		= ATH79_MISC_IRQ(3), | ||||||
|  | -		.flags		= AR71XX_UART_FLAGS, | ||||||
|  | -		.iotype		= UPIO_MEM32, | ||||||
|  | -		.regshift	= 2, | ||||||
|  | -	}, { | ||||||
|  | -		/* terminating entry */ | ||||||
|  | -	} | ||||||
|  | -}; | ||||||
|  | - | ||||||
|  | -static struct platform_device ath79_uart_device = { | ||||||
|  | -	.name		= "serial8250", | ||||||
|  | -	.id		= PLAT8250_DEV_PLATFORM, | ||||||
|  | -	.resource	= ath79_uart_resources, | ||||||
|  | -	.num_resources	= ARRAY_SIZE(ath79_uart_resources), | ||||||
|  | -	.dev = { | ||||||
|  | -		.platform_data	= ath79_uart_data | ||||||
|  | -	}, | ||||||
|  | -}; | ||||||
|  | - | ||||||
|  | -static struct resource ar933x_uart_resources[] = { | ||||||
|  | -	{ | ||||||
|  | -		.start	= AR933X_UART_BASE, | ||||||
|  | -		.end	= AR933X_UART_BASE + AR71XX_UART_SIZE - 1, | ||||||
|  | -		.flags	= IORESOURCE_MEM, | ||||||
|  | -	}, | ||||||
|  | -	{ | ||||||
|  | -		.start	= ATH79_MISC_IRQ(3), | ||||||
|  | -		.end	= ATH79_MISC_IRQ(3), | ||||||
|  | -		.flags	= IORESOURCE_IRQ, | ||||||
|  | -	}, | ||||||
|  | -}; | ||||||
|  | - | ||||||
|  | -static struct platform_device ar933x_uart_device = { | ||||||
|  | -	.name		= "ar933x-uart", | ||||||
|  | -	.id		= -1, | ||||||
|  | -	.resource	= ar933x_uart_resources, | ||||||
|  | -	.num_resources	= ARRAY_SIZE(ar933x_uart_resources), | ||||||
|  | -}; | ||||||
|  | - | ||||||
|  | -void __init ath79_register_uart(void) | ||||||
|  | -{ | ||||||
|  | -	unsigned long uart_clk_rate; | ||||||
|  | - | ||||||
|  | -	uart_clk_rate = ath79_get_sys_clk_rate("uart"); | ||||||
|  | - | ||||||
|  | -	if (soc_is_ar71xx() || | ||||||
|  | -	    soc_is_ar724x() || | ||||||
|  | -	    soc_is_ar913x() || | ||||||
|  | -	    soc_is_ar934x() || | ||||||
|  | -	    soc_is_qca955x()) { | ||||||
|  | -		ath79_uart_data[0].uartclk = uart_clk_rate; | ||||||
|  | -		platform_device_register(&ath79_uart_device); | ||||||
|  | -	} else if (soc_is_ar933x()) { | ||||||
|  | -		platform_device_register(&ar933x_uart_device); | ||||||
|  | -	} else { | ||||||
|  | -		BUG(); | ||||||
|  | -	} | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -void __init ath79_register_wdt(void) | ||||||
|  | -{ | ||||||
|  | -	struct resource res; | ||||||
|  | - | ||||||
|  | -	memset(&res, 0, sizeof(res)); | ||||||
|  | - | ||||||
|  | -	res.flags = IORESOURCE_MEM; | ||||||
|  | -	res.start = AR71XX_RESET_BASE + AR71XX_RESET_REG_WDOG_CTRL; | ||||||
|  | -	res.end = res.start + 0x8 - 1; | ||||||
|  | - | ||||||
|  | -	platform_device_register_simple("ath79-wdt", -1, &res, 1); | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -static struct ath79_gpio_platform_data ath79_gpio_pdata; | ||||||
|  | - | ||||||
|  | -static struct resource ath79_gpio_resources[] = { | ||||||
|  | -	{ | ||||||
|  | -		.flags = IORESOURCE_MEM, | ||||||
|  | -		.start = AR71XX_GPIO_BASE, | ||||||
|  | -		.end = AR71XX_GPIO_BASE + AR71XX_GPIO_SIZE - 1, | ||||||
|  | -	}, | ||||||
|  | -	{ | ||||||
|  | -		.start	= ATH79_MISC_IRQ(2), | ||||||
|  | -		.end	= ATH79_MISC_IRQ(2), | ||||||
|  | -		.flags	= IORESOURCE_IRQ, | ||||||
|  | -	}, | ||||||
|  | -}; | ||||||
|  | - | ||||||
|  | -static struct platform_device ath79_gpio_device = { | ||||||
|  | -	.name		= "ath79-gpio", | ||||||
|  | -	.id		= -1, | ||||||
|  | -	.resource	= ath79_gpio_resources, | ||||||
|  | -	.num_resources	= ARRAY_SIZE(ath79_gpio_resources), | ||||||
|  | -	.dev = { | ||||||
|  | -		.platform_data	= &ath79_gpio_pdata | ||||||
|  | -	}, | ||||||
|  | -}; | ||||||
|  | - | ||||||
|  | -void __init ath79_gpio_init(void) | ||||||
|  | -{ | ||||||
|  | -	if (soc_is_ar71xx()) { | ||||||
|  | -		ath79_gpio_pdata.ngpios = AR71XX_GPIO_COUNT; | ||||||
|  | -	} else if (soc_is_ar7240()) { | ||||||
|  | -		ath79_gpio_pdata.ngpios = AR7240_GPIO_COUNT; | ||||||
|  | -	} else if (soc_is_ar7241() || soc_is_ar7242()) { | ||||||
|  | -		ath79_gpio_pdata.ngpios = AR7241_GPIO_COUNT; | ||||||
|  | -	} else if (soc_is_ar913x()) { | ||||||
|  | -		ath79_gpio_pdata.ngpios = AR913X_GPIO_COUNT; | ||||||
|  | -	} else if (soc_is_ar933x()) { | ||||||
|  | -		ath79_gpio_pdata.ngpios = AR933X_GPIO_COUNT; | ||||||
|  | -	} else if (soc_is_ar934x()) { | ||||||
|  | -		ath79_gpio_pdata.ngpios = AR934X_GPIO_COUNT; | ||||||
|  | -		ath79_gpio_pdata.oe_inverted = 1; | ||||||
|  | -	} else if (soc_is_qca955x()) { | ||||||
|  | -		ath79_gpio_pdata.ngpios = QCA955X_GPIO_COUNT; | ||||||
|  | -		ath79_gpio_pdata.oe_inverted = 1; | ||||||
|  | -	} else { | ||||||
|  | -		BUG(); | ||||||
|  | -	} | ||||||
|  | - | ||||||
|  | -	platform_device_register(&ath79_gpio_device); | ||||||
|  | -} | ||||||
|  | --- a/arch/mips/ath79/dev-common.h | ||||||
|  | +++ /dev/null | ||||||
|  | @@ -1,18 +0,0 @@ | ||||||
|  | -/* | ||||||
|  | - *  Atheros AR71XX/AR724X/AR913X common devices | ||||||
|  | - * | ||||||
|  | - *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | ||||||
|  | - *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.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. | ||||||
|  | - */ | ||||||
|  | - | ||||||
|  | -#ifndef _ATH79_DEV_COMMON_H | ||||||
|  | -#define _ATH79_DEV_COMMON_H | ||||||
|  | - | ||||||
|  | -void ath79_register_uart(void); | ||||||
|  | -void ath79_register_wdt(void); | ||||||
|  | - | ||||||
|  | -#endif /* _ATH79_DEV_COMMON_H */ | ||||||
|  | --- a/arch/mips/ath79/dev-gpio-buttons.c | ||||||
|  | +++ /dev/null | ||||||
|  | @@ -1,56 +0,0 @@ | ||||||
|  | -/* | ||||||
|  | - *  Atheros AR71XX/AR724X/AR913X GPIO button support | ||||||
|  | - * | ||||||
|  | - *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | ||||||
|  | - *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.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/init.h" | ||||||
|  | -#include "linux/slab.h" | ||||||
|  | -#include <linux/platform_device.h> | ||||||
|  | - | ||||||
|  | -#include "dev-gpio-buttons.h" | ||||||
|  | - | ||||||
|  | -void __init ath79_register_gpio_keys_polled(int id, | ||||||
|  | -					    unsigned poll_interval, | ||||||
|  | -					    unsigned nbuttons, | ||||||
|  | -					    struct gpio_keys_button *buttons) | ||||||
|  | -{ | ||||||
|  | -	struct platform_device *pdev; | ||||||
|  | -	struct gpio_keys_platform_data pdata; | ||||||
|  | -	struct gpio_keys_button *p; | ||||||
|  | -	int err; | ||||||
|  | - | ||||||
|  | -	p = kmemdup(buttons, nbuttons * sizeof(*p), GFP_KERNEL); | ||||||
|  | -	if (!p) | ||||||
|  | -		return; | ||||||
|  | - | ||||||
|  | -	pdev = platform_device_alloc("gpio-keys-polled", id); | ||||||
|  | -	if (!pdev) | ||||||
|  | -		goto err_free_buttons; | ||||||
|  | - | ||||||
|  | -	memset(&pdata, 0, sizeof(pdata)); | ||||||
|  | -	pdata.poll_interval = poll_interval; | ||||||
|  | -	pdata.nbuttons = nbuttons; | ||||||
|  | -	pdata.buttons = p; | ||||||
|  | - | ||||||
|  | -	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; | ||||||
|  | - | ||||||
|  | -err_put_pdev: | ||||||
|  | -	platform_device_put(pdev); | ||||||
|  | - | ||||||
|  | -err_free_buttons: | ||||||
|  | -	kfree(p); | ||||||
|  | -} | ||||||
|  | --- a/arch/mips/ath79/dev-gpio-buttons.h | ||||||
|  | +++ /dev/null | ||||||
|  | @@ -1,23 +0,0 @@ | ||||||
|  | -/* | ||||||
|  | - *  Atheros AR71XX/AR724X/AR913X GPIO button support | ||||||
|  | - * | ||||||
|  | - *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | ||||||
|  | - *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.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. | ||||||
|  | - */ | ||||||
|  | - | ||||||
|  | -#ifndef _ATH79_DEV_GPIO_BUTTONS_H | ||||||
|  | -#define _ATH79_DEV_GPIO_BUTTONS_H | ||||||
|  | - | ||||||
|  | -#include <linux/input.h> | ||||||
|  | -#include <linux/gpio_keys.h> | ||||||
|  | - | ||||||
|  | -void ath79_register_gpio_keys_polled(int id, | ||||||
|  | -				     unsigned poll_interval, | ||||||
|  | -				     unsigned nbuttons, | ||||||
|  | -				     struct gpio_keys_button *buttons); | ||||||
|  | - | ||||||
|  | -#endif /* _ATH79_DEV_GPIO_BUTTONS_H */ | ||||||
|  | --- a/arch/mips/ath79/dev-leds-gpio.c | ||||||
|  | +++ /dev/null | ||||||
|  | @@ -1,54 +0,0 @@ | ||||||
|  | -/* | ||||||
|  | - *  Atheros AR71XX/AR724X/AR913X common GPIO LEDs support | ||||||
|  | - * | ||||||
|  | - *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | ||||||
|  | - *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.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/init.h> | ||||||
|  | -#include <linux/slab.h> | ||||||
|  | -#include <linux/platform_device.h> | ||||||
|  | - | ||||||
|  | -#include "dev-leds-gpio.h" | ||||||
|  | - | ||||||
|  | -void __init ath79_register_leds_gpio(int id, | ||||||
|  | -				     unsigned num_leds, | ||||||
|  | -				     struct gpio_led *leds) | ||||||
|  | -{ | ||||||
|  | -	struct platform_device *pdev; | ||||||
|  | -	struct gpio_led_platform_data pdata; | ||||||
|  | -	struct gpio_led *p; | ||||||
|  | -	int err; | ||||||
|  | - | ||||||
|  | -	p = kmemdup(leds, num_leds * sizeof(*p), GFP_KERNEL); | ||||||
|  | -	if (!p) | ||||||
|  | -		return; | ||||||
|  | - | ||||||
|  | -	pdev = platform_device_alloc("leds-gpio", id); | ||||||
|  | -	if (!pdev) | ||||||
|  | -		goto err_free_leds; | ||||||
|  | - | ||||||
|  | -	memset(&pdata, 0, sizeof(pdata)); | ||||||
|  | -	pdata.num_leds = num_leds; | ||||||
|  | -	pdata.leds = p; | ||||||
|  | - | ||||||
|  | -	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; | ||||||
|  | - | ||||||
|  | -err_put_pdev: | ||||||
|  | -	platform_device_put(pdev); | ||||||
|  | - | ||||||
|  | -err_free_leds: | ||||||
|  | -	kfree(p); | ||||||
|  | -} | ||||||
|  | --- a/arch/mips/ath79/dev-leds-gpio.h | ||||||
|  | +++ /dev/null | ||||||
|  | @@ -1,21 +0,0 @@ | ||||||
|  | -/* | ||||||
|  | - *  Atheros AR71XX/AR724X/AR913X common GPIO LEDs support | ||||||
|  | - * | ||||||
|  | - *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | ||||||
|  | - *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.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. | ||||||
|  | - */ | ||||||
|  | - | ||||||
|  | -#ifndef _ATH79_DEV_LEDS_GPIO_H | ||||||
|  | -#define _ATH79_DEV_LEDS_GPIO_H | ||||||
|  | - | ||||||
|  | -#include <linux/leds.h> | ||||||
|  | - | ||||||
|  | -void ath79_register_leds_gpio(int id, | ||||||
|  | -			      unsigned num_leds, | ||||||
|  | -			      struct gpio_led *leds); | ||||||
|  | - | ||||||
|  | -#endif /* _ATH79_DEV_LEDS_GPIO_H */ | ||||||
|  | --- a/arch/mips/ath79/dev-spi.c | ||||||
|  | +++ /dev/null | ||||||
|  | @@ -1,38 +0,0 @@ | ||||||
|  | -/* | ||||||
|  | - *  Atheros AR71XX/AR724X/AR913X SPI controller device | ||||||
|  | - * | ||||||
|  | - *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | ||||||
|  | - *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.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/platform_device.h> | ||||||
|  | -#include <asm/mach-ath79/ar71xx_regs.h> | ||||||
|  | -#include "dev-spi.h" | ||||||
|  | - | ||||||
|  | -static struct resource ath79_spi_resources[] = { | ||||||
|  | -	{ | ||||||
|  | -		.start	= AR71XX_SPI_BASE, | ||||||
|  | -		.end	= AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1, | ||||||
|  | -		.flags	= IORESOURCE_MEM, | ||||||
|  | -	}, | ||||||
|  | -}; | ||||||
|  | - | ||||||
|  | -static struct platform_device ath79_spi_device = { | ||||||
|  | -	.name		= "ath79-spi", | ||||||
|  | -	.id		= -1, | ||||||
|  | -	.resource	= ath79_spi_resources, | ||||||
|  | -	.num_resources	= ARRAY_SIZE(ath79_spi_resources), | ||||||
|  | -}; | ||||||
|  | - | ||||||
|  | -void __init ath79_register_spi(struct ath79_spi_platform_data *pdata, | ||||||
|  | -			       struct spi_board_info const *info, | ||||||
|  | -			       unsigned n) | ||||||
|  | -{ | ||||||
|  | -	spi_register_board_info(info, n); | ||||||
|  | -	ath79_spi_device.dev.platform_data = pdata; | ||||||
|  | -	platform_device_register(&ath79_spi_device); | ||||||
|  | -} | ||||||
|  | --- a/arch/mips/ath79/dev-spi.h | ||||||
|  | +++ /dev/null | ||||||
|  | @@ -1,22 +0,0 @@ | ||||||
|  | -/* | ||||||
|  | - *  Atheros AR71XX/AR724X/AR913X SPI controller device | ||||||
|  | - * | ||||||
|  | - *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | ||||||
|  | - *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.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. | ||||||
|  | - */ | ||||||
|  | - | ||||||
|  | -#ifndef _ATH79_DEV_SPI_H | ||||||
|  | -#define _ATH79_DEV_SPI_H | ||||||
|  | - | ||||||
|  | -#include <linux/spi/spi.h> | ||||||
|  | -#include <asm/mach-ath79/ath79_spi_platform.h> | ||||||
|  | - | ||||||
|  | -void ath79_register_spi(struct ath79_spi_platform_data *pdata, | ||||||
|  | -			 struct spi_board_info const *info, | ||||||
|  | -			 unsigned n); | ||||||
|  | - | ||||||
|  | -#endif /* _ATH79_DEV_SPI_H */ | ||||||
|  | --- a/arch/mips/ath79/dev-usb.c | ||||||
|  | +++ /dev/null | ||||||
|  | @@ -1,242 +0,0 @@ | ||||||
|  | -/* | ||||||
|  | - *  Atheros AR7XXX/AR9XXX USB Host Controller device | ||||||
|  | - * | ||||||
|  | - *  Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | ||||||
|  | - *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||||||
|  | - * | ||||||
|  | - *  Parts of this file are based on Atheros' 2.6.15 BSP | ||||||
|  | - * | ||||||
|  | - *  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/kernel.h> | ||||||
|  | -#include <linux/init.h> | ||||||
|  | -#include <linux/delay.h> | ||||||
|  | -#include <linux/irq.h> | ||||||
|  | -#include <linux/dma-mapping.h> | ||||||
|  | -#include <linux/platform_device.h> | ||||||
|  | -#include <linux/usb/ehci_pdriver.h> | ||||||
|  | -#include <linux/usb/ohci_pdriver.h> | ||||||
|  | - | ||||||
|  | -#include <asm/mach-ath79/ath79.h> | ||||||
|  | -#include <asm/mach-ath79/ar71xx_regs.h> | ||||||
|  | -#include "common.h" | ||||||
|  | -#include "dev-usb.h" | ||||||
|  | - | ||||||
|  | -static u64 ath79_usb_dmamask = DMA_BIT_MASK(32); | ||||||
|  | - | ||||||
|  | -static struct usb_ohci_pdata ath79_ohci_pdata = { | ||||||
|  | -}; | ||||||
|  | - | ||||||
|  | -static struct usb_ehci_pdata ath79_ehci_pdata_v1 = { | ||||||
|  | -	.has_synopsys_hc_bug	= 1, | ||||||
|  | -}; | ||||||
|  | - | ||||||
|  | -static struct usb_ehci_pdata ath79_ehci_pdata_v2 = { | ||||||
|  | -	.caps_offset		= 0x100, | ||||||
|  | -	.has_tt			= 1, | ||||||
|  | -}; | ||||||
|  | - | ||||||
|  | -static void __init ath79_usb_register(const char *name, int id, | ||||||
|  | -				      unsigned long base, unsigned long size, | ||||||
|  | -				      int irq, const void *data, | ||||||
|  | -				      size_t data_size) | ||||||
|  | -{ | ||||||
|  | -	struct resource res[2]; | ||||||
|  | -	struct platform_device *pdev; | ||||||
|  | - | ||||||
|  | -	memset(res, 0, sizeof(res)); | ||||||
|  | - | ||||||
|  | -	res[0].flags = IORESOURCE_MEM; | ||||||
|  | -	res[0].start = base; | ||||||
|  | -	res[0].end = base + size - 1; | ||||||
|  | - | ||||||
|  | -	res[1].flags = IORESOURCE_IRQ; | ||||||
|  | -	res[1].start = irq; | ||||||
|  | -	res[1].end = irq; | ||||||
|  | - | ||||||
|  | -	pdev = platform_device_register_resndata(NULL, name, id, | ||||||
|  | -						 res, ARRAY_SIZE(res), | ||||||
|  | -						 data, data_size); | ||||||
|  | - | ||||||
|  | -	if (IS_ERR(pdev)) { | ||||||
|  | -		pr_err("ath79: unable to register USB at %08lx, err=%d\n", | ||||||
|  | -		       base, (int) PTR_ERR(pdev)); | ||||||
|  | -		return; | ||||||
|  | -	} | ||||||
|  | - | ||||||
|  | -	pdev->dev.dma_mask = &ath79_usb_dmamask; | ||||||
|  | -	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -#define AR71XX_USB_RESET_MASK	(AR71XX_RESET_USB_HOST | \ | ||||||
|  | -				 AR71XX_RESET_USB_PHY | \ | ||||||
|  | -				 AR71XX_RESET_USB_OHCI_DLL) | ||||||
|  | - | ||||||
|  | -static void __init ath79_usb_setup(void) | ||||||
|  | -{ | ||||||
|  | -	void __iomem *usb_ctrl_base; | ||||||
|  | - | ||||||
|  | -	ath79_device_reset_set(AR71XX_USB_RESET_MASK); | ||||||
|  | -	mdelay(1000); | ||||||
|  | -	ath79_device_reset_clear(AR71XX_USB_RESET_MASK); | ||||||
|  | - | ||||||
|  | -	usb_ctrl_base = ioremap(AR71XX_USB_CTRL_BASE, AR71XX_USB_CTRL_SIZE); | ||||||
|  | - | ||||||
|  | -	/* Turning on the Buff and Desc swap bits */ | ||||||
|  | -	__raw_writel(0xf0000, usb_ctrl_base + AR71XX_USB_CTRL_REG_CONFIG); | ||||||
|  | - | ||||||
|  | -	/* WAR for HW bug. Here it adjusts the duration between two SOFS */ | ||||||
|  | -	__raw_writel(0x20c00, usb_ctrl_base + AR71XX_USB_CTRL_REG_FLADJ); | ||||||
|  | - | ||||||
|  | -	iounmap(usb_ctrl_base); | ||||||
|  | - | ||||||
|  | -	mdelay(900); | ||||||
|  | - | ||||||
|  | -	ath79_usb_register("ohci-platform", -1, | ||||||
|  | -			   AR71XX_OHCI_BASE, AR71XX_OHCI_SIZE, | ||||||
|  | -			   ATH79_MISC_IRQ(6), | ||||||
|  | -			   &ath79_ohci_pdata, sizeof(ath79_ohci_pdata)); | ||||||
|  | - | ||||||
|  | -	ath79_usb_register("ehci-platform", -1, | ||||||
|  | -			   AR71XX_EHCI_BASE, AR71XX_EHCI_SIZE, | ||||||
|  | -			   ATH79_CPU_IRQ(3), | ||||||
|  | -			   &ath79_ehci_pdata_v1, sizeof(ath79_ehci_pdata_v1)); | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -static void __init ar7240_usb_setup(void) | ||||||
|  | -{ | ||||||
|  | -	void __iomem *usb_ctrl_base; | ||||||
|  | - | ||||||
|  | -	ath79_device_reset_clear(AR7240_RESET_OHCI_DLL); | ||||||
|  | -	ath79_device_reset_set(AR7240_RESET_USB_HOST); | ||||||
|  | - | ||||||
|  | -	mdelay(1000); | ||||||
|  | - | ||||||
|  | -	ath79_device_reset_set(AR7240_RESET_OHCI_DLL); | ||||||
|  | -	ath79_device_reset_clear(AR7240_RESET_USB_HOST); | ||||||
|  | - | ||||||
|  | -	usb_ctrl_base = ioremap(AR7240_USB_CTRL_BASE, AR7240_USB_CTRL_SIZE); | ||||||
|  | - | ||||||
|  | -	/* WAR for HW bug. Here it adjusts the duration between two SOFS */ | ||||||
|  | -	__raw_writel(0x3, usb_ctrl_base + AR71XX_USB_CTRL_REG_FLADJ); | ||||||
|  | - | ||||||
|  | -	iounmap(usb_ctrl_base); | ||||||
|  | - | ||||||
|  | -	ath79_usb_register("ohci-platform", -1, | ||||||
|  | -			   AR7240_OHCI_BASE, AR7240_OHCI_SIZE, | ||||||
|  | -			   ATH79_CPU_IRQ(3), | ||||||
|  | -			   &ath79_ohci_pdata, sizeof(ath79_ohci_pdata)); | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -static void __init ar724x_usb_setup(void) | ||||||
|  | -{ | ||||||
|  | -	ath79_device_reset_set(AR724X_RESET_USBSUS_OVERRIDE); | ||||||
|  | -	mdelay(10); | ||||||
|  | - | ||||||
|  | -	ath79_device_reset_clear(AR724X_RESET_USB_HOST); | ||||||
|  | -	mdelay(10); | ||||||
|  | - | ||||||
|  | -	ath79_device_reset_clear(AR724X_RESET_USB_PHY); | ||||||
|  | -	mdelay(10); | ||||||
|  | - | ||||||
|  | -	ath79_usb_register("ehci-platform", -1, | ||||||
|  | -			   AR724X_EHCI_BASE, AR724X_EHCI_SIZE, | ||||||
|  | -			   ATH79_CPU_IRQ(3), | ||||||
|  | -			   &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2)); | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -static void __init ar913x_usb_setup(void) | ||||||
|  | -{ | ||||||
|  | -	ath79_device_reset_set(AR913X_RESET_USBSUS_OVERRIDE); | ||||||
|  | -	mdelay(10); | ||||||
|  | - | ||||||
|  | -	ath79_device_reset_clear(AR913X_RESET_USB_HOST); | ||||||
|  | -	mdelay(10); | ||||||
|  | - | ||||||
|  | -	ath79_device_reset_clear(AR913X_RESET_USB_PHY); | ||||||
|  | -	mdelay(10); | ||||||
|  | - | ||||||
|  | -	ath79_usb_register("ehci-platform", -1, | ||||||
|  | -			   AR913X_EHCI_BASE, AR913X_EHCI_SIZE, | ||||||
|  | -			   ATH79_CPU_IRQ(3), | ||||||
|  | -			   &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2)); | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -static void __init ar933x_usb_setup(void) | ||||||
|  | -{ | ||||||
|  | -	ath79_device_reset_set(AR933X_RESET_USBSUS_OVERRIDE); | ||||||
|  | -	mdelay(10); | ||||||
|  | - | ||||||
|  | -	ath79_device_reset_clear(AR933X_RESET_USB_HOST); | ||||||
|  | -	mdelay(10); | ||||||
|  | - | ||||||
|  | -	ath79_device_reset_clear(AR933X_RESET_USB_PHY); | ||||||
|  | -	mdelay(10); | ||||||
|  | - | ||||||
|  | -	ath79_usb_register("ehci-platform", -1, | ||||||
|  | -			   AR933X_EHCI_BASE, AR933X_EHCI_SIZE, | ||||||
|  | -			   ATH79_CPU_IRQ(3), | ||||||
|  | -			   &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2)); | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -static void __init ar934x_usb_setup(void) | ||||||
|  | -{ | ||||||
|  | -	u32 bootstrap; | ||||||
|  | - | ||||||
|  | -	bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP); | ||||||
|  | -	if (bootstrap & AR934X_BOOTSTRAP_USB_MODE_DEVICE) | ||||||
|  | -		return; | ||||||
|  | - | ||||||
|  | -	ath79_device_reset_set(AR934X_RESET_USBSUS_OVERRIDE); | ||||||
|  | -	udelay(1000); | ||||||
|  | - | ||||||
|  | -	ath79_device_reset_clear(AR934X_RESET_USB_PHY); | ||||||
|  | -	udelay(1000); | ||||||
|  | - | ||||||
|  | -	ath79_device_reset_clear(AR934X_RESET_USB_PHY_ANALOG); | ||||||
|  | -	udelay(1000); | ||||||
|  | - | ||||||
|  | -	ath79_device_reset_clear(AR934X_RESET_USB_HOST); | ||||||
|  | -	udelay(1000); | ||||||
|  | - | ||||||
|  | -	ath79_usb_register("ehci-platform", -1, | ||||||
|  | -			   AR934X_EHCI_BASE, AR934X_EHCI_SIZE, | ||||||
|  | -			   ATH79_CPU_IRQ(3), | ||||||
|  | -			   &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2)); | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -static void __init qca955x_usb_setup(void) | ||||||
|  | -{ | ||||||
|  | -	ath79_usb_register("ehci-platform", 0, | ||||||
|  | -			   QCA955X_EHCI0_BASE, QCA955X_EHCI_SIZE, | ||||||
|  | -			   ATH79_IP3_IRQ(0), | ||||||
|  | -			   &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2)); | ||||||
|  | - | ||||||
|  | -	ath79_usb_register("ehci-platform", 1, | ||||||
|  | -			   QCA955X_EHCI1_BASE, QCA955X_EHCI_SIZE, | ||||||
|  | -			   ATH79_IP3_IRQ(1), | ||||||
|  | -			   &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2)); | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -void __init ath79_register_usb(void) | ||||||
|  | -{ | ||||||
|  | -	if (soc_is_ar71xx()) | ||||||
|  | -		ath79_usb_setup(); | ||||||
|  | -	else if (soc_is_ar7240()) | ||||||
|  | -		ar7240_usb_setup(); | ||||||
|  | -	else if (soc_is_ar7241() || soc_is_ar7242()) | ||||||
|  | -		ar724x_usb_setup(); | ||||||
|  | -	else if (soc_is_ar913x()) | ||||||
|  | -		ar913x_usb_setup(); | ||||||
|  | -	else if (soc_is_ar933x()) | ||||||
|  | -		ar933x_usb_setup(); | ||||||
|  | -	else if (soc_is_ar934x()) | ||||||
|  | -		ar934x_usb_setup(); | ||||||
|  | -	else if (soc_is_qca955x()) | ||||||
|  | -		qca955x_usb_setup(); | ||||||
|  | -	else | ||||||
|  | -		BUG(); | ||||||
|  | -} | ||||||
|  | --- a/arch/mips/ath79/dev-usb.h | ||||||
|  | +++ /dev/null | ||||||
|  | @@ -1,17 +0,0 @@ | ||||||
|  | -/* | ||||||
|  | - *  Atheros AR71XX/AR724X/AR913X USB Host Controller support | ||||||
|  | - * | ||||||
|  | - *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | ||||||
|  | - *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.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. | ||||||
|  | - */ | ||||||
|  | - | ||||||
|  | -#ifndef _ATH79_DEV_USB_H | ||||||
|  | -#define _ATH79_DEV_USB_H | ||||||
|  | - | ||||||
|  | -void ath79_register_usb(void); | ||||||
|  | - | ||||||
|  | -#endif /* _ATH79_DEV_USB_H */ | ||||||
|  | --- a/arch/mips/ath79/dev-wmac.c | ||||||
|  | +++ /dev/null | ||||||
|  | @@ -1,155 +0,0 @@ | ||||||
|  | -/* | ||||||
|  | - *  Atheros AR913X/AR933X SoC built-in WMAC device support | ||||||
|  | - * | ||||||
|  | - *  Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com> | ||||||
|  | - *  Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | ||||||
|  | - *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||||||
|  | - * | ||||||
|  | - *  Parts of this file are based on Atheros 2.6.15/2.6.31 BSP | ||||||
|  | - * | ||||||
|  | - *  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/init.h> | ||||||
|  | -#include <linux/delay.h> | ||||||
|  | -#include <linux/irq.h> | ||||||
|  | -#include <linux/platform_device.h> | ||||||
|  | -#include <linux/ath9k_platform.h> | ||||||
|  | - | ||||||
|  | -#include <asm/mach-ath79/ath79.h> | ||||||
|  | -#include <asm/mach-ath79/ar71xx_regs.h> | ||||||
|  | -#include "dev-wmac.h" | ||||||
|  | - | ||||||
|  | -static struct ath9k_platform_data ath79_wmac_data; | ||||||
|  | - | ||||||
|  | -static struct resource ath79_wmac_resources[] = { | ||||||
|  | -	{ | ||||||
|  | -		/* .start and .end fields are filled dynamically */ | ||||||
|  | -		.flags	= IORESOURCE_MEM, | ||||||
|  | -	}, { | ||||||
|  | -		/* .start and .end fields are filled dynamically */ | ||||||
|  | -		.flags	= IORESOURCE_IRQ, | ||||||
|  | -	}, | ||||||
|  | -}; | ||||||
|  | - | ||||||
|  | -static struct platform_device ath79_wmac_device = { | ||||||
|  | -	.name		= "ath9k", | ||||||
|  | -	.id		= -1, | ||||||
|  | -	.resource	= ath79_wmac_resources, | ||||||
|  | -	.num_resources	= ARRAY_SIZE(ath79_wmac_resources), | ||||||
|  | -	.dev = { | ||||||
|  | -		.platform_data = &ath79_wmac_data, | ||||||
|  | -	}, | ||||||
|  | -}; | ||||||
|  | - | ||||||
|  | -static void __init ar913x_wmac_setup(void) | ||||||
|  | -{ | ||||||
|  | -	/* reset the WMAC */ | ||||||
|  | -	ath79_device_reset_set(AR913X_RESET_AMBA2WMAC); | ||||||
|  | -	mdelay(10); | ||||||
|  | - | ||||||
|  | -	ath79_device_reset_clear(AR913X_RESET_AMBA2WMAC); | ||||||
|  | -	mdelay(10); | ||||||
|  | - | ||||||
|  | -	ath79_wmac_resources[0].start = AR913X_WMAC_BASE; | ||||||
|  | -	ath79_wmac_resources[0].end = AR913X_WMAC_BASE + AR913X_WMAC_SIZE - 1; | ||||||
|  | -	ath79_wmac_resources[1].start = ATH79_CPU_IRQ(2); | ||||||
|  | -	ath79_wmac_resources[1].end = ATH79_CPU_IRQ(2); | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | - | ||||||
|  | -static int ar933x_wmac_reset(void) | ||||||
|  | -{ | ||||||
|  | -	ath79_device_reset_set(AR933X_RESET_WMAC); | ||||||
|  | -	ath79_device_reset_clear(AR933X_RESET_WMAC); | ||||||
|  | - | ||||||
|  | -	return 0; | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -static int ar933x_r1_get_wmac_revision(void) | ||||||
|  | -{ | ||||||
|  | -	return ath79_soc_rev; | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -static void __init ar933x_wmac_setup(void) | ||||||
|  | -{ | ||||||
|  | -	u32 t; | ||||||
|  | - | ||||||
|  | -	ar933x_wmac_reset(); | ||||||
|  | - | ||||||
|  | -	ath79_wmac_device.name = "ar933x_wmac"; | ||||||
|  | - | ||||||
|  | -	ath79_wmac_resources[0].start = AR933X_WMAC_BASE; | ||||||
|  | -	ath79_wmac_resources[0].end = AR933X_WMAC_BASE + AR933X_WMAC_SIZE - 1; | ||||||
|  | -	ath79_wmac_resources[1].start = ATH79_CPU_IRQ(2); | ||||||
|  | -	ath79_wmac_resources[1].end = ATH79_CPU_IRQ(2); | ||||||
|  | - | ||||||
|  | -	t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); | ||||||
|  | -	if (t & AR933X_BOOTSTRAP_REF_CLK_40) | ||||||
|  | -		ath79_wmac_data.is_clk_25mhz = false; | ||||||
|  | -	else | ||||||
|  | -		ath79_wmac_data.is_clk_25mhz = true; | ||||||
|  | - | ||||||
|  | -	if (ath79_soc_rev == 1) | ||||||
|  | -		ath79_wmac_data.get_mac_revision = ar933x_r1_get_wmac_revision; | ||||||
|  | - | ||||||
|  | -	ath79_wmac_data.external_reset = ar933x_wmac_reset; | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -static void ar934x_wmac_setup(void) | ||||||
|  | -{ | ||||||
|  | -	u32 t; | ||||||
|  | - | ||||||
|  | -	ath79_wmac_device.name = "ar934x_wmac"; | ||||||
|  | - | ||||||
|  | -	ath79_wmac_resources[0].start = AR934X_WMAC_BASE; | ||||||
|  | -	ath79_wmac_resources[0].end = AR934X_WMAC_BASE + AR934X_WMAC_SIZE - 1; | ||||||
|  | -	ath79_wmac_resources[1].start = ATH79_IP2_IRQ(1); | ||||||
|  | -	ath79_wmac_resources[1].end = ATH79_IP2_IRQ(1); | ||||||
|  | - | ||||||
|  | -	t = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP); | ||||||
|  | -	if (t & AR934X_BOOTSTRAP_REF_CLK_40) | ||||||
|  | -		ath79_wmac_data.is_clk_25mhz = false; | ||||||
|  | -	else | ||||||
|  | -		ath79_wmac_data.is_clk_25mhz = true; | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -static void qca955x_wmac_setup(void) | ||||||
|  | -{ | ||||||
|  | -	u32 t; | ||||||
|  | - | ||||||
|  | -	ath79_wmac_device.name = "qca955x_wmac"; | ||||||
|  | - | ||||||
|  | -	ath79_wmac_resources[0].start = QCA955X_WMAC_BASE; | ||||||
|  | -	ath79_wmac_resources[0].end = QCA955X_WMAC_BASE + QCA955X_WMAC_SIZE - 1; | ||||||
|  | -	ath79_wmac_resources[1].start = ATH79_IP2_IRQ(1); | ||||||
|  | -	ath79_wmac_resources[1].end = ATH79_IP2_IRQ(1); | ||||||
|  | - | ||||||
|  | -	t = ath79_reset_rr(QCA955X_RESET_REG_BOOTSTRAP); | ||||||
|  | -	if (t & QCA955X_BOOTSTRAP_REF_CLK_40) | ||||||
|  | -		ath79_wmac_data.is_clk_25mhz = false; | ||||||
|  | -	else | ||||||
|  | -		ath79_wmac_data.is_clk_25mhz = true; | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -void __init ath79_register_wmac(u8 *cal_data) | ||||||
|  | -{ | ||||||
|  | -	if (soc_is_ar913x()) | ||||||
|  | -		ar913x_wmac_setup(); | ||||||
|  | -	else if (soc_is_ar933x()) | ||||||
|  | -		ar933x_wmac_setup(); | ||||||
|  | -	else if (soc_is_ar934x()) | ||||||
|  | -		ar934x_wmac_setup(); | ||||||
|  | -	else if (soc_is_qca955x()) | ||||||
|  | -		qca955x_wmac_setup(); | ||||||
|  | -	else | ||||||
|  | -		BUG(); | ||||||
|  | - | ||||||
|  | -	if (cal_data) | ||||||
|  | -		memcpy(ath79_wmac_data.eeprom_data, cal_data, | ||||||
|  | -		       sizeof(ath79_wmac_data.eeprom_data)); | ||||||
|  | - | ||||||
|  | -	platform_device_register(&ath79_wmac_device); | ||||||
|  | -} | ||||||
|  | --- a/arch/mips/ath79/dev-wmac.h | ||||||
|  | +++ /dev/null | ||||||
|  | @@ -1,17 +0,0 @@ | ||||||
|  | -/* | ||||||
|  | - *  Atheros AR913X/AR933X SoC built-in WMAC device support | ||||||
|  | - * | ||||||
|  | - *  Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | ||||||
|  | - *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.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. | ||||||
|  | - */ | ||||||
|  | - | ||||||
|  | -#ifndef _ATH79_DEV_WMAC_H | ||||||
|  | -#define _ATH79_DEV_WMAC_H | ||||||
|  | - | ||||||
|  | -void ath79_register_wmac(u8 *cal_data); | ||||||
|  | - | ||||||
|  | -#endif /* _ATH79_DEV_WMAC_H */ | ||||||
|  | --- a/arch/mips/ath79/setup.c | ||||||
|  | +++ b/arch/mips/ath79/setup.c | ||||||
|  | @@ -32,7 +32,6 @@ | ||||||
|  |  #include <asm/mach-ath79/ath79.h> | ||||||
|  |  #include <asm/mach-ath79/ar71xx_regs.h> | ||||||
|  |  #include "common.h" | ||||||
|  | -#include "dev-common.h" | ||||||
|  |   | ||||||
|  |  #define ATH79_SYS_TYPE_LEN	64 | ||||||
|  |   | ||||||
| @@ -0,0 +1,95 @@ | |||||||
|  | From 00e4313da4609074fff134e61dd9ffe3fd37474d Mon Sep 17 00:00:00 2001 | ||||||
|  | From: John Crispin <john@phrozen.org> | ||||||
|  | Date: Sun, 24 Jun 2018 09:39:41 +0200 | ||||||
|  | Subject: [PATCH 31/33] MIPS: ath79: drop !OF clock code | ||||||
|  |  | ||||||
|  | With the target now being fully OF based, we can drop the legacy clock | ||||||
|  | registration code. All clocks are now probed via devicetree. | ||||||
|  |  | ||||||
|  | Signed-off-by: John Crispin <john@phrozen.org> | ||||||
|  | --- | ||||||
|  |  arch/mips/ath79/clock.c  | 56 ------------------------------------------------ | ||||||
|  |  arch/mips/ath79/common.h |  3 --- | ||||||
|  |  2 files changed, 59 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/arch/mips/ath79/clock.c | ||||||
|  | +++ b/arch/mips/ath79/clock.c | ||||||
|  | @@ -617,60 +617,6 @@ static void __init qca956x_clocks_init(v | ||||||
|  |  	ath79_set_clk(ATH79_CLK_AHB, ahb_rate); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -void __init ath79_clocks_init(void) | ||||||
|  | -{ | ||||||
|  | -	const char *wdt; | ||||||
|  | -	const char *uart; | ||||||
|  | - | ||||||
|  | -	if (soc_is_ar71xx()) | ||||||
|  | -		ar71xx_clocks_init(ath79_pll_base); | ||||||
|  | -	else if (soc_is_ar724x() || soc_is_ar913x()) | ||||||
|  | -		ar724x_clocks_init(ath79_pll_base); | ||||||
|  | -	else if (soc_is_ar933x()) | ||||||
|  | -		ar933x_clocks_init(ath79_pll_base); | ||||||
|  | -	else if (soc_is_ar934x()) | ||||||
|  | -		ar934x_clocks_init(ath79_pll_base); | ||||||
|  | -	else if (soc_is_qca953x()) | ||||||
|  | -		qca953x_clocks_init(ath79_pll_base); | ||||||
|  | -	else if (soc_is_qca955x()) | ||||||
|  | -		qca955x_clocks_init(ath79_pll_base); | ||||||
|  | -	else if (soc_is_qca956x() || soc_is_tp9343()) | ||||||
|  | -		qca956x_clocks_init(ath79_pll_base); | ||||||
|  | -	else | ||||||
|  | -		BUG(); | ||||||
|  | - | ||||||
|  | -	if (soc_is_ar71xx() || soc_is_ar724x() || soc_is_ar913x()) { | ||||||
|  | -		wdt = "ahb"; | ||||||
|  | -		uart = "ahb"; | ||||||
|  | -	} else if (soc_is_ar933x()) { | ||||||
|  | -		wdt = "ahb"; | ||||||
|  | -		uart = "ref"; | ||||||
|  | -	} else { | ||||||
|  | -		wdt = "ref"; | ||||||
|  | -		uart = "ref"; | ||||||
|  | -	} | ||||||
|  | - | ||||||
|  | -	clk_add_alias("wdt", NULL, wdt, NULL); | ||||||
|  | -	clk_add_alias("uart", NULL, uart, NULL); | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -unsigned long __init | ||||||
|  | -ath79_get_sys_clk_rate(const char *id) | ||||||
|  | -{ | ||||||
|  | -	struct clk *clk; | ||||||
|  | -	unsigned long rate; | ||||||
|  | - | ||||||
|  | -	clk = clk_get(NULL, id); | ||||||
|  | -	if (IS_ERR(clk)) | ||||||
|  | -		panic("unable to get %s clock, err=%d", id, (int) PTR_ERR(clk)); | ||||||
|  | - | ||||||
|  | -	rate = clk_get_rate(clk); | ||||||
|  | -	clk_put(clk); | ||||||
|  | - | ||||||
|  | -	return rate; | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -#ifdef CONFIG_OF | ||||||
|  |  static void __init ath79_clocks_init_dt(struct device_node *np) | ||||||
|  |  { | ||||||
|  |  	struct clk *ref_clk; | ||||||
|  | @@ -727,5 +673,3 @@ CLK_OF_DECLARE(ar9340_clk, "qca,ar9340-p | ||||||
|  |  CLK_OF_DECLARE(ar9530_clk, "qca,qca9530-pll", ath79_clocks_init_dt); | ||||||
|  |  CLK_OF_DECLARE(ar9550_clk, "qca,qca9550-pll", ath79_clocks_init_dt); | ||||||
|  |  CLK_OF_DECLARE(ar9560_clk, "qca,qca9560-pll", ath79_clocks_init_dt); | ||||||
|  | - | ||||||
|  | -#endif | ||||||
|  | --- a/arch/mips/ath79/common.h | ||||||
|  | +++ b/arch/mips/ath79/common.h | ||||||
|  | @@ -19,9 +19,6 @@ | ||||||
|  |  #define ATH79_MEM_SIZE_MIN	(2 * 1024 * 1024) | ||||||
|  |  #define ATH79_MEM_SIZE_MAX	(256 * 1024 * 1024) | ||||||
|  |   | ||||||
|  | -void ath79_clocks_init(void); | ||||||
|  | -unsigned long ath79_get_sys_clk_rate(const char *id); | ||||||
|  | - | ||||||
|  |  void ath79_ddr_ctrl_init(void); | ||||||
|  |   | ||||||
|  |  #endif /* __ATH79_COMMON_H */ | ||||||
| @@ -0,0 +1,93 @@ | |||||||
|  | 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 | ||||||
|  | @@ -208,6 +208,8 @@ config ATH79 | ||||||
|  |  	select SYS_SUPPORTS_BIG_ENDIAN | ||||||
|  |  	select SYS_SUPPORTS_MIPS16 | ||||||
|  |  	select SYS_SUPPORTS_ZBOOT_UART_PROM | ||||||
|  | +	select HW_HAS_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 HW_HAS_PCI | ||||||
|  | -	def_bool n | ||||||
|  | - | ||||||
|  | -config SOC_AR724X | ||||||
|  | -	select HW_HAS_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 HW_HAS_PCI | ||||||
|  | -	select PCI_AR724X if PCI | ||||||
|  | -	def_bool n | ||||||
|  | - | ||||||
|  | -config SOC_QCA955X | ||||||
|  | -	select HW_HAS_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 | ||||||
|  |  # | ||||||
| @@ -0,0 +1,73 @@ | |||||||
|  | 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> | ||||||
|  | --- | ||||||
|  |  arch/mips/include/asm/mach-ath79/ath79_spi_platform.h | 19 ------------------- | ||||||
|  |  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/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h | ||||||
|  | +++ /dev/null | ||||||
|  | @@ -1,19 +0,0 @@ | ||||||
|  | -/* | ||||||
|  | - *  Platform data definition for Atheros AR71XX/AR724X/AR913X SPI controller | ||||||
|  | - * | ||||||
|  | - *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.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. | ||||||
|  | - */ | ||||||
|  | - | ||||||
|  | -#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 | ||||||
|  | @@ -26,7 +26,6 @@ | ||||||
|  |  #include <linux/err.h> | ||||||
|  |   | ||||||
|  |  #include <asm/mach-ath79/ar71xx_regs.h> | ||||||
|  | -#include <asm/mach-ath79/ath79_spi_platform.h> | ||||||
|  |   | ||||||
|  |  #define DRV_NAME	"ath79-spi" | ||||||
|  |   | ||||||
|  | @@ -208,7 +207,6 @@ static int ath79_spi_probe(struct platfo | ||||||
|  |  { | ||||||
|  |  	struct spi_master *master; | ||||||
|  |  	struct ath79_spi *sp; | ||||||
|  | -	struct ath79_spi_platform_data *pdata; | ||||||
|  |  	struct resource	*r; | ||||||
|  |  	unsigned long rate; | ||||||
|  |  	int ret; | ||||||
|  | @@ -223,15 +221,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->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32); | ||||||
|  |  	master->setup = ath79_spi_setup; | ||||||
|  |  	master->cleanup = ath79_spi_cleanup; | ||||||
|  | -	if (pdata) { | ||||||
|  | -		master->bus_num = pdata->bus_num; | ||||||
|  | -		master->num_chipselect = pdata->num_chipselect; | ||||||
|  | -	} | ||||||
|  |   | ||||||
|  |  	sp->bitbang.master = master; | ||||||
|  |  	sp->bitbang.chipselect = ath79_spi_chipselect; | ||||||
| @@ -0,0 +1,27 @@ | |||||||
|  | --- a/arch/mips/ath79/common.c | ||||||
|  | +++ b/arch/mips/ath79/common.c | ||||||
|  | @@ -34,11 +34,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 | ||||||
|  | @@ -152,6 +152,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) | ||||||
| @@ -0,0 +1,165 @@ | |||||||
|  | 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 | ||||||
|  | @@ -23,6 +23,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" | ||||||
|  |   | ||||||
|  | @@ -654,3 +656,68 @@ void of_gpiochip_remove(struct gpio_chip | ||||||
|  |  	gpiochip_remove_pin_ranges(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 | ||||||
|  | @@ -568,7 +568,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; | ||||||
|  | @@ -630,6 +630,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, | ||||||
|  | @@ -651,6 +653,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 | ||||||
|  | @@ -531,6 +531,7 @@ struct gpio_desc *devm_fwnode_get_gpiod_ | ||||||
|  |   | ||||||
|  |  #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); | ||||||
|  | @@ -538,6 +539,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) | ||||||
|  |  { | ||||||
| @@ -0,0 +1,139 @@ | |||||||
|  | --- a/arch/mips/pci/pci-ar71xx.c | ||||||
|  | +++ b/arch/mips/pci/pci-ar71xx.c | ||||||
|  | @@ -54,11 +54,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 */ | ||||||
|  | @@ -230,104 +228,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); | ||||||
|  | @@ -361,10 +261,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 */ | ||||||
|  | @@ -375,8 +271,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; | ||||||
							
								
								
									
										21
									
								
								target/linux/ath79/patches-4.19/0037-missing-registers.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								target/linux/ath79/patches-4.19/0037-missing-registers.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  | 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 | ||||||
|  | @@ -1229,6 +1229,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 | ||||||
| @@ -0,0 +1,18 @@ | |||||||
|  | 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 | ||||||
|  | @@ -325,7 +325,11 @@ static struct platform_driver ath79_gpio | ||||||
|  |  	.remove = ath79_gpio_remove, | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | -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"); | ||||||
| @@ -0,0 +1,64 @@ | |||||||
|  | --- a/drivers/mtd/chips/cfi_cmdset_0002.c | ||||||
|  | +++ b/drivers/mtd/chips/cfi_cmdset_0002.c | ||||||
|  | @@ -1634,8 +1634,8 @@ static int __xipram do_write_oneword(str | ||||||
|  |  			break; | ||||||
|  |  		} | ||||||
|  |   | ||||||
|  | -		if (chip_ready(map, adr)) | ||||||
|  | -			break; | ||||||
|  | +		if (chip_good(map, adr, datum)) | ||||||
|  | +			goto enable_xip; | ||||||
|  |   | ||||||
|  |  		/* Latency issues. Drop the lock, wait a while and retry */ | ||||||
|  |  		UDELAY(map, chip, adr, 1); | ||||||
|  | @@ -1651,6 +1651,8 @@ static int __xipram do_write_oneword(str | ||||||
|  |   | ||||||
|  |  		ret = -EIO; | ||||||
|  |  	} | ||||||
|  | + | ||||||
|  | + enable_xip: | ||||||
|  |  	xip_enable(map, chip, adr); | ||||||
|  |   op_done: | ||||||
|  |  	if (mode == FL_OTP_WRITE) | ||||||
|  | @@ -2229,7 +2231,6 @@ static int cfi_amdstd_panic_write(struct | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | - | ||||||
|  |  /* | ||||||
|  |   * Handle devices with one erase region, that only implement | ||||||
|  |   * the chip erase command. | ||||||
|  | @@ -2297,7 +2298,7 @@ static int __xipram do_erase_chip(struct | ||||||
|  |  		} | ||||||
|  |   | ||||||
|  |  		if (chip_good(map, adr, map_word_ff(map))) | ||||||
|  | -			break; | ||||||
|  | +			goto op_done; | ||||||
|  |   | ||||||
|  |  		if (time_after(jiffies, timeo)) { | ||||||
|  |  			printk(KERN_WARNING "MTD %s(): software timeout\n", | ||||||
|  | @@ -2321,6 +2322,7 @@ static int __xipram do_erase_chip(struct | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | + op_done: | ||||||
|  |  	chip->state = FL_READY; | ||||||
|  |  	xip_enable(map, chip, adr); | ||||||
|  |  	DISABLE_VPP(map); | ||||||
|  | @@ -2393,7 +2395,7 @@ static int __xipram do_erase_oneblock(st | ||||||
|  |  		} | ||||||
|  |   | ||||||
|  |  		if (chip_good(map, adr, map_word_ff(map))) | ||||||
|  | -			break; | ||||||
|  | +			goto op_done; | ||||||
|  |   | ||||||
|  |  		if (time_after(jiffies, timeo)) { | ||||||
|  |  			printk(KERN_WARNING "MTD %s(): software timeout\n", | ||||||
|  | @@ -2417,6 +2419,7 @@ static int __xipram do_erase_oneblock(st | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | + op_done: | ||||||
|  |  	chip->state = FL_READY; | ||||||
|  |  	xip_enable(map, chip, adr); | ||||||
|  |  	DISABLE_VPP(map); | ||||||
| @@ -0,0 +1,20 @@ | |||||||
|  | --- a/drivers/mtd/parsers/Makefile | ||||||
|  | +++ b/drivers/mtd/parsers/Makefile | ||||||
|  | @@ -1,2 +1,3 @@ | ||||||
|  | +obj-$(CONFIG_MTD_PARSER_CYBERTAN)	+= parser_cybertan.o | ||||||
|  |  obj-$(CONFIG_MTD_PARSER_TRX)		+= parser_trx.o | ||||||
|  |  obj-$(CONFIG_MTD_SHARPSL_PARTS)		+= sharpslpart.o | ||||||
|  | --- a/drivers/mtd/parsers/Kconfig | ||||||
|  | +++ b/drivers/mtd/parsers/Kconfig | ||||||
|  | @@ -1,3 +1,11 @@ | ||||||
|  | +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_TRX | ||||||
|  |  	tristate "Parser for TRX format partitions" | ||||||
|  |  	depends on MTD && (BCM47XX || ARCH_BCM_5301X || COMPILE_TEST) | ||||||
| @@ -0,0 +1,25 @@ | |||||||
|  | --- a/drivers/mtd/Kconfig | ||||||
|  | +++ b/drivers/mtd/Kconfig | ||||||
|  | @@ -193,6 +193,12 @@ config MTD_MYLOADER_PARTS | ||||||
|  |  	  You will still need the parsing functions to be called by the driver | ||||||
|  |  	  for your particular device. It won't happen automatically. | ||||||
|  |   | ||||||
|  | +config MTD_TPLINK_PARTS | ||||||
|  | +	tristate "TP-Link AR7XXX/AR9XXX partitioning support" | ||||||
|  | +	depends on ATH79 | ||||||
|  | +	---help--- | ||||||
|  | +	  TBD. | ||||||
|  | + | ||||||
|  |  comment "User Modules And Translation Layers" | ||||||
|  |   | ||||||
|  |  # | ||||||
|  | --- a/drivers/mtd/Makefile | ||||||
|  | +++ b/drivers/mtd/Makefile | ||||||
|  | @@ -18,6 +18,7 @@ obj-$(CONFIG_MTD_BCM63XX_PARTS)	+= bcm63 | ||||||
|  |  obj-$(CONFIG_MTD_BCM47XX_PARTS)	+= bcm47xxpart.o | ||||||
|  |  obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o | ||||||
|  |  obj-y				+= parsers/ | ||||||
|  | +obj-$(CONFIG_MTD_TPLINK_PARTS)	+= tplinkpart.o | ||||||
|  |   | ||||||
|  |  # 'Users' - code which presents functionality to userspace. | ||||||
|  |  obj-$(CONFIG_MTD_BLKDEVS)	+= mtd_blkdevs.o | ||||||
| @@ -0,0 +1,28 @@ | |||||||
|  | --- a/drivers/net/ethernet/atheros/Kconfig | ||||||
|  | +++ b/drivers/net/ethernet/atheros/Kconfig | ||||||
|  | @@ -5,7 +5,7 @@ | ||||||
|  |  config NET_VENDOR_ATHEROS | ||||||
|  |  	bool "Atheros devices" | ||||||
|  |  	default y | ||||||
|  | -	depends on PCI | ||||||
|  | +	depends on (PCI || ATH79) | ||||||
|  |  	---help--- | ||||||
|  |  	  If you have a network (Ethernet) card belonging to this class, say Y. | ||||||
|  |   | ||||||
|  | @@ -78,4 +78,6 @@ config ALX | ||||||
|  |  	  To compile this driver as a module, choose M here.  The module | ||||||
|  |  	  will be called alx. | ||||||
|  |   | ||||||
|  | +source drivers/net/ethernet/atheros/ag71xx/Kconfig | ||||||
|  | + | ||||||
|  |  endif # NET_VENDOR_ATHEROS | ||||||
|  | --- a/drivers/net/ethernet/atheros/Makefile | ||||||
|  | +++ b/drivers/net/ethernet/atheros/Makefile | ||||||
|  | @@ -3,6 +3,7 @@ | ||||||
|  |  # Makefile for the Atheros network device drivers. | ||||||
|  |  # | ||||||
|  |   | ||||||
|  | +obj-$(CONFIG_AG71XX) += ag71xx/ | ||||||
|  |  obj-$(CONFIG_ATL1) += atlx/ | ||||||
|  |  obj-$(CONFIG_ATL2) += atlx/ | ||||||
|  |  obj-$(CONFIG_ATL1E) += atl1e/ | ||||||
| @@ -0,0 +1,12 @@ | |||||||
|  | --- 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/ | ||||||
| @@ -0,0 +1,98 @@ | |||||||
|  | --- /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 | ||||||
|  | @@ -71,6 +71,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; | ||||||
|  | @@ -279,6 +318,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; | ||||||
|  |  } | ||||||
|  |   | ||||||
| @@ -0,0 +1,103 @@ | |||||||
|  | --- a/drivers/usb/host/ehci-hcd.c | ||||||
|  | +++ b/drivers/usb/host/ehci-hcd.c | ||||||
|  | @@ -239,6 +239,37 @@ int ehci_reset(struct ehci_hcd *ehci) | ||||||
|  |  	command |= CMD_RESET; | ||||||
|  |  	dbg_cmd (ehci, "reset", command); | ||||||
|  |  	ehci_writel(ehci, command, &ehci->regs->command); | ||||||
|  | + | ||||||
|  | +	if (ehci->qca_force_host_mode) { | ||||||
|  | +		u32 usbmode; | ||||||
|  | + | ||||||
|  | +		udelay(1000); | ||||||
|  | + | ||||||
|  | +		usbmode = ehci_readl(ehci, &ehci->regs->usbmode); | ||||||
|  | +		usbmode |= USBMODE_CM_HC | (1 << 4); | ||||||
|  | +		ehci_writel(ehci, usbmode, &ehci->regs->usbmode); | ||||||
|  | + | ||||||
|  | +		ehci_dbg(ehci, "forced host mode, usbmode: %08x\n", | ||||||
|  | +			 ehci_readl(ehci, &ehci->regs->usbmode)); | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	if (ehci->qca_force_16bit_ptw) { | ||||||
|  | +		u32 port_status; | ||||||
|  | + | ||||||
|  | +		udelay(1000); | ||||||
|  | + | ||||||
|  | +		/* enable 16-bit UTMI interface */ | ||||||
|  | +		port_status = ehci_readl(ehci, &ehci->regs->port_status[0]); | ||||||
|  | +		port_status |= BIT(28); | ||||||
|  | +		ehci_writel(ehci, port_status, &ehci->regs->port_status[0]); | ||||||
|  | + | ||||||
|  | +		ehci_dbg(ehci, "16-bit UTMI interface enabled, status: %08x\n", | ||||||
|  | +			 ehci_readl(ehci, &ehci->regs->port_status[0])); | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	if (ehci->reset_notifier) | ||||||
|  | +		ehci->reset_notifier(ehci_to_hcd(ehci)); | ||||||
|  | + | ||||||
|  |  	ehci->rh_state = EHCI_RH_HALTED; | ||||||
|  |  	ehci->next_statechange = jiffies; | ||||||
|  |  	retval = ehci_handshake(ehci, &ehci->regs->command, | ||||||
|  | --- a/drivers/usb/host/ehci.h | ||||||
|  | +++ b/drivers/usb/host/ehci.h | ||||||
|  | @@ -219,6 +219,10 @@ struct ehci_hcd {			/* one per controlle | ||||||
|  |  	unsigned		need_oc_pp_cycle:1; /* MPC834X port power */ | ||||||
|  |  	unsigned		imx28_write_fix:1; /* For Freescale i.MX28 */ | ||||||
|  |  	unsigned		ignore_oc:1; | ||||||
|  | +	unsigned		qca_force_host_mode:1; | ||||||
|  | +	unsigned		qca_force_16bit_ptw:1; /* force 16 bit UTMI */ | ||||||
|  | + | ||||||
|  | +	void (*reset_notifier)(struct usb_hcd *hcd); | ||||||
|  |   | ||||||
|  |  	/* required for usb32 quirk */ | ||||||
|  |  	#define OHCI_CTRL_HCFS          (3 << 6) | ||||||
|  | --- a/include/linux/usb/ehci_pdriver.h | ||||||
|  | +++ b/include/linux/usb/ehci_pdriver.h | ||||||
|  | @@ -51,6 +51,8 @@ struct usb_ehci_pdata { | ||||||
|  |  	unsigned	reset_on_resume:1; | ||||||
|  |  	unsigned	dma_mask_64:1; | ||||||
|  |  	unsigned	ignore_oc:1; | ||||||
|  | +	unsigned	qca_force_host_mode:1; | ||||||
|  | +	unsigned	qca_force_16bit_ptw:1; | ||||||
|  |   | ||||||
|  |  	/* Turn on all power and clocks */ | ||||||
|  |  	int (*power_on)(struct platform_device *pdev); | ||||||
|  | @@ -60,6 +62,7 @@ struct usb_ehci_pdata { | ||||||
|  |  	 * turn off everything else */ | ||||||
|  |  	void (*power_suspend)(struct platform_device *pdev); | ||||||
|  |  	int (*pre_setup)(struct usb_hcd *hcd); | ||||||
|  | +	void (*reset_notifier)(struct platform_device *pdev); | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  #endif /* __USB_CORE_EHCI_PDRIVER_H */ | ||||||
|  | --- a/drivers/usb/host/ehci-platform.c | ||||||
|  | +++ b/drivers/usb/host/ehci-platform.c | ||||||
|  | @@ -48,6 +48,14 @@ struct ehci_platform_priv { | ||||||
|  |   | ||||||
|  |  static const char hcd_name[] = "ehci-platform"; | ||||||
|  |   | ||||||
|  | +static void ehci_platform_reset_notifier(struct usb_hcd *hcd) | ||||||
|  | +{ | ||||||
|  | +	struct platform_device *pdev = to_platform_device(hcd->self.controller); | ||||||
|  | +	struct usb_ehci_pdata *pdata = pdev->dev.platform_data; | ||||||
|  | + | ||||||
|  | +	pdata->reset_notifier(pdev); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  static int ehci_platform_reset(struct usb_hcd *hcd) | ||||||
|  |  { | ||||||
|  |  	struct platform_device *pdev = to_platform_device(hcd->self.controller); | ||||||
|  | @@ -215,6 +223,13 @@ static int ehci_platform_probe(struct pl | ||||||
|  |  		priv->reset_on_resume = true; | ||||||
|  |  	if (pdata->ignore_oc) | ||||||
|  |  		ehci->ignore_oc = 1; | ||||||
|  | +	if (pdata->qca_force_host_mode) | ||||||
|  | +		ehci->qca_force_host_mode = 1; | ||||||
|  | +	if (pdata->qca_force_16bit_ptw) | ||||||
|  | +		ehci->qca_force_16bit_ptw = 1; | ||||||
|  | + | ||||||
|  | +	if (pdata->reset_notifier) | ||||||
|  | +		ehci->reset_notifier = ehci_platform_reset_notifier; | ||||||
|  |   | ||||||
|  |  #ifndef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO | ||||||
|  |  	if (ehci->big_endian_mmio) { | ||||||
| @@ -0,0 +1,32 @@ | |||||||
|  | --- a/drivers/net/phy/mdio-bitbang.c | ||||||
|  | +++ b/drivers/net/phy/mdio-bitbang.c | ||||||
|  | @@ -155,7 +155,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); | ||||||
|  | @@ -165,19 +165,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); | ||||||
| @@ -0,0 +1,61 @@ | |||||||
|  | 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 | ||||||
|  | @@ -17,6 +17,7 @@ | ||||||
|  |   * kind, whether express or implied. | ||||||
|  |   */ | ||||||
|  |   | ||||||
|  | +#include <linux/irqflags.h> | ||||||
|  |  #include <linux/module.h> | ||||||
|  |  #include <linux/mdio-bitbang.h> | ||||||
|  |  #include <linux/types.h> | ||||||
|  | @@ -156,7 +157,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); | ||||||
|  | @@ -169,13 +172,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); | ||||||
|  | @@ -190,6 +197,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; | ||||||
|  |  } | ||||||
|  |   | ||||||
							
								
								
									
										891
									
								
								target/linux/ath79/patches-4.19/910-unaligned_access_hacks.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										891
									
								
								target/linux/ath79/patches-4.19/910-unaligned_access_hacks.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,891 @@ | |||||||
|  | --- 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 | ||||||
|  | @@ -262,8 +262,8 @@ static bool ipv4_pkt_to_tuple(const stru | ||||||
|  |   | ||||||
|  |  	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 | ||||||
|  | @@ -39,6 +39,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> | ||||||
|  | @@ -836,10 +837,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 | ||||||
|  | @@ -477,7 +477,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; | ||||||
|  |  		} | ||||||
|  | @@ -829,12 +829,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/ip6_gre.c | ||||||
|  | +++ b/net/ipv6/ip6_gre.c | ||||||
|  | @@ -452,7 +452,7 @@ static void ip6gre_err(struct sk_buff *s | ||||||
|  |  		return; | ||||||
|  |  	ipv6h = (const struct ipv6hdr *)skb->data; | ||||||
|  |  	greh = (const struct gre_base_hdr *)(skb->data + offset); | ||||||
|  | -	key = key_off ? *(__be32 *)(skb->data + key_off) : 0; | ||||||
|  | +	key = key_off ? net_hdr_word((__be32 *)(skb->data + key_off)) : 0; | ||||||
|  |   | ||||||
|  |  	t = ip6gre_tunnel_lookup(skb->dev, &ipv6h->daddr, &ipv6h->saddr, | ||||||
|  |  				 key, greh->protocol); | ||||||
|  | --- a/net/ipv6/exthdrs.c | ||||||
|  | +++ b/net/ipv6/exthdrs.c | ||||||
|  | @@ -756,7 +756,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 | ||||||
|  | @@ -230,5 +230,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 | ||||||
|  | @@ -1422,8 +1422,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/route.c | ||||||
|  | +++ b/net/ipv4/route.c | ||||||
|  | @@ -448,7 +448,7 @@ static struct neighbour *ipv4_neigh_look | ||||||
|  |  	else if (skb) | ||||||
|  |  		pkey = &ip_hdr(skb)->daddr; | ||||||
|  |   | ||||||
|  | -	n = __ipv4_neigh_lookup(dev, *(__force u32 *)pkey); | ||||||
|  | +	n = __ipv4_neigh_lookup(dev, net_hdr_word(pkey)); | ||||||
|  |  	if (n) | ||||||
|  |  		return n; | ||||||
|  |  	return neigh_create(&arp_tbl, pkey, dev); | ||||||
|  | --- a/net/ipv4/tcp_output.c | ||||||
|  | +++ b/net/ipv4/tcp_output.c | ||||||
|  | @@ -461,48 +461,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)) { | ||||||
|  | @@ -510,16 +515,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; | ||||||
|  | @@ -532,13 +538,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 | ||||||
|  | @@ -111,7 +111,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 | ||||||
|  | @@ -89,7 +89,7 @@ struct ra_msg { | ||||||
|  |          struct icmp6hdr		icmph; | ||||||
|  |  	__be32			reachable_time; | ||||||
|  |  	__be32			retrans_timer; | ||||||
|  | -}; | ||||||
|  | +} __attribute__((packed, aligned(2))); | ||||||
|  |   | ||||||
|  |  struct rd_msg { | ||||||
|  |  	struct icmp6hdr icmph; | ||||||
|  | @@ -368,10 +368,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 | ||||||
|  | @@ -165,7 +165,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; | ||||||
|  |  			} | ||||||
|  | @@ -218,8 +218,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 | ||||||
|  | @@ -223,7 +223,7 @@ static struct sk_buff **ipv6_gro_receive | ||||||
|  |  			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/netdevice.h> | ||||||
|  |  #include <net/if_inet6.h> | ||||||
|  | --- a/include/net/inet_ecn.h | ||||||
|  | +++ b/include/net/inet_ecn.h | ||||||
|  | @@ -125,9 +125,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 | ||||||
|  | @@ -149,7 +149,7 @@ struct frag_hdr { | ||||||
|  |  	__u8	reserved; | ||||||
|  |  	__be16	frag_off; | ||||||
|  |  	__be32	identification; | ||||||
|  | -}; | ||||||
|  | +} __attribute__((packed, aligned(2))); | ||||||
|  |   | ||||||
|  |  #define	IP6_MF		0x0001 | ||||||
|  |  #define	IP6_OFFSET	0xFFF8 | ||||||
|  | @@ -499,8 +499,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, | ||||||
|  | @@ -559,6 +559,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; | ||||||
|  | @@ -567,7 +569,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; | ||||||
|  | @@ -683,13 +687,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)); | ||||||
|  |  	} | ||||||
|  | @@ -876,17 +880,18 @@ static inline int ip6_default_np_autolab | ||||||
|  |  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 | ||||||
|  | @@ -142,7 +142,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) | ||||||
|  | --- a/net/netfilter/nf_conntrack_proto_tcp.c | ||||||
|  | +++ b/net/netfilter/nf_conntrack_proto_tcp.c | ||||||
|  | @@ -423,7 +423,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 | ||||||
|  | @@ -194,8 +194,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 | ||||||
|  | @@ -3898,14 +3898,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 | ||||||
|  | @@ -66,9 +66,9 @@ static void dump_ipv6_packet(struct nf_l | ||||||
|  |  	/* 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 | ||||||
|  | @@ -266,8 +266,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 | ||||||
|  | @@ -447,8 +447,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 | ||||||
|  | @@ -480,7 +480,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. | ||||||
|  | @@ -503,11 +503,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 | ||||||
|  | @@ -226,7 +226,7 @@ struct sk_buff **tcp_gro_receive(struct | ||||||
|  |   | ||||||
|  |  		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; | ||||||
|  |  		} | ||||||
|  | @@ -244,8 +244,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 | ||||||
|  | @@ -50,7 +50,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); | ||||||
|  |   | ||||||
|  | @@ -59,7 +59,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, skb); | ||||||
|  |  		if (err < 0) | ||||||
|  |  			ret = NF_DROP_ERR(err); | ||||||
		Reference in New Issue
	
	Block a user