mirror of https://github.com/hak5/openwrt-owl.git
brcm2708: update against latest rpi-3.10.y branch
Update our copies of the brcm2708 patches to the latest rpi-3.10-y rebased against linux-3.10.y stable (3.10.32). This should hopefully make it easier for us in the future to leverage the raspberry/rpi-* branches. Signed-off-by: Florian Fainelli <florian@openwrt.org> SVN-Revision: 39770owl
parent
c6c0d09f85
commit
bb39b8d99a
|
@ -201,6 +201,7 @@ CONFIG_POWER_SUPPLY=y
|
|||
CONFIG_PRINTK_TIME=y
|
||||
CONFIG_PROC_PAGE_MONITOR=y
|
||||
CONFIG_RAW_DRIVER=y
|
||||
# CONFIG_RTL8192CU is not set
|
||||
CONFIG_SCSI=y
|
||||
# CONFIG_SCSI_LOWLEVEL is not set
|
||||
# CONFIG_SCSI_PROC_FS is not set
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,3 +1,41 @@
|
|||
From dd611b3364087514ef5fc59c6106d8924d2a2a30 Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Wed, 1 May 2013 19:54:32 +0100
|
||||
Subject: [PATCH 003/174] bcm2708 watchdog driver
|
||||
|
||||
Signed-off-by: popcornmix <popcornmix@gmail.com>
|
||||
---
|
||||
drivers/watchdog/Kconfig | 6 +
|
||||
drivers/watchdog/Makefile | 1 +
|
||||
drivers/watchdog/bcm2708_wdog.c | 385 ++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 392 insertions(+)
|
||||
create mode 100644 drivers/watchdog/bcm2708_wdog.c
|
||||
|
||||
--- a/drivers/watchdog/Kconfig
|
||||
+++ b/drivers/watchdog/Kconfig
|
||||
@@ -391,6 +391,12 @@ config RETU_WATCHDOG
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called retu_wdt.
|
||||
|
||||
+config BCM2708_WDT
|
||||
+ tristate "BCM2708 Watchdog"
|
||||
+ depends on ARCH_BCM2708
|
||||
+ help
|
||||
+ Enables BCM2708 watchdog support.
|
||||
+
|
||||
# AVR32 Architecture
|
||||
|
||||
config AT32AP700X_WDT
|
||||
--- a/drivers/watchdog/Makefile
|
||||
+++ b/drivers/watchdog/Makefile
|
||||
@@ -54,6 +54,7 @@ obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_
|
||||
obj-$(CONFIG_IMX2_WDT) += imx2_wdt.o
|
||||
obj-$(CONFIG_UX500_WATCHDOG) += ux500_wdt.o
|
||||
obj-$(CONFIG_RETU_WATCHDOG) += retu_wdt.o
|
||||
+obj-$(CONFIG_BCM2708_WDT) += bcm2708_wdog.o
|
||||
|
||||
# AVR32 Architecture
|
||||
obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/watchdog/bcm2708_wdog.c
|
||||
@@ -0,0 +1,385 @@
|
||||
|
@ -386,28 +424,3 @@
|
|||
+MODULE_ALIAS_MISCDEV(TEMP_MINOR);
|
||||
+MODULE_LICENSE("GPL");
|
||||
+
|
||||
--- a/drivers/watchdog/Kconfig
|
||||
+++ b/drivers/watchdog/Kconfig
|
||||
@@ -391,6 +391,12 @@ config RETU_WATCHDOG
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called retu_wdt.
|
||||
|
||||
+config BCM2708_WDT
|
||||
+ tristate "BCM2708 Watchdog"
|
||||
+ depends on ARCH_BCM2708
|
||||
+ help
|
||||
+ Enables BCM2708 watchdog support.
|
||||
+
|
||||
# AVR32 Architecture
|
||||
|
||||
config AT32AP700X_WDT
|
||||
--- a/drivers/watchdog/Makefile
|
||||
+++ b/drivers/watchdog/Makefile
|
||||
@@ -54,6 +54,7 @@ obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_
|
||||
obj-$(CONFIG_IMX2_WDT) += imx2_wdt.o
|
||||
obj-$(CONFIG_UX500_WATCHDOG) += ux500_wdt.o
|
||||
obj-$(CONFIG_RETU_WATCHDOG) += retu_wdt.o
|
||||
+obj-$(CONFIG_BCM2708_WDT) += bcm2708_wdog.o
|
||||
|
||||
# AVR32 Architecture
|
||||
obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o
|
|
@ -1,6 +1,53 @@
|
|||
From c9fbd3932a41a14af51d04fb6f43c45d60e66f8c Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Wed, 1 May 2013 19:55:09 +0100
|
||||
Subject: [PATCH 004/174] bcm2708 framebuffer driver
|
||||
|
||||
Signed-off-by: popcornmix <popcornmix@gmail.com>
|
||||
---
|
||||
drivers/video/Kconfig | 14 +
|
||||
drivers/video/Makefile | 1 +
|
||||
drivers/video/bcm2708_fb.c | 491 ++++++
|
||||
drivers/video/logo/logo_linux_clut224.ppm | 2483 ++++++++++-------------------
|
||||
4 files changed, 1387 insertions(+), 1602 deletions(-)
|
||||
create mode 100644 drivers/video/bcm2708_fb.c
|
||||
|
||||
--- a/drivers/video/Kconfig
|
||||
+++ b/drivers/video/Kconfig
|
||||
@@ -310,6 +310,20 @@ config FB_PM2_FIFO_DISCONNECT
|
||||
help
|
||||
Support the Permedia2 FIFO disconnect feature.
|
||||
|
||||
+config FB_BCM2708
|
||||
+ tristate "BCM2708 framebuffer support"
|
||||
+ depends on FB && ARM
|
||||
+ select FB_CFB_FILLRECT
|
||||
+ select FB_CFB_COPYAREA
|
||||
+ select FB_CFB_IMAGEBLIT
|
||||
+ help
|
||||
+ This framebuffer device driver is for the BCM2708 framebuffer.
|
||||
+
|
||||
+ If you want to compile this as a module (=code which can be
|
||||
+ inserted into and removed from the running kernel), say M
|
||||
+ here and read <file:Documentation/kbuild/modules.txt>. The module
|
||||
+ will be called bcm2708_fb.
|
||||
+
|
||||
config FB_ARMCLCD
|
||||
tristate "ARM PrimeCell PL110 support"
|
||||
depends on FB && ARM && ARM_AMBA
|
||||
--- a/drivers/video/Makefile
|
||||
+++ b/drivers/video/Makefile
|
||||
@@ -100,6 +100,7 @@ obj-$(CONFIG_FB_PVR2) += pvr
|
||||
obj-$(CONFIG_FB_VOODOO1) += sstfb.o
|
||||
obj-$(CONFIG_FB_ARMCLCD) += amba-clcd.o
|
||||
obj-$(CONFIG_FB_GOLDFISH) += goldfishfb.o
|
||||
+obj-$(CONFIG_FB_BCM2708) += bcm2708_fb.o
|
||||
obj-$(CONFIG_FB_68328) += 68328fb.o
|
||||
obj-$(CONFIG_FB_GBE) += gbefb.o
|
||||
obj-$(CONFIG_FB_CIRRUS) += cirrusfb.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/video/bcm2708_fb.c
|
||||
@@ -0,0 +1,647 @@
|
||||
@@ -0,0 +1,491 @@
|
||||
+/*
|
||||
+ * linux/drivers/video/bcm2708_fb.c
|
||||
+ *
|
||||
|
@ -31,7 +78,6 @@
|
|||
+#include <linux/printk.h>
|
||||
+#include <linux/console.h>
|
||||
+
|
||||
+#include <mach/dma.h>
|
||||
+#include <mach/platform.h>
|
||||
+#include <mach/vcio.h>
|
||||
+
|
||||
|
@ -67,11 +113,6 @@
|
|||
+ struct fbinfo_s *info;
|
||||
+ dma_addr_t dma;
|
||||
+ u32 cmap[16];
|
||||
+ int dma_chan;
|
||||
+ int dma_irq;
|
||||
+ void __iomem *dma_chan_base;
|
||||
+ void *cb_base; /* DMA control blocks */
|
||||
+ dma_addr_t cb_handle;
|
||||
+};
|
||||
+
|
||||
+#define to_bcm2708(info) container_of(info, struct bcm2708_fb, fb)
|
||||
|
@ -321,133 +362,11 @@
|
|||
+ cfb_fillrect(info, rect);
|
||||
+}
|
||||
+
|
||||
+/* A helper function for configuring dma control block */
|
||||
+static void set_dma_cb(struct bcm2708_dma_cb *cb,
|
||||
+ int burst_size,
|
||||
+ dma_addr_t dst,
|
||||
+ int dst_stride,
|
||||
+ dma_addr_t src,
|
||||
+ int src_stride,
|
||||
+ int w,
|
||||
+ int h)
|
||||
+{
|
||||
+ cb->info = BCM2708_DMA_BURST(burst_size) | BCM2708_DMA_S_WIDTH |
|
||||
+ BCM2708_DMA_S_INC | BCM2708_DMA_D_WIDTH |
|
||||
+ BCM2708_DMA_D_INC | BCM2708_DMA_TDMODE;
|
||||
+ cb->dst = dst;
|
||||
+ cb->src = src;
|
||||
+ /*
|
||||
+ * This is not really obvious from the DMA documentation,
|
||||
+ * but the top 16 bits must be programmmed to "height -1"
|
||||
+ * and not "height" in 2D mode.
|
||||
+ */
|
||||
+ cb->length = ((h - 1) << 16) | w;
|
||||
+ cb->stride = ((dst_stride - w) << 16) | (u16)(src_stride - w);
|
||||
+ cb->pad[0] = 0;
|
||||
+ cb->pad[1] = 0;
|
||||
+}
|
||||
+
|
||||
+static void bcm2708_fb_copyarea(struct fb_info *info,
|
||||
+ const struct fb_copyarea *region)
|
||||
+{
|
||||
+ struct bcm2708_fb *fb = to_bcm2708(info);
|
||||
+ struct bcm2708_dma_cb *cb = fb->cb_base;
|
||||
+ int bytes_per_pixel = (info->var.bits_per_pixel + 7) >> 3;
|
||||
+ /* Channel 0 supports larger bursts and is a bit faster */
|
||||
+ int burst_size = (fb->dma_chan == 0) ? 8 : 2;
|
||||
+
|
||||
+ /* Fallback to cfb_copyarea() if we don't like something */
|
||||
+ if (bytes_per_pixel > 4 ||
|
||||
+ info->var.xres > 1920 || info->var.yres > 1200 ||
|
||||
+ region->width <= 0 || region->width > info->var.xres ||
|
||||
+ region->height <= 0 || region->height > info->var.yres ||
|
||||
+ region->sx < 0 || region->sx >= info->var.xres ||
|
||||
+ region->sy < 0 || region->sy >= info->var.yres ||
|
||||
+ region->dx < 0 || region->dx >= info->var.xres ||
|
||||
+ region->dy < 0 || region->dy >= info->var.yres ||
|
||||
+ region->sx + region->width > info->var.xres ||
|
||||
+ region->dx + region->width > info->var.xres ||
|
||||
+ region->sy + region->height > info->var.yres ||
|
||||
+ region->dy + region->height > info->var.yres) {
|
||||
+ cfb_copyarea(info, region);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (region->dy == region->sy && region->dx > region->sx) {
|
||||
+ /*
|
||||
+ * A difficult case of overlapped copy. Because DMA can't
|
||||
+ * copy individual scanlines in backwards direction, we need
|
||||
+ * two-pass processing. We do it by programming a chain of dma
|
||||
+ * control blocks in the first 16K part of the buffer and use
|
||||
+ * the remaining 48K as the intermediate temporary scratch
|
||||
+ * buffer. The buffer size is sufficient to handle up to
|
||||
+ * 1920x1200 resolution at 32bpp pixel depth.
|
||||
+ */
|
||||
+ int y;
|
||||
+ dma_addr_t control_block_pa = fb->cb_handle;
|
||||
+ dma_addr_t scratchbuf = fb->cb_handle + 16 * 1024;
|
||||
+ int scanline_size = bytes_per_pixel * region->width;
|
||||
+ int scanlines_per_cb = (64 * 1024 - 16 * 1024) / scanline_size;
|
||||
+
|
||||
+ for (y = 0; y < region->height; y += scanlines_per_cb) {
|
||||
+ dma_addr_t src =
|
||||
+ fb->fb.fix.smem_start +
|
||||
+ bytes_per_pixel * region->sx +
|
||||
+ (region->sy + y) * fb->fb.fix.line_length;
|
||||
+ dma_addr_t dst =
|
||||
+ fb->fb.fix.smem_start +
|
||||
+ bytes_per_pixel * region->dx +
|
||||
+ (region->dy + y) * fb->fb.fix.line_length;
|
||||
+
|
||||
+ if (region->height - y < scanlines_per_cb)
|
||||
+ scanlines_per_cb = region->height - y;
|
||||
+
|
||||
+ set_dma_cb(cb, burst_size, scratchbuf, scanline_size,
|
||||
+ src, fb->fb.fix.line_length,
|
||||
+ scanline_size, scanlines_per_cb);
|
||||
+ control_block_pa += sizeof(struct bcm2708_dma_cb);
|
||||
+ cb->next = control_block_pa;
|
||||
+ cb++;
|
||||
+
|
||||
+ set_dma_cb(cb, burst_size, dst, fb->fb.fix.line_length,
|
||||
+ scratchbuf, scanline_size,
|
||||
+ scanline_size, scanlines_per_cb);
|
||||
+ control_block_pa += sizeof(struct bcm2708_dma_cb);
|
||||
+ cb->next = control_block_pa;
|
||||
+ cb++;
|
||||
+ }
|
||||
+ /* move the pointer back to the last dma control block */
|
||||
+ cb--;
|
||||
+ } else {
|
||||
+ /* A single dma control block is enough. */
|
||||
+ int sy, dy, stride;
|
||||
+ if (region->dy <= region->sy) {
|
||||
+ /* processing from top to bottom */
|
||||
+ dy = region->dy;
|
||||
+ sy = region->sy;
|
||||
+ stride = fb->fb.fix.line_length;
|
||||
+ } else {
|
||||
+ /* processing from bottom to top */
|
||||
+ dy = region->dy + region->height - 1;
|
||||
+ sy = region->sy + region->height - 1;
|
||||
+ stride = -fb->fb.fix.line_length;
|
||||
+ }
|
||||
+ set_dma_cb(cb, burst_size,
|
||||
+ fb->fb.fix.smem_start + dy * fb->fb.fix.line_length +
|
||||
+ bytes_per_pixel * region->dx,
|
||||
+ stride,
|
||||
+ fb->fb.fix.smem_start + sy * fb->fb.fix.line_length +
|
||||
+ bytes_per_pixel * region->sx,
|
||||
+ stride,
|
||||
+ region->width * bytes_per_pixel,
|
||||
+ region->height);
|
||||
+ }
|
||||
+
|
||||
+ /* end of dma control blocks chain */
|
||||
+ cb->next = 0;
|
||||
+
|
||||
+ bcm_dma_start(fb->dma_chan_base, fb->cb_handle);
|
||||
+ bcm_dma_wait_idle(fb->dma_chan_base);
|
||||
+ /*print_debug("bcm2708_fb_copyarea\n"); */
|
||||
+ cfb_copyarea(info, region);
|
||||
+}
|
||||
+
|
||||
+static void bcm2708_fb_imageblit(struct fb_info *info,
|
||||
|
@ -490,7 +409,7 @@
|
|||
+ fb->dma = dma;
|
||||
+ }
|
||||
+ fb->fb.fbops = &bcm2708_fb_ops;
|
||||
+ fb->fb.flags = FBINFO_FLAG_DEFAULT | FBINFO_HWACCEL_COPYAREA;
|
||||
+ fb->fb.flags = FBINFO_FLAG_DEFAULT;
|
||||
+ fb->fb.pseudo_palette = fb->cmap;
|
||||
+
|
||||
+ strncpy(fb->fb.fix.id, bcm2708_name, sizeof(fb->fb.fix.id));
|
||||
|
@ -555,28 +474,6 @@
|
|||
+ }
|
||||
+ memset(fb, 0, sizeof(struct bcm2708_fb));
|
||||
+
|
||||
+ fb->cb_base = dma_alloc_writecombine(&dev->dev, SZ_64K,
|
||||
+ &fb->cb_handle, GFP_KERNEL);
|
||||
+ if (!fb->cb_base) {
|
||||
+ dev_err(&dev->dev, "cannot allocate DMA CBs\n");
|
||||
+ ret = -ENOMEM;
|
||||
+ goto free_fb;
|
||||
+ }
|
||||
+
|
||||
+ pr_info("BCM2708FB: allocated DMA memory %08x\n",
|
||||
+ fb->cb_handle);
|
||||
+
|
||||
+ ret = bcm_dma_chan_alloc(BCM_DMA_FEATURE_BULK,
|
||||
+ &fb->dma_chan_base, &fb->dma_irq);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(&dev->dev, "couldn't allocate a DMA channel\n");
|
||||
+ goto free_cb;
|
||||
+ }
|
||||
+ fb->dma_chan = ret;
|
||||
+
|
||||
+ pr_info("BCM2708FB: allocated DMA channel %d @ %p\n",
|
||||
+ fb->dma_chan, fb->dma_chan_base);
|
||||
+
|
||||
+ fb->dev = dev;
|
||||
+
|
||||
+ ret = bcm2708_fb_register(fb);
|
||||
|
@ -585,9 +482,6 @@
|
|||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+free_cb:
|
||||
+ dma_free_writecombine(&dev->dev, SZ_64K, fb->cb_base, fb->cb_handle);
|
||||
+free_fb:
|
||||
+ kfree(fb);
|
||||
+free_region:
|
||||
+ dev_err(&dev->dev, "probe failed, err %d\n", ret);
|
||||
|
@ -605,9 +499,6 @@
|
|||
+ iounmap(fb->fb.screen_base);
|
||||
+ unregister_framebuffer(&fb->fb);
|
||||
+
|
||||
+ dma_free_writecombine(&dev->dev, SZ_64K, fb->cb_base, fb->cb_handle);
|
||||
+ bcm_dma_chan_free(fb->dma_chan);
|
||||
+
|
||||
+ dma_free_coherent(NULL, PAGE_ALIGN(sizeof(*fb->info)), (void *)fb->info,
|
||||
+ fb->dma);
|
||||
+ kfree(fb);
|
||||
|
@ -648,264 +539,6 @@
|
|||
+MODULE_PARM_DESC(fbwidth, "Width of ARM Framebuffer");
|
||||
+MODULE_PARM_DESC(fbheight, "Height of ARM Framebuffer");
|
||||
+MODULE_PARM_DESC(fbdepth, "Bit depth of ARM Framebuffer");
|
||||
--- a/drivers/video/cfbimgblt.c
|
||||
+++ b/drivers/video/cfbimgblt.c
|
||||
@@ -28,6 +28,11 @@
|
||||
*
|
||||
* Also need to add code to deal with cards endians that are different than
|
||||
* the native cpu endians. I also need to deal with MSB position in the word.
|
||||
+ * Modified by Harm Hanemaaijer (fgenfb@yahoo.com) 2013:
|
||||
+ * - Provide optimized versions of fast_imageblit for 16 and 32bpp that are
|
||||
+ * significantly faster than the previous implementation.
|
||||
+ * - Simplify the fast/slow_imageblit selection code, avoiding integer
|
||||
+ * divides.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/string.h>
|
||||
@@ -262,6 +267,133 @@ static inline void fast_imageblit(const
|
||||
}
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Optimized fast_imageblit for bpp == 16. ppw = 2, bit_mask = 3 folded
|
||||
+ * into the code, main loop unrolled.
|
||||
+ */
|
||||
+
|
||||
+static inline void fast_imageblit16(const struct fb_image *image,
|
||||
+ struct fb_info *p, u8 __iomem * dst1,
|
||||
+ u32 fgcolor, u32 bgcolor)
|
||||
+{
|
||||
+ u32 fgx = fgcolor, bgx = bgcolor;
|
||||
+ u32 spitch = (image->width + 7) / 8;
|
||||
+ u32 end_mask, eorx;
|
||||
+ const char *s = image->data, *src;
|
||||
+ u32 __iomem *dst;
|
||||
+ const u32 *tab = NULL;
|
||||
+ int i, j, k;
|
||||
+
|
||||
+ tab = fb_be_math(p) ? cfb_tab16_be : cfb_tab16_le;
|
||||
+
|
||||
+ fgx <<= 16;
|
||||
+ bgx <<= 16;
|
||||
+ fgx |= fgcolor;
|
||||
+ bgx |= bgcolor;
|
||||
+
|
||||
+ eorx = fgx ^ bgx;
|
||||
+ k = image->width / 2;
|
||||
+
|
||||
+ for (i = image->height; i--;) {
|
||||
+ dst = (u32 __iomem *) dst1;
|
||||
+ src = s;
|
||||
+
|
||||
+ j = k;
|
||||
+ while (j >= 4) {
|
||||
+ u8 bits = *src;
|
||||
+ end_mask = tab[(bits >> 6) & 3];
|
||||
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
|
||||
+ end_mask = tab[(bits >> 4) & 3];
|
||||
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
|
||||
+ end_mask = tab[(bits >> 2) & 3];
|
||||
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
|
||||
+ end_mask = tab[bits & 3];
|
||||
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
|
||||
+ src++;
|
||||
+ j -= 4;
|
||||
+ }
|
||||
+ if (j != 0) {
|
||||
+ u8 bits = *src;
|
||||
+ end_mask = tab[(bits >> 6) & 3];
|
||||
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
|
||||
+ if (j >= 2) {
|
||||
+ end_mask = tab[(bits >> 4) & 3];
|
||||
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
|
||||
+ if (j == 3) {
|
||||
+ end_mask = tab[(bits >> 2) & 3];
|
||||
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ dst1 += p->fix.line_length;
|
||||
+ s += spitch;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Optimized fast_imageblit for bpp == 32. ppw = 1, bit_mask = 1 folded
|
||||
+ * into the code, main loop unrolled.
|
||||
+ */
|
||||
+
|
||||
+static inline void fast_imageblit32(const struct fb_image *image,
|
||||
+ struct fb_info *p, u8 __iomem * dst1,
|
||||
+ u32 fgcolor, u32 bgcolor)
|
||||
+{
|
||||
+ u32 fgx = fgcolor, bgx = bgcolor;
|
||||
+ u32 spitch = (image->width + 7) / 8;
|
||||
+ u32 end_mask, eorx;
|
||||
+ const char *s = image->data, *src;
|
||||
+ u32 __iomem *dst;
|
||||
+ const u32 *tab = NULL;
|
||||
+ int i, j, k;
|
||||
+
|
||||
+ tab = cfb_tab32;
|
||||
+
|
||||
+ eorx = fgx ^ bgx;
|
||||
+ k = image->width;
|
||||
+
|
||||
+ for (i = image->height; i--;) {
|
||||
+ dst = (u32 __iomem *) dst1;
|
||||
+ src = s;
|
||||
+
|
||||
+ j = k;
|
||||
+ while (j >= 8) {
|
||||
+ u8 bits = *src;
|
||||
+ end_mask = tab[(bits >> 7) & 1];
|
||||
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
|
||||
+ end_mask = tab[(bits >> 6) & 1];
|
||||
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
|
||||
+ end_mask = tab[(bits >> 5) & 1];
|
||||
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
|
||||
+ end_mask = tab[(bits >> 4) & 1];
|
||||
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
|
||||
+ end_mask = tab[(bits >> 3) & 1];
|
||||
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
|
||||
+ end_mask = tab[(bits >> 2) & 1];
|
||||
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
|
||||
+ end_mask = tab[(bits >> 1) & 1];
|
||||
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
|
||||
+ end_mask = tab[bits & 1];
|
||||
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
|
||||
+ src++;
|
||||
+ j -= 8;
|
||||
+ }
|
||||
+ if (j != 0) {
|
||||
+ u32 bits = (u32) * src;
|
||||
+ while (j > 1) {
|
||||
+ end_mask = tab[(bits >> 7) & 1];
|
||||
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
|
||||
+ bits <<= 1;
|
||||
+ j--;
|
||||
+ }
|
||||
+ end_mask = tab[(bits >> 7) & 1];
|
||||
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst);
|
||||
+ }
|
||||
+ dst1 += p->fix.line_length;
|
||||
+ s += spitch;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void cfb_imageblit(struct fb_info *p, const struct fb_image *image)
|
||||
{
|
||||
u32 fgcolor, bgcolor, start_index, bitstart, pitch_index = 0;
|
||||
@@ -294,11 +426,21 @@ void cfb_imageblit(struct fb_info *p, co
|
||||
bgcolor = image->bg_color;
|
||||
}
|
||||
|
||||
- if (32 % bpp == 0 && !start_index && !pitch_index &&
|
||||
- ((width & (32/bpp-1)) == 0) &&
|
||||
- bpp >= 8 && bpp <= 32)
|
||||
- fast_imageblit(image, p, dst1, fgcolor, bgcolor);
|
||||
- else
|
||||
+ if (!start_index && !pitch_index) {
|
||||
+ if (bpp == 32)
|
||||
+ fast_imageblit32(image, p, dst1, fgcolor,
|
||||
+ bgcolor);
|
||||
+ else if (bpp == 16 && (width & 1) == 0)
|
||||
+ fast_imageblit16(image, p, dst1, fgcolor,
|
||||
+ bgcolor);
|
||||
+ else if (bpp == 8 && (width & 3) == 0)
|
||||
+ fast_imageblit(image, p, dst1, fgcolor,
|
||||
+ bgcolor);
|
||||
+ else
|
||||
+ slow_imageblit(image, p, dst1, fgcolor,
|
||||
+ bgcolor,
|
||||
+ start_index, pitch_index);
|
||||
+ } else
|
||||
slow_imageblit(image, p, dst1, fgcolor, bgcolor,
|
||||
start_index, pitch_index);
|
||||
} else
|
||||
--- a/drivers/video/fbmem.c
|
||||
+++ b/drivers/video/fbmem.c
|
||||
@@ -1074,6 +1074,25 @@ fb_blank(struct fb_info *info, int blank
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int fb_copyarea_user(struct fb_info *info,
|
||||
+ struct fb_copyarea *copy)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+ if (!lock_fb_info(info))
|
||||
+ return -ENODEV;
|
||||
+ if (copy->dx + copy->width > info->var.xres ||
|
||||
+ copy->sx + copy->width > info->var.xres ||
|
||||
+ copy->dy + copy->height > info->var.yres ||
|
||||
+ copy->sy + copy->height > info->var.yres) {
|
||||
+ ret = -EINVAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ info->fbops->fb_copyarea(info, copy);
|
||||
+out:
|
||||
+ unlock_fb_info(info);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
@@ -1084,6 +1103,7 @@ static long do_fb_ioctl(struct fb_info *
|
||||
struct fb_cmap cmap_from;
|
||||
struct fb_cmap_user cmap;
|
||||
struct fb_event event;
|
||||
+ struct fb_copyarea copy;
|
||||
void __user *argp = (void __user *)arg;
|
||||
long ret = 0;
|
||||
|
||||
@@ -1193,6 +1213,15 @@ static long do_fb_ioctl(struct fb_info *
|
||||
console_unlock();
|
||||
unlock_fb_info(info);
|
||||
break;
|
||||
+ case FBIOCOPYAREA:
|
||||
+ if (info->flags & FBINFO_HWACCEL_COPYAREA) {
|
||||
+ /* only provide this ioctl if it is accelerated */
|
||||
+ if (copy_from_user(©, argp, sizeof(copy)))
|
||||
+ return -EFAULT;
|
||||
+ ret = fb_copyarea_user(info, ©);
|
||||
+ break;
|
||||
+ }
|
||||
+ /* fall through */
|
||||
default:
|
||||
if (!lock_fb_info(info))
|
||||
return -ENODEV;
|
||||
@@ -1345,6 +1374,7 @@ static long fb_compat_ioctl(struct file
|
||||
case FBIOPAN_DISPLAY:
|
||||
case FBIOGET_CON2FBMAP:
|
||||
case FBIOPUT_CON2FBMAP:
|
||||
+ case FBIOCOPYAREA:
|
||||
arg = (unsigned long) compat_ptr(arg);
|
||||
case FBIOBLANK:
|
||||
ret = do_fb_ioctl(info, cmd, arg);
|
||||
--- a/drivers/video/Kconfig
|
||||
+++ b/drivers/video/Kconfig
|
||||
@@ -310,6 +310,20 @@ config FB_PM2_FIFO_DISCONNECT
|
||||
help
|
||||
Support the Permedia2 FIFO disconnect feature.
|
||||
|
||||
+config FB_BCM2708
|
||||
+ tristate "BCM2708 framebuffer support"
|
||||
+ depends on FB && ARM
|
||||
+ select FB_CFB_FILLRECT
|
||||
+ select FB_CFB_COPYAREA
|
||||
+ select FB_CFB_IMAGEBLIT
|
||||
+ help
|
||||
+ This framebuffer device driver is for the BCM2708 framebuffer.
|
||||
+
|
||||
+ If you want to compile this as a module (=code which can be
|
||||
+ inserted into and removed from the running kernel), say M
|
||||
+ here and read <file:Documentation/kbuild/modules.txt>. The module
|
||||
+ will be called bcm2708_fb.
|
||||
+
|
||||
config FB_ARMCLCD
|
||||
tristate "ARM PrimeCell PL110 support"
|
||||
depends on FB && ARM && ARM_AMBA
|
||||
--- a/drivers/video/logo/logo_linux_clut224.ppm
|
||||
+++ b/drivers/video/logo/logo_linux_clut224.ppm
|
||||
@@ -1,1604 +1,883 @@
|
||||
|
@ -3394,27 +3027,3 @@
|
|||
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
+0 0 0 0 0 0 0 0 0
|
||||
--- a/drivers/video/Makefile
|
||||
+++ b/drivers/video/Makefile
|
||||
@@ -100,6 +100,7 @@ obj-$(CONFIG_FB_PVR2) += pvr
|
||||
obj-$(CONFIG_FB_VOODOO1) += sstfb.o
|
||||
obj-$(CONFIG_FB_ARMCLCD) += amba-clcd.o
|
||||
obj-$(CONFIG_FB_GOLDFISH) += goldfishfb.o
|
||||
+obj-$(CONFIG_FB_BCM2708) += bcm2708_fb.o
|
||||
obj-$(CONFIG_FB_68328) += 68328fb.o
|
||||
obj-$(CONFIG_FB_GBE) += gbefb.o
|
||||
obj-$(CONFIG_FB_CIRRUS) += cirrusfb.o
|
||||
--- a/include/uapi/linux/fb.h
|
||||
+++ b/include/uapi/linux/fb.h
|
||||
@@ -34,6 +34,11 @@
|
||||
#define FBIOPUT_MODEINFO 0x4617
|
||||
#define FBIOGET_DISPINFO 0x4618
|
||||
#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32)
|
||||
+/*
|
||||
+ * HACK: use 'z' in order not to clash with any other ioctl numbers which might
|
||||
+ * be concurrently added to the mainline kernel
|
||||
+ */
|
||||
+#define FBIOCOPYAREA _IOW('z', 0x21, struct fb_copyarea)
|
||||
|
||||
#define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */
|
||||
#define FB_TYPE_PLANES 1 /* Non interleaved planes */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,3 +1,13 @@
|
|||
From bd5ea6c71eb31d1c65f718a2938ea9a4272c8b8e Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Tue, 26 Mar 2013 17:26:38 +0000
|
||||
Subject: [PATCH 008/174] Allow mac address to be set in smsc95xx
|
||||
|
||||
Signed-off-by: popcornmix <popcornmix@gmail.com>
|
||||
---
|
||||
drivers/net/usb/smsc95xx.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 56 insertions(+)
|
||||
|
||||
--- a/drivers/net/usb/smsc95xx.c
|
||||
+++ b/drivers/net/usb/smsc95xx.c
|
||||
@@ -61,6 +61,7 @@
|
|
@ -0,0 +1,34 @@
|
|||
From f7ea3b11c29f79b86cbb2e25fa4cd1598a4350e3 Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Tue, 8 May 2012 23:12:13 +0100
|
||||
Subject: [PATCH 009/174] possible fix for sdcard missing status. Thank naren
|
||||
|
||||
---
|
||||
drivers/mmc/host/sdhci-bcm2708.c | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
--- a/drivers/mmc/host/sdhci-bcm2708.c
|
||||
+++ b/drivers/mmc/host/sdhci-bcm2708.c
|
||||
@@ -1173,6 +1173,14 @@ static unsigned int sdhci_bcm2708_uhs_br
|
||||
return 1;
|
||||
}
|
||||
|
||||
+static unsigned int sdhci_bcm2708_missing_status(struct sdhci_host *host)
|
||||
+{
|
||||
+ if(host->last_cmdop == MMC_SEND_STATUS)
|
||||
+ return 1;
|
||||
+ else
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/***************************************************************************** \
|
||||
* *
|
||||
* Device ops *
|
||||
@@ -1206,6 +1214,7 @@ static struct sdhci_ops sdhci_bcm2708_op
|
||||
.spurious_crc_acmd51 = sdhci_bcm2708_quirk_spurious_crc,
|
||||
.voltage_broken = sdhci_bcm2708_quirk_voltage_broken,
|
||||
.uhs_broken = sdhci_bcm2708_uhs_broken,
|
||||
+ .missing_status = sdhci_bcm2708_missing_status,
|
||||
};
|
||||
|
||||
/*****************************************************************************\
|
|
@ -0,0 +1,56 @@
|
|||
From 7063eab83522ea1f24934b971418bfdd4c5578f1 Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Thu, 17 May 2012 14:44:19 +0100
|
||||
Subject: [PATCH 010/174] sdcard patch improvements from naren
|
||||
|
||||
---
|
||||
drivers/mmc/host/sdhci-bcm2708.c | 23 +++++++----------------
|
||||
1 file changed, 7 insertions(+), 16 deletions(-)
|
||||
|
||||
--- a/drivers/mmc/host/sdhci-bcm2708.c
|
||||
+++ b/drivers/mmc/host/sdhci-bcm2708.c
|
||||
@@ -886,8 +886,7 @@ static void sdhci_bcm2708_dma_complete_i
|
||||
We get CRC and DEND errors unless we wait for
|
||||
the SD controller to finish reading/writing to the card. */
|
||||
u32 state_mask;
|
||||
- int timeout=1000000;
|
||||
- hptime_t now = hptime();
|
||||
+ int timeout=1000;
|
||||
|
||||
DBG("PDMA over - sync card\n");
|
||||
if (data->flags & MMC_DATA_READ)
|
||||
@@ -895,17 +894,12 @@ static void sdhci_bcm2708_dma_complete_i
|
||||
else
|
||||
state_mask = SDHCI_DOING_WRITE;
|
||||
|
||||
- while (0 != (sdhci_bcm2708_raw_readl(host,
|
||||
- SDHCI_PRESENT_STATE) &
|
||||
- state_mask) && --timeout > 0)
|
||||
+ while (0 != (sdhci_bcm2708_raw_readl(host, SDHCI_PRESENT_STATE)
|
||||
+ & state_mask) && --timeout > 0)
|
||||
+ {
|
||||
+ udelay(100);
|
||||
continue;
|
||||
-
|
||||
- if (1000000-timeout > 4000) /*ave. is about 3250*/
|
||||
- DBG("%s: note - long %s sync %luns - "
|
||||
- "%d its.\n",
|
||||
- mmc_hostname(host->mmc),
|
||||
- data->flags & MMC_DATA_READ? "read": "write",
|
||||
- since_ns(now), 1000000-timeout);
|
||||
+ }
|
||||
if (timeout <= 0)
|
||||
printk(KERN_ERR"%s: final %s to SD card still "
|
||||
"running\n",
|
||||
@@ -1175,10 +1169,7 @@ static unsigned int sdhci_bcm2708_uhs_br
|
||||
|
||||
static unsigned int sdhci_bcm2708_missing_status(struct sdhci_host *host)
|
||||
{
|
||||
- if(host->last_cmdop == MMC_SEND_STATUS)
|
||||
- return 1;
|
||||
- else
|
||||
- return 0;
|
||||
+ return 1;
|
||||
}
|
||||
|
||||
/***************************************************************************** \
|
|
@ -0,0 +1,22 @@
|
|||
From e38d3d05747f6877a2ad1a7af1ac26e6a48a8be3 Mon Sep 17 00:00:00 2001
|
||||
From: Grigori Goronzy <greg@blackbox>
|
||||
Date: Mon, 4 Jun 2012 04:27:48 +0200
|
||||
Subject: [PATCH 011/174] sdhci-bcm2708: speed up DMA sync
|
||||
|
||||
Experiments show that it doesn't really take that long to sync, so we
|
||||
can reduce the poll interval slightly. Might improve performance a bit.
|
||||
---
|
||||
drivers/mmc/host/sdhci-bcm2708.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/mmc/host/sdhci-bcm2708.c
|
||||
+++ b/drivers/mmc/host/sdhci-bcm2708.c
|
||||
@@ -897,7 +897,7 @@ static void sdhci_bcm2708_dma_complete_i
|
||||
while (0 != (sdhci_bcm2708_raw_readl(host, SDHCI_PRESENT_STATE)
|
||||
& state_mask) && --timeout > 0)
|
||||
{
|
||||
- udelay(100);
|
||||
+ udelay(30);
|
||||
continue;
|
||||
}
|
||||
if (timeout <= 0)
|
|
@ -0,0 +1,95 @@
|
|||
From 3f65aaaabc3ddc09bacf06bb608f8bab5671fb18 Mon Sep 17 00:00:00 2001
|
||||
From: Grigori Goronzy <greg@blackbox>
|
||||
Date: Mon, 11 Jun 2012 18:52:04 +0200
|
||||
Subject: [PATCH 012/174] sdhci-bcm2708: remove custom clock handling
|
||||
|
||||
The custom clock handling code is redundant and buggy. The MMC/SDHCI
|
||||
subsystem does a better job than it, so remove it for good.
|
||||
---
|
||||
drivers/mmc/host/sdhci-bcm2708.c | 65 +---------------------------------------
|
||||
1 file changed, 1 insertion(+), 64 deletions(-)
|
||||
|
||||
--- a/drivers/mmc/host/sdhci-bcm2708.c
|
||||
+++ b/drivers/mmc/host/sdhci-bcm2708.c
|
||||
@@ -353,68 +353,9 @@ void sdhci_bcm2708_writeb(struct sdhci_h
|
||||
|
||||
static unsigned int sdhci_bcm2708_get_max_clock(struct sdhci_host *host)
|
||||
{
|
||||
- return 20000000; // this value is in Hz (20MHz)
|
||||
+ return BCM2708_EMMC_CLOCK_FREQ;
|
||||
}
|
||||
|
||||
-static unsigned int sdhci_bcm2708_get_timeout_clock(struct sdhci_host *host)
|
||||
-{
|
||||
- if(host->clock)
|
||||
- return (host->clock / 1000); // this value is in kHz (100MHz)
|
||||
- else
|
||||
- return (sdhci_bcm2708_get_max_clock(host) / 1000);
|
||||
-}
|
||||
-
|
||||
-static void sdhci_bcm2708_set_clock(struct sdhci_host *host, unsigned int clock)
|
||||
-{
|
||||
- int div = 0;
|
||||
- u16 clk = 0;
|
||||
- unsigned long timeout;
|
||||
-
|
||||
- if (clock == host->clock)
|
||||
- return;
|
||||
-
|
||||
- sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
|
||||
-
|
||||
- if (clock == 0)
|
||||
- goto out;
|
||||
-
|
||||
- if (BCM2708_EMMC_CLOCK_FREQ <= clock)
|
||||
- div = 1;
|
||||
- else {
|
||||
- for (div = 2; div < SDHCI_MAX_DIV_SPEC_300; div += 2) {
|
||||
- if ((BCM2708_EMMC_CLOCK_FREQ / div) <= clock)
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- DBG( "desired SD clock: %d, actual: %d\n",
|
||||
- clock, BCM2708_EMMC_CLOCK_FREQ / div);
|
||||
-
|
||||
- clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT;
|
||||
- clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN)
|
||||
- << SDHCI_DIVIDER_HI_SHIFT;
|
||||
- clk |= SDHCI_CLOCK_INT_EN;
|
||||
-
|
||||
- sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
|
||||
-
|
||||
- timeout = 20;
|
||||
- while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
|
||||
- & SDHCI_CLOCK_INT_STABLE)) {
|
||||
- if (timeout == 0) {
|
||||
- printk(KERN_ERR "%s: Internal clock never "
|
||||
- "stabilised.\n", mmc_hostname(host->mmc));
|
||||
- return;
|
||||
- }
|
||||
- timeout--;
|
||||
- mdelay(1);
|
||||
- }
|
||||
-
|
||||
- clk |= SDHCI_CLOCK_CARD_EN;
|
||||
- sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
|
||||
-out:
|
||||
- host->clock = clock;
|
||||
- }
|
||||
-
|
||||
/*****************************************************************************\
|
||||
* *
|
||||
* DMA Operation *
|
||||
@@ -1189,11 +1130,7 @@ static struct sdhci_ops sdhci_bcm2708_op
|
||||
#else
|
||||
#error The BCM2708 SDHCI driver needs CONFIG_MMC_SDHCI_IO_ACCESSORS to be set
|
||||
#endif
|
||||
- //.enable_dma = NULL,
|
||||
- .set_clock = sdhci_bcm2708_set_clock,
|
||||
.get_max_clock = sdhci_bcm2708_get_max_clock,
|
||||
- //.get_min_clock = NULL,
|
||||
- .get_timeout_clock = sdhci_bcm2708_get_timeout_clock,
|
||||
|
||||
#ifdef CONFIG_MMC_SDHCI_BCM2708_DMA
|
||||
// Platform DMA operations
|
|
@ -0,0 +1,27 @@
|
|||
From b567bbb9b16e9c860c8d7a4f2c6cf44c66533dfa Mon Sep 17 00:00:00 2001
|
||||
From: Grigori Goronzy <greg@blackbox>
|
||||
Date: Mon, 11 Jun 2012 18:53:59 +0200
|
||||
Subject: [PATCH 013/174] sdhci-bcm2708: add additional quirks
|
||||
|
||||
Some additional quirks are needed for correct operation.
|
||||
There's no SDHCI capabilities register documented, and it always reads
|
||||
zero, so add SDHCI_QUIRK_MISSING_CAPS. Apparently
|
||||
SDHCI_QUIRK_NO_HISPD_BIT is needed for many cards to work correctly in
|
||||
high-speed mode, so add it as well.
|
||||
---
|
||||
drivers/mmc/host/sdhci-bcm2708.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/mmc/host/sdhci-bcm2708.c
|
||||
+++ b/drivers/mmc/host/sdhci-bcm2708.c
|
||||
@@ -1189,7 +1189,9 @@ static int sdhci_bcm2708_probe(struct pl
|
||||
host->quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION |
|
||||
SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
|
||||
SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
|
||||
- SDHCI_QUIRK_NONSTANDARD_CLOCK;
|
||||
+ SDHCI_QUIRK_MISSING_CAPS |
|
||||
+ SDHCI_QUIRK_NO_HISPD_BIT;
|
||||
+
|
||||
#ifdef CONFIG_MMC_SDHCI_BCM2708_DMA
|
||||
host->flags = SDHCI_USE_PLATDMA;
|
||||
#endif
|
|
@ -0,0 +1,45 @@
|
|||
From f779191cd42376e2b1f555be1b2c486dd99b2fef Mon Sep 17 00:00:00 2001
|
||||
From: Grigori Goronzy <greg@blackbox>
|
||||
Date: Mon, 11 Jun 2012 18:57:13 +0200
|
||||
Subject: [PATCH 014/174] sdhci-bcm2708: add allow_highspeed parameter
|
||||
|
||||
Add a parameter to disable high-speed mode for the few cards that
|
||||
still might have problems. High-speed mode is enabled by default.
|
||||
---
|
||||
drivers/mmc/host/sdhci-bcm2708.c | 9 ++++++++-
|
||||
1 file changed, 8 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/mmc/host/sdhci-bcm2708.c
|
||||
+++ b/drivers/mmc/host/sdhci-bcm2708.c
|
||||
@@ -129,6 +129,8 @@ static inline unsigned long int since_ns
|
||||
return (unsigned long)((hptime() - t) * HPTIME_CLK_NS);
|
||||
}
|
||||
|
||||
+static bool allow_highspeed = 1;
|
||||
+
|
||||
#if 0
|
||||
static void hptime_test(void)
|
||||
{
|
||||
@@ -1254,7 +1256,8 @@ static int sdhci_bcm2708_probe(struct pl
|
||||
host_priv->dma_chan, host_priv->dma_chan_base,
|
||||
host_priv->dma_irq);
|
||||
|
||||
- host->mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
|
||||
+ if (allow_highspeed)
|
||||
+ host->mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
|
||||
#endif
|
||||
|
||||
ret = sdhci_add_host(host);
|
||||
@@ -1357,8 +1360,12 @@ static void __exit sdhci_drv_exit(void)
|
||||
module_init(sdhci_drv_init);
|
||||
module_exit(sdhci_drv_exit);
|
||||
|
||||
+module_param(allow_highspeed, bool, 0444);
|
||||
+
|
||||
MODULE_DESCRIPTION("Secure Digital Host Controller Interface platform driver");
|
||||
MODULE_AUTHOR("Broadcom <info@broadcom.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_ALIAS("platform:"DRIVER_NAME);
|
||||
|
||||
+MODULE_PARM_DESC(allow_highspeed, "Allow high speed transfers modes");
|
||||
+
|
|
@ -0,0 +1,23 @@
|
|||
From 55ed27d2c44fcf2e808ba26cc2a1c9c4041500da Mon Sep 17 00:00:00 2001
|
||||
From: Grigori Goronzy <greg@blackbox>
|
||||
Date: Mon, 11 Jun 2012 18:58:40 +0200
|
||||
Subject: [PATCH 015/174] sdhci-bcm2708: assume 50 MHz eMMC clock
|
||||
|
||||
80 MHz clock isnt't suited well to be dividable to get SD clocks of 25
|
||||
MHz (default mode) or 50 MHz (high speed mode). 50 MHz are perfect to
|
||||
drive the SD interface at ideal frequencies.
|
||||
---
|
||||
drivers/mmc/host/sdhci-bcm2708.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/mmc/host/sdhci-bcm2708.c
|
||||
+++ b/drivers/mmc/host/sdhci-bcm2708.c
|
||||
@@ -73,7 +73,7 @@
|
||||
#define BCM2708_SDHCI_SLEEP_TIMEOUT 1000 /* msecs */
|
||||
|
||||
/* Mhz clock that the EMMC core is running at. Should match the platform clockman settings */
|
||||
-#define BCM2708_EMMC_CLOCK_FREQ 80000000
|
||||
+#define BCM2708_EMMC_CLOCK_FREQ 50000000
|
||||
|
||||
/*****************************************************************************\
|
||||
* *
|
|
@ -0,0 +1,44 @@
|
|||
From 9227615100c139c48fbbf39312b38c4430eac00d Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Sat, 16 Jun 2012 22:31:55 +0100
|
||||
Subject: [PATCH 016/174] Allow emmc clock to be specified as command line
|
||||
parameter
|
||||
|
||||
---
|
||||
drivers/mmc/host/sdhci-bcm2708.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/mmc/host/sdhci-bcm2708.c
|
||||
+++ b/drivers/mmc/host/sdhci-bcm2708.c
|
||||
@@ -130,6 +130,7 @@ static inline unsigned long int since_ns
|
||||
}
|
||||
|
||||
static bool allow_highspeed = 1;
|
||||
+static int emmc_clock_freq = BCM2708_EMMC_CLOCK_FREQ;
|
||||
|
||||
#if 0
|
||||
static void hptime_test(void)
|
||||
@@ -355,7 +356,7 @@ void sdhci_bcm2708_writeb(struct sdhci_h
|
||||
|
||||
static unsigned int sdhci_bcm2708_get_max_clock(struct sdhci_host *host)
|
||||
{
|
||||
- return BCM2708_EMMC_CLOCK_FREQ;
|
||||
+ return emmc_clock_freq;
|
||||
}
|
||||
|
||||
/*****************************************************************************\
|
||||
@@ -1361,6 +1362,7 @@ module_init(sdhci_drv_init);
|
||||
module_exit(sdhci_drv_exit);
|
||||
|
||||
module_param(allow_highspeed, bool, 0444);
|
||||
+module_param(emmc_clock_freq, int, 0444);
|
||||
|
||||
MODULE_DESCRIPTION("Secure Digital Host Controller Interface platform driver");
|
||||
MODULE_AUTHOR("Broadcom <info@broadcom.com>");
|
||||
@@ -1368,4 +1370,6 @@ MODULE_LICENSE("GPL v2");
|
||||
MODULE_ALIAS("platform:"DRIVER_NAME);
|
||||
|
||||
MODULE_PARM_DESC(allow_highspeed, "Allow high speed transfers modes");
|
||||
+MODULE_PARM_DESC(emmc_clock_freq, "Specify the speed of emmc clock");
|
||||
+
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
From a6544a62be8711e727a0d774b55c5edeec12e531 Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Sat, 16 Jun 2012 22:35:38 +0100
|
||||
Subject: [PATCH 017/174] sdhci-bcm2708: raise DMA sync timeout
|
||||
|
||||
Commit d64b84c by accident reduced the maximum overall DMA sync
|
||||
timeout. The maximum overall timeout was reduced from 100ms to 30ms,
|
||||
which isn't enough for many cards. Increase it to 150ms, just to be
|
||||
extra safe. According to commit 872a8ff in the MMC subsystem, some
|
||||
cards require crazy long timeouts (3s), but as we're busy-waiting,
|
||||
and shouldn't delay for such a long time, let's hope 150ms will be
|
||||
enough for most cards.
|
||||
---
|
||||
drivers/mmc/host/sdhci-bcm2708.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/mmc/host/sdhci-bcm2708.c
|
||||
+++ b/drivers/mmc/host/sdhci-bcm2708.c
|
||||
@@ -830,7 +830,7 @@ static void sdhci_bcm2708_dma_complete_i
|
||||
We get CRC and DEND errors unless we wait for
|
||||
the SD controller to finish reading/writing to the card. */
|
||||
u32 state_mask;
|
||||
- int timeout=1000;
|
||||
+ int timeout=5000;
|
||||
|
||||
DBG("PDMA over - sync card\n");
|
||||
if (data->flags & MMC_DATA_READ)
|
|
@ -0,0 +1,44 @@
|
|||
From a56370b5a103f3949c5ed2997a971e1949a15132 Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Fri, 22 Jun 2012 12:57:42 +0100
|
||||
Subject: [PATCH 018/174] Use ndelay rather than udelay. Thanks lb
|
||||
|
||||
---
|
||||
drivers/mmc/host/sdhci-bcm2708.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/mmc/host/sdhci-bcm2708.c
|
||||
+++ b/drivers/mmc/host/sdhci-bcm2708.c
|
||||
@@ -249,14 +249,14 @@ static void sdhci_bcm2708_raw_writel(str
|
||||
if (now == last_write_hpt || now == last_write_hpt+1) {
|
||||
/* we can't guarantee any significant time has
|
||||
* passed - we'll have to wait anyway ! */
|
||||
- udelay((ns_2clk+1000-1)/1000);
|
||||
+ ndelay(ns_2clk);
|
||||
} else
|
||||
{
|
||||
/* we must have waited at least this many ns: */
|
||||
unsigned int ns_wait = HPTIME_CLK_NS *
|
||||
(last_write_hpt - now - 1);
|
||||
if (ns_wait < ns_2clk)
|
||||
- udelay((ns_2clk-ns_wait+500)/1000);
|
||||
+ ndelay(ns_2clk - ns_wait);
|
||||
}
|
||||
last_write_hpt = now;
|
||||
}
|
||||
@@ -272,13 +272,13 @@ static void sdhci_bcm2708_raw_writel(str
|
||||
ier &= ~SDHCI_INT_DATA_TIMEOUT;
|
||||
writel(ier, host->ioaddr + SDHCI_SIGNAL_ENABLE);
|
||||
timeout_disabled = true;
|
||||
- udelay((ns_2clk+1000-1)/1000);
|
||||
+ ndelay(ns_2clk);
|
||||
} else if (timeout_disabled) {
|
||||
ier = readl(host->ioaddr + SDHCI_SIGNAL_ENABLE);
|
||||
ier |= SDHCI_INT_DATA_TIMEOUT;
|
||||
writel(ier, host->ioaddr + SDHCI_SIGNAL_ENABLE);
|
||||
timeout_disabled = false;
|
||||
- udelay((ns_2clk+1000-1)/1000);
|
||||
+ ndelay(ns_2clk);
|
||||
}
|
||||
#endif
|
||||
writel(val, host->ioaddr + reg);
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,113 @@
|
|||
From 9e42f33f4f80999a2c65a50b2a7ac6562ca194f5 Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Tue, 17 Jul 2012 00:48:27 +0100
|
||||
Subject: [PATCH 020/174] Add sync_after_dma module parameter
|
||||
|
||||
---
|
||||
drivers/mmc/host/sdhci-bcm2708.c | 60 +++++++++++++++++++++-------------------
|
||||
1 file changed, 32 insertions(+), 28 deletions(-)
|
||||
|
||||
--- a/drivers/mmc/host/sdhci-bcm2708.c
|
||||
+++ b/drivers/mmc/host/sdhci-bcm2708.c
|
||||
@@ -51,7 +51,6 @@
|
||||
#undef CONFIG_MMC_SDHCI_BCM2708_DMA
|
||||
#define CONFIG_MMC_SDHCI_BCM2708_DMA y
|
||||
|
||||
-#define USE_SYNC_AFTER_DMA
|
||||
#ifdef CONFIG_MMC_SDHCI_BCM2708_DMA
|
||||
/* #define CHECK_DMA_USE */
|
||||
#endif
|
||||
@@ -131,6 +130,7 @@ static inline unsigned long int since_ns
|
||||
|
||||
static bool allow_highspeed = 1;
|
||||
static int emmc_clock_freq = BCM2708_EMMC_CLOCK_FREQ;
|
||||
+static bool sync_after_dma = 1;
|
||||
|
||||
#if 0
|
||||
static void hptime_test(void)
|
||||
@@ -822,34 +822,34 @@ static void sdhci_bcm2708_dma_complete_i
|
||||
SDHCI_INT_SPACE_AVAIL);
|
||||
}
|
||||
} else {
|
||||
-#ifdef USE_SYNC_AFTER_DMA
|
||||
- /* On the Arasan controller the stop command (which will be
|
||||
- scheduled after this completes) does not seem to work
|
||||
- properly if we allow it to be issued when we are
|
||||
- transferring data to/from the SD card.
|
||||
- We get CRC and DEND errors unless we wait for
|
||||
- the SD controller to finish reading/writing to the card. */
|
||||
- u32 state_mask;
|
||||
- int timeout=5000;
|
||||
+ if (sync_after_dma) {
|
||||
+ /* On the Arasan controller the stop command (which will be
|
||||
+ scheduled after this completes) does not seem to work
|
||||
+ properly if we allow it to be issued when we are
|
||||
+ transferring data to/from the SD card.
|
||||
+ We get CRC and DEND errors unless we wait for
|
||||
+ the SD controller to finish reading/writing to the card. */
|
||||
+ u32 state_mask;
|
||||
+ int timeout=30*5000;
|
||||
|
||||
- DBG("PDMA over - sync card\n");
|
||||
- if (data->flags & MMC_DATA_READ)
|
||||
- state_mask = SDHCI_DOING_READ;
|
||||
- else
|
||||
- state_mask = SDHCI_DOING_WRITE;
|
||||
+ DBG("PDMA over - sync card\n");
|
||||
+ if (data->flags & MMC_DATA_READ)
|
||||
+ state_mask = SDHCI_DOING_READ;
|
||||
+ else
|
||||
+ state_mask = SDHCI_DOING_WRITE;
|
||||
|
||||
- while (0 != (sdhci_bcm2708_raw_readl(host, SDHCI_PRESENT_STATE)
|
||||
- & state_mask) && --timeout > 0)
|
||||
- {
|
||||
- udelay(30);
|
||||
- continue;
|
||||
+ while (0 != (sdhci_bcm2708_raw_readl(host, SDHCI_PRESENT_STATE)
|
||||
+ & state_mask) && --timeout > 0)
|
||||
+ {
|
||||
+ udelay(1);
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (timeout <= 0)
|
||||
+ printk(KERN_ERR"%s: final %s to SD card still "
|
||||
+ "running\n",
|
||||
+ mmc_hostname(host->mmc),
|
||||
+ data->flags & MMC_DATA_READ? "read": "write");
|
||||
}
|
||||
- if (timeout <= 0)
|
||||
- printk(KERN_ERR"%s: final %s to SD card still "
|
||||
- "running\n",
|
||||
- mmc_hostname(host->mmc),
|
||||
- data->flags & MMC_DATA_READ? "read": "write");
|
||||
-#endif
|
||||
if (host_priv->complete) {
|
||||
(*host_priv->complete)(host);
|
||||
DBG("PDMA %s complete\n",
|
||||
@@ -1193,7 +1193,9 @@ static int sdhci_bcm2708_probe(struct pl
|
||||
SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
|
||||
SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
|
||||
SDHCI_QUIRK_MISSING_CAPS |
|
||||
- SDHCI_QUIRK_NO_HISPD_BIT;
|
||||
+ SDHCI_QUIRK_NO_HISPD_BIT |
|
||||
+ (sync_after_dma ? 0:SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12);
|
||||
+
|
||||
|
||||
#ifdef CONFIG_MMC_SDHCI_BCM2708_DMA
|
||||
host->flags = SDHCI_USE_PLATDMA;
|
||||
@@ -1363,6 +1365,7 @@ module_exit(sdhci_drv_exit);
|
||||
|
||||
module_param(allow_highspeed, bool, 0444);
|
||||
module_param(emmc_clock_freq, int, 0444);
|
||||
+module_param(sync_after_dma, bool, 0444);
|
||||
|
||||
MODULE_DESCRIPTION("Secure Digital Host Controller Interface platform driver");
|
||||
MODULE_AUTHOR("Broadcom <info@broadcom.com>");
|
||||
@@ -1371,5 +1374,6 @@ MODULE_ALIAS("platform:"DRIVER_NAME);
|
||||
|
||||
MODULE_PARM_DESC(allow_highspeed, "Allow high speed transfers modes");
|
||||
MODULE_PARM_DESC(emmc_clock_freq, "Specify the speed of emmc clock");
|
||||
+MODULE_PARM_DESC(sync_after_dma, "Block in driver until dma complete");
|
||||
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
From 3e9891e91d7dda096ab1cc2518830938ad69880d Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Sun, 12 May 2013 12:25:52 +0100
|
||||
Subject: [PATCH 021/174] sdhci-bcm2708: use extension FIFO to buffer DMA
|
||||
transfers
|
||||
|
||||
The additional FIFO might speed up transfers in some cases.
|
||||
---
|
||||
drivers/mmc/host/sdhci-bcm2708.c | 11 +++++++++++
|
||||
1 file changed, 11 insertions(+)
|
||||
|
||||
--- a/drivers/mmc/host/sdhci-bcm2708.c
|
||||
+++ b/drivers/mmc/host/sdhci-bcm2708.c
|
||||
@@ -74,6 +74,9 @@
|
||||
/* Mhz clock that the EMMC core is running at. Should match the platform clockman settings */
|
||||
#define BCM2708_EMMC_CLOCK_FREQ 50000000
|
||||
|
||||
+#define REG_EXRDFIFO_EN 0x80
|
||||
+#define REG_EXRDFIFO_CFG 0x84
|
||||
+
|
||||
/*****************************************************************************\
|
||||
* *
|
||||
* Debug *
|
||||
@@ -957,10 +960,12 @@ static ssize_t attr_dma_store(struct dev
|
||||
int on = simple_strtol(buf, NULL, 0);
|
||||
if (on) {
|
||||
host->flags |= SDHCI_USE_PLATDMA;
|
||||
+ sdhci_bcm2708_writel(host, 1, REG_EXRDFIFO_EN);
|
||||
printk(KERN_INFO "%s: DMA enabled\n",
|
||||
mmc_hostname(host->mmc));
|
||||
} else {
|
||||
host->flags &= ~(SDHCI_USE_PLATDMA | SDHCI_REQ_USE_DMA);
|
||||
+ sdhci_bcm2708_writel(host, 0, REG_EXRDFIFO_EN);
|
||||
printk(KERN_INFO "%s: DMA disabled\n",
|
||||
mmc_hostname(host->mmc));
|
||||
}
|
||||
@@ -1272,6 +1277,12 @@ static int sdhci_bcm2708_probe(struct pl
|
||||
ret = device_create_file(&pdev->dev, &dev_attr_dma_wait);
|
||||
ret = device_create_file(&pdev->dev, &dev_attr_status);
|
||||
|
||||
+#ifdef CONFIG_MMC_SDHCI_BCM2708_DMA
|
||||
+ /* enable extension fifo for paced DMA transfers */
|
||||
+ sdhci_bcm2708_writel(host, 1, REG_EXRDFIFO_EN);
|
||||
+ sdhci_bcm2708_writel(host, 4, REG_EXRDFIFO_CFG);
|
||||
+#endif
|
||||
+
|
||||
printk(KERN_INFO "%s: BCM2708 SDHC host at 0x%08llx DMA %d IRQ %d\n",
|
||||
mmc_hostname(host->mmc), (unsigned long long)iomem->start,
|
||||
host_priv->dma_chan, host_priv->dma_irq);
|
|
@ -0,0 +1,49 @@
|
|||
From 9f5c2a77277b99949398e97cc753074d1b8e9521 Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Wed, 3 Jul 2013 00:42:49 +0100
|
||||
Subject: [PATCH 022/174] sdhci-bcm2708: use multiblock-type transfers for
|
||||
single blocks
|
||||
|
||||
There are issues with both single block reads (missed completion)
|
||||
and writes (data loss in some cases!). Just don't do single block
|
||||
transfers anymore, and treat them like multiblock transfers. This
|
||||
adds a quirk for this and uses it.
|
||||
---
|
||||
drivers/mmc/card/block.c | 2 +-
|
||||
drivers/mmc/host/sdhci-bcm2708.c | 3 +++
|
||||
include/linux/mmc/host.h | 1 +
|
||||
3 files changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/mmc/card/block.c
|
||||
+++ b/drivers/mmc/card/block.c
|
||||
@@ -1333,7 +1333,7 @@ static void mmc_blk_rw_rq_prep(struct mm
|
||||
brq->data.blocks = 1;
|
||||
}
|
||||
|
||||
- if (brq->data.blocks > 1 || do_rel_wr) {
|
||||
+ if (brq->data.blocks > 1 || do_rel_wr || card->host->caps2 & MMC_CAP2_FORCE_MULTIBLOCK) {
|
||||
/* SPI multiblock writes terminate using a special
|
||||
* token, not a STOP_TRANSMISSION request.
|
||||
*/
|
||||
--- a/drivers/mmc/host/sdhci-bcm2708.c
|
||||
+++ b/drivers/mmc/host/sdhci-bcm2708.c
|
||||
@@ -1266,6 +1266,9 @@ static int sdhci_bcm2708_probe(struct pl
|
||||
|
||||
if (allow_highspeed)
|
||||
host->mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
|
||||
+
|
||||
+ /* single block writes cause data loss with some SD cards! */
|
||||
+ host->mmc->caps2 |= MMC_CAP2_FORCE_MULTIBLOCK;
|
||||
#endif
|
||||
|
||||
ret = sdhci_add_host(host);
|
||||
--- a/include/linux/mmc/host.h
|
||||
+++ b/include/linux/mmc/host.h
|
||||
@@ -281,6 +281,7 @@ struct mmc_host {
|
||||
#define MMC_CAP2_PACKED_CMD (MMC_CAP2_PACKED_RD | \
|
||||
MMC_CAP2_PACKED_WR)
|
||||
#define MMC_CAP2_NO_PRESCAN_POWERUP (1 << 14) /* Don't power up before scan */
|
||||
+#define MMC_CAP2_FORCE_MULTIBLOCK (1 << 31) /* Always use multiblock transfers */
|
||||
|
||||
mmc_pm_flag_t pm_caps; /* supported pm features */
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
From 4548721c4c1b160a8b5702b6226c5b6403b3df8b Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Wed, 1 Aug 2012 19:02:14 +0100
|
||||
Subject: [PATCH 023/174] Add module parameter for missing_status quirk.
|
||||
sdhci-bcm2708.missing_status=0 may improve interrupt latency
|
||||
|
||||
---
|
||||
drivers/mmc/host/sdhci-bcm2708.c | 7 ++++++-
|
||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/mmc/host/sdhci-bcm2708.c
|
||||
+++ b/drivers/mmc/host/sdhci-bcm2708.c
|
||||
@@ -134,6 +134,7 @@ static inline unsigned long int since_ns
|
||||
static bool allow_highspeed = 1;
|
||||
static int emmc_clock_freq = BCM2708_EMMC_CLOCK_FREQ;
|
||||
static bool sync_after_dma = 1;
|
||||
+static bool missing_status = 1;
|
||||
|
||||
#if 0
|
||||
static void hptime_test(void)
|
||||
@@ -1150,7 +1151,6 @@ static struct sdhci_ops sdhci_bcm2708_op
|
||||
.spurious_crc_acmd51 = sdhci_bcm2708_quirk_spurious_crc,
|
||||
.voltage_broken = sdhci_bcm2708_quirk_voltage_broken,
|
||||
.uhs_broken = sdhci_bcm2708_uhs_broken,
|
||||
- .missing_status = sdhci_bcm2708_missing_status,
|
||||
};
|
||||
|
||||
/*****************************************************************************\
|
||||
@@ -1189,6 +1189,9 @@ static int sdhci_bcm2708_probe(struct pl
|
||||
ret = PTR_ERR(host);
|
||||
goto err;
|
||||
}
|
||||
+ if (missing_status) {
|
||||
+ sdhci_bcm2708_ops.missing_status = sdhci_bcm2708_missing_status;
|
||||
+ }
|
||||
|
||||
host->hw_name = "BCM2708_Arasan";
|
||||
host->ops = &sdhci_bcm2708_ops;
|
||||
@@ -1380,6 +1383,7 @@ module_exit(sdhci_drv_exit);
|
||||
module_param(allow_highspeed, bool, 0444);
|
||||
module_param(emmc_clock_freq, int, 0444);
|
||||
module_param(sync_after_dma, bool, 0444);
|
||||
+module_param(missing_status, bool, 0444);
|
||||
|
||||
MODULE_DESCRIPTION("Secure Digital Host Controller Interface platform driver");
|
||||
MODULE_AUTHOR("Broadcom <info@broadcom.com>");
|
||||
@@ -1389,5 +1393,6 @@ MODULE_ALIAS("platform:"DRIVER_NAME);
|
||||
MODULE_PARM_DESC(allow_highspeed, "Allow high speed transfers modes");
|
||||
MODULE_PARM_DESC(emmc_clock_freq, "Specify the speed of emmc clock");
|
||||
MODULE_PARM_DESC(sync_after_dma, "Block in driver until dma complete");
|
||||
+MODULE_PARM_DESC(missing_status, "Use the missing status quirk");
|
||||
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
From bd9a95701602937c6e402a4fc6786d1675431117 Mon Sep 17 00:00:00 2001
|
||||
From: ddv2005 <ddv@abinet.com>
|
||||
Date: Sun, 5 Aug 2012 10:42:12 -0400
|
||||
Subject: [PATCH 024/174] Fix spinlock recursion in sdhci-bcm2708.c
|
||||
|
||||
---
|
||||
drivers/mmc/host/sdhci-bcm2708.c | 14 +++++++-------
|
||||
1 file changed, 7 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/drivers/mmc/host/sdhci-bcm2708.c
|
||||
+++ b/drivers/mmc/host/sdhci-bcm2708.c
|
||||
@@ -643,11 +643,11 @@ void
|
||||
sdhci_bcm2708_platdma_reset(struct sdhci_host *host, struct mmc_data *data)
|
||||
{
|
||||
struct sdhci_bcm2708_priv *host_priv = SDHCI_HOST_PRIV(host);
|
||||
- unsigned long flags;
|
||||
+// unsigned long flags;
|
||||
|
||||
BUG_ON(NULL == host);
|
||||
|
||||
- spin_lock_irqsave(&host->lock, flags);
|
||||
+// spin_lock_irqsave(&host->lock, flags);
|
||||
|
||||
if (host_priv->dma_wanted) {
|
||||
if (NULL == data) {
|
||||
@@ -727,7 +727,7 @@ sdhci_bcm2708_platdma_reset(struct sdhci
|
||||
#endif
|
||||
}
|
||||
|
||||
- spin_unlock_irqrestore(&host->lock, flags);
|
||||
+// spin_unlock_irqrestore(&host->lock, flags);
|
||||
}
|
||||
|
||||
|
||||
@@ -740,11 +740,11 @@ static void sdhci_bcm2708_dma_complete_i
|
||||
int sg_len;
|
||||
int sg_ix;
|
||||
int sg_todo;
|
||||
- unsigned long flags;
|
||||
+// unsigned long flags;
|
||||
|
||||
BUG_ON(NULL == host);
|
||||
|
||||
- spin_lock_irqsave(&host->lock, flags);
|
||||
+// spin_lock_irqsave(&host->lock, flags);
|
||||
data = host->data;
|
||||
|
||||
#ifdef CHECK_DMA_USE
|
||||
@@ -769,7 +769,7 @@ static void sdhci_bcm2708_dma_complete_i
|
||||
|
||||
if (NULL == data) {
|
||||
DBG("PDMA unused completion - status 0x%X\n", dma_cs);
|
||||
- spin_unlock_irqrestore(&host->lock, flags);
|
||||
+// spin_unlock_irqrestore(&host->lock, flags);
|
||||
return;
|
||||
}
|
||||
sg = data->sg;
|
||||
@@ -862,7 +862,7 @@ static void sdhci_bcm2708_dma_complete_i
|
||||
SDHCI_INT_SPACE_AVAIL);
|
||||
}
|
||||
}
|
||||
- spin_unlock_irqrestore(&host->lock, flags);
|
||||
+// spin_unlock_irqrestore(&host->lock, flags);
|
||||
}
|
||||
|
||||
static irqreturn_t sdhci_bcm2708_dma_irq(int irq, void *dev_id)
|
|
@ -0,0 +1,60 @@
|
|||
From d3ea04a7506cca51d1e154cde5bcc7063595c98c Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Wed, 8 May 2013 11:46:50 +0100
|
||||
Subject: [PATCH 025/174] enabling the realtime clock 1-wire chip DS1307 and
|
||||
1-wire on GPIO4 (as a module)
|
||||
|
||||
---
|
||||
arch/arm/mach-bcm2708/bcm2708.c | 20 ++++++++++++++++++++
|
||||
1 file changed, 20 insertions(+)
|
||||
|
||||
--- a/arch/arm/mach-bcm2708/bcm2708.c
|
||||
+++ b/arch/arm/mach-bcm2708/bcm2708.c
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/spi/spi.h>
|
||||
+#include <linux/w1-gpio.h>
|
||||
|
||||
#include <linux/version.h>
|
||||
#include <linux/clkdev.h>
|
||||
@@ -71,6 +72,9 @@
|
||||
*/
|
||||
#define DMA_MASK_BITS_COMMON 32
|
||||
|
||||
+// use GPIO 4 for the one-wire GPIO pin, if enabled
|
||||
+#define W1_GPIO 4
|
||||
+
|
||||
/* command line parameters */
|
||||
static unsigned boardrev, serial;
|
||||
static unsigned uart_clock;
|
||||
@@ -251,6 +255,19 @@ static struct platform_device bcm2708_dm
|
||||
.num_resources = ARRAY_SIZE(bcm2708_dmaman_resources),
|
||||
};
|
||||
|
||||
+#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE)
|
||||
+static struct w1_gpio_platform_data w1_gpio_pdata = {
|
||||
+ .pin = W1_GPIO,
|
||||
+ .is_open_drain = 0,
|
||||
+};
|
||||
+
|
||||
+static struct platform_device w1_device = {
|
||||
+ .name = "w1-gpio",
|
||||
+ .id = -1,
|
||||
+ .dev.platform_data = &w1_gpio_pdata,
|
||||
+};
|
||||
+#endif
|
||||
+
|
||||
static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON);
|
||||
|
||||
static struct platform_device bcm2708_fb_device = {
|
||||
@@ -620,6 +637,9 @@ void __init bcm2708_init(void)
|
||||
#ifdef CONFIG_BCM2708_GPIO
|
||||
bcm_register_device(&bcm2708_gpio_device);
|
||||
#endif
|
||||
+#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE)
|
||||
+ platform_device_register(&w1_device);
|
||||
+#endif
|
||||
bcm_register_device(&bcm2708_systemtimer_device);
|
||||
bcm_register_device(&bcm2708_fb_device);
|
||||
bcm_register_device(&bcm2708_usb_device);
|
|
@ -0,0 +1,514 @@
|
|||
From fc153c5cb49f20f5e9644d92b8be064ed9159a16 Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Sun, 12 May 2013 12:27:48 +0100
|
||||
Subject: [PATCH 026/174] Add low-latency mode to sdcard driver. Disable with
|
||||
sdhci-bcm2708.enable_llm=0. Thanks ddv2005.
|
||||
|
||||
---
|
||||
drivers/mmc/host/sdhci-bcm2708.c | 17 ++--
|
||||
drivers/mmc/host/sdhci.c | 165 ++++++++++++++++++++++++++++++---------
|
||||
drivers/mmc/host/sdhci.h | 6 ++
|
||||
include/linux/mmc/sdhci.h | 1 +
|
||||
4 files changed, 145 insertions(+), 44 deletions(-)
|
||||
|
||||
--- a/drivers/mmc/host/sdhci-bcm2708.c
|
||||
+++ b/drivers/mmc/host/sdhci-bcm2708.c
|
||||
@@ -135,6 +135,7 @@ static bool allow_highspeed = 1;
|
||||
static int emmc_clock_freq = BCM2708_EMMC_CLOCK_FREQ;
|
||||
static bool sync_after_dma = 1;
|
||||
static bool missing_status = 1;
|
||||
+bool enable_llm = 1;
|
||||
|
||||
#if 0
|
||||
static void hptime_test(void)
|
||||
@@ -871,12 +872,11 @@ static irqreturn_t sdhci_bcm2708_dma_irq
|
||||
struct sdhci_host *host = dev_id;
|
||||
struct sdhci_bcm2708_priv *host_priv = SDHCI_HOST_PRIV(host);
|
||||
u32 dma_cs; /* control and status register */
|
||||
- unsigned long flags;
|
||||
|
||||
BUG_ON(NULL == dev_id);
|
||||
BUG_ON(NULL == host_priv->dma_chan_base);
|
||||
|
||||
- spin_lock_irqsave(&host->lock, flags);
|
||||
+ sdhci_spin_lock(host);
|
||||
|
||||
dma_cs = readl(host_priv->dma_chan_base + BCM2708_DMA_CS);
|
||||
|
||||
@@ -917,8 +917,7 @@ static irqreturn_t sdhci_bcm2708_dma_irq
|
||||
|
||||
result = IRQ_HANDLED;
|
||||
}
|
||||
-
|
||||
- spin_unlock_irqrestore(&host->lock, flags);
|
||||
+ sdhci_spin_unlock(host);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -1193,9 +1192,12 @@ static int sdhci_bcm2708_probe(struct pl
|
||||
sdhci_bcm2708_ops.missing_status = sdhci_bcm2708_missing_status;
|
||||
}
|
||||
|
||||
+ printk("sdhci: %s low-latency mode\n",enable_llm?"Enable":"Disable");
|
||||
+
|
||||
host->hw_name = "BCM2708_Arasan";
|
||||
host->ops = &sdhci_bcm2708_ops;
|
||||
host->irq = platform_get_irq(pdev, 0);
|
||||
+ host->second_irq = 0;
|
||||
|
||||
host->quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION |
|
||||
SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
|
||||
@@ -1256,12 +1258,13 @@ static int sdhci_bcm2708_probe(struct pl
|
||||
}
|
||||
host_priv->dma_chan = ret;
|
||||
|
||||
- ret = request_irq(host_priv->dma_irq, sdhci_bcm2708_dma_irq,
|
||||
- IRQF_SHARED, DRIVER_NAME " (dma)", host);
|
||||
+ ret = request_irq(host_priv->dma_irq, sdhci_bcm2708_dma_irq,0,//IRQF_SHARED,
|
||||
+ DRIVER_NAME " (dma)", host);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "cannot set DMA IRQ\n");
|
||||
goto err_add_dma_irq;
|
||||
}
|
||||
+ host->second_irq = host_priv->dma_irq;
|
||||
DBG("DMA CBs %p handle %08X DMA%d %p DMA IRQ %d\n",
|
||||
host_priv->cb_base, (unsigned)host_priv->cb_handle,
|
||||
host_priv->dma_chan, host_priv->dma_chan_base,
|
||||
@@ -1384,6 +1387,7 @@ module_param(allow_highspeed, bool, 0444
|
||||
module_param(emmc_clock_freq, int, 0444);
|
||||
module_param(sync_after_dma, bool, 0444);
|
||||
module_param(missing_status, bool, 0444);
|
||||
+module_param(enable_llm, bool, 0444);
|
||||
|
||||
MODULE_DESCRIPTION("Secure Digital Host Controller Interface platform driver");
|
||||
MODULE_AUTHOR("Broadcom <info@broadcom.com>");
|
||||
@@ -1394,5 +1398,6 @@ MODULE_PARM_DESC(allow_highspeed, "Allow
|
||||
MODULE_PARM_DESC(emmc_clock_freq, "Specify the speed of emmc clock");
|
||||
MODULE_PARM_DESC(sync_after_dma, "Block in driver until dma complete");
|
||||
MODULE_PARM_DESC(missing_status, "Use the missing status quirk");
|
||||
+MODULE_PARM_DESC(enable_llm, "Enable low-latency mode");
|
||||
|
||||
|
||||
--- a/drivers/mmc/host/sdhci.c
|
||||
+++ b/drivers/mmc/host/sdhci.c
|
||||
@@ -124,6 +124,91 @@ static void sdhci_dumpregs(struct sdhci_
|
||||
* Low level functions *
|
||||
* *
|
||||
\*****************************************************************************/
|
||||
+extern bool enable_llm;
|
||||
+static int sdhci_locked=0;
|
||||
+void sdhci_spin_lock(struct sdhci_host *host)
|
||||
+{
|
||||
+ spin_lock(&host->lock);
|
||||
+#ifdef CONFIG_PREEMPT
|
||||
+ if(enable_llm)
|
||||
+ {
|
||||
+ disable_irq_nosync(host->irq);
|
||||
+ if(host->second_irq)
|
||||
+ disable_irq_nosync(host->second_irq);
|
||||
+ local_irq_enable();
|
||||
+ }
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+void sdhci_spin_unlock(struct sdhci_host *host)
|
||||
+{
|
||||
+#ifdef CONFIG_PREEMPT
|
||||
+ if(enable_llm)
|
||||
+ {
|
||||
+ local_irq_disable();
|
||||
+ if(host->second_irq)
|
||||
+ enable_irq(host->second_irq);
|
||||
+ enable_irq(host->irq);
|
||||
+ }
|
||||
+#endif
|
||||
+ spin_unlock(&host->lock);
|
||||
+}
|
||||
+
|
||||
+void sdhci_spin_lock_irqsave(struct sdhci_host *host,unsigned long *flags)
|
||||
+{
|
||||
+#ifdef CONFIG_PREEMPT
|
||||
+ if(enable_llm)
|
||||
+ {
|
||||
+ while(sdhci_locked)
|
||||
+ {
|
||||
+ preempt_schedule();
|
||||
+ }
|
||||
+ spin_lock_irqsave(&host->lock,*flags);
|
||||
+ disable_irq(host->irq);
|
||||
+ if(host->second_irq)
|
||||
+ disable_irq(host->second_irq);
|
||||
+ local_irq_enable();
|
||||
+ }
|
||||
+ else
|
||||
+#endif
|
||||
+ spin_lock_irqsave(&host->lock,*flags);
|
||||
+}
|
||||
+
|
||||
+void sdhci_spin_unlock_irqrestore(struct sdhci_host *host,unsigned long flags)
|
||||
+{
|
||||
+#ifdef CONFIG_PREEMPT
|
||||
+ if(enable_llm)
|
||||
+ {
|
||||
+ local_irq_disable();
|
||||
+ if(host->second_irq)
|
||||
+ enable_irq(host->second_irq);
|
||||
+ enable_irq(host->irq);
|
||||
+ }
|
||||
+#endif
|
||||
+ spin_unlock_irqrestore(&host->lock,flags);
|
||||
+}
|
||||
+
|
||||
+static void sdhci_spin_enable_schedule(struct sdhci_host *host)
|
||||
+{
|
||||
+#ifdef CONFIG_PREEMPT
|
||||
+ if(enable_llm)
|
||||
+ {
|
||||
+ sdhci_locked = 1;
|
||||
+ preempt_enable();
|
||||
+ }
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+static void sdhci_spin_disable_schedule(struct sdhci_host *host)
|
||||
+{
|
||||
+#ifdef CONFIG_PREEMPT
|
||||
+ if(enable_llm)
|
||||
+ {
|
||||
+ preempt_disable();
|
||||
+ sdhci_locked = 0;
|
||||
+ }
|
||||
+#endif
|
||||
+}
|
||||
|
||||
static void sdhci_clear_set_irqs(struct sdhci_host *host, u32 clear, u32 set)
|
||||
{
|
||||
@@ -289,7 +374,7 @@ static void sdhci_led_control(struct led
|
||||
struct sdhci_host *host = container_of(led, struct sdhci_host, led);
|
||||
unsigned long flags;
|
||||
|
||||
- spin_lock_irqsave(&host->lock, flags);
|
||||
+ sdhci_spin_lock_irqsave(host, &flags);
|
||||
|
||||
if (host->runtime_suspended)
|
||||
goto out;
|
||||
@@ -299,7 +384,7 @@ static void sdhci_led_control(struct led
|
||||
else
|
||||
sdhci_activate_led(host);
|
||||
out:
|
||||
- spin_unlock_irqrestore(&host->lock, flags);
|
||||
+ sdhci_spin_unlock_irqrestore(host, flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1007,7 +1092,9 @@ static void sdhci_send_command(struct sd
|
||||
return;
|
||||
}
|
||||
timeout--;
|
||||
+ sdhci_spin_enable_schedule(host);
|
||||
mdelay(1);
|
||||
+ sdhci_spin_disable_schedule(host);
|
||||
}
|
||||
DBG("send cmd %d - wait 0x%X irq 0x%x\n", cmd->opcode, mask,
|
||||
sdhci_readl(host, SDHCI_INT_STATUS));
|
||||
@@ -1234,7 +1321,9 @@ clock_set:
|
||||
return;
|
||||
}
|
||||
timeout--;
|
||||
+ sdhci_spin_enable_schedule(host);
|
||||
mdelay(1);
|
||||
+ sdhci_spin_disable_schedule(host);
|
||||
}
|
||||
|
||||
clk |= SDHCI_CLOCK_CARD_EN;
|
||||
@@ -1330,7 +1419,7 @@ static void sdhci_request(struct mmc_hos
|
||||
|
||||
sdhci_runtime_pm_get(host);
|
||||
|
||||
- spin_lock_irqsave(&host->lock, flags);
|
||||
+ sdhci_spin_lock_irqsave(host, &flags);
|
||||
|
||||
WARN_ON(host->mrq != NULL);
|
||||
|
||||
@@ -1388,9 +1477,9 @@ static void sdhci_request(struct mmc_hos
|
||||
mmc->card->type == MMC_TYPE_MMC ?
|
||||
MMC_SEND_TUNING_BLOCK_HS200 :
|
||||
MMC_SEND_TUNING_BLOCK;
|
||||
- spin_unlock_irqrestore(&host->lock, flags);
|
||||
+ sdhci_spin_unlock_irqrestore(host, flags);
|
||||
sdhci_execute_tuning(mmc, tuning_opcode);
|
||||
- spin_lock_irqsave(&host->lock, flags);
|
||||
+ sdhci_spin_lock_irqsave(host, &flags);
|
||||
|
||||
/* Restore original mmc_request structure */
|
||||
host->mrq = mrq;
|
||||
@@ -1404,7 +1493,7 @@ static void sdhci_request(struct mmc_hos
|
||||
}
|
||||
|
||||
mmiowb();
|
||||
- spin_unlock_irqrestore(&host->lock, flags);
|
||||
+ sdhci_spin_unlock_irqrestore(host, flags);
|
||||
}
|
||||
|
||||
static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
|
||||
@@ -1413,10 +1502,10 @@ static void sdhci_do_set_ios(struct sdhc
|
||||
int vdd_bit = -1;
|
||||
u8 ctrl;
|
||||
|
||||
- spin_lock_irqsave(&host->lock, flags);
|
||||
+ sdhci_spin_lock_irqsave(host, &flags);
|
||||
|
||||
if (host->flags & SDHCI_DEVICE_DEAD) {
|
||||
- spin_unlock_irqrestore(&host->lock, flags);
|
||||
+ sdhci_spin_unlock_irqrestore(host, flags);
|
||||
if (host->vmmc && ios->power_mode == MMC_POWER_OFF)
|
||||
mmc_regulator_set_ocr(host->mmc, host->vmmc, 0);
|
||||
return;
|
||||
@@ -1443,9 +1532,9 @@ static void sdhci_do_set_ios(struct sdhc
|
||||
vdd_bit = sdhci_set_power(host, ios->vdd);
|
||||
|
||||
if (host->vmmc && vdd_bit != -1) {
|
||||
- spin_unlock_irqrestore(&host->lock, flags);
|
||||
+ sdhci_spin_unlock_irqrestore(host, flags);
|
||||
mmc_regulator_set_ocr(host->mmc, host->vmmc, vdd_bit);
|
||||
- spin_lock_irqsave(&host->lock, flags);
|
||||
+ sdhci_spin_lock_irqsave(host, &flags);
|
||||
}
|
||||
|
||||
if (host->ops->platform_send_init_74_clocks)
|
||||
@@ -1583,7 +1672,7 @@ static void sdhci_do_set_ios(struct sdhc
|
||||
sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
|
||||
|
||||
mmiowb();
|
||||
- spin_unlock_irqrestore(&host->lock, flags);
|
||||
+ sdhci_spin_unlock_irqrestore(host, flags);
|
||||
}
|
||||
|
||||
static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
|
||||
@@ -1631,7 +1720,7 @@ static int sdhci_check_ro(struct sdhci_h
|
||||
unsigned long flags;
|
||||
int is_readonly;
|
||||
|
||||
- spin_lock_irqsave(&host->lock, flags);
|
||||
+ sdhci_spin_lock_irqsave(host, &flags);
|
||||
|
||||
if (host->flags & SDHCI_DEVICE_DEAD)
|
||||
is_readonly = 0;
|
||||
@@ -1641,7 +1730,7 @@ static int sdhci_check_ro(struct sdhci_h
|
||||
is_readonly = !(sdhci_readl(host, SDHCI_PRESENT_STATE)
|
||||
& SDHCI_WRITE_PROTECT);
|
||||
|
||||
- spin_unlock_irqrestore(&host->lock, flags);
|
||||
+ sdhci_spin_unlock_irqrestore(host, flags);
|
||||
|
||||
/* This quirk needs to be replaced by a callback-function later */
|
||||
return host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT ?
|
||||
@@ -1714,9 +1803,9 @@ static void sdhci_enable_sdio_irq(struct
|
||||
struct sdhci_host *host = mmc_priv(mmc);
|
||||
unsigned long flags;
|
||||
|
||||
- spin_lock_irqsave(&host->lock, flags);
|
||||
+ sdhci_spin_lock_irqsave(host, &flags);
|
||||
sdhci_enable_sdio_irq_nolock(host, enable);
|
||||
- spin_unlock_irqrestore(&host->lock, flags);
|
||||
+ sdhci_spin_unlock_irqrestore(host, flags);
|
||||
}
|
||||
|
||||
static int sdhci_do_start_signal_voltage_switch(struct sdhci_host *host,
|
||||
@@ -2060,7 +2149,7 @@ static void sdhci_card_event(struct mmc_
|
||||
struct sdhci_host *host = mmc_priv(mmc);
|
||||
unsigned long flags;
|
||||
|
||||
- spin_lock_irqsave(&host->lock, flags);
|
||||
+ sdhci_spin_lock_irqsave(host, &flags);
|
||||
|
||||
/* Check host->mrq first in case we are runtime suspended */
|
||||
if (host->mrq &&
|
||||
@@ -2077,7 +2166,7 @@ static void sdhci_card_event(struct mmc_
|
||||
tasklet_schedule(&host->finish_tasklet);
|
||||
}
|
||||
|
||||
- spin_unlock_irqrestore(&host->lock, flags);
|
||||
+ sdhci_spin_unlock_irqrestore(host, flags);
|
||||
}
|
||||
|
||||
static const struct mmc_host_ops sdhci_ops = {
|
||||
@@ -2116,14 +2205,14 @@ static void sdhci_tasklet_finish(unsigne
|
||||
|
||||
host = (struct sdhci_host*)param;
|
||||
|
||||
- spin_lock_irqsave(&host->lock, flags);
|
||||
+ sdhci_spin_lock_irqsave(host, &flags);
|
||||
|
||||
/*
|
||||
* If this tasklet gets rescheduled while running, it will
|
||||
* be run again afterwards but without any active request.
|
||||
*/
|
||||
if (!host->mrq) {
|
||||
- spin_unlock_irqrestore(&host->lock, flags);
|
||||
+ sdhci_spin_unlock_irqrestore(host, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2161,7 +2250,7 @@ static void sdhci_tasklet_finish(unsigne
|
||||
#endif
|
||||
|
||||
mmiowb();
|
||||
- spin_unlock_irqrestore(&host->lock, flags);
|
||||
+ sdhci_spin_unlock_irqrestore(host, flags);
|
||||
|
||||
mmc_request_done(host->mmc, mrq);
|
||||
sdhci_runtime_pm_put(host);
|
||||
@@ -2174,7 +2263,7 @@ static void sdhci_timeout_timer(unsigned
|
||||
|
||||
host = (struct sdhci_host*)data;
|
||||
|
||||
- spin_lock_irqsave(&host->lock, flags);
|
||||
+ sdhci_spin_lock_irqsave(host, &flags);
|
||||
|
||||
if (host->mrq) {
|
||||
pr_err("%s: Timeout waiting for hardware "
|
||||
@@ -2195,7 +2284,7 @@ static void sdhci_timeout_timer(unsigned
|
||||
}
|
||||
|
||||
mmiowb();
|
||||
- spin_unlock_irqrestore(&host->lock, flags);
|
||||
+ sdhci_spin_unlock_irqrestore(host, flags);
|
||||
}
|
||||
|
||||
static void sdhci_tuning_timer(unsigned long data)
|
||||
@@ -2205,11 +2294,11 @@ static void sdhci_tuning_timer(unsigned
|
||||
|
||||
host = (struct sdhci_host *)data;
|
||||
|
||||
- spin_lock_irqsave(&host->lock, flags);
|
||||
+ sdhci_spin_lock_irqsave(host, &flags);
|
||||
|
||||
host->flags |= SDHCI_NEEDS_RETUNING;
|
||||
|
||||
- spin_unlock_irqrestore(&host->lock, flags);
|
||||
+ sdhci_spin_unlock_irqrestore(host, flags);
|
||||
}
|
||||
|
||||
/*****************************************************************************\
|
||||
@@ -2433,10 +2522,10 @@ static irqreturn_t sdhci_irq(int irq, vo
|
||||
u32 intmask, unexpected = 0;
|
||||
int cardint = 0, max_loops = 16;
|
||||
|
||||
- spin_lock(&host->lock);
|
||||
+ sdhci_spin_lock(host);
|
||||
|
||||
if (host->runtime_suspended) {
|
||||
- spin_unlock(&host->lock);
|
||||
+ sdhci_spin_unlock(host);
|
||||
pr_warning("%s: got irq while runtime suspended\n",
|
||||
mmc_hostname(host->mmc));
|
||||
return IRQ_HANDLED;
|
||||
@@ -2540,7 +2629,7 @@ again:
|
||||
if (intmask && --max_loops)
|
||||
goto again;
|
||||
out:
|
||||
- spin_unlock(&host->lock);
|
||||
+ sdhci_spin_unlock(host);
|
||||
|
||||
if (unexpected) {
|
||||
pr_err("%s: Unexpected interrupt 0x%08x.\n",
|
||||
@@ -2702,15 +2791,15 @@ int sdhci_runtime_suspend_host(struct sd
|
||||
host->flags &= ~SDHCI_NEEDS_RETUNING;
|
||||
}
|
||||
|
||||
- spin_lock_irqsave(&host->lock, flags);
|
||||
+ sdhci_spin_lock_irqsave(host, &flags);
|
||||
sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK);
|
||||
- spin_unlock_irqrestore(&host->lock, flags);
|
||||
+ sdhci_spin_unlock_irqrestore(host, flags);
|
||||
|
||||
synchronize_irq(host->irq);
|
||||
|
||||
- spin_lock_irqsave(&host->lock, flags);
|
||||
+ sdhci_spin_lock_irqsave(host, &flags);
|
||||
host->runtime_suspended = true;
|
||||
- spin_unlock_irqrestore(&host->lock, flags);
|
||||
+ sdhci_spin_unlock_irqrestore(host, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -2736,16 +2825,16 @@ int sdhci_runtime_resume_host(struct sdh
|
||||
sdhci_do_start_signal_voltage_switch(host, &host->mmc->ios);
|
||||
if ((host_flags & SDHCI_PV_ENABLED) &&
|
||||
!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN)) {
|
||||
- spin_lock_irqsave(&host->lock, flags);
|
||||
+ sdhci_spin_lock_irqsave(host, &flags);
|
||||
sdhci_enable_preset_value(host, true);
|
||||
- spin_unlock_irqrestore(&host->lock, flags);
|
||||
+ sdhci_spin_unlock_irqrestore(host, flags);
|
||||
}
|
||||
|
||||
/* Set the re-tuning expiration flag */
|
||||
if (host->flags & SDHCI_USING_RETUNING_TIMER)
|
||||
host->flags |= SDHCI_NEEDS_RETUNING;
|
||||
|
||||
- spin_lock_irqsave(&host->lock, flags);
|
||||
+ sdhci_spin_lock_irqsave(host, &flags);
|
||||
|
||||
host->runtime_suspended = false;
|
||||
|
||||
@@ -2756,7 +2845,7 @@ int sdhci_runtime_resume_host(struct sdh
|
||||
/* Enable Card Detection */
|
||||
sdhci_enable_card_detection(host);
|
||||
|
||||
- spin_unlock_irqrestore(&host->lock, flags);
|
||||
+ sdhci_spin_unlock_irqrestore(host, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -3248,7 +3337,7 @@ int sdhci_add_host(struct sdhci_host *ho
|
||||
host->tuning_timer.function = sdhci_tuning_timer;
|
||||
}
|
||||
|
||||
- ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
|
||||
+ ret = request_irq(host->irq, sdhci_irq, 0,//IRQF_SHARED,
|
||||
mmc_hostname(mmc), host);
|
||||
if (ret) {
|
||||
pr_err("%s: Failed to request IRQ %d: %d\n",
|
||||
@@ -3312,7 +3401,7 @@ void sdhci_remove_host(struct sdhci_host
|
||||
unsigned long flags;
|
||||
|
||||
if (dead) {
|
||||
- spin_lock_irqsave(&host->lock, flags);
|
||||
+ sdhci_spin_lock_irqsave(host, &flags);
|
||||
|
||||
host->flags |= SDHCI_DEVICE_DEAD;
|
||||
|
||||
@@ -3324,7 +3413,7 @@ void sdhci_remove_host(struct sdhci_host
|
||||
tasklet_schedule(&host->finish_tasklet);
|
||||
}
|
||||
|
||||
- spin_unlock_irqrestore(&host->lock, flags);
|
||||
+ sdhci_spin_unlock_irqrestore(host, flags);
|
||||
}
|
||||
|
||||
sdhci_disable_card_detection(host);
|
||||
--- a/drivers/mmc/host/sdhci.h
|
||||
+++ b/drivers/mmc/host/sdhci.h
|
||||
@@ -441,4 +441,10 @@ extern int sdhci_runtime_suspend_host(st
|
||||
extern int sdhci_runtime_resume_host(struct sdhci_host *host);
|
||||
#endif
|
||||
|
||||
+extern void sdhci_spin_lock_irqsave(struct sdhci_host *host,unsigned long *flags);
|
||||
+extern void sdhci_spin_unlock_irqrestore(struct sdhci_host *host,unsigned long flags);
|
||||
+extern void sdhci_spin_lock(struct sdhci_host *host);
|
||||
+extern void sdhci_spin_unlock(struct sdhci_host *host);
|
||||
+
|
||||
+
|
||||
#endif /* __SDHCI_HW_H */
|
||||
--- a/include/linux/mmc/sdhci.h
|
||||
+++ b/include/linux/mmc/sdhci.h
|
||||
@@ -97,6 +97,7 @@ struct sdhci_host {
|
||||
#define SDHCI_QUIRK2_PRESET_VALUE_BROKEN (1<<3)
|
||||
|
||||
int irq; /* Device IRQ */
|
||||
+ int second_irq; /* Additional IRQ to disable/enable in low-latency mode */
|
||||
void __iomem *ioaddr; /* Mapped address */
|
||||
|
||||
const struct sdhci_ops *ops; /* Low level hw interface */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,31 @@
|
|||
From dae7c3832370e9a807907128ce37070f40fbb882 Mon Sep 17 00:00:00 2001
|
||||
From: Jo Are By <grimjoey@gmail.com>
|
||||
Date: Sun, 17 Mar 2013 17:45:41 +0100
|
||||
Subject: [PATCH 029/174] Add device ID (330d)
|
||||
|
||||
---
|
||||
drivers/net/wireless/rtl8192cu/hal/rtl8192c/usb/usb_halinit.c | 2 ++
|
||||
drivers/net/wireless/rtl8192cu/os_dep/linux/usb_intf.c | 1 +
|
||||
2 files changed, 3 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/rtl8192cu/hal/rtl8192c/usb/usb_halinit.c
|
||||
+++ b/drivers/net/wireless/rtl8192cu/hal/rtl8192c/usb/usb_halinit.c
|
||||
@@ -3786,6 +3786,8 @@ _ReadIDs(
|
||||
pHalData->CustomerID = RT_CID_DLINK;
|
||||
else if((pHalData->EEPROMVID == 0x2001) && (pHalData->EEPROMPID == 0x330a))
|
||||
pHalData->CustomerID = RT_CID_DLINK;
|
||||
+ else if((pHalData->EEPROMVID == 0x2001) && (pHalData->EEPROMPID == 0x330d))
|
||||
+ pHalData->CustomerID = RT_CID_DLINK;
|
||||
break;
|
||||
case EEPROM_CID_WHQL:
|
||||
/*
|
||||
--- a/drivers/net/wireless/rtl8192cu/os_dep/linux/usb_intf.c
|
||||
+++ b/drivers/net/wireless/rtl8192cu/os_dep/linux/usb_intf.c
|
||||
@@ -137,6 +137,7 @@ static struct usb_device_id rtw_usb_id_t
|
||||
{USB_DEVICE(0x2001, 0x3307)},//D-Link - Cameo
|
||||
{USB_DEVICE(0x2001, 0x330A)},//D-Link - Alpha
|
||||
{USB_DEVICE(0x2001, 0x3309)},//D-Link - Alpha
|
||||
+ {USB_DEVICE(0x2001, 0x330D)},//D-Link - Alpha(?)
|
||||
{USB_DEVICE(0x0586, 0x341F)},//Zyxel - Abocom
|
||||
{USB_DEVICE(0x7392, 0x7822)},//Edimax - Edimax
|
||||
{USB_DEVICE(0x2019, 0xAB2B)},//Planex - Abocom
|
|
@ -0,0 +1,98 @@
|
|||
From f56b0b76fdd4b17bd359536ae926c4cb04706e54 Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Sat, 8 Sep 2012 15:17:53 +0100
|
||||
Subject: [PATCH 030/174] Avoid dynamic memory allocation for channel lock in
|
||||
USB driver. Thanks ddv2005.
|
||||
|
||||
---
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 6 +++---
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd.h | 2 +-
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd_ddma.c | 3 +--
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 3 +--
|
||||
4 files changed, 6 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
|
||||
@@ -822,6 +822,7 @@ static void dwc_otg_hcd_free(dwc_otg_hcd
|
||||
} else if (dwc_otg_hcd->status_buf != NULL) {
|
||||
DWC_FREE(dwc_otg_hcd->status_buf);
|
||||
}
|
||||
+ DWC_SPINLOCK_FREE(dwc_otg_hcd->channel_lock);
|
||||
DWC_SPINLOCK_FREE(dwc_otg_hcd->lock);
|
||||
/* Set core_if's lock pointer to NULL */
|
||||
dwc_otg_hcd->core_if->lock = NULL;
|
||||
@@ -848,6 +849,7 @@ int dwc_otg_hcd_init(dwc_otg_hcd_t * hcd
|
||||
dwc_hc_t *channel;
|
||||
|
||||
hcd->lock = DWC_SPINLOCK_ALLOC();
|
||||
+ hcd->channel_lock = DWC_SPINLOCK_ALLOC();
|
||||
DWC_DEBUGPL(DBG_HCDV, "init of HCD %p given core_if %p\n",
|
||||
hcd, core_if);
|
||||
if (!hcd->lock) {
|
||||
@@ -1248,7 +1250,7 @@ dwc_otg_transaction_type_e dwc_otg_hcd_s
|
||||
dwc_otg_qh_t *qh;
|
||||
int num_channels;
|
||||
dwc_irqflags_t flags;
|
||||
- dwc_spinlock_t *channel_lock = DWC_SPINLOCK_ALLOC();
|
||||
+ dwc_spinlock_t *channel_lock = hcd->channel_lock;
|
||||
dwc_otg_transaction_type_e ret_val = DWC_OTG_TRANSACTION_NONE;
|
||||
|
||||
#ifdef DEBUG_SOF
|
||||
@@ -1348,8 +1350,6 @@ dwc_otg_transaction_type_e dwc_otg_hcd_s
|
||||
#ifdef DEBUG_HOST_CHANNELS
|
||||
last_sel_trans_num_avail_hc_at_end = hcd->available_host_channels;
|
||||
#endif /* DEBUG_HOST_CHANNELS */
|
||||
-
|
||||
- DWC_SPINLOCK_FREE(channel_lock);
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.h
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.h
|
||||
@@ -548,7 +548,7 @@ struct dwc_otg_hcd {
|
||||
|
||||
/* */
|
||||
dwc_spinlock_t *lock;
|
||||
-
|
||||
+ dwc_spinlock_t *channel_lock;
|
||||
/**
|
||||
* Private data that could be used by OS wrapper.
|
||||
*/
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_ddma.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_ddma.c
|
||||
@@ -276,7 +276,7 @@ void dump_frame_list(dwc_otg_hcd_t * hcd
|
||||
static void release_channel_ddma(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh)
|
||||
{
|
||||
dwc_irqflags_t flags;
|
||||
- dwc_spinlock_t *channel_lock = DWC_SPINLOCK_ALLOC();
|
||||
+ dwc_spinlock_t *channel_lock = hcd->channel_lock;
|
||||
|
||||
dwc_hc_t *hc = qh->channel;
|
||||
if (dwc_qh_is_non_per(qh)) {
|
||||
@@ -306,7 +306,6 @@ static void release_channel_ddma(dwc_otg
|
||||
dwc_memset(qh->desc_list, 0x00,
|
||||
sizeof(dwc_otg_host_dma_desc_t) * max_desc_num(qh));
|
||||
}
|
||||
- DWC_SPINLOCK_FREE(channel_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
|
||||
@@ -922,7 +922,7 @@ static void release_channel(dwc_otg_hcd_
|
||||
dwc_otg_transaction_type_e tr_type;
|
||||
int free_qtd;
|
||||
dwc_irqflags_t flags;
|
||||
- dwc_spinlock_t *channel_lock = DWC_SPINLOCK_ALLOC();
|
||||
+ dwc_spinlock_t *channel_lock = hcd->channel_lock;
|
||||
|
||||
DWC_DEBUGPL(DBG_HCDV, " %s: channel %d, halt_status %d, xfer_len %d\n",
|
||||
__func__, hc->hc_num, halt_status, hc->xfer_len);
|
||||
@@ -1009,7 +1009,6 @@ cleanup:
|
||||
if (tr_type != DWC_OTG_TRANSACTION_NONE) {
|
||||
dwc_otg_hcd_queue_transactions(hcd, tr_type);
|
||||
}
|
||||
- DWC_SPINLOCK_FREE(channel_lock);
|
||||
}
|
||||
|
||||
/**
|
|
@ -1,3 +1,50 @@
|
|||
From d19db6057337b577baab7766718781d55c402fbb Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Sat, 2 Nov 2013 22:44:41 +0000
|
||||
Subject: [PATCH 031/174] Add cpufreq driver
|
||||
|
||||
---
|
||||
arch/arm/Kconfig | 1 +
|
||||
drivers/cpufreq/Kconfig.arm | 8 ++
|
||||
drivers/cpufreq/Makefile | 1 +
|
||||
drivers/cpufreq/bcm2835-cpufreq.c | 239 ++++++++++++++++++++++++++++++++++++++
|
||||
4 files changed, 249 insertions(+)
|
||||
create mode 100755 drivers/cpufreq/bcm2835-cpufreq.c
|
||||
|
||||
--- a/arch/arm/Kconfig
|
||||
+++ b/arch/arm/Kconfig
|
||||
@@ -369,6 +369,7 @@ config ARCH_BCM2708
|
||||
select HAVE_SCHED_CLOCK
|
||||
select NEED_MACH_MEMORY_H
|
||||
select CLKDEV_LOOKUP
|
||||
+ select ARCH_HAS_CPUFREQ
|
||||
select GENERIC_CLOCKEVENTS
|
||||
select ARM_ERRATA_411920
|
||||
select MACH_BCM2708
|
||||
--- a/drivers/cpufreq/Kconfig.arm
|
||||
+++ b/drivers/cpufreq/Kconfig.arm
|
||||
@@ -150,3 +150,11 @@ config ARM_SPEAR_CPUFREQ
|
||||
default y
|
||||
help
|
||||
This adds the CPUFreq driver support for SPEAr SOCs.
|
||||
+
|
||||
+config ARM_BCM2835_CPUFREQ
|
||||
+ bool "BCM2835 Driver"
|
||||
+ default y
|
||||
+ help
|
||||
+ This adds the CPUFreq driver for BCM2835
|
||||
+
|
||||
+ If in doubt, say N.
|
||||
--- a/drivers/cpufreq/Makefile
|
||||
+++ b/drivers/cpufreq/Makefile
|
||||
@@ -72,6 +72,7 @@ obj-$(CONFIG_ARM_SA1100_CPUFREQ) += sa11
|
||||
obj-$(CONFIG_ARM_SA1110_CPUFREQ) += sa1110-cpufreq.o
|
||||
obj-$(CONFIG_ARM_SPEAR_CPUFREQ) += spear-cpufreq.o
|
||||
obj-$(CONFIG_ARCH_TEGRA) += tegra-cpufreq.o
|
||||
+obj-$(CONFIG_ARM_BCM2835_CPUFREQ) += bcm2835-cpufreq.o
|
||||
|
||||
##################################################################################
|
||||
# PowerPC platform drivers
|
||||
--- /dev/null
|
||||
+++ b/drivers/cpufreq/bcm2835-cpufreq.c
|
||||
@@ -0,0 +1,239 @@
|
||||
|
@ -240,27 +287,3 @@
|
|||
+module_init(bcm2835_cpufreq_module_init);
|
||||
+module_exit(bcm2835_cpufreq_module_exit);
|
||||
+
|
||||
--- a/drivers/cpufreq/Kconfig.arm
|
||||
+++ b/drivers/cpufreq/Kconfig.arm
|
||||
@@ -150,3 +150,11 @@ config ARM_SPEAR_CPUFREQ
|
||||
default y
|
||||
help
|
||||
This adds the CPUFreq driver support for SPEAr SOCs.
|
||||
+
|
||||
+config ARM_BCM2835_CPUFREQ
|
||||
+ bool "BCM2835 Driver"
|
||||
+ default y
|
||||
+ help
|
||||
+ This adds the CPUFreq driver for BCM2835
|
||||
+
|
||||
+ If in doubt, say N.
|
||||
--- a/drivers/cpufreq/Makefile
|
||||
+++ b/drivers/cpufreq/Makefile
|
||||
@@ -72,6 +72,7 @@ obj-$(CONFIG_ARM_SA1100_CPUFREQ) += sa11
|
||||
obj-$(CONFIG_ARM_SA1110_CPUFREQ) += sa1110-cpufreq.o
|
||||
obj-$(CONFIG_ARM_SPEAR_CPUFREQ) += spear-cpufreq.o
|
||||
obj-$(CONFIG_ARCH_TEGRA) += tegra-cpufreq.o
|
||||
+obj-$(CONFIG_ARM_BCM2835_CPUFREQ) += bcm2835-cpufreq.o
|
||||
|
||||
##################################################################################
|
||||
# PowerPC platform drivers
|
|
@ -0,0 +1,199 @@
|
|||
From 99e6d36a5f752bb0237a61143bea29c93e6da22c Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Mon, 8 Apr 2013 21:12:48 +0100
|
||||
Subject: [PATCH 032/174] Add NAK holdoff scheme. Enabled by default, disable
|
||||
with dwc_otg.nak_holdoff_enable=0. Thanks gsh
|
||||
|
||||
---
|
||||
drivers/usb/host/dwc_otg/dwc_otg_driver.c | 7 ++++++-
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 22 +++++++++++++++++++++-
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd.h | 5 +++++
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 21 +++++++++++++++++++--
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 19 +++++++++++++++++++
|
||||
5 files changed, 70 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_driver.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_driver.c
|
||||
@@ -243,6 +243,9 @@ static struct dwc_otg_driver_module_para
|
||||
//Global variable to switch the fiq fix on or off (declared in bcm2708.c)
|
||||
extern bool fiq_fix_enable;
|
||||
|
||||
+//Global variable to switch the nak holdoff on or off
|
||||
+bool nak_holdoff_enable = true;
|
||||
+
|
||||
|
||||
/**
|
||||
* This function shows the Driver Version.
|
||||
@@ -1086,6 +1089,7 @@ static int __init dwc_otg_driver_init(vo
|
||||
return retval;
|
||||
}
|
||||
printk(KERN_DEBUG "dwc_otg: FIQ %s\n", fiq_fix_enable ? "enabled":"disabled");
|
||||
+ printk(KERN_DEBUG "dwc_otg: NAK holdoff %s\n", nak_holdoff_enable ? "enabled":"disabled");
|
||||
|
||||
error = driver_create_file(drv, &driver_attr_version);
|
||||
#ifdef DEBUG
|
||||
@@ -1366,9 +1370,10 @@ MODULE_PARM_DESC(otg_ver, "OTG revision
|
||||
module_param(microframe_schedule, bool, 0444);
|
||||
MODULE_PARM_DESC(microframe_schedule, "Enable the microframe scheduler");
|
||||
|
||||
-
|
||||
module_param(fiq_fix_enable, bool, 0444);
|
||||
MODULE_PARM_DESC(fiq_fix_enable, "Enable the fiq fix");
|
||||
+module_param(nak_holdoff_enable, bool, 0444);
|
||||
+MODULE_PARM_DESC(nak_holdoff_enable, "Enable the NAK holdoff");
|
||||
|
||||
/** @page "Module Parameters"
|
||||
*
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
|
||||
@@ -527,6 +527,8 @@ int dwc_otg_hcd_urb_dequeue(dwc_otg_hcd_
|
||||
{
|
||||
dwc_otg_qh_t *qh;
|
||||
dwc_otg_qtd_t *urb_qtd;
|
||||
+ BUG_ON(!hcd);
|
||||
+ BUG_ON(!dwc_otg_urb);
|
||||
|
||||
#ifdef DEBUG /* integrity checks (Broadcom) */
|
||||
|
||||
@@ -543,14 +545,17 @@ int dwc_otg_hcd_urb_dequeue(dwc_otg_hcd_
|
||||
return -DWC_E_INVALID;
|
||||
}
|
||||
urb_qtd = dwc_otg_urb->qtd;
|
||||
+ BUG_ON(!urb_qtd);
|
||||
if (urb_qtd->qh == NULL) {
|
||||
DWC_ERROR("**** DWC OTG HCD URB Dequeue with QTD with NULL Q handler\n");
|
||||
return -DWC_E_INVALID;
|
||||
}
|
||||
#else
|
||||
urb_qtd = dwc_otg_urb->qtd;
|
||||
+ BUG_ON(!urb_qtd);
|
||||
#endif
|
||||
qh = urb_qtd->qh;
|
||||
+ BUG_ON(!qh);
|
||||
if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
|
||||
if (urb_qtd->in_process) {
|
||||
dump_channel_info(hcd, qh);
|
||||
@@ -1309,6 +1314,22 @@ dwc_otg_transaction_type_e dwc_otg_hcd_s
|
||||
num_channels - hcd->periodic_channels) &&
|
||||
!DWC_CIRCLEQ_EMPTY(&hcd->free_hc_list)) {
|
||||
|
||||
+ qh = DWC_LIST_ENTRY(qh_ptr, dwc_otg_qh_t, qh_list_entry);
|
||||
+
|
||||
+ /*
|
||||
+ * Check to see if this is a NAK'd retransmit, in which case ignore for retransmission
|
||||
+ * we hold off on bulk retransmissions to reduce NAK interrupt overhead for
|
||||
+ * cheeky devices that just hold off using NAKs
|
||||
+ */
|
||||
+ if (dwc_full_frame_num(qh->nak_frame) == dwc_full_frame_num(dwc_otg_hcd_get_frame_number(hcd))) {
|
||||
+ // Make fiq interrupt run on next frame (i.e. 8 uframes)
|
||||
+ g_next_sched_frame = ((qh->nak_frame + 8) & ~7) & DWC_HFNUM_MAX_FRNUM;
|
||||
+ qh_ptr = DWC_LIST_NEXT(qh_ptr);
|
||||
+ continue;
|
||||
+ }
|
||||
+ else
|
||||
+ qh->nak_frame = 0xffff;
|
||||
+
|
||||
if (microframe_schedule) {
|
||||
DWC_SPINLOCK_IRQSAVE(channel_lock, &flags);
|
||||
if (hcd->available_host_channels < 1) {
|
||||
@@ -1321,7 +1342,6 @@ dwc_otg_transaction_type_e dwc_otg_hcd_s
|
||||
last_sel_trans_num_nonper_scheduled++;
|
||||
#endif /* DEBUG_HOST_CHANNELS */
|
||||
}
|
||||
- qh = DWC_LIST_ENTRY(qh_ptr, dwc_otg_qh_t, qh_list_entry);
|
||||
|
||||
assign_and_init_hc(hcd, qh);
|
||||
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.h
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.h
|
||||
@@ -321,6 +321,11 @@ typedef struct dwc_otg_qh {
|
||||
*/
|
||||
uint16_t sched_frame;
|
||||
|
||||
+ /*
|
||||
+ ** Frame a NAK was received on this queue head, used to minimise NAK retransmission
|
||||
+ */
|
||||
+ uint16_t nak_frame;
|
||||
+
|
||||
/** (micro)frame at which last start split was initialized. */
|
||||
uint16_t start_split_frame;
|
||||
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
|
||||
@@ -56,7 +56,12 @@ int fiq_done, int_done;
|
||||
int g_next_sched_frame, g_np_count, g_np_sent, g_work_expected;
|
||||
static int mphi_int_count = 0 ;
|
||||
|
||||
-extern bool fiq_fix_enable;
|
||||
+extern bool fiq_fix_enable, nak_holdoff_enable;
|
||||
+
|
||||
+hcchar_data_t nak_hcchar;
|
||||
+hctsiz_data_t nak_hctsiz;
|
||||
+hcsplt_data_t nak_hcsplt;
|
||||
+int nak_count;
|
||||
|
||||
void __attribute__ ((naked)) dwc_otg_hcd_handle_fiq(void)
|
||||
{
|
||||
@@ -230,7 +235,7 @@ exit_handler_routine:
|
||||
DWC_WRITE_REG32(c_mphi_regs.ctrl, (1<<31));
|
||||
mphi_int_count = 0;
|
||||
}
|
||||
- int_done++;
|
||||
+ int_done++;
|
||||
if((jiffies / HZ) > last_time)
|
||||
{
|
||||
/* Once a second output the fiq and irq numbers, useful for debug */
|
||||
@@ -1419,6 +1424,18 @@ static int32_t handle_hc_nak_intr(dwc_ot
|
||||
"NAK Received--\n", hc->hc_num);
|
||||
|
||||
/*
|
||||
+ * When we get bulk NAKs then remember this so we holdoff on this qh until
|
||||
+ * the beginning of the next frame
|
||||
+ */
|
||||
+ switch(dwc_otg_hcd_get_pipe_type(&qtd->urb->pipe_info)) {
|
||||
+ case UE_BULK:
|
||||
+ //case UE_INTERRUPT:
|
||||
+ //case UE_CONTROL:
|
||||
+ if (nak_holdoff_enable)
|
||||
+ hc->qh->nak_frame = dwc_otg_hcd_get_frame_number(hcd);
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
* Handle NAK for IN/OUT SSPLIT/CSPLIT transfers, bulk, control, and
|
||||
* interrupt. Re-start the SSPLIT transfer.
|
||||
*/
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c
|
||||
@@ -181,6 +181,7 @@ void qh_init(dwc_otg_hcd_t * hcd, dwc_ot
|
||||
if (microframe_schedule)
|
||||
qh->speed = dev_speed;
|
||||
|
||||
+ qh->nak_frame = 0xffff;
|
||||
|
||||
if (((dev_speed == USB_SPEED_LOW) ||
|
||||
(dev_speed == USB_SPEED_FULL)) &&
|
||||
@@ -764,6 +765,24 @@ void dwc_otg_hcd_qh_deactivate(dwc_otg_h
|
||||
int sched_next_periodic_split)
|
||||
{
|
||||
if (dwc_qh_is_non_per(qh)) {
|
||||
+
|
||||
+ dwc_otg_qh_t *qh_tmp;
|
||||
+ dwc_list_link_t *qh_list;
|
||||
+ DWC_LIST_FOREACH(qh_list, &hcd->non_periodic_sched_inactive)
|
||||
+ {
|
||||
+ qh_tmp = DWC_LIST_ENTRY(qh_list, struct dwc_otg_qh, qh_list_entry);
|
||||
+ if(qh_tmp == qh)
|
||||
+ {
|
||||
+ /*
|
||||
+ * FIQ is being disabled because this one nevers gets a np_count increment
|
||||
+ * This is still not absolutely correct, but it should fix itself with
|
||||
+ * just an unnecessary extra interrupt
|
||||
+ */
|
||||
+ g_np_sent = g_np_count;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+
|
||||
dwc_otg_hcd_qh_remove(hcd, qh);
|
||||
if (!DWC_CIRCLEQ_EMPTY(&qh->qtd_list)) {
|
||||
/* Add back to inactive non-periodic schedule. */
|
|
@ -0,0 +1,519 @@
|
|||
From 40934fa5ae748fab27146883be929d4190b35c16 Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Tue, 26 Mar 2013 19:24:24 +0000
|
||||
Subject: [PATCH 033/174] Added hwmon/thermal driver for reporting core
|
||||
temperature. Thanks Dorian
|
||||
|
||||
---
|
||||
arch/arm/mach-bcm2708/bcm2708.c | 11 ++
|
||||
drivers/hwmon/Kconfig | 10 ++
|
||||
drivers/hwmon/Makefile | 1 +
|
||||
drivers/hwmon/bcm2835-hwmon.c | 219 ++++++++++++++++++++++++++++++++++++++
|
||||
drivers/thermal/Kconfig | 7 ++
|
||||
drivers/thermal/Makefile | 1 +
|
||||
drivers/thermal/bcm2835-thermal.c | 208 ++++++++++++++++++++++++++++++++++++
|
||||
7 files changed, 457 insertions(+)
|
||||
create mode 100644 drivers/hwmon/bcm2835-hwmon.c
|
||||
create mode 100644 drivers/thermal/bcm2835-thermal.c
|
||||
|
||||
--- a/arch/arm/mach-bcm2708/bcm2708.c
|
||||
+++ b/arch/arm/mach-bcm2708/bcm2708.c
|
||||
@@ -562,6 +562,14 @@ static struct platform_device bcm2708_bs
|
||||
.resource = bcm2708_bsc1_resources,
|
||||
};
|
||||
|
||||
+static struct platform_device bcm2835_hwmon_device = {
|
||||
+ .name = "bcm2835_hwmon",
|
||||
+};
|
||||
+
|
||||
+static struct platform_device bcm2835_thermal_device = {
|
||||
+ .name = "bcm2835_thermal",
|
||||
+};
|
||||
+
|
||||
int __init bcm_register_device(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
@@ -682,6 +690,9 @@ void __init bcm2708_init(void)
|
||||
bcm_register_device(&bcm2708_bsc0_device);
|
||||
bcm_register_device(&bcm2708_bsc1_device);
|
||||
|
||||
+ bcm_register_device(&bcm2835_hwmon_device);
|
||||
+ bcm_register_device(&bcm2835_thermal_device);
|
||||
+
|
||||
for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
|
||||
struct amba_device *d = amba_devs[i];
|
||||
amba_device_register(d, &iomem_resource);
|
||||
--- a/drivers/hwmon/Kconfig
|
||||
+++ b/drivers/hwmon/Kconfig
|
||||
@@ -1537,6 +1537,16 @@ config SENSORS_MC13783_ADC
|
||||
help
|
||||
Support for the A/D converter on MC13783 and MC13892 PMIC.
|
||||
|
||||
+config SENSORS_BCM2835
|
||||
+ depends on THERMAL_BCM2835=n
|
||||
+ tristate "Broadcom BCM2835 HWMON Driver"
|
||||
+ help
|
||||
+ If you say yes here you get support for the hardware
|
||||
+ monitoring features of the BCM2835 Chip
|
||||
+
|
||||
+ This driver can also be built as a module. If so, the module
|
||||
+ will be called bcm2835-hwmon.
|
||||
+
|
||||
if ACPI
|
||||
|
||||
comment "ACPI drivers"
|
||||
--- /dev/null
|
||||
+++ b/drivers/hwmon/bcm2835-hwmon.c
|
||||
@@ -0,0 +1,219 @@
|
||||
+/*****************************************************************************
|
||||
+* Copyright 2011 Broadcom Corporation. All rights reserved.
|
||||
+*
|
||||
+* Unless you and Broadcom execute a separate written software license
|
||||
+* agreement governing use of this software, this software is licensed to you
|
||||
+* under the terms of the GNU General Public License version 2, available at
|
||||
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
|
||||
+*
|
||||
+* Notwithstanding the above, under no circumstances may you combine this
|
||||
+* software in any way with any other Broadcom software provided under a
|
||||
+* license other than the GPL, without Broadcom's express prior written
|
||||
+* consent.
|
||||
+*****************************************************************************/
|
||||
+
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/hwmon.h>
|
||||
+#include <linux/hwmon-sysfs.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/sysfs.h>
|
||||
+#include <mach/vcio.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/err.h>
|
||||
+
|
||||
+#define MODULE_NAME "bcm2835_hwmon"
|
||||
+
|
||||
+/*#define HWMON_DEBUG_ENABLE*/
|
||||
+
|
||||
+#ifdef HWMON_DEBUG_ENABLE
|
||||
+#define print_debug(fmt,...) printk(KERN_INFO "%s:%s:%d: "fmt"\n", MODULE_NAME, __func__, __LINE__, ##__VA_ARGS__)
|
||||
+#else
|
||||
+#define print_debug(fmt,...)
|
||||
+#endif
|
||||
+#define print_err(fmt,...) printk(KERN_ERR "%s:%s:%d: "fmt"\n", MODULE_NAME, __func__,__LINE__, ##__VA_ARGS__)
|
||||
+#define print_info(fmt,...) printk(KERN_INFO "%s: "fmt"\n", MODULE_NAME, ##__VA_ARGS__)
|
||||
+
|
||||
+#define VC_TAG_GET_TEMP 0x00030006
|
||||
+#define VC_TAG_GET_MAX_TEMP 0x0003000A
|
||||
+
|
||||
+/* --- STRUCTS --- */
|
||||
+struct bcm2835_hwmon_data {
|
||||
+ struct device *hwmon_dev;
|
||||
+};
|
||||
+
|
||||
+/* tag part of the message */
|
||||
+struct vc_msg_tag {
|
||||
+ uint32_t tag_id; /* the tag ID for the temperature */
|
||||
+ uint32_t buffer_size; /* size of the buffer (should be 8) */
|
||||
+ uint32_t request_code; /* identifies message as a request (should be 0) */
|
||||
+ uint32_t id; /* extra ID field (should be 0) */
|
||||
+ uint32_t val; /* returned value of the temperature */
|
||||
+};
|
||||
+
|
||||
+/* message structure to be sent to videocore */
|
||||
+struct vc_msg {
|
||||
+ uint32_t msg_size; /* simply, sizeof(struct vc_msg) */
|
||||
+ uint32_t request_code; /* holds various information like the success and number of bytes returned (refer to mailboxes wiki) */
|
||||
+ struct vc_msg_tag tag; /* the tag structure above to make */
|
||||
+ uint32_t end_tag; /* an end identifier, should be set to NULL */
|
||||
+};
|
||||
+
|
||||
+typedef enum {
|
||||
+ TEMP,
|
||||
+ MAX_TEMP,
|
||||
+} temp_type;
|
||||
+
|
||||
+/* --- PROTOTYPES --- */
|
||||
+static ssize_t bcm2835_get_temp(struct device *dev, struct device_attribute *attr, char *buf);
|
||||
+static ssize_t bcm2835_get_name(struct device *dev, struct device_attribute *attr, char *buf);
|
||||
+
|
||||
+/* --- GLOBALS --- */
|
||||
+
|
||||
+static struct bcm2835_hwmon_data *bcm2835_data;
|
||||
+static struct platform_driver bcm2835_hwmon_driver;
|
||||
+
|
||||
+static SENSOR_DEVICE_ATTR(name, S_IRUGO,bcm2835_get_name,NULL,0);
|
||||
+static SENSOR_DEVICE_ATTR(temp1_input,S_IRUGO,bcm2835_get_temp,NULL,TEMP);
|
||||
+static SENSOR_DEVICE_ATTR(temp1_max,S_IRUGO,bcm2835_get_temp,NULL,MAX_TEMP);
|
||||
+
|
||||
+static struct attribute* bcm2835_attributes[] = {
|
||||
+ &sensor_dev_attr_name.dev_attr.attr,
|
||||
+ &sensor_dev_attr_temp1_input.dev_attr.attr,
|
||||
+ &sensor_dev_attr_temp1_max.dev_attr.attr,
|
||||
+ NULL,
|
||||
+};
|
||||
+
|
||||
+static struct attribute_group bcm2835_attr_group = {
|
||||
+ .attrs = bcm2835_attributes,
|
||||
+};
|
||||
+
|
||||
+/* --- FUNCTIONS --- */
|
||||
+
|
||||
+static ssize_t bcm2835_get_name(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
+{
|
||||
+ return sprintf(buf,"bcm2835_hwmon\n");
|
||||
+}
|
||||
+
|
||||
+static ssize_t bcm2835_get_temp(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
+{
|
||||
+ struct vc_msg msg;
|
||||
+ int result;
|
||||
+ uint temp = 0;
|
||||
+ int index = ((struct sensor_device_attribute*)to_sensor_dev_attr(attr))->index;
|
||||
+
|
||||
+ print_debug("IN");
|
||||
+
|
||||
+ /* wipe all previous message data */
|
||||
+ memset(&msg, 0, sizeof msg);
|
||||
+
|
||||
+ /* determine the message type */
|
||||
+ if(index == TEMP)
|
||||
+ msg.tag.tag_id = VC_TAG_GET_TEMP;
|
||||
+ else if (index == MAX_TEMP)
|
||||
+ msg.tag.tag_id = VC_TAG_GET_MAX_TEMP;
|
||||
+ else
|
||||
+ {
|
||||
+ print_debug("Unknown temperature message!");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ msg.msg_size = sizeof msg;
|
||||
+ msg.tag.buffer_size = 8;
|
||||
+
|
||||
+ /* send the message */
|
||||
+ result = bcm_mailbox_property(&msg, sizeof msg);
|
||||
+
|
||||
+ /* check if it was all ok and return the rate in milli degrees C */
|
||||
+ if (result == 0 && (msg.request_code & 0x80000000))
|
||||
+ temp = (uint)msg.tag.val;
|
||||
+ #ifdef HWMON_DEBUG_ENABLE
|
||||
+ else
|
||||
+ print_debug("Failed to get temperature!");
|
||||
+ #endif
|
||||
+ print_debug("Got temperature as %u",temp);
|
||||
+ print_debug("OUT");
|
||||
+ return sprintf(buf, "%u\n", temp);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static int bcm2835_hwmon_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ int err;
|
||||
+
|
||||
+ print_debug("IN");
|
||||
+ print_debug("HWMON Driver has been probed!");
|
||||
+
|
||||
+ /* check that the device isn't null!*/
|
||||
+ if(pdev == NULL)
|
||||
+ {
|
||||
+ print_debug("Platform device is empty!");
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
+ /* allocate memory for neccessary data */
|
||||
+ bcm2835_data = kzalloc(sizeof(struct bcm2835_hwmon_data),GFP_KERNEL);
|
||||
+ if(!bcm2835_data)
|
||||
+ {
|
||||
+ print_debug("Unable to allocate memory for hwmon data!");
|
||||
+ err = -ENOMEM;
|
||||
+ goto kzalloc_error;
|
||||
+ }
|
||||
+
|
||||
+ /* create the sysfs files */
|
||||
+ if(sysfs_create_group(&pdev->dev.kobj, &bcm2835_attr_group))
|
||||
+ {
|
||||
+ print_debug("Unable to create sysfs files!");
|
||||
+ err = -EFAULT;
|
||||
+ goto sysfs_error;
|
||||
+ }
|
||||
+
|
||||
+ /* register the hwmon device */
|
||||
+ bcm2835_data->hwmon_dev = hwmon_device_register(&pdev->dev);
|
||||
+ if (IS_ERR(bcm2835_data->hwmon_dev))
|
||||
+ {
|
||||
+ err = PTR_ERR(bcm2835_data->hwmon_dev);
|
||||
+ goto hwmon_error;
|
||||
+ }
|
||||
+ print_debug("OUT");
|
||||
+ return 0;
|
||||
+
|
||||
+ /* error goto's */
|
||||
+ hwmon_error:
|
||||
+ sysfs_remove_group(&pdev->dev.kobj, &bcm2835_attr_group);
|
||||
+
|
||||
+ sysfs_error:
|
||||
+ kfree(bcm2835_data);
|
||||
+
|
||||
+ kzalloc_error:
|
||||
+
|
||||
+ return err;
|
||||
+
|
||||
+}
|
||||
+
|
||||
+static int bcm2835_hwmon_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ print_debug("IN");
|
||||
+ hwmon_device_unregister(bcm2835_data->hwmon_dev);
|
||||
+
|
||||
+ sysfs_remove_group(&pdev->dev.kobj, &bcm2835_attr_group);
|
||||
+ print_debug("OUT");
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* Hwmon Driver */
|
||||
+static struct platform_driver bcm2835_hwmon_driver = {
|
||||
+ .probe = bcm2835_hwmon_probe,
|
||||
+ .remove = bcm2835_hwmon_remove,
|
||||
+ .driver = {
|
||||
+ .name = "bcm2835_hwmon",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+MODULE_LICENSE("GPL");
|
||||
+MODULE_AUTHOR("Dorian Peake");
|
||||
+MODULE_DESCRIPTION("HW Monitor driver for bcm2835 chip");
|
||||
+
|
||||
+module_platform_driver(bcm2835_hwmon_driver);
|
||||
--- a/drivers/thermal/Kconfig
|
||||
+++ b/drivers/thermal/Kconfig
|
||||
@@ -169,4 +169,11 @@ config INTEL_POWERCLAMP
|
||||
enforce idle time which results in more package C-state residency. The
|
||||
user interface is exposed via generic thermal framework.
|
||||
|
||||
+config THERMAL_BCM2835
|
||||
+ tristate "BCM2835 Thermal Driver"
|
||||
+ help
|
||||
+ This will enable temperature monitoring for the Broadcom BCM2835
|
||||
+ chip. If built as a module, it will be called 'bcm2835-thermal'.
|
||||
+
|
||||
endif
|
||||
+
|
||||
--- a/drivers/thermal/Makefile
|
||||
+++ b/drivers/thermal/Makefile
|
||||
@@ -23,4 +23,5 @@ obj-$(CONFIG_DB8500_THERMAL) += db8500_t
|
||||
obj-$(CONFIG_ARMADA_THERMAL) += armada_thermal.o
|
||||
obj-$(CONFIG_DB8500_CPUFREQ_COOLING) += db8500_cpufreq_cooling.o
|
||||
obj-$(CONFIG_INTEL_POWERCLAMP) += intel_powerclamp.o
|
||||
+obj-$(CONFIG_THERMAL_BCM2835) += bcm2835-thermal.o
|
||||
|
||||
--- /dev/null
|
||||
+++ b/drivers/thermal/bcm2835-thermal.c
|
||||
@@ -0,0 +1,208 @@
|
||||
+/*****************************************************************************
|
||||
+* Copyright 2011 Broadcom Corporation. All rights reserved.
|
||||
+*
|
||||
+* Unless you and Broadcom execute a separate written software license
|
||||
+* agreement governing use of this software, this software is licensed to you
|
||||
+* under the terms of the GNU General Public License version 2, available at
|
||||
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
|
||||
+*
|
||||
+* Notwithstanding the above, under no circumstances may you combine this
|
||||
+* software in any way with any other Broadcom software provided under a
|
||||
+* license other than the GPL, without Broadcom's express prior written
|
||||
+* consent.
|
||||
+*****************************************************************************/
|
||||
+
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/sysfs.h>
|
||||
+#include <mach/vcio.h>
|
||||
+#include <linux/thermal.h>
|
||||
+
|
||||
+
|
||||
+/* --- DEFINITIONS --- */
|
||||
+#define MODULE_NAME "bcm2835_thermal"
|
||||
+
|
||||
+/*#define THERMAL_DEBUG_ENABLE*/
|
||||
+
|
||||
+#ifdef THERMAL_DEBUG_ENABLE
|
||||
+#define print_debug(fmt,...) printk(KERN_INFO "%s:%s:%d: "fmt"\n", MODULE_NAME, __func__, __LINE__, ##__VA_ARGS__)
|
||||
+#else
|
||||
+#define print_debug(fmt,...)
|
||||
+#endif
|
||||
+#define print_err(fmt,...) printk(KERN_ERR "%s:%s:%d: "fmt"\n", MODULE_NAME, __func__,__LINE__, ##__VA_ARGS__)
|
||||
+#define print_info(fmt,...) printk(KERN_INFO "%s: "fmt"\n", MODULE_NAME, ##__VA_ARGS__)
|
||||
+
|
||||
+#define VC_TAG_GET_TEMP 0x00030006
|
||||
+#define VC_TAG_GET_MAX_TEMP 0x0003000A
|
||||
+
|
||||
+typedef enum {
|
||||
+ TEMP,
|
||||
+ MAX_TEMP,
|
||||
+} temp_type;
|
||||
+
|
||||
+/* --- STRUCTS --- */
|
||||
+/* tag part of the message */
|
||||
+struct vc_msg_tag {
|
||||
+ uint32_t tag_id; /* the tag ID for the temperature */
|
||||
+ uint32_t buffer_size; /* size of the buffer (should be 8) */
|
||||
+ uint32_t request_code; /* identifies message as a request (should be 0) */
|
||||
+ uint32_t id; /* extra ID field (should be 0) */
|
||||
+ uint32_t val; /* returned value of the temperature */
|
||||
+};
|
||||
+
|
||||
+/* message structure to be sent to videocore */
|
||||
+struct vc_msg {
|
||||
+ uint32_t msg_size; /* simply, sizeof(struct vc_msg) */
|
||||
+ uint32_t request_code; /* holds various information like the success and number of bytes returned (refer to mailboxes wiki) */
|
||||
+ struct vc_msg_tag tag; /* the tag structure above to make */
|
||||
+ uint32_t end_tag; /* an end identifier, should be set to NULL */
|
||||
+};
|
||||
+
|
||||
+struct bcm2835_thermal_data {
|
||||
+ struct thermal_zone_device *thermal_dev;
|
||||
+ struct vc_msg msg;
|
||||
+};
|
||||
+
|
||||
+/* --- PROTOTYPES --- */
|
||||
+static int bcm2835_get_temp(struct thermal_zone_device *thermal_dev, unsigned long *);
|
||||
+static int bcm2835_get_max_temp(struct thermal_zone_device *thermal_dev, int, unsigned long *);
|
||||
+static int bcm2835_get_trip_type(struct thermal_zone_device *thermal_dev, int trip_num, enum thermal_trip_type *trip_type);
|
||||
+static int bcm2835_get_mode(struct thermal_zone_device *thermal_dev, enum thermal_device_mode *dev_mode);
|
||||
+
|
||||
+/* --- GLOBALS --- */
|
||||
+static struct bcm2835_thermal_data bcm2835_data;
|
||||
+
|
||||
+/* Thermal Device Operations */
|
||||
+static struct thermal_zone_device_ops ops;
|
||||
+
|
||||
+/* --- FUNCTIONS --- */
|
||||
+static int bcm2835_get_max_temp(struct thermal_zone_device *thermal_dev, int trip_num, unsigned long *temp)
|
||||
+{
|
||||
+ int result;
|
||||
+
|
||||
+ print_debug("IN");
|
||||
+
|
||||
+ /* wipe all previous message data */
|
||||
+ memset(&bcm2835_data.msg, 0, sizeof bcm2835_data.msg);
|
||||
+
|
||||
+ /* prepare message */
|
||||
+ bcm2835_data.msg.msg_size = sizeof bcm2835_data.msg;
|
||||
+ bcm2835_data.msg.tag.buffer_size = 8;
|
||||
+ bcm2835_data.msg.tag.tag_id = VC_TAG_GET_MAX_TEMP;
|
||||
+
|
||||
+ /* send the message */
|
||||
+ result = bcm_mailbox_property(&bcm2835_data.msg, sizeof bcm2835_data.msg);
|
||||
+
|
||||
+ /* check if it was all ok and return the rate in milli degrees C */
|
||||
+ if (result == 0 && (bcm2835_data.msg.request_code & 0x80000000))
|
||||
+ *temp = (uint)bcm2835_data.msg.tag.val;
|
||||
+ #ifdef THERMAL_DEBUG_ENABLE
|
||||
+ else
|
||||
+ print_debug("Failed to get temperature!");
|
||||
+ #endif
|
||||
+ print_debug("Got temperature as %u",(uint)*temp);
|
||||
+ print_debug("OUT");
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int bcm2835_get_temp(struct thermal_zone_device *thermal_dev, unsigned long *temp)
|
||||
+{
|
||||
+ int result;
|
||||
+
|
||||
+ print_debug("IN");
|
||||
+
|
||||
+ /* wipe all previous message data */
|
||||
+ memset(&bcm2835_data.msg, 0, sizeof bcm2835_data.msg);
|
||||
+
|
||||
+ /* prepare message */
|
||||
+ bcm2835_data.msg.msg_size = sizeof bcm2835_data.msg;
|
||||
+ bcm2835_data.msg.tag.buffer_size = 8;
|
||||
+ bcm2835_data.msg.tag.tag_id = VC_TAG_GET_TEMP;
|
||||
+
|
||||
+ /* send the message */
|
||||
+ result = bcm_mailbox_property(&bcm2835_data.msg, sizeof bcm2835_data.msg);
|
||||
+
|
||||
+ /* check if it was all ok and return the rate in milli degrees C */
|
||||
+ if (result == 0 && (bcm2835_data.msg.request_code & 0x80000000))
|
||||
+ *temp = (uint)bcm2835_data.msg.tag.val;
|
||||
+ #ifdef THERMAL_DEBUG_ENABLE
|
||||
+ else
|
||||
+ print_debug("Failed to get temperature!");
|
||||
+ #endif
|
||||
+ print_debug("Got temperature as %u",(uint)*temp);
|
||||
+ print_debug("OUT");
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static int bcm2835_get_trip_type(struct thermal_zone_device * thermal_dev, int trip_num, enum thermal_trip_type *trip_type)
|
||||
+{
|
||||
+ *trip_type = THERMAL_TRIP_HOT;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static int bcm2835_get_mode(struct thermal_zone_device *thermal_dev, enum thermal_device_mode *dev_mode)
|
||||
+{
|
||||
+ *dev_mode = THERMAL_DEVICE_ENABLED;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static int bcm2835_thermal_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ print_debug("IN");
|
||||
+ print_debug("THERMAL Driver has been probed!");
|
||||
+
|
||||
+ /* check that the device isn't null!*/
|
||||
+ if(pdev == NULL)
|
||||
+ {
|
||||
+ print_debug("Platform device is empty!");
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
+ if(!(bcm2835_data.thermal_dev = thermal_zone_device_register("bcm2835_thermal", 1, 0, NULL, &ops, NULL, 0, 0)))
|
||||
+ {
|
||||
+ print_debug("Unable to register the thermal device!");
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static int bcm2835_thermal_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ print_debug("IN");
|
||||
+
|
||||
+ thermal_zone_device_unregister(bcm2835_data.thermal_dev);
|
||||
+
|
||||
+ print_debug("OUT");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct thermal_zone_device_ops ops = {
|
||||
+ .get_temp = bcm2835_get_temp,
|
||||
+ .get_trip_temp = bcm2835_get_max_temp,
|
||||
+ .get_trip_type = bcm2835_get_trip_type,
|
||||
+ .get_mode = bcm2835_get_mode,
|
||||
+};
|
||||
+
|
||||
+/* Thermal Driver */
|
||||
+static struct platform_driver bcm2835_thermal_driver = {
|
||||
+ .probe = bcm2835_thermal_probe,
|
||||
+ .remove = bcm2835_thermal_remove,
|
||||
+ .driver = {
|
||||
+ .name = "bcm2835_thermal",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+MODULE_LICENSE("GPL");
|
||||
+MODULE_AUTHOR("Dorian Peake");
|
||||
+MODULE_DESCRIPTION("Thermal driver for bcm2835 chip");
|
||||
+
|
||||
+module_platform_driver(bcm2835_thermal_driver);
|
|
@ -0,0 +1,943 @@
|
|||
From dc54a9801e33f0e7c0685f0535b90237ab3d4837 Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Thu, 19 Jul 2012 16:00:28 +0100
|
||||
Subject: [PATCH 034/174] config: add missing options from 3.6.y kernel
|
||||
|
||||
---
|
||||
arch/arm/configs/bcmrpi_defconfig | 653 ++++++++++++++++++++++++++-----
|
||||
drivers/net/wireless/ath/ath9k/hif_usb.c | 2 +
|
||||
2 files changed, 564 insertions(+), 91 deletions(-)
|
||||
|
||||
--- a/arch/arm/configs/bcmrpi_defconfig
|
||||
+++ b/arch/arm/configs/bcmrpi_defconfig
|
||||
@@ -1,11 +1,17 @@
|
||||
-CONFIG_EXPERIMENTAL=y
|
||||
+# CONFIG_ARM_PATCH_PHYS_VIRT is not set
|
||||
# CONFIG_LOCALVERSION_AUTO is not set
|
||||
CONFIG_SYSVIPC=y
|
||||
CONFIG_POSIX_MQUEUE=y
|
||||
-CONFIG_BSD_PROCESS_ACCT=y
|
||||
-CONFIG_BSD_PROCESS_ACCT_V3=y
|
||||
CONFIG_FHANDLE=y
|
||||
CONFIG_AUDIT=y
|
||||
+CONFIG_NO_HZ=y
|
||||
+CONFIG_HIGH_RES_TIMERS=y
|
||||
+CONFIG_BSD_PROCESS_ACCT=y
|
||||
+CONFIG_BSD_PROCESS_ACCT_V3=y
|
||||
+CONFIG_TASKSTATS=y
|
||||
+CONFIG_TASK_DELAY_ACCT=y
|
||||
+CONFIG_TASK_XACCT=y
|
||||
+CONFIG_TASK_IO_ACCOUNTING=y
|
||||
CONFIG_IKCONFIG=y
|
||||
CONFIG_IKCONFIG_PROC=y
|
||||
CONFIG_CGROUP_FREEZER=y
|
||||
@@ -15,22 +21,24 @@ CONFIG_RESOURCE_COUNTERS=y
|
||||
CONFIG_BLK_CGROUP=y
|
||||
CONFIG_NAMESPACES=y
|
||||
CONFIG_SCHED_AUTOGROUP=y
|
||||
+CONFIG_RELAY=y
|
||||
+CONFIG_BLK_DEV_INITRD=y
|
||||
CONFIG_EMBEDDED=y
|
||||
# CONFIG_COMPAT_BRK is not set
|
||||
-CONFIG_SLAB=y
|
||||
CONFIG_PROFILING=y
|
||||
CONFIG_OPROFILE=m
|
||||
CONFIG_KPROBES=y
|
||||
+CONFIG_JUMP_LABEL=y
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_MODULE_UNLOAD=y
|
||||
CONFIG_MODVERSIONS=y
|
||||
CONFIG_MODULE_SRCVERSION_ALL=y
|
||||
# CONFIG_BLK_DEV_BSG is not set
|
||||
CONFIG_BLK_DEV_THROTTLING=y
|
||||
+CONFIG_PARTITION_ADVANCED=y
|
||||
+CONFIG_MAC_PARTITION=y
|
||||
CONFIG_CFQ_GROUP_IOSCHED=y
|
||||
CONFIG_ARCH_BCM2708=y
|
||||
-CONFIG_NO_HZ=y
|
||||
-CONFIG_HIGH_RES_TIMERS=y
|
||||
CONFIG_AEABI=y
|
||||
CONFIG_SECCOMP=y
|
||||
CONFIG_CC_STACKPROTECTOR=y
|
||||
@@ -38,6 +46,14 @@ CONFIG_ZBOOT_ROM_TEXT=0x0
|
||||
CONFIG_ZBOOT_ROM_BSS=0x0
|
||||
CONFIG_CMDLINE="dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 root=/dev/mmcblk0p2 rootfstype=ext3 rootwait"
|
||||
CONFIG_KEXEC=y
|
||||
+CONFIG_CPU_FREQ=y
|
||||
+CONFIG_CPU_FREQ_STAT=m
|
||||
+CONFIG_CPU_FREQ_STAT_DETAILS=y
|
||||
+CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE=y
|
||||
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
|
||||
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
|
||||
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
|
||||
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
|
||||
CONFIG_CPU_IDLE=y
|
||||
CONFIG_VFP=y
|
||||
CONFIG_BINFMT_MISC=m
|
||||
@@ -52,15 +68,257 @@ CONFIG_IP_PNP=y
|
||||
CONFIG_IP_PNP_DHCP=y
|
||||
CONFIG_IP_PNP_RARP=y
|
||||
CONFIG_SYN_COOKIES=y
|
||||
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
|
||||
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
|
||||
-# CONFIG_INET_XFRM_MODE_BEET is not set
|
||||
-# CONFIG_INET_LRO is not set
|
||||
-# CONFIG_INET_DIAG is not set
|
||||
-# CONFIG_IPV6 is not set
|
||||
+CONFIG_INET_AH=m
|
||||
+CONFIG_INET_ESP=m
|
||||
+CONFIG_INET_IPCOMP=m
|
||||
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
|
||||
+CONFIG_INET_XFRM_MODE_TUNNEL=m
|
||||
+CONFIG_INET_XFRM_MODE_BEET=m
|
||||
+CONFIG_INET_LRO=m
|
||||
+CONFIG_INET_DIAG=m
|
||||
+CONFIG_IPV6_PRIVACY=y
|
||||
+CONFIG_INET6_AH=m
|
||||
+CONFIG_INET6_ESP=m
|
||||
+CONFIG_INET6_IPCOMP=m
|
||||
+CONFIG_IPV6_MULTIPLE_TABLES=y
|
||||
+CONFIG_NETFILTER=y
|
||||
+CONFIG_NF_CONNTRACK=m
|
||||
+CONFIG_NF_CONNTRACK_ZONES=y
|
||||
+CONFIG_NF_CONNTRACK_EVENTS=y
|
||||
+CONFIG_NF_CONNTRACK_TIMESTAMP=y
|
||||
+CONFIG_NF_CT_PROTO_DCCP=m
|
||||
+CONFIG_NF_CT_PROTO_UDPLITE=m
|
||||
+CONFIG_NF_CONNTRACK_AMANDA=m
|
||||
+CONFIG_NF_CONNTRACK_FTP=m
|
||||
+CONFIG_NF_CONNTRACK_H323=m
|
||||
+CONFIG_NF_CONNTRACK_IRC=m
|
||||
+CONFIG_NF_CONNTRACK_NETBIOS_NS=m
|
||||
+CONFIG_NF_CONNTRACK_SNMP=m
|
||||
+CONFIG_NF_CONNTRACK_PPTP=m
|
||||
+CONFIG_NF_CONNTRACK_SANE=m
|
||||
+CONFIG_NF_CONNTRACK_SIP=m
|
||||
+CONFIG_NF_CONNTRACK_TFTP=m
|
||||
+CONFIG_NF_CT_NETLINK=m
|
||||
+CONFIG_NETFILTER_TPROXY=m
|
||||
+CONFIG_NETFILTER_XT_SET=m
|
||||
+CONFIG_NETFILTER_XT_TARGET_AUDIT=m
|
||||
+CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
|
||||
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
|
||||
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
|
||||
+CONFIG_NETFILTER_XT_TARGET_DSCP=m
|
||||
+CONFIG_NETFILTER_XT_TARGET_HMARK=m
|
||||
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
|
||||
+CONFIG_NETFILTER_XT_TARGET_LED=m
|
||||
+CONFIG_NETFILTER_XT_TARGET_LOG=m
|
||||
+CONFIG_NETFILTER_XT_TARGET_MARK=m
|
||||
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
|
||||
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
|
||||
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
|
||||
+CONFIG_NETFILTER_XT_TARGET_TEE=m
|
||||
+CONFIG_NETFILTER_XT_TARGET_TPROXY=m
|
||||
+CONFIG_NETFILTER_XT_TARGET_TRACE=m
|
||||
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
|
||||
+CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_BPF=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_CPU=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_ESP=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_MAC=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_MARK=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_NFACCT=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_OSF=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_OWNER=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_RATEEST=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_REALM=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_RECENT=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_SOCKET=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_STATE=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_STRING=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_TIME=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_U32=m
|
||||
+CONFIG_IP_SET=m
|
||||
+CONFIG_IP_SET_BITMAP_IP=m
|
||||
+CONFIG_IP_SET_BITMAP_IPMAC=m
|
||||
+CONFIG_IP_SET_BITMAP_PORT=m
|
||||
+CONFIG_IP_SET_HASH_IP=m
|
||||
+CONFIG_IP_SET_HASH_IPPORT=m
|
||||
+CONFIG_IP_SET_HASH_IPPORTIP=m
|
||||
+CONFIG_IP_SET_HASH_IPPORTNET=m
|
||||
+CONFIG_IP_SET_HASH_NET=m
|
||||
+CONFIG_IP_SET_HASH_NETPORT=m
|
||||
+CONFIG_IP_SET_HASH_NETIFACE=m
|
||||
+CONFIG_IP_SET_LIST_SET=m
|
||||
+CONFIG_IP_VS=m
|
||||
+CONFIG_IP_VS_PROTO_TCP=y
|
||||
+CONFIG_IP_VS_PROTO_UDP=y
|
||||
+CONFIG_IP_VS_PROTO_ESP=y
|
||||
+CONFIG_IP_VS_PROTO_AH=y
|
||||
+CONFIG_IP_VS_PROTO_SCTP=y
|
||||
+CONFIG_IP_VS_RR=m
|
||||
+CONFIG_IP_VS_WRR=m
|
||||
+CONFIG_IP_VS_LC=m
|
||||
+CONFIG_IP_VS_WLC=m
|
||||
+CONFIG_IP_VS_LBLC=m
|
||||
+CONFIG_IP_VS_LBLCR=m
|
||||
+CONFIG_IP_VS_DH=m
|
||||
+CONFIG_IP_VS_SH=m
|
||||
+CONFIG_IP_VS_SED=m
|
||||
+CONFIG_IP_VS_NQ=m
|
||||
+CONFIG_IP_VS_FTP=m
|
||||
+CONFIG_IP_VS_PE_SIP=m
|
||||
+CONFIG_NF_CONNTRACK_IPV4=m
|
||||
+CONFIG_IP_NF_IPTABLES=m
|
||||
+CONFIG_IP_NF_MATCH_AH=m
|
||||
+CONFIG_IP_NF_MATCH_ECN=m
|
||||
+CONFIG_IP_NF_MATCH_TTL=m
|
||||
+CONFIG_IP_NF_FILTER=m
|
||||
+CONFIG_IP_NF_TARGET_REJECT=m
|
||||
+CONFIG_IP_NF_TARGET_ULOG=m
|
||||
+CONFIG_NF_NAT_IPV4=m
|
||||
+CONFIG_IP_NF_TARGET_MASQUERADE=m
|
||||
+CONFIG_IP_NF_TARGET_NETMAP=m
|
||||
+CONFIG_IP_NF_TARGET_REDIRECT=m
|
||||
+CONFIG_IP_NF_MANGLE=m
|
||||
+CONFIG_IP_NF_TARGET_ECN=m
|
||||
+CONFIG_IP_NF_TARGET_TTL=m
|
||||
+CONFIG_IP_NF_RAW=m
|
||||
+CONFIG_IP_NF_ARPTABLES=m
|
||||
+CONFIG_IP_NF_ARPFILTER=m
|
||||
+CONFIG_IP_NF_ARP_MANGLE=m
|
||||
+CONFIG_NF_CONNTRACK_IPV6=m
|
||||
+CONFIG_IP6_NF_IPTABLES=m
|
||||
+CONFIG_IP6_NF_MATCH_AH=m
|
||||
+CONFIG_IP6_NF_MATCH_EUI64=m
|
||||
+CONFIG_IP6_NF_MATCH_FRAG=m
|
||||
+CONFIG_IP6_NF_MATCH_OPTS=m
|
||||
+CONFIG_IP6_NF_MATCH_HL=m
|
||||
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
|
||||
+CONFIG_IP6_NF_MATCH_MH=m
|
||||
+CONFIG_IP6_NF_MATCH_RT=m
|
||||
+CONFIG_IP6_NF_TARGET_HL=m
|
||||
+CONFIG_IP6_NF_FILTER=m
|
||||
+CONFIG_IP6_NF_TARGET_REJECT=m
|
||||
+CONFIG_IP6_NF_MANGLE=m
|
||||
+CONFIG_IP6_NF_RAW=m
|
||||
+CONFIG_NF_NAT_IPV6=m
|
||||
+CONFIG_IP6_NF_TARGET_MASQUERADE=m
|
||||
+CONFIG_IP6_NF_TARGET_NPT=m
|
||||
+CONFIG_BRIDGE_NF_EBTABLES=m
|
||||
+CONFIG_BRIDGE_EBT_BROUTE=m
|
||||
+CONFIG_BRIDGE_EBT_T_FILTER=m
|
||||
+CONFIG_BRIDGE_EBT_T_NAT=m
|
||||
+CONFIG_BRIDGE_EBT_802_3=m
|
||||
+CONFIG_BRIDGE_EBT_AMONG=m
|
||||
+CONFIG_BRIDGE_EBT_ARP=m
|
||||
+CONFIG_BRIDGE_EBT_IP=m
|
||||
+CONFIG_BRIDGE_EBT_IP6=m
|
||||
+CONFIG_BRIDGE_EBT_LIMIT=m
|
||||
+CONFIG_BRIDGE_EBT_MARK=m
|
||||
+CONFIG_BRIDGE_EBT_PKTTYPE=m
|
||||
+CONFIG_BRIDGE_EBT_STP=m
|
||||
+CONFIG_BRIDGE_EBT_VLAN=m
|
||||
+CONFIG_BRIDGE_EBT_ARPREPLY=m
|
||||
+CONFIG_BRIDGE_EBT_DNAT=m
|
||||
+CONFIG_BRIDGE_EBT_MARK_T=m
|
||||
+CONFIG_BRIDGE_EBT_REDIRECT=m
|
||||
+CONFIG_BRIDGE_EBT_SNAT=m
|
||||
+CONFIG_BRIDGE_EBT_LOG=m
|
||||
+CONFIG_BRIDGE_EBT_ULOG=m
|
||||
+CONFIG_BRIDGE_EBT_NFLOG=m
|
||||
+CONFIG_SCTP_COOKIE_HMAC_SHA1=y
|
||||
+CONFIG_L2TP=m
|
||||
+CONFIG_BRIDGE=m
|
||||
+CONFIG_VLAN_8021Q=m
|
||||
+CONFIG_VLAN_8021Q_GVRP=y
|
||||
+CONFIG_ATALK=m
|
||||
+CONFIG_NET_SCHED=y
|
||||
+CONFIG_NET_SCH_CBQ=m
|
||||
+CONFIG_NET_SCH_HTB=m
|
||||
+CONFIG_NET_SCH_HFSC=m
|
||||
+CONFIG_NET_SCH_PRIO=m
|
||||
+CONFIG_NET_SCH_MULTIQ=m
|
||||
+CONFIG_NET_SCH_RED=m
|
||||
+CONFIG_NET_SCH_SFB=m
|
||||
+CONFIG_NET_SCH_SFQ=m
|
||||
+CONFIG_NET_SCH_TEQL=m
|
||||
+CONFIG_NET_SCH_TBF=m
|
||||
+CONFIG_NET_SCH_GRED=m
|
||||
+CONFIG_NET_SCH_DSMARK=m
|
||||
+CONFIG_NET_SCH_NETEM=m
|
||||
+CONFIG_NET_SCH_DRR=m
|
||||
+CONFIG_NET_SCH_MQPRIO=m
|
||||
+CONFIG_NET_SCH_CHOKE=m
|
||||
+CONFIG_NET_SCH_QFQ=m
|
||||
+CONFIG_NET_SCH_CODEL=m
|
||||
+CONFIG_NET_SCH_FQ_CODEL=m
|
||||
+CONFIG_NET_SCH_INGRESS=m
|
||||
+CONFIG_NET_SCH_PLUG=m
|
||||
+CONFIG_NET_CLS_BASIC=m
|
||||
+CONFIG_NET_CLS_TCINDEX=m
|
||||
+CONFIG_NET_CLS_ROUTE4=m
|
||||
+CONFIG_NET_CLS_FW=m
|
||||
+CONFIG_NET_CLS_U32=m
|
||||
+CONFIG_CLS_U32_MARK=y
|
||||
+CONFIG_NET_CLS_RSVP=m
|
||||
+CONFIG_NET_CLS_RSVP6=m
|
||||
+CONFIG_NET_CLS_FLOW=m
|
||||
+CONFIG_NET_CLS_CGROUP=m
|
||||
+CONFIG_NET_EMATCH=y
|
||||
+CONFIG_NET_EMATCH_CMP=m
|
||||
+CONFIG_NET_EMATCH_NBYTE=m
|
||||
+CONFIG_NET_EMATCH_U32=m
|
||||
+CONFIG_NET_EMATCH_META=m
|
||||
+CONFIG_NET_EMATCH_TEXT=m
|
||||
+CONFIG_NET_EMATCH_IPSET=m
|
||||
+CONFIG_NET_CLS_ACT=y
|
||||
+CONFIG_NET_ACT_POLICE=m
|
||||
+CONFIG_NET_ACT_GACT=m
|
||||
+CONFIG_GACT_PROB=y
|
||||
+CONFIG_NET_ACT_MIRRED=m
|
||||
+CONFIG_NET_ACT_IPT=m
|
||||
+CONFIG_NET_ACT_NAT=m
|
||||
+CONFIG_NET_ACT_PEDIT=m
|
||||
+CONFIG_NET_ACT_SIMP=m
|
||||
+CONFIG_NET_ACT_SKBEDIT=m
|
||||
+CONFIG_NET_ACT_CSUM=m
|
||||
+CONFIG_BATMAN_ADV=m
|
||||
+CONFIG_OPENVSWITCH=m
|
||||
CONFIG_NET_PKTGEN=m
|
||||
+CONFIG_HAMRADIO=y
|
||||
+CONFIG_AX25=m
|
||||
+CONFIG_NETROM=m
|
||||
+CONFIG_ROSE=m
|
||||
+CONFIG_MKISS=m
|
||||
+CONFIG_6PACK=m
|
||||
+CONFIG_BPQETHER=m
|
||||
+CONFIG_BAYCOM_SER_FDX=m
|
||||
+CONFIG_BAYCOM_SER_HDX=m
|
||||
+CONFIG_YAM=m
|
||||
CONFIG_IRDA=m
|
||||
CONFIG_IRLAN=m
|
||||
+CONFIG_IRNET=m
|
||||
CONFIG_IRCOMM=m
|
||||
CONFIG_IRDA_ULTRA=y
|
||||
CONFIG_IRDA_CACHE_LAST_LSAP=y
|
||||
@@ -73,8 +331,6 @@ CONFIG_USB_IRDA=m
|
||||
CONFIG_SIGMATEL_FIR=m
|
||||
CONFIG_MCS_FIR=m
|
||||
CONFIG_BT=m
|
||||
-CONFIG_BT_L2CAP=y
|
||||
-CONFIG_BT_SCO=y
|
||||
CONFIG_BT_RFCOMM=m
|
||||
CONFIG_BT_RFCOMM_TTY=y
|
||||
CONFIG_BT_BNEP=m
|
||||
@@ -89,21 +345,28 @@ CONFIG_BT_HCIVHCI=m
|
||||
CONFIG_BT_MRVL=m
|
||||
CONFIG_BT_MRVL_SDIO=m
|
||||
CONFIG_BT_ATH3K=m
|
||||
+CONFIG_BT_WILINK=m
|
||||
CONFIG_CFG80211=m
|
||||
+CONFIG_CFG80211_WEXT=y
|
||||
CONFIG_MAC80211=m
|
||||
CONFIG_MAC80211_RC_PID=y
|
||||
CONFIG_MAC80211_MESH=y
|
||||
CONFIG_WIMAX=m
|
||||
+CONFIG_RFKILL=m
|
||||
+CONFIG_RFKILL_INPUT=y
|
||||
CONFIG_NET_9P=m
|
||||
CONFIG_NFC=m
|
||||
CONFIG_NFC_PN533=m
|
||||
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
|
||||
+CONFIG_DEVTMPFS=y
|
||||
+CONFIG_DEVTMPFS_MOUNT=y
|
||||
+CONFIG_CMA=y
|
||||
CONFIG_BLK_DEV_LOOP=y
|
||||
CONFIG_BLK_DEV_CRYPTOLOOP=m
|
||||
+CONFIG_BLK_DEV_DRBD=m
|
||||
CONFIG_BLK_DEV_NBD=m
|
||||
CONFIG_BLK_DEV_RAM=y
|
||||
CONFIG_CDROM_PKTCDVD=m
|
||||
-CONFIG_MISC_DEVICES=y
|
||||
CONFIG_SCSI=y
|
||||
# CONFIG_SCSI_PROC_FS is not set
|
||||
CONFIG_BLK_DEV_SD=m
|
||||
@@ -111,13 +374,50 @@ CONFIG_BLK_DEV_SR=m
|
||||
CONFIG_SCSI_MULTI_LUN=y
|
||||
# CONFIG_SCSI_LOWLEVEL is not set
|
||||
CONFIG_MD=y
|
||||
+CONFIG_BLK_DEV_DM=m
|
||||
+CONFIG_DM_CRYPT=m
|
||||
CONFIG_NETDEVICES=y
|
||||
+CONFIG_DUMMY=m
|
||||
+CONFIG_NETCONSOLE=m
|
||||
CONFIG_TUN=m
|
||||
-CONFIG_PHYLIB=m
|
||||
CONFIG_MDIO_BITBANG=m
|
||||
-CONFIG_NET_ETHERNET=y
|
||||
-# CONFIG_NETDEV_1000 is not set
|
||||
-# CONFIG_NETDEV_10000 is not set
|
||||
+CONFIG_PPP=m
|
||||
+CONFIG_PPP_BSDCOMP=m
|
||||
+CONFIG_PPP_DEFLATE=m
|
||||
+CONFIG_PPP_ASYNC=m
|
||||
+CONFIG_PPP_SYNC_TTY=m
|
||||
+CONFIG_SLIP=m
|
||||
+CONFIG_SLIP_COMPRESSED=y
|
||||
+CONFIG_USB_CATC=m
|
||||
+CONFIG_USB_KAWETH=m
|
||||
+CONFIG_USB_PEGASUS=m
|
||||
+CONFIG_USB_RTL8150=m
|
||||
+CONFIG_USB_RTL8152=m
|
||||
+CONFIG_USB_USBNET=y
|
||||
+CONFIG_USB_NET_AX8817X=m
|
||||
+CONFIG_USB_NET_CDCETHER=m
|
||||
+CONFIG_USB_NET_CDC_EEM=m
|
||||
+CONFIG_USB_NET_CDC_MBIM=m
|
||||
+CONFIG_USB_NET_DM9601=m
|
||||
+CONFIG_USB_NET_SMSC75XX=m
|
||||
+CONFIG_USB_NET_SMSC95XX=y
|
||||
+CONFIG_USB_NET_GL620A=m
|
||||
+CONFIG_USB_NET_NET1080=m
|
||||
+CONFIG_USB_NET_PLUSB=m
|
||||
+CONFIG_USB_NET_MCS7830=m
|
||||
+CONFIG_USB_NET_CDC_SUBSET=m
|
||||
+CONFIG_USB_ALI_M5632=y
|
||||
+CONFIG_USB_AN2720=y
|
||||
+CONFIG_USB_EPSON2888=y
|
||||
+CONFIG_USB_KC2190=y
|
||||
+CONFIG_USB_NET_ZAURUS=m
|
||||
+CONFIG_USB_NET_CX82310_ETH=m
|
||||
+CONFIG_USB_NET_KALMIA=m
|
||||
+CONFIG_USB_NET_QMI_WWAN=m
|
||||
+CONFIG_USB_NET_INT51X1=m
|
||||
+CONFIG_USB_IPHETH=m
|
||||
+CONFIG_USB_SIERRA_NET=m
|
||||
+CONFIG_USB_VL600=m
|
||||
CONFIG_LIBERTAS_THINFIRM=m
|
||||
CONFIG_LIBERTAS_THINFIRM_USB=m
|
||||
CONFIG_AT76C50X_USB=m
|
||||
@@ -125,14 +425,16 @@ CONFIG_USB_ZD1201=m
|
||||
CONFIG_USB_NET_RNDIS_WLAN=m
|
||||
CONFIG_RTL8187=m
|
||||
CONFIG_MAC80211_HWSIM=m
|
||||
-CONFIG_ATH_COMMON=m
|
||||
+CONFIG_ATH_CARDS=m
|
||||
CONFIG_ATH9K=m
|
||||
CONFIG_ATH9K_HTC=m
|
||||
CONFIG_CARL9170=m
|
||||
+CONFIG_ATH6KL=m
|
||||
+CONFIG_ATH6KL_USB=m
|
||||
+CONFIG_AR5523=m
|
||||
CONFIG_B43=m
|
||||
CONFIG_B43LEGACY=m
|
||||
CONFIG_HOSTAP=m
|
||||
-CONFIG_IWM=m
|
||||
CONFIG_LIBERTAS=m
|
||||
CONFIG_LIBERTAS_USB=m
|
||||
CONFIG_LIBERTAS_SDIO=m
|
||||
@@ -143,56 +445,25 @@ CONFIG_RT2500USB=m
|
||||
CONFIG_RT73USB=m
|
||||
CONFIG_RT2800USB=m
|
||||
CONFIG_RT2800USB_RT53XX=y
|
||||
-CONFIG_RTL8192CU=m
|
||||
-CONFIG_WL1251=m
|
||||
-CONFIG_WL12XX_MENU=m
|
||||
+CONFIG_RT2800USB_UNKNOWN=y
|
||||
CONFIG_ZD1211RW=m
|
||||
CONFIG_MWIFIEX=m
|
||||
CONFIG_MWIFIEX_SDIO=m
|
||||
+CONFIG_RTL8192CU=m
|
||||
CONFIG_WIMAX_I2400M_USB=m
|
||||
-CONFIG_USB_CATC=m
|
||||
-CONFIG_USB_KAWETH=m
|
||||
-CONFIG_USB_PEGASUS=m
|
||||
-CONFIG_USB_RTL8150=m
|
||||
-CONFIG_USB_USBNET=y
|
||||
-CONFIG_USB_NET_AX8817X=m
|
||||
-CONFIG_USB_NET_CDCETHER=m
|
||||
-CONFIG_USB_NET_CDC_EEM=m
|
||||
-CONFIG_USB_NET_DM9601=m
|
||||
-CONFIG_USB_NET_SMSC75XX=m
|
||||
-CONFIG_USB_NET_SMSC95XX=y
|
||||
-CONFIG_USB_NET_GL620A=m
|
||||
-CONFIG_USB_NET_NET1080=m
|
||||
-CONFIG_USB_NET_PLUSB=m
|
||||
-CONFIG_USB_NET_MCS7830=m
|
||||
-CONFIG_USB_NET_CDC_SUBSET=m
|
||||
-CONFIG_USB_ALI_M5632=y
|
||||
-CONFIG_USB_AN2720=y
|
||||
-CONFIG_USB_KC2190=y
|
||||
-# CONFIG_USB_NET_ZAURUS is not set
|
||||
-CONFIG_USB_NET_CX82310_ETH=m
|
||||
-CONFIG_USB_NET_KALMIA=m
|
||||
-CONFIG_USB_NET_INT51X1=m
|
||||
-CONFIG_USB_IPHETH=m
|
||||
-CONFIG_USB_SIERRA_NET=m
|
||||
-CONFIG_USB_VL600=m
|
||||
-CONFIG_PPP=m
|
||||
-CONFIG_PPP_ASYNC=m
|
||||
-CONFIG_PPP_SYNC_TTY=m
|
||||
-CONFIG_PPP_DEFLATE=m
|
||||
-CONFIG_PPP_BSDCOMP=m
|
||||
-CONFIG_SLIP=m
|
||||
-CONFIG_SLIP_COMPRESSED=y
|
||||
-CONFIG_NETCONSOLE=m
|
||||
CONFIG_INPUT_POLLDEV=m
|
||||
# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
|
||||
CONFIG_INPUT_JOYDEV=m
|
||||
CONFIG_INPUT_EVDEV=m
|
||||
# CONFIG_INPUT_KEYBOARD is not set
|
||||
# CONFIG_INPUT_MOUSE is not set
|
||||
+CONFIG_INPUT_JOYSTICK=y
|
||||
+CONFIG_JOYSTICK_IFORCE=m
|
||||
+CONFIG_JOYSTICK_IFORCE_USB=y
|
||||
+CONFIG_JOYSTICK_XPAD=y
|
||||
+CONFIG_JOYSTICK_XPAD_FF=y
|
||||
CONFIG_INPUT_MISC=y
|
||||
CONFIG_INPUT_AD714X=m
|
||||
-CONFIG_INPUT_ATI_REMOTE=m
|
||||
CONFIG_INPUT_ATI_REMOTE2=m
|
||||
CONFIG_INPUT_KEYSPAN_REMOTE=m
|
||||
CONFIG_INPUT_POWERMATE=m
|
||||
@@ -202,28 +473,188 @@ CONFIG_INPUT_UINPUT=m
|
||||
CONFIG_INPUT_GPIO_ROTARY_ENCODER=m
|
||||
CONFIG_INPUT_ADXL34X=m
|
||||
CONFIG_INPUT_CMA3000=m
|
||||
-CONFIG_SERIO=m
|
||||
-CONFIG_SERIO_RAW=m
|
||||
-CONFIG_GAMEPORT=m
|
||||
-CONFIG_GAMEPORT_NS558=m
|
||||
-CONFIG_GAMEPORT_L4=m
|
||||
+# CONFIG_SERIO is not set
|
||||
CONFIG_VT_HW_CONSOLE_BINDING=y
|
||||
# CONFIG_LEGACY_PTYS is not set
|
||||
# CONFIG_DEVKMEM is not set
|
||||
CONFIG_SERIAL_AMBA_PL011=y
|
||||
CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
|
||||
-# CONFIG_HW_RANDOM is not set
|
||||
+CONFIG_HW_RANDOM=y
|
||||
+CONFIG_HW_RANDOM_BCM2708=y
|
||||
CONFIG_RAW_DRIVER=y
|
||||
+CONFIG_BRCM_CHAR_DRIVERS=y
|
||||
+CONFIG_BCM_VC_CMA=y
|
||||
CONFIG_I2C=y
|
||||
CONFIG_I2C_CHARDEV=m
|
||||
CONFIG_I2C_BCM2708=m
|
||||
CONFIG_SPI=y
|
||||
CONFIG_SPI_BCM2708=m
|
||||
+CONFIG_SPI_SPIDEV=m
|
||||
CONFIG_GPIO_SYSFS=y
|
||||
+CONFIG_W1=m
|
||||
+CONFIG_W1_MASTER_DS2490=m
|
||||
+CONFIG_W1_MASTER_DS2482=m
|
||||
+CONFIG_W1_MASTER_DS1WM=m
|
||||
+CONFIG_W1_MASTER_GPIO=m
|
||||
+CONFIG_W1_SLAVE_THERM=m
|
||||
+CONFIG_W1_SLAVE_SMEM=m
|
||||
+CONFIG_W1_SLAVE_DS2408=m
|
||||
+CONFIG_W1_SLAVE_DS2413=m
|
||||
+CONFIG_W1_SLAVE_DS2423=m
|
||||
+CONFIG_W1_SLAVE_DS2431=m
|
||||
+CONFIG_W1_SLAVE_DS2433=m
|
||||
+CONFIG_W1_SLAVE_DS2760=m
|
||||
+CONFIG_W1_SLAVE_DS2780=m
|
||||
+CONFIG_W1_SLAVE_DS2781=m
|
||||
+CONFIG_W1_SLAVE_DS28E04=m
|
||||
+CONFIG_W1_SLAVE_BQ27000=m
|
||||
+CONFIG_BATTERY_DS2760=m
|
||||
# CONFIG_HWMON is not set
|
||||
+CONFIG_THERMAL=y
|
||||
+CONFIG_THERMAL_BCM2835=y
|
||||
CONFIG_WATCHDOG=y
|
||||
CONFIG_BCM2708_WDT=m
|
||||
-# CONFIG_MFD_SUPPORT is not set
|
||||
+CONFIG_MEDIA_SUPPORT=m
|
||||
+CONFIG_MEDIA_CAMERA_SUPPORT=y
|
||||
+CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
|
||||
+CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
|
||||
+CONFIG_MEDIA_RADIO_SUPPORT=y
|
||||
+CONFIG_MEDIA_RC_SUPPORT=y
|
||||
+CONFIG_MEDIA_CONTROLLER=y
|
||||
+CONFIG_LIRC=m
|
||||
+CONFIG_RC_DEVICES=y
|
||||
+CONFIG_RC_ATI_REMOTE=m
|
||||
+CONFIG_IR_IMON=m
|
||||
+CONFIG_IR_MCEUSB=m
|
||||
+CONFIG_IR_REDRAT3=m
|
||||
+CONFIG_IR_STREAMZAP=m
|
||||
+CONFIG_IR_IGUANA=m
|
||||
+CONFIG_IR_TTUSBIR=m
|
||||
+CONFIG_RC_LOOPBACK=m
|
||||
+CONFIG_IR_GPIO_CIR=m
|
||||
+CONFIG_MEDIA_USB_SUPPORT=y
|
||||
+CONFIG_USB_VIDEO_CLASS=m
|
||||
+CONFIG_USB_M5602=m
|
||||
+CONFIG_USB_STV06XX=m
|
||||
+CONFIG_USB_GL860=m
|
||||
+CONFIG_USB_GSPCA_BENQ=m
|
||||
+CONFIG_USB_GSPCA_CONEX=m
|
||||
+CONFIG_USB_GSPCA_CPIA1=m
|
||||
+CONFIG_USB_GSPCA_ETOMS=m
|
||||
+CONFIG_USB_GSPCA_FINEPIX=m
|
||||
+CONFIG_USB_GSPCA_JEILINJ=m
|
||||
+CONFIG_USB_GSPCA_JL2005BCD=m
|
||||
+CONFIG_USB_GSPCA_KINECT=m
|
||||
+CONFIG_USB_GSPCA_KONICA=m
|
||||
+CONFIG_USB_GSPCA_MARS=m
|
||||
+CONFIG_USB_GSPCA_MR97310A=m
|
||||
+CONFIG_USB_GSPCA_NW80X=m
|
||||
+CONFIG_USB_GSPCA_OV519=m
|
||||
+CONFIG_USB_GSPCA_OV534=m
|
||||
+CONFIG_USB_GSPCA_OV534_9=m
|
||||
+CONFIG_USB_GSPCA_PAC207=m
|
||||
+CONFIG_USB_GSPCA_PAC7302=m
|
||||
+CONFIG_USB_GSPCA_PAC7311=m
|
||||
+CONFIG_USB_GSPCA_SE401=m
|
||||
+CONFIG_USB_GSPCA_SN9C2028=m
|
||||
+CONFIG_USB_GSPCA_SN9C20X=m
|
||||
+CONFIG_USB_GSPCA_SONIXB=m
|
||||
+CONFIG_USB_GSPCA_SONIXJ=m
|
||||
+CONFIG_USB_GSPCA_SPCA500=m
|
||||
+CONFIG_USB_GSPCA_SPCA501=m
|
||||
+CONFIG_USB_GSPCA_SPCA505=m
|
||||
+CONFIG_USB_GSPCA_SPCA506=m
|
||||
+CONFIG_USB_GSPCA_SPCA508=m
|
||||
+CONFIG_USB_GSPCA_SPCA561=m
|
||||
+CONFIG_USB_GSPCA_SPCA1528=m
|
||||
+CONFIG_USB_GSPCA_SQ905=m
|
||||
+CONFIG_USB_GSPCA_SQ905C=m
|
||||
+CONFIG_USB_GSPCA_SQ930X=m
|
||||
+CONFIG_USB_GSPCA_STK014=m
|
||||
+CONFIG_USB_GSPCA_STV0680=m
|
||||
+CONFIG_USB_GSPCA_SUNPLUS=m
|
||||
+CONFIG_USB_GSPCA_T613=m
|
||||
+CONFIG_USB_GSPCA_TOPRO=m
|
||||
+CONFIG_USB_GSPCA_TV8532=m
|
||||
+CONFIG_USB_GSPCA_VC032X=m
|
||||
+CONFIG_USB_GSPCA_VICAM=m
|
||||
+CONFIG_USB_GSPCA_XIRLINK_CIT=m
|
||||
+CONFIG_USB_GSPCA_ZC3XX=m
|
||||
+CONFIG_USB_PWC=m
|
||||
+CONFIG_VIDEO_CPIA2=m
|
||||
+CONFIG_USB_ZR364XX=m
|
||||
+CONFIG_USB_STKWEBCAM=m
|
||||
+CONFIG_USB_S2255=m
|
||||
+CONFIG_USB_SN9C102=m
|
||||
+CONFIG_VIDEO_PVRUSB2=m
|
||||
+CONFIG_VIDEO_HDPVR=m
|
||||
+CONFIG_VIDEO_TLG2300=m
|
||||
+CONFIG_VIDEO_USBVISION=m
|
||||
+CONFIG_VIDEO_STK1160=m
|
||||
+CONFIG_VIDEO_STK1160_AC97=y
|
||||
+CONFIG_VIDEO_AU0828=m
|
||||
+CONFIG_VIDEO_CX231XX=m
|
||||
+CONFIG_VIDEO_CX231XX_ALSA=m
|
||||
+CONFIG_VIDEO_CX231XX_DVB=m
|
||||
+CONFIG_VIDEO_TM6000=m
|
||||
+CONFIG_VIDEO_TM6000_ALSA=m
|
||||
+CONFIG_VIDEO_TM6000_DVB=m
|
||||
+CONFIG_DVB_USB=m
|
||||
+CONFIG_DVB_USB_A800=m
|
||||
+CONFIG_DVB_USB_DIBUSB_MB=m
|
||||
+CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y
|
||||
+CONFIG_DVB_USB_DIBUSB_MC=m
|
||||
+CONFIG_DVB_USB_DIB0700=m
|
||||
+CONFIG_DVB_USB_UMT_010=m
|
||||
+CONFIG_DVB_USB_CXUSB=m
|
||||
+CONFIG_DVB_USB_M920X=m
|
||||
+CONFIG_DVB_USB_DIGITV=m
|
||||
+CONFIG_DVB_USB_VP7045=m
|
||||
+CONFIG_DVB_USB_VP702X=m
|
||||
+CONFIG_DVB_USB_GP8PSK=m
|
||||
+CONFIG_DVB_USB_NOVA_T_USB2=m
|
||||
+CONFIG_DVB_USB_TTUSB2=m
|
||||
+CONFIG_DVB_USB_DTT200U=m
|
||||
+CONFIG_DVB_USB_OPERA1=m
|
||||
+CONFIG_DVB_USB_AF9005=m
|
||||
+CONFIG_DVB_USB_AF9005_REMOTE=m
|
||||
+CONFIG_DVB_USB_PCTV452E=m
|
||||
+CONFIG_DVB_USB_DW2102=m
|
||||
+CONFIG_DVB_USB_CINERGY_T2=m
|
||||
+CONFIG_DVB_USB_DTV5100=m
|
||||
+CONFIG_DVB_USB_FRIIO=m
|
||||
+CONFIG_DVB_USB_AZ6027=m
|
||||
+CONFIG_DVB_USB_TECHNISAT_USB2=m
|
||||
+CONFIG_DVB_USB_V2=m
|
||||
+CONFIG_DVB_USB_AF9015=m
|
||||
+CONFIG_DVB_USB_AF9035=m
|
||||
+CONFIG_DVB_USB_ANYSEE=m
|
||||
+CONFIG_DVB_USB_AU6610=m
|
||||
+CONFIG_DVB_USB_AZ6007=m
|
||||
+CONFIG_DVB_USB_CE6230=m
|
||||
+CONFIG_DVB_USB_EC168=m
|
||||
+CONFIG_DVB_USB_GL861=m
|
||||
+CONFIG_DVB_USB_IT913X=m
|
||||
+CONFIG_DVB_USB_LME2510=m
|
||||
+CONFIG_DVB_USB_MXL111SF=m
|
||||
+CONFIG_DVB_USB_RTL28XXU=m
|
||||
+CONFIG_SMS_USB_DRV=m
|
||||
+CONFIG_DVB_B2C2_FLEXCOP_USB=m
|
||||
+CONFIG_VIDEO_EM28XX=m
|
||||
+CONFIG_VIDEO_EM28XX_ALSA=m
|
||||
+CONFIG_VIDEO_EM28XX_DVB=m
|
||||
+CONFIG_RADIO_SI470X=y
|
||||
+CONFIG_USB_SI470X=m
|
||||
+CONFIG_USB_MR800=m
|
||||
+CONFIG_USB_DSBR=m
|
||||
+CONFIG_RADIO_SHARK=m
|
||||
+CONFIG_RADIO_SHARK2=m
|
||||
+CONFIG_RADIO_SI4713=m
|
||||
+CONFIG_USB_KEENE=m
|
||||
+CONFIG_USB_MA901=m
|
||||
+CONFIG_RADIO_SAA7706H=m
|
||||
+CONFIG_RADIO_TEF6862=m
|
||||
+CONFIG_RADIO_WL128X=m
|
||||
CONFIG_FB=y
|
||||
CONFIG_FB_BCM2708=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||
@@ -250,8 +681,7 @@ CONFIG_SND_USB_UA101=m
|
||||
CONFIG_SND_USB_CAIAQ=m
|
||||
CONFIG_SND_USB_6FIRE=m
|
||||
CONFIG_SOUND_PRIME=m
|
||||
-CONFIG_HID_PID=y
|
||||
-CONFIG_USB_HIDDEV=y
|
||||
+CONFIG_HIDRAW=y
|
||||
CONFIG_HID_A4TECH=m
|
||||
CONFIG_HID_ACRUX=m
|
||||
CONFIG_HID_APPLE=m
|
||||
@@ -282,7 +712,6 @@ CONFIG_HID_ORTEK=m
|
||||
CONFIG_HID_PANTHERLORD=m
|
||||
CONFIG_HID_PETALYNX=m
|
||||
CONFIG_HID_PICOLCD=m
|
||||
-CONFIG_HID_QUANTA=m
|
||||
CONFIG_HID_ROCCAT=m
|
||||
CONFIG_HID_SAMSUNG=m
|
||||
CONFIG_HID_SONY=m
|
||||
@@ -291,15 +720,18 @@ CONFIG_HID_SUNPLUS=m
|
||||
CONFIG_HID_GREENASIA=m
|
||||
CONFIG_HID_SMARTJOYPLUS=m
|
||||
CONFIG_HID_TOPSEED=m
|
||||
+CONFIG_HID_THINGM=m
|
||||
CONFIG_HID_THRUSTMASTER=m
|
||||
CONFIG_HID_WACOM=m
|
||||
CONFIG_HID_WIIMOTE=m
|
||||
CONFIG_HID_ZEROPLUS=m
|
||||
CONFIG_HID_ZYDACRON=m
|
||||
-CONFIG_USB=y
|
||||
+CONFIG_HID_PID=y
|
||||
+CONFIG_USB_HIDDEV=y
|
||||
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
|
||||
CONFIG_USB_MON=m
|
||||
CONFIG_USB_DWCOTG=y
|
||||
+CONFIG_USB_PRINTER=m
|
||||
CONFIG_USB_STORAGE=y
|
||||
CONFIG_USB_STORAGE_REALTEK=m
|
||||
CONFIG_USB_STORAGE_DATAFAB=m
|
||||
@@ -314,8 +746,6 @@ CONFIG_USB_STORAGE_ONETOUCH=m
|
||||
CONFIG_USB_STORAGE_KARMA=m
|
||||
CONFIG_USB_STORAGE_CYPRESS_ATACB=m
|
||||
CONFIG_USB_STORAGE_ENE_UB6250=m
|
||||
-CONFIG_USB_UAS=m
|
||||
-CONFIG_USB_LIBUSUAL=y
|
||||
CONFIG_USB_MDC800=m
|
||||
CONFIG_USB_MICROTEK=m
|
||||
CONFIG_USB_SERIAL=m
|
||||
@@ -336,6 +766,7 @@ CONFIG_USB_SERIAL_IPAQ=m
|
||||
CONFIG_USB_SERIAL_IR=m
|
||||
CONFIG_USB_SERIAL_EDGEPORT=m
|
||||
CONFIG_USB_SERIAL_EDGEPORT_TI=m
|
||||
+CONFIG_USB_SERIAL_F81232=m
|
||||
CONFIG_USB_SERIAL_GARMIN=m
|
||||
CONFIG_USB_SERIAL_IPW=m
|
||||
CONFIG_USB_SERIAL_IUU=m
|
||||
@@ -344,6 +775,7 @@ CONFIG_USB_SERIAL_KEYSPAN=m
|
||||
CONFIG_USB_SERIAL_KLSI=m
|
||||
CONFIG_USB_SERIAL_KOBIL_SCT=m
|
||||
CONFIG_USB_SERIAL_MCT_U232=m
|
||||
+CONFIG_USB_SERIAL_METRO=m
|
||||
CONFIG_USB_SERIAL_MOS7720=m
|
||||
CONFIG_USB_SERIAL_MOS7840=m
|
||||
CONFIG_USB_SERIAL_MOTOROLA=m
|
||||
@@ -365,8 +797,12 @@ CONFIG_USB_SERIAL_OPTION=m
|
||||
CONFIG_USB_SERIAL_OMNINET=m
|
||||
CONFIG_USB_SERIAL_OPTICON=m
|
||||
CONFIG_USB_SERIAL_VIVOPAY_SERIAL=m
|
||||
+CONFIG_USB_SERIAL_XSENS_MT=m
|
||||
CONFIG_USB_SERIAL_ZIO=m
|
||||
+CONFIG_USB_SERIAL_WISHBONE=m
|
||||
+CONFIG_USB_SERIAL_ZTE=m
|
||||
CONFIG_USB_SERIAL_SSU100=m
|
||||
+CONFIG_USB_SERIAL_QT2=m
|
||||
CONFIG_USB_SERIAL_DEBUG=m
|
||||
CONFIG_USB_EMI62=m
|
||||
CONFIG_USB_EMI26=m
|
||||
@@ -388,17 +824,59 @@ CONFIG_USB_TEST=m
|
||||
CONFIG_USB_ISIGHTFW=m
|
||||
CONFIG_USB_YUREX=m
|
||||
CONFIG_MMC=y
|
||||
+CONFIG_MMC_BLOCK_MINORS=32
|
||||
CONFIG_MMC_SDHCI=y
|
||||
CONFIG_MMC_SDHCI_PLTFM=y
|
||||
CONFIG_MMC_SDHCI_BCM2708=y
|
||||
CONFIG_MMC_SDHCI_BCM2708_DMA=y
|
||||
-CONFIG_LEDS_GPIO=y
|
||||
-CONFIG_LEDS_TRIGGER_TIMER=m
|
||||
-CONFIG_LEDS_TRIGGER_HEARTBEAT=m
|
||||
-CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
|
||||
+CONFIG_LEDS_GPIO=m
|
||||
+CONFIG_LEDS_TRIGGER_TIMER=y
|
||||
+CONFIG_LEDS_TRIGGER_ONESHOT=y
|
||||
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
|
||||
+CONFIG_LEDS_TRIGGER_BACKLIGHT=y
|
||||
+CONFIG_LEDS_TRIGGER_CPU=y
|
||||
+CONFIG_LEDS_TRIGGER_GPIO=y
|
||||
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
|
||||
+CONFIG_LEDS_TRIGGER_TRANSIENT=m
|
||||
+CONFIG_LEDS_TRIGGER_CAMERA=m
|
||||
+CONFIG_RTC_CLASS=y
|
||||
+CONFIG_RTC_DRV_DS1307=m
|
||||
+CONFIG_RTC_DRV_DS1374=m
|
||||
+CONFIG_RTC_DRV_DS1672=m
|
||||
+CONFIG_RTC_DRV_DS3232=m
|
||||
+CONFIG_RTC_DRV_MAX6900=m
|
||||
+CONFIG_RTC_DRV_RS5C372=m
|
||||
+CONFIG_RTC_DRV_ISL1208=m
|
||||
+CONFIG_RTC_DRV_ISL12022=m
|
||||
+CONFIG_RTC_DRV_X1205=m
|
||||
+CONFIG_RTC_DRV_PCF8523=m
|
||||
+CONFIG_RTC_DRV_PCF8563=m
|
||||
+CONFIG_RTC_DRV_PCF8583=m
|
||||
+CONFIG_RTC_DRV_M41T80=m
|
||||
+CONFIG_RTC_DRV_BQ32K=m
|
||||
+CONFIG_RTC_DRV_S35390A=m
|
||||
+CONFIG_RTC_DRV_FM3130=m
|
||||
+CONFIG_RTC_DRV_RX8581=m
|
||||
+CONFIG_RTC_DRV_RX8025=m
|
||||
+CONFIG_RTC_DRV_EM3027=m
|
||||
+CONFIG_RTC_DRV_RV3029C2=m
|
||||
+CONFIG_RTC_DRV_M41T93=m
|
||||
+CONFIG_RTC_DRV_M41T94=m
|
||||
+CONFIG_RTC_DRV_DS1305=m
|
||||
+CONFIG_RTC_DRV_DS1390=m
|
||||
+CONFIG_RTC_DRV_MAX6902=m
|
||||
+CONFIG_RTC_DRV_R9701=m
|
||||
+CONFIG_RTC_DRV_RS5C348=m
|
||||
+CONFIG_RTC_DRV_DS3234=m
|
||||
+CONFIG_RTC_DRV_PCF2123=m
|
||||
+CONFIG_RTC_DRV_RX4581=m
|
||||
CONFIG_UIO=m
|
||||
CONFIG_UIO_PDRV=m
|
||||
CONFIG_UIO_PDRV_GENIRQ=m
|
||||
+CONFIG_STAGING=y
|
||||
+CONFIG_STAGING_MEDIA=y
|
||||
+CONFIG_LIRC_STAGING=y
|
||||
+CONFIG_LIRC_RPI=m
|
||||
# CONFIG_IOMMU_SUPPORT is not set
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
@@ -421,6 +899,8 @@ CONFIG_BTRFS_FS=m
|
||||
CONFIG_BTRFS_FS_POSIX_ACL=y
|
||||
CONFIG_NILFS2_FS=m
|
||||
CONFIG_FANOTIFY=y
|
||||
+CONFIG_QFMT_V1=m
|
||||
+CONFIG_QFMT_V2=m
|
||||
CONFIG_AUTOFS4_FS=y
|
||||
CONFIG_FUSE_FS=m
|
||||
CONFIG_CUSE=m
|
||||
@@ -443,21 +923,22 @@ CONFIG_SQUASHFS=m
|
||||
CONFIG_SQUASHFS_XATTR=y
|
||||
CONFIG_SQUASHFS_LZO=y
|
||||
CONFIG_SQUASHFS_XZ=y
|
||||
+CONFIG_F2FS_FS=y
|
||||
CONFIG_NFS_FS=y
|
||||
-CONFIG_NFS_V3=y
|
||||
CONFIG_NFS_V3_ACL=y
|
||||
CONFIG_NFS_V4=y
|
||||
CONFIG_ROOT_NFS=y
|
||||
CONFIG_NFS_FSCACHE=y
|
||||
+CONFIG_NFSD=m
|
||||
+CONFIG_NFSD_V3_ACL=y
|
||||
+CONFIG_NFSD_V4=y
|
||||
CONFIG_CIFS=m
|
||||
CONFIG_CIFS_WEAK_PW_HASH=y
|
||||
CONFIG_CIFS_XATTR=y
|
||||
CONFIG_CIFS_POSIX=y
|
||||
+# CONFIG_CIFS_DEBUG is not set
|
||||
CONFIG_9P_FS=m
|
||||
CONFIG_9P_FS_POSIX_ACL=y
|
||||
-CONFIG_PARTITION_ADVANCED=y
|
||||
-CONFIG_MAC_PARTITION=y
|
||||
-CONFIG_EFI_PARTITION=y
|
||||
CONFIG_NLS_DEFAULT="utf8"
|
||||
CONFIG_NLS_CODEPAGE_437=y
|
||||
CONFIG_NLS_CODEPAGE_737=m
|
||||
@@ -497,38 +978,28 @@ CONFIG_NLS_ISO8859_15=m
|
||||
CONFIG_NLS_KOI8_R=m
|
||||
CONFIG_NLS_KOI8_U=m
|
||||
CONFIG_NLS_UTF8=m
|
||||
+CONFIG_DLM=m
|
||||
CONFIG_PRINTK_TIME=y
|
||||
CONFIG_DETECT_HUNG_TASK=y
|
||||
CONFIG_TIMER_STATS=y
|
||||
-CONFIG_DEBUG_STACK_USAGE=y
|
||||
-CONFIG_DEBUG_INFO=y
|
||||
CONFIG_DEBUG_MEMORY_INIT=y
|
||||
CONFIG_BOOT_PRINTK_DELAY=y
|
||||
CONFIG_LATENCYTOP=y
|
||||
-CONFIG_SYSCTL_SYSCALL_CHECK=y
|
||||
-CONFIG_IRQSOFF_TRACER=y
|
||||
-CONFIG_SCHED_TRACER=y
|
||||
-CONFIG_STACK_TRACER=y
|
||||
-CONFIG_BLK_DEV_IO_TRACE=y
|
||||
-CONFIG_FUNCTION_PROFILER=y
|
||||
CONFIG_KGDB=y
|
||||
CONFIG_KGDB_KDB=y
|
||||
CONFIG_KDB_KEYBOARD=y
|
||||
CONFIG_STRICT_DEVMEM=y
|
||||
-CONFIG_CRYPTO_AUTHENC=m
|
||||
CONFIG_CRYPTO_SEQIV=m
|
||||
CONFIG_CRYPTO_CBC=y
|
||||
CONFIG_CRYPTO_HMAC=y
|
||||
CONFIG_CRYPTO_XCBC=m
|
||||
CONFIG_CRYPTO_MD5=y
|
||||
CONFIG_CRYPTO_SHA1=y
|
||||
-CONFIG_CRYPTO_SHA256=m
|
||||
CONFIG_CRYPTO_SHA512=m
|
||||
CONFIG_CRYPTO_TGR192=m
|
||||
CONFIG_CRYPTO_WP512=m
|
||||
CONFIG_CRYPTO_CAST5=m
|
||||
CONFIG_CRYPTO_DES=y
|
||||
-CONFIG_CRYPTO_DEFLATE=m
|
||||
# CONFIG_CRYPTO_ANSI_CPRNG is not set
|
||||
# CONFIG_CRYPTO_HW is not set
|
||||
CONFIG_CRC_ITU_T=y
|
||||
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
|
||||
@@ -37,9 +37,11 @@ static struct usb_device_id ath9k_hif_us
|
||||
{ USB_DEVICE(0x13D3, 0x3350) }, /* Azurewave */
|
||||
{ USB_DEVICE(0x04CA, 0x4605) }, /* Liteon */
|
||||
{ USB_DEVICE(0x040D, 0x3801) }, /* VIA */
|
||||
+ { USB_DEVICE(0x0cf3, 0xb002) }, /* Ubiquiti WifiStation */
|
||||
{ USB_DEVICE(0x0cf3, 0xb003) }, /* Ubiquiti WifiStation Ext */
|
||||
{ USB_DEVICE(0x0cf3, 0xb002) }, /* Ubiquiti WifiStation */
|
||||
{ USB_DEVICE(0x057c, 0x8403) }, /* AVM FRITZ!WLAN 11N v2 USB */
|
||||
+ { USB_DEVICE(0x057c, 0x8403) }, /* AVM FRITZ!WLAN 11N v2 USB */
|
||||
|
||||
{ USB_DEVICE(0x0cf3, 0x7015),
|
||||
.driver_info = AR9287_USB }, /* Atheros */
|
|
@ -0,0 +1,72 @@
|
|||
From 10a2ded6cbf58da71121f0c7a35462f52f49dfae Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Wed, 17 Apr 2013 12:16:36 +0100
|
||||
Subject: [PATCH 035/174] Enable multiple ALSA channels
|
||||
|
||||
---
|
||||
arch/arm/mach-bcm2708/bcm2708.c | 54 ++++++++++++++++++++++++++++++++++++-----
|
||||
1 file changed, 48 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/arch/arm/mach-bcm2708/bcm2708.c
|
||||
+++ b/arch/arm/mach-bcm2708/bcm2708.c
|
||||
@@ -471,12 +471,54 @@ struct platform_device bcm2708_powerman_
|
||||
|
||||
|
||||
static struct platform_device bcm2708_alsa_devices[] = {
|
||||
- [0] = {
|
||||
- .name = "bcm2835_AUD0",
|
||||
- .id = 0, /* first audio device */
|
||||
- .resource = 0,
|
||||
- .num_resources = 0,
|
||||
- },
|
||||
+ [0] = {
|
||||
+ .name = "bcm2835_AUD0",
|
||||
+ .id = 0, /* first audio device */
|
||||
+ .resource = 0,
|
||||
+ .num_resources = 0,
|
||||
+ },
|
||||
+ [1] = {
|
||||
+ .name = "bcm2835_AUD1",
|
||||
+ .id = 1, /* second audio device */
|
||||
+ .resource = 0,
|
||||
+ .num_resources = 0,
|
||||
+ },
|
||||
+ [2] = {
|
||||
+ .name = "bcm2835_AUD2",
|
||||
+ .id = 2, /* third audio device */
|
||||
+ .resource = 0,
|
||||
+ .num_resources = 0,
|
||||
+ },
|
||||
+ [3] = {
|
||||
+ .name = "bcm2835_AUD3",
|
||||
+ .id = 3, /* forth audio device */
|
||||
+ .resource = 0,
|
||||
+ .num_resources = 0,
|
||||
+ },
|
||||
+ [4] = {
|
||||
+ .name = "bcm2835_AUD4",
|
||||
+ .id = 4, /* fifth audio device */
|
||||
+ .resource = 0,
|
||||
+ .num_resources = 0,
|
||||
+ },
|
||||
+ [5] = {
|
||||
+ .name = "bcm2835_AUD5",
|
||||
+ .id = 5, /* sixth audio device */
|
||||
+ .resource = 0,
|
||||
+ .num_resources = 0,
|
||||
+ },
|
||||
+ [6] = {
|
||||
+ .name = "bcm2835_AUD6",
|
||||
+ .id = 6, /* seventh audio device */
|
||||
+ .resource = 0,
|
||||
+ .num_resources = 0,
|
||||
+ },
|
||||
+ [7] = {
|
||||
+ .name = "bcm2835_AUD7",
|
||||
+ .id = 7, /* eighth audio device */
|
||||
+ .resource = 0,
|
||||
+ .num_resources = 0,
|
||||
+ },
|
||||
};
|
||||
|
||||
static struct resource bcm2708_spi_resources[] = {
|
|
@ -0,0 +1,70 @@
|
|||
From 17bb1be5d09fe58cd14084c5eac0052f03d6d71f Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Wed, 3 Oct 2012 20:08:19 +0100
|
||||
Subject: [PATCH 036/174] set i2c speed via module-parameter or menuconfig.
|
||||
Thanks FrankBoesing
|
||||
|
||||
---
|
||||
drivers/i2c/busses/Kconfig | 11 +++++++++++
|
||||
drivers/i2c/busses/i2c-bcm2708.c | 12 ++++++++----
|
||||
2 files changed, 19 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/i2c/busses/Kconfig
|
||||
+++ b/drivers/i2c/busses/Kconfig
|
||||
@@ -353,6 +353,17 @@ config I2C_BCM2708
|
||||
support for the BCM2708. BSC is a Broadcom proprietary bus compatible
|
||||
with I2C/TWI/SMBus.
|
||||
|
||||
+config I2C_BCM2708_BAUDRATE
|
||||
+ prompt "BCM2708 I2C baudrate"
|
||||
+ depends on I2C_BCM2708
|
||||
+ int
|
||||
+ default 100000
|
||||
+ help
|
||||
+ Set the I2C baudrate. This will alter the default value. A
|
||||
+ different baudrate can be set by using a module parameter as well. If
|
||||
+ no parameter is provided when loading, this is the value that will be
|
||||
+ used.
|
||||
+
|
||||
config I2C_BLACKFIN_TWI
|
||||
tristate "Blackfin TWI I2C support"
|
||||
depends on BLACKFIN
|
||||
--- a/drivers/i2c/busses/i2c-bcm2708.c
|
||||
+++ b/drivers/i2c/busses/i2c-bcm2708.c
|
||||
@@ -66,11 +66,15 @@
|
||||
#define BSC_S_DONE 0x00000002
|
||||
#define BSC_S_TA 0x00000001
|
||||
|
||||
-#define I2C_CLOCK_HZ 100000 /* FIXME: get from DT */
|
||||
#define I2C_TIMEOUT_MS 150
|
||||
|
||||
#define DRV_NAME "bcm2708_i2c"
|
||||
|
||||
+static unsigned int baudrate = CONFIG_I2C_BCM2708_BAUDRATE;
|
||||
+module_param(baudrate, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
|
||||
+MODULE_PARM_DESC(baudrate, "The I2C baudrate");
|
||||
+
|
||||
+
|
||||
struct bcm2708_i2c {
|
||||
struct i2c_adapter adapter;
|
||||
|
||||
@@ -148,7 +152,7 @@ static inline void bcm2708_bsc_setup(str
|
||||
u32 c = BSC_C_I2CEN | BSC_C_INTD | BSC_C_ST | BSC_C_CLEAR_1;
|
||||
|
||||
bus_hz = clk_get_rate(bi->clk);
|
||||
- cdiv = bus_hz / I2C_CLOCK_HZ;
|
||||
+ cdiv = bus_hz / baudrate;
|
||||
|
||||
if (bi->msg->flags & I2C_M_RD)
|
||||
c |= BSC_C_INTR | BSC_C_READ;
|
||||
@@ -331,8 +335,8 @@ static int bcm2708_i2c_probe(struct plat
|
||||
goto out_free_irq;
|
||||
}
|
||||
|
||||
- dev_info(&pdev->dev, "BSC%d Controller at 0x%08lx (irq %d)\n",
|
||||
- pdev->id, (unsigned long)regs->start, irq);
|
||||
+ dev_info(&pdev->dev, "BSC%d Controller at 0x%08lx (irq %d) (baudrate %dk)\n",
|
||||
+ pdev->id, (unsigned long)regs->start, irq, baudrate/1000);
|
||||
|
||||
return 0;
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
From addefb978a42b1699979ef8ecef08a01977dfd7d Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Wed, 3 Oct 2012 21:31:48 +0100
|
||||
Subject: [PATCH 037/174] Allow the number of cycles delay between sdcard
|
||||
peripheral writes to be specified on command line with
|
||||
sdhci-bcm2708.cycle_delay
|
||||
|
||||
---
|
||||
drivers/mmc/host/sdhci-bcm2708.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/mmc/host/sdhci-bcm2708.c
|
||||
+++ b/drivers/mmc/host/sdhci-bcm2708.c
|
||||
@@ -77,6 +77,8 @@
|
||||
#define REG_EXRDFIFO_EN 0x80
|
||||
#define REG_EXRDFIFO_CFG 0x84
|
||||
|
||||
+int cycle_delay=2;
|
||||
+
|
||||
/*****************************************************************************\
|
||||
* *
|
||||
* Debug *
|
||||
@@ -249,7 +251,7 @@ static void sdhci_bcm2708_raw_writel(str
|
||||
/* host->clock is the clock freq in Hz */
|
||||
static hptime_t last_write_hpt;
|
||||
hptime_t now = hptime();
|
||||
- ns_2clk = 2000000000/host->clock;
|
||||
+ ns_2clk = cycle_delay*1000000/(host->clock/1000);
|
||||
|
||||
if (now == last_write_hpt || now == last_write_hpt+1) {
|
||||
/* we can't guarantee any significant time has
|
||||
@@ -1388,6 +1390,7 @@ module_param(emmc_clock_freq, int, 0444)
|
||||
module_param(sync_after_dma, bool, 0444);
|
||||
module_param(missing_status, bool, 0444);
|
||||
module_param(enable_llm, bool, 0444);
|
||||
+module_param(cycle_delay, int, 0444);
|
||||
|
||||
MODULE_DESCRIPTION("Secure Digital Host Controller Interface platform driver");
|
||||
MODULE_AUTHOR("Broadcom <info@broadcom.com>");
|
|
@ -0,0 +1,227 @@
|
|||
From d6442f505a7bf1bebe9bd4689d021f007a269cd6 Mon Sep 17 00:00:00 2001
|
||||
From: dero <de@ro>
|
||||
Date: Mon, 19 Nov 2012 12:46:06 +0100
|
||||
Subject: [PATCH 038/174] Lazy CRC quirk: Implemented retrying mechanisms for
|
||||
SD SSR and SCR, disabled missing_status and spurious CRC ACMD51 quirks by
|
||||
default (should be fixed by the retrying-mechanishm)
|
||||
|
||||
---
|
||||
drivers/mmc/core/sd.c | 115 +++++++++++++++++++++++++++++++++------
|
||||
drivers/mmc/host/sdhci-bcm2708.c | 11 +++-
|
||||
2 files changed, 108 insertions(+), 18 deletions(-)
|
||||
|
||||
--- a/drivers/mmc/core/sd.c
|
||||
+++ b/drivers/mmc/core/sd.c
|
||||
@@ -13,6 +13,8 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/stat.h>
|
||||
+#include <linux/jiffies.h>
|
||||
+#include <linux/nmi.h>
|
||||
|
||||
#include <linux/mmc/host.h>
|
||||
#include <linux/mmc/card.h>
|
||||
@@ -58,6 +60,15 @@ static const unsigned int tacc_mant[] =
|
||||
__res & __mask; \
|
||||
})
|
||||
|
||||
+// timeout for tries
|
||||
+static const unsigned long retry_timeout_ms= 10*1000;
|
||||
+
|
||||
+// try at least 10 times, even if timeout is reached
|
||||
+static const int retry_min_tries= 10;
|
||||
+
|
||||
+// delay between tries
|
||||
+static const unsigned long retry_delay_ms= 10;
|
||||
+
|
||||
/*
|
||||
* Given the decoded CSD structure, decode the raw CID to our CID structure.
|
||||
*/
|
||||
@@ -210,12 +221,62 @@ static int mmc_decode_scr(struct mmc_car
|
||||
}
|
||||
|
||||
/*
|
||||
- * Fetch and process SD Status register.
|
||||
+ * Fetch and process SD Configuration Register.
|
||||
+ */
|
||||
+static int mmc_read_scr(struct mmc_card *card)
|
||||
+{
|
||||
+ unsigned long timeout_at;
|
||||
+ int err, tries;
|
||||
+
|
||||
+ timeout_at= jiffies + msecs_to_jiffies( retry_timeout_ms );
|
||||
+ tries= 0;
|
||||
+
|
||||
+ while( tries < retry_min_tries || time_before( jiffies, timeout_at ) )
|
||||
+ {
|
||||
+ unsigned long delay_at;
|
||||
+ tries++;
|
||||
+
|
||||
+ err = mmc_app_send_scr(card, card->raw_scr);
|
||||
+ if( !err )
|
||||
+ break; // sucess!!!
|
||||
+
|
||||
+ touch_nmi_watchdog(); // we are still alive!
|
||||
+
|
||||
+ // delay
|
||||
+ delay_at= jiffies + msecs_to_jiffies( retry_delay_ms );
|
||||
+ while( time_before( jiffies, delay_at ) )
|
||||
+ {
|
||||
+ mdelay( 1 );
|
||||
+ touch_nmi_watchdog(); // we are still alive!
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if( err)
|
||||
+ {
|
||||
+ pr_err("%s: failed to read SD Configuration register (SCR) after %d tries during %lu ms, error %d\n", mmc_hostname(card->host), tries, retry_timeout_ms, err );
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ if( tries > 1 )
|
||||
+ {
|
||||
+ pr_info("%s: could read SD Configuration register (SCR) at the %dth attempt\n", mmc_hostname(card->host), tries );
|
||||
+ }
|
||||
+
|
||||
+ err = mmc_decode_scr(card);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Fetch and process SD Status Register.
|
||||
*/
|
||||
static int mmc_read_ssr(struct mmc_card *card)
|
||||
{
|
||||
+ unsigned long timeout_at;
|
||||
unsigned int au, es, et, eo;
|
||||
- int err, i;
|
||||
+ int err, i, tries;
|
||||
u32 *ssr;
|
||||
|
||||
if (!(card->csd.cmdclass & CCC_APP_SPEC)) {
|
||||
@@ -227,15 +288,41 @@ static int mmc_read_ssr(struct mmc_card
|
||||
ssr = kmalloc(64, GFP_KERNEL);
|
||||
if (!ssr)
|
||||
return -ENOMEM;
|
||||
-
|
||||
- err = mmc_app_sd_status(card, ssr);
|
||||
- if (err) {
|
||||
- pr_warning("%s: problem reading SD Status "
|
||||
- "register.\n", mmc_hostname(card->host));
|
||||
- err = 0;
|
||||
+
|
||||
+ timeout_at= jiffies + msecs_to_jiffies( retry_timeout_ms );
|
||||
+ tries= 0;
|
||||
+
|
||||
+ while( tries < retry_min_tries || time_before( jiffies, timeout_at ) )
|
||||
+ {
|
||||
+ unsigned long delay_at;
|
||||
+ tries++;
|
||||
+
|
||||
+ err= mmc_app_sd_status(card, ssr);
|
||||
+ if( !err )
|
||||
+ break; // sucess!!!
|
||||
+
|
||||
+ touch_nmi_watchdog(); // we are still alive!
|
||||
+
|
||||
+ // delay
|
||||
+ delay_at= jiffies + msecs_to_jiffies( retry_delay_ms );
|
||||
+ while( time_before( jiffies, delay_at ) )
|
||||
+ {
|
||||
+ mdelay( 1 );
|
||||
+ touch_nmi_watchdog(); // we are still alive!
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if( err)
|
||||
+ {
|
||||
+ pr_err("%s: failed to read SD Status register (SSR) after %d tries during %lu ms, error %d\n", mmc_hostname(card->host), tries, retry_timeout_ms, err );
|
||||
goto out;
|
||||
}
|
||||
|
||||
+ if( tries > 1 )
|
||||
+ {
|
||||
+ pr_info("%s: could read SD Status register (SSR) at the %dth attempt\n", mmc_hostname(card->host), tries );
|
||||
+ }
|
||||
+
|
||||
for (i = 0; i < 16; i++)
|
||||
ssr[i] = be32_to_cpu(ssr[i]);
|
||||
|
||||
@@ -808,15 +895,11 @@ int mmc_sd_setup_card(struct mmc_host *h
|
||||
|
||||
if (!reinit) {
|
||||
/*
|
||||
- * Fetch SCR from card.
|
||||
+ * Fetch and decode SD Configuration register.
|
||||
*/
|
||||
- err = mmc_app_send_scr(card, card->raw_scr);
|
||||
- if (err)
|
||||
- return err;
|
||||
-
|
||||
- err = mmc_decode_scr(card);
|
||||
- if (err)
|
||||
- return err;
|
||||
+ err = mmc_read_scr(card);
|
||||
+ if( err )
|
||||
+ return err;
|
||||
|
||||
/*
|
||||
* Fetch and process SD Status register.
|
||||
--- a/drivers/mmc/host/sdhci-bcm2708.c
|
||||
+++ b/drivers/mmc/host/sdhci-bcm2708.c
|
||||
@@ -137,6 +137,7 @@ static bool allow_highspeed = 1;
|
||||
static int emmc_clock_freq = BCM2708_EMMC_CLOCK_FREQ;
|
||||
static bool sync_after_dma = 1;
|
||||
static bool missing_status = 1;
|
||||
+static bool spurious_crc_acmd51 = 0;
|
||||
bool enable_llm = 1;
|
||||
|
||||
#if 0
|
||||
@@ -1103,7 +1104,7 @@ static unsigned int sdhci_bcm2708_quirk_
|
||||
return 1;
|
||||
}
|
||||
|
||||
-static unsigned int sdhci_bcm2708_quirk_spurious_crc(struct sdhci_host *host)
|
||||
+static unsigned int sdhci_bcm2708_quirk_spurious_crc_acmd51(struct sdhci_host *host)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
@@ -1149,7 +1150,6 @@ static struct sdhci_ops sdhci_bcm2708_op
|
||||
.pdma_reset = sdhci_bcm2708_platdma_reset,
|
||||
#endif
|
||||
.extra_ints = sdhci_bcm2708_quirk_extra_ints,
|
||||
- .spurious_crc_acmd51 = sdhci_bcm2708_quirk_spurious_crc,
|
||||
.voltage_broken = sdhci_bcm2708_quirk_voltage_broken,
|
||||
.uhs_broken = sdhci_bcm2708_uhs_broken,
|
||||
};
|
||||
@@ -1194,6 +1194,11 @@ static int sdhci_bcm2708_probe(struct pl
|
||||
sdhci_bcm2708_ops.missing_status = sdhci_bcm2708_missing_status;
|
||||
}
|
||||
|
||||
+ if( spurious_crc_acmd51 ) {
|
||||
+ sdhci_bcm2708_ops.spurious_crc_acmd51 = sdhci_bcm2708_quirk_spurious_crc_acmd51;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
printk("sdhci: %s low-latency mode\n",enable_llm?"Enable":"Disable");
|
||||
|
||||
host->hw_name = "BCM2708_Arasan";
|
||||
@@ -1389,6 +1394,7 @@ module_param(allow_highspeed, bool, 0444
|
||||
module_param(emmc_clock_freq, int, 0444);
|
||||
module_param(sync_after_dma, bool, 0444);
|
||||
module_param(missing_status, bool, 0444);
|
||||
+module_param(spurious_crc_acmd51, bool, 0444);
|
||||
module_param(enable_llm, bool, 0444);
|
||||
module_param(cycle_delay, int, 0444);
|
||||
|
||||
@@ -1401,6 +1407,7 @@ MODULE_PARM_DESC(allow_highspeed, "Allow
|
||||
MODULE_PARM_DESC(emmc_clock_freq, "Specify the speed of emmc clock");
|
||||
MODULE_PARM_DESC(sync_after_dma, "Block in driver until dma complete");
|
||||
MODULE_PARM_DESC(missing_status, "Use the missing status quirk");
|
||||
+MODULE_PARM_DESC(spurious_crc_acmd51, "Use the spurious crc quirk for reading SCR (ACMD51)");
|
||||
MODULE_PARM_DESC(enable_llm, "Enable low-latency mode");
|
||||
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
From bf571a571b090c16cd49458126e996243d8a2626 Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Thu, 28 Mar 2013 00:10:32 +0000
|
||||
Subject: [PATCH 039/174] bcm2708: Add vc_cma driver to enable use of CMA
|
||||
|
||||
---
|
||||
arch/arm/mach-bcm2708/bcm2708.c | 16 ++++++++++++++++
|
||||
1 file changed, 16 insertions(+)
|
||||
|
||||
--- a/arch/arm/mach-bcm2708/bcm2708.c
|
||||
+++ b/arch/arm/mach-bcm2708/bcm2708.c
|
||||
@@ -60,6 +60,11 @@
|
||||
#include "armctrl.h"
|
||||
#include "clock.h"
|
||||
|
||||
+#ifdef CONFIG_BCM_VC_CMA
|
||||
+#include <linux/broadcom/vc_cma.h>
|
||||
+#endif
|
||||
+
|
||||
+
|
||||
/* Effectively we have an IOMMU (ARM<->VideoCore map) that is set up to
|
||||
* give us IO access only to 64Mbytes of physical memory (26 bits). We could
|
||||
* represent this window by setting our dmamasks to 26 bits but, in fact
|
||||
@@ -693,6 +698,9 @@ void __init bcm2708_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
+#if defined(CONFIG_BCM_VC_CMA)
|
||||
+ vc_cma_early_init();
|
||||
+#endif
|
||||
printk("bcm2708.uart_clock = %d\n", uart_clock);
|
||||
pm_power_off = bcm2708_power_off;
|
||||
|
||||
@@ -889,6 +897,13 @@ void __init bcm2708_init_early(void)
|
||||
init_dma_coherent_pool_size(SZ_4M);
|
||||
}
|
||||
|
||||
+static void __init board_reserve(void)
|
||||
+{
|
||||
+#if defined(CONFIG_BCM_VC_CMA)
|
||||
+ vc_cma_reserve();
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
MACHINE_START(BCM2708, "BCM2708")
|
||||
/* Maintainer: Broadcom Europe Ltd. */
|
||||
.map_io = bcm2708_map_io,
|
||||
@@ -897,6 +912,7 @@ MACHINE_START(BCM2708, "BCM2708")
|
||||
.init_machine = bcm2708_init,
|
||||
.init_early = bcm2708_init_early,
|
||||
.restart = bcm2708_restart,
|
||||
+ .reserve = board_reserve,
|
||||
MACHINE_END
|
||||
|
||||
module_param(boardrev, uint, 0644);
|
|
@ -0,0 +1,20 @@
|
|||
From c7502584abba164c1cda1378c86e95cd879e1e1a Mon Sep 17 00:00:00 2001
|
||||
From: Gordon Hollingworth <gordon@holliweb.co.uk>
|
||||
Date: Sun, 4 Nov 2012 15:55:01 +0000
|
||||
Subject: [PATCH 040/174] Make sure we wait for the reset to finish
|
||||
|
||||
---
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
|
||||
@@ -232,6 +232,8 @@ exit_handler_routine:
|
||||
if (mphi_int_count >= 60)
|
||||
{
|
||||
DWC_WRITE_REG32(c_mphi_regs.ctrl, ((1<<31) + (1<<16)));
|
||||
+ while(!(DWC_READ_REG32(c_mphi_regs.ctrl) & (1 << 17)))
|
||||
+ ;
|
||||
DWC_WRITE_REG32(c_mphi_regs.ctrl, (1<<31));
|
||||
mphi_int_count = 0;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,3 +1,15 @@
|
|||
From b7496d2df33f324ee6854c600944b50a011d95e0 Mon Sep 17 00:00:00 2001
|
||||
From: Aron Szabo <aron@aron.ws>
|
||||
Date: Sat, 16 Jun 2012 12:15:55 +0200
|
||||
Subject: [PATCH 042/174] lirc: added support for RaspberryPi GPIO
|
||||
|
||||
---
|
||||
drivers/staging/media/lirc/Kconfig | 6 +
|
||||
drivers/staging/media/lirc/Makefile | 1 +
|
||||
drivers/staging/media/lirc/lirc_rpi.c | 687 ++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 694 insertions(+)
|
||||
create mode 100644 drivers/staging/media/lirc/lirc_rpi.c
|
||||
|
||||
--- a/drivers/staging/media/lirc/Kconfig
|
||||
+++ b/drivers/staging/media/lirc/Kconfig
|
||||
@@ -38,6 +38,12 @@ config LIRC_PARALLEL
|
||||
|
@ -13,9 +25,19 @@
|
|||
config LIRC_SASEM
|
||||
tristate "Sasem USB IR Remote"
|
||||
depends on LIRC && USB
|
||||
--- a/drivers/staging/media/lirc/Makefile
|
||||
+++ b/drivers/staging/media/lirc/Makefile
|
||||
@@ -7,6 +7,7 @@ obj-$(CONFIG_LIRC_BT829) += lirc_bt829.o
|
||||
obj-$(CONFIG_LIRC_IGORPLUGUSB) += lirc_igorplugusb.o
|
||||
obj-$(CONFIG_LIRC_IMON) += lirc_imon.o
|
||||
obj-$(CONFIG_LIRC_PARALLEL) += lirc_parallel.o
|
||||
+obj-$(CONFIG_LIRC_RPI) += lirc_rpi.o
|
||||
obj-$(CONFIG_LIRC_SASEM) += lirc_sasem.o
|
||||
obj-$(CONFIG_LIRC_SERIAL) += lirc_serial.o
|
||||
obj-$(CONFIG_LIRC_SIR) += lirc_sir.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/staging/media/lirc/lirc_rpi.c
|
||||
@@ -0,0 +1,692 @@
|
||||
@@ -0,0 +1,687 @@
|
||||
+/*
|
||||
+ * lirc_rpi.c
|
||||
+ *
|
||||
|
@ -86,8 +108,6 @@
|
|||
+static int sense = -1;
|
||||
+/* use softcarrier by default */
|
||||
+static int softcarrier = 1;
|
||||
+/* 0 = do not invert output, 1 = invert output */
|
||||
+static int invert = 0;
|
||||
+
|
||||
+struct gpio_chip *gpiochip;
|
||||
+struct irq_chip *irqchip;
|
||||
|
@ -155,10 +175,10 @@
|
|||
+ actual = 0; target = 0; flag = 0;
|
||||
+ while (actual < length) {
|
||||
+ if (flag) {
|
||||
+ gpiochip->set(gpiochip, gpio_out_pin, invert);
|
||||
+ gpiochip->set(gpiochip, gpio_out_pin, 0);
|
||||
+ target += space_width;
|
||||
+ } else {
|
||||
+ gpiochip->set(gpiochip, gpio_out_pin, !invert);
|
||||
+ gpiochip->set(gpiochip, gpio_out_pin, 1);
|
||||
+ target += pulse_width;
|
||||
+ }
|
||||
+ d = (target - actual -
|
||||
|
@ -182,7 +202,7 @@
|
|||
+ if (softcarrier) {
|
||||
+ return send_pulse_softcarrier(length);
|
||||
+ } else {
|
||||
+ gpiochip->set(gpiochip, gpio_out_pin, !invert);
|
||||
+ gpiochip->set(gpiochip, gpio_out_pin, 1);
|
||||
+ safe_udelay(length);
|
||||
+ return 0;
|
||||
+ }
|
||||
|
@ -190,7 +210,7 @@
|
|||
+
|
||||
+static void send_space(long length)
|
||||
+{
|
||||
+ gpiochip->set(gpiochip, gpio_out_pin, invert);
|
||||
+ gpiochip->set(gpiochip, gpio_out_pin, 0);
|
||||
+ if (length <= 0)
|
||||
+ return;
|
||||
+ safe_udelay(length);
|
||||
|
@ -338,7 +358,7 @@
|
|||
+
|
||||
+ gpiochip->direction_input(gpiochip, gpio_in_pin);
|
||||
+ gpiochip->direction_output(gpiochip, gpio_out_pin, 1);
|
||||
+ gpiochip->set(gpiochip, gpio_out_pin, invert);
|
||||
+ gpiochip->set(gpiochip, gpio_out_pin, 0);
|
||||
+
|
||||
+ irq = gpiochip->to_irq(gpiochip, gpio_in_pin);
|
||||
+ dprintk("to_irq %d\n", irq);
|
||||
|
@ -477,7 +497,7 @@
|
|||
+ else
|
||||
+ delta = send_pulse(wbuf[i]);
|
||||
+ }
|
||||
+ gpiochip->set(gpiochip, gpio_out_pin, invert);
|
||||
+ gpiochip->set(gpiochip, gpio_out_pin, 0);
|
||||
+
|
||||
+ spin_unlock_irqrestore(&lock, flags);
|
||||
+ kfree(wbuf);
|
||||
|
@ -703,18 +723,5 @@
|
|||
+module_param(softcarrier, bool, S_IRUGO);
|
||||
+MODULE_PARM_DESC(softcarrier, "Software carrier (0 = off, 1 = on, default on)");
|
||||
+
|
||||
+module_param(invert, bool, S_IRUGO);
|
||||
+MODULE_PARM_DESC(invert, "Invert output (0 = off, 1 = on, default off");
|
||||
+
|
||||
+module_param(debug, bool, S_IRUGO | S_IWUSR);
|
||||
+MODULE_PARM_DESC(debug, "Enable debugging messages");
|
||||
--- a/drivers/staging/media/lirc/Makefile
|
||||
+++ b/drivers/staging/media/lirc/Makefile
|
||||
@@ -7,6 +7,7 @@ obj-$(CONFIG_LIRC_BT829) += lirc_bt829.o
|
||||
obj-$(CONFIG_LIRC_IGORPLUGUSB) += lirc_igorplugusb.o
|
||||
obj-$(CONFIG_LIRC_IMON) += lirc_imon.o
|
||||
obj-$(CONFIG_LIRC_PARALLEL) += lirc_parallel.o
|
||||
+obj-$(CONFIG_LIRC_RPI) += lirc_rpi.o
|
||||
obj-$(CONFIG_LIRC_SASEM) += lirc_sasem.o
|
||||
obj-$(CONFIG_LIRC_SERIAL) += lirc_serial.o
|
||||
obj-$(CONFIG_LIRC_SIR) += lirc_sir.o
|
|
@ -0,0 +1,20 @@
|
|||
From 2a720d265e89fc6145b87420c4cefec1582afa80 Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Tue, 11 Dec 2012 18:23:03 +0000
|
||||
Subject: [PATCH 043/174] Default to dwc_otp.lpm_enable=0
|
||||
|
||||
---
|
||||
drivers/usb/host/dwc_otg/dwc_otg_driver.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_driver.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_driver.c
|
||||
@@ -228,7 +228,7 @@ static struct dwc_otg_driver_module_para
|
||||
.rx_thr_length = -1,
|
||||
.pti_enable = -1,
|
||||
.mpi_enable = -1,
|
||||
- .lpm_enable = -1,
|
||||
+ .lpm_enable = 0,
|
||||
.ic_usb_cap = -1,
|
||||
.ahb_thr_ratio = -1,
|
||||
.power_down = -1,
|
|
@ -0,0 +1,32 @@
|
|||
From 17b1eb8e7fdbca81bc6d74c003b02ca3b08f1fa4 Mon Sep 17 00:00:00 2001
|
||||
From: P33M <P33M@github.com>
|
||||
Date: Wed, 9 Jan 2013 16:12:04 +0000
|
||||
Subject: [PATCH 044/174] dwc_otg: fix bug in dwc_otg_hcd.c resulting in silent
|
||||
kernel memory corruption, escalating to OOPS under high USB load.
|
||||
|
||||
---
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 2 --
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 1 +
|
||||
2 files changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
|
||||
@@ -500,8 +500,6 @@ int dwc_otg_hcd_urb_enqueue(dwc_otg_hcd_
|
||||
DWC_ERROR("DWC OTG HCD URB Enqueue failed adding QTD. "
|
||||
"Error status %d\n", retval);
|
||||
dwc_otg_hcd_qtd_free(qtd);
|
||||
- } else {
|
||||
- qtd->qh = *ep_handle;
|
||||
}
|
||||
intr_mask.d32 = DWC_READ_REG32(&hcd->core_if->core_global_regs->gintmsk);
|
||||
if (!intr_mask.b.sofintr && retval == 0) {
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c
|
||||
@@ -946,6 +946,7 @@ int dwc_otg_hcd_qtd_add(dwc_otg_qtd_t *
|
||||
if (retval == 0) {
|
||||
DWC_CIRCLEQ_INSERT_TAIL(&((*qh)->qtd_list), qtd,
|
||||
qtd_list_entry);
|
||||
+ qtd->qh = *qh;
|
||||
}
|
||||
DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags);
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
From 96bf154aade59a5527611b93bdc3ff5faf8ecc10 Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Mon, 21 Jan 2013 23:03:53 +0000
|
||||
Subject: [PATCH 045/174] Return error value from bcm2708_setup_state. Thanks
|
||||
notro
|
||||
|
||||
---
|
||||
drivers/spi/spi-bcm2708.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/drivers/spi/spi-bcm2708.c
|
||||
+++ b/drivers/spi/spi-bcm2708.c
|
||||
@@ -378,6 +378,7 @@ static int bcm2708_spi_setup(struct spi_
|
||||
if (ret < 0) {
|
||||
kfree(state);
|
||||
spi->controller_state = NULL;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
dev_dbg(&spi->dev,
|
|
@ -0,0 +1,42 @@
|
|||
From 444149f35455bfe551ce9dfa21d00b5b34ffb04f Mon Sep 17 00:00:00 2001
|
||||
From: Kamal Mostafa <kamal@whence.com>
|
||||
Date: Mon, 22 Oct 2012 15:52:44 -0700
|
||||
Subject: [PATCH 046/174] spi/spi-bcm2708: respect per-transfer SPI clock
|
||||
speed_hz value
|
||||
|
||||
The bcm2708 SPI driver's bcm2708_process_transfer() was ignoring the
|
||||
per-transfer speed_hz value even when it was provided (it always just
|
||||
used the spi device's max_speed_hz value). Now, per-transfer speed_hz
|
||||
values are respected.
|
||||
|
||||
Also added debug print to bcm2708_setup_state() to help keep an eye on
|
||||
the configured SPI parameters.
|
||||
|
||||
Signed-off-by: Kamal Mostafa <kamal@whence.com>
|
||||
---
|
||||
drivers/spi/spi-bcm2708.c | 7 ++++++-
|
||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/spi/spi-bcm2708.c
|
||||
+++ b/drivers/spi/spi-bcm2708.c
|
||||
@@ -259,6 +259,10 @@ static int bcm2708_setup_state(struct sp
|
||||
if (state) {
|
||||
state->cs = cs;
|
||||
state->cdiv = cdiv;
|
||||
+ dev_dbg(dev, "setup: want %d Hz; "
|
||||
+ "bus_hz=%lu / cdiv=%u == %lu Hz; "
|
||||
+ "mode %u: cs 0x%08X\n",
|
||||
+ hz, bus_hz, cdiv, bus_hz/cdiv, mode, cs);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -277,7 +281,8 @@ static int bcm2708_process_transfer(stru
|
||||
|
||||
if (xfer->bits_per_word || xfer->speed_hz) {
|
||||
ret = bcm2708_setup_state(spi->master, &spi->dev, &state,
|
||||
- spi->max_speed_hz, spi->chip_select, spi->mode,
|
||||
+ xfer->speed_hz ? xfer->speed_hz : spi->max_speed_hz,
|
||||
+ spi->chip_select, spi->mode,
|
||||
spi->bits_per_word);
|
||||
if (ret)
|
||||
return ret;
|
|
@ -1,3 +1,51 @@
|
|||
From 8a467ffd4cdce4f87c363c24be193b99b2688126 Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Wed, 3 Jul 2013 00:51:55 +0100
|
||||
Subject: [PATCH 047/174] Add hwrng (hardware random number generator) driver
|
||||
|
||||
---
|
||||
arch/arm/mach-bcm2708/include/mach/platform.h | 1 +
|
||||
drivers/char/hw_random/Kconfig | 12 +++
|
||||
drivers/char/hw_random/Makefile | 1 +
|
||||
drivers/char/hw_random/bcm2708-rng.c | 117 ++++++++++++++++++++++++++
|
||||
4 files changed, 131 insertions(+)
|
||||
create mode 100755 drivers/char/hw_random/bcm2708-rng.c
|
||||
|
||||
--- a/arch/arm/mach-bcm2708/include/mach/platform.h
|
||||
+++ b/arch/arm/mach-bcm2708/include/mach/platform.h
|
||||
@@ -62,6 +62,7 @@
|
||||
#define DMA_BASE (BCM2708_PERI_BASE + 0x7000) /* DMA controller */
|
||||
#define ARM_BASE (BCM2708_PERI_BASE + 0xB000) /* BCM2708 ARM control block */
|
||||
#define PM_BASE (BCM2708_PERI_BASE + 0x100000) /* Power Management, Reset controller and Watchdog registers */
|
||||
+#define RNG_BASE (BCM2708_PERI_BASE + 0x104000) /* Hardware RNG */
|
||||
#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) /* GPIO */
|
||||
#define UART0_BASE (BCM2708_PERI_BASE + 0x201000) /* Uart 0 */
|
||||
#define MMCI0_BASE (BCM2708_PERI_BASE + 0x202000) /* MMC interface */
|
||||
--- a/drivers/char/hw_random/Kconfig
|
||||
+++ b/drivers/char/hw_random/Kconfig
|
||||
@@ -314,3 +314,15 @@ config HW_RANDOM_TPM
|
||||
module will be called tpm-rng.
|
||||
|
||||
If unsure, say Y.
|
||||
+
|
||||
+config HW_RANDOM_BCM2708
|
||||
+ tristate "BCM2708 generic true random number generator support"
|
||||
+ depends on HW_RANDOM && ARCH_BCM2708
|
||||
+ ---help---
|
||||
+ This driver provides the kernel-side support for the BCM2708 hardware.
|
||||
+
|
||||
+ To compile this driver as a module, choose M here: the
|
||||
+ module will be called bcm2708-rng.
|
||||
+
|
||||
+ If unsure, say N.
|
||||
+
|
||||
--- a/drivers/char/hw_random/Makefile
|
||||
+++ b/drivers/char/hw_random/Makefile
|
||||
@@ -27,3 +27,4 @@ obj-$(CONFIG_HW_RANDOM_PSERIES) += pseri
|
||||
obj-$(CONFIG_HW_RANDOM_EXYNOS) += exynos-rng.o
|
||||
obj-$(CONFIG_HW_RANDOM_TPM) += tpm-rng.o
|
||||
obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o
|
||||
+obj-$(CONFIG_HW_RANDOM_BCM2708) += bcm2708-rng.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/char/hw_random/bcm2708-rng.c
|
||||
@@ -0,0 +1,117 @@
|
||||
|
@ -118,28 +166,3 @@
|
|||
+
|
||||
+MODULE_DESCRIPTION("BCM2708 H/W Random Number Generator (RNG) driver");
|
||||
+MODULE_LICENSE("GPL and additional rights");
|
||||
--- a/drivers/char/hw_random/Kconfig
|
||||
+++ b/drivers/char/hw_random/Kconfig
|
||||
@@ -314,3 +314,15 @@ config HW_RANDOM_TPM
|
||||
module will be called tpm-rng.
|
||||
|
||||
If unsure, say Y.
|
||||
+
|
||||
+config HW_RANDOM_BCM2708
|
||||
+ tristate "BCM2708 generic true random number generator support"
|
||||
+ depends on HW_RANDOM && ARCH_BCM2708
|
||||
+ ---help---
|
||||
+ This driver provides the kernel-side support for the BCM2708 hardware.
|
||||
+
|
||||
+ To compile this driver as a module, choose M here: the
|
||||
+ module will be called bcm2708-rng.
|
||||
+
|
||||
+ If unsure, say N.
|
||||
+
|
||||
--- a/drivers/char/hw_random/Makefile
|
||||
+++ b/drivers/char/hw_random/Makefile
|
||||
@@ -27,3 +27,4 @@ obj-$(CONFIG_HW_RANDOM_PSERIES) += pseri
|
||||
obj-$(CONFIG_HW_RANDOM_EXYNOS) += exynos-rng.o
|
||||
obj-$(CONFIG_HW_RANDOM_TPM) += tpm-rng.o
|
||||
obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o
|
||||
+obj-$(CONFIG_HW_RANDOM_BCM2708) += bcm2708-rng.o
|
|
@ -0,0 +1,32 @@
|
|||
From 2d37b2d242b41270a7ae1aeccfe06fc253e8d180 Mon Sep 17 00:00:00 2001
|
||||
From: Technion <Technion>
|
||||
Date: Mon, 11 Feb 2013 22:08:53 +1100
|
||||
Subject: [PATCH 048/174] Changed wording on logging. Previously, we received
|
||||
errors like this: mmc0: could read SD Status register (SSR) at the 3th
|
||||
attempt A more sensible response is now returned. A typo also fixed in
|
||||
comments.
|
||||
|
||||
---
|
||||
drivers/mmc/core/sd.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/mmc/core/sd.c
|
||||
+++ b/drivers/mmc/core/sd.c
|
||||
@@ -238,7 +238,7 @@ static int mmc_read_scr(struct mmc_card
|
||||
|
||||
err = mmc_app_send_scr(card, card->raw_scr);
|
||||
if( !err )
|
||||
- break; // sucess!!!
|
||||
+ break; // success!!!
|
||||
|
||||
touch_nmi_watchdog(); // we are still alive!
|
||||
|
||||
@@ -320,7 +320,7 @@ static int mmc_read_ssr(struct mmc_card
|
||||
|
||||
if( tries > 1 )
|
||||
{
|
||||
- pr_info("%s: could read SD Status register (SSR) at the %dth attempt\n", mmc_hostname(card->host), tries );
|
||||
+ pr_info("%s: read SD Status register (SSR) after %d attempts\n", mmc_hostname(card->host), tries );
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i++)
|
|
@ -0,0 +1,82 @@
|
|||
From 08e3e98d28e32852e43bf25fb3e64bb3f5e6af4d Mon Sep 17 00:00:00 2001
|
||||
From: P33M <P33M@github.com>
|
||||
Date: Fri, 15 Feb 2013 22:36:47 +0000
|
||||
Subject: [PATCH 049/174] dwc_otg: Fix unsafe access of QTD during URB enqueue
|
||||
|
||||
In dwc_otg_hcd_urb_enqueue during qtd creation, it was possible that the
|
||||
transaction could complete almost immediately after the qtd was assigned
|
||||
to a host channel during URB enqueue, which meant the qtd pointer was no
|
||||
longer valid having been completed and removed. Usually, this resulted in
|
||||
an OOPS during URB submission. By predetermining whether transactions
|
||||
need to be queued or not, this unsafe pointer access is avoided.
|
||||
|
||||
This bug was only evident on the Pi model A where a device was attached
|
||||
that had no periodic endpoints (e.g. USB pendrive or some wlan devices).
|
||||
---
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 23 ++++++++++++-----------
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 2 +-
|
||||
2 files changed, 13 insertions(+), 12 deletions(-)
|
||||
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
|
||||
@@ -462,6 +462,8 @@ int dwc_otg_hcd_urb_enqueue(dwc_otg_hcd_
|
||||
{
|
||||
dwc_irqflags_t flags;
|
||||
int retval = 0;
|
||||
+ uint8_t needs_scheduling = 0;
|
||||
+ dwc_otg_transaction_type_e tr_type;
|
||||
dwc_otg_qtd_t *qtd;
|
||||
gintmsk_data_t intr_mask = {.d32 = 0 };
|
||||
|
||||
@@ -493,22 +495,22 @@ int dwc_otg_hcd_urb_enqueue(dwc_otg_hcd_
|
||||
return -DWC_E_NO_MEMORY;
|
||||
}
|
||||
#endif
|
||||
- retval =
|
||||
- dwc_otg_hcd_qtd_add(qtd, hcd, (dwc_otg_qh_t **) ep_handle, atomic_alloc);
|
||||
+ intr_mask.d32 = DWC_READ_REG32(&hcd->core_if->core_global_regs->gintmsk);
|
||||
+ if(!intr_mask.b.sofintr) needs_scheduling = 1;
|
||||
+ if((((dwc_otg_qh_t *)ep_handle)->ep_type == UE_BULK) && !(qtd->urb->flags & URB_GIVEBACK_ASAP))
|
||||
+ /* Do not schedule SG transactions until qtd has URB_GIVEBACK_ASAP set */
|
||||
+ needs_scheduling = 0;
|
||||
+
|
||||
+ retval = dwc_otg_hcd_qtd_add(qtd, hcd, (dwc_otg_qh_t **) ep_handle, atomic_alloc);
|
||||
// creates a new queue in ep_handle if it doesn't exist already
|
||||
if (retval < 0) {
|
||||
DWC_ERROR("DWC OTG HCD URB Enqueue failed adding QTD. "
|
||||
"Error status %d\n", retval);
|
||||
dwc_otg_hcd_qtd_free(qtd);
|
||||
+ return retval;
|
||||
}
|
||||
- intr_mask.d32 = DWC_READ_REG32(&hcd->core_if->core_global_regs->gintmsk);
|
||||
- if (!intr_mask.b.sofintr && retval == 0) {
|
||||
- dwc_otg_transaction_type_e tr_type;
|
||||
- if ((qtd->qh->ep_type == UE_BULK)
|
||||
- && !(qtd->urb->flags & URB_GIVEBACK_ASAP)) {
|
||||
- /* Do not schedule SG transactions until qtd has URB_GIVEBACK_ASAP set */
|
||||
- return 0;
|
||||
- }
|
||||
+
|
||||
+ if(needs_scheduling) {
|
||||
DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags);
|
||||
tr_type = dwc_otg_hcd_select_transactions(hcd);
|
||||
if (tr_type != DWC_OTG_TRANSACTION_NONE) {
|
||||
@@ -516,7 +518,6 @@ int dwc_otg_hcd_urb_enqueue(dwc_otg_hcd_
|
||||
}
|
||||
DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags);
|
||||
}
|
||||
-
|
||||
return retval;
|
||||
}
|
||||
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c
|
||||
@@ -937,7 +937,7 @@ int dwc_otg_hcd_qtd_add(dwc_otg_qtd_t *
|
||||
if (*qh == NULL) {
|
||||
*qh = dwc_otg_hcd_qh_create(hcd, urb, atomic_alloc);
|
||||
if (*qh == NULL) {
|
||||
- retval = -1;
|
||||
+ retval = -DWC_E_NO_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
From e3e9b6dbd5507ea5e571acae3ef6ed2e2d5dadcf Mon Sep 17 00:00:00 2001
|
||||
From: P33M <P33M@github.com>
|
||||
Date: Fri, 15 Feb 2013 22:38:40 +0000
|
||||
Subject: [PATCH 050/174] dwc_otg: Fix incorrect URB allocation error handling
|
||||
|
||||
If the memory allocation for a dwc_otg_urb failed, the kernel would OOPS
|
||||
because for some reason a member of the *unallocated* struct was set to
|
||||
zero. Error handling changed to fail correctly.
|
||||
---
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 16 ++++++----------
|
||||
1 file changed, 6 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
|
||||
@@ -3136,17 +3136,13 @@ dwc_otg_hcd_urb_t *dwc_otg_hcd_urb_alloc
|
||||
else
|
||||
dwc_otg_urb = DWC_ALLOC(size);
|
||||
|
||||
- if (NULL != dwc_otg_urb)
|
||||
- dwc_otg_urb->packet_count = iso_desc_count;
|
||||
+ if (dwc_otg_urb)
|
||||
+ dwc_otg_urb->packet_count = iso_desc_count;
|
||||
else {
|
||||
- dwc_otg_urb->packet_count = 0;
|
||||
- if (size != 0) {
|
||||
- DWC_ERROR("**** DWC OTG HCD URB alloc - "
|
||||
- "%salloc of %db failed\n",
|
||||
- atomic_alloc?"atomic ":"", size);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
+ DWC_ERROR("**** DWC OTG HCD URB alloc - "
|
||||
+ "%salloc of %db failed\n",
|
||||
+ atomic_alloc?"atomic ":"", size);
|
||||
+ }
|
||||
return dwc_otg_urb;
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
From f1f13a6b3798161ccc3852320bd2184b85c9209b Mon Sep 17 00:00:00 2001
|
||||
From: pjennings <pjennings-git@pjennings.net>
|
||||
Date: Wed, 20 Feb 2013 17:51:43 -0600
|
||||
Subject: [PATCH 051/174] Added inverted transmitter support
|
||||
|
||||
---
|
||||
drivers/staging/media/lirc/lirc_rpi.c | 17 +++++++++++------
|
||||
1 file changed, 11 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/staging/media/lirc/lirc_rpi.c
|
||||
+++ b/drivers/staging/media/lirc/lirc_rpi.c
|
||||
@@ -68,6 +68,8 @@ static int debug;
|
||||
static int sense = -1;
|
||||
/* use softcarrier by default */
|
||||
static int softcarrier = 1;
|
||||
+/* 0 = do not invert output, 1 = invert output */
|
||||
+static int invert = 0;
|
||||
|
||||
struct gpio_chip *gpiochip;
|
||||
struct irq_chip *irqchip;
|
||||
@@ -135,10 +137,10 @@ static long send_pulse_softcarrier(unsig
|
||||
actual = 0; target = 0; flag = 0;
|
||||
while (actual < length) {
|
||||
if (flag) {
|
||||
- gpiochip->set(gpiochip, gpio_out_pin, 0);
|
||||
+ gpiochip->set(gpiochip, gpio_out_pin, invert);
|
||||
target += space_width;
|
||||
} else {
|
||||
- gpiochip->set(gpiochip, gpio_out_pin, 1);
|
||||
+ gpiochip->set(gpiochip, gpio_out_pin, !invert);
|
||||
target += pulse_width;
|
||||
}
|
||||
d = (target - actual -
|
||||
@@ -162,7 +164,7 @@ static long send_pulse(unsigned long len
|
||||
if (softcarrier) {
|
||||
return send_pulse_softcarrier(length);
|
||||
} else {
|
||||
- gpiochip->set(gpiochip, gpio_out_pin, 1);
|
||||
+ gpiochip->set(gpiochip, gpio_out_pin, !invert);
|
||||
safe_udelay(length);
|
||||
return 0;
|
||||
}
|
||||
@@ -170,7 +172,7 @@ static long send_pulse(unsigned long len
|
||||
|
||||
static void send_space(long length)
|
||||
{
|
||||
- gpiochip->set(gpiochip, gpio_out_pin, 0);
|
||||
+ gpiochip->set(gpiochip, gpio_out_pin, invert);
|
||||
if (length <= 0)
|
||||
return;
|
||||
safe_udelay(length);
|
||||
@@ -318,7 +320,7 @@ static int init_port(void)
|
||||
|
||||
gpiochip->direction_input(gpiochip, gpio_in_pin);
|
||||
gpiochip->direction_output(gpiochip, gpio_out_pin, 1);
|
||||
- gpiochip->set(gpiochip, gpio_out_pin, 0);
|
||||
+ gpiochip->set(gpiochip, gpio_out_pin, invert);
|
||||
|
||||
irq = gpiochip->to_irq(gpiochip, gpio_in_pin);
|
||||
dprintk("to_irq %d\n", irq);
|
||||
@@ -457,7 +459,7 @@ static ssize_t lirc_write(struct file *f
|
||||
else
|
||||
delta = send_pulse(wbuf[i]);
|
||||
}
|
||||
- gpiochip->set(gpiochip, gpio_out_pin, 0);
|
||||
+ gpiochip->set(gpiochip, gpio_out_pin, invert);
|
||||
|
||||
spin_unlock_irqrestore(&lock, flags);
|
||||
kfree(wbuf);
|
||||
@@ -683,5 +685,8 @@ MODULE_PARM_DESC(sense, "Override autode
|
||||
module_param(softcarrier, bool, S_IRUGO);
|
||||
MODULE_PARM_DESC(softcarrier, "Software carrier (0 = off, 1 = on, default on)");
|
||||
|
||||
+module_param(invert, bool, S_IRUGO);
|
||||
+MODULE_PARM_DESC(invert, "Invert output (0 = off, 1 = on, default off");
|
||||
+
|
||||
module_param(debug, bool, S_IRUGO | S_IWUSR);
|
||||
MODULE_PARM_DESC(debug, "Enable debugging messages");
|
|
@ -0,0 +1,124 @@
|
|||
From 2e7a6ee154b800b1e749e99d20a29673eea70aa1 Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Sun, 24 Feb 2013 16:30:57 +0000
|
||||
Subject: [PATCH 052/174] Add retry on error and tidy of temperature driver
|
||||
|
||||
---
|
||||
drivers/thermal/bcm2835-thermal.c | 78 ++++++++++++++-------------------------
|
||||
1 file changed, 27 insertions(+), 51 deletions(-)
|
||||
|
||||
--- a/drivers/thermal/bcm2835-thermal.c
|
||||
+++ b/drivers/thermal/bcm2835-thermal.c
|
||||
@@ -33,7 +33,6 @@
|
||||
#define print_debug(fmt,...)
|
||||
#endif
|
||||
#define print_err(fmt,...) printk(KERN_ERR "%s:%s:%d: "fmt"\n", MODULE_NAME, __func__,__LINE__, ##__VA_ARGS__)
|
||||
-#define print_info(fmt,...) printk(KERN_INFO "%s: "fmt"\n", MODULE_NAME, ##__VA_ARGS__)
|
||||
|
||||
#define VC_TAG_GET_TEMP 0x00030006
|
||||
#define VC_TAG_GET_MAX_TEMP 0x0003000A
|
||||
@@ -66,12 +65,6 @@ struct bcm2835_thermal_data {
|
||||
struct vc_msg msg;
|
||||
};
|
||||
|
||||
-/* --- PROTOTYPES --- */
|
||||
-static int bcm2835_get_temp(struct thermal_zone_device *thermal_dev, unsigned long *);
|
||||
-static int bcm2835_get_max_temp(struct thermal_zone_device *thermal_dev, int, unsigned long *);
|
||||
-static int bcm2835_get_trip_type(struct thermal_zone_device *thermal_dev, int trip_num, enum thermal_trip_type *trip_type);
|
||||
-static int bcm2835_get_mode(struct thermal_zone_device *thermal_dev, enum thermal_device_mode *dev_mode);
|
||||
-
|
||||
/* --- GLOBALS --- */
|
||||
static struct bcm2835_thermal_data bcm2835_data;
|
||||
|
||||
@@ -79,64 +72,47 @@ static struct bcm2835_thermal_data bcm28
|
||||
static struct thermal_zone_device_ops ops;
|
||||
|
||||
/* --- FUNCTIONS --- */
|
||||
-static int bcm2835_get_max_temp(struct thermal_zone_device *thermal_dev, int trip_num, unsigned long *temp)
|
||||
-{
|
||||
- int result;
|
||||
|
||||
+static int bcm2835_get_temp_or_max(struct thermal_zone_device *thermal_dev, unsigned long *temp, unsigned tag_id)
|
||||
+{
|
||||
+ int result = -1, retry = 3;
|
||||
print_debug("IN");
|
||||
|
||||
- /* wipe all previous message data */
|
||||
- memset(&bcm2835_data.msg, 0, sizeof bcm2835_data.msg);
|
||||
-
|
||||
- /* prepare message */
|
||||
- bcm2835_data.msg.msg_size = sizeof bcm2835_data.msg;
|
||||
- bcm2835_data.msg.tag.buffer_size = 8;
|
||||
- bcm2835_data.msg.tag.tag_id = VC_TAG_GET_MAX_TEMP;
|
||||
-
|
||||
- /* send the message */
|
||||
- result = bcm_mailbox_property(&bcm2835_data.msg, sizeof bcm2835_data.msg);
|
||||
+ *temp = 0;
|
||||
+ while (result != 0 && retry-- > 0) {
|
||||
+ /* wipe all previous message data */
|
||||
+ memset(&bcm2835_data.msg, 0, sizeof bcm2835_data.msg);
|
||||
+
|
||||
+ /* prepare message */
|
||||
+ bcm2835_data.msg.msg_size = sizeof bcm2835_data.msg;
|
||||
+ bcm2835_data.msg.tag.buffer_size = 8;
|
||||
+ bcm2835_data.msg.tag.tag_id = tag_id;
|
||||
+
|
||||
+ /* send the message */
|
||||
+ result = bcm_mailbox_property(&bcm2835_data.msg, sizeof bcm2835_data.msg);
|
||||
+ print_debug("Got %stemperature as %u (%d,%x)\n", tag_id==VC_TAG_GET_MAX_TEMP ? "max ":"", (uint)bcm2835_data.msg.tag.val, result, bcm2835_data.msg.request_code);
|
||||
+ if (!(bcm2835_data.msg.request_code & 0x80000000))
|
||||
+ result = -1;
|
||||
+ }
|
||||
|
||||
/* check if it was all ok and return the rate in milli degrees C */
|
||||
- if (result == 0 && (bcm2835_data.msg.request_code & 0x80000000))
|
||||
+ if (result == 0)
|
||||
*temp = (uint)bcm2835_data.msg.tag.val;
|
||||
- #ifdef THERMAL_DEBUG_ENABLE
|
||||
else
|
||||
- print_debug("Failed to get temperature!");
|
||||
- #endif
|
||||
- print_debug("Got temperature as %u",(uint)*temp);
|
||||
+ print_err("Failed to get temperature! (%x:%d)\n", tag_id, result);
|
||||
print_debug("OUT");
|
||||
- return 0;
|
||||
+ return result;
|
||||
}
|
||||
|
||||
static int bcm2835_get_temp(struct thermal_zone_device *thermal_dev, unsigned long *temp)
|
||||
{
|
||||
- int result;
|
||||
-
|
||||
- print_debug("IN");
|
||||
-
|
||||
- /* wipe all previous message data */
|
||||
- memset(&bcm2835_data.msg, 0, sizeof bcm2835_data.msg);
|
||||
-
|
||||
- /* prepare message */
|
||||
- bcm2835_data.msg.msg_size = sizeof bcm2835_data.msg;
|
||||
- bcm2835_data.msg.tag.buffer_size = 8;
|
||||
- bcm2835_data.msg.tag.tag_id = VC_TAG_GET_TEMP;
|
||||
-
|
||||
- /* send the message */
|
||||
- result = bcm_mailbox_property(&bcm2835_data.msg, sizeof bcm2835_data.msg);
|
||||
-
|
||||
- /* check if it was all ok and return the rate in milli degrees C */
|
||||
- if (result == 0 && (bcm2835_data.msg.request_code & 0x80000000))
|
||||
- *temp = (uint)bcm2835_data.msg.tag.val;
|
||||
- #ifdef THERMAL_DEBUG_ENABLE
|
||||
- else
|
||||
- print_debug("Failed to get temperature!");
|
||||
- #endif
|
||||
- print_debug("Got temperature as %u",(uint)*temp);
|
||||
- print_debug("OUT");
|
||||
- return 0;
|
||||
+ return bcm2835_get_temp_or_max(thermal_dev, temp, VC_TAG_GET_TEMP);
|
||||
}
|
||||
|
||||
+static int bcm2835_get_max_temp(struct thermal_zone_device *thermal_dev, int trip_num, unsigned long *temp)
|
||||
+{
|
||||
+ return bcm2835_get_temp_or_max(thermal_dev, temp, VC_TAG_GET_MAX_TEMP);
|
||||
+}
|
||||
|
||||
static int bcm2835_get_trip_type(struct thermal_zone_device * thermal_dev, int trip_num, enum thermal_trip_type *trip_type)
|
||||
{
|
|
@ -0,0 +1,29 @@
|
|||
From 51d7ae6f936ea32dedbe423fab97e3281994fe82 Mon Sep 17 00:00:00 2001
|
||||
From: P33M <P33M@github.com>
|
||||
Date: Thu, 28 Feb 2013 16:52:51 +0000
|
||||
Subject: [PATCH 053/174] dwc_otg: fix potential use-after-free case in
|
||||
interrupt handler
|
||||
|
||||
If a transaction had previously aborted, certain interrupts are
|
||||
enabled to track error counts and reset where necessary. On IN
|
||||
endpoints the host generates an ACK interrupt near-simultaneously
|
||||
with completion of transfer. In the case where this transfer had
|
||||
previously had an error, this results in a use-after-free on
|
||||
the QTD memory space with a 1-byte length being overwritten to
|
||||
0x00.
|
||||
---
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
|
||||
@@ -2223,7 +2223,8 @@ int32_t dwc_otg_hcd_handle_hc_n_intr(dwc
|
||||
retval |= handle_hc_nak_intr(dwc_otg_hcd, hc, hc_regs, qtd);
|
||||
}
|
||||
if (hcint.b.ack) {
|
||||
- retval |= handle_hc_ack_intr(dwc_otg_hcd, hc, hc_regs, qtd);
|
||||
+ if(!hcint.b.chhltd)
|
||||
+ retval |= handle_hc_ack_intr(dwc_otg_hcd, hc, hc_regs, qtd);
|
||||
}
|
||||
if (hcint.b.nyet) {
|
||||
retval |= handle_hc_nyet_intr(dwc_otg_hcd, hc, hc_regs, qtd);
|
|
@ -0,0 +1,52 @@
|
|||
From f90755cd13b722cd3ea79bee92c29d2828b3905f Mon Sep 17 00:00:00 2001
|
||||
From: P33M <P33M@github.com>
|
||||
Date: Sun, 3 Mar 2013 14:45:53 +0000
|
||||
Subject: [PATCH 054/174] dwc_otg: add handling of SPLIT transaction data
|
||||
toggle errors
|
||||
|
||||
Previously a data toggle error on packets from a USB1.1 device behind
|
||||
a TT would result in the Pi locking up as the driver never handled
|
||||
the associated interrupt. Patch adds basic retry mechanism and
|
||||
interrupt acknowledgement to cater for either a chance toggle error or
|
||||
for devices that have a broken initial toggle state (FT8U232/FT232BM).
|
||||
---
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 19 ++++++++++++++-----
|
||||
1 file changed, 14 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
|
||||
@@ -1921,13 +1921,20 @@ static int32_t handle_hc_datatglerr_intr
|
||||
dwc_otg_qtd_t * qtd)
|
||||
{
|
||||
DWC_DEBUGPL(DBG_HCDI, "--Host Channel %d Interrupt: "
|
||||
- "Data Toggle Error--\n", hc->hc_num);
|
||||
+ "Data Toggle Error on %s transfer--\n",
|
||||
+ hc->hc_num, (hc->ep_is_in ? "IN" : "OUT"));
|
||||
|
||||
- if (hc->ep_is_in) {
|
||||
+ /* Data toggles on split transactions cause the hc to halt.
|
||||
+ * restart transfer */
|
||||
+ if(hc->qh->do_split)
|
||||
+ {
|
||||
+ qtd->error_count++;
|
||||
+ dwc_otg_hcd_save_data_toggle(hc, hc_regs, qtd);
|
||||
+ update_urb_state_xfer_intr(hc, hc_regs,
|
||||
+ qtd->urb, qtd, DWC_OTG_HC_XFER_XACT_ERR);
|
||||
+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_XACT_ERR);
|
||||
+ } else if (hc->ep_is_in) {
|
||||
qtd->error_count = 0;
|
||||
- } else {
|
||||
- DWC_ERROR("Data Toggle Error on OUT transfer,"
|
||||
- "channel %d\n", hc->hc_num);
|
||||
}
|
||||
|
||||
disable_hc_int(hc_regs, datatglerr);
|
||||
@@ -2080,6 +2087,8 @@ static void handle_hc_chhltd_intr_dma(dw
|
||||
handle_hc_babble_intr(hcd, hc, hc_regs, qtd);
|
||||
} else if (hcint.b.frmovrun) {
|
||||
handle_hc_frmovrun_intr(hcd, hc, hc_regs, qtd);
|
||||
+ } else if (hcint.b.datatglerr) {
|
||||
+ handle_hc_datatglerr_intr(hcd, hc, hc_regs, qtd);
|
||||
} else if (!out_nak_enh) {
|
||||
if (hcint.b.nyet) {
|
||||
/*
|
|
@ -0,0 +1,130 @@
|
|||
From 28ca85a46bbdae4152b48a669872ac205d053856 Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Wed, 1 May 2013 21:14:28 +0100
|
||||
Subject: [PATCH 055/174] Add bitbanging pullups, use them for w1-gpio
|
||||
|
||||
Allows parasite power to work, uses module option pullup=1
|
||||
---
|
||||
drivers/w1/masters/w1-gpio.c | 20 ++++++++++++++++++++
|
||||
drivers/w1/w1.h | 6 ++++++
|
||||
drivers/w1/w1_int.c | 16 +++++++++-------
|
||||
drivers/w1/w1_io.c | 18 +++++++++++++++---
|
||||
4 files changed, 50 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/drivers/w1/masters/w1-gpio.c
|
||||
+++ b/drivers/w1/masters/w1-gpio.c
|
||||
@@ -23,6 +23,9 @@
|
||||
#include "../w1.h"
|
||||
#include "../w1_int.h"
|
||||
|
||||
+static int w1_gpio_pullup = 0;
|
||||
+module_param_named(pullup, w1_gpio_pullup, int, 0);
|
||||
+
|
||||
static void w1_gpio_write_bit_dir(void *data, u8 bit)
|
||||
{
|
||||
struct w1_gpio_platform_data *pdata = data;
|
||||
@@ -47,6 +50,16 @@ static u8 w1_gpio_read_bit(void *data)
|
||||
return gpio_get_value(pdata->pin) ? 1 : 0;
|
||||
}
|
||||
|
||||
+static void w1_gpio_bitbang_pullup(void *data, u8 on)
|
||||
+{
|
||||
+ struct w1_gpio_platform_data *pdata = data;
|
||||
+
|
||||
+ if (on)
|
||||
+ gpio_direction_output(pdata->pin, 1);
|
||||
+ else
|
||||
+ gpio_direction_input(pdata->pin);
|
||||
+}
|
||||
+
|
||||
#if defined(CONFIG_OF)
|
||||
static struct of_device_id w1_gpio_dt_ids[] = {
|
||||
{ .compatible = "w1-gpio" },
|
||||
@@ -133,6 +146,13 @@ static int w1_gpio_probe(struct platform
|
||||
master->write_bit = w1_gpio_write_bit_dir;
|
||||
}
|
||||
|
||||
+ if (w1_gpio_pullup)
|
||||
+ if (pdata->is_open_drain)
|
||||
+ printk(KERN_ERR "w1-gpio 'pullup' option "
|
||||
+ "doesn't work with open drain GPIO\n");
|
||||
+ else
|
||||
+ master->bitbang_pullup = w1_gpio_bitbang_pullup;
|
||||
+
|
||||
err = w1_add_master_device(master);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "w1_add_master device failed\n");
|
||||
--- a/drivers/w1/w1.h
|
||||
+++ b/drivers/w1/w1.h
|
||||
@@ -148,6 +148,12 @@ struct w1_bus_master
|
||||
*/
|
||||
u8 (*set_pullup)(void *, int);
|
||||
|
||||
+ /**
|
||||
+ * Turns the pullup on/off in bitbanging mode, takes an on/off argument.
|
||||
+ * @return -1=Error, 0=completed
|
||||
+ */
|
||||
+ void (*bitbang_pullup) (void *, u8);
|
||||
+
|
||||
/** Really nice hardware can handles the different types of ROM search
|
||||
* w1_master* is passed to the slave found callback.
|
||||
*/
|
||||
--- a/drivers/w1/w1_int.c
|
||||
+++ b/drivers/w1/w1_int.c
|
||||
@@ -117,19 +117,21 @@ int w1_add_master_device(struct w1_bus_m
|
||||
printk(KERN_ERR "w1_add_master_device: invalid function set\n");
|
||||
return(-EINVAL);
|
||||
}
|
||||
- /* While it would be electrically possible to make a device that
|
||||
- * generated a strong pullup in bit bang mode, only hardware that
|
||||
- * controls 1-wire time frames are even expected to support a strong
|
||||
- * pullup. w1_io.c would need to support calling set_pullup before
|
||||
- * the last write_bit operation of a w1_write_8 which it currently
|
||||
- * doesn't.
|
||||
- */
|
||||
+
|
||||
+ /* bitbanging hardware uses bitbang_pullup, other hardware uses set_pullup
|
||||
+ * and takes care of timing itself */
|
||||
if (!master->write_byte && !master->touch_bit && master->set_pullup) {
|
||||
printk(KERN_ERR "w1_add_master_device: set_pullup requires "
|
||||
"write_byte or touch_bit, disabling\n");
|
||||
master->set_pullup = NULL;
|
||||
}
|
||||
|
||||
+ if (master->set_pullup && master->bitbang_pullup) {
|
||||
+ printk(KERN_ERR "w1_add_master_device: set_pullup should not "
|
||||
+ "be set when bitbang_pullup is used, disabling\n");
|
||||
+ master->set_pullup = NULL;
|
||||
+ }
|
||||
+
|
||||
/* Lock until the device is added (or not) to w1_masters. */
|
||||
mutex_lock(&w1_mlock);
|
||||
/* Search for the first available id (starting at 1). */
|
||||
--- a/drivers/w1/w1_io.c
|
||||
+++ b/drivers/w1/w1_io.c
|
||||
@@ -127,10 +127,22 @@ static void w1_pre_write(struct w1_maste
|
||||
static void w1_post_write(struct w1_master *dev)
|
||||
{
|
||||
if (dev->pullup_duration) {
|
||||
- if (dev->enable_pullup && dev->bus_master->set_pullup)
|
||||
- dev->bus_master->set_pullup(dev->bus_master->data, 0);
|
||||
- else
|
||||
+ if (dev->enable_pullup) {
|
||||
+ if (dev->bus_master->set_pullup) {
|
||||
+ dev->bus_master->set_pullup(dev->
|
||||
+ bus_master->data,
|
||||
+ 0);
|
||||
+ } else if (dev->bus_master->bitbang_pullup) {
|
||||
+ dev->bus_master->
|
||||
+ bitbang_pullup(dev->bus_master->data, 1);
|
||||
msleep(dev->pullup_duration);
|
||||
+ dev->bus_master->
|
||||
+ bitbang_pullup(dev->bus_master->data, 0);
|
||||
+ }
|
||||
+ } else {
|
||||
+ msleep(dev->pullup_duration);
|
||||
+ }
|
||||
+
|
||||
dev->pullup_duration = 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
From 75c9b03f90ca974cb072d96f423884b773ca5425 Mon Sep 17 00:00:00 2001
|
||||
From: notro <notro@tronnes.org>
|
||||
Date: Sat, 26 Jan 2013 20:38:03 +0100
|
||||
Subject: [PATCH 056/174] spi-bcm2708: add 9-bit support using LoSSI mode
|
||||
|
||||
---
|
||||
drivers/spi/spi-bcm2708.c | 30 ++++++++++++++++++++++++++++--
|
||||
1 file changed, 28 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/spi/spi-bcm2708.c
|
||||
+++ b/drivers/spi/spi-bcm2708.c
|
||||
@@ -146,10 +146,31 @@ static inline void bcm2708_rd_fifo(struc
|
||||
static inline void bcm2708_wr_fifo(struct bcm2708_spi *bs, int len)
|
||||
{
|
||||
u8 byte;
|
||||
+ u16 val;
|
||||
|
||||
if (len > bs->len)
|
||||
len = bs->len;
|
||||
|
||||
+ if (unlikely(bcm2708_rd(bs, SPI_CS) & SPI_CS_LEN)) {
|
||||
+ /* LoSSI mode */
|
||||
+ if (unlikely(len % 2)) {
|
||||
+ printk(KERN_ERR"bcm2708_wr_fifo: length must be even, skipping.\n");
|
||||
+ bs->len = 0;
|
||||
+ return;
|
||||
+ }
|
||||
+ while (len) {
|
||||
+ if (bs->tx_buf) {
|
||||
+ val = *(const u16 *)bs->tx_buf;
|
||||
+ bs->tx_buf += 2;
|
||||
+ } else
|
||||
+ val = 0;
|
||||
+ bcm2708_wr(bs, SPI_FIFO, val);
|
||||
+ bs->len -= 2;
|
||||
+ len -= 2;
|
||||
+ }
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
while (len--) {
|
||||
byte = bs->tx_buf ? *bs->tx_buf++ : 0;
|
||||
bcm2708_wr(bs, SPI_FIFO, byte);
|
||||
@@ -234,8 +255,12 @@ static int bcm2708_setup_state(struct sp
|
||||
switch (bpw) {
|
||||
case 8:
|
||||
break;
|
||||
+ case 9:
|
||||
+ /* Reading in LoSSI mode is a special case. See 'BCM2835 ARM Peripherals' datasheet */
|
||||
+ cs |= SPI_CS_LEN;
|
||||
+ break;
|
||||
default:
|
||||
- dev_dbg(dev, "setup: invalid bits_per_word %u (must be 8)\n",
|
||||
+ dev_dbg(dev, "setup: invalid bits_per_word %u (must be 8 or 9)\n",
|
||||
bpw);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -283,7 +308,8 @@ static int bcm2708_process_transfer(stru
|
||||
ret = bcm2708_setup_state(spi->master, &spi->dev, &state,
|
||||
xfer->speed_hz ? xfer->speed_hz : spi->max_speed_hz,
|
||||
spi->chip_select, spi->mode,
|
||||
- spi->bits_per_word);
|
||||
+ xfer->bits_per_word ? xfer->bits_per_word :
|
||||
+ spi->bits_per_word);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
@ -0,0 +1,229 @@
|
|||
From 71109f7d314b6205259d5cecf8314708f84fb9e6 Mon Sep 17 00:00:00 2001
|
||||
From: P33M <P33M@github.com>
|
||||
Date: Thu, 21 Mar 2013 19:36:17 +0000
|
||||
Subject: [PATCH 057/174] dwc_otg: implement tasklet for returning URBs to
|
||||
usbcore hcd layer
|
||||
|
||||
The dwc_otg driver interrupt handler for transfer completion will spend
|
||||
a very long time with interrupts disabled when a URB is completed -
|
||||
this is because usb_hcd_giveback_urb is called from within the handler
|
||||
which for a USB device driver with complicated processing (e.g. webcam)
|
||||
will take an exorbitant amount of time to complete. This results in
|
||||
missed completion interrupts for other USB packets which lead to them
|
||||
being dropped due to microframe overruns.
|
||||
|
||||
This patch splits returning the URB to the usb hcd layer into a
|
||||
high-priority tasklet. This will have most benefit for isochronous IN
|
||||
transfers but will also have incidental benefit where multiple periodic
|
||||
devices are active at once.
|
||||
---
|
||||
.../usb/host/dwc_common_port/dwc_common_linux.c | 5 ++++
|
||||
drivers/usb/host/dwc_common_port/dwc_list.h | 14 ++++-----
|
||||
drivers/usb/host/dwc_common_port/dwc_os.h | 2 ++
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 34 +++++++++++++++++++++-
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd.h | 10 +++++++
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 25 ++++++++++------
|
||||
6 files changed, 73 insertions(+), 17 deletions(-)
|
||||
|
||||
--- a/drivers/usb/host/dwc_common_port/dwc_common_linux.c
|
||||
+++ b/drivers/usb/host/dwc_common_port/dwc_common_linux.c
|
||||
@@ -991,6 +991,11 @@ void DWC_TASK_SCHEDULE(dwc_tasklet_t *ta
|
||||
tasklet_schedule(&task->t);
|
||||
}
|
||||
|
||||
+void DWC_TASK_HI_SCHEDULE(dwc_tasklet_t *task)
|
||||
+{
|
||||
+ tasklet_hi_schedule(&task->t);
|
||||
+}
|
||||
+
|
||||
|
||||
/* workqueues
|
||||
- run in process context (can sleep)
|
||||
--- a/drivers/usb/host/dwc_common_port/dwc_list.h
|
||||
+++ b/drivers/usb/host/dwc_common_port/dwc_list.h
|
||||
@@ -384,17 +384,17 @@ struct { \
|
||||
#define DWC_TAILQ_PREV(elm, headname, field) \
|
||||
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
|
||||
#define DWC_TAILQ_EMPTY(head) \
|
||||
- (TAILQ_FIRST(head) == TAILQ_END(head))
|
||||
+ (DWC_TAILQ_FIRST(head) == DWC_TAILQ_END(head))
|
||||
|
||||
#define DWC_TAILQ_FOREACH(var, head, field) \
|
||||
- for((var) = TAILQ_FIRST(head); \
|
||||
- (var) != TAILQ_END(head); \
|
||||
- (var) = TAILQ_NEXT(var, field))
|
||||
+ for ((var) = DWC_TAILQ_FIRST(head); \
|
||||
+ (var) != DWC_TAILQ_END(head); \
|
||||
+ (var) = DWC_TAILQ_NEXT(var, field))
|
||||
|
||||
#define DWC_TAILQ_FOREACH_REVERSE(var, head, headname, field) \
|
||||
- for((var) = TAILQ_LAST(head, headname); \
|
||||
- (var) != TAILQ_END(head); \
|
||||
- (var) = TAILQ_PREV(var, headname, field))
|
||||
+ for ((var) = DWC_TAILQ_LAST(head, headname); \
|
||||
+ (var) != DWC_TAILQ_END(head); \
|
||||
+ (var) = DWC_TAILQ_PREV(var, headname, field))
|
||||
|
||||
/*
|
||||
* Tail queue functions.
|
||||
--- a/drivers/usb/host/dwc_common_port/dwc_os.h
|
||||
+++ b/drivers/usb/host/dwc_common_port/dwc_os.h
|
||||
@@ -981,6 +981,8 @@ extern void DWC_TASK_FREE(dwc_tasklet_t
|
||||
extern void DWC_TASK_SCHEDULE(dwc_tasklet_t *task);
|
||||
#define dwc_task_schedule DWC_TASK_SCHEDULE
|
||||
|
||||
+extern void DWC_TASK_HI_SCHEDULE(dwc_tasklet_t *task);
|
||||
+#define dwc_task_hi_schedule DWC_TASK_HI_SCHEDULE
|
||||
|
||||
/** @name Timer
|
||||
*
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
|
||||
@@ -40,6 +40,9 @@
|
||||
* header file.
|
||||
*/
|
||||
|
||||
+#include <linux/usb.h>
|
||||
+#include <linux/usb/hcd.h>
|
||||
+
|
||||
#include "dwc_otg_hcd.h"
|
||||
#include "dwc_otg_regs.h"
|
||||
|
||||
@@ -694,6 +697,31 @@ static void reset_tasklet_func(void *dat
|
||||
dwc_otg_hcd->flags.b.port_reset_change = 1;
|
||||
}
|
||||
|
||||
+static void completion_tasklet_func(void *ptr)
|
||||
+{
|
||||
+ dwc_otg_hcd_t *hcd = (dwc_otg_hcd_t *) ptr;
|
||||
+ struct urb *urb;
|
||||
+ urb_tq_entry_t *item;
|
||||
+ dwc_irqflags_t flags;
|
||||
+
|
||||
+ DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags);
|
||||
+ while (!DWC_TAILQ_EMPTY(&hcd->completed_urb_list)) {
|
||||
+ item = DWC_TAILQ_FIRST(&hcd->completed_urb_list);
|
||||
+ urb = item->urb;
|
||||
+ DWC_TAILQ_REMOVE(&hcd->completed_urb_list, item,
|
||||
+ urb_tq_entries);
|
||||
+ DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags);
|
||||
+ DWC_FREE(item);
|
||||
+
|
||||
+ usb_hcd_unlink_urb_from_ep(hcd->priv, urb);
|
||||
+ usb_hcd_giveback_urb(hcd->priv, urb, urb->status);
|
||||
+
|
||||
+ DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags);
|
||||
+ }
|
||||
+ DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags);
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
static void qh_list_free(dwc_otg_hcd_t * hcd, dwc_list_link_t * qh_list)
|
||||
{
|
||||
dwc_list_link_t *item;
|
||||
@@ -833,6 +861,7 @@ static void dwc_otg_hcd_free(dwc_otg_hcd
|
||||
|
||||
DWC_TIMER_FREE(dwc_otg_hcd->conn_timer);
|
||||
DWC_TASK_FREE(dwc_otg_hcd->reset_tasklet);
|
||||
+ DWC_TASK_FREE(dwc_otg_hcd->completion_tasklet);
|
||||
|
||||
#ifdef DWC_DEV_SRPCAP
|
||||
if (dwc_otg_hcd->core_if->power_down == 2 &&
|
||||
@@ -877,7 +906,7 @@ int dwc_otg_hcd_init(dwc_otg_hcd_t * hcd
|
||||
DWC_LIST_INIT(&hcd->periodic_sched_ready);
|
||||
DWC_LIST_INIT(&hcd->periodic_sched_assigned);
|
||||
DWC_LIST_INIT(&hcd->periodic_sched_queued);
|
||||
-
|
||||
+ DWC_TAILQ_INIT(&hcd->completed_urb_list);
|
||||
/*
|
||||
* Create a host channel descriptor for each host channel implemented
|
||||
* in the controller. Initialize the channel descriptor array.
|
||||
@@ -915,6 +944,9 @@ int dwc_otg_hcd_init(dwc_otg_hcd_t * hcd
|
||||
|
||||
/* Initialize reset tasklet. */
|
||||
hcd->reset_tasklet = DWC_TASK_ALLOC("reset_tasklet", reset_tasklet_func, hcd);
|
||||
+
|
||||
+ hcd->completion_tasklet = DWC_TASK_ALLOC("completion_tasklet",
|
||||
+ completion_tasklet_func, hcd);
|
||||
#ifdef DWC_DEV_SRPCAP
|
||||
if (hcd->core_if->power_down == 2) {
|
||||
/* Initialize Power on timer for Host power up in case hibernation */
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.h
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.h
|
||||
@@ -374,6 +374,13 @@ typedef struct dwc_otg_qh {
|
||||
|
||||
DWC_CIRCLEQ_HEAD(hc_list, dwc_hc);
|
||||
|
||||
+typedef struct urb_tq_entry {
|
||||
+ struct urb *urb;
|
||||
+ DWC_TAILQ_ENTRY(urb_tq_entry) urb_tq_entries;
|
||||
+} urb_tq_entry_t;
|
||||
+
|
||||
+DWC_TAILQ_HEAD(urb_list, urb_tq_entry);
|
||||
+
|
||||
/**
|
||||
* This structure holds the state of the HCD, including the non-periodic and
|
||||
* periodic schedules.
|
||||
@@ -551,6 +558,9 @@ struct dwc_otg_hcd {
|
||||
/* Tasket to do a reset */
|
||||
dwc_tasklet_t *reset_tasklet;
|
||||
|
||||
+ dwc_tasklet_t *completion_tasklet;
|
||||
+ struct urb_list completed_urb_list;
|
||||
+
|
||||
/* */
|
||||
dwc_spinlock_t *lock;
|
||||
dwc_spinlock_t *channel_lock;
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
|
||||
@@ -271,7 +271,7 @@ static int _complete(dwc_otg_hcd_t * hcd
|
||||
dwc_otg_hcd_urb_t * dwc_otg_urb, int32_t status)
|
||||
{
|
||||
struct urb *urb = (struct urb *)urb_handle;
|
||||
-
|
||||
+ urb_tq_entry_t *new_entry;
|
||||
if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
|
||||
DWC_PRINTF("%s: urb %p, device %d, ep %d %s, status=%d\n",
|
||||
__func__, urb, usb_pipedevice(urb->pipe),
|
||||
@@ -285,7 +285,7 @@ static int _complete(dwc_otg_hcd_t * hcd
|
||||
}
|
||||
}
|
||||
}
|
||||
-
|
||||
+ new_entry = DWC_ALLOC_ATOMIC(sizeof(urb_tq_entry_t));
|
||||
urb->actual_length = dwc_otg_hcd_urb_get_actual_length(dwc_otg_urb);
|
||||
/* Convert status value. */
|
||||
switch (status) {
|
||||
@@ -348,18 +348,25 @@ static int _complete(dwc_otg_hcd_t * hcd
|
||||
}
|
||||
|
||||
DWC_FREE(dwc_otg_urb);
|
||||
-
|
||||
+ if (!new_entry) {
|
||||
+ DWC_ERROR("dwc_otg_hcd: complete: cannot allocate URB TQ entry\n");
|
||||
+ urb->status = -EPROTO;
|
||||
+ /* don't schedule the tasklet -
|
||||
+ * directly return the packet here with error. */
|
||||
#if USB_URB_EP_LINKING
|
||||
- usb_hcd_unlink_urb_from_ep(dwc_otg_hcd_to_hcd(hcd), urb);
|
||||
+ usb_hcd_unlink_urb_from_ep(dwc_otg_hcd_to_hcd(hcd), urb);
|
||||
#endif
|
||||
- DWC_SPINUNLOCK(hcd->lock);
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
|
||||
- usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(hcd), urb);
|
||||
+ usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(hcd), urb);
|
||||
#else
|
||||
- usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(hcd), urb, status);
|
||||
+ usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(hcd), urb, urb->status);
|
||||
#endif
|
||||
- DWC_SPINLOCK(hcd->lock);
|
||||
-
|
||||
+ } else {
|
||||
+ new_entry->urb = urb;
|
||||
+ DWC_TAILQ_INSERT_TAIL(&hcd->completed_urb_list, new_entry,
|
||||
+ urb_tq_entries);
|
||||
+ DWC_TASK_HI_SCHEDULE(hcd->completion_tasklet);
|
||||
+ }
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
From 4013559fb9dca2beff1fa59a87ac1d1578408ad0 Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Wed, 3 Jul 2013 00:54:08 +0100
|
||||
Subject: [PATCH 058/174] Added Device IDs for August DVB-T 205
|
||||
|
||||
---
|
||||
drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
|
||||
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
|
||||
@@ -1408,6 +1408,10 @@ static const struct usb_device_id rtl28x
|
||||
&rtl2832u_props, "Compro VideoMate U620F", NULL) },
|
||||
{ DVB_USB_DEVICE(USB_VID_KWORLD_2, 0xd394,
|
||||
&rtl2832u_props, "MaxMedia HU394-T", NULL) },
|
||||
+ { DVB_USB_DEVICE(USB_VID_GTEK, 0xb803 /*USB_PID_AUGUST_DVBT205*/,
|
||||
+ &rtl2832u_props, "August DVB-T 205", NULL) },
|
||||
+ { DVB_USB_DEVICE(USB_VID_GTEK, 0xa803 /*USB_PID_AUGUST_DVBT205*/,
|
||||
+ &rtl2832u_props, "August DVB-T 205", NULL) },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, rtl28xxu_id_table);
|
|
@ -0,0 +1,20 @@
|
|||
From f7d501dfb97c2af4dd1f60f85e94bf110f69834c Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Tue, 16 Apr 2013 15:36:01 +0100
|
||||
Subject: [PATCH 059/174] Add v6wbi_flush_kern_tlb_range to allow zsmalloc to
|
||||
be built as a module
|
||||
|
||||
---
|
||||
arch/arm/kernel/armksyms.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
--- a/arch/arm/kernel/armksyms.c
|
||||
+++ b/arch/arm/kernel/armksyms.c
|
||||
@@ -156,3 +156,7 @@ EXPORT_SYMBOL(__gnu_mcount_nc);
|
||||
#ifdef CONFIG_ARM_PATCH_PHYS_VIRT
|
||||
EXPORT_SYMBOL(__pv_phys_offset);
|
||||
#endif
|
||||
+
|
||||
+extern void v6wbi_flush_kern_tlb_range(void);
|
||||
+EXPORT_SYMBOL(v6wbi_flush_kern_tlb_range);
|
||||
+
|
|
@ -0,0 +1,67 @@
|
|||
From 370cbdb4a5ec521d9312b02bbaf269ed520b1451 Mon Sep 17 00:00:00 2001
|
||||
From: P33M <P33M@github.com>
|
||||
Date: Mon, 22 Apr 2013 00:08:36 +0100
|
||||
Subject: [PATCH 060/174] dwc_otg: fix NAK holdoff and allow on split
|
||||
transactions only
|
||||
|
||||
This corrects a bug where if a single active non-periodic endpoint
|
||||
had at least one transaction in its qh, on frnum == MAX_FRNUM the qh
|
||||
would get skipped and never get queued again. This would result in
|
||||
a silent device until error detection (automatic or otherwise) would
|
||||
either reset the device or flush and requeue the URBs.
|
||||
|
||||
Additionally the NAK holdoff was enabled for all transactions - this
|
||||
would potentially stall a HS endpoint for 1ms if a previous error state
|
||||
enabled this interrupt and the next response was a NAK. Fix so that
|
||||
only split transactions get held off.
|
||||
---
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 28 ++++++++++++++++++----------
|
||||
1 file changed, 18 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
|
||||
@@ -46,7 +46,7 @@
|
||||
#include "dwc_otg_hcd.h"
|
||||
#include "dwc_otg_regs.h"
|
||||
|
||||
-extern bool microframe_schedule;
|
||||
+extern bool microframe_schedule, nak_holdoff_enable;
|
||||
|
||||
//#define DEBUG_HOST_CHANNELS
|
||||
#ifdef DEBUG_HOST_CHANNELS
|
||||
@@ -1349,18 +1349,26 @@ dwc_otg_transaction_type_e dwc_otg_hcd_s
|
||||
|
||||
/*
|
||||
* Check to see if this is a NAK'd retransmit, in which case ignore for retransmission
|
||||
- * we hold off on bulk retransmissions to reduce NAK interrupt overhead for
|
||||
+ * we hold off on bulk retransmissions to reduce NAK interrupt overhead for full-speed
|
||||
* cheeky devices that just hold off using NAKs
|
||||
*/
|
||||
- if (dwc_full_frame_num(qh->nak_frame) == dwc_full_frame_num(dwc_otg_hcd_get_frame_number(hcd))) {
|
||||
- // Make fiq interrupt run on next frame (i.e. 8 uframes)
|
||||
- g_next_sched_frame = ((qh->nak_frame + 8) & ~7) & DWC_HFNUM_MAX_FRNUM;
|
||||
- qh_ptr = DWC_LIST_NEXT(qh_ptr);
|
||||
- continue;
|
||||
+ if (nak_holdoff_enable && qh->do_split) {
|
||||
+ if (qh->nak_frame != 0xffff &&
|
||||
+ dwc_full_frame_num(qh->nak_frame) ==
|
||||
+ dwc_full_frame_num(dwc_otg_hcd_get_frame_number(hcd))) {
|
||||
+ /*
|
||||
+ * Revisit: Need to avoid trampling on periodic scheduling.
|
||||
+ * Currently we are safe because g_np_count != g_np_sent whenever we hit this,
|
||||
+ * but if this behaviour is changed then periodic endpoints will get a slower
|
||||
+ * polling rate.
|
||||
+ */
|
||||
+ g_next_sched_frame = ((qh->nak_frame + 8) & ~7) & DWC_HFNUM_MAX_FRNUM;
|
||||
+ qh_ptr = DWC_LIST_NEXT(qh_ptr);
|
||||
+ continue;
|
||||
+ } else {
|
||||
+ qh->nak_frame = 0xffff;
|
||||
+ }
|
||||
}
|
||||
- else
|
||||
- qh->nak_frame = 0xffff;
|
||||
-
|
||||
if (microframe_schedule) {
|
||||
DWC_SPINLOCK_IRQSAVE(channel_lock, &flags);
|
||||
if (hcd->available_host_channels < 1) {
|
|
@ -0,0 +1,472 @@
|
|||
From 5d42dfcf42ba987a03d8b5f2dfa30e9cb2dc4721 Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Fri, 26 Apr 2013 10:08:31 -0700
|
||||
Subject: [PATCH 061/174] Merge pull request #286 from
|
||||
martinezjavier/rpi-3.6.y-dev
|
||||
|
||||
add mmap support and some cleanups to bcm2835 ALSA driver
|
||||
---
|
||||
sound/arm/bcm2835-pcm.c | 69 ++++++++++++++++++++++--------------
|
||||
sound/arm/bcm2835-vchiq.c | 89 +++++++++++++++++++++++++++++++++--------------
|
||||
sound/arm/bcm2835.c | 34 +++++++++---------
|
||||
sound/arm/bcm2835.h | 2 ++
|
||||
4 files changed, 124 insertions(+), 70 deletions(-)
|
||||
|
||||
--- a/sound/arm/bcm2835-pcm.c
|
||||
+++ b/sound/arm/bcm2835-pcm.c
|
||||
@@ -19,7 +19,8 @@
|
||||
|
||||
/* hardware definition */
|
||||
static struct snd_pcm_hardware snd_bcm2835_playback_hw = {
|
||||
- .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER),
|
||||
+ .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
|
||||
+ SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),
|
||||
.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
|
||||
.rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
|
||||
.rate_min = 8000,
|
||||
@@ -251,6 +252,12 @@ static int snd_bcm2835_pcm_prepare(struc
|
||||
|
||||
audio_info(" .. IN\n");
|
||||
|
||||
+ memset(&alsa_stream->pcm_indirect, 0, sizeof(alsa_stream->pcm_indirect));
|
||||
+
|
||||
+ alsa_stream->pcm_indirect.hw_buffer_size =
|
||||
+ alsa_stream->pcm_indirect.sw_buffer_size =
|
||||
+ snd_pcm_lib_buffer_bytes(substream);
|
||||
+
|
||||
alsa_stream->buffer_size = snd_pcm_lib_buffer_bytes(substream);
|
||||
alsa_stream->period_size = snd_pcm_lib_period_bytes(substream);
|
||||
alsa_stream->pos = 0;
|
||||
@@ -263,6 +270,32 @@ static int snd_bcm2835_pcm_prepare(struc
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void snd_bcm2835_pcm_transfer(struct snd_pcm_substream *substream,
|
||||
+ struct snd_pcm_indirect *rec, size_t bytes)
|
||||
+{
|
||||
+ struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
+ bcm2835_alsa_stream_t *alsa_stream = runtime->private_data;
|
||||
+ void *src = (void *)(substream->runtime->dma_area + rec->sw_data);
|
||||
+ int err;
|
||||
+
|
||||
+ err = bcm2835_audio_write(alsa_stream, bytes, src);
|
||||
+ if (err)
|
||||
+ audio_error(" Failed to transfer to alsa device (%d)\n", err);
|
||||
+
|
||||
+}
|
||||
+
|
||||
+static int snd_bcm2835_pcm_ack(struct snd_pcm_substream *substream)
|
||||
+{
|
||||
+ struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
+ bcm2835_alsa_stream_t *alsa_stream = runtime->private_data;
|
||||
+ struct snd_pcm_indirect *pcm_indirect = &alsa_stream->pcm_indirect;
|
||||
+
|
||||
+ pcm_indirect->hw_queue_size = runtime->hw.buffer_bytes_max;
|
||||
+ snd_pcm_indirect_playback_transfer(substream, pcm_indirect,
|
||||
+ snd_bcm2835_pcm_transfer);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/* trigger callback */
|
||||
static int snd_bcm2835_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
|
||||
{
|
||||
@@ -279,6 +312,11 @@ static int snd_bcm2835_pcm_trigger(struc
|
||||
if (!alsa_stream->running) {
|
||||
err = bcm2835_audio_start(alsa_stream);
|
||||
if (err == 0) {
|
||||
+ alsa_stream->pcm_indirect.hw_io =
|
||||
+ alsa_stream->pcm_indirect.hw_data =
|
||||
+ bytes_to_frames(runtime,
|
||||
+ alsa_stream->pos);
|
||||
+ substream->ops->ack(substream);
|
||||
alsa_stream->running = 1;
|
||||
alsa_stream->draining = 1;
|
||||
} else {
|
||||
@@ -327,30 +365,9 @@ snd_bcm2835_pcm_pointer(struct snd_pcm_s
|
||||
alsa_stream->pos);
|
||||
|
||||
audio_info(" .. OUT\n");
|
||||
- return bytes_to_frames(runtime, alsa_stream->pos);
|
||||
-}
|
||||
-
|
||||
-static int snd_bcm2835_pcm_copy(struct snd_pcm_substream *substream,
|
||||
- int channel, snd_pcm_uframes_t pos, void *src,
|
||||
- snd_pcm_uframes_t count)
|
||||
-{
|
||||
- int ret;
|
||||
- struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
- bcm2835_alsa_stream_t *alsa_stream = runtime->private_data;
|
||||
-
|
||||
- audio_info(" .. IN\n");
|
||||
- audio_debug("copy.......... (%d) hwptr=%d appl=%d pos=%d\n",
|
||||
- frames_to_bytes(runtime, count), frames_to_bytes(runtime,
|
||||
- runtime->
|
||||
- status->
|
||||
- hw_ptr),
|
||||
- frames_to_bytes(runtime, runtime->control->appl_ptr),
|
||||
- alsa_stream->pos);
|
||||
- ret =
|
||||
- bcm2835_audio_write(alsa_stream, frames_to_bytes(runtime, count),
|
||||
- src);
|
||||
- audio_info(" .. OUT\n");
|
||||
- return ret;
|
||||
+ return snd_pcm_indirect_playback_pointer(substream,
|
||||
+ &alsa_stream->pcm_indirect,
|
||||
+ alsa_stream->pos);
|
||||
}
|
||||
|
||||
static int snd_bcm2835_pcm_lib_ioctl(struct snd_pcm_substream *substream,
|
||||
@@ -372,7 +389,7 @@ static struct snd_pcm_ops snd_bcm2835_pl
|
||||
.prepare = snd_bcm2835_pcm_prepare,
|
||||
.trigger = snd_bcm2835_pcm_trigger,
|
||||
.pointer = snd_bcm2835_pcm_pointer,
|
||||
- .copy = snd_bcm2835_pcm_copy,
|
||||
+ .ack = snd_bcm2835_pcm_ack,
|
||||
};
|
||||
|
||||
/* create a pcm device */
|
||||
--- a/sound/arm/bcm2835-vchiq.c
|
||||
+++ b/sound/arm/bcm2835-vchiq.c
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/module.h>
|
||||
+#include <linux/completion.h>
|
||||
|
||||
#include "bcm2835.h"
|
||||
|
||||
@@ -37,6 +38,10 @@
|
||||
|
||||
/* ---- Private Constants and Types ------------------------------------------ */
|
||||
|
||||
+#define BCM2835_AUDIO_STOP 0
|
||||
+#define BCM2835_AUDIO_START 1
|
||||
+#define BCM2835_AUDIO_WRITE 2
|
||||
+
|
||||
/* Logging macros (for remapping to other logging mechanisms, i.e., printf) */
|
||||
#ifdef AUDIO_DEBUG_ENABLE
|
||||
#define LOG_ERR( fmt, arg... ) pr_err( "%s:%d " fmt, __func__, __LINE__, ##arg)
|
||||
@@ -53,7 +58,7 @@
|
||||
typedef struct opaque_AUDIO_INSTANCE_T {
|
||||
uint32_t num_connections;
|
||||
VCHI_SERVICE_HANDLE_T vchi_handle[VCHI_MAX_NUM_CONNECTIONS];
|
||||
- struct semaphore msg_avail_event;
|
||||
+ struct completion msg_avail_comp;
|
||||
struct mutex vchi_mutex;
|
||||
bcm2835_alsa_stream_t *alsa_stream;
|
||||
int32_t result;
|
||||
@@ -70,27 +75,35 @@ bool force_bulk = false;
|
||||
|
||||
static int bcm2835_audio_stop_worker(bcm2835_alsa_stream_t * alsa_stream);
|
||||
static int bcm2835_audio_start_worker(bcm2835_alsa_stream_t * alsa_stream);
|
||||
+static int bcm2835_audio_write_worker(bcm2835_alsa_stream_t *alsa_stream,
|
||||
+ uint32_t count, void *src);
|
||||
|
||||
typedef struct {
|
||||
struct work_struct my_work;
|
||||
bcm2835_alsa_stream_t *alsa_stream;
|
||||
- int x;
|
||||
+ int cmd;
|
||||
+ void *src;
|
||||
+ uint32_t count;
|
||||
} my_work_t;
|
||||
|
||||
static void my_wq_function(struct work_struct *work)
|
||||
{
|
||||
my_work_t *w = (my_work_t *) work;
|
||||
int ret = -9;
|
||||
- LOG_DBG(" .. IN %p:%d\n", w->alsa_stream, w->x);
|
||||
- switch (w->x) {
|
||||
- case 1:
|
||||
+ LOG_DBG(" .. IN %p:%d\n", w->alsa_stream, w->cmd);
|
||||
+ switch (w->cmd) {
|
||||
+ case BCM2835_AUDIO_START:
|
||||
ret = bcm2835_audio_start_worker(w->alsa_stream);
|
||||
break;
|
||||
- case 2:
|
||||
+ case BCM2835_AUDIO_STOP:
|
||||
ret = bcm2835_audio_stop_worker(w->alsa_stream);
|
||||
break;
|
||||
+ case BCM2835_AUDIO_WRITE:
|
||||
+ ret = bcm2835_audio_write_worker(w->alsa_stream, w->count,
|
||||
+ w->src);
|
||||
+ break;
|
||||
default:
|
||||
- LOG_ERR(" Unexpected work: %p:%d\n", w->alsa_stream, w->x);
|
||||
+ LOG_ERR(" Unexpected work: %p:%d\n", w->alsa_stream, w->cmd);
|
||||
break;
|
||||
}
|
||||
kfree((void *)work);
|
||||
@@ -107,7 +120,7 @@ int bcm2835_audio_start(bcm2835_alsa_str
|
||||
if (work) {
|
||||
INIT_WORK((struct work_struct *)work, my_wq_function);
|
||||
work->alsa_stream = alsa_stream;
|
||||
- work->x = 1;
|
||||
+ work->cmd = BCM2835_AUDIO_START;
|
||||
if (queue_work
|
||||
(alsa_stream->my_wq, (struct work_struct *)work))
|
||||
ret = 0;
|
||||
@@ -128,7 +141,31 @@ int bcm2835_audio_stop(bcm2835_alsa_stre
|
||||
if (work) {
|
||||
INIT_WORK((struct work_struct *)work, my_wq_function);
|
||||
work->alsa_stream = alsa_stream;
|
||||
- work->x = 2;
|
||||
+ work->cmd = BCM2835_AUDIO_STOP;
|
||||
+ if (queue_work
|
||||
+ (alsa_stream->my_wq, (struct work_struct *)work))
|
||||
+ ret = 0;
|
||||
+ } else
|
||||
+ LOG_ERR(" .. Error: NULL work kmalloc\n");
|
||||
+ }
|
||||
+ LOG_DBG(" .. OUT %d\n", ret);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+int bcm2835_audio_write(bcm2835_alsa_stream_t *alsa_stream,
|
||||
+ uint32_t count, void *src)
|
||||
+{
|
||||
+ int ret = -1;
|
||||
+ LOG_DBG(" .. IN\n");
|
||||
+ if (alsa_stream->my_wq) {
|
||||
+ my_work_t *work = kmalloc(sizeof(my_work_t), GFP_ATOMIC);
|
||||
+ /*--- Queue some work (item 1) ---*/
|
||||
+ if (work) {
|
||||
+ INIT_WORK((struct work_struct *)work, my_wq_function);
|
||||
+ work->alsa_stream = alsa_stream;
|
||||
+ work->cmd = BCM2835_AUDIO_WRITE;
|
||||
+ work->src = src;
|
||||
+ work->count = count;
|
||||
if (queue_work
|
||||
(alsa_stream->my_wq, (struct work_struct *)work))
|
||||
ret = 0;
|
||||
@@ -178,7 +215,7 @@ static void audio_vchi_callback(void *pa
|
||||
(" .. instance=%p, m.type=VC_AUDIO_MSG_TYPE_RESULT, success=%d\n",
|
||||
instance, m.u.result.success);
|
||||
instance->result = m.u.result.success;
|
||||
- up(&instance->msg_avail_event);
|
||||
+ complete(&instance->msg_avail_comp);
|
||||
} else if (m.type == VC_AUDIO_MSG_TYPE_COMPLETE) {
|
||||
irq_handler_t callback = (irq_handler_t) m.u.complete.callback;
|
||||
LOG_DBG
|
||||
@@ -435,8 +472,8 @@ static int bcm2835_audio_set_ctls_chan(b
|
||||
m.u.control.dest = chip->dest;
|
||||
m.u.control.volume = chip->volume;
|
||||
|
||||
- /* Create the message available event */
|
||||
- sema_init(&instance->msg_avail_event, 0);
|
||||
+ /* Create the message available completion */
|
||||
+ init_completion(&instance->msg_avail_comp);
|
||||
|
||||
/* Send the message to the videocore */
|
||||
success = vchi_msg_queue(instance->vchi_handle[0],
|
||||
@@ -452,11 +489,10 @@ static int bcm2835_audio_set_ctls_chan(b
|
||||
}
|
||||
|
||||
/* We are expecting a reply from the videocore */
|
||||
- if (down_interruptible(&instance->msg_avail_event)) {
|
||||
+ ret = wait_for_completion_interruptible(&instance->msg_avail_comp);
|
||||
+ if (ret) {
|
||||
LOG_ERR("%s: failed on waiting for event (status=%d)\n",
|
||||
__func__, success);
|
||||
-
|
||||
- ret = -1;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
@@ -539,8 +575,8 @@ int bcm2835_audio_set_params(bcm2835_als
|
||||
m.u.config.samplerate = samplerate;
|
||||
m.u.config.bps = bps;
|
||||
|
||||
- /* Create the message available event */
|
||||
- sema_init(&instance->msg_avail_event, 0);
|
||||
+ /* Create the message available completion */
|
||||
+ init_completion(&instance->msg_avail_comp);
|
||||
|
||||
/* Send the message to the videocore */
|
||||
success = vchi_msg_queue(instance->vchi_handle[0],
|
||||
@@ -556,11 +592,10 @@ int bcm2835_audio_set_params(bcm2835_als
|
||||
}
|
||||
|
||||
/* We are expecting a reply from the videocore */
|
||||
- if (down_interruptible(&instance->msg_avail_event)) {
|
||||
+ ret = wait_for_completion_interruptible(&instance->msg_avail_comp);
|
||||
+ if (ret) {
|
||||
LOG_ERR("%s: failed on waiting for event (status=%d)\n",
|
||||
__func__, success);
|
||||
-
|
||||
- ret = -1;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
@@ -688,8 +723,8 @@ int bcm2835_audio_close(bcm2835_alsa_str
|
||||
|
||||
m.type = VC_AUDIO_MSG_TYPE_CLOSE;
|
||||
|
||||
- /* Create the message available event */
|
||||
- sema_init(&instance->msg_avail_event, 0);
|
||||
+ /* Create the message available completion */
|
||||
+ init_completion(&instance->msg_avail_comp);
|
||||
|
||||
/* Send the message to the videocore */
|
||||
success = vchi_msg_queue(instance->vchi_handle[0],
|
||||
@@ -702,11 +737,11 @@ int bcm2835_audio_close(bcm2835_alsa_str
|
||||
ret = -1;
|
||||
goto unlock;
|
||||
}
|
||||
- if (down_interruptible(&instance->msg_avail_event)) {
|
||||
+
|
||||
+ ret = wait_for_completion_interruptible(&instance->msg_avail_comp);
|
||||
+ if (ret) {
|
||||
LOG_ERR("%s: failed on waiting for event (status=%d)",
|
||||
__func__, success);
|
||||
-
|
||||
- ret = -1;
|
||||
goto unlock;
|
||||
}
|
||||
if (instance->result != 0) {
|
||||
@@ -732,8 +767,8 @@ unlock:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-int bcm2835_audio_write(bcm2835_alsa_stream_t * alsa_stream, uint32_t count,
|
||||
- void *src)
|
||||
+int bcm2835_audio_write_worker(bcm2835_alsa_stream_t *alsa_stream,
|
||||
+ uint32_t count, void *src)
|
||||
{
|
||||
VC_AUDIO_MSG_T m;
|
||||
AUDIO_INSTANCE_T *instance = alsa_stream->instance;
|
||||
--- a/sound/arm/bcm2835.c
|
||||
+++ b/sound/arm/bcm2835.c
|
||||
@@ -110,20 +110,20 @@ static int snd_bcm2835_alsa_probe(struct
|
||||
|
||||
err = snd_bcm2835_create(g_card, pdev, &chip);
|
||||
if (err < 0) {
|
||||
- printk(KERN_ERR "Failed to create bcm2835 chip\n");
|
||||
+ dev_err(&pdev->dev, "Failed to create bcm2835 chip\n");
|
||||
goto out_bcm2835_create;
|
||||
}
|
||||
|
||||
g_chip = chip;
|
||||
err = snd_bcm2835_new_pcm(chip);
|
||||
if (err < 0) {
|
||||
- printk(KERN_ERR "Failed to create new BCM2835 pcm device\n");
|
||||
+ dev_err(&pdev->dev, "Failed to create new BCM2835 pcm device\n");
|
||||
goto out_bcm2835_new_pcm;
|
||||
}
|
||||
|
||||
err = snd_bcm2835_new_ctl(chip);
|
||||
if (err < 0) {
|
||||
- printk(KERN_ERR "Failed to create new BCM2835 ctl\n");
|
||||
+ dev_err(&pdev->dev, "Failed to create new BCM2835 ctl\n");
|
||||
goto out_bcm2835_new_ctl;
|
||||
}
|
||||
|
||||
@@ -139,14 +139,14 @@ add_register_map:
|
||||
if (dev == 0) {
|
||||
err = snd_card_register(card);
|
||||
if (err < 0) {
|
||||
- printk(KERN_ERR
|
||||
- "Failed to register bcm2835 ALSA card \n");
|
||||
+ dev_err(&pdev->dev,
|
||||
+ "Failed to register bcm2835 ALSA card \n");
|
||||
goto out_card_register;
|
||||
}
|
||||
platform_set_drvdata(pdev, card);
|
||||
- printk(KERN_INFO "bcm2835 ALSA card created!\n");
|
||||
+ audio_info("bcm2835 ALSA card created!\n");
|
||||
} else {
|
||||
- printk(KERN_INFO "bcm2835 ALSA chip created!\n");
|
||||
+ audio_info("bcm2835 ALSA chip created!\n");
|
||||
platform_set_drvdata(pdev, (void *)dev);
|
||||
}
|
||||
|
||||
@@ -160,11 +160,11 @@ out_bcm2835_new_pcm:
|
||||
out_bcm2835_create:
|
||||
BUG_ON(!g_card);
|
||||
if (snd_card_free(g_card))
|
||||
- printk(KERN_ERR "Failed to free Registered alsa card\n");
|
||||
+ dev_err(&pdev->dev, "Failed to free Registered alsa card\n");
|
||||
g_card = NULL;
|
||||
out:
|
||||
dev = SNDRV_CARDS; /* stop more avail_substreams from being probed */
|
||||
- printk(KERN_ERR "BCM2835 ALSA Probe failed !!\n");
|
||||
+ dev_err(&pdev->dev, "BCM2835 ALSA Probe failed !!\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -326,49 +326,49 @@ static int bcm2835_alsa_device_init(void
|
||||
int err;
|
||||
err = platform_driver_register(&bcm2835_alsa0_driver);
|
||||
if (err) {
|
||||
- printk("Error registering bcm2835_alsa0_driver %d .\n", err);
|
||||
+ pr_err("Error registering bcm2835_alsa0_driver %d .\n", err);
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = platform_driver_register(&bcm2835_alsa1_driver);
|
||||
if (err) {
|
||||
- printk("Error registering bcm2835_alsa1_driver %d .\n", err);
|
||||
+ pr_err("Error registering bcm2835_alsa0_driver %d .\n", err);
|
||||
goto unregister_0;
|
||||
}
|
||||
|
||||
err = platform_driver_register(&bcm2835_alsa2_driver);
|
||||
if (err) {
|
||||
- printk("Error registering bcm2835_alsa2_driver %d .\n", err);
|
||||
+ pr_err("Error registering bcm2835_alsa0_driver %d .\n", err);
|
||||
goto unregister_1;
|
||||
}
|
||||
|
||||
err = platform_driver_register(&bcm2835_alsa3_driver);
|
||||
if (err) {
|
||||
- printk("Error registering bcm2835_alsa3_driver %d .\n", err);
|
||||
+ pr_err("Error registering bcm2835_alsa0_driver %d .\n", err);
|
||||
goto unregister_2;
|
||||
}
|
||||
|
||||
err = platform_driver_register(&bcm2835_alsa4_driver);
|
||||
if (err) {
|
||||
- printk("Error registering bcm2835_alsa4_driver %d .\n", err);
|
||||
+ pr_err("Error registering bcm2835_alsa0_driver %d .\n", err);
|
||||
goto unregister_3;
|
||||
}
|
||||
|
||||
err = platform_driver_register(&bcm2835_alsa5_driver);
|
||||
if (err) {
|
||||
- printk("Error registering bcm2835_alsa5_driver %d .\n", err);
|
||||
+ pr_err("Error registering bcm2835_alsa0_driver %d .\n", err);
|
||||
goto unregister_4;
|
||||
}
|
||||
|
||||
err = platform_driver_register(&bcm2835_alsa6_driver);
|
||||
if (err) {
|
||||
- printk("Error registering bcm2835_alsa6_driver %d .\n", err);
|
||||
+ pr_err("Error registering bcm2835_alsa0_driver %d .\n", err);
|
||||
goto unregister_5;
|
||||
}
|
||||
|
||||
err = platform_driver_register(&bcm2835_alsa7_driver);
|
||||
if (err) {
|
||||
- printk("Error registering bcm2835_alsa7_driver %d .\n", err);
|
||||
+ pr_err("Error registering bcm2835_alsa0_driver %d .\n", err);
|
||||
goto unregister_6;
|
||||
}
|
||||
|
||||
--- a/sound/arm/bcm2835.h
|
||||
+++ b/sound/arm/bcm2835.h
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <sound/initval.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/pcm_params.h>
|
||||
+#include <sound/pcm-indirect.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
/*
|
||||
@@ -110,6 +111,7 @@ typedef struct bcm2835_chip {
|
||||
typedef struct bcm2835_alsa_stream {
|
||||
bcm2835_chip_t *chip;
|
||||
struct snd_pcm_substream *substream;
|
||||
+ struct snd_pcm_indirect pcm_indirect;
|
||||
|
||||
struct semaphore buffers_update_sem;
|
||||
struct semaphore control_sem;
|
|
@ -0,0 +1,212 @@
|
|||
From 353d37b0b26870a4bfd3e0cac6e535895ba4a01e Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Tue, 7 May 2013 22:20:24 +0100
|
||||
Subject: [PATCH 062/174] Add quick config.
|
||||
|
||||
This is designed for quick compiling when developing.
|
||||
No modules are needed and it includes all Pi specific drivers
|
||||
---
|
||||
arch/arm/configs/bcmrpi_quick_defconfig | 197 ++++++++++++++++++++++++++++++++
|
||||
1 file changed, 197 insertions(+)
|
||||
create mode 100644 arch/arm/configs/bcmrpi_quick_defconfig
|
||||
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/configs/bcmrpi_quick_defconfig
|
||||
@@ -0,0 +1,197 @@
|
||||
+# CONFIG_ARM_PATCH_PHYS_VIRT is not set
|
||||
+CONFIG_LOCALVERSION="-quick"
|
||||
+# CONFIG_LOCALVERSION_AUTO is not set
|
||||
+# CONFIG_SWAP is not set
|
||||
+CONFIG_SYSVIPC=y
|
||||
+CONFIG_POSIX_MQUEUE=y
|
||||
+CONFIG_NO_HZ=y
|
||||
+CONFIG_HIGH_RES_TIMERS=y
|
||||
+CONFIG_IKCONFIG=y
|
||||
+CONFIG_IKCONFIG_PROC=y
|
||||
+CONFIG_KALLSYMS_ALL=y
|
||||
+CONFIG_EMBEDDED=y
|
||||
+CONFIG_PERF_EVENTS=y
|
||||
+# CONFIG_COMPAT_BRK is not set
|
||||
+CONFIG_SLAB=y
|
||||
+CONFIG_MODULES=y
|
||||
+CONFIG_MODULE_UNLOAD=y
|
||||
+CONFIG_MODVERSIONS=y
|
||||
+CONFIG_MODULE_SRCVERSION_ALL=y
|
||||
+# CONFIG_BLK_DEV_BSG is not set
|
||||
+CONFIG_ARCH_BCM2708=y
|
||||
+CONFIG_PREEMPT=y
|
||||
+CONFIG_AEABI=y
|
||||
+CONFIG_UACCESS_WITH_MEMCPY=y
|
||||
+CONFIG_ZBOOT_ROM_TEXT=0x0
|
||||
+CONFIG_ZBOOT_ROM_BSS=0x0
|
||||
+CONFIG_CMDLINE="dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait"
|
||||
+CONFIG_CPU_FREQ=y
|
||||
+CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE=y
|
||||
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
|
||||
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
|
||||
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
|
||||
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
|
||||
+CONFIG_CPU_IDLE=y
|
||||
+CONFIG_VFP=y
|
||||
+CONFIG_BINFMT_MISC=y
|
||||
+CONFIG_NET=y
|
||||
+CONFIG_PACKET=y
|
||||
+CONFIG_UNIX=y
|
||||
+CONFIG_INET=y
|
||||
+CONFIG_IP_MULTICAST=y
|
||||
+CONFIG_IP_PNP=y
|
||||
+CONFIG_IP_PNP_DHCP=y
|
||||
+CONFIG_IP_PNP_RARP=y
|
||||
+CONFIG_SYN_COOKIES=y
|
||||
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
|
||||
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
|
||||
+# CONFIG_INET_XFRM_MODE_BEET is not set
|
||||
+# CONFIG_INET_LRO is not set
|
||||
+# CONFIG_INET_DIAG is not set
|
||||
+# CONFIG_IPV6 is not set
|
||||
+# CONFIG_WIRELESS is not set
|
||||
+CONFIG_DEVTMPFS=y
|
||||
+CONFIG_DEVTMPFS_MOUNT=y
|
||||
+CONFIG_BLK_DEV_LOOP=y
|
||||
+CONFIG_BLK_DEV_RAM=y
|
||||
+CONFIG_SCSI=y
|
||||
+# CONFIG_SCSI_PROC_FS is not set
|
||||
+# CONFIG_SCSI_LOWLEVEL is not set
|
||||
+CONFIG_NETDEVICES=y
|
||||
+# CONFIG_NET_VENDOR_BROADCOM is not set
|
||||
+# CONFIG_NET_VENDOR_CIRRUS is not set
|
||||
+# CONFIG_NET_VENDOR_FARADAY is not set
|
||||
+# CONFIG_NET_VENDOR_INTEL is not set
|
||||
+# CONFIG_NET_VENDOR_MARVELL is not set
|
||||
+# CONFIG_NET_VENDOR_MICREL is not set
|
||||
+# CONFIG_NET_VENDOR_NATSEMI is not set
|
||||
+# CONFIG_NET_VENDOR_SEEQ is not set
|
||||
+# CONFIG_NET_VENDOR_STMICRO is not set
|
||||
+# CONFIG_NET_VENDOR_WIZNET is not set
|
||||
+CONFIG_USB_USBNET=y
|
||||
+# CONFIG_USB_NET_AX8817X is not set
|
||||
+# CONFIG_USB_NET_CDCETHER is not set
|
||||
+# CONFIG_USB_NET_CDC_NCM is not set
|
||||
+CONFIG_USB_NET_SMSC95XX=y
|
||||
+# CONFIG_USB_NET_NET1080 is not set
|
||||
+# CONFIG_USB_NET_CDC_SUBSET is not set
|
||||
+# CONFIG_USB_NET_ZAURUS is not set
|
||||
+# CONFIG_WLAN is not set
|
||||
+# CONFIG_INPUT_MOUSEDEV is not set
|
||||
+CONFIG_INPUT_EVDEV=y
|
||||
+# CONFIG_INPUT_KEYBOARD is not set
|
||||
+# CONFIG_INPUT_MOUSE is not set
|
||||
+# CONFIG_SERIO is not set
|
||||
+CONFIG_VT_HW_CONSOLE_BINDING=y
|
||||
+# CONFIG_LEGACY_PTYS is not set
|
||||
+# CONFIG_DEVKMEM is not set
|
||||
+CONFIG_SERIAL_AMBA_PL011=y
|
||||
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
|
||||
+CONFIG_TTY_PRINTK=y
|
||||
+CONFIG_HW_RANDOM=y
|
||||
+CONFIG_HW_RANDOM_BCM2708=y
|
||||
+CONFIG_RAW_DRIVER=y
|
||||
+CONFIG_THERMAL=y
|
||||
+CONFIG_THERMAL_BCM2835=y
|
||||
+CONFIG_WATCHDOG=y
|
||||
+CONFIG_BCM2708_WDT=y
|
||||
+CONFIG_REGULATOR=y
|
||||
+CONFIG_REGULATOR_DEBUG=y
|
||||
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
|
||||
+CONFIG_REGULATOR_VIRTUAL_CONSUMER=y
|
||||
+CONFIG_REGULATOR_USERSPACE_CONSUMER=y
|
||||
+CONFIG_FB=y
|
||||
+CONFIG_FB_BCM2708=y
|
||||
+CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||
+CONFIG_LOGO=y
|
||||
+# CONFIG_LOGO_LINUX_MONO is not set
|
||||
+# CONFIG_LOGO_LINUX_VGA16 is not set
|
||||
+CONFIG_SOUND=y
|
||||
+CONFIG_SND=y
|
||||
+CONFIG_SND_BCM2835=y
|
||||
+# CONFIG_SND_USB is not set
|
||||
+CONFIG_USB=y
|
||||
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
|
||||
+CONFIG_USB_DWCOTG=y
|
||||
+CONFIG_MMC=y
|
||||
+CONFIG_MMC_SDHCI=y
|
||||
+CONFIG_MMC_SDHCI_PLTFM=y
|
||||
+CONFIG_MMC_SDHCI_BCM2708=y
|
||||
+CONFIG_MMC_SDHCI_BCM2708_DMA=y
|
||||
+CONFIG_NEW_LEDS=y
|
||||
+CONFIG_LEDS_CLASS=y
|
||||
+CONFIG_LEDS_TRIGGERS=y
|
||||
+# CONFIG_IOMMU_SUPPORT is not set
|
||||
+CONFIG_EXT4_FS=y
|
||||
+CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
+CONFIG_EXT4_FS_SECURITY=y
|
||||
+CONFIG_AUTOFS4_FS=y
|
||||
+CONFIG_FSCACHE=y
|
||||
+CONFIG_CACHEFILES=y
|
||||
+CONFIG_MSDOS_FS=y
|
||||
+CONFIG_VFAT_FS=y
|
||||
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
|
||||
+CONFIG_TMPFS=y
|
||||
+CONFIG_TMPFS_POSIX_ACL=y
|
||||
+CONFIG_CONFIGFS_FS=y
|
||||
+# CONFIG_MISC_FILESYSTEMS is not set
|
||||
+CONFIG_NFS_FS=y
|
||||
+CONFIG_NFS_V3_ACL=y
|
||||
+CONFIG_NFS_V4=y
|
||||
+CONFIG_ROOT_NFS=y
|
||||
+CONFIG_NFS_FSCACHE=y
|
||||
+CONFIG_NLS_DEFAULT="utf8"
|
||||
+CONFIG_NLS_CODEPAGE_437=y
|
||||
+CONFIG_NLS_CODEPAGE_737=y
|
||||
+CONFIG_NLS_CODEPAGE_775=y
|
||||
+CONFIG_NLS_CODEPAGE_850=y
|
||||
+CONFIG_NLS_CODEPAGE_852=y
|
||||
+CONFIG_NLS_CODEPAGE_855=y
|
||||
+CONFIG_NLS_CODEPAGE_857=y
|
||||
+CONFIG_NLS_CODEPAGE_860=y
|
||||
+CONFIG_NLS_CODEPAGE_861=y
|
||||
+CONFIG_NLS_CODEPAGE_862=y
|
||||
+CONFIG_NLS_CODEPAGE_863=y
|
||||
+CONFIG_NLS_CODEPAGE_864=y
|
||||
+CONFIG_NLS_CODEPAGE_865=y
|
||||
+CONFIG_NLS_CODEPAGE_866=y
|
||||
+CONFIG_NLS_CODEPAGE_869=y
|
||||
+CONFIG_NLS_CODEPAGE_936=y
|
||||
+CONFIG_NLS_CODEPAGE_950=y
|
||||
+CONFIG_NLS_CODEPAGE_932=y
|
||||
+CONFIG_NLS_CODEPAGE_949=y
|
||||
+CONFIG_NLS_CODEPAGE_874=y
|
||||
+CONFIG_NLS_ISO8859_8=y
|
||||
+CONFIG_NLS_CODEPAGE_1250=y
|
||||
+CONFIG_NLS_CODEPAGE_1251=y
|
||||
+CONFIG_NLS_ASCII=y
|
||||
+CONFIG_NLS_ISO8859_1=y
|
||||
+CONFIG_NLS_ISO8859_2=y
|
||||
+CONFIG_NLS_ISO8859_3=y
|
||||
+CONFIG_NLS_ISO8859_4=y
|
||||
+CONFIG_NLS_ISO8859_5=y
|
||||
+CONFIG_NLS_ISO8859_6=y
|
||||
+CONFIG_NLS_ISO8859_7=y
|
||||
+CONFIG_NLS_ISO8859_9=y
|
||||
+CONFIG_NLS_ISO8859_13=y
|
||||
+CONFIG_NLS_ISO8859_14=y
|
||||
+CONFIG_NLS_ISO8859_15=y
|
||||
+CONFIG_NLS_UTF8=y
|
||||
+CONFIG_PRINTK_TIME=y
|
||||
+CONFIG_DEBUG_FS=y
|
||||
+CONFIG_DETECT_HUNG_TASK=y
|
||||
+# CONFIG_DEBUG_PREEMPT is not set
|
||||
+# CONFIG_DEBUG_BUGVERBOSE is not set
|
||||
+# CONFIG_FTRACE is not set
|
||||
+CONFIG_KGDB=y
|
||||
+CONFIG_KGDB_KDB=y
|
||||
+# CONFIG_ARM_UNWIND is not set
|
||||
+CONFIG_CRYPTO_CBC=y
|
||||
+CONFIG_CRYPTO_HMAC=y
|
||||
+CONFIG_CRYPTO_MD5=y
|
||||
+CONFIG_CRYPTO_SHA1=y
|
||||
+CONFIG_CRYPTO_DES=y
|
||||
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
|
||||
+# CONFIG_CRYPTO_HW is not set
|
||||
+CONFIG_CRC_ITU_T=y
|
||||
+CONFIG_LIBCRC32C=y
|
|
@ -0,0 +1,63 @@
|
|||
From dfe5d158300e7500873f1f81d89a05842460befc Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Fri, 10 May 2013 19:42:38 +0100
|
||||
Subject: [PATCH 063/174] mmc: suppress sdcard warnings we are happy about by
|
||||
default
|
||||
|
||||
---
|
||||
drivers/mmc/host/sdhci-bcm2708.c | 11 +++++++++--
|
||||
1 file changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/mmc/host/sdhci-bcm2708.c
|
||||
+++ b/drivers/mmc/host/sdhci-bcm2708.c
|
||||
@@ -139,6 +139,7 @@ static bool sync_after_dma = 1;
|
||||
static bool missing_status = 1;
|
||||
static bool spurious_crc_acmd51 = 0;
|
||||
bool enable_llm = 1;
|
||||
+bool extra_messages = 0;
|
||||
|
||||
#if 0
|
||||
static void hptime_test(void)
|
||||
@@ -672,13 +673,16 @@ sdhci_bcm2708_platdma_reset(struct sdhci
|
||||
cs = readl(host_priv->dma_chan_base + BCM2708_DMA_CS);
|
||||
|
||||
if (!(BCM2708_DMA_ACTIVE & cs))
|
||||
- printk(KERN_INFO "%s: missed completion of "
|
||||
+ {
|
||||
+ if (extra_messages)
|
||||
+ printk(KERN_INFO "%s: missed completion of "
|
||||
"cmd %d DMA (%d/%d [%d]/[%d]) - "
|
||||
"ignoring it\n",
|
||||
mmc_hostname(host->mmc),
|
||||
host->last_cmdop,
|
||||
host_priv->sg_done, sg_todo,
|
||||
host_priv->sg_ix+1, sg_len);
|
||||
+ }
|
||||
else
|
||||
printk(KERN_INFO "%s: resetting ongoing cmd %d"
|
||||
"DMA before %d/%d [%d]/[%d] complete\n",
|
||||
@@ -903,7 +907,8 @@ static irqreturn_t sdhci_bcm2708_dma_irq
|
||||
|
||||
if (!host_priv->dma_wanted) {
|
||||
/* ignore this interrupt - it was reset */
|
||||
- printk(KERN_INFO "%s: DMA IRQ %X ignored - "
|
||||
+ if (extra_messages)
|
||||
+ printk(KERN_INFO "%s: DMA IRQ %X ignored - "
|
||||
"results were reset\n",
|
||||
mmc_hostname(host->mmc), dma_cs);
|
||||
#ifdef CHECK_DMA_USE
|
||||
@@ -1397,6 +1402,7 @@ module_param(missing_status, bool, 0444)
|
||||
module_param(spurious_crc_acmd51, bool, 0444);
|
||||
module_param(enable_llm, bool, 0444);
|
||||
module_param(cycle_delay, int, 0444);
|
||||
+module_param(extra_messages, bool, 0444);
|
||||
|
||||
MODULE_DESCRIPTION("Secure Digital Host Controller Interface platform driver");
|
||||
MODULE_AUTHOR("Broadcom <info@broadcom.com>");
|
||||
@@ -1409,5 +1415,6 @@ MODULE_PARM_DESC(sync_after_dma, "Block
|
||||
MODULE_PARM_DESC(missing_status, "Use the missing status quirk");
|
||||
MODULE_PARM_DESC(spurious_crc_acmd51, "Use the spurious crc quirk for reading SCR (ACMD51)");
|
||||
MODULE_PARM_DESC(enable_llm, "Enable low-latency mode");
|
||||
+MODULE_PARM_DESC(extra_messages, "Enable more sdcard warning messages");
|
||||
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
From b74d345f074c12d21e8dda2807750e8559588822 Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Fri, 17 May 2013 15:19:49 +0100
|
||||
Subject: [PATCH 064/174] Add missing ids for Netgear WNA1000N and D-Link Alpha
|
||||
|
||||
---
|
||||
drivers/net/wireless/rtl8192cu/os_dep/linux/usb_intf.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/drivers/net/wireless/rtl8192cu/os_dep/linux/usb_intf.c
|
||||
+++ b/drivers/net/wireless/rtl8192cu/os_dep/linux/usb_intf.c
|
||||
@@ -114,6 +114,7 @@ static struct usb_device_id rtw_usb_id_t
|
||||
{USB_DEVICE(0x4856, 0x0091)},//NetweeN - Feixun
|
||||
{USB_DEVICE(0x2019, 0x4902)},//Planex - Etop
|
||||
{USB_DEVICE(0x2019, 0xAB2E)},//SW-WF02-AD15 -Abocom
|
||||
+ {USB_DEVICE(0x0846, 0x9041)},//Netgear
|
||||
|
||||
/****** 8188 RU ********/
|
||||
{USB_DEVICE(0x0BDA, 0x317F)},//Netcore,Netcore
|
|
@ -0,0 +1,22 @@
|
|||
From 2d491bef93b86787eb5b5e83c46d1f4d87edf84f Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Fri, 31 May 2013 14:50:09 +0100
|
||||
Subject: [PATCH 065/174] rtl8192cu: select required config options to allow
|
||||
builds without other wifi modules. Thanks UrsusArctos
|
||||
|
||||
---
|
||||
drivers/net/wireless/rtl8192cu/Kconfig | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/rtl8192cu/Kconfig
|
||||
+++ b/drivers/net/wireless/rtl8192cu/Kconfig
|
||||
@@ -1,6 +1,8 @@
|
||||
config RTL8192CU
|
||||
tristate "Realtek 8192C USB WiFi"
|
||||
depends on USB
|
||||
+ select WIRELESS_EXT
|
||||
+ select WEXT_PRIV
|
||||
---help---
|
||||
- Help message of RTL8192CU
|
||||
+ Enable wireless network adapters based on Realtek RTL8192C chipset family, such as EDUP nano series
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
From 7776b6ebf1063d2f9fac33313c8d049b424fce46 Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Sat, 8 Jun 2013 22:14:13 +0100
|
||||
Subject: [PATCH 066/174] Only init gpio pins of selected i2c bus
|
||||
|
||||
---
|
||||
drivers/i2c/busses/i2c-bcm2708.c | 8 +++++---
|
||||
1 file changed, 5 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/i2c/busses/i2c-bcm2708.c
|
||||
+++ b/drivers/i2c/busses/i2c-bcm2708.c
|
||||
@@ -97,7 +97,7 @@ struct bcm2708_i2c {
|
||||
*
|
||||
* FIXME: This is a hack. Use pinmux / pinctrl.
|
||||
*/
|
||||
-static void bcm2708_i2c_init_pinmode(void)
|
||||
+static void bcm2708_i2c_init_pinmode(int id)
|
||||
{
|
||||
#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
|
||||
#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))
|
||||
@@ -105,8 +105,10 @@ static void bcm2708_i2c_init_pinmode(voi
|
||||
int pin;
|
||||
u32 *gpio = ioremap(0x20200000, SZ_16K);
|
||||
|
||||
+ BUG_ON(id != 0 && id != 1);
|
||||
/* BSC0 is on GPIO 0 & 1, BSC1 is on GPIO 2 & 3 */
|
||||
- for (pin = 0; pin <= 3; pin++) {
|
||||
+ for (pin = id*2+0; pin <= id*2+1; pin++) {
|
||||
+printk("bcm2708_i2c_init_pinmode(%d,%d)\n", id, pin);
|
||||
INP_GPIO(pin); /* set mode to GPIO input first */
|
||||
SET_GPIO_ALT(pin, 0); /* set mode to ALT 0 */
|
||||
}
|
||||
@@ -279,7 +281,7 @@ static int bcm2708_i2c_probe(struct plat
|
||||
return PTR_ERR(clk);
|
||||
}
|
||||
|
||||
- bcm2708_i2c_init_pinmode();
|
||||
+ bcm2708_i2c_init_pinmode(pdev->id);
|
||||
|
||||
bi = kzalloc(sizeof(*bi), GFP_KERNEL);
|
||||
if (!bi)
|
|
@ -0,0 +1,31 @@
|
|||
From 03f44ba654e40b60ffcec14030abf35152d0b639 Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Thu, 13 Jun 2013 16:46:54 +0100
|
||||
Subject: [PATCH 067/174] Avoid responding to unexpected I2C interrupts
|
||||
|
||||
---
|
||||
drivers/i2c/busses/i2c-bcm2708.c | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
--- a/drivers/i2c/busses/i2c-bcm2708.c
|
||||
+++ b/drivers/i2c/busses/i2c-bcm2708.c
|
||||
@@ -175,6 +175,11 @@ static irqreturn_t bcm2708_i2c_interrupt
|
||||
|
||||
spin_lock(&bi->lock);
|
||||
|
||||
+ /* we may see camera interrupts on the "other" I2C channel
|
||||
+ Just return if we've not sent anything */
|
||||
+ if (!bi->nmsgs || !bi->msg )
|
||||
+ goto early_exit;
|
||||
+
|
||||
s = bcm2708_rd(bi, BSC_S);
|
||||
|
||||
if (s & (BSC_S_CLKT | BSC_S_ERR)) {
|
||||
@@ -208,6 +213,7 @@ static irqreturn_t bcm2708_i2c_interrupt
|
||||
handled = false;
|
||||
}
|
||||
|
||||
+early_exit:
|
||||
spin_unlock(&bi->lock);
|
||||
|
||||
return handled ? IRQ_HANDLED : IRQ_NONE;
|
|
@ -0,0 +1,209 @@
|
|||
From 42b4a831d77ee33f67142882b2b68e4138cbf13e Mon Sep 17 00:00:00 2001
|
||||
From: Harm Hanemaaijer <fgenfb@yahoo.com>
|
||||
Date: Thu, 20 Jun 2013 20:21:39 +0200
|
||||
Subject: [PATCH 068/174] Speed up console framebuffer imageblit function
|
||||
|
||||
Especially on platforms with a slower CPU but a relatively high
|
||||
framebuffer fill bandwidth, like current ARM devices, the existing
|
||||
console monochrome imageblit function used to draw console text is
|
||||
suboptimal for common pixel depths such as 16bpp and 32bpp. The existing
|
||||
code is quite general and can deal with several pixel depths. By creating
|
||||
special case functions for 16bpp and 32bpp, by far the most common pixel
|
||||
formats used on modern systems, a significant speed-up is attained
|
||||
which can be readily felt on ARM-based devices like the Raspberry Pi
|
||||
and the Allwinner platform, but should help any platform using the
|
||||
fb layer.
|
||||
|
||||
The special case functions allow constant folding, eliminating a number
|
||||
of instructions including divide operations, and allow the use of an
|
||||
unrolled loop, eliminating instructions with a variable shift size,
|
||||
reducing source memory access instructions, and eliminating excessive
|
||||
branching. These unrolled loops also allow much better code optimization
|
||||
by the C compiler. The code that selects which optimized variant is used
|
||||
is also simplified, eliminating integer divide instructions.
|
||||
|
||||
The speed-up, measured by timing 'cat file.txt' in the console, varies
|
||||
between 40% and 70%, when testing on the Raspberry Pi and Allwinner
|
||||
ARM-based platforms, depending on font size and the pixel depth, with
|
||||
the greater benefit for 32bpp.
|
||||
|
||||
Signed-off-by: Harm Hanemaaijer <fgenfb@yahoo.com>
|
||||
---
|
||||
drivers/video/cfbimgblt.c | 152 ++++++++++++++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 147 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/video/cfbimgblt.c
|
||||
+++ b/drivers/video/cfbimgblt.c
|
||||
@@ -28,6 +28,11 @@
|
||||
*
|
||||
* Also need to add code to deal with cards endians that are different than
|
||||
* the native cpu endians. I also need to deal with MSB position in the word.
|
||||
+ * Modified by Harm Hanemaaijer (fgenfb@yahoo.com) 2013:
|
||||
+ * - Provide optimized versions of fast_imageblit for 16 and 32bpp that are
|
||||
+ * significantly faster than the previous implementation.
|
||||
+ * - Simplify the fast/slow_imageblit selection code, avoiding integer
|
||||
+ * divides.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/string.h>
|
||||
@@ -262,6 +267,133 @@ static inline void fast_imageblit(const
|
||||
}
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Optimized fast_imageblit for bpp == 16. ppw = 2, bit_mask = 3 folded
|
||||
+ * into the code, main loop unrolled.
|
||||
+ */
|
||||
+
|
||||
+static inline void fast_imageblit16(const struct fb_image *image,
|
||||
+ struct fb_info *p, u8 __iomem * dst1,
|
||||
+ u32 fgcolor, u32 bgcolor)
|
||||
+{
|
||||
+ u32 fgx = fgcolor, bgx = bgcolor;
|
||||
+ u32 spitch = (image->width + 7) / 8;
|
||||
+ u32 end_mask, eorx;
|
||||
+ const char *s = image->data, *src;
|
||||
+ u32 __iomem *dst;
|
||||
+ const u32 *tab = NULL;
|
||||
+ int i, j, k;
|
||||
+
|
||||
+ tab = fb_be_math(p) ? cfb_tab16_be : cfb_tab16_le;
|
||||
+
|
||||
+ fgx <<= 16;
|
||||
+ bgx <<= 16;
|
||||
+ fgx |= fgcolor;
|
||||
+ bgx |= bgcolor;
|
||||
+
|
||||
+ eorx = fgx ^ bgx;
|
||||
+ k = image->width / 2;
|
||||
+
|
||||
+ for (i = image->height; i--;) {
|
||||
+ dst = (u32 __iomem *) dst1;
|
||||
+ src = s;
|
||||
+
|
||||
+ j = k;
|
||||
+ while (j >= 4) {
|
||||
+ u8 bits = *src;
|
||||
+ end_mask = tab[(bits >> 6) & 3];
|
||||
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
|
||||
+ end_mask = tab[(bits >> 4) & 3];
|
||||
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
|
||||
+ end_mask = tab[(bits >> 2) & 3];
|
||||
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
|
||||
+ end_mask = tab[bits & 3];
|
||||
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
|
||||
+ src++;
|
||||
+ j -= 4;
|
||||
+ }
|
||||
+ if (j != 0) {
|
||||
+ u8 bits = *src;
|
||||
+ end_mask = tab[(bits >> 6) & 3];
|
||||
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
|
||||
+ if (j >= 2) {
|
||||
+ end_mask = tab[(bits >> 4) & 3];
|
||||
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
|
||||
+ if (j == 3) {
|
||||
+ end_mask = tab[(bits >> 2) & 3];
|
||||
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ dst1 += p->fix.line_length;
|
||||
+ s += spitch;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Optimized fast_imageblit for bpp == 32. ppw = 1, bit_mask = 1 folded
|
||||
+ * into the code, main loop unrolled.
|
||||
+ */
|
||||
+
|
||||
+static inline void fast_imageblit32(const struct fb_image *image,
|
||||
+ struct fb_info *p, u8 __iomem * dst1,
|
||||
+ u32 fgcolor, u32 bgcolor)
|
||||
+{
|
||||
+ u32 fgx = fgcolor, bgx = bgcolor;
|
||||
+ u32 spitch = (image->width + 7) / 8;
|
||||
+ u32 end_mask, eorx;
|
||||
+ const char *s = image->data, *src;
|
||||
+ u32 __iomem *dst;
|
||||
+ const u32 *tab = NULL;
|
||||
+ int i, j, k;
|
||||
+
|
||||
+ tab = cfb_tab32;
|
||||
+
|
||||
+ eorx = fgx ^ bgx;
|
||||
+ k = image->width;
|
||||
+
|
||||
+ for (i = image->height; i--;) {
|
||||
+ dst = (u32 __iomem *) dst1;
|
||||
+ src = s;
|
||||
+
|
||||
+ j = k;
|
||||
+ while (j >= 8) {
|
||||
+ u8 bits = *src;
|
||||
+ end_mask = tab[(bits >> 7) & 1];
|
||||
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
|
||||
+ end_mask = tab[(bits >> 6) & 1];
|
||||
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
|
||||
+ end_mask = tab[(bits >> 5) & 1];
|
||||
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
|
||||
+ end_mask = tab[(bits >> 4) & 1];
|
||||
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
|
||||
+ end_mask = tab[(bits >> 3) & 1];
|
||||
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
|
||||
+ end_mask = tab[(bits >> 2) & 1];
|
||||
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
|
||||
+ end_mask = tab[(bits >> 1) & 1];
|
||||
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
|
||||
+ end_mask = tab[bits & 1];
|
||||
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
|
||||
+ src++;
|
||||
+ j -= 8;
|
||||
+ }
|
||||
+ if (j != 0) {
|
||||
+ u32 bits = (u32) * src;
|
||||
+ while (j > 1) {
|
||||
+ end_mask = tab[(bits >> 7) & 1];
|
||||
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++);
|
||||
+ bits <<= 1;
|
||||
+ j--;
|
||||
+ }
|
||||
+ end_mask = tab[(bits >> 7) & 1];
|
||||
+ FB_WRITEL((end_mask & eorx) ^ bgx, dst);
|
||||
+ }
|
||||
+ dst1 += p->fix.line_length;
|
||||
+ s += spitch;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void cfb_imageblit(struct fb_info *p, const struct fb_image *image)
|
||||
{
|
||||
u32 fgcolor, bgcolor, start_index, bitstart, pitch_index = 0;
|
||||
@@ -294,11 +426,21 @@ void cfb_imageblit(struct fb_info *p, co
|
||||
bgcolor = image->bg_color;
|
||||
}
|
||||
|
||||
- if (32 % bpp == 0 && !start_index && !pitch_index &&
|
||||
- ((width & (32/bpp-1)) == 0) &&
|
||||
- bpp >= 8 && bpp <= 32)
|
||||
- fast_imageblit(image, p, dst1, fgcolor, bgcolor);
|
||||
- else
|
||||
+ if (!start_index && !pitch_index) {
|
||||
+ if (bpp == 32)
|
||||
+ fast_imageblit32(image, p, dst1, fgcolor,
|
||||
+ bgcolor);
|
||||
+ else if (bpp == 16 && (width & 1) == 0)
|
||||
+ fast_imageblit16(image, p, dst1, fgcolor,
|
||||
+ bgcolor);
|
||||
+ else if (bpp == 8 && (width & 3) == 0)
|
||||
+ fast_imageblit(image, p, dst1, fgcolor,
|
||||
+ bgcolor);
|
||||
+ else
|
||||
+ slow_imageblit(image, p, dst1, fgcolor,
|
||||
+ bgcolor,
|
||||
+ start_index, pitch_index);
|
||||
+ } else
|
||||
slow_imageblit(image, p, dst1, fgcolor, bgcolor,
|
||||
start_index, pitch_index);
|
||||
} else
|
|
@ -0,0 +1,91 @@
|
|||
From bae48dcebc8f847977f6077910afb93f754708d6 Mon Sep 17 00:00:00 2001
|
||||
From: Siarhei Siamashka <siarhei.siamashka@gmail.com>
|
||||
Date: Mon, 17 Jun 2013 13:32:11 +0300
|
||||
Subject: [PATCH 069/174] fbdev: add FBIOCOPYAREA ioctl
|
||||
|
||||
Based on the patch authored by Ali Gholami Rudi at
|
||||
https://lkml.org/lkml/2009/7/13/153
|
||||
|
||||
Provide an ioctl for userspace applications, but only if this operation
|
||||
is hardware accelerated (otherwide it does not make any sense).
|
||||
|
||||
Signed-off-by: Siarhei Siamashka <siarhei.siamashka@gmail.com>
|
||||
---
|
||||
drivers/video/fbmem.c | 30 ++++++++++++++++++++++++++++++
|
||||
include/uapi/linux/fb.h | 5 +++++
|
||||
2 files changed, 35 insertions(+)
|
||||
|
||||
--- a/drivers/video/fbmem.c
|
||||
+++ b/drivers/video/fbmem.c
|
||||
@@ -1074,6 +1074,25 @@ fb_blank(struct fb_info *info, int blank
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int fb_copyarea_user(struct fb_info *info,
|
||||
+ struct fb_copyarea *copy)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+ if (!lock_fb_info(info))
|
||||
+ return -ENODEV;
|
||||
+ if (copy->dx + copy->width > info->var.xres ||
|
||||
+ copy->sx + copy->width > info->var.xres ||
|
||||
+ copy->dy + copy->height > info->var.yres ||
|
||||
+ copy->sy + copy->height > info->var.yres) {
|
||||
+ ret = -EINVAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ info->fbops->fb_copyarea(info, copy);
|
||||
+out:
|
||||
+ unlock_fb_info(info);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
@@ -1084,6 +1103,7 @@ static long do_fb_ioctl(struct fb_info *
|
||||
struct fb_cmap cmap_from;
|
||||
struct fb_cmap_user cmap;
|
||||
struct fb_event event;
|
||||
+ struct fb_copyarea copy;
|
||||
void __user *argp = (void __user *)arg;
|
||||
long ret = 0;
|
||||
|
||||
@@ -1193,6 +1213,15 @@ static long do_fb_ioctl(struct fb_info *
|
||||
console_unlock();
|
||||
unlock_fb_info(info);
|
||||
break;
|
||||
+ case FBIOCOPYAREA:
|
||||
+ if (info->flags & FBINFO_HWACCEL_COPYAREA) {
|
||||
+ /* only provide this ioctl if it is accelerated */
|
||||
+ if (copy_from_user(©, argp, sizeof(copy)))
|
||||
+ return -EFAULT;
|
||||
+ ret = fb_copyarea_user(info, ©);
|
||||
+ break;
|
||||
+ }
|
||||
+ /* fall through */
|
||||
default:
|
||||
if (!lock_fb_info(info))
|
||||
return -ENODEV;
|
||||
@@ -1345,6 +1374,7 @@ static long fb_compat_ioctl(struct file
|
||||
case FBIOPAN_DISPLAY:
|
||||
case FBIOGET_CON2FBMAP:
|
||||
case FBIOPUT_CON2FBMAP:
|
||||
+ case FBIOCOPYAREA:
|
||||
arg = (unsigned long) compat_ptr(arg);
|
||||
case FBIOBLANK:
|
||||
ret = do_fb_ioctl(info, cmd, arg);
|
||||
--- a/include/uapi/linux/fb.h
|
||||
+++ b/include/uapi/linux/fb.h
|
||||
@@ -34,6 +34,11 @@
|
||||
#define FBIOPUT_MODEINFO 0x4617
|
||||
#define FBIOGET_DISPINFO 0x4618
|
||||
#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32)
|
||||
+/*
|
||||
+ * HACK: use 'z' in order not to clash with any other ioctl numbers which might
|
||||
+ * be concurrently added to the mainline kernel
|
||||
+ */
|
||||
+#define FBIOCOPYAREA _IOW('z', 0x21, struct fb_copyarea)
|
||||
|
||||
#define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */
|
||||
#define FB_TYPE_PLANES 1 /* Non interleaved planes */
|
|
@ -0,0 +1,241 @@
|
|||
From ba65074e39e6aee492bd3c077f640b29a0a89c05 Mon Sep 17 00:00:00 2001
|
||||
From: Siarhei Siamashka <siarhei.siamashka@gmail.com>
|
||||
Date: Mon, 17 Jun 2013 16:00:25 +0300
|
||||
Subject: [PATCH 070/174] bcm2708_fb: DMA acceleration for fb_copyarea
|
||||
|
||||
Based on http://www.raspberrypi.org/phpBB3/viewtopic.php?p=62425#p62425
|
||||
Also used Simon's dmaer_master module as a reference for tweaking DMA
|
||||
settings for better performance.
|
||||
|
||||
For now busylooping only. IRQ support might be added later.
|
||||
With non-overclocked Raspberry Pi, the performance is ~360 MB/s
|
||||
for simple copy or ~260 MB/s for two-pass copy (used when dragging
|
||||
windows to the right).
|
||||
|
||||
In the case of using DMA channel 0, the performance improves
|
||||
to ~440 MB/s.
|
||||
|
||||
For comparison, VFP optimized CPU copy can only do ~114 MB/s in
|
||||
the same conditions (hindered by reading uncached source buffer).
|
||||
|
||||
Signed-off-by: Siarhei Siamashka <siarhei.siamashka@gmail.com>
|
||||
---
|
||||
drivers/video/bcm2708_fb.c | 162 ++++++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 159 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/video/bcm2708_fb.c
|
||||
+++ b/drivers/video/bcm2708_fb.c
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <linux/printk.h>
|
||||
#include <linux/console.h>
|
||||
|
||||
+#include <mach/dma.h>
|
||||
#include <mach/platform.h>
|
||||
#include <mach/vcio.h>
|
||||
|
||||
@@ -63,6 +64,11 @@ struct bcm2708_fb {
|
||||
struct fbinfo_s *info;
|
||||
dma_addr_t dma;
|
||||
u32 cmap[16];
|
||||
+ int dma_chan;
|
||||
+ int dma_irq;
|
||||
+ void __iomem *dma_chan_base;
|
||||
+ void *cb_base; /* DMA control blocks */
|
||||
+ dma_addr_t cb_handle;
|
||||
};
|
||||
|
||||
#define to_bcm2708(info) container_of(info, struct bcm2708_fb, fb)
|
||||
@@ -312,11 +318,133 @@ static void bcm2708_fb_fillrect(struct f
|
||||
cfb_fillrect(info, rect);
|
||||
}
|
||||
|
||||
+/* A helper function for configuring dma control block */
|
||||
+static void set_dma_cb(struct bcm2708_dma_cb *cb,
|
||||
+ int burst_size,
|
||||
+ dma_addr_t dst,
|
||||
+ int dst_stride,
|
||||
+ dma_addr_t src,
|
||||
+ int src_stride,
|
||||
+ int w,
|
||||
+ int h)
|
||||
+{
|
||||
+ cb->info = BCM2708_DMA_BURST(burst_size) | BCM2708_DMA_S_WIDTH |
|
||||
+ BCM2708_DMA_S_INC | BCM2708_DMA_D_WIDTH |
|
||||
+ BCM2708_DMA_D_INC | BCM2708_DMA_TDMODE;
|
||||
+ cb->dst = dst;
|
||||
+ cb->src = src;
|
||||
+ /*
|
||||
+ * This is not really obvious from the DMA documentation,
|
||||
+ * but the top 16 bits must be programmmed to "height -1"
|
||||
+ * and not "height" in 2D mode.
|
||||
+ */
|
||||
+ cb->length = ((h - 1) << 16) | w;
|
||||
+ cb->stride = ((dst_stride - w) << 16) | (u16)(src_stride - w);
|
||||
+ cb->pad[0] = 0;
|
||||
+ cb->pad[1] = 0;
|
||||
+}
|
||||
+
|
||||
static void bcm2708_fb_copyarea(struct fb_info *info,
|
||||
const struct fb_copyarea *region)
|
||||
{
|
||||
- /*print_debug("bcm2708_fb_copyarea\n"); */
|
||||
- cfb_copyarea(info, region);
|
||||
+ struct bcm2708_fb *fb = to_bcm2708(info);
|
||||
+ struct bcm2708_dma_cb *cb = fb->cb_base;
|
||||
+ int bytes_per_pixel = (info->var.bits_per_pixel + 7) >> 3;
|
||||
+ /* Channel 0 supports larger bursts and is a bit faster */
|
||||
+ int burst_size = (fb->dma_chan == 0) ? 8 : 2;
|
||||
+
|
||||
+ /* Fallback to cfb_copyarea() if we don't like something */
|
||||
+ if (bytes_per_pixel > 4 ||
|
||||
+ info->var.xres > 1920 || info->var.yres > 1200 ||
|
||||
+ region->width <= 0 || region->width > info->var.xres ||
|
||||
+ region->height <= 0 || region->height > info->var.yres ||
|
||||
+ region->sx < 0 || region->sx >= info->var.xres ||
|
||||
+ region->sy < 0 || region->sy >= info->var.yres ||
|
||||
+ region->dx < 0 || region->dx >= info->var.xres ||
|
||||
+ region->dy < 0 || region->dy >= info->var.yres ||
|
||||
+ region->sx + region->width > info->var.xres ||
|
||||
+ region->dx + region->width > info->var.xres ||
|
||||
+ region->sy + region->height > info->var.yres ||
|
||||
+ region->dy + region->height > info->var.yres) {
|
||||
+ cfb_copyarea(info, region);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (region->dy == region->sy && region->dx > region->sx) {
|
||||
+ /*
|
||||
+ * A difficult case of overlapped copy. Because DMA can't
|
||||
+ * copy individual scanlines in backwards direction, we need
|
||||
+ * two-pass processing. We do it by programming a chain of dma
|
||||
+ * control blocks in the first 16K part of the buffer and use
|
||||
+ * the remaining 48K as the intermediate temporary scratch
|
||||
+ * buffer. The buffer size is sufficient to handle up to
|
||||
+ * 1920x1200 resolution at 32bpp pixel depth.
|
||||
+ */
|
||||
+ int y;
|
||||
+ dma_addr_t control_block_pa = fb->cb_handle;
|
||||
+ dma_addr_t scratchbuf = fb->cb_handle + 16 * 1024;
|
||||
+ int scanline_size = bytes_per_pixel * region->width;
|
||||
+ int scanlines_per_cb = (64 * 1024 - 16 * 1024) / scanline_size;
|
||||
+
|
||||
+ for (y = 0; y < region->height; y += scanlines_per_cb) {
|
||||
+ dma_addr_t src =
|
||||
+ fb->fb.fix.smem_start +
|
||||
+ bytes_per_pixel * region->sx +
|
||||
+ (region->sy + y) * fb->fb.fix.line_length;
|
||||
+ dma_addr_t dst =
|
||||
+ fb->fb.fix.smem_start +
|
||||
+ bytes_per_pixel * region->dx +
|
||||
+ (region->dy + y) * fb->fb.fix.line_length;
|
||||
+
|
||||
+ if (region->height - y < scanlines_per_cb)
|
||||
+ scanlines_per_cb = region->height - y;
|
||||
+
|
||||
+ set_dma_cb(cb, burst_size, scratchbuf, scanline_size,
|
||||
+ src, fb->fb.fix.line_length,
|
||||
+ scanline_size, scanlines_per_cb);
|
||||
+ control_block_pa += sizeof(struct bcm2708_dma_cb);
|
||||
+ cb->next = control_block_pa;
|
||||
+ cb++;
|
||||
+
|
||||
+ set_dma_cb(cb, burst_size, dst, fb->fb.fix.line_length,
|
||||
+ scratchbuf, scanline_size,
|
||||
+ scanline_size, scanlines_per_cb);
|
||||
+ control_block_pa += sizeof(struct bcm2708_dma_cb);
|
||||
+ cb->next = control_block_pa;
|
||||
+ cb++;
|
||||
+ }
|
||||
+ /* move the pointer back to the last dma control block */
|
||||
+ cb--;
|
||||
+ } else {
|
||||
+ /* A single dma control block is enough. */
|
||||
+ int sy, dy, stride;
|
||||
+ if (region->dy <= region->sy) {
|
||||
+ /* processing from top to bottom */
|
||||
+ dy = region->dy;
|
||||
+ sy = region->sy;
|
||||
+ stride = fb->fb.fix.line_length;
|
||||
+ } else {
|
||||
+ /* processing from bottom to top */
|
||||
+ dy = region->dy + region->height - 1;
|
||||
+ sy = region->sy + region->height - 1;
|
||||
+ stride = -fb->fb.fix.line_length;
|
||||
+ }
|
||||
+ set_dma_cb(cb, burst_size,
|
||||
+ fb->fb.fix.smem_start + dy * fb->fb.fix.line_length +
|
||||
+ bytes_per_pixel * region->dx,
|
||||
+ stride,
|
||||
+ fb->fb.fix.smem_start + sy * fb->fb.fix.line_length +
|
||||
+ bytes_per_pixel * region->sx,
|
||||
+ stride,
|
||||
+ region->width * bytes_per_pixel,
|
||||
+ region->height);
|
||||
+ }
|
||||
+
|
||||
+ /* end of dma control blocks chain */
|
||||
+ cb->next = 0;
|
||||
+
|
||||
+ bcm_dma_start(fb->dma_chan_base, fb->cb_handle);
|
||||
+ bcm_dma_wait_idle(fb->dma_chan_base);
|
||||
}
|
||||
|
||||
static void bcm2708_fb_imageblit(struct fb_info *info,
|
||||
@@ -359,7 +487,7 @@ static int bcm2708_fb_register(struct bc
|
||||
fb->dma = dma;
|
||||
}
|
||||
fb->fb.fbops = &bcm2708_fb_ops;
|
||||
- fb->fb.flags = FBINFO_FLAG_DEFAULT;
|
||||
+ fb->fb.flags = FBINFO_FLAG_DEFAULT | FBINFO_HWACCEL_COPYAREA;
|
||||
fb->fb.pseudo_palette = fb->cmap;
|
||||
|
||||
strncpy(fb->fb.fix.id, bcm2708_name, sizeof(fb->fb.fix.id));
|
||||
@@ -424,6 +552,28 @@ static int bcm2708_fb_probe(struct platf
|
||||
}
|
||||
memset(fb, 0, sizeof(struct bcm2708_fb));
|
||||
|
||||
+ fb->cb_base = dma_alloc_writecombine(&dev->dev, SZ_64K,
|
||||
+ &fb->cb_handle, GFP_KERNEL);
|
||||
+ if (!fb->cb_base) {
|
||||
+ dev_err(&dev->dev, "cannot allocate DMA CBs\n");
|
||||
+ ret = -ENOMEM;
|
||||
+ goto free_fb;
|
||||
+ }
|
||||
+
|
||||
+ pr_info("BCM2708FB: allocated DMA memory %08x\n",
|
||||
+ fb->cb_handle);
|
||||
+
|
||||
+ ret = bcm_dma_chan_alloc(BCM_DMA_FEATURE_BULK,
|
||||
+ &fb->dma_chan_base, &fb->dma_irq);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(&dev->dev, "couldn't allocate a DMA channel\n");
|
||||
+ goto free_cb;
|
||||
+ }
|
||||
+ fb->dma_chan = ret;
|
||||
+
|
||||
+ pr_info("BCM2708FB: allocated DMA channel %d @ %p\n",
|
||||
+ fb->dma_chan, fb->dma_chan_base);
|
||||
+
|
||||
fb->dev = dev;
|
||||
|
||||
ret = bcm2708_fb_register(fb);
|
||||
@@ -432,6 +582,9 @@ static int bcm2708_fb_probe(struct platf
|
||||
goto out;
|
||||
}
|
||||
|
||||
+free_cb:
|
||||
+ dma_free_writecombine(&dev->dev, SZ_64K, fb->cb_base, fb->cb_handle);
|
||||
+free_fb:
|
||||
kfree(fb);
|
||||
free_region:
|
||||
dev_err(&dev->dev, "probe failed, err %d\n", ret);
|
||||
@@ -449,6 +602,9 @@ static int bcm2708_fb_remove(struct plat
|
||||
iounmap(fb->fb.screen_base);
|
||||
unregister_framebuffer(&fb->fb);
|
||||
|
||||
+ dma_free_writecombine(&dev->dev, SZ_64K, fb->cb_base, fb->cb_handle);
|
||||
+ bcm_dma_chan_free(fb->dma_chan);
|
||||
+
|
||||
dma_free_coherent(NULL, PAGE_ALIGN(sizeof(*fb->info)), (void *)fb->info,
|
||||
fb->dma);
|
||||
kfree(fb);
|
|
@ -0,0 +1,82 @@
|
|||
From 9b8c30f46a381533c92a6424ff25f9014d8802b0 Mon Sep 17 00:00:00 2001
|
||||
From: Mike Bradley <mike.bradley@incanetworks.com>
|
||||
Date: Mon, 17 Jun 2013 11:31:42 -0700
|
||||
Subject: [PATCH 071/174] dwc_otg: Call usb_hcd_unlink_urb_from_ep with lock
|
||||
held in completion handler
|
||||
|
||||
usb_hcd_unlink_urb_from_ep must be called with the HCD lock held. Calling it
|
||||
asynchronously in the tasklet was not safe (regression in
|
||||
c4564d4a1a0a9b10d4419e48239f5d99e88d2667).
|
||||
|
||||
This change unlinks it from the endpoint prior to queueing it for handling in
|
||||
the tasklet, and also adds a check to ensure the urb is OK to be unlinked
|
||||
before doing so.
|
||||
|
||||
NULL pointer dereference kernel oopses had been observed in usb_hcd_giveback_urb
|
||||
when a USB device was unplugged/replugged during data transfer. This effect
|
||||
was reproduced using automated USB port power control, hundreds of replug
|
||||
events were performed during active transfers to confirm that the problem was
|
||||
eliminated.
|
||||
---
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 2 +-
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 18 ++++++++++++++----
|
||||
2 files changed, 15 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
|
||||
@@ -704,6 +704,7 @@ static void completion_tasklet_func(void
|
||||
urb_tq_entry_t *item;
|
||||
dwc_irqflags_t flags;
|
||||
|
||||
+ /* This could just be spin_lock_irq */
|
||||
DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags);
|
||||
while (!DWC_TAILQ_EMPTY(&hcd->completed_urb_list)) {
|
||||
item = DWC_TAILQ_FIRST(&hcd->completed_urb_list);
|
||||
@@ -713,7 +714,6 @@ static void completion_tasklet_func(void
|
||||
DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags);
|
||||
DWC_FREE(item);
|
||||
|
||||
- usb_hcd_unlink_urb_from_ep(hcd->priv, urb);
|
||||
usb_hcd_giveback_urb(hcd->priv, urb, urb->status);
|
||||
|
||||
DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags);
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
|
||||
@@ -265,13 +265,15 @@ static void free_bus_bandwidth(struct us
|
||||
|
||||
/**
|
||||
* Sets the final status of an URB and returns it to the device driver. Any
|
||||
- * required cleanup of the URB is performed.
|
||||
+ * required cleanup of the URB is performed. The HCD lock should be held on
|
||||
+ * entry.
|
||||
*/
|
||||
static int _complete(dwc_otg_hcd_t * hcd, void *urb_handle,
|
||||
dwc_otg_hcd_urb_t * dwc_otg_urb, int32_t status)
|
||||
{
|
||||
struct urb *urb = (struct urb *)urb_handle;
|
||||
urb_tq_entry_t *new_entry;
|
||||
+ int rc = 0;
|
||||
if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
|
||||
DWC_PRINTF("%s: urb %p, device %d, ep %d %s, status=%d\n",
|
||||
__func__, urb, usb_pipedevice(urb->pipe),
|
||||
@@ -363,9 +365,17 @@ static int _complete(dwc_otg_hcd_t * hcd
|
||||
#endif
|
||||
} else {
|
||||
new_entry->urb = urb;
|
||||
- DWC_TAILQ_INSERT_TAIL(&hcd->completed_urb_list, new_entry,
|
||||
- urb_tq_entries);
|
||||
- DWC_TASK_HI_SCHEDULE(hcd->completion_tasklet);
|
||||
+#if USB_URB_EP_LINKING
|
||||
+ rc = usb_hcd_check_unlink_urb(dwc_otg_hcd_to_hcd(hcd), urb, urb->status);
|
||||
+ if(0 == rc) {
|
||||
+ usb_hcd_unlink_urb_from_ep(dwc_otg_hcd_to_hcd(hcd), urb);
|
||||
+ }
|
||||
+#endif
|
||||
+ if(0 == rc) {
|
||||
+ DWC_TAILQ_INSERT_TAIL(&hcd->completed_urb_list, new_entry,
|
||||
+ urb_tq_entries);
|
||||
+ DWC_TASK_HI_SCHEDULE(hcd->completion_tasklet);
|
||||
+ }
|
||||
}
|
||||
return 0;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,66 @@
|
|||
From 7653ccf871836bc9a49f55df82d7f14596115146 Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Wed, 3 Jul 2013 11:39:46 +0100
|
||||
Subject: [PATCH 073/174] dwc_otg: fix device attributes and avoid kernel
|
||||
warnings on boot
|
||||
|
||||
---
|
||||
drivers/usb/host/dwc_otg/dwc_otg_attr.c | 12 ++++++------
|
||||
1 file changed, 6 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_attr.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_attr.c
|
||||
@@ -909,7 +909,7 @@ static ssize_t regdump_show(struct devic
|
||||
return sprintf(buf, "Register Dump\n");
|
||||
}
|
||||
|
||||
-DEVICE_ATTR(regdump, S_IRUGO | S_IWUSR, regdump_show, 0);
|
||||
+DEVICE_ATTR(regdump, S_IRUGO, regdump_show, 0);
|
||||
|
||||
/**
|
||||
* Dump global registers and either host or device registers (depending on the
|
||||
@@ -925,7 +925,7 @@ static ssize_t spramdump_show(struct dev
|
||||
return sprintf(buf, "SPRAM Dump\n");
|
||||
}
|
||||
|
||||
-DEVICE_ATTR(spramdump, S_IRUGO | S_IWUSR, spramdump_show, 0);
|
||||
+DEVICE_ATTR(spramdump, S_IRUGO, spramdump_show, 0);
|
||||
|
||||
/**
|
||||
* Dump the current hcd state.
|
||||
@@ -940,7 +940,7 @@ static ssize_t hcddump_show(struct devic
|
||||
return sprintf(buf, "HCD Dump\n");
|
||||
}
|
||||
|
||||
-DEVICE_ATTR(hcddump, S_IRUGO | S_IWUSR, hcddump_show, 0);
|
||||
+DEVICE_ATTR(hcddump, S_IRUGO, hcddump_show, 0);
|
||||
|
||||
/**
|
||||
* Dump the average frame remaining at SOF. This can be used to
|
||||
@@ -958,7 +958,7 @@ static ssize_t hcd_frrem_show(struct dev
|
||||
return sprintf(buf, "HCD Dump Frame Remaining\n");
|
||||
}
|
||||
|
||||
-DEVICE_ATTR(hcd_frrem, S_IRUGO | S_IWUSR, hcd_frrem_show, 0);
|
||||
+DEVICE_ATTR(hcd_frrem, S_IRUGO, hcd_frrem_show, 0);
|
||||
|
||||
/**
|
||||
* Displays the time required to read the GNPTXFSIZ register many times (the
|
||||
@@ -986,7 +986,7 @@ static ssize_t rd_reg_test_show(struct d
|
||||
RW_REG_COUNT, time * MSEC_PER_JIFFIE, time);
|
||||
}
|
||||
|
||||
-DEVICE_ATTR(rd_reg_test, S_IRUGO | S_IWUSR, rd_reg_test_show, 0);
|
||||
+DEVICE_ATTR(rd_reg_test, S_IRUGO, rd_reg_test_show, 0);
|
||||
|
||||
/**
|
||||
* Displays the time required to write the GNPTXFSIZ register many times (the
|
||||
@@ -1014,7 +1014,7 @@ static ssize_t wr_reg_test_show(struct d
|
||||
RW_REG_COUNT, time * MSEC_PER_JIFFIE, time);
|
||||
}
|
||||
|
||||
-DEVICE_ATTR(wr_reg_test, S_IRUGO | S_IWUSR, wr_reg_test_show, 0);
|
||||
+DEVICE_ATTR(wr_reg_test, S_IRUGO, wr_reg_test_show, 0);
|
||||
|
||||
#ifdef CONFIG_USB_DWC_OTG_LPM
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
From a720faa00a378b304c7a24cbbde6d9bc98fb5c70 Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Wed, 3 Jul 2013 13:55:00 +0100
|
||||
Subject: [PATCH 074/174] hack: fix for incorrect uart fifo size detection
|
||||
|
||||
---
|
||||
drivers/tty/serial/amba-pl011.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/tty/serial/amba-pl011.c
|
||||
+++ b/drivers/tty/serial/amba-pl011.c
|
||||
@@ -84,7 +84,7 @@ struct vendor_data {
|
||||
|
||||
static unsigned int get_fifosize_arm(unsigned int periphid)
|
||||
{
|
||||
- unsigned int rev = (periphid >> 20) & 0xf;
|
||||
+ unsigned int rev = 0; //(periphid >> 20) & 0xf;
|
||||
return rev < 3 ? 16 : 32;
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
From 9fc9389ab723f75d183813ca8012b89a01a70a1a Mon Sep 17 00:00:00 2001
|
||||
From: Jonathan Bensen <cybertronic@gmail.com>
|
||||
Date: Mon, 8 Jul 2013 09:49:56 -0700
|
||||
Subject: [PATCH 075/174] Fix for deprecated/undefined create_proc_entry in
|
||||
RTL8192cu driver
|
||||
|
||||
---
|
||||
drivers/net/wireless/rtl8192cu/os_dep/linux/os_intfs.c | 13 +++++++++++++
|
||||
1 file changed, 13 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/rtl8192cu/os_dep/linux/os_intfs.c
|
||||
+++ b/drivers/net/wireless/rtl8192cu/os_dep/linux/os_intfs.c
|
||||
@@ -255,6 +255,18 @@ static char rtw_proc_name[IFNAMSIZ];
|
||||
static struct proc_dir_entry *rtw_proc = NULL;
|
||||
static int rtw_proc_cnt = 0;
|
||||
|
||||
+#ifndef create_proc_entry
|
||||
+/* dummy routines */
|
||||
+void rtw_proc_remove_one(struct net_device *dev)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+void rtw_proc_init_one(struct net_device *dev)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+#else /* create_proc_entry not defined */
|
||||
+
|
||||
void rtw_proc_init_one(struct net_device *dev)
|
||||
{
|
||||
struct proc_dir_entry *dir_dev = NULL;
|
||||
@@ -525,6 +537,7 @@ void rtw_proc_remove_one(struct net_devi
|
||||
}
|
||||
}
|
||||
#endif
|
||||
+#endif
|
||||
|
||||
uint loadparam( _adapter *padapter, _nic_hdl pnetdev)
|
||||
{
|
|
@ -0,0 +1,23 @@
|
|||
From a1cd8994c1f5d01f8932ad5d047677d6a264f711 Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Wed, 10 Jul 2013 23:53:31 +0100
|
||||
Subject: [PATCH 076/174] sdhci-bcm2807: Increase sync_after_dma timeout
|
||||
|
||||
The current timeout is being hit with some cards that complete successfully with a longer timeout.
|
||||
The timeout is not handled well, and is believed to be a code path that causes corruption.
|
||||
872a8ff suggests that crappy cards can take up to 3 seconds to respond
|
||||
---
|
||||
drivers/mmc/host/sdhci-bcm2708.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/mmc/host/sdhci-bcm2708.c
|
||||
+++ b/drivers/mmc/host/sdhci-bcm2708.c
|
||||
@@ -842,7 +842,7 @@ static void sdhci_bcm2708_dma_complete_i
|
||||
We get CRC and DEND errors unless we wait for
|
||||
the SD controller to finish reading/writing to the card. */
|
||||
u32 state_mask;
|
||||
- int timeout=30*5000;
|
||||
+ int timeout=3*1000*1000;
|
||||
|
||||
DBG("PDMA over - sync card\n");
|
||||
if (data->flags & MMC_DATA_READ)
|
|
@ -0,0 +1,22 @@
|
|||
From 9112b4c659edaf09792f1af02fe9e9c4753fb411 Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Mon, 15 Jul 2013 23:55:52 +0100
|
||||
Subject: [PATCH 077/174] dcw_otg: avoid logging function that can cause panics
|
||||
|
||||
See: https://github.com/raspberrypi/firmware/issues/21
|
||||
Thanks to cleverca22 for fix
|
||||
---
|
||||
drivers/usb/host/dwc_otg/dwc_otg_attr.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_attr.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_attr.c
|
||||
@@ -920,7 +920,7 @@ static ssize_t spramdump_show(struct dev
|
||||
{
|
||||
dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
|
||||
|
||||
- dwc_otg_dump_spram(otg_dev->core_if);
|
||||
+ //dwc_otg_dump_spram(otg_dev->core_if);
|
||||
|
||||
return sprintf(buf, "SPRAM Dump\n");
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
From cb902630ae7ef709c8f40ca3f506cf5052077701 Mon Sep 17 00:00:00 2001
|
||||
From: P33M <P33M@github.com>
|
||||
Date: Sat, 13 Jul 2013 20:41:26 +0100
|
||||
Subject: [PATCH 078/174] dwc_otg: mask correct interrupts after transaction
|
||||
error recovery
|
||||
|
||||
The dwc_otg driver will unmask certain interrupts on a transaction
|
||||
that previously halted in the error state in order to reset the
|
||||
QTD error count. The various fine-grained interrupt handlers do not
|
||||
consider that other interrupts besides themselves were unmasked.
|
||||
|
||||
By disabling the two other interrupts only ever enabled in DMA mode
|
||||
for this purpose, we can avoid unnecessary function calls in the
|
||||
IRQ handler. This will also prevent an unneccesary FIQ interrupt
|
||||
from being generated if the FIQ is enabled.
|
||||
---
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 21 +++++++++++++++++++++
|
||||
1 file changed, 21 insertions(+)
|
||||
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
|
||||
@@ -1851,7 +1851,11 @@ static int32_t handle_hc_nak_intr(dwc_ot
|
||||
* transfers in DMA mode for the sole purpose of
|
||||
* resetting the error count after a transaction error
|
||||
* occurs. The core will continue transferring data.
|
||||
+ * Disable other interrupts unmasked for the same
|
||||
+ * reason.
|
||||
*/
|
||||
+ disable_hc_int(hc_regs, datatglerr);
|
||||
+ disable_hc_int(hc_regs, ack);
|
||||
qtd->error_count = 0;
|
||||
goto handle_nak_done;
|
||||
}
|
||||
@@ -1963,6 +1967,15 @@ static int32_t handle_hc_ack_intr(dwc_ot
|
||||
halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_ACK);
|
||||
}
|
||||
} else {
|
||||
+ /*
|
||||
+ * An unmasked ACK on a non-split DMA transaction is
|
||||
+ * for the sole purpose of resetting error counts. Disable other
|
||||
+ * interrupts unmasked for the same reason.
|
||||
+ */
|
||||
+ if(hcd->core_if->dma_enable) {
|
||||
+ disable_hc_int(hc_regs, datatglerr);
|
||||
+ disable_hc_int(hc_regs, nak);
|
||||
+ }
|
||||
qtd->error_count = 0;
|
||||
|
||||
if (hc->qh->ping_state) {
|
||||
@@ -2328,6 +2341,14 @@ static int32_t handle_hc_datatglerr_intr
|
||||
qtd->urb, qtd, DWC_OTG_HC_XFER_XACT_ERR);
|
||||
halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_XACT_ERR);
|
||||
} else if (hc->ep_is_in) {
|
||||
+ /* An unmasked data toggle error on a non-split DMA transaction is
|
||||
+ * for the sole purpose of resetting error counts. Disable other
|
||||
+ * interrupts unmasked for the same reason.
|
||||
+ */
|
||||
+ if(hcd->core_if->dma_enable) {
|
||||
+ disable_hc_int(hc_regs, ack);
|
||||
+ disable_hc_int(hc_regs, nak);
|
||||
+ }
|
||||
qtd->error_count = 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
From 4d44d8447b13ded9c6931583938183c76b1846ed Mon Sep 17 00:00:00 2001
|
||||
From: P33M <P33M@github.com>
|
||||
Date: Sat, 13 Jul 2013 21:48:41 +0100
|
||||
Subject: [PATCH 079/174] dwc_otg: fiq: prevent FIQ thrash and incorrect state
|
||||
passing to IRQ
|
||||
|
||||
In the case of a transaction to a device that had previously aborted
|
||||
due to an error, several interrupts are enabled to reset the error
|
||||
count when a device responds. This has the side-effect of making the
|
||||
FIQ thrash because the hardware will generate multiple instances of
|
||||
a NAK on an IN bulk/interrupt endpoint and multiple instances of ACK
|
||||
on an OUT bulk/interrupt endpoint. Make the FIQ mask and clear the
|
||||
associated interrupts.
|
||||
|
||||
Additionally, on non-split transactions make sure that only unmasked
|
||||
interrupts are cleared. This caused a hard-to-trigger but serious
|
||||
race condition when you had the combination of an endpoint awaiting
|
||||
error recovery and a transaction completed on an endpoint - due to
|
||||
the sequencing and timing of interrupts generated by the dwc_otg core,
|
||||
it was possible to confuse the IRQ handler.
|
||||
---
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 21 +++++++++++++++++++++
|
||||
1 file changed, 21 insertions(+)
|
||||
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
|
||||
@@ -324,6 +324,27 @@ int fiq_hcintr_handle(int channel, hfnum
|
||||
}
|
||||
}
|
||||
}
|
||||
+ else
|
||||
+ {
|
||||
+ /*
|
||||
+ * If we have any of NAK, ACK, Datatlgerr active on a
|
||||
+ * non-split channel, the sole reason is to reset error
|
||||
+ * counts for a previously broken transaction. The FIQ
|
||||
+ * will thrash on NAK IN and ACK OUT in particular so
|
||||
+ * handle it "once" and allow the IRQ to do the rest.
|
||||
+ */
|
||||
+ hcint.d32 &= hcintmsk.d32;
|
||||
+ if(hcint.b.nak)
|
||||
+ {
|
||||
+ hcintmsk.b.nak = 0;
|
||||
+ FIQ_WRITE((dwc_regs_base + 0x500 + (channel * 0x20) + 0xc), hcintmsk.d32);
|
||||
+ }
|
||||
+ if (hcint.b.ack)
|
||||
+ {
|
||||
+ hcintmsk.b.ack = 0;
|
||||
+ FIQ_WRITE((dwc_regs_base + 0x500 + (channel * 0x20) + 0xc), hcintmsk.d32);
|
||||
+ }
|
||||
+ }
|
||||
|
||||
// Clear the interrupt, this will also clear the HAINT bit
|
||||
FIQ_WRITE((dwc_regs_base + 0x500 + (channel * 0x20) + 0x8), hcint.d32);
|
|
@ -0,0 +1,62 @@
|
|||
From f7785b067f07e444934fe0e6c31fff36f5863079 Mon Sep 17 00:00:00 2001
|
||||
From: Gordon Hollingworth <gordon@holliweb.co.uk>
|
||||
Date: Mon, 8 Jul 2013 04:12:19 +0100
|
||||
Subject: [PATCH 080/174] Fix function tracing
|
||||
|
||||
---
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 12 ++++++------
|
||||
1 file changed, 6 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
|
||||
@@ -77,7 +77,7 @@ int queued_port[MAX_EPS_CHANNELS];
|
||||
#ifdef FIQ_DEBUG
|
||||
char buffer[1000*16];
|
||||
int wptr;
|
||||
-void _fiq_print(FIQDBG_T dbg_lvl, char *fmt, ...)
|
||||
+void notrace _fiq_print(FIQDBG_T dbg_lvl, char *fmt, ...)
|
||||
{
|
||||
FIQDBG_T dbg_lvl_req = FIQDBG_PORTHUB;
|
||||
va_list args;
|
||||
@@ -101,7 +101,7 @@ void _fiq_print(FIQDBG_T dbg_lvl, char *
|
||||
}
|
||||
#endif
|
||||
|
||||
-void fiq_queue_request(int channel, int odd_frame)
|
||||
+void notrace fiq_queue_request(int channel, int odd_frame)
|
||||
{
|
||||
hcchar_data_t hcchar = { .d32 = FIQ_READ(dwc_regs_base + 0x500 + (channel * 0x20) + 0x0) };
|
||||
hcsplt_data_t hcsplt = { .d32 = FIQ_READ(dwc_regs_base + 0x500 + (channel * 0x20) + 0x4) };
|
||||
@@ -147,7 +147,7 @@ static int last_sof = -1;
|
||||
*/
|
||||
int diff;
|
||||
|
||||
-int fiq_sof_handle(hfnum_data_t hfnum)
|
||||
+int notrace fiq_sof_handle(hfnum_data_t hfnum)
|
||||
{
|
||||
int handled = 0;
|
||||
int i;
|
||||
@@ -206,12 +206,12 @@ int fiq_sof_handle(hfnum_data_t hfnum)
|
||||
return handled;
|
||||
}
|
||||
|
||||
-int port_id(hcsplt_data_t hcsplt)
|
||||
+int notrace port_id(hcsplt_data_t hcsplt)
|
||||
{
|
||||
return hcsplt.b.prtaddr + (hcsplt.b.hubaddr << 8);
|
||||
}
|
||||
|
||||
-int fiq_hcintr_handle(int channel, hfnum_data_t hfnum)
|
||||
+int notrace fiq_hcintr_handle(int channel, hfnum_data_t hfnum)
|
||||
{
|
||||
hcchar_data_t hcchar = { .d32 = FIQ_READ(dwc_regs_base + 0x500 + (channel * 0x20) + 0x0) };
|
||||
hcsplt_data_t hcsplt = { .d32 = FIQ_READ(dwc_regs_base + 0x500 + (channel * 0x20) + 0x4) };
|
||||
@@ -361,7 +361,7 @@ gintmsk_data_t gintmsk;
|
||||
gintsts_data_t triggered, handled, keep;
|
||||
hfnum_data_t hfnum;
|
||||
|
||||
-void __attribute__ ((naked)) dwc_otg_hcd_handle_fiq(void)
|
||||
+void __attribute__ ((naked)) notrace dwc_otg_hcd_handle_fiq(void)
|
||||
{
|
||||
|
||||
/* entry takes care to store registers we will be treading on here */
|
|
@ -0,0 +1,88 @@
|
|||
From a7ae411621bcf80fcb2f920084183d98adb6213b Mon Sep 17 00:00:00 2001
|
||||
From: P33M <P33M@github.com>
|
||||
Date: Thu, 18 Jul 2013 16:32:41 +0100
|
||||
Subject: [PATCH 081/174] dwc_otg: whitespace cleanup in dwc_otg_urb_enqueue
|
||||
|
||||
---
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 59 ++++++++++++++--------------
|
||||
1 file changed, 29 insertions(+), 30 deletions(-)
|
||||
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
|
||||
@@ -733,10 +733,10 @@ static int dwc_otg_urb_enqueue(struct us
|
||||
if(dwc_otg_urb == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
- urb->hcpriv = dwc_otg_urb;
|
||||
- if (!dwc_otg_urb && urb->number_of_packets)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
+ urb->hcpriv = dwc_otg_urb;
|
||||
+ if (!dwc_otg_urb && urb->number_of_packets)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
dwc_otg_hcd_urb_set_pipeinfo(dwc_otg_urb, usb_pipedevice(urb->pipe),
|
||||
usb_pipeendpoint(urb->pipe), ep_type,
|
||||
usb_pipein(urb->pipe),
|
||||
@@ -776,36 +776,35 @@ static int dwc_otg_urb_enqueue(struct us
|
||||
}
|
||||
|
||||
#if USB_URB_EP_LINKING
|
||||
- DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &irqflags);
|
||||
+ DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &irqflags);
|
||||
retval = usb_hcd_link_urb_to_ep(hcd, urb);
|
||||
- DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, irqflags);
|
||||
- if (0 == retval)
|
||||
+ DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, irqflags);
|
||||
+ if (0 == retval)
|
||||
#endif
|
||||
- {
|
||||
- retval = dwc_otg_hcd_urb_enqueue(dwc_otg_hcd, dwc_otg_urb,
|
||||
- /*(dwc_otg_qh_t **)*/
|
||||
- ref_ep_hcpriv,
|
||||
- mem_flags == GFP_ATOMIC ? 1 : 0);
|
||||
- if (0 == retval) {
|
||||
- if (alloc_bandwidth) {
|
||||
- allocate_bus_bandwidth(hcd,
|
||||
- dwc_otg_hcd_get_ep_bandwidth(
|
||||
- dwc_otg_hcd, *ref_ep_hcpriv),
|
||||
- urb);
|
||||
- }
|
||||
- } else {
|
||||
+ {
|
||||
+ retval = dwc_otg_hcd_urb_enqueue(dwc_otg_hcd, dwc_otg_urb,
|
||||
+ /*(dwc_otg_qh_t **)*/
|
||||
+ ref_ep_hcpriv,
|
||||
+ mem_flags == GFP_ATOMIC ? 1 : 0);
|
||||
+ if (0 == retval) {
|
||||
+ if (alloc_bandwidth) {
|
||||
+ allocate_bus_bandwidth(hcd,
|
||||
+ dwc_otg_hcd_get_ep_bandwidth(
|
||||
+ dwc_otg_hcd, *ref_ep_hcpriv),
|
||||
+ urb);
|
||||
+ }
|
||||
+ } else {
|
||||
#if USB_URB_EP_LINKING
|
||||
- dwc_irqflags_t irqflags;
|
||||
- DWC_DEBUGPL(DBG_HCD, "DWC OTG dwc_otg_hcd_urb_enqueue failed rc %d\n", retval);
|
||||
- DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &irqflags);
|
||||
- usb_hcd_unlink_urb_from_ep(hcd, urb);
|
||||
- DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, irqflags);
|
||||
+ dwc_irqflags_t irqflags;
|
||||
+ DWC_DEBUGPL(DBG_HCD, "DWC OTG dwc_otg_hcd_urb_enqueue failed rc %d\n", retval);
|
||||
+ DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &irqflags);
|
||||
+ usb_hcd_unlink_urb_from_ep(hcd, urb);
|
||||
+ DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, irqflags);
|
||||
#endif
|
||||
- if (retval == -DWC_E_NO_DEVICE) {
|
||||
- retval = -ENODEV;
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
+ if (retval == -DWC_E_NO_DEVICE)
|
||||
+ retval = -ENODEV;
|
||||
+ }
|
||||
+ }
|
||||
return retval;
|
||||
}
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
From dc570a70493daf0ec548ff57f1a1a9fb31caccb7 Mon Sep 17 00:00:00 2001
|
||||
From: P33M <P33M@github.com>
|
||||
Date: Thu, 18 Jul 2013 17:07:26 +0100
|
||||
Subject: [PATCH 082/174] dwc_otg: prevent OOPSes during device disconnects
|
||||
|
||||
The dwc_otg_urb_enqueue function is thread-unsafe. In particular the
|
||||
access of urb->hcpriv, usb_hcd_link_urb_to_ep, dwc_otg_urb->qtd and
|
||||
friends does not occur within a critical section and so if a device
|
||||
was unplugged during activity there was a high chance that the
|
||||
usbcore hub_thread would try to disable the endpoint with partially-
|
||||
formed entries in the URB queue. This would result in BUG() or null
|
||||
pointer dereferences.
|
||||
|
||||
Fix so that access of urb->hcpriv, enqueuing to the hardware and
|
||||
adding to usbcore endpoint URB lists is contained within a single
|
||||
critical section.
|
||||
---
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 3 ---
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 14 +++++---------
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 6 +-----
|
||||
3 files changed, 6 insertions(+), 17 deletions(-)
|
||||
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
|
||||
@@ -464,7 +464,6 @@ int dwc_otg_hcd_urb_enqueue(dwc_otg_hcd_
|
||||
dwc_otg_hcd_urb_t * dwc_otg_urb, void **ep_handle,
|
||||
int atomic_alloc)
|
||||
{
|
||||
- dwc_irqflags_t flags;
|
||||
int retval = 0;
|
||||
uint8_t needs_scheduling = 0;
|
||||
dwc_otg_transaction_type_e tr_type;
|
||||
@@ -515,12 +514,10 @@ int dwc_otg_hcd_urb_enqueue(dwc_otg_hcd_
|
||||
}
|
||||
|
||||
if(needs_scheduling) {
|
||||
- DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags);
|
||||
tr_type = dwc_otg_hcd_select_transactions(hcd);
|
||||
if (tr_type != DWC_OTG_TRANSACTION_NONE) {
|
||||
dwc_otg_hcd_queue_transactions(hcd, tr_type);
|
||||
}
|
||||
- DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
|
||||
@@ -679,9 +679,7 @@ static int dwc_otg_urb_enqueue(struct us
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
|
||||
struct usb_host_endpoint *ep = urb->ep;
|
||||
#endif
|
||||
-#if USB_URB_EP_LINKING
|
||||
dwc_irqflags_t irqflags;
|
||||
-#endif
|
||||
void **ref_ep_hcpriv = &ep->hcpriv;
|
||||
dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
|
||||
dwc_otg_hcd_urb_t *dwc_otg_urb;
|
||||
@@ -733,7 +731,6 @@ static int dwc_otg_urb_enqueue(struct us
|
||||
if(dwc_otg_urb == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
- urb->hcpriv = dwc_otg_urb;
|
||||
if (!dwc_otg_urb && urb->number_of_packets)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -775,10 +772,10 @@ static int dwc_otg_urb_enqueue(struct us
|
||||
iso_frame_desc[i].length);
|
||||
}
|
||||
|
||||
-#if USB_URB_EP_LINKING
|
||||
DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &irqflags);
|
||||
+ urb->hcpriv = dwc_otg_urb;
|
||||
+#if USB_URB_EP_LINKING
|
||||
retval = usb_hcd_link_urb_to_ep(hcd, urb);
|
||||
- DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, irqflags);
|
||||
if (0 == retval)
|
||||
#endif
|
||||
{
|
||||
@@ -794,17 +791,16 @@ static int dwc_otg_urb_enqueue(struct us
|
||||
urb);
|
||||
}
|
||||
} else {
|
||||
-#if USB_URB_EP_LINKING
|
||||
- dwc_irqflags_t irqflags;
|
||||
DWC_DEBUGPL(DBG_HCD, "DWC OTG dwc_otg_hcd_urb_enqueue failed rc %d\n", retval);
|
||||
- DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &irqflags);
|
||||
+#if USB_URB_EP_LINKING
|
||||
usb_hcd_unlink_urb_from_ep(hcd, urb);
|
||||
- DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, irqflags);
|
||||
#endif
|
||||
+ urb->hcpriv = NULL;
|
||||
if (retval == -DWC_E_NO_DEVICE)
|
||||
retval = -ENODEV;
|
||||
}
|
||||
}
|
||||
+ DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, irqflags);
|
||||
return retval;
|
||||
}
|
||||
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c
|
||||
@@ -919,6 +919,7 @@ void dwc_otg_hcd_qtd_init(dwc_otg_qtd_t
|
||||
* QH to place the QTD into. If it does not find a QH, then it will create a
|
||||
* new QH. If the QH to which the QTD is added is not currently scheduled, it
|
||||
* is placed into the proper schedule based on its EP type.
|
||||
+ * HCD lock must be held and interrupts must be disabled on entry
|
||||
*
|
||||
* @param[in] qtd The QTD to add
|
||||
* @param[in] hcd The DWC HCD structure
|
||||
@@ -931,8 +932,6 @@ int dwc_otg_hcd_qtd_add(dwc_otg_qtd_t *
|
||||
dwc_otg_hcd_t * hcd, dwc_otg_qh_t ** qh, int atomic_alloc)
|
||||
{
|
||||
int retval = 0;
|
||||
- dwc_irqflags_t flags;
|
||||
-
|
||||
dwc_otg_hcd_urb_t *urb = qtd->urb;
|
||||
|
||||
/*
|
||||
@@ -946,15 +945,12 @@ int dwc_otg_hcd_qtd_add(dwc_otg_qtd_t *
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
- DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags);
|
||||
retval = dwc_otg_hcd_qh_add(hcd, *qh);
|
||||
if (retval == 0) {
|
||||
DWC_CIRCLEQ_INSERT_TAIL(&((*qh)->qtd_list), qtd,
|
||||
qtd_list_entry);
|
||||
qtd->qh = *qh;
|
||||
}
|
||||
- DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags);
|
||||
-
|
||||
done:
|
||||
|
||||
return retval;
|
|
@ -0,0 +1,83 @@
|
|||
From 3c3c5a15a17649092ecf4c128478b267676c3353 Mon Sep 17 00:00:00 2001
|
||||
From: P33M <P33M@github.com>
|
||||
Date: Mon, 22 Jul 2013 14:08:26 +0100
|
||||
Subject: [PATCH 083/174] dwc_otg: prevent BUG() in TT allocation if hub
|
||||
address is > 16
|
||||
|
||||
A fixed-size array is used to track TT allocation. This was
|
||||
previously set to 16 which caused a crash because
|
||||
dwc_otg_hcd_allocate_port would read past the end of the array.
|
||||
|
||||
This was hit if a hub was plugged in which enumerated as addr > 16,
|
||||
due to previous device resets or unplugs.
|
||||
|
||||
Also add #ifdef FIQ_DEBUG around hcd->hub_port_alloc[], which grows
|
||||
to a large size if 128 hub addresses are supported. This field is
|
||||
for debug only for tracking which frame an allocate happened in.
|
||||
---
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 7 ++++++-
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd.h | 6 ++++--
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 3 ++-
|
||||
3 files changed, 12 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
|
||||
@@ -983,7 +983,9 @@ int dwc_otg_hcd_init(dwc_otg_hcd_t * hcd
|
||||
hcd->periodic_qh_count = 0;
|
||||
|
||||
DWC_MEMSET(hcd->hub_port, 0, sizeof(hcd->hub_port));
|
||||
+#ifdef FIQ_DEBUG
|
||||
DWC_MEMSET(hcd->hub_port_alloc, -1, sizeof(hcd->hub_port_alloc));
|
||||
+#endif
|
||||
|
||||
out:
|
||||
return retval;
|
||||
@@ -1317,7 +1319,9 @@ int dwc_otg_hcd_allocate_port(dwc_otg_hc
|
||||
qh->skip_count = 0;
|
||||
hcd->hub_port[hub_addr] |= 1 << port_addr;
|
||||
fiq_print(FIQDBG_PORTHUB, "H%dP%d:A %d", hub_addr, port_addr, DWC_CIRCLEQ_FIRST(&qh->qtd_list)->urb->pipe_info.ep_num);
|
||||
+#ifdef FIQ_DEBUG
|
||||
hcd->hub_port_alloc[hub_addr * 16 + port_addr] = dwc_otg_hcd_get_frame_number(hcd);
|
||||
+#endif
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1331,8 +1335,9 @@ void dwc_otg_hcd_release_port(dwc_otg_hc
|
||||
hcd->fops->hub_info(hcd, DWC_CIRCLEQ_FIRST(&qh->qtd_list)->urb->priv, &hub_addr, &port_addr);
|
||||
|
||||
hcd->hub_port[hub_addr] &= ~(1 << port_addr);
|
||||
+#ifdef FIQ_DEBUG
|
||||
hcd->hub_port_alloc[hub_addr * 16 + port_addr] = -1;
|
||||
-
|
||||
+#endif
|
||||
fiq_print(FIQDBG_PORTHUB, "H%dP%d:RO%d", hub_addr, port_addr, DWC_CIRCLEQ_FIRST(&qh->qtd_list)->urb->pipe_info.ep_num);
|
||||
|
||||
}
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.h
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.h
|
||||
@@ -577,8 +577,10 @@ struct dwc_otg_hcd {
|
||||
uint32_t *frame_list;
|
||||
|
||||
/** Hub - Port assignment */
|
||||
- int hub_port[16];
|
||||
- int hub_port_alloc[256];
|
||||
+ int hub_port[128];
|
||||
+#ifdef FIQ_DEBUG
|
||||
+ int hub_port_alloc[2048];
|
||||
+#endif
|
||||
|
||||
/** Frame List DMA address */
|
||||
dma_addr_t frame_list_dma;
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
|
||||
@@ -1419,8 +1419,9 @@ cleanup:
|
||||
}
|
||||
|
||||
hcd->hub_port[hc->hub_addr] &= ~(1 << hc->port_addr);
|
||||
+#ifdef FIQ_DEBUG
|
||||
hcd->hub_port_alloc[hc->hub_addr * 16 + hc->port_addr] = -1;
|
||||
-
|
||||
+#endif
|
||||
fiq_print(FIQDBG_PORTHUB, "H%dP%d:RR%d", hc->hub_addr, hc->port_addr, endp);
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
From e2c9f557c5bff8c839704d0627d5dd108a0e14f2 Mon Sep 17 00:00:00 2001
|
||||
From: P33M <P33M@github.com>
|
||||
Date: Tue, 23 Jul 2013 14:15:32 +0100
|
||||
Subject: [PATCH 084/174] dwc_otg: make channel halts with unknown state less
|
||||
damaging
|
||||
|
||||
If the IRQ received a channel halt interrupt through the FIQ
|
||||
with no other bits set, the IRQ would not release the host
|
||||
channel and never complete the URB.
|
||||
|
||||
Add catchall handling to treat as a transaction error and retry.
|
||||
---
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 12 ++++++++++++
|
||||
1 file changed, 12 insertions(+)
|
||||
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
|
||||
@@ -2578,12 +2578,24 @@ static void handle_hc_chhltd_intr_dma(dw
|
||||
DWC_READ_REG32(&hcd->
|
||||
core_if->core_global_regs->
|
||||
gintsts));
|
||||
+ /* Failthrough: use 3-strikes rule */
|
||||
+ qtd->error_count++;
|
||||
+ dwc_otg_hcd_save_data_toggle(hc, hc_regs, qtd);
|
||||
+ update_urb_state_xfer_intr(hc, hc_regs,
|
||||
+ qtd->urb, qtd, DWC_OTG_HC_XFER_XACT_ERR);
|
||||
+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_XACT_ERR);
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
DWC_PRINTF("NYET/NAK/ACK/other in non-error case, 0x%08x\n",
|
||||
hcint.d32);
|
||||
+ /* Failthrough: use 3-strikes rule */
|
||||
+ qtd->error_count++;
|
||||
+ dwc_otg_hcd_save_data_toggle(hc, hc_regs, qtd);
|
||||
+ update_urb_state_xfer_intr(hc, hc_regs,
|
||||
+ qtd->urb, qtd, DWC_OTG_HC_XFER_XACT_ERR);
|
||||
+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_XACT_ERR);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
From 2b66f2f4f07ed87db0e241489d4e93881fe50a85 Mon Sep 17 00:00:00 2001
|
||||
From: P33M <P33M@github.com>
|
||||
Date: Tue, 30 Jul 2013 09:58:48 +0100
|
||||
Subject: [PATCH 085/174] dwc_otg: fiq_split: use TTs with more granularity
|
||||
|
||||
This fixes certain issues with split transaction scheduling.
|
||||
|
||||
- Isochronous multi-packet OUT transactions now hog the TT until
|
||||
they are completed - this prevents hubs aborting transactions
|
||||
if they get a periodic start-split out-of-order
|
||||
- Don't perform TT allocation on non-periodic endpoints - this
|
||||
allows simultaneous use of the TT's bulk/control and periodic
|
||||
transaction buffers
|
||||
|
||||
This commit will mainly affect USB audio playback.
|
||||
---
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 26 +++++++++++++-------------
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 20 ++++++++++++++++----
|
||||
2 files changed, 29 insertions(+), 17 deletions(-)
|
||||
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
|
||||
@@ -1356,6 +1356,7 @@ dwc_otg_transaction_type_e dwc_otg_hcd_s
|
||||
{
|
||||
dwc_list_link_t *qh_ptr;
|
||||
dwc_otg_qh_t *qh;
|
||||
+ dwc_otg_qtd_t *qtd;
|
||||
int num_channels;
|
||||
dwc_irqflags_t flags;
|
||||
dwc_spinlock_t *channel_lock = hcd->channel_lock;
|
||||
@@ -1379,11 +1380,18 @@ dwc_otg_transaction_type_e dwc_otg_hcd_s
|
||||
|
||||
qh = DWC_LIST_ENTRY(qh_ptr, dwc_otg_qh_t, qh_list_entry);
|
||||
|
||||
- if(qh->do_split && dwc_otg_hcd_allocate_port(hcd, qh))
|
||||
- {
|
||||
- qh_ptr = DWC_LIST_NEXT(qh_ptr);
|
||||
- g_next_sched_frame = dwc_frame_num_inc(dwc_otg_hcd_get_frame_number(hcd), 1);
|
||||
- continue;
|
||||
+ if(qh->do_split) {
|
||||
+ qtd = DWC_CIRCLEQ_FIRST(&qh->qtd_list);
|
||||
+ if(!(qh->ep_type == UE_ISOCHRONOUS &&
|
||||
+ (qtd->isoc_split_pos == DWC_HCSPLIT_XACTPOS_MID ||
|
||||
+ qtd->isoc_split_pos == DWC_HCSPLIT_XACTPOS_END))) {
|
||||
+ if(dwc_otg_hcd_allocate_port(hcd, qh))
|
||||
+ {
|
||||
+ qh_ptr = DWC_LIST_NEXT(qh_ptr);
|
||||
+ g_next_sched_frame = dwc_frame_num_inc(dwc_otg_hcd_get_frame_number(hcd), 1);
|
||||
+ continue;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
if (microframe_schedule) {
|
||||
@@ -1451,18 +1459,10 @@ dwc_otg_transaction_type_e dwc_otg_hcd_s
|
||||
}
|
||||
}
|
||||
|
||||
- if (qh->do_split && dwc_otg_hcd_allocate_port(hcd, qh))
|
||||
- {
|
||||
- g_next_sched_frame = dwc_frame_num_inc(dwc_otg_hcd_get_frame_number(hcd), 1);
|
||||
- qh_ptr = DWC_LIST_NEXT(qh_ptr);
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
if (microframe_schedule) {
|
||||
DWC_SPINLOCK_IRQSAVE(channel_lock, &flags);
|
||||
if (hcd->available_host_channels < 1) {
|
||||
DWC_SPINUNLOCK_IRQRESTORE(channel_lock, flags);
|
||||
- if(qh->do_split) dwc_otg_hcd_release_port(hcd, qh);
|
||||
break;
|
||||
}
|
||||
hcd->available_host_channels--;
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
|
||||
@@ -1328,10 +1328,20 @@ static void release_channel(dwc_otg_hcd_
|
||||
#ifdef FIQ_DEBUG
|
||||
int endp = qtd->urb ? qtd->urb->pipe_info.ep_num : 0;
|
||||
#endif
|
||||
+ int hog_port = 0;
|
||||
|
||||
DWC_DEBUGPL(DBG_HCDV, " %s: channel %d, halt_status %d, xfer_len %d\n",
|
||||
__func__, hc->hc_num, halt_status, hc->xfer_len);
|
||||
|
||||
+ if(fiq_split_enable && hc->do_split) {
|
||||
+ if(!hc->ep_is_in && hc->ep_type == UE_ISOCHRONOUS) {
|
||||
+ if(hc->xact_pos == DWC_HCSPLIT_XACTPOS_MID ||
|
||||
+ hc->xact_pos == DWC_HCSPLIT_XACTPOS_BEGIN) {
|
||||
+ hog_port = 1;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
switch (halt_status) {
|
||||
case DWC_OTG_HC_XFER_URB_COMPLETE:
|
||||
free_qtd = 1;
|
||||
@@ -1417,12 +1427,14 @@ cleanup:
|
||||
fiq_print(FIQDBG_ERR, "PRTNOTAL");
|
||||
//BUG();
|
||||
}
|
||||
-
|
||||
- hcd->hub_port[hc->hub_addr] &= ~(1 << hc->port_addr);
|
||||
+ if(!hog_port && (hc->ep_type == DWC_OTG_EP_TYPE_ISOC ||
|
||||
+ hc->ep_type == DWC_OTG_EP_TYPE_INTR)) {
|
||||
+ hcd->hub_port[hc->hub_addr] &= ~(1 << hc->port_addr);
|
||||
#ifdef FIQ_DEBUG
|
||||
- hcd->hub_port_alloc[hc->hub_addr * 16 + hc->port_addr] = -1;
|
||||
+ hcd->hub_port_alloc[hc->hub_addr * 16 + hc->port_addr] = -1;
|
||||
#endif
|
||||
- fiq_print(FIQDBG_PORTHUB, "H%dP%d:RR%d", hc->hub_addr, hc->port_addr, endp);
|
||||
+ fiq_print(FIQDBG_PORTHUB, "H%dP%d:RR%d", hc->hub_addr, hc->port_addr, endp);
|
||||
+ }
|
||||
}
|
||||
|
||||
/* Try to queue more transfers now that there's a free channel. */
|
|
@ -0,0 +1,26 @@
|
|||
From 445255441aa03cca3d1318d1e7ff58872c91c645 Mon Sep 17 00:00:00 2001
|
||||
From: P33M <P33M@github.com>
|
||||
Date: Fri, 2 Aug 2013 10:04:18 +0100
|
||||
Subject: [PATCH 086/174] dwc_otg: fix potential sleep while atomic during urb
|
||||
enqueue
|
||||
|
||||
Fixes a regression introduced with eb1b482a. Kmalloc called from
|
||||
dwc_otg_hcd_qtd_add / dwc_otg_hcd_qtd_create did not always have
|
||||
the GPF_ATOMIC flag set. Force this flag when inside the larger
|
||||
critical section.
|
||||
---
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
|
||||
@@ -781,8 +781,7 @@ static int dwc_otg_urb_enqueue(struct us
|
||||
{
|
||||
retval = dwc_otg_hcd_urb_enqueue(dwc_otg_hcd, dwc_otg_urb,
|
||||
/*(dwc_otg_qh_t **)*/
|
||||
- ref_ep_hcpriv,
|
||||
- mem_flags == GFP_ATOMIC ? 1 : 0);
|
||||
+ ref_ep_hcpriv, 1);
|
||||
if (0 == retval) {
|
||||
if (alloc_bandwidth) {
|
||||
allocate_bus_bandwidth(hcd,
|
|
@ -0,0 +1,26 @@
|
|||
From 635578168de091d59e7d1a837286cff86fb9badb Mon Sep 17 00:00:00 2001
|
||||
From: P33M <P33M@github.com>
|
||||
Date: Mon, 5 Aug 2013 11:42:12 +0100
|
||||
Subject: [PATCH 087/174] dwc_otg: make fiq_split_enable imply fiq_fix_enable
|
||||
|
||||
Failing to set up the FIQ correctly would result in
|
||||
"IRQ 32: nobody cared" errors in dmesg.
|
||||
---
|
||||
drivers/usb/host/dwc_otg/dwc_otg_driver.c | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_driver.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_driver.c
|
||||
@@ -1070,6 +1070,12 @@ static int __init dwc_otg_driver_init(vo
|
||||
int retval = 0;
|
||||
int error;
|
||||
struct device_driver *drv;
|
||||
+
|
||||
+ if(fiq_split_enable && !fiq_fix_enable) {
|
||||
+ printk(KERN_WARNING "dwc_otg: fiq_split_enable was set without fiq_fix_enable! Correcting.\n");
|
||||
+ fiq_fix_enable = 1;
|
||||
+ }
|
||||
+
|
||||
printk(KERN_INFO "%s: version %s (%s bus)\n", dwc_driver_name,
|
||||
DWC_DRIVER_VERSION,
|
||||
#ifdef LM_INTERFACE
|
|
@ -0,0 +1,151 @@
|
|||
From afde583fbb644cff07984f2b47f75c0410d72205 Mon Sep 17 00:00:00 2001
|
||||
From: P33M <P33M@github.com>
|
||||
Date: Mon, 5 Aug 2013 11:47:12 +0100
|
||||
Subject: [PATCH 088/174] dwc_otg: prevent crashes on host port disconnects
|
||||
|
||||
Fix several issues resulting in crashes or inconsistent state
|
||||
if a Model A root port was disconnected.
|
||||
|
||||
- Clean up queue heads properly in kill_urbs_in_qh_list by
|
||||
removing the empty QHs from the schedule lists
|
||||
- Set the halt status properly to prevent IRQ handlers from
|
||||
using freed memory
|
||||
- Add fiq_split related cleanup for saved registers
|
||||
- Make microframe scheduling reclaim host channels if
|
||||
active during a disconnect
|
||||
- Abort URBs with -ESHUTDOWN status response, informing
|
||||
device drivers so they respond in a more correct fashion
|
||||
and don't try to resubmit URBs
|
||||
- Prevent IRQ handlers from attempting to handle channel
|
||||
interrupts if the associated URB was dequeued (and the
|
||||
driver state was cleared)
|
||||
---
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 44 ++++++++++++++++++++++++----
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 7 +++++
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 3 ++
|
||||
3 files changed, 48 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
|
||||
@@ -59,6 +59,11 @@ static int last_sel_trans_num_avail_hc_a
|
||||
|
||||
extern int g_next_sched_frame, g_np_count, g_np_sent;
|
||||
|
||||
+extern haint_data_t haint_saved;
|
||||
+extern hcintmsk_data_t hcintmsk_saved[MAX_EPS_CHANNELS];
|
||||
+extern hcint_data_t hcint_saved[MAX_EPS_CHANNELS];
|
||||
+extern gintsts_data_t ginsts_saved;
|
||||
+
|
||||
dwc_otg_hcd_t *dwc_otg_hcd_alloc_hcd(void)
|
||||
{
|
||||
return DWC_ALLOC(sizeof(dwc_otg_hcd_t));
|
||||
@@ -168,31 +173,43 @@ static void del_timers(dwc_otg_hcd_t * h
|
||||
|
||||
/**
|
||||
* Processes all the URBs in a single list of QHs. Completes them with
|
||||
- * -ETIMEDOUT and frees the QTD.
|
||||
+ * -ESHUTDOWN and frees the QTD.
|
||||
*/
|
||||
static void kill_urbs_in_qh_list(dwc_otg_hcd_t * hcd, dwc_list_link_t * qh_list)
|
||||
{
|
||||
- dwc_list_link_t *qh_item;
|
||||
+ dwc_list_link_t *qh_item, *qh_tmp;
|
||||
dwc_otg_qh_t *qh;
|
||||
dwc_otg_qtd_t *qtd, *qtd_tmp;
|
||||
|
||||
- DWC_LIST_FOREACH(qh_item, qh_list) {
|
||||
+ DWC_LIST_FOREACH_SAFE(qh_item, qh_tmp, qh_list) {
|
||||
qh = DWC_LIST_ENTRY(qh_item, dwc_otg_qh_t, qh_list_entry);
|
||||
DWC_CIRCLEQ_FOREACH_SAFE(qtd, qtd_tmp,
|
||||
&qh->qtd_list, qtd_list_entry) {
|
||||
qtd = DWC_CIRCLEQ_FIRST(&qh->qtd_list);
|
||||
if (qtd->urb != NULL) {
|
||||
hcd->fops->complete(hcd, qtd->urb->priv,
|
||||
- qtd->urb, -DWC_E_TIMEOUT);
|
||||
+ qtd->urb, -DWC_E_SHUTDOWN);
|
||||
dwc_otg_hcd_qtd_remove_and_free(hcd, qtd, qh);
|
||||
}
|
||||
|
||||
}
|
||||
+ if(qh->channel) {
|
||||
+ /* Using hcchar.chen == 1 is not a reliable test.
|
||||
+ * It is possible that the channel has already halted
|
||||
+ * but not yet been through the IRQ handler.
|
||||
+ */
|
||||
+ dwc_otg_hc_halt(hcd->core_if, qh->channel,
|
||||
+ DWC_OTG_HC_XFER_URB_DEQUEUE);
|
||||
+ if(microframe_schedule)
|
||||
+ hcd->available_host_channels++;
|
||||
+ qh->channel = NULL;
|
||||
+ }
|
||||
+ dwc_otg_hcd_qh_remove(hcd, qh);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
- * Responds with an error status of ETIMEDOUT to all URBs in the non-periodic
|
||||
+ * Responds with an error status of ESHUTDOWN to all URBs in the non-periodic
|
||||
* and periodic schedules. The QTD associated with each URB is removed from
|
||||
* the schedule and freed. This function may be called when a disconnect is
|
||||
* detected or when the HCD is being stopped.
|
||||
@@ -278,7 +295,8 @@ static int32_t dwc_otg_hcd_disconnect_cb
|
||||
*/
|
||||
dwc_otg_hcd->flags.b.port_connect_status_change = 1;
|
||||
dwc_otg_hcd->flags.b.port_connect_status = 0;
|
||||
-
|
||||
+ if(fiq_fix_enable)
|
||||
+ local_fiq_disable();
|
||||
/*
|
||||
* Shutdown any transfers in process by clearing the Tx FIFO Empty
|
||||
* interrupt mask and status bits and disabling subsequent host
|
||||
@@ -374,8 +392,22 @@ static int32_t dwc_otg_hcd_disconnect_cb
|
||||
channel->qh = NULL;
|
||||
}
|
||||
}
|
||||
+ if(fiq_split_enable) {
|
||||
+ for(i=0; i < 128; i++) {
|
||||
+ dwc_otg_hcd->hub_port[i] = 0;
|
||||
+ }
|
||||
+ haint_saved.d32 = 0;
|
||||
+ for(i=0; i < MAX_EPS_CHANNELS; i++) {
|
||||
+ hcint_saved[i].d32 = 0;
|
||||
+ hcintmsk_saved[i].d32 = 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
}
|
||||
|
||||
+ if(fiq_fix_enable)
|
||||
+ local_fiq_enable();
|
||||
+
|
||||
if (dwc_otg_hcd->fops->disconnect) {
|
||||
dwc_otg_hcd->fops->disconnect(dwc_otg_hcd);
|
||||
}
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
|
||||
@@ -2660,6 +2660,13 @@ int32_t dwc_otg_hcd_handle_hc_n_intr(dwc
|
||||
|
||||
hc = dwc_otg_hcd->hc_ptr_array[num];
|
||||
hc_regs = dwc_otg_hcd->core_if->host_if->hc_regs[num];
|
||||
+ if(hc->halt_status == DWC_OTG_HC_XFER_URB_DEQUEUE) {
|
||||
+ /* We are responding to a channel disable. Driver
|
||||
+ * state is cleared - our qtd has gone away.
|
||||
+ */
|
||||
+ release_channel(dwc_otg_hcd, hc, NULL, hc->halt_status);
|
||||
+ return 1;
|
||||
+ }
|
||||
qtd = DWC_CIRCLEQ_FIRST(&hc->qh->qtd_list);
|
||||
|
||||
hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
|
||||
@@ -309,6 +309,9 @@ static int _complete(dwc_otg_hcd_t * hcd
|
||||
case -DWC_E_OVERFLOW:
|
||||
status = -EOVERFLOW;
|
||||
break;
|
||||
+ case -DWC_E_SHUTDOWN:
|
||||
+ status = -ESHUTDOWN;
|
||||
+ break;
|
||||
default:
|
||||
if (status) {
|
||||
DWC_PRINTF("Uknown urb status %d\n", status);
|
|
@ -0,0 +1,33 @@
|
|||
From 42ed35f8f9c76ff56afdda9b0d3add958936bea6 Mon Sep 17 00:00:00 2001
|
||||
From: P33M <P33M@github.com>
|
||||
Date: Mon, 5 Aug 2013 13:17:58 +0100
|
||||
Subject: [PATCH 089/174] dwc_otg: prevent leaking URBs during enqueue
|
||||
|
||||
A dwc_otg_urb would get leaked if the HCD enqueue function
|
||||
failed for any reason. Free the URB at the appropriate points.
|
||||
---
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
|
||||
@@ -797,11 +797,19 @@ static int dwc_otg_urb_enqueue(struct us
|
||||
#if USB_URB_EP_LINKING
|
||||
usb_hcd_unlink_urb_from_ep(hcd, urb);
|
||||
#endif
|
||||
+ DWC_FREE(dwc_otg_urb);
|
||||
urb->hcpriv = NULL;
|
||||
if (retval == -DWC_E_NO_DEVICE)
|
||||
retval = -ENODEV;
|
||||
}
|
||||
}
|
||||
+#if USB_URB_EP_LINKING
|
||||
+ else
|
||||
+ {
|
||||
+ DWC_FREE(dwc_otg_urb);
|
||||
+ urb->hcpriv = NULL;
|
||||
+ }
|
||||
+#endif
|
||||
DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, irqflags);
|
||||
return retval;
|
||||
}
|
|
@ -1,656 +0,0 @@
|
|||
--- a/drivers/spi/Kconfig
|
||||
+++ b/drivers/spi/Kconfig
|
||||
@@ -86,6 +86,14 @@ config SPI_BCM2835
|
||||
is for the regular SPI controller. Slave mode operation is not also
|
||||
not supported.
|
||||
|
||||
+config SPI_BCM2708
|
||||
+ tristate "BCM2708 SPI controller driver (SPI0)"
|
||||
+ depends on MACH_BCM2708
|
||||
+ help
|
||||
+ This selects a driver for the Broadcom BCM2708 SPI master (SPI0). This
|
||||
+ driver is not compatible with the "Universal SPI Master" or the SPI slave
|
||||
+ device.
|
||||
+
|
||||
config SPI_BFIN5XX
|
||||
tristate "SPI controller driver for ADI Blackfin5xx"
|
||||
depends on BLACKFIN
|
||||
--- a/drivers/spi/Makefile
|
||||
+++ b/drivers/spi/Makefile
|
||||
@@ -17,6 +17,7 @@ obj-$(CONFIG_SPI_AU1550) += spi-au1550.
|
||||
obj-$(CONFIG_SPI_BCM2835) += spi-bcm2835.o
|
||||
obj-$(CONFIG_SPI_BCM63XX) += spi-bcm63xx.o
|
||||
obj-$(CONFIG_SPI_BFIN5XX) += spi-bfin5xx.o
|
||||
+obj-$(CONFIG_SPI_BCM2708) += spi-bcm2708.o
|
||||
obj-$(CONFIG_SPI_BFIN_SPORT) += spi-bfin-sport.o
|
||||
obj-$(CONFIG_SPI_BITBANG) += spi-bitbang.o
|
||||
obj-$(CONFIG_SPI_BUTTERFLY) += spi-butterfly.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/spi/spi-bcm2708.c
|
||||
@@ -0,0 +1,626 @@
|
||||
+/*
|
||||
+ * Driver for Broadcom BCM2708 SPI Controllers
|
||||
+ *
|
||||
+ * Copyright (C) 2012 Chris Boot
|
||||
+ *
|
||||
+ * This driver is inspired by:
|
||||
+ * spi-ath79.c, Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
|
||||
+ * spi-atmel.c, Copyright (C) 2006 Atmel Corporation
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation; either version 2 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/spinlock.h>
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/spi/spi.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/log2.h>
|
||||
+#include <linux/sched.h>
|
||||
+#include <linux/wait.h>
|
||||
+
|
||||
+/* SPI register offsets */
|
||||
+#define SPI_CS 0x00
|
||||
+#define SPI_FIFO 0x04
|
||||
+#define SPI_CLK 0x08
|
||||
+#define SPI_DLEN 0x0c
|
||||
+#define SPI_LTOH 0x10
|
||||
+#define SPI_DC 0x14
|
||||
+
|
||||
+/* Bitfields in CS */
|
||||
+#define SPI_CS_LEN_LONG 0x02000000
|
||||
+#define SPI_CS_DMA_LEN 0x01000000
|
||||
+#define SPI_CS_CSPOL2 0x00800000
|
||||
+#define SPI_CS_CSPOL1 0x00400000
|
||||
+#define SPI_CS_CSPOL0 0x00200000
|
||||
+#define SPI_CS_RXF 0x00100000
|
||||
+#define SPI_CS_RXR 0x00080000
|
||||
+#define SPI_CS_TXD 0x00040000
|
||||
+#define SPI_CS_RXD 0x00020000
|
||||
+#define SPI_CS_DONE 0x00010000
|
||||
+#define SPI_CS_LEN 0x00002000
|
||||
+#define SPI_CS_REN 0x00001000
|
||||
+#define SPI_CS_ADCS 0x00000800
|
||||
+#define SPI_CS_INTR 0x00000400
|
||||
+#define SPI_CS_INTD 0x00000200
|
||||
+#define SPI_CS_DMAEN 0x00000100
|
||||
+#define SPI_CS_TA 0x00000080
|
||||
+#define SPI_CS_CSPOL 0x00000040
|
||||
+#define SPI_CS_CLEAR_RX 0x00000020
|
||||
+#define SPI_CS_CLEAR_TX 0x00000010
|
||||
+#define SPI_CS_CPOL 0x00000008
|
||||
+#define SPI_CS_CPHA 0x00000004
|
||||
+#define SPI_CS_CS_10 0x00000002
|
||||
+#define SPI_CS_CS_01 0x00000001
|
||||
+
|
||||
+#define SPI_TIMEOUT_MS 150
|
||||
+
|
||||
+#define DRV_NAME "bcm2708_spi"
|
||||
+
|
||||
+struct bcm2708_spi {
|
||||
+ spinlock_t lock;
|
||||
+ void __iomem *base;
|
||||
+ int irq;
|
||||
+ struct clk *clk;
|
||||
+ bool stopping;
|
||||
+
|
||||
+ struct list_head queue;
|
||||
+ struct workqueue_struct *workq;
|
||||
+ struct work_struct work;
|
||||
+ struct completion done;
|
||||
+
|
||||
+ const u8 *tx_buf;
|
||||
+ u8 *rx_buf;
|
||||
+ int len;
|
||||
+};
|
||||
+
|
||||
+struct bcm2708_spi_state {
|
||||
+ u32 cs;
|
||||
+ u16 cdiv;
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * This function sets the ALT mode on the SPI pins so that we can use them with
|
||||
+ * the SPI hardware.
|
||||
+ *
|
||||
+ * FIXME: This is a hack. Use pinmux / pinctrl.
|
||||
+ */
|
||||
+static void bcm2708_init_pinmode(void)
|
||||
+{
|
||||
+#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
|
||||
+#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))
|
||||
+
|
||||
+ int pin;
|
||||
+ u32 *gpio = ioremap(0x20200000, SZ_16K);
|
||||
+
|
||||
+ /* SPI is on GPIO 7..11 */
|
||||
+ for (pin = 7; pin <= 11; pin++) {
|
||||
+ INP_GPIO(pin); /* set mode to GPIO input first */
|
||||
+ SET_GPIO_ALT(pin, 0); /* set mode to ALT 0 */
|
||||
+ }
|
||||
+
|
||||
+ iounmap(gpio);
|
||||
+
|
||||
+#undef INP_GPIO
|
||||
+#undef SET_GPIO_ALT
|
||||
+}
|
||||
+
|
||||
+static inline u32 bcm2708_rd(struct bcm2708_spi *bs, unsigned reg)
|
||||
+{
|
||||
+ return readl(bs->base + reg);
|
||||
+}
|
||||
+
|
||||
+static inline void bcm2708_wr(struct bcm2708_spi *bs, unsigned reg, u32 val)
|
||||
+{
|
||||
+ writel(val, bs->base + reg);
|
||||
+}
|
||||
+
|
||||
+static inline void bcm2708_rd_fifo(struct bcm2708_spi *bs, int len)
|
||||
+{
|
||||
+ u8 byte;
|
||||
+
|
||||
+ while (len--) {
|
||||
+ byte = bcm2708_rd(bs, SPI_FIFO);
|
||||
+ if (bs->rx_buf)
|
||||
+ *bs->rx_buf++ = byte;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static inline void bcm2708_wr_fifo(struct bcm2708_spi *bs, int len)
|
||||
+{
|
||||
+ u8 byte;
|
||||
+ u16 val;
|
||||
+
|
||||
+ if (len > bs->len)
|
||||
+ len = bs->len;
|
||||
+
|
||||
+ if (unlikely(bcm2708_rd(bs, SPI_CS) & SPI_CS_LEN)) {
|
||||
+ /* LoSSI mode */
|
||||
+ if (unlikely(len % 2)) {
|
||||
+ printk(KERN_ERR"bcm2708_wr_fifo: length must be even, skipping.\n");
|
||||
+ bs->len = 0;
|
||||
+ return;
|
||||
+ }
|
||||
+ while (len) {
|
||||
+ if (bs->tx_buf) {
|
||||
+ val = *(const u16 *)bs->tx_buf;
|
||||
+ bs->tx_buf += 2;
|
||||
+ } else
|
||||
+ val = 0;
|
||||
+ bcm2708_wr(bs, SPI_FIFO, val);
|
||||
+ bs->len -= 2;
|
||||
+ len -= 2;
|
||||
+ }
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ while (len--) {
|
||||
+ byte = bs->tx_buf ? *bs->tx_buf++ : 0;
|
||||
+ bcm2708_wr(bs, SPI_FIFO, byte);
|
||||
+ bs->len--;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static irqreturn_t bcm2708_spi_interrupt(int irq, void *dev_id)
|
||||
+{
|
||||
+ struct spi_master *master = dev_id;
|
||||
+ struct bcm2708_spi *bs = spi_master_get_devdata(master);
|
||||
+ u32 cs;
|
||||
+
|
||||
+ spin_lock(&bs->lock);
|
||||
+
|
||||
+ cs = bcm2708_rd(bs, SPI_CS);
|
||||
+
|
||||
+ if (cs & SPI_CS_DONE) {
|
||||
+ if (bs->len) { /* first interrupt in a transfer */
|
||||
+ /* fill the TX fifo with up to 16 bytes */
|
||||
+ bcm2708_wr_fifo(bs, 16);
|
||||
+ } else { /* transfer complete */
|
||||
+ /* disable interrupts */
|
||||
+ cs &= ~(SPI_CS_INTR | SPI_CS_INTD);
|
||||
+ bcm2708_wr(bs, SPI_CS, cs);
|
||||
+
|
||||
+ /* drain RX FIFO */
|
||||
+ while (cs & SPI_CS_RXD) {
|
||||
+ bcm2708_rd_fifo(bs, 1);
|
||||
+ cs = bcm2708_rd(bs, SPI_CS);
|
||||
+ }
|
||||
+
|
||||
+ /* wake up our bh */
|
||||
+ complete(&bs->done);
|
||||
+ }
|
||||
+ } else if (cs & SPI_CS_RXR) {
|
||||
+ /* read 12 bytes of data */
|
||||
+ bcm2708_rd_fifo(bs, 12);
|
||||
+
|
||||
+ /* write up to 12 bytes */
|
||||
+ bcm2708_wr_fifo(bs, 12);
|
||||
+ }
|
||||
+
|
||||
+ spin_unlock(&bs->lock);
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static int bcm2708_setup_state(struct spi_master *master,
|
||||
+ struct device *dev, struct bcm2708_spi_state *state,
|
||||
+ u32 hz, u8 csel, u8 mode, u8 bpw)
|
||||
+{
|
||||
+ struct bcm2708_spi *bs = spi_master_get_devdata(master);
|
||||
+ int cdiv;
|
||||
+ unsigned long bus_hz;
|
||||
+ u32 cs = 0;
|
||||
+
|
||||
+ bus_hz = clk_get_rate(bs->clk);
|
||||
+
|
||||
+ if (hz >= bus_hz) {
|
||||
+ cdiv = 2; /* bus_hz / 2 is as fast as we can go */
|
||||
+ } else if (hz) {
|
||||
+ cdiv = DIV_ROUND_UP(bus_hz, hz);
|
||||
+
|
||||
+ /* CDIV must be a power of 2, so round up */
|
||||
+ cdiv = roundup_pow_of_two(cdiv);
|
||||
+
|
||||
+ if (cdiv > 65536) {
|
||||
+ dev_dbg(dev,
|
||||
+ "setup: %d Hz too slow, cdiv %u; min %ld Hz\n",
|
||||
+ hz, cdiv, bus_hz / 65536);
|
||||
+ return -EINVAL;
|
||||
+ } else if (cdiv == 65536) {
|
||||
+ cdiv = 0;
|
||||
+ } else if (cdiv == 1) {
|
||||
+ cdiv = 2; /* 1 gets rounded down to 0; == 65536 */
|
||||
+ }
|
||||
+ } else {
|
||||
+ cdiv = 0;
|
||||
+ }
|
||||
+
|
||||
+ switch (bpw) {
|
||||
+ case 8:
|
||||
+ break;
|
||||
+ case 9:
|
||||
+ /* Reading in LoSSI mode is a special case. See 'BCM2835 ARM Peripherals' datasheet */
|
||||
+ cs |= SPI_CS_LEN;
|
||||
+ break;
|
||||
+ default:
|
||||
+ dev_dbg(dev, "setup: invalid bits_per_word %u (must be 8 or 9)\n",
|
||||
+ bpw);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (mode & SPI_CPOL)
|
||||
+ cs |= SPI_CS_CPOL;
|
||||
+ if (mode & SPI_CPHA)
|
||||
+ cs |= SPI_CS_CPHA;
|
||||
+
|
||||
+ if (!(mode & SPI_NO_CS)) {
|
||||
+ if (mode & SPI_CS_HIGH) {
|
||||
+ cs |= SPI_CS_CSPOL;
|
||||
+ cs |= SPI_CS_CSPOL0 << csel;
|
||||
+ }
|
||||
+
|
||||
+ cs |= csel;
|
||||
+ } else {
|
||||
+ cs |= SPI_CS_CS_10 | SPI_CS_CS_01;
|
||||
+ }
|
||||
+
|
||||
+ if (state) {
|
||||
+ state->cs = cs;
|
||||
+ state->cdiv = cdiv;
|
||||
+ dev_dbg(dev, "setup: want %d Hz; "
|
||||
+ "bus_hz=%lu / cdiv=%u == %lu Hz; "
|
||||
+ "mode %u: cs 0x%08X\n",
|
||||
+ hz, bus_hz, cdiv, bus_hz/cdiv, mode, cs);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int bcm2708_process_transfer(struct bcm2708_spi *bs,
|
||||
+ struct spi_message *msg, struct spi_transfer *xfer)
|
||||
+{
|
||||
+ struct spi_device *spi = msg->spi;
|
||||
+ struct bcm2708_spi_state state, *stp;
|
||||
+ int ret;
|
||||
+ u32 cs;
|
||||
+
|
||||
+ if (bs->stopping)
|
||||
+ return -ESHUTDOWN;
|
||||
+
|
||||
+ if (xfer->bits_per_word || xfer->speed_hz) {
|
||||
+ ret = bcm2708_setup_state(spi->master, &spi->dev, &state,
|
||||
+ xfer->speed_hz ? xfer->speed_hz : spi->max_speed_hz,
|
||||
+ spi->chip_select, spi->mode,
|
||||
+ xfer->bits_per_word ? xfer->bits_per_word :
|
||||
+ spi->bits_per_word);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ stp = &state;
|
||||
+ } else {
|
||||
+ stp = spi->controller_state;
|
||||
+ }
|
||||
+
|
||||
+ INIT_COMPLETION(bs->done);
|
||||
+ bs->tx_buf = xfer->tx_buf;
|
||||
+ bs->rx_buf = xfer->rx_buf;
|
||||
+ bs->len = xfer->len;
|
||||
+
|
||||
+ cs = stp->cs | SPI_CS_INTR | SPI_CS_INTD | SPI_CS_TA;
|
||||
+
|
||||
+ bcm2708_wr(bs, SPI_CLK, stp->cdiv);
|
||||
+ bcm2708_wr(bs, SPI_CS, cs);
|
||||
+
|
||||
+ ret = wait_for_completion_timeout(&bs->done,
|
||||
+ msecs_to_jiffies(SPI_TIMEOUT_MS));
|
||||
+ if (ret == 0) {
|
||||
+ dev_err(&spi->dev, "transfer timed out\n");
|
||||
+ return -ETIMEDOUT;
|
||||
+ }
|
||||
+
|
||||
+ if (xfer->delay_usecs)
|
||||
+ udelay(xfer->delay_usecs);
|
||||
+
|
||||
+ if (list_is_last(&xfer->transfer_list, &msg->transfers) ||
|
||||
+ xfer->cs_change) {
|
||||
+ /* clear TA and interrupt flags */
|
||||
+ bcm2708_wr(bs, SPI_CS, stp->cs);
|
||||
+ }
|
||||
+
|
||||
+ msg->actual_length += (xfer->len - bs->len);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void bcm2708_work(struct work_struct *work)
|
||||
+{
|
||||
+ struct bcm2708_spi *bs = container_of(work, struct bcm2708_spi, work);
|
||||
+ unsigned long flags;
|
||||
+ struct spi_message *msg;
|
||||
+ struct spi_transfer *xfer;
|
||||
+ int status = 0;
|
||||
+
|
||||
+ spin_lock_irqsave(&bs->lock, flags);
|
||||
+ while (!list_empty(&bs->queue)) {
|
||||
+ msg = list_first_entry(&bs->queue, struct spi_message, queue);
|
||||
+ list_del_init(&msg->queue);
|
||||
+ spin_unlock_irqrestore(&bs->lock, flags);
|
||||
+
|
||||
+ list_for_each_entry(xfer, &msg->transfers, transfer_list) {
|
||||
+ status = bcm2708_process_transfer(bs, msg, xfer);
|
||||
+ if (status)
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ msg->status = status;
|
||||
+ msg->complete(msg->context);
|
||||
+
|
||||
+ spin_lock_irqsave(&bs->lock, flags);
|
||||
+ }
|
||||
+ spin_unlock_irqrestore(&bs->lock, flags);
|
||||
+}
|
||||
+
|
||||
+static int bcm2708_spi_setup(struct spi_device *spi)
|
||||
+{
|
||||
+ struct bcm2708_spi *bs = spi_master_get_devdata(spi->master);
|
||||
+ struct bcm2708_spi_state *state;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (bs->stopping)
|
||||
+ return -ESHUTDOWN;
|
||||
+
|
||||
+ if (!(spi->mode & SPI_NO_CS) &&
|
||||
+ (spi->chip_select > spi->master->num_chipselect)) {
|
||||
+ dev_dbg(&spi->dev,
|
||||
+ "setup: invalid chipselect %u (%u defined)\n",
|
||||
+ spi->chip_select, spi->master->num_chipselect);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ state = spi->controller_state;
|
||||
+ if (!state) {
|
||||
+ state = kzalloc(sizeof(*state), GFP_KERNEL);
|
||||
+ if (!state)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ spi->controller_state = state;
|
||||
+ }
|
||||
+
|
||||
+ ret = bcm2708_setup_state(spi->master, &spi->dev, state,
|
||||
+ spi->max_speed_hz, spi->chip_select, spi->mode,
|
||||
+ spi->bits_per_word);
|
||||
+ if (ret < 0) {
|
||||
+ kfree(state);
|
||||
+ spi->controller_state = NULL;
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ dev_dbg(&spi->dev,
|
||||
+ "setup: cd %d: %d Hz, bpw %u, mode 0x%x -> CS=%08x CDIV=%04x\n",
|
||||
+ spi->chip_select, spi->max_speed_hz, spi->bits_per_word,
|
||||
+ spi->mode, state->cs, state->cdiv);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int bcm2708_spi_transfer(struct spi_device *spi, struct spi_message *msg)
|
||||
+{
|
||||
+ struct bcm2708_spi *bs = spi_master_get_devdata(spi->master);
|
||||
+ struct spi_transfer *xfer;
|
||||
+ int ret;
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ if (unlikely(list_empty(&msg->transfers)))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (bs->stopping)
|
||||
+ return -ESHUTDOWN;
|
||||
+
|
||||
+ list_for_each_entry(xfer, &msg->transfers, transfer_list) {
|
||||
+ if (!(xfer->tx_buf || xfer->rx_buf) && xfer->len) {
|
||||
+ dev_dbg(&spi->dev, "missing rx or tx buf\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (!xfer->bits_per_word || xfer->speed_hz)
|
||||
+ continue;
|
||||
+
|
||||
+ ret = bcm2708_setup_state(spi->master, &spi->dev, NULL,
|
||||
+ xfer->speed_hz ? xfer->speed_hz : spi->max_speed_hz,
|
||||
+ spi->chip_select, spi->mode,
|
||||
+ xfer->bits_per_word ? xfer->bits_per_word :
|
||||
+ spi->bits_per_word);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ msg->status = -EINPROGRESS;
|
||||
+ msg->actual_length = 0;
|
||||
+
|
||||
+ spin_lock_irqsave(&bs->lock, flags);
|
||||
+ list_add_tail(&msg->queue, &bs->queue);
|
||||
+ queue_work(bs->workq, &bs->work);
|
||||
+ spin_unlock_irqrestore(&bs->lock, flags);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void bcm2708_spi_cleanup(struct spi_device *spi)
|
||||
+{
|
||||
+ if (spi->controller_state) {
|
||||
+ kfree(spi->controller_state);
|
||||
+ spi->controller_state = NULL;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int bcm2708_spi_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct resource *regs;
|
||||
+ int irq, err = -ENOMEM;
|
||||
+ struct clk *clk;
|
||||
+ struct spi_master *master;
|
||||
+ struct bcm2708_spi *bs;
|
||||
+
|
||||
+ regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ if (!regs) {
|
||||
+ dev_err(&pdev->dev, "could not get IO memory\n");
|
||||
+ return -ENXIO;
|
||||
+ }
|
||||
+
|
||||
+ irq = platform_get_irq(pdev, 0);
|
||||
+ if (irq < 0) {
|
||||
+ dev_err(&pdev->dev, "could not get IRQ\n");
|
||||
+ return irq;
|
||||
+ }
|
||||
+
|
||||
+ clk = clk_get(&pdev->dev, NULL);
|
||||
+ if (IS_ERR(clk)) {
|
||||
+ dev_err(&pdev->dev, "could not find clk: %ld\n", PTR_ERR(clk));
|
||||
+ return PTR_ERR(clk);
|
||||
+ }
|
||||
+
|
||||
+ bcm2708_init_pinmode();
|
||||
+
|
||||
+ master = spi_alloc_master(&pdev->dev, sizeof(*bs));
|
||||
+ if (!master) {
|
||||
+ dev_err(&pdev->dev, "spi_alloc_master() failed\n");
|
||||
+ goto out_clk_put;
|
||||
+ }
|
||||
+
|
||||
+ /* the spi->mode bits understood by this driver: */
|
||||
+ master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_NO_CS;
|
||||
+
|
||||
+ master->bus_num = pdev->id;
|
||||
+ master->num_chipselect = 3;
|
||||
+ master->setup = bcm2708_spi_setup;
|
||||
+ master->transfer = bcm2708_spi_transfer;
|
||||
+ master->cleanup = bcm2708_spi_cleanup;
|
||||
+ platform_set_drvdata(pdev, master);
|
||||
+
|
||||
+ bs = spi_master_get_devdata(master);
|
||||
+
|
||||
+ spin_lock_init(&bs->lock);
|
||||
+ INIT_LIST_HEAD(&bs->queue);
|
||||
+ init_completion(&bs->done);
|
||||
+ INIT_WORK(&bs->work, bcm2708_work);
|
||||
+
|
||||
+ bs->base = ioremap(regs->start, resource_size(regs));
|
||||
+ if (!bs->base) {
|
||||
+ dev_err(&pdev->dev, "could not remap memory\n");
|
||||
+ goto out_master_put;
|
||||
+ }
|
||||
+
|
||||
+ bs->workq = create_singlethread_workqueue(dev_name(&pdev->dev));
|
||||
+ if (!bs->workq) {
|
||||
+ dev_err(&pdev->dev, "could not create workqueue\n");
|
||||
+ goto out_iounmap;
|
||||
+ }
|
||||
+
|
||||
+ bs->irq = irq;
|
||||
+ bs->clk = clk;
|
||||
+ bs->stopping = false;
|
||||
+
|
||||
+ err = request_irq(irq, bcm2708_spi_interrupt, 0, dev_name(&pdev->dev),
|
||||
+ master);
|
||||
+ if (err) {
|
||||
+ dev_err(&pdev->dev, "could not request IRQ: %d\n", err);
|
||||
+ goto out_workqueue;
|
||||
+ }
|
||||
+
|
||||
+ /* initialise the hardware */
|
||||
+ clk_enable(clk);
|
||||
+ bcm2708_wr(bs, SPI_CS, SPI_CS_REN | SPI_CS_CLEAR_RX | SPI_CS_CLEAR_TX);
|
||||
+
|
||||
+ err = spi_register_master(master);
|
||||
+ if (err) {
|
||||
+ dev_err(&pdev->dev, "could not register SPI master: %d\n", err);
|
||||
+ goto out_free_irq;
|
||||
+ }
|
||||
+
|
||||
+ dev_info(&pdev->dev, "SPI Controller at 0x%08lx (irq %d)\n",
|
||||
+ (unsigned long)regs->start, irq);
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+out_free_irq:
|
||||
+ free_irq(bs->irq, master);
|
||||
+out_workqueue:
|
||||
+ destroy_workqueue(bs->workq);
|
||||
+out_iounmap:
|
||||
+ iounmap(bs->base);
|
||||
+out_master_put:
|
||||
+ spi_master_put(master);
|
||||
+out_clk_put:
|
||||
+ clk_put(clk);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static int bcm2708_spi_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct spi_master *master = platform_get_drvdata(pdev);
|
||||
+ struct bcm2708_spi *bs = spi_master_get_devdata(master);
|
||||
+
|
||||
+ /* reset the hardware and block queue progress */
|
||||
+ spin_lock_irq(&bs->lock);
|
||||
+ bs->stopping = true;
|
||||
+ bcm2708_wr(bs, SPI_CS, SPI_CS_CLEAR_RX | SPI_CS_CLEAR_TX);
|
||||
+ spin_unlock_irq(&bs->lock);
|
||||
+
|
||||
+ flush_work_sync(&bs->work);
|
||||
+
|
||||
+ clk_disable(bs->clk);
|
||||
+ clk_put(bs->clk);
|
||||
+ free_irq(bs->irq, master);
|
||||
+ iounmap(bs->base);
|
||||
+
|
||||
+ spi_unregister_master(master);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver bcm2708_spi_driver = {
|
||||
+ .driver = {
|
||||
+ .name = DRV_NAME,
|
||||
+ .owner = THIS_MODULE,
|
||||
+ },
|
||||
+ .probe = bcm2708_spi_probe,
|
||||
+ .remove = bcm2708_spi_remove,
|
||||
+};
|
||||
+
|
||||
+
|
||||
+static int __init bcm2708_spi_init(void)
|
||||
+{
|
||||
+ return platform_driver_probe(&bcm2708_spi_driver, bcm2708_spi_probe);
|
||||
+}
|
||||
+module_init(bcm2708_spi_init);
|
||||
+
|
||||
+static void __exit bcm2708_spi_exit(void)
|
||||
+{
|
||||
+ platform_driver_unregister(&bcm2708_spi_driver);
|
||||
+}
|
||||
+module_exit(bcm2708_spi_exit);
|
||||
+
|
||||
+
|
||||
+//module_platform_driver(bcm2708_spi_driver);
|
||||
+
|
||||
+MODULE_DESCRIPTION("SPI controller driver for Broadcom BCM2708");
|
||||
+MODULE_AUTHOR("Chris Boot <bootc@bootc.net>");
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
+MODULE_ALIAS("platform:" DRV_NAME);
|
|
@ -0,0 +1,30 @@
|
|||
From 3c174c25ed6ef1108d0a0f8c106c074225d7194b Mon Sep 17 00:00:00 2001
|
||||
From: Fabio Estevam <festevam@gmail.com>
|
||||
Date: Fri, 16 Aug 2013 12:55:56 +0100
|
||||
Subject: [PATCH 091/174] ARM: 7819/1: fiq: Cast the first argument of
|
||||
flush_icache_range()
|
||||
|
||||
Commit 2ba85e7af4 (ARM: Fix FIQ code on VIVT CPUs) causes the following build warning:
|
||||
|
||||
arch/arm/kernel/fiq.c:92:3: warning: passing argument 1 of 'cpu_cache.coherent_kern_range' makes integer from pointer without a cast [enabled by default]
|
||||
|
||||
Cast it as '(unsigned long)base' to avoid the warning.
|
||||
|
||||
Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
|
||||
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
|
||||
---
|
||||
arch/arm/kernel/fiq.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/arch/arm/kernel/fiq.c
|
||||
+++ b/arch/arm/kernel/fiq.c
|
||||
@@ -89,7 +89,8 @@ void set_fiq_handler(void *start, unsign
|
||||
|
||||
memcpy(base + offset, start, length);
|
||||
if (!cache_is_vipt_nonaliasing())
|
||||
- flush_icache_range(base + offset, offset + length);
|
||||
+ flush_icache_range((unsigned long)base + offset, offset +
|
||||
+ length);
|
||||
flush_icache_range(0xffff0000 + offset, 0xffff0000 + offset + length);
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
From b735e5ba3039bbd89651b881705a6cb8d62882d6 Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Sat, 7 Sep 2013 19:07:33 +0100
|
||||
Subject: [PATCH 092/174] Support for cheap Ralink 3070 WiFi plug
|
||||
|
||||
See: https://github.com/raspberrypi/linux/pull/321
|
||||
---
|
||||
drivers/net/wireless/rt2x00/rt2800.h | 1 +
|
||||
drivers/net/wireless/rt2x00/rt2800lib.c | 6 ++++++
|
||||
2 files changed, 7 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/rt2x00/rt2800.h
|
||||
+++ b/drivers/net/wireless/rt2x00/rt2800.h
|
||||
@@ -70,6 +70,7 @@
|
||||
#define RF3322 0x000c
|
||||
#define RF3053 0x000d
|
||||
#define RF5592 0x000f
|
||||
+#define RF3070 0x3070
|
||||
#define RF3290 0x3290
|
||||
#define RF5360 0x5360
|
||||
#define RF5370 0x5370
|
||||
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
|
||||
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
|
||||
@@ -2599,6 +2599,7 @@ static void rt2800_config_channel(struct
|
||||
break;
|
||||
case RF5360:
|
||||
case RF5370:
|
||||
+ case RF3070:
|
||||
case RF5372:
|
||||
case RF5390:
|
||||
case RF5392:
|
||||
@@ -2615,6 +2616,7 @@ static void rt2800_config_channel(struct
|
||||
rt2x00_rf(rt2x00dev, RF3322) ||
|
||||
rt2x00_rf(rt2x00dev, RF5360) ||
|
||||
rt2x00_rf(rt2x00dev, RF5370) ||
|
||||
+ rt2x00_rf(rt2x00dev, RF3070) ||
|
||||
rt2x00_rf(rt2x00dev, RF5372) ||
|
||||
rt2x00_rf(rt2x00dev, RF5390) ||
|
||||
rt2x00_rf(rt2x00dev, RF5392)) {
|
||||
@@ -3206,6 +3208,7 @@ void rt2800_vco_calibration(struct rt2x0
|
||||
case RF3290:
|
||||
case RF5360:
|
||||
case RF5370:
|
||||
+ case RF3070:
|
||||
case RF5372:
|
||||
case RF5390:
|
||||
case RF5392:
|
||||
@@ -5524,6 +5527,7 @@ static int rt2800_init_eeprom(struct rt2
|
||||
case RF3322:
|
||||
case RF5360:
|
||||
case RF5370:
|
||||
+ case RF3070:
|
||||
case RF5372:
|
||||
case RF5390:
|
||||
case RF5392:
|
||||
@@ -5979,6 +5983,7 @@ static int rt2800_probe_hw_mode(struct r
|
||||
rt2x00_rf(rt2x00dev, RF3322) ||
|
||||
rt2x00_rf(rt2x00dev, RF5360) ||
|
||||
rt2x00_rf(rt2x00dev, RF5370) ||
|
||||
+ rt2x00_rf(rt2x00dev, RF3070) ||
|
||||
rt2x00_rf(rt2x00dev, RF5372) ||
|
||||
rt2x00_rf(rt2x00dev, RF5390) ||
|
||||
rt2x00_rf(rt2x00dev, RF5392)) {
|
||||
@@ -6081,6 +6086,7 @@ static int rt2800_probe_hw_mode(struct r
|
||||
case RF3290:
|
||||
case RF5360:
|
||||
case RF5370:
|
||||
+ case RF3070:
|
||||
case RF5372:
|
||||
case RF5390:
|
||||
case RF5392:
|
|
@ -0,0 +1,30 @@
|
|||
From 3d8a3a5cbcd4d36768cf53e778d8165aefabd5b0 Mon Sep 17 00:00:00 2001
|
||||
From: P33M <P33M@github.com>
|
||||
Date: Fri, 20 Sep 2013 16:08:27 +0100
|
||||
Subject: [PATCH 093/174] dwc_otg: Enable NAK holdoff for control split
|
||||
transactions
|
||||
|
||||
Certain low-speed devices take a very long time to complete a
|
||||
data or status stage of a control transaction, producing NAK
|
||||
responses until they complete internal processing - the USB2.0
|
||||
spec limit is up to 500mS. This causes the same type of interrupt
|
||||
storm as seen with USB-serial dongles prior to c8edb238.
|
||||
|
||||
In certain circumstances, usually while booting, this interrupt
|
||||
storm could cause SD card timeouts.
|
||||
---
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
|
||||
@@ -1857,8 +1857,7 @@ static int32_t handle_hc_nak_intr(dwc_ot
|
||||
*/
|
||||
switch(dwc_otg_hcd_get_pipe_type(&qtd->urb->pipe_info)) {
|
||||
case UE_BULK:
|
||||
- //case UE_INTERRUPT:
|
||||
- //case UE_CONTROL:
|
||||
+ case UE_CONTROL:
|
||||
if (nak_holdoff_enable)
|
||||
hc->qh->nak_frame = dwc_otg_hcd_get_frame_number(hcd);
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
From 4de1c90013a4ee22aa8250f455b1a6417e0d90fb Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Fri, 20 Sep 2013 19:07:56 +0100
|
||||
Subject: [PATCH 094/174] dwc_otg: Fix for occasional lockup on boot when doing
|
||||
a USB reset
|
||||
|
||||
---
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
|
||||
@@ -742,8 +742,8 @@ int32_t dwc_otg_hcd_handle_sof_intr(dwc_
|
||||
}
|
||||
|
||||
/* Clear interrupt */
|
||||
- //gintsts.b.sofintr = 1;
|
||||
- //DWC_WRITE_REG32(&hcd->core_if->core_global_regs->gintsts, gintsts.d32);
|
||||
+ gintsts.b.sofintr = 1;
|
||||
+ DWC_WRITE_REG32(&hcd->core_if->core_global_regs->gintsts, gintsts.d32);
|
||||
|
||||
return 1;
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
From 0dd387f3d3d1184fe45b57afbe73796e2ebe8d39 Mon Sep 17 00:00:00 2001
|
||||
From: P33M <P33M@github.com>
|
||||
Date: Fri, 27 Sep 2013 14:42:24 +0100
|
||||
Subject: [PATCH 095/174] dwc_otg: Don't issue traffic to LS devices in FS mode
|
||||
|
||||
Issuing low-speed packets when the root port is in full-speed mode
|
||||
causes the root port to stop responding. Explicitly fail when
|
||||
enqueuing URBs to a LS endpoint on a FS bus.
|
||||
---
|
||||
drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 11 +++++++++++
|
||||
1 file changed, 11 insertions(+)
|
||||
|
||||
--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
|
||||
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
|
||||
@@ -501,6 +501,7 @@ int dwc_otg_hcd_urb_enqueue(dwc_otg_hcd_
|
||||
dwc_otg_transaction_type_e tr_type;
|
||||
dwc_otg_qtd_t *qtd;
|
||||
gintmsk_data_t intr_mask = {.d32 = 0 };
|
||||
+ hprt0_data_t hprt0 = { .d32 = 0 };
|
||||
|
||||
#ifdef DEBUG /* integrity checks (Broadcom) */
|
||||
if (NULL == hcd->core_if) {
|
||||
@@ -515,6 +516,16 @@ int dwc_otg_hcd_urb_enqueue(dwc_otg_hcd_
|
||||
return -DWC_E_NO_DEVICE;
|
||||
}
|
||||
|
||||
+ /* Some core configurations cannot support LS traffic on a FS root port */
|
||||
+ if ((hcd->fops->speed(hcd, dwc_otg_urb->priv) == USB_SPEED_LOW) &&
|
||||
+ (hcd->core_if->hwcfg2.b.fs_phy_type == 1) &&
|
||||
+ (hcd->core_if->hwcfg2.b.hs_phy_type == 1)) {
|
||||
+ hprt0.d32 = DWC_READ_REG32(hcd->core_if->host_if->hprt0);
|
||||
+ if (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_FULL_SPEED) {
|
||||
+ return -DWC_E_NO_DEVICE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
qtd = dwc_otg_hcd_qtd_create(dwc_otg_urb, atomic_alloc);
|
||||
if (qtd == NULL) {
|
||||
DWC_ERROR("DWC OTG HCD URB Enqueue failed creating QTD\n");
|
|
@ -0,0 +1,303 @@
|
|||
From 062e7d1247624034c6b9ff1515245930baee8862 Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Wed, 6 Nov 2013 12:08:46 +0000
|
||||
Subject: [PATCH 096/174] config: enable BLK_DEV_SD statically. Add some
|
||||
DM_MIRROR raid options. Add ISCSI_TCP. Add R8712U
|
||||
|
||||
kernel: config: add missing PPP config options
|
||||
|
||||
kernel: config: Add MMC_SPI and DM_LOG_USERSPACE
|
||||
|
||||
kernel: config: Add crypto modules
|
||||
|
||||
config: Enable NET_IPIP, IP_ADVANCED_ROUTER, IP_MULTIPLE_TABLES, IP_ROUTE_MULTIPATH, NETFILTER_MATCH_IPVS
|
||||
|
||||
config: Enable MROUTE options
|
||||
|
||||
config: enable CONFIG_CRYPTO_AES_ARM
|
||||
|
||||
config: Add more config options from 3.6 tree including PREEMPT, SPEAKUP, NTFS_RW, HFS
|
||||
|
||||
config: Set CONFIG_SPI_SPIDEV=y
|
||||
---
|
||||
arch/arm/configs/bcmrpi_defconfig | 93 +++++++++++++++++++++++++++++++++------
|
||||
1 file changed, 80 insertions(+), 13 deletions(-)
|
||||
|
||||
--- a/arch/arm/configs/bcmrpi_defconfig
|
||||
+++ b/arch/arm/configs/bcmrpi_defconfig
|
||||
@@ -33,18 +33,21 @@ CONFIG_MODULES=y
|
||||
CONFIG_MODULE_UNLOAD=y
|
||||
CONFIG_MODVERSIONS=y
|
||||
CONFIG_MODULE_SRCVERSION_ALL=y
|
||||
-# CONFIG_BLK_DEV_BSG is not set
|
||||
CONFIG_BLK_DEV_THROTTLING=y
|
||||
CONFIG_PARTITION_ADVANCED=y
|
||||
CONFIG_MAC_PARTITION=y
|
||||
CONFIG_CFQ_GROUP_IOSCHED=y
|
||||
CONFIG_ARCH_BCM2708=y
|
||||
+CONFIG_PREEMPT=y
|
||||
CONFIG_AEABI=y
|
||||
+CONFIG_CLEANCACHE=y
|
||||
+CONFIG_FRONTSWAP=y
|
||||
+CONFIG_UACCESS_WITH_MEMCPY=y
|
||||
CONFIG_SECCOMP=y
|
||||
CONFIG_CC_STACKPROTECTOR=y
|
||||
CONFIG_ZBOOT_ROM_TEXT=0x0
|
||||
CONFIG_ZBOOT_ROM_BSS=0x0
|
||||
-CONFIG_CMDLINE="dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 root=/dev/mmcblk0p2 rootfstype=ext3 rootwait"
|
||||
+CONFIG_CMDLINE="console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait"
|
||||
CONFIG_KEXEC=y
|
||||
CONFIG_CPU_FREQ=y
|
||||
CONFIG_CPU_FREQ_STAT=m
|
||||
@@ -64,9 +67,20 @@ CONFIG_XFRM_USER=y
|
||||
CONFIG_NET_KEY=m
|
||||
CONFIG_INET=y
|
||||
CONFIG_IP_MULTICAST=y
|
||||
+CONFIG_IP_ADVANCED_ROUTER=y
|
||||
+CONFIG_IP_MULTIPLE_TABLES=y
|
||||
+CONFIG_IP_ROUTE_MULTIPATH=y
|
||||
+CONFIG_IP_ROUTE_VERBOSE=y
|
||||
CONFIG_IP_PNP=y
|
||||
CONFIG_IP_PNP_DHCP=y
|
||||
CONFIG_IP_PNP_RARP=y
|
||||
+CONFIG_NET_IPIP=m
|
||||
+CONFIG_NET_IPGRE_DEMUX=m
|
||||
+CONFIG_NET_IPGRE=m
|
||||
+CONFIG_IP_MROUTE=y
|
||||
+CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
|
||||
+CONFIG_IP_PIMSM_V1=y
|
||||
+CONFIG_IP_PIMSM_V2=y
|
||||
CONFIG_SYN_COOKIES=y
|
||||
CONFIG_INET_AH=m
|
||||
CONFIG_INET_ESP=m
|
||||
@@ -81,6 +95,9 @@ CONFIG_INET6_AH=m
|
||||
CONFIG_INET6_ESP=m
|
||||
CONFIG_INET6_IPCOMP=m
|
||||
CONFIG_IPV6_MULTIPLE_TABLES=y
|
||||
+CONFIG_IPV6_MROUTE=y
|
||||
+CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y
|
||||
+CONFIG_IPV6_PIMSM_V2=y
|
||||
CONFIG_NETFILTER=y
|
||||
CONFIG_NF_CONNTRACK=m
|
||||
CONFIG_NF_CONNTRACK_ZONES=y
|
||||
@@ -136,6 +153,7 @@ CONFIG_NETFILTER_XT_MATCH_ESP=m
|
||||
CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_HELPER=m
|
||||
CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_IPVS=m
|
||||
CONFIG_NETFILTER_XT_MATCH_LENGTH=m
|
||||
CONFIG_NETFILTER_XT_MATCH_LIMIT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_MAC=m
|
||||
@@ -357,7 +375,6 @@ CONFIG_RFKILL_INPUT=y
|
||||
CONFIG_NET_9P=m
|
||||
CONFIG_NFC=m
|
||||
CONFIG_NFC_PN533=m
|
||||
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_DEVTMPFS_MOUNT=y
|
||||
CONFIG_CMA=y
|
||||
@@ -369,25 +386,44 @@ CONFIG_BLK_DEV_RAM=y
|
||||
CONFIG_CDROM_PKTCDVD=m
|
||||
CONFIG_SCSI=y
|
||||
# CONFIG_SCSI_PROC_FS is not set
|
||||
-CONFIG_BLK_DEV_SD=m
|
||||
+CONFIG_BLK_DEV_SD=y
|
||||
+CONFIG_CHR_DEV_ST=m
|
||||
+CONFIG_CHR_DEV_OSST=m
|
||||
CONFIG_BLK_DEV_SR=m
|
||||
CONFIG_SCSI_MULTI_LUN=y
|
||||
-# CONFIG_SCSI_LOWLEVEL is not set
|
||||
+CONFIG_SCSI_ISCSI_ATTRS=y
|
||||
+CONFIG_ISCSI_TCP=m
|
||||
+CONFIG_ISCSI_BOOT_SYSFS=m
|
||||
CONFIG_MD=y
|
||||
+CONFIG_MD_RAID0=m
|
||||
CONFIG_BLK_DEV_DM=m
|
||||
CONFIG_DM_CRYPT=m
|
||||
+CONFIG_DM_SNAPSHOT=m
|
||||
+CONFIG_DM_MIRROR=m
|
||||
+CONFIG_DM_RAID=m
|
||||
+CONFIG_DM_LOG_USERSPACE=m
|
||||
+CONFIG_DM_ZERO=m
|
||||
+CONFIG_DM_DELAY=m
|
||||
CONFIG_NETDEVICES=y
|
||||
+CONFIG_BONDING=m
|
||||
CONFIG_DUMMY=m
|
||||
+CONFIG_MACVLAN=m
|
||||
CONFIG_NETCONSOLE=m
|
||||
CONFIG_TUN=m
|
||||
CONFIG_MDIO_BITBANG=m
|
||||
CONFIG_PPP=m
|
||||
CONFIG_PPP_BSDCOMP=m
|
||||
CONFIG_PPP_DEFLATE=m
|
||||
+CONFIG_PPP_FILTER=y
|
||||
+CONFIG_PPP_MPPE=m
|
||||
+CONFIG_PPP_MULTILINK=y
|
||||
+CONFIG_PPPOE=m
|
||||
+CONFIG_PPPOL2TP=m
|
||||
CONFIG_PPP_ASYNC=m
|
||||
CONFIG_PPP_SYNC_TTY=m
|
||||
CONFIG_SLIP=m
|
||||
CONFIG_SLIP_COMPRESSED=y
|
||||
+CONFIG_SLIP_SMART=y
|
||||
CONFIG_USB_CATC=m
|
||||
CONFIG_USB_KAWETH=m
|
||||
CONFIG_USB_PEGASUS=m
|
||||
@@ -397,6 +433,7 @@ CONFIG_USB_USBNET=y
|
||||
CONFIG_USB_NET_AX8817X=m
|
||||
CONFIG_USB_NET_CDCETHER=m
|
||||
CONFIG_USB_NET_CDC_EEM=m
|
||||
+CONFIG_USB_NET_CDC_NCM=m
|
||||
CONFIG_USB_NET_CDC_MBIM=m
|
||||
CONFIG_USB_NET_DM9601=m
|
||||
CONFIG_USB_NET_SMSC75XX=m
|
||||
@@ -473,14 +510,19 @@ CONFIG_INPUT_UINPUT=m
|
||||
CONFIG_INPUT_GPIO_ROTARY_ENCODER=m
|
||||
CONFIG_INPUT_ADXL34X=m
|
||||
CONFIG_INPUT_CMA3000=m
|
||||
-# CONFIG_SERIO is not set
|
||||
+CONFIG_SERIO=m
|
||||
+CONFIG_SERIO_RAW=m
|
||||
+CONFIG_GAMEPORT=m
|
||||
+CONFIG_GAMEPORT_NS558=m
|
||||
+CONFIG_GAMEPORT_L4=m
|
||||
CONFIG_VT_HW_CONSOLE_BINDING=y
|
||||
# CONFIG_LEGACY_PTYS is not set
|
||||
# CONFIG_DEVKMEM is not set
|
||||
CONFIG_SERIAL_AMBA_PL011=y
|
||||
CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
|
||||
+CONFIG_TTY_PRINTK=y
|
||||
CONFIG_HW_RANDOM=y
|
||||
-CONFIG_HW_RANDOM_BCM2708=y
|
||||
+CONFIG_HW_RANDOM_BCM2708=m
|
||||
CONFIG_RAW_DRIVER=y
|
||||
CONFIG_BRCM_CHAR_DRIVERS=y
|
||||
CONFIG_BCM_VC_CMA=y
|
||||
@@ -489,7 +531,7 @@ CONFIG_I2C_CHARDEV=m
|
||||
CONFIG_I2C_BCM2708=m
|
||||
CONFIG_SPI=y
|
||||
CONFIG_SPI_BCM2708=m
|
||||
-CONFIG_SPI_SPIDEV=m
|
||||
+CONFIG_SPI_SPIDEV=y
|
||||
CONFIG_GPIO_SYSFS=y
|
||||
CONFIG_W1=m
|
||||
CONFIG_W1_MASTER_DS2490=m
|
||||
@@ -645,6 +687,7 @@ CONFIG_VIDEO_EM28XX_ALSA=m
|
||||
CONFIG_VIDEO_EM28XX_DVB=m
|
||||
CONFIG_RADIO_SI470X=y
|
||||
CONFIG_USB_SI470X=m
|
||||
+CONFIG_I2C_SI470X=m
|
||||
CONFIG_USB_MR800=m
|
||||
CONFIG_USB_DSBR=m
|
||||
CONFIG_RADIO_SHARK=m
|
||||
@@ -652,11 +695,14 @@ CONFIG_RADIO_SHARK2=m
|
||||
CONFIG_RADIO_SI4713=m
|
||||
CONFIG_USB_KEENE=m
|
||||
CONFIG_USB_MA901=m
|
||||
+CONFIG_RADIO_TEA5764=m
|
||||
CONFIG_RADIO_SAA7706H=m
|
||||
CONFIG_RADIO_TEF6862=m
|
||||
+CONFIG_RADIO_WL1273=m
|
||||
CONFIG_RADIO_WL128X=m
|
||||
CONFIG_FB=y
|
||||
CONFIG_FB_BCM2708=y
|
||||
+# CONFIG_BACKLIGHT_GENERIC is not set
|
||||
CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||
CONFIG_LOGO=y
|
||||
# CONFIG_LOGO_LINUX_MONO is not set
|
||||
@@ -679,6 +725,7 @@ CONFIG_SND_BCM2835=m
|
||||
CONFIG_SND_USB_AUDIO=m
|
||||
CONFIG_SND_USB_UA101=m
|
||||
CONFIG_SND_USB_CAIAQ=m
|
||||
+CONFIG_SND_USB_CAIAQ_INPUT=y
|
||||
CONFIG_SND_USB_6FIRE=m
|
||||
CONFIG_SOUND_PRIME=m
|
||||
CONFIG_HIDRAW=y
|
||||
@@ -829,6 +876,7 @@ CONFIG_MMC_SDHCI=y
|
||||
CONFIG_MMC_SDHCI_PLTFM=y
|
||||
CONFIG_MMC_SDHCI_BCM2708=y
|
||||
CONFIG_MMC_SDHCI_BCM2708_DMA=y
|
||||
+CONFIG_MMC_SPI=m
|
||||
CONFIG_LEDS_GPIO=m
|
||||
CONFIG_LEDS_TRIGGER_TIMER=y
|
||||
CONFIG_LEDS_TRIGGER_ONESHOT=y
|
||||
@@ -874,9 +922,20 @@ CONFIG_UIO=m
|
||||
CONFIG_UIO_PDRV=m
|
||||
CONFIG_UIO_PDRV_GENIRQ=m
|
||||
CONFIG_STAGING=y
|
||||
+CONFIG_W35UND=m
|
||||
+CONFIG_PRISM2_USB=m
|
||||
+CONFIG_R8712U=m
|
||||
+CONFIG_VT6656=m
|
||||
+CONFIG_SPEAKUP=m
|
||||
+CONFIG_SPEAKUP_SYNTH_SOFT=m
|
||||
CONFIG_STAGING_MEDIA=y
|
||||
+CONFIG_DVB_AS102=m
|
||||
CONFIG_LIRC_STAGING=y
|
||||
+CONFIG_LIRC_IGORPLUGUSB=m
|
||||
+CONFIG_LIRC_IMON=m
|
||||
CONFIG_LIRC_RPI=m
|
||||
+CONFIG_LIRC_SASEM=m
|
||||
+CONFIG_LIRC_SERIAL=m
|
||||
# CONFIG_IOMMU_SUPPORT is not set
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
@@ -916,9 +975,13 @@ CONFIG_MSDOS_FS=y
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
|
||||
CONFIG_NTFS_FS=m
|
||||
+CONFIG_NTFS_RW=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_TMPFS_POSIX_ACL=y
|
||||
CONFIG_CONFIGFS_FS=y
|
||||
+CONFIG_ECRYPT_FS=m
|
||||
+CONFIG_HFS_FS=m
|
||||
+CONFIG_HFSPLUS_FS=m
|
||||
CONFIG_SQUASHFS=m
|
||||
CONFIG_SQUASHFS_XATTR=y
|
||||
CONFIG_SQUASHFS_LZO=y
|
||||
@@ -936,7 +999,6 @@ CONFIG_CIFS=m
|
||||
CONFIG_CIFS_WEAK_PW_HASH=y
|
||||
CONFIG_CIFS_XATTR=y
|
||||
CONFIG_CIFS_POSIX=y
|
||||
-# CONFIG_CIFS_DEBUG is not set
|
||||
CONFIG_9P_FS=m
|
||||
CONFIG_9P_FS_POSIX_ACL=y
|
||||
CONFIG_NLS_DEFAULT="utf8"
|
||||
@@ -977,27 +1039,32 @@ CONFIG_NLS_ISO8859_14=m
|
||||
CONFIG_NLS_ISO8859_15=m
|
||||
CONFIG_NLS_KOI8_R=m
|
||||
CONFIG_NLS_KOI8_U=m
|
||||
-CONFIG_NLS_UTF8=m
|
||||
CONFIG_DLM=m
|
||||
CONFIG_PRINTK_TIME=y
|
||||
+CONFIG_DEBUG_FS=y
|
||||
CONFIG_DETECT_HUNG_TASK=y
|
||||
CONFIG_TIMER_STATS=y
|
||||
+# CONFIG_DEBUG_PREEMPT is not set
|
||||
CONFIG_DEBUG_MEMORY_INIT=y
|
||||
CONFIG_BOOT_PRINTK_DELAY=y
|
||||
CONFIG_LATENCYTOP=y
|
||||
+# CONFIG_KPROBE_EVENT is not set
|
||||
CONFIG_KGDB=y
|
||||
CONFIG_KGDB_KDB=y
|
||||
CONFIG_KDB_KEYBOARD=y
|
||||
CONFIG_STRICT_DEVMEM=y
|
||||
+CONFIG_CRYPTO_USER=m
|
||||
+CONFIG_CRYPTO_NULL=m
|
||||
+CONFIG_CRYPTO_CRYPTD=m
|
||||
CONFIG_CRYPTO_SEQIV=m
|
||||
CONFIG_CRYPTO_CBC=y
|
||||
-CONFIG_CRYPTO_HMAC=y
|
||||
+CONFIG_CRYPTO_XTS=m
|
||||
CONFIG_CRYPTO_XCBC=m
|
||||
-CONFIG_CRYPTO_MD5=y
|
||||
-CONFIG_CRYPTO_SHA1=y
|
||||
+CONFIG_CRYPTO_SHA1_ARM=m
|
||||
CONFIG_CRYPTO_SHA512=m
|
||||
CONFIG_CRYPTO_TGR192=m
|
||||
CONFIG_CRYPTO_WP512=m
|
||||
+CONFIG_CRYPTO_AES_ARM=m
|
||||
CONFIG_CRYPTO_CAST5=m
|
||||
CONFIG_CRYPTO_DES=y
|
||||
# CONFIG_CRYPTO_ANSI_CPRNG is not set
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,99 @@
|
|||
From 1c4544175663c38eb22b9095ce75c31f2d6c6e18 Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Sat, 9 Nov 2013 13:32:03 +0000
|
||||
Subject: [PATCH 098/174] wifi: add patches from 3.6.y tree to make rtl8192cu
|
||||
work
|
||||
|
||||
wifi: add missing patch from 3.6.y tree to disable debug
|
||||
---
|
||||
drivers/net/wireless/rtl8192cu/Kconfig | 4 +++-
|
||||
drivers/net/wireless/rtl8192cu/Makefile | 6 +++++-
|
||||
drivers/net/wireless/rtl8192cu/include/autoconf.h | 2 +-
|
||||
drivers/net/wireless/rtl8192cu/os_dep/linux/os_intfs.c | 13 +++++++++++++
|
||||
drivers/net/wireless/rtl8192cu/os_dep/linux/usb_intf.c | 1 +
|
||||
5 files changed, 23 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/rtl8192cu/Kconfig
|
||||
+++ b/drivers/net/wireless/rtl8192cu/Kconfig
|
||||
@@ -1,6 +1,8 @@
|
||||
config RTL8192CU
|
||||
tristate "Realtek 8192C USB WiFi"
|
||||
depends on USB
|
||||
+ select WIRELESS_EXT
|
||||
+ select WEXT_PRIV
|
||||
---help---
|
||||
- Help message of RTL8192CU
|
||||
+ Enable wireless network adapters based on Realtek RTL8192C chipset family, such as EDUP nano series
|
||||
|
||||
--- a/drivers/net/wireless/rtl8192cu/Makefile
|
||||
+++ b/drivers/net/wireless/rtl8192cu/Makefile
|
||||
@@ -38,7 +38,7 @@ CONFIG_RTL8192CU_REDEFINE_1X1 = n
|
||||
CONFIG_INTEL_WIDI = n
|
||||
CONFIG_WAKE_ON_WLAN = n
|
||||
|
||||
-CONFIG_PLATFORM_I386_PC = y
|
||||
+CONFIG_PLATFORM_I386_PC = n
|
||||
CONFIG_PLATFORM_TI_AM3517 = n
|
||||
CONFIG_PLATFORM_ANDROID_X86 = n
|
||||
CONFIG_PLATFORM_JB_X86 = n
|
||||
@@ -524,6 +524,10 @@ KVER := 3.3.0
|
||||
#KSRC:= ../lichee/linux-3.3/
|
||||
endif
|
||||
|
||||
+ifeq ($(CONFIG_ARCH_BCM2708), y)
|
||||
+EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN
|
||||
+endif
|
||||
+
|
||||
ifneq ($(USER_MODULE_NAME),)
|
||||
MODULE_NAME := $(USER_MODULE_NAME)
|
||||
endif
|
||||
--- a/drivers/net/wireless/rtl8192cu/include/autoconf.h
|
||||
+++ b/drivers/net/wireless/rtl8192cu/include/autoconf.h
|
||||
@@ -296,7 +296,7 @@
|
||||
//#define CONFIG_DEBUG_RTL871X
|
||||
|
||||
#define DBG 0
|
||||
-#define CONFIG_DEBUG_RTL819X
|
||||
+//#define CONFIG_DEBUG_RTL819X
|
||||
|
||||
#define CONFIG_PROC_DEBUG 1
|
||||
|
||||
--- a/drivers/net/wireless/rtl8192cu/os_dep/linux/os_intfs.c
|
||||
+++ b/drivers/net/wireless/rtl8192cu/os_dep/linux/os_intfs.c
|
||||
@@ -277,6 +277,18 @@ static int rtw_proc_cnt = 0;
|
||||
|
||||
#define RTW_PROC_NAME DRV_NAME
|
||||
|
||||
+#ifndef create_proc_entry
|
||||
+/* dummy routines */
|
||||
+void rtw_proc_remove_one(struct net_device *dev)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+void rtw_proc_init_one(struct net_device *dev)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+#else /* create_proc_entry not defined */
|
||||
+
|
||||
void rtw_proc_init_one(struct net_device *dev)
|
||||
{
|
||||
struct proc_dir_entry *dir_dev = NULL;
|
||||
@@ -751,6 +763,7 @@ void rtw_proc_remove_one(struct net_devi
|
||||
}
|
||||
}
|
||||
}
|
||||
+#endif /* create_proc_entry not defined */
|
||||
#endif
|
||||
|
||||
uint loadparam( _adapter *padapter, _nic_hdl pnetdev);
|
||||
--- a/drivers/net/wireless/rtl8192cu/os_dep/linux/usb_intf.c
|
||||
+++ b/drivers/net/wireless/rtl8192cu/os_dep/linux/usb_intf.c
|
||||
@@ -138,6 +138,7 @@ static void rtw_dev_remove(struct usb_in
|
||||
{USB_DEVICE(0x2001, 0x3307)},/* D-Link - Cameo */ \
|
||||
{USB_DEVICE(0x2001, 0x330A)},/* D-Link - Alpha */ \
|
||||
{USB_DEVICE(0x2001, 0x3309)},/* D-Link - Alpha */ \
|
||||
+ {USB_DEVICE(0x2001, 0x330D)},/* D-Link - Alpha(?) */ \
|
||||
{USB_DEVICE(0x0586, 0x341F)},/* Zyxel - Abocom */ \
|
||||
{USB_DEVICE(0x7392, 0x7822)},/* Edimax - Edimax */ \
|
||||
{USB_DEVICE(0x2019, 0xAB2B)},/* Planex - Abocom */ \
|
|
@ -0,0 +1,316 @@
|
|||
From c24b41600f008f5662a467de17644d26a0c269fd Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Sat, 9 Nov 2013 17:42:58 +0000
|
||||
Subject: [PATCH 099/174] mmc: Report 3.3V support in caps
|
||||
|
||||
sdhci: Use macros for out spin lock/unlock functions to reduce diffs with upstream code
|
||||
---
|
||||
drivers/mmc/host/sdhci-bcm2708.c | 2 +
|
||||
drivers/mmc/host/sdhci.c | 82 ++++++++++++++++++++++------------------
|
||||
2 files changed, 47 insertions(+), 37 deletions(-)
|
||||
|
||||
--- a/drivers/mmc/host/sdhci-bcm2708.c
|
||||
+++ b/drivers/mmc/host/sdhci-bcm2708.c
|
||||
@@ -1282,6 +1282,8 @@ static int sdhci_bcm2708_probe(struct pl
|
||||
host_priv->dma_chan, host_priv->dma_chan_base,
|
||||
host_priv->dma_irq);
|
||||
|
||||
+ // we support 3.3V
|
||||
+ host->caps |= SDHCI_CAN_VDD_330;
|
||||
if (allow_highspeed)
|
||||
host->mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
|
||||
|
||||
--- a/drivers/mmc/host/sdhci.c
|
||||
+++ b/drivers/mmc/host/sdhci.c
|
||||
@@ -210,6 +210,14 @@ static void sdhci_spin_disable_schedule(
|
||||
#endif
|
||||
}
|
||||
|
||||
+
|
||||
+#undef spin_lock_irqsave
|
||||
+#define spin_lock_irqsave(host_lock, flags) sdhci_spin_lock_irqsave(container_of(host_lock, struct sdhci_host, lock), &flags)
|
||||
+#define spin_unlock_irqrestore(host_lock, flags) sdhci_spin_unlock_irqrestore(container_of(host_lock, struct sdhci_host, lock), flags)
|
||||
+
|
||||
+#define spin_lock(host_lock) sdhci_spin_lock(container_of(host_lock, struct sdhci_host, lock))
|
||||
+#define spin_unlock(host_lock) sdhci_spin_unlock(container_of(host_lock, struct sdhci_host, lock))
|
||||
+
|
||||
static void sdhci_clear_set_irqs(struct sdhci_host *host, u32 clear, u32 set)
|
||||
{
|
||||
u32 ier;
|
||||
@@ -374,7 +382,7 @@ static void sdhci_led_control(struct led
|
||||
struct sdhci_host *host = container_of(led, struct sdhci_host, led);
|
||||
unsigned long flags;
|
||||
|
||||
- sdhci_spin_lock_irqsave(host, &flags);
|
||||
+ spin_lock_irqsave(&host->lock, flags);
|
||||
|
||||
if (host->runtime_suspended)
|
||||
goto out;
|
||||
@@ -384,7 +392,7 @@ static void sdhci_led_control(struct led
|
||||
else
|
||||
sdhci_activate_led(host);
|
||||
out:
|
||||
- sdhci_spin_unlock_irqrestore(host, flags);
|
||||
+ spin_unlock_irqrestore(&host->lock, flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1419,7 +1427,7 @@ static void sdhci_request(struct mmc_hos
|
||||
|
||||
sdhci_runtime_pm_get(host);
|
||||
|
||||
- sdhci_spin_lock_irqsave(host, &flags);
|
||||
+ spin_lock_irqsave(&host->lock, flags);
|
||||
|
||||
WARN_ON(host->mrq != NULL);
|
||||
|
||||
@@ -1477,9 +1485,9 @@ static void sdhci_request(struct mmc_hos
|
||||
mmc->card->type == MMC_TYPE_MMC ?
|
||||
MMC_SEND_TUNING_BLOCK_HS200 :
|
||||
MMC_SEND_TUNING_BLOCK;
|
||||
- sdhci_spin_unlock_irqrestore(host, flags);
|
||||
+ spin_unlock_irqrestore(&host->lock, flags);
|
||||
sdhci_execute_tuning(mmc, tuning_opcode);
|
||||
- sdhci_spin_lock_irqsave(host, &flags);
|
||||
+ spin_lock_irqsave(&host->lock, flags);
|
||||
|
||||
/* Restore original mmc_request structure */
|
||||
host->mrq = mrq;
|
||||
@@ -1493,7 +1501,7 @@ static void sdhci_request(struct mmc_hos
|
||||
}
|
||||
|
||||
mmiowb();
|
||||
- sdhci_spin_unlock_irqrestore(host, flags);
|
||||
+ spin_unlock_irqrestore(&host->lock, flags);
|
||||
}
|
||||
|
||||
static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
|
||||
@@ -1502,10 +1510,10 @@ static void sdhci_do_set_ios(struct sdhc
|
||||
int vdd_bit = -1;
|
||||
u8 ctrl;
|
||||
|
||||
- sdhci_spin_lock_irqsave(host, &flags);
|
||||
+ spin_lock_irqsave(&host->lock, flags);
|
||||
|
||||
if (host->flags & SDHCI_DEVICE_DEAD) {
|
||||
- sdhci_spin_unlock_irqrestore(host, flags);
|
||||
+ spin_unlock_irqrestore(&host->lock, flags);
|
||||
if (host->vmmc && ios->power_mode == MMC_POWER_OFF)
|
||||
mmc_regulator_set_ocr(host->mmc, host->vmmc, 0);
|
||||
return;
|
||||
@@ -1532,9 +1540,9 @@ static void sdhci_do_set_ios(struct sdhc
|
||||
vdd_bit = sdhci_set_power(host, ios->vdd);
|
||||
|
||||
if (host->vmmc && vdd_bit != -1) {
|
||||
- sdhci_spin_unlock_irqrestore(host, flags);
|
||||
+ spin_unlock_irqrestore(&host->lock, flags);
|
||||
mmc_regulator_set_ocr(host->mmc, host->vmmc, vdd_bit);
|
||||
- sdhci_spin_lock_irqsave(host, &flags);
|
||||
+ spin_lock_irqsave(&host->lock, flags);
|
||||
}
|
||||
|
||||
if (host->ops->platform_send_init_74_clocks)
|
||||
@@ -1672,7 +1680,7 @@ static void sdhci_do_set_ios(struct sdhc
|
||||
sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
|
||||
|
||||
mmiowb();
|
||||
- sdhci_spin_unlock_irqrestore(host, flags);
|
||||
+ spin_unlock_irqrestore(&host->lock, flags);
|
||||
}
|
||||
|
||||
static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
|
||||
@@ -1720,7 +1728,7 @@ static int sdhci_check_ro(struct sdhci_h
|
||||
unsigned long flags;
|
||||
int is_readonly;
|
||||
|
||||
- sdhci_spin_lock_irqsave(host, &flags);
|
||||
+ spin_lock_irqsave(&host->lock, flags);
|
||||
|
||||
if (host->flags & SDHCI_DEVICE_DEAD)
|
||||
is_readonly = 0;
|
||||
@@ -1730,7 +1738,7 @@ static int sdhci_check_ro(struct sdhci_h
|
||||
is_readonly = !(sdhci_readl(host, SDHCI_PRESENT_STATE)
|
||||
& SDHCI_WRITE_PROTECT);
|
||||
|
||||
- sdhci_spin_unlock_irqrestore(host, flags);
|
||||
+ spin_unlock_irqrestore(&host->lock, flags);
|
||||
|
||||
/* This quirk needs to be replaced by a callback-function later */
|
||||
return host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT ?
|
||||
@@ -1803,9 +1811,9 @@ static void sdhci_enable_sdio_irq(struct
|
||||
struct sdhci_host *host = mmc_priv(mmc);
|
||||
unsigned long flags;
|
||||
|
||||
- sdhci_spin_lock_irqsave(host, &flags);
|
||||
+ spin_lock_irqsave(&host->lock, flags);
|
||||
sdhci_enable_sdio_irq_nolock(host, enable);
|
||||
- sdhci_spin_unlock_irqrestore(host, flags);
|
||||
+ spin_unlock_irqrestore(&host->lock, flags);
|
||||
}
|
||||
|
||||
static int sdhci_do_start_signal_voltage_switch(struct sdhci_host *host,
|
||||
@@ -2149,7 +2157,7 @@ static void sdhci_card_event(struct mmc_
|
||||
struct sdhci_host *host = mmc_priv(mmc);
|
||||
unsigned long flags;
|
||||
|
||||
- sdhci_spin_lock_irqsave(host, &flags);
|
||||
+ spin_lock_irqsave(&host->lock, flags);
|
||||
|
||||
/* Check host->mrq first in case we are runtime suspended */
|
||||
if (host->mrq &&
|
||||
@@ -2166,7 +2174,7 @@ static void sdhci_card_event(struct mmc_
|
||||
tasklet_schedule(&host->finish_tasklet);
|
||||
}
|
||||
|
||||
- sdhci_spin_unlock_irqrestore(host, flags);
|
||||
+ spin_unlock_irqrestore(&host->lock, flags);
|
||||
}
|
||||
|
||||
static const struct mmc_host_ops sdhci_ops = {
|
||||
@@ -2205,14 +2213,14 @@ static void sdhci_tasklet_finish(unsigne
|
||||
|
||||
host = (struct sdhci_host*)param;
|
||||
|
||||
- sdhci_spin_lock_irqsave(host, &flags);
|
||||
+ spin_lock_irqsave(&host->lock, flags);
|
||||
|
||||
/*
|
||||
* If this tasklet gets rescheduled while running, it will
|
||||
* be run again afterwards but without any active request.
|
||||
*/
|
||||
if (!host->mrq) {
|
||||
- sdhci_spin_unlock_irqrestore(host, flags);
|
||||
+ spin_unlock_irqrestore(&host->lock, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2250,7 +2258,7 @@ static void sdhci_tasklet_finish(unsigne
|
||||
#endif
|
||||
|
||||
mmiowb();
|
||||
- sdhci_spin_unlock_irqrestore(host, flags);
|
||||
+ spin_unlock_irqrestore(&host->lock, flags);
|
||||
|
||||
mmc_request_done(host->mmc, mrq);
|
||||
sdhci_runtime_pm_put(host);
|
||||
@@ -2263,7 +2271,7 @@ static void sdhci_timeout_timer(unsigned
|
||||
|
||||
host = (struct sdhci_host*)data;
|
||||
|
||||
- sdhci_spin_lock_irqsave(host, &flags);
|
||||
+ spin_lock_irqsave(&host->lock, flags);
|
||||
|
||||
if (host->mrq) {
|
||||
pr_err("%s: Timeout waiting for hardware "
|
||||
@@ -2284,7 +2292,7 @@ static void sdhci_timeout_timer(unsigned
|
||||
}
|
||||
|
||||
mmiowb();
|
||||
- sdhci_spin_unlock_irqrestore(host, flags);
|
||||
+ spin_unlock_irqrestore(&host->lock, flags);
|
||||
}
|
||||
|
||||
static void sdhci_tuning_timer(unsigned long data)
|
||||
@@ -2294,11 +2302,11 @@ static void sdhci_tuning_timer(unsigned
|
||||
|
||||
host = (struct sdhci_host *)data;
|
||||
|
||||
- sdhci_spin_lock_irqsave(host, &flags);
|
||||
+ spin_lock_irqsave(&host->lock, flags);
|
||||
|
||||
host->flags |= SDHCI_NEEDS_RETUNING;
|
||||
|
||||
- sdhci_spin_unlock_irqrestore(host, flags);
|
||||
+ spin_unlock_irqrestore(&host->lock, flags);
|
||||
}
|
||||
|
||||
/*****************************************************************************\
|
||||
@@ -2522,10 +2530,10 @@ static irqreturn_t sdhci_irq(int irq, vo
|
||||
u32 intmask, unexpected = 0;
|
||||
int cardint = 0, max_loops = 16;
|
||||
|
||||
- sdhci_spin_lock(host);
|
||||
+ spin_lock(&host->lock);
|
||||
|
||||
if (host->runtime_suspended) {
|
||||
- sdhci_spin_unlock(host);
|
||||
+ spin_unlock(&host->lock);
|
||||
pr_warning("%s: got irq while runtime suspended\n",
|
||||
mmc_hostname(host->mmc));
|
||||
return IRQ_HANDLED;
|
||||
@@ -2629,7 +2637,7 @@ again:
|
||||
if (intmask && --max_loops)
|
||||
goto again;
|
||||
out:
|
||||
- sdhci_spin_unlock(host);
|
||||
+ spin_unlock(&host->lock);
|
||||
|
||||
if (unexpected) {
|
||||
pr_err("%s: Unexpected interrupt 0x%08x.\n",
|
||||
@@ -2791,15 +2799,15 @@ int sdhci_runtime_suspend_host(struct sd
|
||||
host->flags &= ~SDHCI_NEEDS_RETUNING;
|
||||
}
|
||||
|
||||
- sdhci_spin_lock_irqsave(host, &flags);
|
||||
+ spin_lock_irqsave(&host->lock, flags);
|
||||
sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK);
|
||||
- sdhci_spin_unlock_irqrestore(host, flags);
|
||||
+ spin_unlock_irqrestore(&host->lock, flags);
|
||||
|
||||
synchronize_irq(host->irq);
|
||||
|
||||
- sdhci_spin_lock_irqsave(host, &flags);
|
||||
+ spin_lock_irqsave(&host->lock, flags);
|
||||
host->runtime_suspended = true;
|
||||
- sdhci_spin_unlock_irqrestore(host, flags);
|
||||
+ spin_unlock_irqrestore(&host->lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -2825,16 +2833,16 @@ int sdhci_runtime_resume_host(struct sdh
|
||||
sdhci_do_start_signal_voltage_switch(host, &host->mmc->ios);
|
||||
if ((host_flags & SDHCI_PV_ENABLED) &&
|
||||
!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN)) {
|
||||
- sdhci_spin_lock_irqsave(host, &flags);
|
||||
+ spin_lock_irqsave(&host->lock, flags);
|
||||
sdhci_enable_preset_value(host, true);
|
||||
- sdhci_spin_unlock_irqrestore(host, flags);
|
||||
+ spin_unlock_irqrestore(&host->lock, flags);
|
||||
}
|
||||
|
||||
/* Set the re-tuning expiration flag */
|
||||
if (host->flags & SDHCI_USING_RETUNING_TIMER)
|
||||
host->flags |= SDHCI_NEEDS_RETUNING;
|
||||
|
||||
- sdhci_spin_lock_irqsave(host, &flags);
|
||||
+ spin_lock_irqsave(&host->lock, flags);
|
||||
|
||||
host->runtime_suspended = false;
|
||||
|
||||
@@ -2845,7 +2853,7 @@ int sdhci_runtime_resume_host(struct sdh
|
||||
/* Enable Card Detection */
|
||||
sdhci_enable_card_detection(host);
|
||||
|
||||
- sdhci_spin_unlock_irqrestore(host, flags);
|
||||
+ spin_unlock_irqrestore(&host->lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -3401,7 +3409,7 @@ void sdhci_remove_host(struct sdhci_host
|
||||
unsigned long flags;
|
||||
|
||||
if (dead) {
|
||||
- sdhci_spin_lock_irqsave(host, &flags);
|
||||
+ spin_lock_irqsave(&host->lock, flags);
|
||||
|
||||
host->flags |= SDHCI_DEVICE_DEAD;
|
||||
|
||||
@@ -3413,7 +3421,7 @@ void sdhci_remove_host(struct sdhci_host
|
||||
tasklet_schedule(&host->finish_tasklet);
|
||||
}
|
||||
|
||||
- sdhci_spin_unlock_irqrestore(host, flags);
|
||||
+ spin_unlock_irqrestore(&host->lock, flags);
|
||||
}
|
||||
|
||||
sdhci_disable_card_detection(host);
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue