mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-27 01:11:14 +00:00
f5919b65d4
Patch generation process: - rebase rpi/rpi-4.14.y on v4.14.89 from linux-stable - git format-patch v4.14.89 Patches skipped during rebase: - lan78xx: Read MAC address from DT if present - lan78xx: Enable LEDs and auto-negotiation - Revert "softirq: Let ksoftirqd do its job" - sc16is7xx: Fix for multi-channel stall - lan78xx: Ignore DT MAC address if already valid - lan78xx: Simple patch to prevent some crashes - tcp_write_queue_purge clears all the SKBs in the write queue - Revert "lan78xx: Simple patch to prevent some crashes" - lan78xx: Connect phy early - Arm: mm: ftrace: Only set text back to ro after kernel has been marked ro - Revert "Revert "softirq: Let ksoftirqd do its job"" - ASoC: cs4265: SOC_SINGLE register value error fix - Revert "ASoC: cs4265: SOC_SINGLE register value error fix" - Revert "net: pskb_trim_rcsum() and CHECKSUM_COMPLETE are friends" - Revert "Revert "net: pskb_trim_rcsum() and CHECKSUM_COMPLETE are friends"" Patches dropped after rebase: - net: Add non-mainline source for rtl8192cu wlan - net: Fix rtl8192cu build errors on other platforms - brcm: adds support for BCM43341 wifi - brcmfmac: Mute expected startup 'errors' - ARM64: Fix build break for RTL8187/RTL8192CU wifi - ARM64: Enable RTL8187/RTL8192CU wifi in build config - This is the driver for Sony CXD2880 DVB-T2/T tuner + demodulator - brcmfmac: add CLM download support - brcmfmac: request_firmware_direct is quieter - Sets the BCDC priority to constant 0 - brcmfmac: Disable ARP offloading when promiscuous - brcmfmac: Avoid possible out-of-bounds read - brcmfmac: Delete redundant length check - net: rtl8192cu: Normalize indentation - net: rtl8192cu: Fix implicit fallthrough warnings - Revert "Sets the BCDC priority to constant 0" - media: cxd2880: Bump to match 4.18.y version - media: cxd2880-spi: Bump to match 4.18.y version - Revert "mm: alloc_contig: re-allow CMA to compact FS pages" - Revert "Revert "mm: alloc_contig: re-allow CMA to compact FS pages"" - cxd2880: CXD2880_SPI_DRV should select DVB_CXD2880 with MEDIA_SUBDRV_AUTOSELECT - 950-0421-HID-hid-bigbenff-driver-for-BigBen-Interactive-PS3OF.patch - 950-0453-Add-hid-bigbenff-to-list-of-have_special_driver-for-.patch Make I2C built-in instead of modular as in upstream defconfig; also the easiest way to get MFD_ARIZONA enabled, which is required by kmod-sound-soc-rpi-cirrus. Add missing compatible strings from 4.9/960-add-rasbperrypi-compatible.patch, using upstream names for compute modules. Add extra patch to enable the LEDs on lan78xx. Compile-tested: bcm2708, bcm2709, bcm2710 (with CONFIG_ALL_KMODS=y) Runtime-tested: bcm2708, bcm2710 Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
330 lines
8.2 KiB
Diff
330 lines
8.2 KiB
Diff
From c9a1f4547556a531c4fd61ccde08391ec0ad390c Mon Sep 17 00:00:00 2001
|
|
From: Michael Zoran <mzoran@crowfest.net>
|
|
Date: Sat, 14 Jan 2017 21:33:51 -0800
|
|
Subject: [PATCH 102/454] ARM64/DWC_OTG: Port dwc_otg driver to ARM64
|
|
|
|
In ARM64, the FIQ mechanism used by this driver is not current
|
|
implemented. As a workaround, reqular IRQ is used instead
|
|
of FIQ.
|
|
|
|
In a separate change, the IRQ-CPU mapping is round robined
|
|
on ARM64 to increase concurrency and allow multiple interrupts
|
|
to be serviced at a time. This reduces the need for FIQ.
|
|
|
|
Tests Run:
|
|
|
|
This mechanism is most likely to break when multiple USB devices
|
|
are attached at the same time. So the system was tested under
|
|
stress.
|
|
|
|
Devices:
|
|
|
|
1. USB Speakers playing back a FLAC audio through VLC
|
|
at 96KHz.(Higher then typically, but supported on my speakers).
|
|
|
|
2. sftp transferring large files through the buildin ethernet
|
|
connection which is connected through USB.
|
|
|
|
3. Keyboard and mouse attached and being used.
|
|
|
|
Although I do occasionally hear some glitches, the music seems to
|
|
play quite well.
|
|
|
|
Signed-off-by: Michael Zoran <mzoran@crowfest.net>
|
|
---
|
|
drivers/usb/host/dwc_otg/Makefile | 3 +
|
|
drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c | 17 +++++
|
|
drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h | 24 +++++++
|
|
drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 4 ++
|
|
drivers/usb/host/dwc_otg/dwc_otg_hcd_if.h | 4 ++
|
|
drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 3 +-
|
|
drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 72 ++++++++++++++++++++
|
|
drivers/usb/host/dwc_otg/dwc_otg_os_dep.h | 2 +
|
|
8 files changed, 128 insertions(+), 1 deletion(-)
|
|
|
|
--- a/drivers/usb/host/dwc_otg/Makefile
|
|
+++ b/drivers/usb/host/dwc_otg/Makefile
|
|
@@ -37,7 +37,10 @@ dwc_otg-objs += dwc_otg_pcd_linux.o dwc_
|
|
dwc_otg-objs += dwc_otg_hcd.o dwc_otg_hcd_linux.o dwc_otg_hcd_intr.o dwc_otg_hcd_queue.o dwc_otg_hcd_ddma.o
|
|
dwc_otg-objs += dwc_otg_adp.o
|
|
dwc_otg-objs += dwc_otg_fiq_fsm.o
|
|
+ifneq ($(CONFIG_ARM64),y)
|
|
dwc_otg-objs += dwc_otg_fiq_stub.o
|
|
+endif
|
|
+
|
|
ifneq ($(CFI),)
|
|
dwc_otg-objs += dwc_otg_cfi.o
|
|
endif
|
|
--- a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c
|
|
+++ b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c
|
|
@@ -74,6 +74,21 @@ void notrace _fiq_print(enum fiq_debug_l
|
|
}
|
|
}
|
|
|
|
+
|
|
+#ifdef CONFIG_ARM64
|
|
+
|
|
+inline void fiq_fsm_spin_lock(fiq_lock_t *lock)
|
|
+{
|
|
+ spin_lock((spinlock_t *)lock);
|
|
+}
|
|
+
|
|
+inline void fiq_fsm_spin_unlock(fiq_lock_t *lock)
|
|
+{
|
|
+ spin_unlock((spinlock_t *)lock);
|
|
+}
|
|
+
|
|
+#else
|
|
+
|
|
/**
|
|
* fiq_fsm_spin_lock() - ARMv6+ bare bones spinlock
|
|
* Must be called with local interrupts and FIQ disabled.
|
|
@@ -121,6 +136,8 @@ inline void fiq_fsm_spin_unlock(fiq_lock
|
|
inline void fiq_fsm_spin_unlock(fiq_lock_t *lock) { }
|
|
#endif
|
|
|
|
+#endif
|
|
+
|
|
/**
|
|
* fiq_fsm_restart_channel() - Poke channel enable bit for a split transaction
|
|
* @channel: channel to re-enable
|
|
--- a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h
|
|
+++ b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h
|
|
@@ -127,6 +127,12 @@ enum fiq_debug_level {
|
|
FIQDBG_PORTHUB = (1 << 3),
|
|
};
|
|
|
|
+#ifdef CONFIG_ARM64
|
|
+
|
|
+typedef spinlock_t fiq_lock_t;
|
|
+
|
|
+#else
|
|
+
|
|
typedef struct {
|
|
union {
|
|
uint32_t slock;
|
|
@@ -137,6 +143,8 @@ typedef struct {
|
|
};
|
|
} fiq_lock_t;
|
|
|
|
+#endif
|
|
+
|
|
struct fiq_state;
|
|
|
|
extern void _fiq_print (enum fiq_debug_level dbg_lvl, volatile struct fiq_state *state, char *fmt, ...);
|
|
@@ -357,6 +365,22 @@ struct fiq_state {
|
|
struct fiq_channel_state channel[0];
|
|
};
|
|
|
|
+#ifdef CONFIG_ARM64
|
|
+
|
|
+#ifdef local_fiq_enable
|
|
+#undef local_fiq_enable
|
|
+#endif
|
|
+
|
|
+#ifdef local_fiq_disable
|
|
+#undef local_fiq_disable
|
|
+#endif
|
|
+
|
|
+extern void local_fiq_enable(void);
|
|
+
|
|
+extern void local_fiq_disable(void);
|
|
+
|
|
+#endif
|
|
+
|
|
extern void fiq_fsm_spin_lock(fiq_lock_t *lock);
|
|
|
|
extern void fiq_fsm_spin_unlock(fiq_lock_t *lock);
|
|
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
|
|
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
|
|
@@ -1000,6 +1000,10 @@ int dwc_otg_hcd_init(dwc_otg_hcd_t * hcd
|
|
}
|
|
DWC_MEMSET(hcd->fiq_state, 0, (sizeof(struct fiq_state) + (sizeof(struct fiq_channel_state) * num_channels)));
|
|
|
|
+#ifdef CONFIG_ARM64
|
|
+ spin_lock_init(&hcd->fiq_state->lock);
|
|
+#endif
|
|
+
|
|
for (i = 0; i < num_channels; i++) {
|
|
hcd->fiq_state->channel[i].fsm = FIQ_PASSTHROUGH;
|
|
}
|
|
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_if.h
|
|
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_if.h
|
|
@@ -116,7 +116,11 @@ extern int32_t dwc_otg_hcd_handle_intr(d
|
|
/** This function is used to handle the fast interrupt
|
|
*
|
|
*/
|
|
+#ifdef CONFIG_ARM64
|
|
+extern void dwc_otg_hcd_handle_fiq(void);
|
|
+#else
|
|
extern void __attribute__ ((naked)) dwc_otg_hcd_handle_fiq(void);
|
|
+#endif
|
|
|
|
/**
|
|
* Returns private data set by
|
|
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
|
|
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
|
|
@@ -36,8 +36,9 @@
|
|
#include "dwc_otg_regs.h"
|
|
|
|
#include <linux/jiffies.h>
|
|
+#ifdef CONFIG_ARM
|
|
#include <asm/fiq.h>
|
|
-
|
|
+#endif
|
|
|
|
extern bool microframe_schedule;
|
|
|
|
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
|
|
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
|
|
@@ -51,7 +51,9 @@
|
|
#include <linux/dma-mapping.h>
|
|
#include <linux/version.h>
|
|
#include <asm/io.h>
|
|
+#ifdef CONFIG_ARM
|
|
#include <asm/fiq.h>
|
|
+#endif
|
|
#include <linux/usb.h>
|
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35)
|
|
#include <../drivers/usb/core/hcd.h>
|
|
@@ -71,6 +73,13 @@
|
|
#include "dwc_otg_driver.h"
|
|
#include "dwc_otg_hcd.h"
|
|
|
|
+#ifndef __virt_to_bus
|
|
+#define __virt_to_bus __virt_to_phys
|
|
+#define __bus_to_virt __phys_to_virt
|
|
+#define __pfn_to_bus(x) __pfn_to_phys(x)
|
|
+#define __bus_to_pfn(x) __phys_to_pfn(x)
|
|
+#endif
|
|
+
|
|
extern unsigned char _dwc_otg_fiq_stub, _dwc_otg_fiq_stub_end;
|
|
|
|
/**
|
|
@@ -395,14 +404,49 @@ static struct dwc_otg_hcd_function_ops h
|
|
.get_b_hnp_enable = _get_b_hnp_enable,
|
|
};
|
|
|
|
+#ifdef CONFIG_ARM64
|
|
+
|
|
+static int simfiq_irq = -1;
|
|
+
|
|
+void local_fiq_enable(void)
|
|
+{
|
|
+ if (simfiq_irq >= 0)
|
|
+ enable_irq(simfiq_irq);
|
|
+}
|
|
+
|
|
+void local_fiq_disable(void)
|
|
+{
|
|
+ if (simfiq_irq >= 0)
|
|
+ disable_irq(simfiq_irq);
|
|
+}
|
|
+
|
|
+irqreturn_t fiq_irq_handler(int irq, void *dev_id)
|
|
+{
|
|
+ dwc_otg_hcd_t *dwc_otg_hcd = (dwc_otg_hcd_t *)dev_id;
|
|
+
|
|
+ if (fiq_fsm_enable)
|
|
+ dwc_otg_fiq_fsm(dwc_otg_hcd->fiq_state, dwc_otg_hcd->core_if->core_params->host_channels);
|
|
+ else
|
|
+ dwc_otg_fiq_nop(dwc_otg_hcd->fiq_state);
|
|
+
|
|
+ return IRQ_HANDLED;
|
|
+}
|
|
+
|
|
+#else
|
|
static struct fiq_handler fh = {
|
|
.name = "usb_fiq",
|
|
};
|
|
|
|
+#endif
|
|
+
|
|
static void hcd_init_fiq(void *cookie)
|
|
{
|
|
dwc_otg_device_t *otg_dev = cookie;
|
|
dwc_otg_hcd_t *dwc_otg_hcd = otg_dev->hcd;
|
|
+#ifdef CONFIG_ARM64
|
|
+ int retval = 0;
|
|
+ int irq;
|
|
+#else
|
|
struct pt_regs regs;
|
|
int irq;
|
|
|
|
@@ -430,6 +474,7 @@ static void hcd_init_fiq(void *cookie)
|
|
|
|
// __show_regs(®s);
|
|
set_fiq_regs(®s);
|
|
+#endif
|
|
|
|
//Set the mphi periph to the required registers
|
|
dwc_otg_hcd->fiq_state->mphi_regs.base = otg_dev->os_dep.mphi_base;
|
|
@@ -448,6 +493,23 @@ static void hcd_init_fiq(void *cookie)
|
|
DWC_WARN("MPHI periph has NOT been enabled");
|
|
#endif
|
|
// Enable FIQ interrupt from USB peripheral
|
|
+#ifdef CONFIG_ARM64
|
|
+ irq = platform_get_irq(otg_dev->os_dep.platformdev, 1);
|
|
+
|
|
+ if (irq < 0) {
|
|
+ DWC_ERROR("Can't get SIM-FIQ irq");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ retval = request_irq(irq, fiq_irq_handler, 0, "dwc_otg_sim-fiq", dwc_otg_hcd);
|
|
+
|
|
+ if (retval < 0) {
|
|
+ DWC_ERROR("Unable to request SIM-FIQ irq\n");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ simfiq_irq = irq;
|
|
+#else
|
|
#ifdef CONFIG_MULTI_IRQ_HANDLER
|
|
irq = platform_get_irq(otg_dev->os_dep.platformdev, 1);
|
|
#else
|
|
@@ -459,6 +521,8 @@ static void hcd_init_fiq(void *cookie)
|
|
}
|
|
enable_fiq(irq);
|
|
local_fiq_enable();
|
|
+#endif
|
|
+
|
|
}
|
|
|
|
/**
|
|
@@ -521,6 +585,13 @@ int hcd_init(dwc_bus_dev_t *_dev)
|
|
otg_dev->hcd = dwc_otg_hcd;
|
|
otg_dev->hcd->otg_dev = otg_dev;
|
|
|
|
+#ifdef CONFIG_ARM64
|
|
+ if (dwc_otg_hcd_init(dwc_otg_hcd, otg_dev->core_if))
|
|
+ goto error2;
|
|
+
|
|
+ if (fiq_enable)
|
|
+ hcd_init_fiq(otg_dev);
|
|
+#else
|
|
if (dwc_otg_hcd_init(dwc_otg_hcd, otg_dev->core_if)) {
|
|
goto error2;
|
|
}
|
|
@@ -533,6 +604,7 @@ int hcd_init(dwc_bus_dev_t *_dev)
|
|
smp_call_function_single(0, hcd_init_fiq, otg_dev, 1);
|
|
}
|
|
}
|
|
+#endif
|
|
|
|
hcd->self.otg_port = dwc_otg_hcd_otg_port(dwc_otg_hcd);
|
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33) //don't support for LM(with 2.6.20.1 kernel)
|
|
--- a/drivers/usb/host/dwc_otg/dwc_otg_os_dep.h
|
|
+++ b/drivers/usb/host/dwc_otg/dwc_otg_os_dep.h
|
|
@@ -76,8 +76,10 @@
|
|
|
|
#ifdef PLATFORM_INTERFACE
|
|
#include <linux/platform_device.h>
|
|
+#ifdef CONFIG_ARM
|
|
#include <asm/mach/map.h>
|
|
#endif
|
|
+#endif
|
|
|
|
/** The OS page size */
|
|
#define DWC_OS_PAGE_SIZE PAGE_SIZE
|