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: 39770
This commit is contained in:
Florian Fainelli 2014-02-28 20:30:08 +00:00
parent c6c0d09f85
commit bb39b8d99a
180 changed files with 358176 additions and 11796 deletions

View File

@ -201,6 +201,7 @@ CONFIG_POWER_SUPPLY=y
CONFIG_PRINTK_TIME=y CONFIG_PRINTK_TIME=y
CONFIG_PROC_PAGE_MONITOR=y CONFIG_PROC_PAGE_MONITOR=y
CONFIG_RAW_DRIVER=y CONFIG_RAW_DRIVER=y
# CONFIG_RTL8192CU is not set
CONFIG_SCSI=y CONFIG_SCSI=y
# CONFIG_SCSI_LOWLEVEL is not set # CONFIG_SCSI_LOWLEVEL is not set
# CONFIG_SCSI_PROC_FS is not set # CONFIG_SCSI_PROC_FS is not set

View File

@ -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 --- /dev/null
+++ b/drivers/watchdog/bcm2708_wdog.c +++ b/drivers/watchdog/bcm2708_wdog.c
@@ -0,0 +1,385 @@ @@ -0,0 +1,385 @@
@ -386,28 +424,3 @@
+MODULE_ALIAS_MISCDEV(TEMP_MINOR); +MODULE_ALIAS_MISCDEV(TEMP_MINOR);
+MODULE_LICENSE("GPL"); +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

View File

@ -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 --- /dev/null
+++ b/drivers/video/bcm2708_fb.c +++ b/drivers/video/bcm2708_fb.c
@@ -0,0 +1,647 @@ @@ -0,0 +1,491 @@
+/* +/*
+ * linux/drivers/video/bcm2708_fb.c + * linux/drivers/video/bcm2708_fb.c
+ * + *
@ -31,7 +78,6 @@
+#include <linux/printk.h> +#include <linux/printk.h>
+#include <linux/console.h> +#include <linux/console.h>
+ +
+#include <mach/dma.h>
+#include <mach/platform.h> +#include <mach/platform.h>
+#include <mach/vcio.h> +#include <mach/vcio.h>
+ +
@ -67,11 +113,6 @@
+ struct fbinfo_s *info; + struct fbinfo_s *info;
+ dma_addr_t dma; + dma_addr_t dma;
+ u32 cmap[16]; + 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) +#define to_bcm2708(info) container_of(info, struct bcm2708_fb, fb)
@ -321,133 +362,11 @@
+ cfb_fillrect(info, rect); + 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, +static void bcm2708_fb_copyarea(struct fb_info *info,
+ const struct fb_copyarea *region) + const struct fb_copyarea *region)
+{ +{
+ struct bcm2708_fb *fb = to_bcm2708(info); + /*print_debug("bcm2708_fb_copyarea\n"); */
+ struct bcm2708_dma_cb *cb = fb->cb_base; + cfb_copyarea(info, region);
+ 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, +static void bcm2708_fb_imageblit(struct fb_info *info,
@ -490,7 +409,7 @@
+ fb->dma = dma; + fb->dma = dma;
+ } + }
+ fb->fb.fbops = &bcm2708_fb_ops; + 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; + fb->fb.pseudo_palette = fb->cmap;
+ +
+ strncpy(fb->fb.fix.id, bcm2708_name, sizeof(fb->fb.fix.id)); + strncpy(fb->fb.fix.id, bcm2708_name, sizeof(fb->fb.fix.id));
@ -555,28 +474,6 @@
+ } + }
+ memset(fb, 0, sizeof(struct bcm2708_fb)); + 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; + fb->dev = dev;
+ +
+ ret = bcm2708_fb_register(fb); + ret = bcm2708_fb_register(fb);
@ -585,9 +482,6 @@
+ goto out; + goto out;
+ } + }
+ +
+free_cb:
+ dma_free_writecombine(&dev->dev, SZ_64K, fb->cb_base, fb->cb_handle);
+free_fb:
+ kfree(fb); + kfree(fb);
+free_region: +free_region:
+ dev_err(&dev->dev, "probe failed, err %d\n", ret); + dev_err(&dev->dev, "probe failed, err %d\n", ret);
@ -605,9 +499,6 @@
+ iounmap(fb->fb.screen_base); + iounmap(fb->fb.screen_base);
+ unregister_framebuffer(&fb->fb); + 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, + dma_free_coherent(NULL, PAGE_ALIGN(sizeof(*fb->info)), (void *)fb->info,
+ fb->dma); + fb->dma);
+ kfree(fb); + kfree(fb);
@ -648,264 +539,6 @@
+MODULE_PARM_DESC(fbwidth, "Width of ARM Framebuffer"); +MODULE_PARM_DESC(fbwidth, "Width of ARM Framebuffer");
+MODULE_PARM_DESC(fbheight, "Height of ARM Framebuffer"); +MODULE_PARM_DESC(fbheight, "Height of ARM Framebuffer");
+MODULE_PARM_DESC(fbdepth, "Bit depth 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(&copy, argp, sizeof(copy)))
+ return -EFAULT;
+ ret = fb_copyarea_user(info, &copy);
+ 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 --- a/drivers/video/logo/logo_linux_clut224.ppm
+++ b/drivers/video/logo/logo_linux_clut224.ppm +++ b/drivers/video/logo/logo_linux_clut224.ppm
@@ -1,1604 +1,883 @@ @@ -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 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 */

View File

@ -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 --- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c
@@ -61,6 +61,7 @@ @@ -61,6 +61,7 @@

View File

@ -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,
};
/*****************************************************************************\

View File

@ -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;
}
/***************************************************************************** \

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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");
+

View File

@ -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
/*****************************************************************************\
* *

View File

@ -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");
+

View File

@ -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)

View File

@ -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);

View File

@ -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");

View File

@ -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);

View File

@ -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 */

View File

@ -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");

View File

@ -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)

View File

@ -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);

View File

@ -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 */

View File

@ -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

View File

@ -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);
}
/**

View File

@ -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 --- /dev/null
+++ b/drivers/cpufreq/bcm2835-cpufreq.c +++ b/drivers/cpufreq/bcm2835-cpufreq.c
@@ -0,0 +1,239 @@ @@ -0,0 +1,239 @@
@ -240,27 +287,3 @@
+module_init(bcm2835_cpufreq_module_init); +module_init(bcm2835_cpufreq_module_init);
+module_exit(bcm2835_cpufreq_module_exit); +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

View File

@ -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. */

View File

@ -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);

View File

@ -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 */

View File

@ -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[] = {

View File

@ -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;

View File

@ -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>");

View File

@ -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");

View File

@ -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);

View File

@ -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;
}

View File

@ -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 --- a/drivers/staging/media/lirc/Kconfig
+++ b/drivers/staging/media/lirc/Kconfig +++ b/drivers/staging/media/lirc/Kconfig
@@ -38,6 +38,12 @@ config LIRC_PARALLEL @@ -38,6 +38,12 @@ config LIRC_PARALLEL
@ -13,9 +25,19 @@
config LIRC_SASEM config LIRC_SASEM
tristate "Sasem USB IR Remote" tristate "Sasem USB IR Remote"
depends on LIRC && USB 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 --- /dev/null
+++ b/drivers/staging/media/lirc/lirc_rpi.c +++ b/drivers/staging/media/lirc/lirc_rpi.c
@@ -0,0 +1,692 @@ @@ -0,0 +1,687 @@
+/* +/*
+ * lirc_rpi.c + * lirc_rpi.c
+ * + *
@ -86,8 +108,6 @@
+static int sense = -1; +static int sense = -1;
+/* use softcarrier by default */ +/* use softcarrier by default */
+static int softcarrier = 1; +static int softcarrier = 1;
+/* 0 = do not invert output, 1 = invert output */
+static int invert = 0;
+ +
+struct gpio_chip *gpiochip; +struct gpio_chip *gpiochip;
+struct irq_chip *irqchip; +struct irq_chip *irqchip;
@ -155,10 +175,10 @@
+ actual = 0; target = 0; flag = 0; + actual = 0; target = 0; flag = 0;
+ while (actual < length) { + while (actual < length) {
+ if (flag) { + if (flag) {
+ gpiochip->set(gpiochip, gpio_out_pin, invert); + gpiochip->set(gpiochip, gpio_out_pin, 0);
+ target += space_width; + target += space_width;
+ } else { + } else {
+ gpiochip->set(gpiochip, gpio_out_pin, !invert); + gpiochip->set(gpiochip, gpio_out_pin, 1);
+ target += pulse_width; + target += pulse_width;
+ } + }
+ d = (target - actual - + d = (target - actual -
@ -182,7 +202,7 @@
+ if (softcarrier) { + if (softcarrier) {
+ return send_pulse_softcarrier(length); + return send_pulse_softcarrier(length);
+ } else { + } else {
+ gpiochip->set(gpiochip, gpio_out_pin, !invert); + gpiochip->set(gpiochip, gpio_out_pin, 1);
+ safe_udelay(length); + safe_udelay(length);
+ return 0; + return 0;
+ } + }
@ -190,7 +210,7 @@
+ +
+static void send_space(long length) +static void send_space(long length)
+{ +{
+ gpiochip->set(gpiochip, gpio_out_pin, invert); + gpiochip->set(gpiochip, gpio_out_pin, 0);
+ if (length <= 0) + if (length <= 0)
+ return; + return;
+ safe_udelay(length); + safe_udelay(length);
@ -338,7 +358,7 @@
+ +
+ gpiochip->direction_input(gpiochip, gpio_in_pin); + gpiochip->direction_input(gpiochip, gpio_in_pin);
+ gpiochip->direction_output(gpiochip, gpio_out_pin, 1); + 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); + irq = gpiochip->to_irq(gpiochip, gpio_in_pin);
+ dprintk("to_irq %d\n", irq); + dprintk("to_irq %d\n", irq);
@ -477,7 +497,7 @@
+ else + else
+ delta = send_pulse(wbuf[i]); + delta = send_pulse(wbuf[i]);
+ } + }
+ gpiochip->set(gpiochip, gpio_out_pin, invert); + gpiochip->set(gpiochip, gpio_out_pin, 0);
+ +
+ spin_unlock_irqrestore(&lock, flags); + spin_unlock_irqrestore(&lock, flags);
+ kfree(wbuf); + kfree(wbuf);
@ -703,18 +723,5 @@
+module_param(softcarrier, bool, S_IRUGO); +module_param(softcarrier, bool, S_IRUGO);
+MODULE_PARM_DESC(softcarrier, "Software carrier (0 = off, 1 = on, default on)"); +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_param(debug, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Enable debugging messages"); +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

View File

@ -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,

View File

@ -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);

View File

@ -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,

View File

@ -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;

View File

@ -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 --- /dev/null
+++ b/drivers/char/hw_random/bcm2708-rng.c +++ b/drivers/char/hw_random/bcm2708-rng.c
@@ -0,0 +1,117 @@ @@ -0,0 +1,117 @@
@ -118,28 +166,3 @@
+ +
+MODULE_DESCRIPTION("BCM2708 H/W Random Number Generator (RNG) driver"); +MODULE_DESCRIPTION("BCM2708 H/W Random Number Generator (RNG) driver");
+MODULE_LICENSE("GPL and additional rights"); +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

View File

@ -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++)

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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");

View File

@ -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)
{

View File

@ -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);

View File

@ -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) {
/*

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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);

View File

@ -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);
+

View File

@ -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) {

View File

@ -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;

View File

@ -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

View File

@ -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");

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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;

View File

@ -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

View File

@ -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(&copy, argp, sizeof(copy)))
+ return -EFAULT;
+ ret = fb_copyarea_user(info, &copy);
+ 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 */

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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)
{

View File

@ -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)

View File

@ -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");
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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 */

View File

@ -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;
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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. */

View File

@ -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,

View File

@ -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

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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:

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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");

View File

@ -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

View File

@ -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 */ \

View File

@ -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