From 35e1fe37f02aeea215bf08ce56bea2d5f6d543ee Mon Sep 17 00:00:00 2001 From: Stephan Raue Date: Sun, 25 Jan 2015 13:48:24 +0100 Subject: [PATCH] projects/RPi/patches/linux: update RPi support patch Signed-off-by: Stephan Raue --- .../patches/linux/linux-01-RPi_support.patch | 10506 ++++++++++------ 1 file changed, 6854 insertions(+), 3652 deletions(-) diff --git a/projects/RPi/patches/linux/linux-01-RPi_support.patch b/projects/RPi/patches/linux/linux-01-RPi_support.patch index 55e101000b..5735ee1586 100644 --- a/projects/RPi/patches/linux/linux-01-RPi_support.patch +++ b/projects/RPi/patches/linux/linux-01-RPi_support.patch @@ -1,7 +1,7 @@ -From e06cd62d169985e2dc8ad7018d624d24a09ab8e5 Mon Sep 17 00:00:00 2001 +From fb6c72d2652c2bca95e3388f79b57f545c10d44a Mon Sep 17 00:00:00 2001 From: popcornmix Date: Sun, 12 May 2013 12:24:19 +0100 -Subject: [PATCH 01/87] Main bcm2708 linux port +Subject: [PATCH 01/76] Main bcm2708 linux port Signed-off-by: popcornmix --- @@ -29,7 +29,7 @@ Signed-off-by: popcornmix arch/arm/mach-bcm2708/include/mach/frc.h | 38 ++ arch/arm/mach-bcm2708/include/mach/hardware.h | 28 + arch/arm/mach-bcm2708/include/mach/io.h | 27 + - arch/arm/mach-bcm2708/include/mach/irqs.h | 194 +++++++ + arch/arm/mach-bcm2708/include/mach/irqs.h | 196 +++++++ arch/arm/mach-bcm2708/include/mach/memory.h | 57 ++ arch/arm/mach-bcm2708/include/mach/platform.h | 228 ++++++++ arch/arm/mach-bcm2708/include/mach/power.h | 26 + @@ -48,7 +48,7 @@ Signed-off-by: popcornmix drivers/tty/serial/amba-pl011.c | 2 +- include/linux/mmc/host.h | 1 + include/linux/mmc/sdhci.h | 1 + - 43 files changed, 4715 insertions(+), 5 deletions(-) + 43 files changed, 4717 insertions(+), 5 deletions(-) create mode 100644 arch/arm/configs/bcmrpi_defconfig create mode 100644 arch/arm/mach-bcm2708/Kconfig create mode 100644 arch/arm/mach-bcm2708/Makefile @@ -695,7 +695,7 @@ index 0000000..67039c3 +initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-bcm2708/armctrl.c b/arch/arm/mach-bcm2708/armctrl.c new file mode 100644 -index 0000000..efade23 +index 0000000..ef1c8d5 --- /dev/null +++ b/arch/arm/mach-bcm2708/armctrl.c @@ -0,0 +1,208 @@ @@ -893,7 +893,7 @@ index 0000000..efade23 +{ + unsigned int irq; + -+ for (irq = 0; irq < NR_IRQS; irq++) { ++ for (irq = 0; irq < BCM2708_ALLOC_IRQS; irq++) { + unsigned int data = irq; + if (irq >= INTERRUPT_JPEG && irq <= INTERRUPT_ARASANSDIO) + data = remap_irqs[irq - INTERRUPT_JPEG]; @@ -2981,10 +2981,10 @@ index 0000000..e6eb84d +#endif diff --git a/arch/arm/mach-bcm2708/include/mach/irqs.h b/arch/arm/mach-bcm2708/include/mach/irqs.h new file mode 100644 -index 0000000..faf5d1a +index 0000000..3a88a1a --- /dev/null +++ b/arch/arm/mach-bcm2708/include/mach/irqs.h -@@ -0,0 +1,194 @@ +@@ -0,0 +1,196 @@ +/* + * arch/arm/mach-bcm2708/include/mach/irqs.h + * @@ -3175,8 +3175,10 @@ index 0000000..faf5d1a +#define HARD_IRQS (64 + 21) +#define GPIO_IRQ_START (HARD_IRQS) +#define GPIO_IRQS (32*5) -+#define SPARE_IRQS (64) -+#define NR_IRQS (HARD_IRQS+GPIO_IRQS+SPARE_IRQS) ++#define SPARE_ALLOC_IRQS 64 ++#define BCM2708_ALLOC_IRQS (HARD_IRQS+FIQ_IRQS+GPIO_IRQS+SPARE_ALLOC_IRQS) ++#define FREE_IRQS 128 ++#define NR_IRQS (BCM2708_ALLOC_IRQS+FREE_IRQS) + +#endif /* _BCM2708_IRQS_H_ */ diff --git a/arch/arm/mach-bcm2708/include/mach/memory.h b/arch/arm/mach-bcm2708/include/mach/memory.h @@ -5120,10 +5122,10 @@ index dba793e..9300f87 100644 unsigned int version; /* SDHCI spec. version */ -From 53ce5129b52eff70f734862a174754ca7f85c829 Mon Sep 17 00:00:00 2001 +From 942d904dc6a0ee26c45cacdf732e8949bfa47466 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 8 Oct 2014 18:50:05 +0100 -Subject: [PATCH 02/87] Add bcm2708_gpio driver +Subject: [PATCH 02/76] Add bcm2708_gpio driver Signed-off-by: popcornmix @@ -5135,14 +5137,34 @@ change the pull configuration from it's default pull-down state, add an extension which allows configuring the pull per gpio. Signed-off-by: Julian Scheel + +bcm2708-gpio: Revert the use of pinctrl_request_gpio + +In non-DT systems, pinctrl_request_gpio always fails causing +"requests probe deferral" messages. In DT systems, it isn't useful +because the reference counting is independent of the normal pinctrl +pin reservations. + +gpio: Only clear the currently occurring interrupt. Avoids losing interrupts + +See: linux #760 + +bcm2708_gpio: Avoid calling irq_unmask for all interrupts + +When setting up the interrupts, specify that the handle_simple_irq +handler should be used. This leaves interrupt acknowledgement to +the caller, and prevents irq_unmask from being called for all +interrupts. + +Issue: linux #760 --- arch/arm/mach-bcm2708/Kconfig | 8 + arch/arm/mach-bcm2708/Makefile | 1 + - arch/arm/mach-bcm2708/bcm2708.c | 28 +++ - arch/arm/mach-bcm2708/bcm2708_gpio.c | 401 ++++++++++++++++++++++++++++++ + arch/arm/mach-bcm2708/bcm2708.c | 28 ++ + arch/arm/mach-bcm2708/bcm2708_gpio.c | 426 ++++++++++++++++++++++++++++++ arch/arm/mach-bcm2708/include/mach/gpio.h | 17 ++ include/linux/platform_data/bcm2708.h | 23 ++ - 6 files changed, 478 insertions(+) + 6 files changed, 503 insertions(+) create mode 100644 arch/arm/mach-bcm2708/bcm2708_gpio.c create mode 100644 arch/arm/mach-bcm2708/include/mach/gpio.h create mode 100644 include/linux/platform_data/bcm2708.h @@ -5224,10 +5246,10 @@ index 9b4e709..7503649 100644 bcm_register_device(&bcm2708_usb_device); diff --git a/arch/arm/mach-bcm2708/bcm2708_gpio.c b/arch/arm/mach-bcm2708/bcm2708_gpio.c new file mode 100644 -index 0000000..97c8245 +index 0000000..c1e9254 --- /dev/null +++ b/arch/arm/mach-bcm2708/bcm2708_gpio.c -@@ -0,0 +1,401 @@ +@@ -0,0 +1,426 @@ +/* + * linux/arch/arm/mach-bcm2708/bcm2708_gpio.c + * @@ -5251,6 +5273,7 @@ index 0000000..97c8245 +#include +#include +#include ++#include + +#include + @@ -5272,6 +5295,8 @@ index 0000000..97c8245 +#define GPIOUD(x) (0x94+(x)*4) +#define GPIOUDCLK(x) (0x98+(x)*4) + ++#define GPIO_BANKS 2 ++ +enum { GPIO_FSEL_INPUT, GPIO_FSEL_OUTPUT, + GPIO_FSEL_ALT5, GPIO_FSEL_ALT_4, + GPIO_FSEL_ALT0, GPIO_FSEL_ALT1, @@ -5468,8 +5493,6 @@ index 0000000..97c8245 + unsigned long high = readl(gpio->base + GPIOHEN(gb)); + unsigned long low = readl(gpio->base + GPIOLEN(gb)); + -+ writel(1 << go, gpio->base + GPIOEDS(gb)); -+ + if (gpio->rising[gb] & (1 << go)) { + writel(rising | (1 << go), gpio->base + GPIOREN(gb)); + } else { @@ -5510,13 +5533,25 @@ index 0000000..97c8245 + unsigned bank; + int i; + unsigned gpio; -+ for (bank = 0; bank <= 1; bank++) { ++ unsigned level_bits; ++ struct bcm2708_gpio *gpio_data = dev_id; ++ ++ for (bank = 0; bank < GPIO_BANKS; bank++) { + edsr = readl(__io_address(GPIO_BASE) + GPIOEDS(bank)); ++ level_bits = gpio_data->high[bank] | gpio_data->low[bank]; ++ + for_each_set_bit(i, &edsr, 32) { + gpio = i + bank * 32; ++ /* ack edge triggered IRQs immediately */ ++ if (!(level_bits & (1<gc.set = bcm2708_gpio_set; + ucb->gc.can_sleep = 0; + ++ for (bank = 0; bank < GPIO_BANKS; bank++) { ++ writel(0, ucb->base + GPIOREN(bank)); ++ writel(0, ucb->base + GPIOFEN(bank)); ++ writel(0, ucb->base + GPIOHEN(bank)); ++ writel(0, ucb->base + GPIOLEN(bank)); ++ writel(0, ucb->base + GPIOAREN(bank)); ++ writel(0, ucb->base + GPIOAFEN(bank)); ++ writel(~0, ucb->base + GPIOEDS(bank)); ++ } ++ + bcm2708_gpio_irq_init(ucb); + + err = gpiochip_add(&ucb->gc); -+ if (err) -+ goto err; + +err: + return err; @@ -5682,10 +5729,10 @@ index 0000000..fb69624 + +#endif -From a0917ecb05a1cda23451e92288020506596ae7c9 Mon Sep 17 00:00:00 2001 +From d9779b67b9edf0bc01d6f5803ce2c961c15977fd Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 7 May 2013 22:20:24 +0100 -Subject: [PATCH 03/87] Add quick config. +Subject: [PATCH 03/76] Add quick config. This is designed for quick compiling when developing. No modules are needed and it includes all Pi specific drivers @@ -5898,10 +5945,10 @@ index 0000000..e5efe75 +CONFIG_CRC_ITU_T=y +CONFIG_LIBCRC32C=y -From 98dc742d7dc83b824b5a4b990dbe34b96172efc7 Mon Sep 17 00:00:00 2001 +From b010b43050ed7c24a31e82b05b66fde7e3d53ca0 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 1 May 2013 19:46:17 +0100 -Subject: [PATCH 04/87] Add dwc_otg driver +Subject: [PATCH 04/76] Add dwc_otg driver Signed-off-by: popcornmix @@ -63004,10 +63051,10 @@ index 0000000..cdc9963 +test_main(); +0; -From 2f65a140b82fd08c4774802fd038539d6e2de510 Mon Sep 17 00:00:00 2001 +From 3e6a088bdcf2e8c6fe8d870d1eb63e709586b6d9 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 1 May 2013 19:54:32 +0100 -Subject: [PATCH 05/87] bcm2708 watchdog driver +Subject: [PATCH 05/76] bcm2708 watchdog driver Signed-off-by: popcornmix --- @@ -63435,24 +63482,409 @@ index 0000000..8a27d68 +MODULE_ALIAS_MISCDEV(TEMP_MINOR); +MODULE_LICENSE("GPL"); -From 1c10683e3ffe66fdd733aa56780693226b01e084 Mon Sep 17 00:00:00 2001 + +From 3c120c31ef0751e438aa89c6c014c4dd8185dba3 Mon Sep 17 00:00:00 2001 +From: Harm Hanemaaijer +Date: Thu, 20 Jun 2013 20:21:39 +0200 +Subject: [PATCH 07/76] 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 +--- + drivers/video/fbdev/core/cfbimgblt.c | 152 +++++++++++++++++++++++++++++++++-- + 1 file changed, 147 insertions(+), 5 deletions(-) + +diff --git a/drivers/video/fbdev/core/cfbimgblt.c b/drivers/video/fbdev/core/cfbimgblt.c +index a2bb276..436494f 100644 +--- a/drivers/video/fbdev/core/cfbimgblt.c ++++ b/drivers/video/fbdev/core/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 + #include +@@ -262,6 +267,133 @@ static inline void fast_imageblit(const struct fb_image *image, struct fb_info * + } + } + ++/* ++ * 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, const struct fb_image *image) + 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 + +From 4106beb2f536eaa4d00e4c34fecb840edb972688 Mon Sep 17 00:00:00 2001 +From: Siarhei Siamashka +Date: Mon, 17 Jun 2013 13:32:11 +0300 +Subject: [PATCH 08/76] 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 +--- + drivers/video/fbdev/core/fbmem.c | 30 ++++++++++++++++++++++++++++++ + include/uapi/linux/fb.h | 5 +++++ + 2 files changed, 35 insertions(+) + +diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c +index 0705d88..771992a 100644 +--- a/drivers/video/fbdev/core/fbmem.c ++++ b/drivers/video/fbdev/core/fbmem.c +@@ -1084,6 +1084,25 @@ fb_blank(struct fb_info *info, int blank) + } + EXPORT_SYMBOL(fb_blank); + ++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) + { +@@ -1094,6 +1113,7 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, + 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; + +@@ -1211,6 +1231,15 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, + unlock_fb_info(info); + console_unlock(); + break; ++ case FBIOCOPYAREA: ++ if (info->flags & FBINFO_HWACCEL_COPYAREA) { ++ /* only provide this ioctl if it is accelerated */ ++ if (copy_from_user(©, argp, sizeof(copy))) ++ return -EFAULT; ++ ret = fb_copyarea_user(info, ©); ++ break; ++ } ++ /* fall through */ + default: + if (!lock_fb_info(info)) + return -ENODEV; +@@ -1365,6 +1394,7 @@ static long fb_compat_ioctl(struct file *file, unsigned int cmd, + 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); +diff --git a/include/uapi/linux/fb.h b/include/uapi/linux/fb.h +index fb795c3..fa72af0 100644 +--- 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 */ + +From 804773518c0a9ff9ee6e12fc81d5c85ee636c374 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 1 May 2013 19:55:09 +0100 -Subject: [PATCH 06/87] bcm2708 framebuffer driver +Subject: [PATCH 09/76] bcm2708 framebuffer driver Signed-off-by: popcornmix bcm2708_fb : Implement blanking support using the mailbox property interface bcm2708_fb: Add pan and vsync controls + +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 + +bcm2708_fb: report number of dma copies + +Add a counter (exported via debugfs) reporting the +number of dma copies that the framebuffer driver +has done, in order to help evaluate different +optimization strategies. + +Signed-off-by: Luke Diamand + +bcm2708_fb: use IRQ for DMA copies + +The copyarea ioctl() uses DMA to speed things along. This +was busy-waiting for completion. This change supports using +an interrupt instead for larger transfers. For small +transfers, busy-waiting is still likely to be faster. + +Signed-off-by: Luke Diamand --- + arch/arm/mach-bcm2708/dma.c | 8 + + arch/arm/mach-bcm2708/include/mach/dma.h | 2 + drivers/video/fbdev/Kconfig | 14 + drivers/video/fbdev/Makefile | 1 + - drivers/video/fbdev/bcm2708_fb.c | 557 +++++++ + drivers/video/fbdev/bcm2708_fb.c | 818 ++++++++++ drivers/video/logo/logo_linux_clut224.ppm | 2483 ++++++++++------------------- - 4 files changed, 1453 insertions(+), 1602 deletions(-) + 6 files changed, 1724 insertions(+), 1602 deletions(-) create mode 100644 drivers/video/fbdev/bcm2708_fb.c +diff --git a/arch/arm/mach-bcm2708/dma.c b/arch/arm/mach-bcm2708/dma.c +index 51d147a..1da2413 100644 +--- a/arch/arm/mach-bcm2708/dma.c ++++ b/arch/arm/mach-bcm2708/dma.c +@@ -83,6 +83,14 @@ extern void bcm_dma_wait_idle(void __iomem *dma_chan_base) + + EXPORT_SYMBOL_GPL(bcm_dma_start); + ++extern bool bcm_dma_is_busy(void __iomem *dma_chan_base) ++{ ++ dsb(); ++ ++ return readl(dma_chan_base + BCM2708_DMA_CS) & BCM2708_DMA_ACTIVE; ++} ++EXPORT_SYMBOL_GPL(bcm_dma_is_busy); ++ + /* Complete an ongoing DMA (assuming its results are to be ignored) + Does nothing if there is no DMA in progress. + This routine waits for the current AXI transfer to complete before +diff --git a/arch/arm/mach-bcm2708/include/mach/dma.h b/arch/arm/mach-bcm2708/include/mach/dma.h +index f2568d4..a4aac4c 100644 +--- a/arch/arm/mach-bcm2708/include/mach/dma.h ++++ b/arch/arm/mach-bcm2708/include/mach/dma.h +@@ -64,11 +64,13 @@ struct bcm2708_dma_cb { + unsigned long next; + unsigned long pad[2]; + }; ++struct scatterlist; + + extern int bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, int sg_len); + extern void bcm_dma_start(void __iomem *dma_chan_base, + dma_addr_t control_block); + extern void bcm_dma_wait_idle(void __iomem *dma_chan_base); ++extern bool bcm_dma_is_busy(void __iomem *dma_chan_base); + extern int /*rc*/ bcm_dma_abort(void __iomem *dma_chan_base); + + /* When listing features we can ask for when allocating DMA channels give diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index c7bf606..0349473 100644 --- a/drivers/video/fbdev/Kconfig @@ -63492,10 +63924,10 @@ index 1979aff..57181ad 100644 obj-$(CONFIG_FB_CLPS711X) += clps711x-fb.o diff --git a/drivers/video/fbdev/bcm2708_fb.c b/drivers/video/fbdev/bcm2708_fb.c new file mode 100644 -index 0000000..ac04125 +index 0000000..a443666 --- /dev/null +++ b/drivers/video/fbdev/bcm2708_fb.c -@@ -0,0 +1,557 @@ +@@ -0,0 +1,818 @@ +/* + * linux/drivers/video/bcm2708_fb.c + * @@ -63519,13 +63951,16 @@ index 0000000..ac04125 +#include +#include +#include ++#include +#include +#include +#include +#include +#include +#include ++#include + ++#include +#include +#include + @@ -63552,6 +63987,10 @@ index 0000000..ac04125 +static int fbdepth = 16; /* module parameter */ +static int fbswap = 0; /* module parameter */ + ++static u32 dma_busy_wait_threshold = 1<<15; ++module_param(dma_busy_wait_threshold, int, 0644); ++MODULE_PARM_DESC(dma_busy_wait_threshold, "Busy-wait for DMA completion below this area"); ++ +/* this data structure describes each frame buffer device we find */ + +struct fbinfo_s { @@ -63563,16 +64002,74 @@ index 0000000..ac04125 + u16 cmap[256]; +}; + ++struct bcm2708_fb_stats { ++ struct debugfs_regset32 regset; ++ u32 dma_copies; ++ u32 dma_irqs; ++}; ++ +struct bcm2708_fb { + struct fb_info fb; + struct platform_device *dev; + 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; ++ struct dentry *debugfs_dir; ++ wait_queue_head_t dma_waitq; ++ struct bcm2708_fb_stats stats; ++ unsigned long fb_bus_address; +}; + +#define to_bcm2708(info) container_of(info, struct bcm2708_fb, fb) + ++static void bcm2708_fb_debugfs_deinit(struct bcm2708_fb *fb) ++{ ++ debugfs_remove_recursive(fb->debugfs_dir); ++ fb->debugfs_dir = NULL; ++} ++ ++static int bcm2708_fb_debugfs_init(struct bcm2708_fb *fb) ++{ ++ static struct debugfs_reg32 stats_registers[] = { ++ { ++ "dma_copies", ++ offsetof(struct bcm2708_fb_stats, dma_copies) ++ }, ++ { ++ "dma_irqs", ++ offsetof(struct bcm2708_fb_stats, dma_irqs) ++ }, ++ }; ++ ++ fb->debugfs_dir = debugfs_create_dir(DRIVER_NAME, NULL); ++ if (!fb->debugfs_dir) { ++ pr_warn("%s: could not create debugfs entry\n", ++ __func__); ++ return -EFAULT; ++ } ++ ++ fb->stats.regset.regs = stats_registers; ++ fb->stats.regset.nregs = ARRAY_SIZE(stats_registers); ++ fb->stats.regset.base = &fb->stats; ++ ++ if (!debugfs_create_regset32( ++ "stats", 0444, fb->debugfs_dir, &fb->stats.regset)) { ++ pr_warn("%s: could not create statistics registers\n", ++ __func__); ++ goto fail; ++ } ++ return 0; ++ ++fail: ++ bcm2708_fb_debugfs_deinit(fb); ++ return -EFAULT; ++} ++ +static int bcm2708_fb_set_bitfields(struct fb_var_screeninfo *var) +{ + int ret = 0; @@ -63701,12 +64198,6 @@ index 0000000..ac04125 + else if (var->vmode & FB_VMODE_INTERLACED) + yres = (yres + 1) / 2; + -+ if (var->xres * yres > 1920 * 1200) { -+ pr_err("bcm2708_fb_check_var: ERROR: Pixel size >= 1920x1200; " -+ "special treatment required! (TODO)\n"); -+ return -EINVAL; -+ } -+ + return 0; +} + @@ -63751,13 +64242,15 @@ index 0000000..ac04125 + else + fb->fb.fix.visual = FB_VISUAL_TRUECOLOR; + ++ fb->fb_bus_address = fbinfo->base; ++ fbinfo->base &= ~0xc0000000; + fb->fb.fix.smem_start = fbinfo->base; + fb->fb.fix.smem_len = fbinfo->pitch * fbinfo->yres_virtual; + fb->fb.screen_size = fbinfo->screen_size; + if (fb->fb.screen_base) + iounmap(fb->fb.screen_base); + fb->fb.screen_base = -+ (void *)ioremap_wc(fb->fb.fix.smem_start, fb->fb.screen_size); ++ (void *)ioremap_wc(fbinfo->base, fb->fb.screen_size); + if (!fb->fb.screen_base) { + /* the console may currently be locked */ + console_trylock(); @@ -63768,7 +64261,7 @@ index 0000000..ac04125 + } + print_debug + ("BCM2708FB: start = %p,%p width=%d, height=%d, bpp=%d, pitch=%d size=%d success=%d\n", -+ (void *)fb->fb.screen_base, (void *)fb->fb.fix.smem_start, ++ (void *)fb->fb.screen_base, (void *)fb->fb_bus_address, + fbinfo->xres, fbinfo->yres, fbinfo->bpp, + fbinfo->pitch, (int)fb->fb.screen_size, val); + @@ -63875,11 +64368,149 @@ index 0000000..ac04125 + 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; ++ int pixels = region->width * region->height; ++ ++ /* Fallback to cfb_copyarea() if we don't like something */ ++ if (in_atomic() || ++ bytes_per_pixel > 4 || ++ info->var.xres * info->var.yres > 1920 * 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_bus_address + ++ bytes_per_pixel * region->sx + ++ (region->sy + y) * fb->fb.fix.line_length; ++ dma_addr_t dst = ++ fb->fb_bus_address + ++ 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_bus_address + dy * fb->fb.fix.line_length + ++ bytes_per_pixel * region->dx, ++ stride, ++ fb->fb_bus_address + 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; ++ ++ ++ if (pixels < dma_busy_wait_threshold) { ++ bcm_dma_start(fb->dma_chan_base, fb->cb_handle); ++ bcm_dma_wait_idle(fb->dma_chan_base); ++ } else { ++ void __iomem *dma_chan = fb->dma_chan_base; ++ cb->info |= BCM2708_DMA_INT_EN; ++ bcm_dma_start(fb->dma_chan_base, fb->cb_handle); ++ while (bcm_dma_is_busy(dma_chan)) { ++ wait_event_interruptible( ++ fb->dma_waitq, ++ !bcm_dma_is_busy(dma_chan)); ++ } ++ fb->stats.dma_irqs++; ++ } ++ fb->stats.dma_copies++; +} + +static void bcm2708_fb_imageblit(struct fb_info *info, @@ -63889,6 +64520,24 @@ index 0000000..ac04125 + cfb_imageblit(info, image); +} + ++static irqreturn_t bcm2708_fb_dma_irq(int irq, void *cxt) ++{ ++ struct bcm2708_fb *fb = cxt; ++ ++ /* FIXME: should read status register to check if this is ++ * actually interrupting us or not, in case this interrupt ++ * ever becomes shared amongst several DMA channels ++ * ++ * readl(dma_chan_base + BCM2708_DMA_CS) & BCM2708_DMA_IRQ; ++ */ ++ ++ /* acknowledge the interrupt */ ++ writel(BCM2708_DMA_INT, fb->dma_chan_base + BCM2708_DMA_CS); ++ ++ wake_up(&fb->dma_waitq); ++ return IRQ_HANDLED; ++} ++ +static struct fb_ops bcm2708_fb_ops = { + .owner = THIS_MODULE, + .fb_check_var = bcm2708_fb_check_var, @@ -63920,7 +64569,7 @@ index 0000000..ac04125 + 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)); @@ -63951,6 +64600,7 @@ index 0000000..ac04125 + fb->fb.monspecs.dclkmax = 100000000; + + bcm2708_fb_set_bitfields(&fb->fb.var); ++ init_waitqueue_head(&fb->dma_waitq); + + /* + * Allocate colourmap. @@ -63977,14 +64627,45 @@ index 0000000..ac04125 + struct bcm2708_fb *fb; + int ret; + -+ fb = kmalloc(sizeof(struct bcm2708_fb), GFP_KERNEL); ++ fb = kzalloc(sizeof(struct bcm2708_fb), GFP_KERNEL); + if (!fb) { + dev_err(&dev->dev, + "could not allocate new bcm2708_fb struct\n"); + ret = -ENOMEM; + goto free_region; + } -+ memset(fb, 0, sizeof(struct bcm2708_fb)); ++ ++ bcm2708_fb_debugfs_init(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; ++ ++ ret = request_irq(fb->dma_irq, bcm2708_fb_dma_irq, ++ 0, "bcm2708_fb dma", fb); ++ if (ret) { ++ pr_err("%s: failed to request DMA irq\n", __func__); ++ goto free_dma_chan; ++ } ++ ++ ++ pr_info("BCM2708FB: allocated DMA channel %d @ %p\n", ++ fb->dma_chan, fb->dma_chan_base); + + fb->dev = dev; + @@ -63994,6 +64675,11 @@ index 0000000..ac04125 + goto out; + } + ++free_dma_chan: ++ bcm_dma_chan_free(fb->dma_chan); ++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); @@ -64011,8 +64697,15 @@ index 0000000..ac04125 + 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); ++ bcm2708_fb_debugfs_deinit(fb); ++ ++ free_irq(fb->dma_irq, fb); ++ + kfree(fb); + + return 0; @@ -66544,805 +67237,10 @@ index 3c14e43..7626beb 100644 +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 -From abd46c08f49df3d6cddd1e7371a296640dede01d Mon Sep 17 00:00:00 2001 -From: Harm Hanemaaijer -Date: Thu, 20 Jun 2013 20:21:39 +0200 -Subject: [PATCH 07/87] 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 ---- - drivers/video/fbdev/core/cfbimgblt.c | 152 +++++++++++++++++++++++++++++++++-- - 1 file changed, 147 insertions(+), 5 deletions(-) - -diff --git a/drivers/video/fbdev/core/cfbimgblt.c b/drivers/video/fbdev/core/cfbimgblt.c -index a2bb276..436494f 100644 ---- a/drivers/video/fbdev/core/cfbimgblt.c -+++ b/drivers/video/fbdev/core/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 - #include -@@ -262,6 +267,133 @@ static inline void fast_imageblit(const struct fb_image *image, struct fb_info * - } - } - -+/* -+ * 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, const struct fb_image *image) - 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 - -From 8ebfecfe9cac285c783391afc54f2906c12ec374 Mon Sep 17 00:00:00 2001 -From: Siarhei Siamashka -Date: Mon, 17 Jun 2013 13:32:11 +0300 -Subject: [PATCH 08/87] 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 ---- - drivers/video/fbdev/core/fbmem.c | 30 ++++++++++++++++++++++++++++++ - include/uapi/linux/fb.h | 5 +++++ - 2 files changed, 35 insertions(+) - -diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c -index 0705d88..771992a 100644 ---- a/drivers/video/fbdev/core/fbmem.c -+++ b/drivers/video/fbdev/core/fbmem.c -@@ -1084,6 +1084,25 @@ fb_blank(struct fb_info *info, int blank) - } - EXPORT_SYMBOL(fb_blank); - -+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) - { -@@ -1094,6 +1113,7 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, - 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; - -@@ -1211,6 +1231,15 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, - unlock_fb_info(info); - console_unlock(); - break; -+ case FBIOCOPYAREA: -+ if (info->flags & FBINFO_HWACCEL_COPYAREA) { -+ /* only provide this ioctl if it is accelerated */ -+ if (copy_from_user(©, argp, sizeof(copy))) -+ return -EFAULT; -+ ret = fb_copyarea_user(info, ©); -+ break; -+ } -+ /* fall through */ - default: - if (!lock_fb_info(info)) - return -ENODEV; -@@ -1365,6 +1394,7 @@ static long fb_compat_ioctl(struct file *file, unsigned int cmd, - 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); -diff --git a/include/uapi/linux/fb.h b/include/uapi/linux/fb.h -index fb795c3..fa72af0 100644 ---- 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 */ - -From 00f3af8c01c3223d8ea5475e1db1a70ef4f4d027 Mon Sep 17 00:00:00 2001 -From: Siarhei Siamashka -Date: Mon, 17 Jun 2013 16:00:25 +0300 -Subject: [PATCH 09/87] 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 - -bcm2708_fb: report number of dma copies - -Add a counter (exported via debugfs) reporting the -number of dma copies that the framebuffer driver -has done, in order to help evaluate different -optimization strategies. - -Signed-off-by: Luke Diamand - -bcm2708_fb: use IRQ for DMA copies - -The copyarea ioctl() uses DMA to speed things along. This -was busy-waiting for completion. This change supports using -an interrupt instead for larger transfers. For small -transfers, busy-waiting is still likely to be faster. - -Signed-off-by: Luke Diamand - -fb: distinguish physical and bus addresses ---- - arch/arm/mach-bcm2708/dma.c | 8 + - arch/arm/mach-bcm2708/include/mach/dma.h | 2 + - drivers/video/fbdev/bcm2708_fb.c | 280 ++++++++++++++++++++++++++++++- - 3 files changed, 283 insertions(+), 7 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/dma.c b/arch/arm/mach-bcm2708/dma.c -index 51d147a..1da2413 100644 ---- a/arch/arm/mach-bcm2708/dma.c -+++ b/arch/arm/mach-bcm2708/dma.c -@@ -83,6 +83,14 @@ extern void bcm_dma_wait_idle(void __iomem *dma_chan_base) - - EXPORT_SYMBOL_GPL(bcm_dma_start); - -+extern bool bcm_dma_is_busy(void __iomem *dma_chan_base) -+{ -+ dsb(); -+ -+ return readl(dma_chan_base + BCM2708_DMA_CS) & BCM2708_DMA_ACTIVE; -+} -+EXPORT_SYMBOL_GPL(bcm_dma_is_busy); -+ - /* Complete an ongoing DMA (assuming its results are to be ignored) - Does nothing if there is no DMA in progress. - This routine waits for the current AXI transfer to complete before -diff --git a/arch/arm/mach-bcm2708/include/mach/dma.h b/arch/arm/mach-bcm2708/include/mach/dma.h -index f2568d4..a4aac4c 100644 ---- a/arch/arm/mach-bcm2708/include/mach/dma.h -+++ b/arch/arm/mach-bcm2708/include/mach/dma.h -@@ -64,11 +64,13 @@ struct bcm2708_dma_cb { - unsigned long next; - unsigned long pad[2]; - }; -+struct scatterlist; - - extern int bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, int sg_len); - extern void bcm_dma_start(void __iomem *dma_chan_base, - dma_addr_t control_block); - extern void bcm_dma_wait_idle(void __iomem *dma_chan_base); -+extern bool bcm_dma_is_busy(void __iomem *dma_chan_base); - extern int /*rc*/ bcm_dma_abort(void __iomem *dma_chan_base); - - /* When listing features we can ask for when allocating DMA channels give -diff --git a/drivers/video/fbdev/bcm2708_fb.c b/drivers/video/fbdev/bcm2708_fb.c -index ac04125..9d7ecda 100644 ---- a/drivers/video/fbdev/bcm2708_fb.c -+++ b/drivers/video/fbdev/bcm2708_fb.c -@@ -21,13 +21,16 @@ - #include - #include - #include -+#include - #include - #include - #include - #include - #include - #include -+#include - -+#include - #include - #include - -@@ -54,6 +57,10 @@ static int fbheight = 480; /* module parameter */ - static int fbdepth = 16; /* module parameter */ - static int fbswap = 0; /* module parameter */ - -+static u32 dma_busy_wait_threshold = 1<<15; -+module_param(dma_busy_wait_threshold, int, 0644); -+MODULE_PARM_DESC(dma_busy_wait_threshold, "Busy-wait for DMA completion below this area"); -+ - /* this data structure describes each frame buffer device we find */ - - struct fbinfo_s { -@@ -65,16 +72,74 @@ struct fbinfo_s { - u16 cmap[256]; - }; - -+struct bcm2708_fb_stats { -+ struct debugfs_regset32 regset; -+ u32 dma_copies; -+ u32 dma_irqs; -+}; -+ - struct bcm2708_fb { - struct fb_info fb; - struct platform_device *dev; - 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; -+ struct dentry *debugfs_dir; -+ wait_queue_head_t dma_waitq; -+ struct bcm2708_fb_stats stats; -+ unsigned long fb_bus_address; - }; - - #define to_bcm2708(info) container_of(info, struct bcm2708_fb, fb) - -+static void bcm2708_fb_debugfs_deinit(struct bcm2708_fb *fb) -+{ -+ debugfs_remove_recursive(fb->debugfs_dir); -+ fb->debugfs_dir = NULL; -+} -+ -+static int bcm2708_fb_debugfs_init(struct bcm2708_fb *fb) -+{ -+ static struct debugfs_reg32 stats_registers[] = { -+ { -+ "dma_copies", -+ offsetof(struct bcm2708_fb_stats, dma_copies) -+ }, -+ { -+ "dma_irqs", -+ offsetof(struct bcm2708_fb_stats, dma_irqs) -+ }, -+ }; -+ -+ fb->debugfs_dir = debugfs_create_dir(DRIVER_NAME, NULL); -+ if (!fb->debugfs_dir) { -+ pr_warn("%s: could not create debugfs entry\n", -+ __func__); -+ return -EFAULT; -+ } -+ -+ fb->stats.regset.regs = stats_registers; -+ fb->stats.regset.nregs = ARRAY_SIZE(stats_registers); -+ fb->stats.regset.base = &fb->stats; -+ -+ if (!debugfs_create_regset32( -+ "stats", 0444, fb->debugfs_dir, &fb->stats.regset)) { -+ pr_warn("%s: could not create statistics registers\n", -+ __func__); -+ goto fail; -+ } -+ return 0; -+ -+fail: -+ bcm2708_fb_debugfs_deinit(fb); -+ return -EFAULT; -+} -+ - static int bcm2708_fb_set_bitfields(struct fb_var_screeninfo *var) - { - int ret = 0; -@@ -253,13 +318,15 @@ static int bcm2708_fb_set_par(struct fb_info *info) - else - fb->fb.fix.visual = FB_VISUAL_TRUECOLOR; - -+ fb->fb_bus_address = fbinfo->base; -+ fbinfo->base &= ~0xc0000000; - fb->fb.fix.smem_start = fbinfo->base; - fb->fb.fix.smem_len = fbinfo->pitch * fbinfo->yres_virtual; - fb->fb.screen_size = fbinfo->screen_size; - if (fb->fb.screen_base) - iounmap(fb->fb.screen_base); - fb->fb.screen_base = -- (void *)ioremap_wc(fb->fb.fix.smem_start, fb->fb.screen_size); -+ (void *)ioremap_wc(fbinfo->base, fb->fb.screen_size); - if (!fb->fb.screen_base) { - /* the console may currently be locked */ - console_trylock(); -@@ -270,7 +337,7 @@ static int bcm2708_fb_set_par(struct fb_info *info) - } - print_debug - ("BCM2708FB: start = %p,%p width=%d, height=%d, bpp=%d, pitch=%d size=%d success=%d\n", -- (void *)fb->fb.screen_base, (void *)fb->fb.fix.smem_start, -+ (void *)fb->fb.screen_base, (void *)fb->fb_bus_address, - fbinfo->xres, fbinfo->yres, fbinfo->bpp, - fbinfo->pitch, (int)fb->fb.screen_size, val); - -@@ -377,11 +444,148 @@ static void bcm2708_fb_fillrect(struct fb_info *info, - 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; -+ int pixels = region->width * region->height; -+ -+ /* Fallback to cfb_copyarea() if we don't like something */ -+ if (bytes_per_pixel > 4 || -+ info->var.xres * info->var.yres > 1920 * 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_bus_address + -+ bytes_per_pixel * region->sx + -+ (region->sy + y) * fb->fb.fix.line_length; -+ dma_addr_t dst = -+ fb->fb_bus_address + -+ 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_bus_address + dy * fb->fb.fix.line_length + -+ bytes_per_pixel * region->dx, -+ stride, -+ fb->fb_bus_address + 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; -+ -+ -+ if (pixels < dma_busy_wait_threshold) { -+ bcm_dma_start(fb->dma_chan_base, fb->cb_handle); -+ bcm_dma_wait_idle(fb->dma_chan_base); -+ } else { -+ void __iomem *dma_chan = fb->dma_chan_base; -+ cb->info |= BCM2708_DMA_INT_EN; -+ bcm_dma_start(fb->dma_chan_base, fb->cb_handle); -+ while (bcm_dma_is_busy(dma_chan)) { -+ wait_event_interruptible( -+ fb->dma_waitq, -+ !bcm_dma_is_busy(dma_chan)); -+ } -+ fb->stats.dma_irqs++; -+ } -+ fb->stats.dma_copies++; - } - - static void bcm2708_fb_imageblit(struct fb_info *info, -@@ -391,6 +595,24 @@ static void bcm2708_fb_imageblit(struct fb_info *info, - cfb_imageblit(info, image); - } - -+static irqreturn_t bcm2708_fb_dma_irq(int irq, void *cxt) -+{ -+ struct bcm2708_fb *fb = cxt; -+ -+ /* FIXME: should read status register to check if this is -+ * actually interrupting us or not, in case this interrupt -+ * ever becomes shared amongst several DMA channels -+ * -+ * readl(dma_chan_base + BCM2708_DMA_CS) & BCM2708_DMA_IRQ; -+ */ -+ -+ /* acknowledge the interrupt */ -+ writel(BCM2708_DMA_INT, fb->dma_chan_base + BCM2708_DMA_CS); -+ -+ wake_up(&fb->dma_waitq); -+ return IRQ_HANDLED; -+} -+ - static struct fb_ops bcm2708_fb_ops = { - .owner = THIS_MODULE, - .fb_check_var = bcm2708_fb_check_var, -@@ -422,7 +644,7 @@ static int bcm2708_fb_register(struct bcm2708_fb *fb) - 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)); -@@ -453,6 +675,7 @@ static int bcm2708_fb_register(struct bcm2708_fb *fb) - fb->fb.monspecs.dclkmax = 100000000; - - bcm2708_fb_set_bitfields(&fb->fb.var); -+ init_waitqueue_head(&fb->dma_waitq); - - /* - * Allocate colourmap. -@@ -479,14 +702,45 @@ static int bcm2708_fb_probe(struct platform_device *dev) - struct bcm2708_fb *fb; - int ret; - -- fb = kmalloc(sizeof(struct bcm2708_fb), GFP_KERNEL); -+ fb = kzalloc(sizeof(struct bcm2708_fb), GFP_KERNEL); - if (!fb) { - dev_err(&dev->dev, - "could not allocate new bcm2708_fb struct\n"); - ret = -ENOMEM; - goto free_region; - } -- memset(fb, 0, sizeof(struct bcm2708_fb)); -+ -+ bcm2708_fb_debugfs_init(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; -+ -+ ret = request_irq(fb->dma_irq, bcm2708_fb_dma_irq, -+ 0, "bcm2708_fb dma", fb); -+ if (ret) { -+ pr_err("%s: failed to request DMA irq\n", __func__); -+ goto free_dma_chan; -+ } -+ -+ -+ pr_info("BCM2708FB: allocated DMA channel %d @ %p\n", -+ fb->dma_chan, fb->dma_chan_base); - - fb->dev = dev; - -@@ -496,6 +750,11 @@ static int bcm2708_fb_probe(struct platform_device *dev) - goto out; - } - -+free_dma_chan: -+ bcm_dma_chan_free(fb->dma_chan); -+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); -@@ -513,8 +772,15 @@ static int bcm2708_fb_remove(struct platform_device *dev) - 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); -+ bcm2708_fb_debugfs_deinit(fb); -+ -+ free_irq(fb->dma_irq, fb); -+ - kfree(fb); - - return 0; - -From df3f65668a5fb75915acb9ede96bac80f8fd9d7e Mon Sep 17 00:00:00 2001 +From c1ca6a3147915e0b47ce580c266ee0d58e8d1ca0 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 2 Jul 2013 23:42:01 +0100 -Subject: [PATCH 10/87] bcm2708 vchiq driver +Subject: [PATCH 10/76] bcm2708 vchiq driver Signed-off-by: popcornmix @@ -80291,10 +80189,10 @@ index 0000000..b6bfa21 + return vchiq_build_time; +} -From 918270607c11470943c18ffb32211775a51f323c Mon Sep 17 00:00:00 2001 +From 780499145e9e2670fc9890989ca048ec56f50993 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 12 May 2014 15:12:02 +0100 -Subject: [PATCH 11/87] vchiq: Avoid high load when blocked and unkillable +Subject: [PATCH 11/76] vchiq: Avoid high load when blocked and unkillable vchiq: Include SIGSTOP and SIGCONT in list of signals not-masked by vchiq to allow gdb to work --- @@ -80456,10 +80354,10 @@ index c2eefef..05e7979 100644 static inline int is_pow2(int i) { -From 138ab6a6512b4fa5960a43e4c9c57f2d384a9c72 Mon Sep 17 00:00:00 2001 +From 9e39d834add3712c89fec14fd5d017da60dd671b Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 3 Jul 2013 00:31:47 +0100 -Subject: [PATCH 12/87] cma: Add vc_cma driver to enable use of CMA +Subject: [PATCH 12/76] cma: Add vc_cma driver to enable use of CMA Signed-off-by: popcornmix --- @@ -81747,10 +81645,10 @@ index 0000000..5325832 + +#endif /* VC_CMA_H */ -From 8f444f02f445dcbb2ff933ec1cbe621727146eb9 Mon Sep 17 00:00:00 2001 +From f5aa21b929e83e8f85c57422d871b544145fb239 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 26 Mar 2012 22:15:50 +0100 -Subject: [PATCH 13/87] bcm2708: alsa sound driver +Subject: [PATCH 13/76] bcm2708: alsa sound driver Signed-off-by: popcornmix @@ -84513,10 +84411,10 @@ index 0000000..af3e6eb + +#endif // _VC_AUDIO_DEFS_H_ -From db11fc52b5814fbd6503bf41787210de50d444cd Mon Sep 17 00:00:00 2001 +From 8211debe0b082e96c2f97613f3b26252418abf13 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 3 Jul 2013 00:51:55 +0100 -Subject: [PATCH 14/87] Add hwrng (hardware random number generator) driver +Subject: [PATCH 14/76] Add hwrng (hardware random number generator) driver --- drivers/char/hw_random/Kconfig | 11 ++++ @@ -84683,10 +84581,10 @@ index 0000000..340f004 +MODULE_DESCRIPTION("BCM2708 H/W Random Number Generator (RNG) driver"); +MODULE_LICENSE("GPL and additional rights"); -From 52004453c2e2e2eb585ae677f2377883c9167ea3 Mon Sep 17 00:00:00 2001 +From 680ce71208c50b022174fe198170c72108cf6d26 Mon Sep 17 00:00:00 2001 From: Aron Szabo Date: Sat, 16 Jun 2012 12:15:55 +0200 -Subject: [PATCH 15/87] lirc: added support for RaspberryPi GPIO +Subject: [PATCH 15/76] lirc: added support for RaspberryPi GPIO lirc_rpi: Use read_current_timer to determine transmitter delay. Thanks to jjmz and others See: https://github.com/raspberrypi/linux/issues/525 @@ -84702,11 +84600,25 @@ gpios internal pull from it pull-down default behaviour. Add a module parameter to allow the user to set it explicitly. Signed-off-by: Julian Scheel + +lirc-rpi: Use the higher-level irq control functions + +This module used to access the irq_chip methods of the +gpio controller directly, rather than going through the +standard enable_irq/irq_set_irq_type functions. This +caused problems on pinctrl-bcm2835 which only implements +the irq_enable/disable methods and not irq_unmask/mask. + +lirc-rpi: Correct the interrupt usage + +1) Correct the use of enable_irq (i.e. don't call it so often) +2) Correct the shutdown sequence. +3) Avoid a bcm2708_gpio driver quirk by setting the irq flags earlier --- drivers/staging/media/lirc/Kconfig | 6 + drivers/staging/media/lirc/Makefile | 1 + - drivers/staging/media/lirc/lirc_rpi.c | 689 ++++++++++++++++++++++++++++++++++ - 3 files changed, 696 insertions(+) + drivers/staging/media/lirc/lirc_rpi.c | 659 ++++++++++++++++++++++++++++++++++ + 3 files changed, 666 insertions(+) create mode 100644 drivers/staging/media/lirc/lirc_rpi.c diff --git a/drivers/staging/media/lirc/Kconfig b/drivers/staging/media/lirc/Kconfig @@ -84740,10 +84652,10 @@ index b90fcab..2b227fd 100644 obj-$(CONFIG_LIRC_SIR) += lirc_sir.o diff --git a/drivers/staging/media/lirc/lirc_rpi.c b/drivers/staging/media/lirc/lirc_rpi.c new file mode 100644 -index 0000000..887c36b +index 0000000..c688364 --- /dev/null +++ b/drivers/staging/media/lirc/lirc_rpi.c -@@ -0,0 +1,689 @@ +@@ -0,0 +1,659 @@ +/* + * lirc_rpi.c + * @@ -84824,8 +84736,7 @@ index 0000000..887c36b +static bool invert = 0; + +struct gpio_chip *gpiochip; -+struct irq_chip *irqchip; -+struct irq_data *irqdata; ++static int irq_num; + +/* forward declarations */ +static long send_pulse(unsigned long length); @@ -84991,9 +84902,6 @@ index 0000000..887c36b + /* use the GPIO signal level */ + signal = gpiochip->get(gpiochip, gpio_in_pin); + -+ /* unmask the irq */ -+ irqchip->irq_unmask(irqdata); -+ + if (sense != -1) { + /* get current time */ + do_gettimeofday(&tv); @@ -85047,7 +84955,7 @@ index 0000000..887c36b + +static int init_port(void) +{ -+ int i, nlow, nhigh, ret, irq; ++ int i, nlow, nhigh, ret; + + gpiochip = gpiochip_find("bcm2708_gpio", is_right_chip); + @@ -85073,16 +84981,8 @@ index 0000000..887c36b + gpiochip->direction_output(gpiochip, gpio_out_pin, 1); + gpiochip->set(gpiochip, gpio_out_pin, invert); + -+ irq = gpiochip->to_irq(gpiochip, gpio_in_pin); -+ dprintk("to_irq %d\n", irq); -+ irqdata = irq_get_irq_data(irq); -+ -+ if (irqdata && irqdata->chip) { -+ irqchip = irqdata->chip; -+ } else { -+ ret = -ENODEV; -+ goto exit_gpio_free_in_pin; -+ } ++ irq_num = gpiochip->to_irq(gpiochip, gpio_in_pin); ++ dprintk("to_irq %d\n", irq_num); + + /* if pin is high, then this must be an active low receiver. */ + if (sense == -1) { @@ -85114,9 +85014,6 @@ index 0000000..887c36b + + return 0; + -+ exit_gpio_free_in_pin: -+ gpio_free(gpio_in_pin); -+ + exit_gpio_free_out_pin: + gpio_free(gpio_out_pin); + @@ -85128,20 +85025,20 @@ index 0000000..887c36b +static int set_use_inc(void *data) +{ + int result; -+ unsigned long flags; + + /* initialize timestamp */ + do_gettimeofday(&lasttv); + -+ result = request_irq(gpiochip->to_irq(gpiochip, gpio_in_pin), -+ (irq_handler_t) irq_handler, 0, ++ result = request_irq(irq_num, ++ (irq_handler_t) irq_handler, ++ IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING, + LIRC_DRIVER_NAME, (void*) 0); + + switch (result) { + case -EBUSY: + printk(KERN_ERR LIRC_DRIVER_NAME + ": IRQ %d is busy\n", -+ gpiochip->to_irq(gpiochip, gpio_in_pin)); ++ irq_num); + return -EBUSY; + case -EINVAL: + printk(KERN_ERR LIRC_DRIVER_NAME @@ -85149,43 +85046,26 @@ index 0000000..887c36b + return -EINVAL; + default: + dprintk("Interrupt %d obtained\n", -+ gpiochip->to_irq(gpiochip, gpio_in_pin)); ++ irq_num); + break; + }; + + /* initialize pulse/space widths */ + init_timing_params(duty_cycle, freq); + -+ spin_lock_irqsave(&lock, flags); -+ -+ /* GPIO Pin Falling/Rising Edge Detect Enable */ -+ irqchip->irq_set_type(irqdata, -+ IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING); -+ -+ /* unmask the irq */ -+ irqchip->irq_unmask(irqdata); -+ -+ spin_unlock_irqrestore(&lock, flags); -+ + return 0; +} + +static void set_use_dec(void *data) +{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&lock, flags); -+ + /* GPIO Pin Falling/Rising Edge Detect Disable */ -+ irqchip->irq_set_type(irqdata, 0); -+ irqchip->irq_mask(irqdata); ++ irq_set_irq_type(irq_num, 0); ++ disable_irq(irq_num); + -+ spin_unlock_irqrestore(&lock, flags); -+ -+ free_irq(gpiochip->to_irq(gpiochip, gpio_in_pin), (void *) 0); ++ free_irq(irq_num, (void *) 0); + + dprintk(KERN_INFO LIRC_DRIVER_NAME -+ ": freed IRQ %d\n", gpiochip->to_irq(gpiochip, gpio_in_pin)); ++ ": freed IRQ %d\n", irq_num); +} + +static ssize_t lirc_write(struct file *file, const char *buf, @@ -85341,7 +85221,8 @@ index 0000000..887c36b + +static void lirc_rpi_exit(void) +{ -+ platform_device_unregister(lirc_rpi_dev); ++ if (!lirc_rpi_dev->dev.of_node) ++ platform_device_unregister(lirc_rpi_dev); + platform_driver_unregister(&lirc_rpi_driver); + lirc_buffer_free(&rbuf); +} @@ -85392,12 +85273,13 @@ index 0000000..887c36b + +static void __exit lirc_rpi_exit_module(void) +{ ++ lirc_unregister_driver(driver.minor); ++ + gpio_free(gpio_out_pin); + gpio_free(gpio_in_pin); + + lirc_rpi_exit(); + -+ lirc_unregister_driver(driver.minor); + printk(KERN_INFO LIRC_DRIVER_NAME ": cleaned up module\n"); +} + @@ -85434,10 +85316,10 @@ index 0000000..887c36b +module_param(debug, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(debug, "Enable debugging messages"); -From 3accdaee0529e04e8eaf1fbbf962de81358b2072 Mon Sep 17 00:00:00 2001 +From 91467560535d3515f4aaf8ce569b190a5f79e408 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 3 Jul 2013 00:49:20 +0100 -Subject: [PATCH 16/87] Add cpufreq driver +Subject: [PATCH 16/76] Add cpufreq driver --- arch/arm/Kconfig | 1 + @@ -85721,10 +85603,10 @@ index 0000000..447ca09 +module_init(bcm2835_cpufreq_module_init); +module_exit(bcm2835_cpufreq_module_exit); -From 15a901d70141951d27144b90f7ec15d09e5d9d6f Mon Sep 17 00:00:00 2001 +From 7498bb369f589f1eb8f28fa9d15be6ce1efe3f7c Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 26 Mar 2013 19:24:24 +0000 -Subject: [PATCH 17/87] Added hwmon/thermal driver for reporting core +Subject: [PATCH 17/76] Added hwmon/thermal driver for reporting core temperature. Thanks Dorian --- @@ -86246,10 +86128,10 @@ index 0000000..85fceb5 + +module_platform_driver(bcm2835_thermal_driver); -From 96fdd6c4c066556ae7dfacde29ae85173efe8f7f Mon Sep 17 00:00:00 2001 +From 36eb7c00b5d6de80fdd323ddbe2151c80d23c821 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 26 Mar 2013 17:26:38 +0000 -Subject: [PATCH 18/87] Allow mac address to be set in smsc95xx +Subject: [PATCH 18/76] Allow mac address to be set in smsc95xx Signed-off-by: popcornmix --- @@ -86340,10 +86222,10 @@ index d07bf4c..5ae60ab 100644 if (smsc95xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN, dev->net->dev_addr) == 0) { -From ffafcc67ea6dab2c17e57e81c720c2052cd75f81 Mon Sep 17 00:00:00 2001 +From fa3da5047c86fbc517ae0629a6011cce2b76846a Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 4 Nov 2013 18:56:10 +0000 -Subject: [PATCH 19/87] Add Chris Boot's i2c and spi drivers. +Subject: [PATCH 19/76] Add Chris Boot's i2c and spi drivers. i2c-bcm2708: fixed baudrate @@ -86359,11 +86241,11 @@ The correct baudrate is shown in the log after the cdiv > 0xffff correction. arch/arm/mach-bcm2708/bcm2708.c | 104 ++++++- drivers/i2c/busses/Kconfig | 19 ++ drivers/i2c/busses/Makefile | 1 + - drivers/i2c/busses/i2c-bcm2708.c | 419 +++++++++++++++++++++++++ + drivers/i2c/busses/i2c-bcm2708.c | 420 +++++++++++++++++++++++++ drivers/spi/Kconfig | 8 + drivers/spi/Makefile | 1 + drivers/spi/spi-bcm2708.c | 626 ++++++++++++++++++++++++++++++++++++++ - 9 files changed, 1190 insertions(+), 2 deletions(-) + 9 files changed, 1191 insertions(+), 2 deletions(-) create mode 100644 drivers/i2c/busses/i2c-bcm2708.c create mode 100644 drivers/spi/spi-bcm2708.c @@ -86602,10 +86484,10 @@ index 78d56c5..abe642f 100644 obj-$(CONFIG_I2C_CBUS_GPIO) += i2c-cbus-gpio.o diff --git a/drivers/i2c/busses/i2c-bcm2708.c b/drivers/i2c/busses/i2c-bcm2708.c new file mode 100644 -index 0000000..f266f10 +index 0000000..09203c0 --- /dev/null +++ b/drivers/i2c/busses/i2c-bcm2708.c -@@ -0,0 +1,419 @@ +@@ -0,0 +1,420 @@ +/* + * Driver for Broadcom BCM2708 BSC Controllers + * @@ -86844,10 +86726,11 @@ index 0000000..f266f10 + bi->nmsgs = num; + bi->error = false; + -+ spin_unlock_irqrestore(&bi->lock, flags); -+ + bcm2708_bsc_setup(bi); + ++ /* unlockig _after_ the setup to avoid races with the interrupt routine */ ++ spin_unlock_irqrestore(&bi->lock, flags); ++ + ret = wait_for_completion_timeout(&bi->done, + msecs_to_jiffies(I2C_TIMEOUT_MS)); + if (ret == 0) { @@ -87689,10 +87572,10 @@ index 0000000..b04a57d +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" DRV_NAME); -From e093f147af2dcafa8f7aa57faf816a4708b9c2e7 Mon Sep 17 00:00:00 2001 +From e8db11907c26d546f0ee587f4d8021e619b3d4f3 Mon Sep 17 00:00:00 2001 From: cbeytas Date: Mon, 24 Jun 2013 00:05:40 -0400 -Subject: [PATCH 20/87] Perform I2C combined transactions when possible +Subject: [PATCH 20/76] Perform I2C combined transactions when possible Perform I2C combined transactions whenever possible, within the restrictions of the Broadcomm Serial Controller. @@ -87708,7 +87591,7 @@ i2c: Make combined transactions optional and disabled by default 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-bcm2708.c b/drivers/i2c/busses/i2c-bcm2708.c -index f266f10..8750634 100644 +index 09203c0..7d385a3 100644 --- a/drivers/i2c/busses/i2c-bcm2708.c +++ b/drivers/i2c/busses/i2c-bcm2708.c @@ -74,6 +74,9 @@ static unsigned int baudrate = CONFIG_I2C_BCM2708_BAUDRATE; @@ -87764,10 +87647,10 @@ index f266f10..8750634 100644 } -From bac73e0a55b4227952ac46d1fe7925f4235ce2c8 Mon Sep 17 00:00:00 2001 +From 9e4c97d08b3ff495728b69b6ae4cc1b611cd8eb4 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 8 May 2013 11:46:50 +0100 -Subject: [PATCH 21/87] enabling the realtime clock 1-wire chip DS1307 and +Subject: [PATCH 21/76] enabling the realtime clock 1-wire chip DS1307 and 1-wire on GPIO4 (as a module) 1-wire: Add support for configuring pin for w1-gpio kernel module @@ -88039,17 +87922,18 @@ index 2820924..fd0550f 100644 } } -From d8e5144b7f9885fcd1cb26ca40bc84f69c0e6749 Mon Sep 17 00:00:00 2001 + +From f09a69f3af9b69f4ba693bdc8a156fe56a36ec7e Mon Sep 17 00:00:00 2001 From: popcornmix Date: Fri, 12 Apr 2013 23:58:47 +0100 -Subject: [PATCH 23/87] config: add missing options from 3.6.y kernel +Subject: [PATCH 23/76] config: add missing options from 3.6.y kernel --- - arch/arm/configs/bcmrpi_defconfig | 652 ++++++++++++++++++++++++++++++++++++-- - 1 file changed, 631 insertions(+), 21 deletions(-) + arch/arm/configs/bcmrpi_defconfig | 658 ++++++++++++++++++++++++++++++++++++-- + 1 file changed, 636 insertions(+), 22 deletions(-) diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 6d2eae1..0f3fe96 100644 +index 6d2eae1..e2da9da 100644 --- a/arch/arm/configs/bcmrpi_defconfig +++ b/arch/arm/configs/bcmrpi_defconfig @@ -1,3 +1,5 @@ @@ -88393,12 +88277,12 @@ index 6d2eae1..0f3fe96 100644 CONFIG_IRCOMM=m CONFIG_IRDA_ULTRA=y CONFIG_IRDA_CACHE_LAST_LSAP=y -@@ -87,44 +359,84 @@ CONFIG_BT_HCIVHCI=m +@@ -87,45 +359,87 @@ CONFIG_BT_HCIVHCI=m CONFIG_BT_MRVL=m CONFIG_BT_MRVL_SDIO=m CONFIG_BT_ATH3K=m +-CONFIG_CFG80211=m +CONFIG_BT_WILINK=m - CONFIG_CFG80211=m +CONFIG_CFG80211_WEXT=y CONFIG_MAC80211=m CONFIG_MAC80211_MESH=y @@ -88477,11 +88361,15 @@ index 6d2eae1..0f3fe96 100644 CONFIG_USB_NET_CDCETHER=m CONFIG_USB_NET_CDC_EEM=m +CONFIG_USB_NET_CDC_NCM=m ++CONFIG_USB_NET_HUAWEI_CDC_NCM=m +CONFIG_USB_NET_CDC_MBIM=m CONFIG_USB_NET_DM9601=m ++CONFIG_USB_NET_SR9700=m ++CONFIG_USB_NET_SR9800=m CONFIG_USB_NET_SMSC75XX=m CONFIG_USB_NET_SMSC95XX=y -@@ -135,10 +447,13 @@ CONFIG_USB_NET_MCS7830=m + CONFIG_USB_NET_GL620A=m +@@ -135,10 +449,13 @@ CONFIG_USB_NET_MCS7830=m CONFIG_USB_NET_CDC_SUBSET=m CONFIG_USB_ALI_M5632=y CONFIG_USB_AN2720=y @@ -88496,7 +88384,7 @@ index 6d2eae1..0f3fe96 100644 CONFIG_USB_NET_INT51X1=m CONFIG_USB_IPHETH=m CONFIG_USB_SIERRA_NET=m -@@ -150,7 +465,15 @@ CONFIG_USB_ZD1201=m +@@ -150,7 +467,15 @@ CONFIG_USB_ZD1201=m CONFIG_USB_NET_RNDIS_WLAN=m CONFIG_RTL8187=m CONFIG_MAC80211_HWSIM=m @@ -88512,7 +88400,7 @@ index 6d2eae1..0f3fe96 100644 CONFIG_B43LEGACY=m CONFIG_HOSTAP=m CONFIG_LIBERTAS=m -@@ -162,7 +485,10 @@ CONFIG_RT2X00=m +@@ -162,7 +487,10 @@ CONFIG_RT2X00=m CONFIG_RT2500USB=m CONFIG_RT73USB=m CONFIG_RT2800USB=m @@ -88523,7 +88411,7 @@ index 6d2eae1..0f3fe96 100644 CONFIG_RTL8192CU=m CONFIG_ZD1211RW=m CONFIG_MWIFIEX=m -@@ -174,6 +500,13 @@ CONFIG_INPUT_JOYDEV=m +@@ -174,6 +502,13 @@ CONFIG_INPUT_JOYDEV=m CONFIG_INPUT_EVDEV=m # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set @@ -88537,7 +88425,7 @@ index 6d2eae1..0f3fe96 100644 CONFIG_INPUT_MISC=y CONFIG_INPUT_AD714X=m CONFIG_INPUT_ATI_REMOTE2=m -@@ -189,22 +522,207 @@ CONFIG_SERIO_RAW=m +@@ -189,22 +524,207 @@ CONFIG_SERIO_RAW=m CONFIG_GAMEPORT=m CONFIG_GAMEPORT_NS558=m CONFIG_GAMEPORT_L4=m @@ -88747,7 +88635,7 @@ index 6d2eae1..0f3fe96 100644 CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set -@@ -227,8 +745,10 @@ CONFIG_SND_BCM2835=m +@@ -227,8 +747,10 @@ CONFIG_SND_BCM2835=m CONFIG_SND_USB_AUDIO=m CONFIG_SND_USB_UA101=m CONFIG_SND_USB_CAIAQ=m @@ -88758,7 +88646,7 @@ index 6d2eae1..0f3fe96 100644 CONFIG_HID_A4TECH=m CONFIG_HID_ACRUX=m CONFIG_HID_APPLE=m -@@ -267,9 +787,11 @@ CONFIG_HID_SUNPLUS=m +@@ -267,9 +789,11 @@ CONFIG_HID_SUNPLUS=m CONFIG_HID_GREENASIA=m CONFIG_HID_SMARTJOYPLUS=m CONFIG_HID_TOPSEED=m @@ -88770,7 +88658,7 @@ index 6d2eae1..0f3fe96 100644 CONFIG_HID_ZEROPLUS=m CONFIG_HID_ZYDACRON=m CONFIG_HID_PID=y -@@ -277,6 +799,8 @@ CONFIG_USB_HIDDEV=y +@@ -277,6 +801,8 @@ CONFIG_USB_HIDDEV=y CONFIG_USB=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y CONFIG_USB_MON=m @@ -88779,7 +88667,7 @@ index 6d2eae1..0f3fe96 100644 CONFIG_USB_STORAGE=y CONFIG_USB_STORAGE_REALTEK=m CONFIG_USB_STORAGE_DATAFAB=m -@@ -311,6 +835,7 @@ CONFIG_USB_SERIAL_IPAQ=m +@@ -311,6 +837,7 @@ CONFIG_USB_SERIAL_IPAQ=m CONFIG_USB_SERIAL_IR=m CONFIG_USB_SERIAL_EDGEPORT=m CONFIG_USB_SERIAL_EDGEPORT_TI=m @@ -88787,7 +88675,7 @@ index 6d2eae1..0f3fe96 100644 CONFIG_USB_SERIAL_GARMIN=m CONFIG_USB_SERIAL_IPW=m CONFIG_USB_SERIAL_IUU=m -@@ -319,6 +844,7 @@ CONFIG_USB_SERIAL_KEYSPAN=m +@@ -319,6 +846,7 @@ CONFIG_USB_SERIAL_KEYSPAN=m CONFIG_USB_SERIAL_KLSI=m CONFIG_USB_SERIAL_KOBIL_SCT=m CONFIG_USB_SERIAL_MCT_U232=m @@ -88795,7 +88683,7 @@ index 6d2eae1..0f3fe96 100644 CONFIG_USB_SERIAL_MOS7720=m CONFIG_USB_SERIAL_MOS7840=m CONFIG_USB_SERIAL_NAVMAN=m -@@ -336,7 +862,10 @@ CONFIG_USB_SERIAL_XIRCOM=m +@@ -336,7 +864,10 @@ CONFIG_USB_SERIAL_XIRCOM=m CONFIG_USB_SERIAL_OPTION=m CONFIG_USB_SERIAL_OMNINET=m CONFIG_USB_SERIAL_OPTICON=m @@ -88806,7 +88694,7 @@ index 6d2eae1..0f3fe96 100644 CONFIG_USB_SERIAL_DEBUG=m CONFIG_USB_EMI62=m CONFIG_USB_EMI26=m -@@ -357,12 +886,79 @@ CONFIG_USB_IOWARRIOR=m +@@ -357,12 +888,81 @@ CONFIG_USB_IOWARRIOR=m CONFIG_USB_TEST=m CONFIG_USB_ISIGHTFW=m CONFIG_USB_YUREX=m @@ -88870,6 +88758,8 @@ index 6d2eae1..0f3fe96 100644 +CONFIG_STAGING=y +CONFIG_PRISM2_USB=m +CONFIG_R8712U=m ++CONFIG_R8188EU=m ++CONFIG_R8723AU=m +CONFIG_VT6656=m +CONFIG_SPEAKUP=m +CONFIG_SPEAKUP_SYNTH_SOFT=m @@ -88886,7 +88776,7 @@ index 6d2eae1..0f3fe96 100644 CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y -@@ -384,6 +980,8 @@ CONFIG_BTRFS_FS=m +@@ -384,6 +984,8 @@ CONFIG_BTRFS_FS=m CONFIG_BTRFS_FS_POSIX_ACL=y CONFIG_NILFS2_FS=m CONFIG_FANOTIFY=y @@ -88895,7 +88785,7 @@ index 6d2eae1..0f3fe96 100644 CONFIG_AUTOFS4_FS=y CONFIG_FUSE_FS=m CONFIG_CUSE=m -@@ -399,18 +997,26 @@ CONFIG_MSDOS_FS=y +@@ -399,18 +1001,26 @@ CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y CONFIG_FAT_DEFAULT_IOCHARSET="ascii" CONFIG_NTFS_FS=m @@ -88922,7 +88812,7 @@ index 6d2eae1..0f3fe96 100644 CONFIG_CIFS=m CONFIG_CIFS_WEAK_PW_HASH=y CONFIG_CIFS_XATTR=y -@@ -455,36 +1061,40 @@ CONFIG_NLS_ISO8859_14=m +@@ -455,36 +1065,40 @@ CONFIG_NLS_ISO8859_14=m CONFIG_NLS_ISO8859_15=m CONFIG_NLS_KOI8_R=m CONFIG_NLS_KOI8_U=m @@ -88970,10 +88860,10 @@ index 6d2eae1..0f3fe96 100644 # CONFIG_CRYPTO_HW is not set CONFIG_CRC_ITU_T=y -From d1a86275aaba5bb17498eec49160e5ff29c14686 Mon Sep 17 00:00:00 2001 +From d2769a6cb68db83871206bfe113c5a34fef3d9d1 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 18 Dec 2013 22:16:19 +0000 -Subject: [PATCH 24/87] config: Enable CONFIG_MEMCG, but leave it disabled (due +Subject: [PATCH 24/76] config: Enable CONFIG_MEMCG, but leave it disabled (due to memory cost). Enable with cgroup_enable=memory. --- @@ -88983,7 +88873,7 @@ Subject: [PATCH 24/87] config: Enable CONFIG_MEMCG, but leave it disabled (due 3 files changed, 25 insertions(+) diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 0f3fe96..c017b94 100644 +index e2da9da..897616c 100644 --- a/arch/arm/configs/bcmrpi_defconfig +++ b/arch/arm/configs/bcmrpi_defconfig @@ -19,6 +19,7 @@ CONFIG_CGROUP_FREEZER=y @@ -89041,10 +88931,10 @@ index d6ac0e3..49f53b1 100644 #ifdef CONFIG_MEMCG_SWAP -From 16eda2f645d4e1f6d8a44d169c8351ace4ad7336 Mon Sep 17 00:00:00 2001 +From af98cb9f2fcc3f5d931b12eb10b877eb4fece8d1 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 3 Jul 2013 00:46:42 +0100 -Subject: [PATCH 25/87] Add FIQ patch to dwc_otg driver. Enable with +Subject: [PATCH 25/76] Add FIQ patch to dwc_otg driver. Enable with dwc_otg.fiq_fix_enable=1. Should give about 10% more ARM performance. Thanks to Gordon and Costas @@ -89301,7 +89191,7 @@ incarnations. arch/arm/kernel/fiqasm.S | 4 + arch/arm/mach-bcm2708/armctrl.c | 19 +- arch/arm/mach-bcm2708/bcm2708.c | 29 +- - arch/arm/mach-bcm2708/include/mach/irqs.h | 155 ++--- + arch/arm/mach-bcm2708/include/mach/irqs.h | 153 ++--- .../usb/host/dwc_common_port/dwc_common_linux.c | 11 + drivers/usb/host/dwc_common_port/dwc_list.h | 14 +- drivers/usb/host/dwc_common_port/dwc_os.h | 2 + @@ -89321,7 +89211,7 @@ incarnations. drivers/usb/host/dwc_otg/dwc_otg_mphi_fix.h | 48 ++ drivers/usb/host/dwc_otg/dwc_otg_os_dep.h | 3 + drivers/usb/host/dwc_otg/dwc_otg_pcd_intr.c | 2 +- - 25 files changed, 1545 insertions(+), 252 deletions(-) + 25 files changed, 1544 insertions(+), 251 deletions(-) create mode 100755 drivers/usb/host/dwc_otg/dwc_otg_mphi_fix.c create mode 100755 drivers/usb/host/dwc_otg/dwc_otg_mphi_fix.h @@ -89380,7 +89270,7 @@ index 8dd26e1..eef4847 100644 + mov pc, r8 +ENDPROC(__FIQ_Branch) diff --git a/arch/arm/mach-bcm2708/armctrl.c b/arch/arm/mach-bcm2708/armctrl.c -index efade23..d4c5333 100644 +index ef1c8d5..96fa9b9 100644 --- a/arch/arm/mach-bcm2708/armctrl.c +++ b/arch/arm/mach-bcm2708/armctrl.c @@ -52,8 +52,12 @@ static void armctrl_mask_irq(struct irq_data *d) @@ -89474,10 +89364,10 @@ index 7dd89a7f..dc59a6b 100644 bcm_register_device(&bcm2708_uart1_device); bcm_register_device(&bcm2708_powerman_device); diff --git a/arch/arm/mach-bcm2708/include/mach/irqs.h b/arch/arm/mach-bcm2708/include/mach/irqs.h -index faf5d1a..4299054 100644 +index 3a88a1a..45152ed 100644 --- a/arch/arm/mach-bcm2708/include/mach/irqs.h +++ b/arch/arm/mach-bcm2708/include/mach/irqs.h -@@ -106,89 +106,92 @@ +@@ -106,87 +106,90 @@ #define IRQ_PENDING1 (IRQ_ARMCTRL_START + INTERRUPT_PENDING1) #define IRQ_PENDING2 (IRQ_ARMCTRL_START + INTERRUPT_PENDING2) @@ -89641,11 +89531,8 @@ index faf5d1a..4299054 100644 +#define FIQ_IRQS (64 + 21) +#define GPIO_IRQ_START (HARD_IRQS + FIQ_IRQS) #define GPIO_IRQS (32*5) - #define SPARE_IRQS (64) --#define NR_IRQS (HARD_IRQS+GPIO_IRQS+SPARE_IRQS) -+#define NR_IRQS (HARD_IRQS+FIQ_IRQS+GPIO_IRQS+SPARE_IRQS) - - #endif /* _BCM2708_IRQS_H_ */ + #define SPARE_ALLOC_IRQS 64 + #define BCM2708_ALLOC_IRQS (HARD_IRQS+FIQ_IRQS+GPIO_IRQS+SPARE_ALLOC_IRQS) diff --git a/drivers/usb/host/dwc_common_port/dwc_common_linux.c b/drivers/usb/host/dwc_common_port/dwc_common_linux.c index 1668f10..5c50a8b 100644 --- a/drivers/usb/host/dwc_common_port/dwc_common_linux.c @@ -92340,10 +92227,10 @@ index 1b1f83c..c8590b5 100644 if (status.b.sr) { -From 426b37a828ce1dbfb28ffe9abb1a0584a1c0f8c4 Mon Sep 17 00:00:00 2001 +From 415e228dd3fdbfde78ae16570c1b97bfbcd2049e Mon Sep 17 00:00:00 2001 From: P33M Date: Wed, 19 Mar 2014 12:58:23 +0000 -Subject: [PATCH 26/87] dwc_otg: fiq_fsm: Base commit for driver rewrite +Subject: [PATCH 26/76] dwc_otg: fiq_fsm: Base commit for driver rewrite This commit removes the previous FIQ fixes entirely and adds fiq_fsm. @@ -97239,10 +97126,10 @@ index 5d310df..4b32941 100644 return -EBUSY; } -From 8f509ffcbc8f163dfa3eb4711269bbbb9c606e3d Mon Sep 17 00:00:00 2001 +From f556db93e27dd5f8fb6b10dd5f7513d3f869a8cf Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Wed, 30 Jan 2013 12:45:18 +0000 -Subject: [PATCH 27/87] bcm2835: add v4l2 camera device +Subject: [PATCH 27/76] bcm2835: add v4l2 camera device - Supports raw YUV capture, preview, JPEG and H264. - Uses videobuf2 for data transfer, using dma_buf. @@ -103225,10 +103112,10 @@ index 0000000..9d1d11e + +#endif /* MMAL_VCHIQ_H */ -From 45b91b2377e542c3fdc6f38f89688ea4353c72c3 Mon Sep 17 00:00:00 2001 +From d92591c77a6e18e78012fa741cbc99cc27bba8d0 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Mon, 9 Dec 2013 10:58:01 +0000 -Subject: [PATCH 28/87] V4L2: Fixes from 6by9 +Subject: [PATCH 28/76] V4L2: Fixes from 6by9 V4L2: Fix EV values. Add manual shutter speed control @@ -103460,10 +103347,10 @@ bcm2835-camera: stop_streaming now has a void return 8 files changed, 1300 insertions(+), 187 deletions(-) diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index c017b94..ea24343 100644 +index 897616c..3f99687 100644 --- a/arch/arm/configs/bcmrpi_defconfig +++ b/arch/arm/configs/bcmrpi_defconfig -@@ -706,6 +706,9 @@ CONFIG_DVB_AS102=m +@@ -708,6 +708,9 @@ CONFIG_DVB_AS102=m CONFIG_VIDEO_EM28XX=m CONFIG_VIDEO_EM28XX_ALSA=m CONFIG_VIDEO_EM28XX_DVB=m @@ -105640,10 +105527,10 @@ index a06fb44..76f249e 100644 release_msg: -From 53fe0c3937f06eae6ef85181a3e014e2328088db Mon Sep 17 00:00:00 2001 +From 8a267a675b1ccff065ced03ef234c237e0498bf6 Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 14:22:53 +0100 -Subject: [PATCH 29/87] dmaengine: Add support for BCM2708 +Subject: [PATCH 29/76] dmaengine: Add support for BCM2708 Add support for DMA controller of BCM2708 as used in the Raspberry Pi. Currently it only supports cyclic DMA. @@ -105651,13 +105538,15 @@ Currently it only supports cyclic DMA. Signed-off-by: Florian Meier dmaengine: expand functionality by supporting scatter/gather transfers sdhci-bcm2708 and dma.c: fix for LITE channels + +DMA: fix cyclic LITE length overflow bug --- arch/arm/mach-bcm2708/dma.c | 2 + arch/arm/mach-bcm2708/include/mach/dma.h | 6 +- drivers/dma/Kconfig | 6 + drivers/dma/Makefile | 1 + - drivers/dma/bcm2708-dmaengine.c | 1041 ++++++++++++++++++++++++++++++ - 5 files changed, 1055 insertions(+), 1 deletion(-) + drivers/dma/bcm2708-dmaengine.c | 1052 ++++++++++++++++++++++++++++++ + 5 files changed, 1066 insertions(+), 1 deletion(-) create mode 100644 drivers/dma/bcm2708-dmaengine.c diff --git a/arch/arm/mach-bcm2708/dma.c b/arch/arm/mach-bcm2708/dma.c @@ -105723,10 +105612,10 @@ index cb626c1..d3c4a82 100644 obj-$(CONFIG_TI_CPPI41) += cppi41.o diff --git a/drivers/dma/bcm2708-dmaengine.c b/drivers/dma/bcm2708-dmaengine.c new file mode 100644 -index 0000000..6766799 +index 0000000..10463db --- /dev/null +++ b/drivers/dma/bcm2708-dmaengine.c -@@ -0,0 +1,1041 @@ +@@ -0,0 +1,1052 @@ +/* + * BCM2835 DMA engine support + * @@ -105858,7 +105747,7 @@ index 0000000..6766799 +#define BCM2835_DMA_PER_MAP(x) ((x) << 16) +#define BCM2835_DMA_WAITS(x) (((x)&0x1f) << 21) + -+#define SDHCI_BCM_DMA_WAITS 20 /* delays slowing DMA transfers: 0-31 */ ++#define SDHCI_BCM_DMA_WAITS 0 /* delays slowing DMA transfers: 0-31 */ + +#define BCM2835_DMA_DATA_TYPE_S8 1 +#define BCM2835_DMA_DATA_TYPE_S16 2 @@ -106120,7 +106009,7 @@ index 0000000..6766799 + struct bcm2835_desc *d; + dma_addr_t dev_addr; + unsigned int es, sync_type; -+ unsigned int frame; ++ unsigned int frame, max_size; + + /* Grab configuration */ + if (!is_slave_direction(direction)) { @@ -106153,7 +106042,14 @@ index 0000000..6766799 + return NULL; + + d->dir = direction; -+ d->frames = buf_len / period_len; ++ ++ if (c->ch >= 8) /* we have a LITE channel */ ++ max_size = MAX_LITE_TRANSFER; ++ else ++ max_size = MAX_NORMAL_TRANSFER; ++ period_len = min(period_len, max_size); ++ ++ d->frames = (buf_len-1) / period_len + 1; + + /* Allocate memory for control blocks */ + d->control_block_size = d->frames * sizeof(struct bcm2835_dma_cb); @@ -106198,7 +106094,11 @@ index 0000000..6766799 + BCM2835_DMA_PER_MAP(c->cfg.slave_id); + + /* Length of a frame */ -+ control_block->length = period_len; ++ if (frame != d->frames-1) ++ control_block->length = period_len; ++ else ++ control_block->length = buf_len - (d->frames - 1) * period_len; ++ + d->size += control_block->length; + + /* @@ -106769,10 +106669,10 @@ index 0000000..6766799 +MODULE_AUTHOR("Gellert Weisz "); +MODULE_LICENSE("GPL v2"); -From e6438af7156c328ec9b0b4984e3ef33dbcaf26e7 Mon Sep 17 00:00:00 2001 +From 730cb8a1216f9da3d097072cd9bb06e0db348172 Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 14:33:38 +0100 -Subject: [PATCH 30/87] ASoC: Add support for BCM2708 +Subject: [PATCH 30/76] ASoC: Add support for BCM2708 This driver adds support for digital audio (I2S) for the BCM2708 SoC that is used by the @@ -107904,10 +107804,10 @@ index 0000000..94fed6a + +#endif -From d9347a289bb9b8f9c7e77f3f9e98ecf36bdabaf4 Mon Sep 17 00:00:00 2001 +From 2c8c4468a7948d1b308b2999435c6a5ab15af01f Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 14:59:51 +0100 -Subject: [PATCH 31/87] ASoC: Add support for PCM5102A codec +Subject: [PATCH 31/76] ASoC: Add support for PCM5102A codec Some definitions to support the PCM5102A codec by Texas Instruments. @@ -108032,10 +107932,10 @@ index 0000000..126f1e9 +MODULE_AUTHOR("Florian Meier "); +MODULE_LICENSE("GPL v2"); -From e80e01e0fde534457804f0816f37040bcba76269 Mon Sep 17 00:00:00 2001 +From 6e8c6be0372f6efcb4fef83c9c6f8f21ed93ccc7 Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 19:04:54 +0100 -Subject: [PATCH 32/87] BCM2708: Add I2S support to board file +Subject: [PATCH 32/76] BCM2708: Add I2S support to board file Adds the required initializations for I2S to the board file of mach-bcm2708. @@ -108090,10 +107990,10 @@ index a740344..dca28ad 100644 struct amba_device *d = amba_devs[i]; amba_device_register(d, &iomem_resource); -From 1754cf0588685eb8cbe6125424c53e027249aa43 Mon Sep 17 00:00:00 2001 +From 74971db057d368308b6c892cb8d7d86ae5ae069c Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 19:19:08 +0100 -Subject: [PATCH 33/87] ASoC: Add support for HifiBerry DAC +Subject: [PATCH 33/76] ASoC: Add support for HifiBerry DAC This adds a machine driver for the HifiBerry DAC. It is a sound card that can @@ -108242,10 +108142,10 @@ index 0000000..4b70b45 +MODULE_DESCRIPTION("ASoC Driver for HifiBerry DAC"); +MODULE_LICENSE("GPL v2"); -From adf71becb306e783aa880c988387a3c53ac32a50 Mon Sep 17 00:00:00 2001 +From 7a10241635674408cdf3ec93f4c077d83e10a21c Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 19:21:34 +0100 -Subject: [PATCH 34/87] BCM2708: Add HifiBerry DAC to board file +Subject: [PATCH 34/76] BCM2708: Add HifiBerry DAC to board file This adds the initalization of the HifiBerry DAC to the mach-bcm2708 board file. @@ -108293,10 +108193,10 @@ index dca28ad..50d4991 100644 struct amba_device *d = amba_devs[i]; amba_device_register(d, &iomem_resource); -From 9e3fa566c19004b00d87181d59d34ce99571437f Mon Sep 17 00:00:00 2001 +From c1678789f9cf8c91d633f5c7a51f72c3b6bd12d3 Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Mon, 2 Dec 2013 20:28:22 +0100 -Subject: [PATCH 35/87] BCM2708: Add I2S and DMA support to default config +Subject: [PATCH 35/76] BCM2708: Add I2S and DMA support to default config This commit adds several modules that are needed for I2S support for the Raspberry Pi to the defconfig. @@ -108307,10 +108207,10 @@ Signed-off-by: Florian Meier 1 file changed, 6 insertions(+) diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index ea24343..09c61b0 100644 +index 3f99687..dfd98df 100644 --- a/arch/arm/configs/bcmrpi_defconfig +++ b/arch/arm/configs/bcmrpi_defconfig -@@ -751,6 +751,10 @@ CONFIG_SND_USB_UA101=m +@@ -753,6 +753,10 @@ CONFIG_SND_USB_UA101=m CONFIG_SND_USB_CAIAQ=m CONFIG_SND_USB_CAIAQ_INPUT=y CONFIG_SND_USB_6FIRE=m @@ -108321,7 +108221,7 @@ index ea24343..09c61b0 100644 CONFIG_SOUND_PRIME=m CONFIG_HIDRAW=y CONFIG_HID_A4TECH=m -@@ -945,6 +949,8 @@ CONFIG_RTC_DRV_RS5C348=m +@@ -947,6 +951,8 @@ CONFIG_RTC_DRV_RS5C348=m CONFIG_RTC_DRV_DS3234=m CONFIG_RTC_DRV_PCF2123=m CONFIG_RTC_DRV_RX4581=m @@ -108331,10 +108231,10 @@ index ea24343..09c61b0 100644 CONFIG_UIO_PDRV_GENIRQ=m CONFIG_STAGING=y -From af6f000362e735c9714940c96f11865f8388ca2c Mon Sep 17 00:00:00 2001 +From ce53d73e2e0d6367af4903cd0a8c3aa8e50cba45 Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 6 Dec 2013 20:50:28 +0100 -Subject: [PATCH 36/87] ASoC: BCM2708: Add support for RPi-DAC +Subject: [PATCH 36/76] ASoC: BCM2708: Add support for RPi-DAC This adds a machine driver for the RPi-DAC. @@ -108353,10 +108253,10 @@ Signed-off-by: Florian Meier create mode 100644 sound/soc/codecs/pcm1794a.c diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 09c61b0..8ede9ca 100644 +index dfd98df..f688da5 100644 --- a/arch/arm/configs/bcmrpi_defconfig +++ b/arch/arm/configs/bcmrpi_defconfig -@@ -754,6 +754,7 @@ CONFIG_SND_USB_6FIRE=m +@@ -756,6 +756,7 @@ CONFIG_SND_USB_6FIRE=m CONFIG_SND_SOC=m CONFIG_SND_BCM2708_SOC_I2S=m CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m @@ -108642,10 +108542,10 @@ index 0000000..b4eaa44 +MODULE_AUTHOR("Florian Meier "); +MODULE_LICENSE("GPL v2"); -From f8b269dcdf4414eeceb92c8021d9728559df0c4d Mon Sep 17 00:00:00 2001 +From 1eaf0583120666f39de82b6d1445eac658f56df3 Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Wed, 15 Jan 2014 21:41:23 +0100 -Subject: [PATCH 37/87] ASoC: wm8804: Implement MCLK configuration options, add +Subject: [PATCH 37/76] ASoC: wm8804: Implement MCLK configuration options, add 32bit support WM8804 can run with PLL frequencies of 256xfs and 128xfs for most sample rates. At 192kHz only 128xfs is supported. The existing driver selects 128xfs automatically for some lower samples rates. By using an @@ -108685,10 +108585,10 @@ index 3addc5f..d060b23 100644 #define WM8804_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | \ -From 3affd35e2cf59c17242a82ec695344892063ecc2 Mon Sep 17 00:00:00 2001 +From d3a5ba66399452de1a4ab6a82bc00116d1a4b932 Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Wed, 15 Jan 2014 21:42:08 +0100 -Subject: [PATCH 38/87] ASoC: BCM:Add support for HiFiBerry Digi. Driver is +Subject: [PATCH 38/76] ASoC: BCM:Add support for HiFiBerry Digi. Driver is based on the patched WM8804 driver. Signed-off-by: Daniel Matuschek @@ -108891,10 +108791,10 @@ index 0000000..e4f769d +MODULE_DESCRIPTION("ASoC Driver for HifiBerry Digi"); +MODULE_LICENSE("GPL v2"); -From de3f6cfb38c5ab3e441bae4fce582c86b651b374 Mon Sep 17 00:00:00 2001 +From 7e6722ece19aba93b04f8c111b99f1a994bb4526 Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Thu, 16 Jan 2014 07:26:08 +0100 -Subject: [PATCH 39/87] BCM2708: Added support for HiFiBerry Digi board Board +Subject: [PATCH 39/76] BCM2708: Added support for HiFiBerry Digi board Board initalization by I2C Signed-off-by: Daniel Matuschek @@ -108941,10 +108841,10 @@ index 100c223..a57cb85 100644 bcm_register_device(&snd_rpi_dac_device); bcm_register_device(&snd_pcm1794a_codec_device); -From fdd464bddf5ae9896f0a843759780c6582c13dbc Mon Sep 17 00:00:00 2001 +From 7774300c1a115825db8a5bf86c4c198afd2c6de6 Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Thu, 16 Jan 2014 07:27:28 +0100 -Subject: [PATCH 40/87] BCM2708: Added HiFiBerry Digi configuration option It +Subject: [PATCH 40/76] BCM2708: Added HiFiBerry Digi configuration option It will be compiled as a module by default. This also includes the WM8804 driver. @@ -108954,10 +108854,10 @@ Signed-off-by: Daniel Matuschek 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 8ede9ca..dc57f43 100644 +index f688da5..c9d3fac 100644 --- a/arch/arm/configs/bcmrpi_defconfig +++ b/arch/arm/configs/bcmrpi_defconfig -@@ -754,6 +754,7 @@ CONFIG_SND_USB_6FIRE=m +@@ -756,6 +756,7 @@ CONFIG_SND_USB_6FIRE=m CONFIG_SND_SOC=m CONFIG_SND_BCM2708_SOC_I2S=m CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m @@ -108966,10 +108866,10 @@ index 8ede9ca..dc57f43 100644 CONFIG_SND_SIMPLE_CARD=m CONFIG_SOUND_PRIME=m -From c875a360b96fca9926167eba6e7cc59a8c50eded Mon Sep 17 00:00:00 2001 +From fc7a3b585ef21087587ec901a117cc4138d014ef Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Thu, 16 Jan 2014 07:36:35 +0100 -Subject: [PATCH 41/87] ASoC: wm8804: Set idle_bias_off to false Idle bias has +Subject: [PATCH 41/76] ASoC: wm8804: Set idle_bias_off to false Idle bias has been change to remove warning on driver startup Signed-off-by: Daniel Matuschek @@ -108991,10 +108891,10 @@ index d060b23..d486a9d 100644 .controls = wm8804_snd_controls, .num_controls = ARRAY_SIZE(wm8804_snd_controls), -From b82e9fe19068d5fccff1ce7be1ab6da99ec99cea Mon Sep 17 00:00:00 2001 +From ebef8aefa5fd7e8fb9efa0c32345f6e734f3d8e7 Mon Sep 17 00:00:00 2001 From: Gordon Garrity Date: Sat, 8 Mar 2014 16:56:57 +0000 -Subject: [PATCH 42/87] Add IQaudIO Sound Card support for Raspberry Pi +Subject: [PATCH 42/76] Add IQaudIO Sound Card support for Raspberry Pi --- arch/arm/configs/bcmrpi_defconfig | 1 + @@ -109006,10 +108906,10 @@ Subject: [PATCH 42/87] Add IQaudIO Sound Card support for Raspberry Pi create mode 100644 sound/soc/bcm/iqaudio-dac.c diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index dc57f43..5a2714c 100644 +index c9d3fac..f15a4b9 100644 --- a/arch/arm/configs/bcmrpi_defconfig +++ b/arch/arm/configs/bcmrpi_defconfig -@@ -756,6 +756,7 @@ CONFIG_SND_BCM2708_SOC_I2S=m +@@ -758,6 +758,7 @@ CONFIG_SND_BCM2708_SOC_I2S=m CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m CONFIG_SND_BCM2708_SOC_RPI_DAC=m @@ -109204,10 +109104,10 @@ index 0000000..8d0e2ae +MODULE_DESCRIPTION("ASoC Driver for IQAudio DAC"); +MODULE_LICENSE("GPL v2"); -From f931826ec6d01fd7eedf75517058174f3ac802a6 Mon Sep 17 00:00:00 2001 +From 457a0d6f5961c18f79a7643ca0a3e8565af8a0eb Mon Sep 17 00:00:00 2001 From: Howard Mitchell Date: Fri, 28 Mar 2014 16:40:31 +0000 -Subject: [PATCH 43/87] pcm512x: Use a range macro for Volume and rename to +Subject: [PATCH 43/76] pcm512x: Use a range macro for Volume and rename to PCM. This allows limiting the output gain to avoid clipping in the @@ -109232,10 +109132,10 @@ index 0c8aefa..8252e6d 100644 PCM512x_LAGN_SHIFT, PCM512x_RAGN_SHIFT, 1, 1, analog_tlv), SOC_DOUBLE_TLV("Playback Boost Volume", PCM512x_ANALOG_GAIN_BOOST, -From 03d70d6ee3548261dddee64c934bfda4bd39c709 Mon Sep 17 00:00:00 2001 +From cdd19b1533661648b673f041462d49a9d5a3f202 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 18 Jun 2014 13:42:01 +0100 -Subject: [PATCH 44/87] vmstat: Workaround for issue where dirty page count +Subject: [PATCH 44/76] vmstat: Workaround for issue where dirty page count goes negative See: @@ -109262,10 +109162,10 @@ index 82e7db7..f87d16d 100644 static inline void __inc_zone_page_state(struct page *page, -From 883832016f4b3c14f5f7067edb6a094e38ae05b5 Mon Sep 17 00:00:00 2001 +From 5c6da22dbbbb0652138258b2a003ac390d0dfeeb Mon Sep 17 00:00:00 2001 From: P33M Date: Fri, 20 Jun 2014 16:03:12 +0100 -Subject: [PATCH 45/87] dwc_otg: Fix various issues with root port and +Subject: [PATCH 45/76] dwc_otg: Fix various issues with root port and transaction errors Process the host port interrupts correctly (and don't trample them). @@ -109335,10 +109235,10 @@ index d3e2035..6182d3e 100644 fiq_print(FIQDBG_ERR, dwc_otg_hcd->fiq_state, "RESET "); } -From ef5f8d5147086a10032c770e49e15065523460b6 Mon Sep 17 00:00:00 2001 +From 102c7fde61a329cd26fbb50c78be919c5cfc8727 Mon Sep 17 00:00:00 2001 From: P33M Date: Fri, 20 Jun 2014 17:23:20 +0100 -Subject: [PATCH 46/87] fiq_fsm: Implement hack for Split Interrupt +Subject: [PATCH 46/76] fiq_fsm: Implement hack for Split Interrupt transactions Hubs aren't too picky about which endpoint we send Control type split @@ -109424,10 +109324,10 @@ index ebc3553..c39ef31 100644 break; } -From 3f0b322f014dc983d3f5f8855516ae0e78c3efca Mon Sep 17 00:00:00 2001 +From 999c84bc86d3c05bf54251670bea1f0f5c5aebdb Mon Sep 17 00:00:00 2001 From: notro Date: Sun, 6 Jul 2014 12:07:25 +0200 -Subject: [PATCH 47/87] spi-bcm2708: Prepare for Common Clock Framework +Subject: [PATCH 47/76] spi-bcm2708: Prepare for Common Clock Framework migration As part of migrating to use the Common Clock Framework, replace clk_enable() @@ -109472,10 +109372,10 @@ index b04a57d..349d21f 100644 free_irq(bs->irq, master); iounmap(bs->base); -From a1b2ce17b07acbbcaec6f66864eb331a62032d4c Mon Sep 17 00:00:00 2001 +From edd404504eabf20b447729270e1b707fc9262948 Mon Sep 17 00:00:00 2001 From: notro Date: Sun, 6 Jul 2014 12:09:30 +0200 -Subject: [PATCH 48/87] BCM2708: Migrate to the Common Clock Framework +Subject: [PATCH 48/76] BCM2708: Migrate to the Common Clock Framework As part of moving towards using Device Tree, the Common Clock Framework has to be used instead of the BCM2708 clock implementation. @@ -109745,10 +109645,10 @@ index 5f9d725..0000000 - unsigned long rate; -}; -From a4833007678f0810c9f652eb0742905dad5b33a4 Mon Sep 17 00:00:00 2001 +From 5ca609b6684f9da82b1381c95fcf8160d3e0d469 Mon Sep 17 00:00:00 2001 From: notro Date: Wed, 9 Jul 2014 14:46:08 +0200 -Subject: [PATCH 49/87] BCM2708: Add core Device Tree support +Subject: [PATCH 49/76] BCM2708: Add core Device Tree support Add the bare minimum needed to boot BCM2708 from a Device Tree. @@ -109913,10 +109813,10 @@ index ef12cb8..747e27a 100644 module_param(boardrev, uint, 0644); -From 95ee62c9e6e33483b510932ae96f9a57b018bfac Mon Sep 17 00:00:00 2001 +From 0861d3c2129e67b4a91e3fc3dad50523f8b376e2 Mon Sep 17 00:00:00 2001 From: notro Date: Wed, 9 Jul 2014 14:47:48 +0200 -Subject: [PATCH 50/87] BCM2708: armctrl: Add IRQ Device Tree support +Subject: [PATCH 50/76] BCM2708: armctrl: Add IRQ Device Tree support Add Device Tree IRQ support for BCM2708. Usage is the same as for irq-bcm2835. @@ -109925,11 +109825,18 @@ See binding document: brcm,bcm2835-armctrl-ic.txt A bank 3 is added to handle GPIO interrupts. This is done because armctrl also handles GPIO interrupts. +Signed-off-by: Noralf Tronnes + +BCM2708: armctrl: remove irq bank 3 + +irq bank 3 was needed by the pinctrl-bcm2708 and bcm2708_gpio +combination. It is no longer required. + Signed-off-by: Noralf Tronnes --- arch/arm/boot/dts/bcm2708.dtsi | 9 ++++ - arch/arm/mach-bcm2708/armctrl.c | 97 +++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 106 insertions(+) + arch/arm/mach-bcm2708/armctrl.c | 96 +++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 105 insertions(+) diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi index 50da059..a06f5b8 100644 @@ -109959,7 +109866,7 @@ index 50da059..a06f5b8 100644 clocks { diff --git a/arch/arm/mach-bcm2708/armctrl.c b/arch/arm/mach-bcm2708/armctrl.c -index d4c5333..42f5e1c 100644 +index 96fa9b9..74bacb3 100644 --- a/arch/arm/mach-bcm2708/armctrl.c +++ b/arch/arm/mach-bcm2708/armctrl.c @@ -23,6 +23,8 @@ @@ -109971,14 +109878,14 @@ index d4c5333..42f5e1c 100644 #include #include -@@ -79,6 +81,100 @@ static void armctrl_unmask_irq(struct irq_data *d) +@@ -79,6 +81,99 @@ static void armctrl_unmask_irq(struct irq_data *d) } } +#ifdef CONFIG_OF + +#define NR_IRQS_BANK0 21 -+#define NR_BANKS 3 + 1 /* bank 3 is used for GPIO interrupts */ ++#define NR_BANKS 3 +#define IRQS_PER_BANK 32 + +/* from drivers/irqchip/irq-bcm2835.c */ @@ -110002,10 +109909,8 @@ index d4c5333..42f5e1c 100644 + *out_hwirq = ARM_IRQ0_BASE + intspec[1]; + else if (intspec[0] == 1) + *out_hwirq = ARM_IRQ1_BASE + intspec[1]; -+ else if (intspec[0] == 2) -+ *out_hwirq = ARM_IRQ2_BASE + intspec[1]; + else -+ *out_hwirq = GPIO_IRQ_START + intspec[1]; ++ *out_hwirq = ARM_IRQ2_BASE + intspec[1]; + + /* reverse remap_irqs[] */ + switch (*out_hwirq) { @@ -110061,7 +109966,8 @@ index d4c5333..42f5e1c 100644 + if (!np) + return; + -+ domain = irq_domain_add_legacy(np, NR_IRQS, IRQ_ARMCTRL_START, 0, ++ domain = irq_domain_add_legacy(np, BCM2708_ALLOC_IRQS, ++ IRQ_ARMCTRL_START, 0, + &armctrl_ops, NULL); + WARN_ON(!domain); +} @@ -110072,7 +109978,7 @@ index d4c5333..42f5e1c 100644 #if defined(CONFIG_PM) /* for kernels 3.xx use the new syscore_ops apis but for older kernels use the sys dev class */ -@@ -215,5 +311,6 @@ int __init armctrl_init(void __iomem * base, unsigned int irq_start, +@@ -215,5 +310,6 @@ int __init armctrl_init(void __iomem * base, unsigned int irq_start, armctrl_pm_register(base, irq_start, resume_sources); init_FIQ(FIQ_START); @@ -110080,878 +109986,118 @@ index d4c5333..42f5e1c 100644 return 0; } -From 953d76437a38df8f76c88bf63289de927f8f83d2 Mon Sep 17 00:00:00 2001 +From c3d7470d326a229710a756b747a8bdeb81f190ac Mon Sep 17 00:00:00 2001 From: notro Date: Thu, 10 Jul 2014 13:59:47 +0200 -Subject: [PATCH 51/87] pinctrl: add bcm2708 driver +Subject: [PATCH 51/76] BCM2708: use pinctrl-bcm2835 -This driver is a verbatim copy of the pinctrl-bcm2835 driver, except for: -* changed 2835 to 2708 -* gpio_chip and IRQ part are removed -* Probing function is changed. - -Because armctrl sets up the gpio irqs, we use the bcm2708_gpio driver. -This hack is used to be able to support both DT and non-DT builds. - -Binding document: brcm,bcm2835-gpio.txt -It's not possible to set trigger type and level flags for IRQs in the DT. +Use pinctrl-bcm2835 instead of the pinctrl-bcm2708 and bcm2708_gpio +combination. Signed-off-by: Noralf Tronnes - -pinctrl-bcm2708: pinmux_ops no longer includes disable --- - arch/arm/boot/dts/bcm2708.dtsi | 7 + - arch/arm/mach-bcm2708/Kconfig | 3 + - drivers/pinctrl/Kconfig | 5 + - drivers/pinctrl/Makefile | 1 + - drivers/pinctrl/pinctrl-bcm2708.c | 762 ++++++++++++++++++++++++++++++++++++++ - 5 files changed, 778 insertions(+) - create mode 100644 drivers/pinctrl/pinctrl-bcm2708.c + arch/arm/boot/dts/bcm2708.dtsi | 12 ++++++++++++ + arch/arm/mach-bcm2708/Kconfig | 3 +++ + arch/arm/mach-bcm2708/bcm2708.c | 2 +- + drivers/pinctrl/pinctrl-bcm2835.c | 2 +- + 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi -index a06f5b8..e02e67b 100644 +index a06f5b8..b2920c8 100644 --- a/arch/arm/boot/dts/bcm2708.dtsi +++ b/arch/arm/boot/dts/bcm2708.dtsi -@@ -26,6 +26,13 @@ +@@ -26,6 +26,18 @@ interrupt-controller; #interrupt-cells = <2>; }; + + gpio: gpio { -+ compatible = "brcm,bcm2708-pinctrl"; ++ compatible = "brcm,bcm2835-gpio"; + reg = <0x7e200000 0xb4>; ++ interrupts = <2 17>, <2 18>; ++ + gpio-controller; + #gpio-cells = <2>; ++ ++ interrupt-controller; ++ #interrupt-cells = <2>; + }; }; clocks { diff --git a/arch/arm/mach-bcm2708/Kconfig b/arch/arm/mach-bcm2708/Kconfig -index 182e7ba..05945d6 100644 +index 182e7ba..4cfae55 100644 --- a/arch/arm/mach-bcm2708/Kconfig +++ b/arch/arm/mach-bcm2708/Kconfig @@ -14,6 +14,9 @@ config BCM2708_DT depends on MACH_BCM2708 default n select USE_OF ++ select ARCH_REQUIRE_GPIOLIB + select PINCTRL -+ select PINCTRL_BCM2708 -+ select BCM2708_GPIO ++ select PINCTRL_BCM2835 help Enable Device Tree support for BCM2708 -diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig -index c6a66de..dd631cc 100644 ---- a/drivers/pinctrl/Kconfig -+++ b/drivers/pinctrl/Kconfig -@@ -79,6 +79,11 @@ config PINCTRL_BAYTRAIL - - Requires ACPI device enumeration code to set up a platform device. - -+config PINCTRL_BCM2708 -+ bool -+ select PINMUX -+ select PINCONF -+ - config PINCTRL_BCM2835 - bool - select PINMUX -diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile -index 51f52d3..12ae1bd 100644 ---- a/drivers/pinctrl/Makefile -+++ b/drivers/pinctrl/Makefile -@@ -14,6 +14,7 @@ obj-$(CONFIG_PINCTRL_AS3722) += pinctrl-as3722.o - obj-$(CONFIG_PINCTRL_BF54x) += pinctrl-adi2-bf54x.o - obj-$(CONFIG_PINCTRL_BF60x) += pinctrl-adi2-bf60x.o - obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o -+obj-$(CONFIG_PINCTRL_BCM2708) += pinctrl-bcm2708.o - obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o - obj-$(CONFIG_PINCTRL_BAYTRAIL) += pinctrl-baytrail.o - obj-$(CONFIG_PINCTRL_BCM281XX) += pinctrl-bcm281xx.o -diff --git a/drivers/pinctrl/pinctrl-bcm2708.c b/drivers/pinctrl/pinctrl-bcm2708.c -new file mode 100644 -index 0000000..f395e95 ---- /dev/null -+++ b/drivers/pinctrl/pinctrl-bcm2708.c -@@ -0,0 +1,762 @@ -+/* -+ * Driver for Broadcom BCM2708 GPIO unit (pinctrl only) -+ * -+ * Copyright (C) 2012 Chris Boot, Simon Arlott, Stephen Warren -+ * Copyright (C) 2014 Noralf Tronnes -+ * -+ * This driver is a verbatim copy of the pinctrl-bcm2835 driver, except for: -+ * - changed 2835 to 2708 -+ * - gpio_chip and IRQ part are removed -+ * - Probing function is changed. -+ * -+ * Because armctrl sets up the gpio irqs, we use the bcm2708_gpio driver. -+ * This hack is used to be able to support both DT and non-DT builds. -+ * It's not possible to set trigger type and level flags for IRQs in the DT. -+ * -+ * This driver is inspired by: -+ * pinctrl-nomadik.c, please see original file for copyright information -+ * pinctrl-tegra.c, please see original file for copyright information -+ * -+ * 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. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MODULE_NAME "pinctrl-bcm2708" -+#define BCM2708_NUM_GPIOS 54 -+#define BCM2708_NUM_BANKS 2 -+ -+#define BCM2708_PIN_BITMAP_SZ \ -+ DIV_ROUND_UP(BCM2708_NUM_GPIOS, sizeof(unsigned long) * 8) -+ -+/* GPIO register offsets */ -+#define GPFSEL0 0x0 /* Function Select */ -+#define GPSET0 0x1c /* Pin Output Set */ -+#define GPCLR0 0x28 /* Pin Output Clear */ -+#define GPLEV0 0x34 /* Pin Level */ -+#define GPEDS0 0x40 /* Pin Event Detect Status */ -+#define GPREN0 0x4c /* Pin Rising Edge Detect Enable */ -+#define GPFEN0 0x58 /* Pin Falling Edge Detect Enable */ -+#define GPHEN0 0x64 /* Pin High Detect Enable */ -+#define GPLEN0 0x70 /* Pin Low Detect Enable */ -+#define GPAREN0 0x7c /* Pin Async Rising Edge Detect */ -+#define GPAFEN0 0x88 /* Pin Async Falling Edge Detect */ -+#define GPPUD 0x94 /* Pin Pull-up/down Enable */ -+#define GPPUDCLK0 0x98 /* Pin Pull-up/down Enable Clock */ -+ -+#define FSEL_REG(p) (GPFSEL0 + (((p) / 10) * 4)) -+#define FSEL_SHIFT(p) (((p) % 10) * 3) -+#define GPIO_REG_OFFSET(p) ((p) / 32) -+#define GPIO_REG_SHIFT(p) ((p) % 32) -+ -+enum bcm2708_pinconf_param { -+ /* argument: bcm2708_pinconf_pull */ -+ BCM2708_PINCONF_PARAM_PULL, -+}; -+ -+enum bcm2708_pinconf_pull { -+ BCM2708_PINCONFIG_PULL_NONE, -+ BCM2708_PINCONFIG_PULL_DOWN, -+ BCM2708_PINCONFIG_PULL_UP, -+}; -+ -+#define BCM2708_PINCONF_PACK(_param_, _arg_) ((_param_) << 16 | (_arg_)) -+#define BCM2708_PINCONF_UNPACK_PARAM(_conf_) ((_conf_) >> 16) -+#define BCM2708_PINCONF_UNPACK_ARG(_conf_) ((_conf_) & 0xffff) -+ -+struct bcm2708_gpio_irqdata { -+ struct bcm2708_pinctrl *pc; -+ int bank; -+}; -+ -+struct bcm2708_pinctrl { -+ struct device *dev; -+ void __iomem *base; -+ int irq[BCM2708_NUM_BANKS]; -+ -+ /* note: locking assumes each bank will have its own unsigned long */ -+ unsigned long enabled_irq_map[BCM2708_NUM_BANKS]; -+ unsigned int irq_type[BCM2708_NUM_GPIOS]; -+ -+ struct pinctrl_dev *pctl_dev; -+ struct irq_domain *irq_domain; -+ struct gpio_chip gpio_chip; -+ struct pinctrl_gpio_range gpio_range; -+ -+ struct bcm2708_gpio_irqdata irq_data[BCM2708_NUM_BANKS]; -+ spinlock_t irq_lock[BCM2708_NUM_BANKS]; -+}; -+ -+/* pins are just named GPIO0..GPIO53 */ -+#define BCM2708_GPIO_PIN(a) PINCTRL_PIN(a, "gpio" #a) -+static struct pinctrl_pin_desc bcm2708_gpio_pins[] = { -+ BCM2708_GPIO_PIN(0), -+ BCM2708_GPIO_PIN(1), -+ BCM2708_GPIO_PIN(2), -+ BCM2708_GPIO_PIN(3), -+ BCM2708_GPIO_PIN(4), -+ BCM2708_GPIO_PIN(5), -+ BCM2708_GPIO_PIN(6), -+ BCM2708_GPIO_PIN(7), -+ BCM2708_GPIO_PIN(8), -+ BCM2708_GPIO_PIN(9), -+ BCM2708_GPIO_PIN(10), -+ BCM2708_GPIO_PIN(11), -+ BCM2708_GPIO_PIN(12), -+ BCM2708_GPIO_PIN(13), -+ BCM2708_GPIO_PIN(14), -+ BCM2708_GPIO_PIN(15), -+ BCM2708_GPIO_PIN(16), -+ BCM2708_GPIO_PIN(17), -+ BCM2708_GPIO_PIN(18), -+ BCM2708_GPIO_PIN(19), -+ BCM2708_GPIO_PIN(20), -+ BCM2708_GPIO_PIN(21), -+ BCM2708_GPIO_PIN(22), -+ BCM2708_GPIO_PIN(23), -+ BCM2708_GPIO_PIN(24), -+ BCM2708_GPIO_PIN(25), -+ BCM2708_GPIO_PIN(26), -+ BCM2708_GPIO_PIN(27), -+ BCM2708_GPIO_PIN(28), -+ BCM2708_GPIO_PIN(29), -+ BCM2708_GPIO_PIN(30), -+ BCM2708_GPIO_PIN(31), -+ BCM2708_GPIO_PIN(32), -+ BCM2708_GPIO_PIN(33), -+ BCM2708_GPIO_PIN(34), -+ BCM2708_GPIO_PIN(35), -+ BCM2708_GPIO_PIN(36), -+ BCM2708_GPIO_PIN(37), -+ BCM2708_GPIO_PIN(38), -+ BCM2708_GPIO_PIN(39), -+ BCM2708_GPIO_PIN(40), -+ BCM2708_GPIO_PIN(41), -+ BCM2708_GPIO_PIN(42), -+ BCM2708_GPIO_PIN(43), -+ BCM2708_GPIO_PIN(44), -+ BCM2708_GPIO_PIN(45), -+ BCM2708_GPIO_PIN(46), -+ BCM2708_GPIO_PIN(47), -+ BCM2708_GPIO_PIN(48), -+ BCM2708_GPIO_PIN(49), -+ BCM2708_GPIO_PIN(50), -+ BCM2708_GPIO_PIN(51), -+ BCM2708_GPIO_PIN(52), -+ BCM2708_GPIO_PIN(53), -+}; -+ -+/* one pin per group */ -+static const char * const bcm2708_gpio_groups[] = { -+ "gpio0", -+ "gpio1", -+ "gpio2", -+ "gpio3", -+ "gpio4", -+ "gpio5", -+ "gpio6", -+ "gpio7", -+ "gpio8", -+ "gpio9", -+ "gpio10", -+ "gpio11", -+ "gpio12", -+ "gpio13", -+ "gpio14", -+ "gpio15", -+ "gpio16", -+ "gpio17", -+ "gpio18", -+ "gpio19", -+ "gpio20", -+ "gpio21", -+ "gpio22", -+ "gpio23", -+ "gpio24", -+ "gpio25", -+ "gpio26", -+ "gpio27", -+ "gpio28", -+ "gpio29", -+ "gpio30", -+ "gpio31", -+ "gpio32", -+ "gpio33", -+ "gpio34", -+ "gpio35", -+ "gpio36", -+ "gpio37", -+ "gpio38", -+ "gpio39", -+ "gpio40", -+ "gpio41", -+ "gpio42", -+ "gpio43", -+ "gpio44", -+ "gpio45", -+ "gpio46", -+ "gpio47", -+ "gpio48", -+ "gpio49", -+ "gpio50", -+ "gpio51", -+ "gpio52", -+ "gpio53", -+}; -+ -+enum bcm2708_fsel { -+ BCM2708_FSEL_GPIO_IN = 0, -+ BCM2708_FSEL_GPIO_OUT = 1, -+ BCM2708_FSEL_ALT0 = 4, -+ BCM2708_FSEL_ALT1 = 5, -+ BCM2708_FSEL_ALT2 = 6, -+ BCM2708_FSEL_ALT3 = 7, -+ BCM2708_FSEL_ALT4 = 3, -+ BCM2708_FSEL_ALT5 = 2, -+ BCM2708_FSEL_COUNT = 8, -+ BCM2708_FSEL_MASK = 0x7, -+}; -+ -+static const char * const bcm2708_functions[BCM2708_FSEL_COUNT] = { -+ [BCM2708_FSEL_GPIO_IN] = "gpio_in", -+ [BCM2708_FSEL_GPIO_OUT] = "gpio_out", -+ [BCM2708_FSEL_ALT0] = "alt0", -+ [BCM2708_FSEL_ALT1] = "alt1", -+ [BCM2708_FSEL_ALT2] = "alt2", -+ [BCM2708_FSEL_ALT3] = "alt3", -+ [BCM2708_FSEL_ALT4] = "alt4", -+ [BCM2708_FSEL_ALT5] = "alt5", -+}; -+ -+static const char * const irq_type_names[] = { -+ [IRQ_TYPE_NONE] = "none", -+ [IRQ_TYPE_EDGE_RISING] = "edge-rising", -+ [IRQ_TYPE_EDGE_FALLING] = "edge-falling", -+ [IRQ_TYPE_EDGE_BOTH] = "edge-both", -+ [IRQ_TYPE_LEVEL_HIGH] = "level-high", -+ [IRQ_TYPE_LEVEL_LOW] = "level-low", -+}; -+ -+static inline u32 bcm2708_gpio_rd(struct bcm2708_pinctrl *pc, unsigned reg) -+{ -+ return readl(pc->base + reg); -+} -+ -+static inline void bcm2708_gpio_wr(struct bcm2708_pinctrl *pc, unsigned reg, -+ u32 val) -+{ -+ writel(val, pc->base + reg); -+} -+ -+static inline int bcm2708_gpio_get_bit(struct bcm2708_pinctrl *pc, unsigned reg, -+ unsigned bit) -+{ -+ reg += GPIO_REG_OFFSET(bit) * 4; -+ return (bcm2708_gpio_rd(pc, reg) >> GPIO_REG_SHIFT(bit)) & 1; -+} -+ -+/* note NOT a read/modify/write cycle */ -+static inline void bcm2708_gpio_set_bit(struct bcm2708_pinctrl *pc, -+ unsigned reg, unsigned bit) -+{ -+ reg += GPIO_REG_OFFSET(bit) * 4; -+ bcm2708_gpio_wr(pc, reg, BIT(GPIO_REG_SHIFT(bit))); -+} -+ -+static inline enum bcm2708_fsel bcm2708_pinctrl_fsel_get( -+ struct bcm2708_pinctrl *pc, unsigned pin) -+{ -+ u32 val = bcm2708_gpio_rd(pc, FSEL_REG(pin)); -+ enum bcm2708_fsel status = (val >> FSEL_SHIFT(pin)) & BCM2708_FSEL_MASK; -+ -+ dev_dbg(pc->dev, "get %08x (%u => %s)\n", val, pin, -+ bcm2708_functions[status]); -+ -+ return status; -+} -+ -+static inline void bcm2708_pinctrl_fsel_set( -+ struct bcm2708_pinctrl *pc, unsigned pin, -+ enum bcm2708_fsel fsel) -+{ -+ u32 val = bcm2708_gpio_rd(pc, FSEL_REG(pin)); -+ enum bcm2708_fsel cur = (val >> FSEL_SHIFT(pin)) & BCM2708_FSEL_MASK; -+ -+ dev_dbg(pc->dev, "read %08x (%u => %s)\n", val, pin, -+ bcm2708_functions[cur]); -+ -+ if (cur == fsel) -+ return; -+ -+ if (cur != BCM2708_FSEL_GPIO_IN && fsel != BCM2708_FSEL_GPIO_IN) { -+ /* always transition through GPIO_IN */ -+ val &= ~(BCM2708_FSEL_MASK << FSEL_SHIFT(pin)); -+ val |= BCM2708_FSEL_GPIO_IN << FSEL_SHIFT(pin); -+ -+ dev_dbg(pc->dev, "trans %08x (%u <= %s)\n", val, pin, -+ bcm2708_functions[BCM2708_FSEL_GPIO_IN]); -+ bcm2708_gpio_wr(pc, FSEL_REG(pin), val); -+ } -+ -+ val &= ~(BCM2708_FSEL_MASK << FSEL_SHIFT(pin)); -+ val |= fsel << FSEL_SHIFT(pin); -+ -+ dev_dbg(pc->dev, "write %08x (%u <= %s)\n", val, pin, -+ bcm2708_functions[fsel]); -+ bcm2708_gpio_wr(pc, FSEL_REG(pin), val); -+} -+ -+static int bcm2708_pctl_get_groups_count(struct pinctrl_dev *pctldev) -+{ -+ return ARRAY_SIZE(bcm2708_gpio_groups); -+} -+ -+static const char *bcm2708_pctl_get_group_name(struct pinctrl_dev *pctldev, -+ unsigned selector) -+{ -+ return bcm2708_gpio_groups[selector]; -+} -+ -+static int bcm2708_pctl_get_group_pins(struct pinctrl_dev *pctldev, -+ unsigned selector, -+ const unsigned **pins, -+ unsigned *num_pins) -+{ -+ *pins = &bcm2708_gpio_pins[selector].number; -+ *num_pins = 1; -+ -+ return 0; -+} -+ -+static void bcm2708_pctl_pin_dbg_show(struct pinctrl_dev *pctldev, -+ struct seq_file *s, -+ unsigned offset) -+{ -+ struct bcm2708_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); -+ enum bcm2708_fsel fsel = bcm2708_pinctrl_fsel_get(pc, offset); -+ const char *fname = bcm2708_functions[fsel]; -+ int value = bcm2708_gpio_get_bit(pc, GPLEV0, offset); -+ int irq = irq_find_mapping(pc->irq_domain, offset); -+ -+ seq_printf(s, "function %s in %s; irq %d (%s)", -+ fname, value ? "hi" : "lo", -+ irq, irq_type_names[pc->irq_type[offset]]); -+} -+ -+static void bcm2708_pctl_dt_free_map(struct pinctrl_dev *pctldev, -+ struct pinctrl_map *maps, unsigned num_maps) -+{ -+ int i; -+ -+ for (i = 0; i < num_maps; i++) -+ if (maps[i].type == PIN_MAP_TYPE_CONFIGS_PIN) -+ kfree(maps[i].data.configs.configs); -+ -+ kfree(maps); -+} -+ -+static int bcm2708_pctl_dt_node_to_map_func(struct bcm2708_pinctrl *pc, -+ struct device_node *np, u32 pin, u32 fnum, -+ struct pinctrl_map **maps) -+{ -+ struct pinctrl_map *map = *maps; -+ -+ if (fnum >= ARRAY_SIZE(bcm2708_functions)) { -+ dev_err(pc->dev, "%s: invalid brcm,function %d\n", -+ of_node_full_name(np), fnum); -+ return -EINVAL; -+ } -+ -+ map->type = PIN_MAP_TYPE_MUX_GROUP; -+ map->data.mux.group = bcm2708_gpio_groups[pin]; -+ map->data.mux.function = bcm2708_functions[fnum]; -+ (*maps)++; -+ -+ return 0; -+} -+ -+static int bcm2708_pctl_dt_node_to_map_pull(struct bcm2708_pinctrl *pc, -+ struct device_node *np, u32 pin, u32 pull, -+ struct pinctrl_map **maps) -+{ -+ struct pinctrl_map *map = *maps; -+ unsigned long *configs; -+ -+ if (pull > 2) { -+ dev_err(pc->dev, "%s: invalid brcm,pull %d\n", -+ of_node_full_name(np), pull); -+ return -EINVAL; -+ } -+ -+ configs = kzalloc(sizeof(*configs), GFP_KERNEL); -+ if (!configs) -+ return -ENOMEM; -+ configs[0] = BCM2708_PINCONF_PACK(BCM2708_PINCONF_PARAM_PULL, pull); -+ -+ map->type = PIN_MAP_TYPE_CONFIGS_PIN; -+ map->data.configs.group_or_pin = bcm2708_gpio_pins[pin].name; -+ map->data.configs.configs = configs; -+ map->data.configs.num_configs = 1; -+ (*maps)++; -+ -+ return 0; -+} -+ -+static int bcm2708_pctl_dt_node_to_map(struct pinctrl_dev *pctldev, -+ struct device_node *np, -+ struct pinctrl_map **map, unsigned *num_maps) -+{ -+ struct bcm2708_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); -+ struct property *pins, *funcs, *pulls; -+ int num_pins, num_funcs, num_pulls, maps_per_pin; -+ struct pinctrl_map *maps, *cur_map; -+ int i, err; -+ u32 pin, func, pull; -+ -+ pins = of_find_property(np, "brcm,pins", NULL); -+ if (!pins) { -+ dev_err(pc->dev, "%s: missing brcm,pins property\n", -+ of_node_full_name(np)); -+ return -EINVAL; -+ } -+ -+ funcs = of_find_property(np, "brcm,function", NULL); -+ pulls = of_find_property(np, "brcm,pull", NULL); -+ -+ if (!funcs && !pulls) { -+ dev_err(pc->dev, -+ "%s: neither brcm,function nor brcm,pull specified\n", -+ of_node_full_name(np)); -+ return -EINVAL; -+ } -+ -+ num_pins = pins->length / 4; -+ num_funcs = funcs ? (funcs->length / 4) : 0; -+ num_pulls = pulls ? (pulls->length / 4) : 0; -+ -+ if (num_funcs > 1 && num_funcs != num_pins) { -+ dev_err(pc->dev, -+ "%s: brcm,function must have 1 or %d entries\n", -+ of_node_full_name(np), num_pins); -+ return -EINVAL; -+ } -+ -+ if (num_pulls > 1 && num_pulls != num_pins) { -+ dev_err(pc->dev, -+ "%s: brcm,pull must have 1 or %d entries\n", -+ of_node_full_name(np), num_pins); -+ return -EINVAL; -+ } -+ -+ maps_per_pin = 0; -+ if (num_funcs) -+ maps_per_pin++; -+ if (num_pulls) -+ maps_per_pin++; -+ cur_map = maps = kzalloc(num_pins * maps_per_pin * sizeof(*maps), -+ GFP_KERNEL); -+ if (!maps) -+ return -ENOMEM; -+ -+ for (i = 0; i < num_pins; i++) { -+ err = of_property_read_u32_index(np, "brcm,pins", i, &pin); -+ if (err) -+ goto out; -+ if (pin >= ARRAY_SIZE(bcm2708_gpio_pins)) { -+ dev_err(pc->dev, "%s: invalid brcm,pins value %d\n", -+ of_node_full_name(np), pin); -+ err = -EINVAL; -+ goto out; -+ } -+ -+ if (num_funcs) { -+ err = of_property_read_u32_index(np, "brcm,function", -+ (num_funcs > 1) ? i : 0, &func); -+ if (err) -+ goto out; -+ err = bcm2708_pctl_dt_node_to_map_func(pc, np, pin, -+ func, &cur_map); -+ if (err) -+ goto out; -+ } -+ if (num_pulls) { -+ err = of_property_read_u32_index(np, "brcm,pull", -+ (num_funcs > 1) ? i : 0, &pull); -+ if (err) -+ goto out; -+ err = bcm2708_pctl_dt_node_to_map_pull(pc, np, pin, -+ pull, &cur_map); -+ if (err) -+ goto out; -+ } -+ } -+ -+ *map = maps; -+ *num_maps = num_pins * maps_per_pin; -+ -+ return 0; -+ -+out: -+ kfree(maps); -+ return err; -+} -+ -+static const struct pinctrl_ops bcm2708_pctl_ops = { -+ .get_groups_count = bcm2708_pctl_get_groups_count, -+ .get_group_name = bcm2708_pctl_get_group_name, -+ .get_group_pins = bcm2708_pctl_get_group_pins, -+ .pin_dbg_show = bcm2708_pctl_pin_dbg_show, -+ .dt_node_to_map = bcm2708_pctl_dt_node_to_map, -+ .dt_free_map = bcm2708_pctl_dt_free_map, -+}; -+ -+static int bcm2708_pmx_get_functions_count(struct pinctrl_dev *pctldev) -+{ -+ return BCM2708_FSEL_COUNT; -+} -+ -+static const char *bcm2708_pmx_get_function_name(struct pinctrl_dev *pctldev, -+ unsigned selector) -+{ -+ return bcm2708_functions[selector]; -+} -+ -+static int bcm2708_pmx_get_function_groups(struct pinctrl_dev *pctldev, -+ unsigned selector, -+ const char * const **groups, -+ unsigned * const num_groups) -+{ -+ /* every pin can do every function */ -+ *groups = bcm2708_gpio_groups; -+ *num_groups = ARRAY_SIZE(bcm2708_gpio_groups); -+ -+ return 0; -+} -+ -+static int bcm2708_pmx_set(struct pinctrl_dev *pctldev, -+ unsigned func_selector, -+ unsigned group_selector) -+{ -+ struct bcm2708_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); -+ -+ bcm2708_pinctrl_fsel_set(pc, group_selector, func_selector); -+ -+ return 0; -+} -+ -+static void bcm2708_pmx_gpio_disable_free(struct pinctrl_dev *pctldev, -+ struct pinctrl_gpio_range *range, -+ unsigned offset) -+{ -+ struct bcm2708_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); -+ -+ /* disable by setting to GPIO_IN */ -+ bcm2708_pinctrl_fsel_set(pc, offset, BCM2708_FSEL_GPIO_IN); -+} -+ -+static int bcm2708_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, -+ struct pinctrl_gpio_range *range, -+ unsigned offset, -+ bool input) -+{ -+ struct bcm2708_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); -+ enum bcm2708_fsel fsel = input ? -+ BCM2708_FSEL_GPIO_IN : BCM2708_FSEL_GPIO_OUT; -+ -+ bcm2708_pinctrl_fsel_set(pc, offset, fsel); -+ -+ return 0; -+} -+ -+static const struct pinmux_ops bcm2708_pmx_ops = { -+ .get_functions_count = bcm2708_pmx_get_functions_count, -+ .get_function_name = bcm2708_pmx_get_function_name, -+ .get_function_groups = bcm2708_pmx_get_function_groups, -+ .set_mux = bcm2708_pmx_set, -+ .gpio_disable_free = bcm2708_pmx_gpio_disable_free, -+ .gpio_set_direction = bcm2708_pmx_gpio_set_direction, -+}; -+ -+static int bcm2708_pinconf_get(struct pinctrl_dev *pctldev, -+ unsigned pin, unsigned long *config) -+{ -+ /* No way to read back config in HW */ -+ return -ENOTSUPP; -+} -+ -+static int bcm2708_pinconf_set(struct pinctrl_dev *pctldev, -+ unsigned pin, unsigned long *configs, -+ unsigned num_configs) -+{ -+ struct bcm2708_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); -+ enum bcm2708_pinconf_param param; -+ u16 arg; -+ u32 off, bit; -+ int i; -+ -+ for (i = 0; i < num_configs; i++) { -+ param = BCM2708_PINCONF_UNPACK_PARAM(configs[i]); -+ arg = BCM2708_PINCONF_UNPACK_ARG(configs[i]); -+ -+ dev_dbg(pc->dev, "configure pin %u (%s) = %04X\n", pin, bcm2708_gpio_groups[pin], arg); -+ if (param != BCM2708_PINCONF_PARAM_PULL) -+ return -EINVAL; -+ -+ off = GPIO_REG_OFFSET(pin); -+ bit = GPIO_REG_SHIFT(pin); -+ -+ bcm2708_gpio_wr(pc, GPPUD, arg & 3); -+ /* -+ * Docs say to wait 150 cycles, but not of what. We assume a -+ * 1 MHz clock here, which is pretty slow... -+ */ -+ udelay(150); -+ bcm2708_gpio_wr(pc, GPPUDCLK0 + (off * 4), BIT(bit)); -+ udelay(150); -+ bcm2708_gpio_wr(pc, GPPUDCLK0 + (off * 4), 0); -+ } /* for each config */ -+ -+ return 0; -+} -+ -+static const struct pinconf_ops bcm2708_pinconf_ops = { -+ .pin_config_get = bcm2708_pinconf_get, -+ .pin_config_set = bcm2708_pinconf_set, -+}; -+ -+static struct pinctrl_desc bcm2708_pinctrl_desc = { -+ .name = MODULE_NAME, -+ .pins = bcm2708_gpio_pins, -+ .npins = ARRAY_SIZE(bcm2708_gpio_pins), -+ .pctlops = &bcm2708_pctl_ops, -+ .pmxops = &bcm2708_pmx_ops, -+ .confops = &bcm2708_pinconf_ops, -+ .owner = THIS_MODULE, -+}; -+ -+static struct pinctrl_gpio_range bcm2708_pinctrl_gpio_range = { -+ .name = MODULE_NAME, -+ .npins = BCM2708_NUM_GPIOS, -+}; -+ -+/* bcm2708_gpio has base=0 */ -+static int bcm2708_pinctrl_gpiochip_find(struct gpio_chip *gc, void *data) -+{ -+ pr_debug("%s: base = %d\n", __func__, gc->base); -+ return gc->base == 0 ? 1 : 0; -+} -+ -+static int bcm2708_pinctrl_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct device_node *np = dev->of_node; -+ struct bcm2708_pinctrl *pc; -+ struct gpio_chip *gc; -+ struct resource iomem; -+ int err; -+ BUILD_BUG_ON(ARRAY_SIZE(bcm2708_gpio_pins) != BCM2708_NUM_GPIOS); -+ BUILD_BUG_ON(ARRAY_SIZE(bcm2708_gpio_groups) != BCM2708_NUM_GPIOS); -+ -+ /* use gpio_chip registered by the bcm2708_gpio driver */ -+ gc = gpiochip_find(NULL, bcm2708_pinctrl_gpiochip_find); -+ if (!gc) -+ return -EPROBE_DEFER; -+ -+ gc->of_node = np; -+ gc->of_gpio_n_cells = 2; -+ gc->of_xlate = of_gpio_simple_xlate; -+ -+ pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL); -+ if (!pc) -+ return -ENOMEM; -+ -+ platform_set_drvdata(pdev, pc); -+ pc->dev = dev; -+ -+ err = of_address_to_resource(np, 0, &iomem); -+ if (err) { -+ dev_err(dev, "could not get IO memory\n"); -+ return err; -+ } -+ -+ pc->base = devm_ioremap_resource(dev, &iomem); -+ if (IS_ERR(pc->base)) -+ return PTR_ERR(pc->base); -+ -+ pc->gpio_chip = *gc; -+ -+ pc->pctl_dev = pinctrl_register(&bcm2708_pinctrl_desc, dev, pc); -+ if (!pc->pctl_dev) -+ return -EINVAL; -+ -+ pc->gpio_range = bcm2708_pinctrl_gpio_range; -+ pc->gpio_range.base = pc->gpio_chip.base; -+ pc->gpio_range.gc = &pc->gpio_chip; -+ pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range); -+ -+ return 0; -+} -+ -+static int bcm2708_pinctrl_remove(struct platform_device *pdev) -+{ -+ struct bcm2708_pinctrl *pc = platform_get_drvdata(pdev); -+ -+ pinctrl_unregister(pc->pctl_dev); -+ gpiochip_remove(&pc->gpio_chip); -+ -+ return 0; -+} -+ -+static struct of_device_id bcm2708_pinctrl_match[] = { -+ { .compatible = "brcm,bcm2708-pinctrl" }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, bcm2708_pinctrl_match); -+ -+static struct platform_driver bcm2708_pinctrl_driver = { -+ .probe = bcm2708_pinctrl_probe, -+ .remove = bcm2708_pinctrl_remove, -+ .driver = { -+ .name = MODULE_NAME, -+ .owner = THIS_MODULE, -+ .of_match_table = bcm2708_pinctrl_match, -+ }, -+}; -+module_platform_driver(bcm2708_pinctrl_driver); -+ -+MODULE_AUTHOR("Chris Boot, Simon Arlott, Stephen Warren, Noralf Tronnes"); -+MODULE_DESCRIPTION("BCM2708 Pin control driver"); -+MODULE_LICENSE("GPL"); +diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c +index 747e27a..0e5bd43 100644 +--- a/arch/arm/mach-bcm2708/bcm2708.c ++++ b/arch/arm/mach-bcm2708/bcm2708.c +@@ -767,7 +767,7 @@ void __init bcm2708_init(void) + bcm_register_device(&bcm2708_dmaman_device); + bcm_register_device(&bcm2708_vcio_device); + #ifdef CONFIG_BCM2708_GPIO +- bcm_register_device(&bcm2708_gpio_device); ++ bcm_register_device_dt(&bcm2708_gpio_device); + #endif + #if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) + w1_gpio_pdata.pin = w1_gpio_pin; +diff --git a/drivers/pinctrl/pinctrl-bcm2835.c b/drivers/pinctrl/pinctrl-bcm2835.c +index eabba02..962e180 100644 +--- a/drivers/pinctrl/pinctrl-bcm2835.c ++++ b/drivers/pinctrl/pinctrl-bcm2835.c +@@ -382,7 +382,7 @@ static struct gpio_chip bcm2835_gpio_chip = { + .get = bcm2835_gpio_get, + .set = bcm2835_gpio_set, + .to_irq = bcm2835_gpio_to_irq, +- .base = -1, ++ .base = 0, + .ngpio = BCM2835_NUM_GPIOS, + .can_sleep = false, + }; -From c5c3a31046630ac668c74babf9c64777a6c6196d Mon Sep 17 00:00:00 2001 +From 8bc39e48d192b74a39301783d49b3515b3fd2756 Mon Sep 17 00:00:00 2001 From: notro Date: Sun, 27 Jul 2014 20:12:58 +0200 -Subject: [PATCH 52/87] spi: bcm2708: add device tree support +Subject: [PATCH 52/76] spi: bcm2708: add device tree support Add DT support to driver and add to .dtsi file. Setup pins and spidev in .dts file. SPI is disabled by default. Signed-off-by: Noralf Tronnes + +BCM2708: don't register SPI controller when using DT + +The device for the SPI controller is in the Device Tree. +Only register the device when not using DT. + +Signed-off-by: Noralf Tronnes + +spi: bcm2835: make driver available on ARCH_BCM2708 + +Make this driver available on ARCH_BCM2708 + +Signed-off-by: Noralf Tronnes + +bcm2708: Remove the prohibition on mixing SPIDEV and DT --- arch/arm/boot/dts/bcm2708-rpi-b.dts | 32 ++++++++++++++++++++++++++++++++ arch/arm/boot/dts/bcm2708.dtsi | 18 ++++++++++++++++++ + arch/arm/mach-bcm2708/bcm2708.c | 19 ++++++++++++++++--- + drivers/spi/Kconfig | 2 +- drivers/spi/spi-bcm2708.c | 8 ++++++++ - 3 files changed, 58 insertions(+) + 5 files changed, 75 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts index e319c8e..30107fb 100644 @@ -110995,12 +110141,12 @@ index e319c8e..30107fb 100644 + }; }; diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi -index e02e67b..ec1d006 100644 +index b2920c8..e90bf4c 100644 --- a/arch/arm/boot/dts/bcm2708.dtsi +++ b/arch/arm/boot/dts/bcm2708.dtsi -@@ -33,11 +33,29 @@ - gpio-controller; - #gpio-cells = <2>; +@@ -38,11 +38,29 @@ + interrupt-controller; + #interrupt-cells = <2>; }; + + spi0: spi@7e204000 { @@ -111028,66 +110174,8 @@ index e02e67b..ec1d006 100644 + }; }; }; -diff --git a/drivers/spi/spi-bcm2708.c b/drivers/spi/spi-bcm2708.c -index 349d21f..041b5e2 100644 ---- a/drivers/spi/spi-bcm2708.c -+++ b/drivers/spi/spi-bcm2708.c -@@ -512,6 +512,7 @@ static int bcm2708_spi_probe(struct platform_device *pdev) - master->setup = bcm2708_spi_setup; - master->transfer = bcm2708_spi_transfer; - master->cleanup = bcm2708_spi_cleanup; -+ master->dev.of_node = pdev->dev.of_node; - platform_set_drvdata(pdev, master); - - bs = spi_master_get_devdata(master); -@@ -596,10 +597,17 @@ static int bcm2708_spi_remove(struct platform_device *pdev) - return 0; - } - -+static const struct of_device_id bcm2708_spi_match[] = { -+ { .compatible = "brcm,bcm2708-spi", }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, bcm2708_spi_match); -+ - static struct platform_driver bcm2708_spi_driver = { - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, -+ .of_match_table = bcm2708_spi_match, - }, - .probe = bcm2708_spi_probe, - .remove = bcm2708_spi_remove, - -From 37c26457e4ceba3f49b594431432c9cd57c70188 Mon Sep 17 00:00:00 2001 -From: notro -Date: Sun, 27 Jul 2014 20:13:44 +0200 -Subject: [PATCH 53/87] BCM2708: don't register SPI controller when using DT - -The device for the SPI controller is in the Device Tree. -Only register the device when not using DT. - -Signed-off-by: Noralf Tronnes ---- - arch/arm/mach-bcm2708/Kconfig | 2 +- - arch/arm/mach-bcm2708/bcm2708.c | 14 +++++++++++++- - 2 files changed, 14 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/Kconfig b/arch/arm/mach-bcm2708/Kconfig -index 05945d6..1f29d7d 100644 ---- a/arch/arm/mach-bcm2708/Kconfig -+++ b/arch/arm/mach-bcm2708/Kconfig -@@ -44,7 +44,7 @@ config BCM2708_NOL2CACHE - - config BCM2708_SPIDEV - bool "Bind spidev to SPI0 master" -- depends on MACH_BCM2708 -+ depends on MACH_BCM2708 && !USE_OF - depends on SPI - default y - help diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 747e27a..0434cbf 100644 +index 0e5bd43..a2069f8 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c @@ -486,6 +486,7 @@ static struct platform_device bcm2708_alsa_devices[] = { @@ -111132,19 +110220,18 @@ index 747e27a..0434cbf 100644 bcm_register_device(&bcm2708_bsc0_device); bcm_register_device(&bcm2708_bsc1_device); - -From 503b772789cf0e88898278dda62b491cb1c5d258 Mon Sep 17 00:00:00 2001 -From: notro -Date: Sun, 27 Jul 2014 20:14:05 +0200 -Subject: [PATCH 54/87] spi: bcm2835: make driver available on ARCH_BCM2708 - -Make this driver available on ARCH_BCM2708 - -Signed-off-by: Noralf Tronnes ---- - drivers/spi/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - +@@ -824,8 +836,9 @@ void __init bcm2708_init(void) + system_serial_low = serial; + + #ifdef CONFIG_BCM2708_SPIDEV +- spi_register_board_info(bcm2708_spi_devices, +- ARRAY_SIZE(bcm2708_spi_devices)); ++ if (!use_dt) ++ spi_register_board_info(bcm2708_spi_devices, ++ ARRAY_SIZE(bcm2708_spi_devices)); + #endif + } + diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 71b4741..a5238ab 100644 --- a/drivers/spi/Kconfig @@ -111158,22 +110245,67 @@ index 71b4741..a5238ab 100644 help This selects a driver for the Broadcom BCM2835 SPI master. +diff --git a/drivers/spi/spi-bcm2708.c b/drivers/spi/spi-bcm2708.c +index 349d21f..041b5e2 100644 +--- a/drivers/spi/spi-bcm2708.c ++++ b/drivers/spi/spi-bcm2708.c +@@ -512,6 +512,7 @@ static int bcm2708_spi_probe(struct platform_device *pdev) + master->setup = bcm2708_spi_setup; + master->transfer = bcm2708_spi_transfer; + master->cleanup = bcm2708_spi_cleanup; ++ master->dev.of_node = pdev->dev.of_node; + platform_set_drvdata(pdev, master); + + bs = spi_master_get_devdata(master); +@@ -596,10 +597,17 @@ static int bcm2708_spi_remove(struct platform_device *pdev) + return 0; + } + ++static const struct of_device_id bcm2708_spi_match[] = { ++ { .compatible = "brcm,bcm2708-spi", }, ++ {} ++}; ++MODULE_DEVICE_TABLE(of, bcm2708_spi_match); ++ + static struct platform_driver bcm2708_spi_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, ++ .of_match_table = bcm2708_spi_match, + }, + .probe = bcm2708_spi_probe, + .remove = bcm2708_spi_remove, -From 918466788c24fa1bdee3f8f4037a22e852a20275 Mon Sep 17 00:00:00 2001 +From 363efe4c5bed0c162630f31d5f6ad2b3aceb0d0c Mon Sep 17 00:00:00 2001 From: notro Date: Tue, 29 Jul 2014 11:04:49 +0200 -Subject: [PATCH 55/87] i2c: bcm2708: add device tree support +Subject: [PATCH 53/76] i2c: bcm2708: add device tree support Add DT support to driver and add to .dtsi file. Setup pins in .dts file. i2c is disabled by default. +Signed-off-by: Noralf Tronnes + +bcm2708: don't register i2c controllers when using DT + +The devices for the i2c controllers are in the Device Tree. +Only register devices when not using DT. + +Signed-off-by: Noralf Tronnes + +i2c: bcm2835: make driver available on ARCH_BCM2708 + +Make this driver available on ARCH_BCM2708 + Signed-off-by: Noralf Tronnes --- arch/arm/boot/dts/bcm2708-rpi-b.dts | 24 ++++++++++++++++++++++++ arch/arm/boot/dts/bcm2708.dtsi | 27 +++++++++++++++++++++++++++ + arch/arm/mach-bcm2708/bcm2708.c | 6 ++++-- + drivers/i2c/busses/Kconfig | 2 +- drivers/i2c/busses/i2c-bcm2708.c | 24 ++++++++++++++++++++++++ - 3 files changed, 75 insertions(+) + 5 files changed, 80 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts index 30107fb..5893122 100644 @@ -111222,10 +110354,10 @@ index 30107fb..5893122 100644 + clock-frequency = <100000>; +}; diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi -index ec1d006..edf3619 100644 +index e90bf4c..2ca6d63 100644 --- a/arch/arm/boot/dts/bcm2708.dtsi +++ b/arch/arm/boot/dts/bcm2708.dtsi -@@ -43,6 +43,26 @@ +@@ -48,6 +48,26 @@ #size-cells = <0>; status = "disabled"; }; @@ -111252,7 +110384,7 @@ index ec1d006..edf3619 100644 }; clocks { -@@ -50,6 +70,13 @@ +@@ -55,6 +75,13 @@ #address-cells = <1>; #size-cells = <0>; @@ -111266,82 +110398,8 @@ index ec1d006..edf3619 100644 clk_spi: clock@2 { compatible = "fixed-clock"; reg = <2>; -diff --git a/drivers/i2c/busses/i2c-bcm2708.c b/drivers/i2c/busses/i2c-bcm2708.c -index 8750634..728cb69 100644 ---- a/drivers/i2c/busses/i2c-bcm2708.c -+++ b/drivers/i2c/busses/i2c-bcm2708.c -@@ -26,6 +26,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -302,6 +303,21 @@ static int bcm2708_i2c_probe(struct platform_device *pdev) - unsigned long bus_hz; - u32 cdiv; - -+ if (pdev->dev.of_node) { -+ u32 bus_clk_rate; -+ pdev->id = of_alias_get_id(pdev->dev.of_node, "i2c"); -+ if (pdev->id < 0) { -+ dev_err(&pdev->dev, "alias is missing\n"); -+ return -EINVAL; -+ } -+ if (!of_property_read_u32(pdev->dev.of_node, -+ "clock-frequency", &bus_clk_rate)) -+ baudrate = bus_clk_rate; -+ else -+ dev_warn(&pdev->dev, -+ "Could not read clock-frequency property\n"); -+ } -+ - regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!regs) { - dev_err(&pdev->dev, "could not get IO memory\n"); -@@ -335,6 +351,7 @@ static int bcm2708_i2c_probe(struct platform_device *pdev) - adap->dev.parent = &pdev->dev; - adap->nr = pdev->id; - strlcpy(adap->name, dev_name(&pdev->dev), sizeof(adap->name)); -+ adap->dev.of_node = pdev->dev.of_node; - - switch (pdev->id) { - case 0: -@@ -415,10 +432,17 @@ static int bcm2708_i2c_remove(struct platform_device *pdev) - return 0; - } - -+static const struct of_device_id bcm2708_i2c_of_match[] = { -+ { .compatible = "brcm,bcm2708-i2c" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, bcm2708_i2c_of_match); -+ - static struct platform_driver bcm2708_i2c_driver = { - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, -+ .of_match_table = bcm2708_i2c_of_match, - }, - .probe = bcm2708_i2c_probe, - .remove = bcm2708_i2c_remove, - -From 6d10b38d8ccf6640538e2ff74720e5e088dcb78a Mon Sep 17 00:00:00 2001 -From: notro -Date: Tue, 29 Jul 2014 11:05:18 +0200 -Subject: [PATCH 56/87] bcm2708: don't register i2c controllers when using DT - -The devices for the i2c controllers are in the Device Tree. -Only register devices when not using DT. - -Signed-off-by: Noralf Tronnes ---- - arch/arm/mach-bcm2708/bcm2708.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 0434cbf..902f8c7 100644 +index a2069f8..b45f327 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c @@ -532,6 +532,7 @@ static struct spi_board_info bcm2708_spi_devices[] = { @@ -111371,19 +110429,6 @@ index 0434cbf..902f8c7 100644 bcm_register_device(&bcm2835_hwmon_device); bcm_register_device(&bcm2835_thermal_device); - -From 16522c5131466ead24a8f6c508ae0bf64c203e44 Mon Sep 17 00:00:00 2001 -From: notro -Date: Tue, 29 Jul 2014 11:05:39 +0200 -Subject: [PATCH 57/87] i2c: bcm2835: make driver available on ARCH_BCM2708 - -Make this driver available on ARCH_BCM2708 - -Signed-off-by: Noralf Tronnes ---- - drivers/i2c/busses/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 3d3db41..d30a986 100644 --- a/drivers/i2c/busses/Kconfig @@ -111397,11 +110442,71 @@ index 3d3db41..d30a986 100644 help If you say yes to this option, support will be included for the BCM2835 I2C controller. +diff --git a/drivers/i2c/busses/i2c-bcm2708.c b/drivers/i2c/busses/i2c-bcm2708.c +index 7d385a3..526129b 100644 +--- a/drivers/i2c/busses/i2c-bcm2708.c ++++ b/drivers/i2c/busses/i2c-bcm2708.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -303,6 +304,21 @@ static int bcm2708_i2c_probe(struct platform_device *pdev) + unsigned long bus_hz; + u32 cdiv; + ++ if (pdev->dev.of_node) { ++ u32 bus_clk_rate; ++ pdev->id = of_alias_get_id(pdev->dev.of_node, "i2c"); ++ if (pdev->id < 0) { ++ dev_err(&pdev->dev, "alias is missing\n"); ++ return -EINVAL; ++ } ++ if (!of_property_read_u32(pdev->dev.of_node, ++ "clock-frequency", &bus_clk_rate)) ++ baudrate = bus_clk_rate; ++ else ++ dev_warn(&pdev->dev, ++ "Could not read clock-frequency property\n"); ++ } ++ + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!regs) { + dev_err(&pdev->dev, "could not get IO memory\n"); +@@ -336,6 +352,7 @@ static int bcm2708_i2c_probe(struct platform_device *pdev) + adap->dev.parent = &pdev->dev; + adap->nr = pdev->id; + strlcpy(adap->name, dev_name(&pdev->dev), sizeof(adap->name)); ++ adap->dev.of_node = pdev->dev.of_node; + + switch (pdev->id) { + case 0: +@@ -416,10 +433,17 @@ static int bcm2708_i2c_remove(struct platform_device *pdev) + return 0; + } + ++static const struct of_device_id bcm2708_i2c_of_match[] = { ++ { .compatible = "brcm,bcm2708-i2c" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, bcm2708_i2c_of_match); ++ + static struct platform_driver bcm2708_i2c_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, ++ .of_match_table = bcm2708_i2c_of_match, + }, + .probe = bcm2708_i2c_probe, + .remove = bcm2708_i2c_remove, -From c645b231fc20ea8108b4b099f8cd6fe5468084b1 Mon Sep 17 00:00:00 2001 +From ecf35fb1a168f0faab35509335716f0b075424f5 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 14 Jul 2014 22:02:09 +0100 -Subject: [PATCH 58/87] hid: Reduce default mouse polling interval to 60Hz +Subject: [PATCH 54/76] hid: Reduce default mouse polling interval to 60Hz Reduces overhead when using X --- @@ -111437,10 +110542,10 @@ index ca6849a..4671921 100644 ret = -ENOMEM; if (usb_endpoint_dir_in(endpoint)) { -From fd6f47b6ad4477097d8e505f50a4bb4858656288 Mon Sep 17 00:00:00 2001 +From 4a9e6322572b259088f7b4dbf8a2eea2680d5708 Mon Sep 17 00:00:00 2001 From: P33M Date: Thu, 24 Jul 2014 21:24:03 +0100 -Subject: [PATCH 59/87] usb: core: make overcurrent messages more prominent +Subject: [PATCH 55/76] usb: core: make overcurrent messages more prominent Hub overcurrent messages are more serious than "debug". Increase loglevel. --- @@ -111461,10 +110566,10 @@ index b649fef..5f8d914 100644 USB_PORT_FEAT_C_OVER_CURRENT); msleep(100); /* Cool down */ -From 9e78784975e7411d0bc6bd87119f84349843ca6b Mon Sep 17 00:00:00 2001 +From 79c11d68d582d6561891fc52423754f14cc3ba31 Mon Sep 17 00:00:00 2001 From: Tim Gover Date: Tue, 22 Jul 2014 15:41:04 +0100 -Subject: [PATCH 60/87] vcsm: VideoCore shared memory service for BCM2835 +Subject: [PATCH 56/76] vcsm: VideoCore shared memory service for BCM2835 Add experimental support for the VideoCore shared memory service. This allows user processes to allocate memory from VideoCore's @@ -115797,10 +114902,10 @@ index 0000000..da1c523 +MODULE_DESCRIPTION("VideoCore SharedMemory Driver"); +MODULE_LICENSE("GPL v2"); -From 1ca69f1065de9fda7a259195522af33bfdd57d0b Mon Sep 17 00:00:00 2001 +From 08300f102032071719eda4bd4c0709c8a81b1cb0 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Thu, 7 Aug 2014 02:03:50 +0100 -Subject: [PATCH 61/87] Revert "ARM: dma: Use dma_pfn_offset for dma address +Subject: [PATCH 57/76] Revert "ARM: dma: Use dma_pfn_offset for dma address translation" This reverts commit 6ce0d20016925d031f1e24d64302e4c976d7cec6. @@ -115852,25 +114957,25 @@ index 85738b2..9477f09 100644 } -From 0af048a460e8ec3b9a1fc576ba33e9b252f79024 Mon Sep 17 00:00:00 2001 +From 5825382cf4c614ee606bddb187375a2451ec7a4a Mon Sep 17 00:00:00 2001 From: gellert Date: Fri, 15 Aug 2014 16:35:06 +0100 -Subject: [PATCH 62/87] MMC: added alternative MMC driver +Subject: [PATCH 58/76] MMC: added alternative MMC driver --- arch/arm/configs/bcmrpi_defconfig | 2 + arch/arm/mach-bcm2708/bcm2708.c | 31 + drivers/mmc/host/Kconfig | 40 +- drivers/mmc/host/Makefile | 1 + - drivers/mmc/host/bcm2835-mmc.c | 1547 +++++++++++++++++++++++++++++++++++++ - 5 files changed, 1610 insertions(+), 11 deletions(-) + drivers/mmc/host/bcm2835-mmc.c | 1557 +++++++++++++++++++++++++++++++++++++ + 5 files changed, 1620 insertions(+), 11 deletions(-) create mode 100644 drivers/mmc/host/bcm2835-mmc.c diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 5a2714c..ca84a3b 100644 +index f15a4b9..c363a10 100644 --- a/arch/arm/configs/bcmrpi_defconfig +++ b/arch/arm/configs/bcmrpi_defconfig -@@ -906,6 +906,8 @@ CONFIG_MMC=y +@@ -908,6 +908,8 @@ CONFIG_MMC=y CONFIG_MMC_BLOCK_MINORS=32 CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_PLTFM=y @@ -115880,7 +114985,7 @@ index 5a2714c..ca84a3b 100644 CONFIG_LEDS_CLASS=y CONFIG_LEDS_GPIO=y diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 902f8c7..c9e3038 100644 +index b45f327..5ff1299 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c @@ -414,6 +414,34 @@ static struct platform_device bcm2708_systemtimer_device = { @@ -116000,10 +115105,10 @@ index b09ecfb..7b17387 100644 obj-$(CONFIG_MMC_OMAP) += omap.o diff --git a/drivers/mmc/host/bcm2835-mmc.c b/drivers/mmc/host/bcm2835-mmc.c new file mode 100644 -index 0000000..123ff94 +index 0000000..cefba7c --- /dev/null +++ b/drivers/mmc/host/bcm2835-mmc.c -@@ -0,0 +1,1547 @@ +@@ -0,0 +1,1557 @@ +/* + * BCM2835 MMC host driver. + * @@ -116778,6 +115883,11 @@ index 0000000..123ff94 + if (host->cmd == host->mrq->sbc) { + host->cmd = NULL; + bcm2835_mmc_send_command(host, host->mrq->cmd); ++ ++ if (host->mrq->cmd->data && host->use_dma) { ++ /* DMA transfer starts now, PIO starts after interrupt */ ++ bcm2835_mmc_transfer_dma(host); ++ } + } else { + + /* Processed actual command. */ @@ -117135,11 +116245,16 @@ index 0000000..123ff94 + WARN_ON(host->mrq != NULL); + + host->mrq = mrq; -+ bcm2835_mmc_send_command(host, mrq->cmd); ++ ++ if (mrq->sbc && !(host->flags & SDHCI_AUTO_CMD23)) ++ bcm2835_mmc_send_command(host, mrq->sbc); ++ else ++ bcm2835_mmc_send_command(host, mrq->cmd); ++ + mmiowb(); + spin_unlock_irqrestore(&host->lock, flags); + -+ if (mrq->cmd->data && host->use_dma) { ++ if (!(mrq->sbc && !(host->flags & SDHCI_AUTO_CMD23)) && mrq->cmd->data && host->use_dma) { + /* DMA transfer starts now, PIO starts after interrupt */ + bcm2835_mmc_transfer_dma(host); + } @@ -117552,10 +116667,39 @@ index 0000000..123ff94 +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Gellert Weisz"); -From d2f60dd79e4099d49d8feeb1f598fc811261f336 Mon Sep 17 00:00:00 2001 +From 52bb08dae804332e656e9663a4c7955a836c187f Mon Sep 17 00:00:00 2001 +From: P33M +Date: Tue, 13 Jan 2015 17:12:18 +0000 +Subject: [PATCH 59/76] mmc: Disable CMD23 transfers on all cards + +Pending wire-level investigation of these types of transfers +and associated errors on bcm2835-mmc, disable for now. Fallback of +CMD18/CMD25 transfers will be used automatically by the MMC layer. + +Reported/Tested-by: Gellert Weisz +--- + drivers/mmc/core/quirks.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/mmc/core/quirks.c b/drivers/mmc/core/quirks.c +index dd1d1e0..f472082 100644 +--- a/drivers/mmc/core/quirks.c ++++ b/drivers/mmc/core/quirks.c +@@ -95,5 +95,9 @@ void mmc_fixup_device(struct mmc_card *card, const struct mmc_fixup *table) + f->vendor_fixup(card, f->data); + } + } ++ /* SDHCI on BCM2708 - bug causes a certain sequence of CMD23 operations to fail. ++ * Disable this flag for all cards (fall-back to CMD25/CMD18 multi-block transfers). ++ */ ++ card->quirks |= MMC_QUIRK_BLK_NO_CMD23; + } + EXPORT_SYMBOL(mmc_fixup_device); + +From 9f25f6c8508ab94b4393981a837de15f41dce07d Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Mon, 4 Aug 2014 10:06:56 +0200 -Subject: [PATCH 63/87] Added support for HiFiBerry DAC+ +Subject: [PATCH 60/76] Added support for HiFiBerry DAC+ The driver is based on the HiFiBerry DAC driver. However HiFiBerry DAC+ uses a different codec chip (PCM5122), therefore a new driver is necessary. @@ -117569,10 +116713,10 @@ a different codec chip (PCM5122), therefore a new driver is necessary. create mode 100644 sound/soc/bcm/hifiberry_dacplus.c diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index ca84a3b..4be393a 100644 +index c363a10..28547eb 100644 --- a/arch/arm/configs/bcmrpi_defconfig +++ b/arch/arm/configs/bcmrpi_defconfig -@@ -754,6 +754,7 @@ CONFIG_SND_USB_6FIRE=m +@@ -756,6 +756,7 @@ CONFIG_SND_USB_6FIRE=m CONFIG_SND_SOC=m CONFIG_SND_BCM2708_SOC_I2S=m CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m @@ -117581,7 +116725,7 @@ index ca84a3b..4be393a 100644 CONFIG_SND_BCM2708_SOC_RPI_DAC=m CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index c9e3038..5c19350 100644 +index 5ff1299..aa62e55 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c @@ -645,6 +645,20 @@ static struct platform_device snd_pcm5102a_codec_device = { @@ -117779,10 +116923,10 @@ index 0000000..c63387b +MODULE_DESCRIPTION("ASoC Driver for HiFiBerry DAC+"); +MODULE_LICENSE("GPL v2"); -From 286ac0b773dab08b5ce46497754748e9ccf4dfbd Mon Sep 17 00:00:00 2001 +From 508fb196c75dd4283f83e16ff7863db19c69b2a2 Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Mon, 4 Aug 2014 11:09:58 +0200 -Subject: [PATCH 64/87] Added driver for HiFiBerry Amp amplifier add-on board +Subject: [PATCH 61/76] Added driver for HiFiBerry Amp amplifier add-on board The driver contains a low-level hardware driver for the TAS5713 and the drivers for the Raspberry Pi I2S subsystem. @@ -117802,10 +116946,10 @@ drivers for the Raspberry Pi I2S subsystem. create mode 100644 sound/soc/codecs/tas5713.h diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 4be393a..614158e 100644 +index 28547eb..997e1f3 100644 --- a/arch/arm/configs/bcmrpi_defconfig +++ b/arch/arm/configs/bcmrpi_defconfig -@@ -756,6 +756,7 @@ CONFIG_SND_BCM2708_SOC_I2S=m +@@ -758,6 +758,7 @@ CONFIG_SND_BCM2708_SOC_I2S=m CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m @@ -117814,7 +116958,7 @@ index 4be393a..614158e 100644 CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m CONFIG_SND_SIMPLE_CARD=m diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 5c19350..2f2e11f 100644 +index aa62e55..5f6a1fa 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c @@ -674,6 +674,20 @@ static struct i2c_board_info __initdata snd_wm8804_i2c_devices[] = { @@ -118626,10 +117770,10 @@ index 0000000..8f019e0 + +#endif /* _TAS5713_H */ -From cedada8df17e326d6e1c0ff24b12c473ff204540 Mon Sep 17 00:00:00 2001 +From fe5a92538a62c6724a9298305a438eb48a75f5d9 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 13 Oct 2014 11:47:53 +0100 -Subject: [PATCH 65/87] Improve __copy_to_user and __copy_from_user performance +Subject: [PATCH 62/76] Improve __copy_to_user and __copy_from_user performance Provide a __copy_from_user that uses memcpy. On BCM2708, use optimised memcpy/memmove/memcmp/memset implementations. @@ -120152,10 +119296,10 @@ index 3e58d71..0622891 100644 static unsigned long noinline __clear_user_memset(void __user *addr, unsigned long n) -From eeb0125101864b040215911a6ce602287a18dc93 Mon Sep 17 00:00:00 2001 +From c31fbfd215f5900c20ae1237be7d758b157fbc34 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 1 Sep 2014 16:35:56 +0100 -Subject: [PATCH 66/87] bcm2708: Allow option card devices to be configured via +Subject: [PATCH 63/76] bcm2708: Allow option card devices to be configured via DT If the kernel is built with Device Tree support, and if a DT blob @@ -120173,7 +119317,7 @@ support code with each new device. 6 files changed, 80 insertions(+), 64 deletions(-) diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 2f2e11f..c6d4ff6 100644 +index 5f6a1fa..2c6a29d 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c @@ -35,6 +35,7 @@ @@ -120340,7 +119484,7 @@ index 2f2e11f..c6d4ff6 100644 #endif -@@ -1040,9 +1040,9 @@ static struct platform_device bcm2708_led_device = { +@@ -1041,9 +1041,9 @@ static struct platform_device bcm2708_led_device = { static void __init bcm2708_init_led(void) { @@ -120354,7 +119498,7 @@ index 2f2e11f..c6d4ff6 100644 #else static inline void bcm2708_init_led(void) diff --git a/drivers/dma/bcm2708-dmaengine.c b/drivers/dma/bcm2708-dmaengine.c -index 6766799..27ee1c1 100644 +index 10463db..3f9be02 100644 --- a/drivers/dma/bcm2708-dmaengine.c +++ b/drivers/dma/bcm2708-dmaengine.c @@ -42,7 +42,7 @@ @@ -120366,7 +119510,7 @@ index 6766799..27ee1c1 100644 /* dma manager */ #include -@@ -710,7 +710,7 @@ static int bcm2835_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, +@@ -721,7 +721,7 @@ static int bcm2835_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, } } @@ -120375,7 +119519,7 @@ index 6766799..27ee1c1 100644 static int bcm2835_dma_chan_init(struct bcm2835_dmadev *d, int chan_id, int irq) { struct bcm2835_chan *c; -@@ -773,7 +773,7 @@ static const struct of_device_id bcm2835_dma_of_match[] = { +@@ -784,7 +784,7 @@ static const struct of_device_id bcm2835_dma_of_match[] = { }; MODULE_DEVICE_TABLE(of, bcm2835_dma_of_match); @@ -120384,7 +119528,7 @@ index 6766799..27ee1c1 100644 static struct dma_chan *bcm2835_dma_xlate(struct of_phandle_args *spec, struct of_dma *ofdma) { -@@ -806,7 +806,7 @@ static int bcm2835_dma_device_slave_caps(struct dma_chan *dchan, +@@ -817,7 +817,7 @@ static int bcm2835_dma_device_slave_caps(struct dma_chan *dchan, static int bcm2835_dma_probe(struct platform_device *pdev) { struct bcm2835_dmadev *od; @@ -120393,7 +119537,7 @@ index 6766799..27ee1c1 100644 struct resource *res; void __iomem *base; uint32_t chans_available; -@@ -819,10 +819,10 @@ static int bcm2835_dma_probe(struct platform_device *pdev) +@@ -830,10 +830,10 @@ static int bcm2835_dma_probe(struct platform_device *pdev) if (!pdev->dev.dma_mask) pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; @@ -120406,7 +119550,7 @@ index 6766799..27ee1c1 100644 rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); if (rc) -@@ -976,7 +976,7 @@ static int bcm2835_dma_remove(struct platform_device *pdev) +@@ -987,7 +987,7 @@ static int bcm2835_dma_remove(struct platform_device *pdev) return 0; } @@ -120416,7 +119560,7 @@ index 6766799..27ee1c1 100644 static struct platform_driver bcm2835_dma_driver = { diff --git a/drivers/mmc/host/bcm2835-mmc.c b/drivers/mmc/host/bcm2835-mmc.c -index 123ff94..d8b034a 100644 +index cefba7c..34d6167 100644 --- a/drivers/mmc/host/bcm2835-mmc.c +++ b/drivers/mmc/host/bcm2835-mmc.c @@ -42,7 +42,7 @@ @@ -120437,7 +119581,7 @@ index 123ff94..d8b034a 100644 if (!cmd->data && cmd->busy_timeout > 9000) timeout += DIV_ROUND_UP(cmd->busy_timeout, 1000) * HZ + HZ; else -@@ -957,7 +957,7 @@ static irqreturn_t bcm2835_mmc_irq(int irq, void *dev_id) +@@ -962,7 +962,7 @@ static irqreturn_t bcm2835_mmc_irq(int irq, void *dev_id) struct bcm2835_host *host = dev_id; u32 intmask, mask, unexpected = 0; int max_loops = 16; @@ -120446,7 +119590,7 @@ index 123ff94..d8b034a 100644 int cardint = 0; #endif -@@ -988,7 +988,7 @@ static irqreturn_t bcm2835_mmc_irq(int irq, void *dev_id) +@@ -993,7 +993,7 @@ static irqreturn_t bcm2835_mmc_irq(int irq, void *dev_id) mmc_hostname(host->mmc)); if (intmask & SDHCI_INT_CARD_INT) { @@ -120455,7 +119599,7 @@ index 123ff94..d8b034a 100644 cardint = 1; #else bcm2835_mmc_enable_sdio_irq_nolock(host, false); -@@ -1021,7 +1021,7 @@ static irqreturn_t bcm2835_mmc_irq(int irq, void *dev_id) +@@ -1026,7 +1026,7 @@ static irqreturn_t bcm2835_mmc_irq(int irq, void *dev_id) bcm2835_mmc_dumpregs(host); } @@ -120464,7 +119608,7 @@ index 123ff94..d8b034a 100644 if (cardint) mmc_signal_sdio_irq(host->mmc); #endif -@@ -1029,7 +1029,7 @@ static irqreturn_t bcm2835_mmc_irq(int irq, void *dev_id) +@@ -1034,7 +1034,7 @@ static irqreturn_t bcm2835_mmc_irq(int irq, void *dev_id) return result; } @@ -120473,7 +119617,7 @@ index 123ff94..d8b034a 100644 static irqreturn_t bcm2835_mmc_thread_irq(int irq, void *dev_id) { struct bcm2835_host *host = dev_id; -@@ -1278,7 +1278,7 @@ int bcm2835_mmc_add_host(struct bcm2835_host *host) +@@ -1288,7 +1288,7 @@ int bcm2835_mmc_add_host(struct bcm2835_host *host) /* SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK */ host->timeout_clk = mmc->f_max / 1000; @@ -120482,7 +119626,7 @@ index 123ff94..d8b034a 100644 mmc->max_busy_timeout = (1 << 27) / host->timeout_clk; #endif /* host controller capabilities */ -@@ -1335,7 +1335,7 @@ int bcm2835_mmc_add_host(struct bcm2835_host *host) +@@ -1345,7 +1345,7 @@ int bcm2835_mmc_add_host(struct bcm2835_host *host) init_waitqueue_head(&host->buf_ready_int); bcm2835_mmc_init(host, 0); @@ -120491,7 +119635,7 @@ index 123ff94..d8b034a 100644 ret = request_irq(host->irq, bcm2835_mmc_irq, 0 /*IRQF_SHARED*/, mmc_hostname(mmc), host); #else -@@ -1364,7 +1364,7 @@ int bcm2835_mmc_add_host(struct bcm2835_host *host) +@@ -1374,7 +1374,7 @@ int bcm2835_mmc_add_host(struct bcm2835_host *host) static int bcm2835_mmc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -120500,7 +119644,7 @@ index 123ff94..d8b034a 100644 struct device_node *node = dev->of_node; struct clk *clk; #endif -@@ -1373,7 +1373,7 @@ static int bcm2835_mmc_probe(struct platform_device *pdev) +@@ -1383,7 +1383,7 @@ static int bcm2835_mmc_probe(struct platform_device *pdev) int ret; struct mmc_host *mmc; @@ -120509,7 +119653,7 @@ index 123ff94..d8b034a 100644 dma_cap_mask_t mask; #endif -@@ -1398,7 +1398,7 @@ static int bcm2835_mmc_probe(struct platform_device *pdev) +@@ -1408,7 +1408,7 @@ static int bcm2835_mmc_probe(struct platform_device *pdev) host->phys_addr = iomem->start + BCM2835_VCMMU_SHIFT; @@ -120518,7 +119662,7 @@ index 123ff94..d8b034a 100644 #ifndef FORCE_PIO dma_cap_zero(mask); /* we don't care about the channel, any would work */ -@@ -1448,7 +1448,7 @@ static int bcm2835_mmc_probe(struct platform_device *pdev) +@@ -1458,7 +1458,7 @@ static int bcm2835_mmc_probe(struct platform_device *pdev) } @@ -120611,10 +119755,10 @@ index 2685fe4..e2c61d1 100644 static struct platform_driver bcm2835_i2s_driver = { .probe = bcm2835_i2s_probe, -From 0df6c079bc6aa8712cb19a67174b9e66de5ce247 Mon Sep 17 00:00:00 2001 +From c22aa1d9eb9f71602d937d5aa93731a2a745c820 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 12 Nov 2014 17:07:02 +0000 -Subject: [PATCH 67/87] Adding Device Tree support for some RPi audio cards +Subject: [PATCH 64/76] Adding Device Tree support for some RPi audio cards --- arch/arm/boot/dts/Makefile | 2 + @@ -120793,7 +119937,7 @@ index 5893122..d8c6d15 100644 + pinctrl-0 = <&i2s_pins>; +}; diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi -index edf3619..4b86aaa 100644 +index 2ca6d63..6b36128 100644 --- a/arch/arm/boot/dts/bcm2708.dtsi +++ b/arch/arm/boot/dts/bcm2708.dtsi @@ -7,11 +7,8 @@ @@ -120810,8 +119954,8 @@ index edf3619..4b86aaa 100644 }; soc { -@@ -34,6 +31,17 @@ - #gpio-cells = <2>; +@@ -39,6 +36,17 @@ + #interrupt-cells = <2>; }; + i2s: i2s@7e203000 { @@ -121239,10 +120383,10 @@ index 126f1e9..7c6598e 100644 }; -From 26236ffbb3a4169e29ef01d6ea4f3a1c2305895c Mon Sep 17 00:00:00 2001 +From e790396032213f89a24c7e5eded9a44d36732400 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 5 Dec 2014 17:26:26 +0000 -Subject: [PATCH 68/87] fdt: Add support for the CONFIG_CMDLINE_EXTEND option +Subject: [PATCH 65/76] fdt: Add support for the CONFIG_CMDLINE_EXTEND option --- drivers/of/fdt.c | 29 ++++++++++++++++++++++++----- @@ -121297,17 +120441,17 @@ index 2e2b6d0..badc6a3 100644 pr_debug("Command line is: %s\n", (char*)data); -From 810085f6b25afc495c7a6320da17a789226988bd Mon Sep 17 00:00:00 2001 +From 2d58034cf30c9bce60d5e8e0a8ddff60ab8bae65 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 25 Nov 2014 13:39:03 +0000 -Subject: [PATCH 69/87] config: Enable device tree +Subject: [PATCH 66/76] config: Enable device tree --- arch/arm/configs/bcmrpi_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 614158e..c4bfefc 100644 +index 997e1f3..2cd8227 100644 --- a/arch/arm/configs/bcmrpi_defconfig +++ b/arch/arm/configs/bcmrpi_defconfig @@ -39,6 +39,7 @@ CONFIG_PARTITION_ADVANCED=y @@ -121319,170 +120463,10 @@ index 614158e..c4bfefc 100644 CONFIG_AEABI=y CONFIG_CLEANCACHE=y -From 2a156f5a47a73a15aa3a1ca8dac7b0c73d6682cf Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 11 Dec 2014 15:17:28 +0000 -Subject: [PATCH 70/87] bcm2708: Remove the prohibition on mixing SPIDEV and DT - ---- - arch/arm/mach-bcm2708/Kconfig | 2 +- - arch/arm/mach-bcm2708/bcm2708.c | 5 +++-- - 2 files changed, 4 insertions(+), 3 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/Kconfig b/arch/arm/mach-bcm2708/Kconfig -index 1f29d7d..05945d6 100644 ---- a/arch/arm/mach-bcm2708/Kconfig -+++ b/arch/arm/mach-bcm2708/Kconfig -@@ -44,7 +44,7 @@ config BCM2708_NOL2CACHE - - config BCM2708_SPIDEV - bool "Bind spidev to SPI0 master" -- depends on MACH_BCM2708 && !USE_OF -+ depends on MACH_BCM2708 - depends on SPI - default y - help -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index c6d4ff6..199d8a5 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -908,8 +908,9 @@ void __init bcm2708_init(void) - system_serial_low = serial; - - #ifdef CONFIG_BCM2708_SPIDEV -- spi_register_board_info(bcm2708_spi_devices, -- ARRAY_SIZE(bcm2708_spi_devices)); -+ if (!use_dt) -+ spi_register_board_info(bcm2708_spi_devices, -+ ARRAY_SIZE(bcm2708_spi_devices)); - #endif - } - - -From c4e0fdf33959197cc5ca72a0d0ea25c0a1d40452 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Fri, 12 Dec 2014 11:24:48 +0000 -Subject: [PATCH 71/87] config: Add CONFIG_R8188EU and CONFIG_R8723AU - ---- - arch/arm/configs/bcmrpi_defconfig | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index c4bfefc..4f0d826 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -362,7 +362,6 @@ 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_MESH=y -@@ -964,6 +963,8 @@ CONFIG_UIO_PDRV_GENIRQ=m - CONFIG_STAGING=y - CONFIG_PRISM2_USB=m - CONFIG_R8712U=m -+CONFIG_R8188EU=m -+CONFIG_R8723AU=m - CONFIG_VT6656=m - CONFIG_SPEAKUP=m - CONFIG_SPEAKUP_SYNTH_SOFT=m - -From b10a3f036d8977052871adc6e93e1ce24eccafd3 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sat, 13 Dec 2014 15:22:27 +0000 -Subject: [PATCH 72/87] bcm2708_fb: Update from 3.12 - ---- - drivers/video/fbdev/bcm2708_fb.c | 9 ++------- - 1 file changed, 2 insertions(+), 7 deletions(-) - -diff --git a/drivers/video/fbdev/bcm2708_fb.c b/drivers/video/fbdev/bcm2708_fb.c -index 9d7ecda..a443666 100644 ---- a/drivers/video/fbdev/bcm2708_fb.c -+++ b/drivers/video/fbdev/bcm2708_fb.c -@@ -268,12 +268,6 @@ static int bcm2708_fb_check_var(struct fb_var_screeninfo *var, - else if (var->vmode & FB_VMODE_INTERLACED) - yres = (yres + 1) / 2; - -- if (var->xres * yres > 1920 * 1200) { -- pr_err("bcm2708_fb_check_var: ERROR: Pixel size >= 1920x1200; " -- "special treatment required! (TODO)\n"); -- return -EINVAL; -- } -- - return 0; - } - -@@ -481,7 +475,8 @@ static void bcm2708_fb_copyarea(struct fb_info *info, - int pixels = region->width * region->height; - - /* Fallback to cfb_copyarea() if we don't like something */ -- if (bytes_per_pixel > 4 || -+ if (in_atomic() || -+ bytes_per_pixel > 4 || - info->var.xres * info->var.yres > 1920 * 1200 || - region->width <= 0 || region->width > info->var.xres || - region->height <= 0 || region->height > info->var.yres || - -From cbb3bdd72df651bb856add4f3a6e5dbc5e4ba2b6 Mon Sep 17 00:00:00 2001 -From: gellert -Date: Mon, 15 Dec 2014 17:44:18 +0000 -Subject: [PATCH 73/87] DMA: fix cyclic LITE length overflow bug - ---- - drivers/dma/bcm2708-dmaengine.c | 17 ++++++++++++++--- - 1 file changed, 14 insertions(+), 3 deletions(-) - -diff --git a/drivers/dma/bcm2708-dmaengine.c b/drivers/dma/bcm2708-dmaengine.c -index 27ee1c1..e525190 100644 ---- a/drivers/dma/bcm2708-dmaengine.c -+++ b/drivers/dma/bcm2708-dmaengine.c -@@ -391,7 +391,7 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic( - struct bcm2835_desc *d; - dma_addr_t dev_addr; - unsigned int es, sync_type; -- unsigned int frame; -+ unsigned int frame, max_size; - - /* Grab configuration */ - if (!is_slave_direction(direction)) { -@@ -424,7 +424,14 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic( - return NULL; - - d->dir = direction; -- d->frames = buf_len / period_len; -+ -+ if (c->ch >= 8) /* we have a LITE channel */ -+ max_size = MAX_LITE_TRANSFER; -+ else -+ max_size = MAX_NORMAL_TRANSFER; -+ period_len = min(period_len, max_size); -+ -+ d->frames = (buf_len-1) / period_len + 1; - - /* Allocate memory for control blocks */ - d->control_block_size = d->frames * sizeof(struct bcm2835_dma_cb); -@@ -469,7 +476,11 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic( - BCM2835_DMA_PER_MAP(c->cfg.slave_id); - - /* Length of a frame */ -- control_block->length = period_len; -+ if (frame != d->frames-1) -+ control_block->length = period_len; -+ else -+ control_block->length = buf_len - (d->frames - 1) * period_len; -+ - d->size += control_block->length; - - /* - -From 660dc2931ea0ff0142d5f6c22a9ca538d8df100a Mon Sep 17 00:00:00 2001 +From 7c8d0fbefdc950506e9c314c9d6dc1d9e7462933 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 16 Dec 2014 10:23:48 +0000 -Subject: [PATCH 74/87] DT: Add overrides to enable i2c0, i2c1, spi and i2s +Subject: [PATCH 67/76] DT: Add overrides to enable i2c0, i2c1, spi and i2s --- arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 10 ++++++++++ @@ -121526,20 +120510,21 @@ index d8c6d15..167b22b 100644 + }; +}; -From b030b630a4fac3c2d6a6c3aa253d7c6680e67124 Mon Sep 17 00:00:00 2001 +From 016c324594d83f472051035de057f0bdb03a2f45 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 18 Dec 2014 16:48:32 +0000 -Subject: [PATCH 75/87] lirc-rpi: Add device tree support, and a suitable +Subject: [PATCH 68/76] lirc-rpi: Add device tree support, and a suitable overlay The overlay supports DT parameters that match the old module parameters, except that gpio_in_pull should be set using the strings "up", "down" or "off". + +lirc-rpi: Also support pinctrl-bcm2835 in non-DT mode --- - arch/arm/boot/dts/lirc-rpi-overlay.dts | 57 +++++++++++++ - arch/arm/mach-bcm2708/bcm2708_gpio.c | 12 +++ - drivers/staging/media/lirc/lirc_rpi.c | 143 ++++++++++++++++++++++++++------- - 3 files changed, 185 insertions(+), 27 deletions(-) + arch/arm/boot/dts/lirc-rpi-overlay.dts | 57 ++++++++++++ + drivers/staging/media/lirc/lirc_rpi.c | 154 +++++++++++++++++++++++++++------ + 2 files changed, 183 insertions(+), 28 deletions(-) create mode 100644 arch/arm/boot/dts/lirc-rpi-overlay.dts diff --git a/arch/arm/boot/dts/lirc-rpi-overlay.dts b/arch/arm/boot/dts/lirc-rpi-overlay.dts @@ -121605,38 +120590,8 @@ index 0000000..7d5d82b + debug = <&lirc_rpi>,"rpi,debug:0"; + }; +}; -diff --git a/arch/arm/mach-bcm2708/bcm2708_gpio.c b/arch/arm/mach-bcm2708/bcm2708_gpio.c -index 97c8245..a094fc2 100644 ---- a/arch/arm/mach-bcm2708/bcm2708_gpio.c -+++ b/arch/arm/mach-bcm2708/bcm2708_gpio.c -@@ -90,6 +90,16 @@ static int bcm2708_set_function(struct gpio_chip *gc, unsigned offset, - return 0; - } - -+static int bcm2708_gpio_request(struct gpio_chip *chip, unsigned offset) -+{ -+ return pinctrl_request_gpio(chip->base + offset); -+} -+ -+static void bcm2708_gpio_free(struct gpio_chip *chip, unsigned offset) -+{ -+ pinctrl_free_gpio(chip->base + offset); -+} -+ - static int bcm2708_gpio_dir_in(struct gpio_chip *gc, unsigned offset) - { - return bcm2708_set_function(gc, offset, GPIO_FSEL_INPUT); -@@ -345,6 +355,8 @@ static int bcm2708_gpio_probe(struct platform_device *dev) - ucb->gc.ngpio = BCM2708_NR_GPIOS; - ucb->gc.owner = THIS_MODULE; - -+ ucb->gc.request = bcm2708_gpio_request; -+ ucb->gc.free = bcm2708_gpio_free; - ucb->gc.direction_input = bcm2708_gpio_dir_in; - ucb->gc.direction_output = bcm2708_gpio_dir_out; - ucb->gc.get = bcm2708_gpio_get; diff --git a/drivers/staging/media/lirc/lirc_rpi.c b/drivers/staging/media/lirc/lirc_rpi.c -index 887c36b..b7d82ad 100644 +index c688364..cd66ca2 100644 --- a/drivers/staging/media/lirc/lirc_rpi.c +++ b/drivers/staging/media/lirc/lirc_rpi.c @@ -40,6 +40,7 @@ @@ -121647,7 +120602,7 @@ index 887c36b..b7d82ad 100644 #include -@@ -299,32 +300,108 @@ static int is_right_chip(struct gpio_chip *chip, void *data) +@@ -295,32 +296,117 @@ static int is_right_chip(struct gpio_chip *chip, void *data) return 0; } @@ -121692,20 +120647,25 @@ index 887c36b..b7d82ad 100644 + static int init_port(void) { - int i, nlow, nhigh, ret, irq; + int i, nlow, nhigh, ret; + struct device_node *node; ++ ++ node = lirc_rpi_dev->dev.of_node; gpiochip = gpiochip_find("bcm2708_gpio", is_right_chip); - if (!gpiochip) +- if (!gpiochip) ++ /* ++ * Because of the lack of a setpull function, only support ++ * pinctrl-bcm2835 if using device tree. ++ */ ++ if (!gpiochip && node) ++ gpiochip = gpiochip_find("pinctrl-bcm2835", is_right_chip); ++ ++ if (!gpiochip) { ++ pr_err(LIRC_DRIVER_NAME ": gpio chip not found!\n"); return -ENODEV; - -- if (gpio_request(gpio_out_pin, LIRC_DRIVER_NAME " ir/out")) { -- printk(KERN_ALERT LIRC_DRIVER_NAME -- ": cant claim gpio pin %d\n", gpio_out_pin); -- ret = -ENODEV; -- goto exit_init_port; -+ node = lirc_rpi_dev->dev.of_node; ++ } + + if (node) { + struct device_node *pins_node; @@ -121727,7 +120687,12 @@ index 887c36b..b7d82ad 100644 + read_bool_property(node, "rpi,invert", &invert); + + read_bool_property(node, "rpi,debug", &debug); -+ + +- if (gpio_request(gpio_out_pin, LIRC_DRIVER_NAME " ir/out")) { +- printk(KERN_ALERT LIRC_DRIVER_NAME +- ": cant claim gpio pin %d\n", gpio_out_pin); +- ret = -ENODEV; +- goto exit_init_port; } + else + { @@ -121768,8 +120733,8 @@ index 887c36b..b7d82ad 100644 - gpiochip->direction_output(gpiochip, gpio_out_pin, 1); gpiochip->set(gpiochip, gpio_out_pin, invert); - irq = gpiochip->to_irq(gpiochip, gpio_in_pin); -@@ -546,15 +623,23 @@ static struct lirc_driver driver = { + irq_num = gpiochip->to_irq(gpiochip, gpio_in_pin); +@@ -514,15 +600,23 @@ static struct lirc_driver driver = { .owner = THIS_MODULE, }; @@ -121793,7 +120758,7 @@ index 887c36b..b7d82ad 100644 int result; /* Init read buffer. */ -@@ -569,15 +654,26 @@ static int __init lirc_rpi_init(void) +@@ -537,15 +631,26 @@ static int __init lirc_rpi_init(void) goto exit_buffer_free; } @@ -121827,7 +120792,7 @@ index 887c36b..b7d82ad 100644 return 0; -@@ -608,13 +704,6 @@ static int __init lirc_rpi_init_module(void) +@@ -577,13 +682,6 @@ static int __init lirc_rpi_init_module(void) if (result) return result; @@ -121842,1077 +120807,10 @@ index 887c36b..b7d82ad 100644 if (result < 0) goto exit_rpi; -From 63b3cbcf5b9d2f7363900137016a485bc61b1764 Mon Sep 17 00:00:00 2001 -From: jeanleflambeur -Date: Sat, 20 Dec 2014 12:20:39 +0100 -Subject: [PATCH 76/87] Update i2c-bcm2708.c - ---- - drivers/i2c/busses/i2c-bcm2708.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/drivers/i2c/busses/i2c-bcm2708.c b/drivers/i2c/busses/i2c-bcm2708.c -index 728cb69..526129b 100644 ---- a/drivers/i2c/busses/i2c-bcm2708.c -+++ b/drivers/i2c/busses/i2c-bcm2708.c -@@ -266,10 +266,11 @@ static int bcm2708_i2c_master_xfer(struct i2c_adapter *adap, - bi->nmsgs = num; - bi->error = false; - -- spin_unlock_irqrestore(&bi->lock, flags); -- - bcm2708_bsc_setup(bi); - -+ /* unlockig _after_ the setup to avoid races with the interrupt routine */ -+ spin_unlock_irqrestore(&bi->lock, flags); -+ - ret = wait_for_completion_timeout(&bi->done, - msecs_to_jiffies(I2C_TIMEOUT_MS)); - if (ret == 0) { - -From 08e393af2b1e6cb234fa95455a6cd883e64b7e3d Mon Sep 17 00:00:00 2001 -From: notro -Date: Sat, 27 Dec 2014 13:44:05 +0100 -Subject: [PATCH 77/87] BCM2708: armctrl: add space to allocate irq descriptors - -Drivers that act as interrupt controllers need to allocate irq descriptors. -This adds room for that. - -Reported-by: chaosjug -Signed-off-by: Noralf Tronnes ---- - arch/arm/mach-bcm2708/armctrl.c | 5 +++-- - arch/arm/mach-bcm2708/include/mach/irqs.h | 6 ++++-- - 2 files changed, 7 insertions(+), 4 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/armctrl.c b/arch/arm/mach-bcm2708/armctrl.c -index 42f5e1c..9734b0d 100644 ---- a/arch/arm/mach-bcm2708/armctrl.c -+++ b/arch/arm/mach-bcm2708/armctrl.c -@@ -167,7 +167,8 @@ void __init armctrl_dt_init(void) - if (!np) - return; - -- domain = irq_domain_add_legacy(np, NR_IRQS, IRQ_ARMCTRL_START, 0, -+ domain = irq_domain_add_legacy(np, BCM2708_ALLOC_IRQS, -+ IRQ_ARMCTRL_START, 0, - &armctrl_ops, NULL); - WARN_ON(!domain); - } -@@ -298,7 +299,7 @@ int __init armctrl_init(void __iomem * base, unsigned int irq_start, - { - unsigned int irq; - -- for (irq = 0; irq < NR_IRQS; irq++) { -+ for (irq = 0; irq < BCM2708_ALLOC_IRQS; irq++) { - unsigned int data = irq; - if (irq >= INTERRUPT_JPEG && irq <= INTERRUPT_ARASANSDIO) - data = remap_irqs[irq - INTERRUPT_JPEG]; -diff --git a/arch/arm/mach-bcm2708/include/mach/irqs.h b/arch/arm/mach-bcm2708/include/mach/irqs.h -index 4299054..45152ed 100644 ---- a/arch/arm/mach-bcm2708/include/mach/irqs.h -+++ b/arch/arm/mach-bcm2708/include/mach/irqs.h -@@ -191,7 +191,9 @@ - #define FIQ_IRQS (64 + 21) - #define GPIO_IRQ_START (HARD_IRQS + FIQ_IRQS) - #define GPIO_IRQS (32*5) --#define SPARE_IRQS (64) --#define NR_IRQS (HARD_IRQS+FIQ_IRQS+GPIO_IRQS+SPARE_IRQS) -+#define SPARE_ALLOC_IRQS 64 -+#define BCM2708_ALLOC_IRQS (HARD_IRQS+FIQ_IRQS+GPIO_IRQS+SPARE_ALLOC_IRQS) -+#define FREE_IRQS 128 -+#define NR_IRQS (BCM2708_ALLOC_IRQS+FREE_IRQS) - - #endif /* _BCM2708_IRQS_H_ */ - -From a4954d353cc993811994f527ee11cffea3c075bd Mon Sep 17 00:00:00 2001 -From: notro -Date: Sat, 27 Dec 2014 13:46:00 +0100 -Subject: [PATCH 78/87] BCM2708: use pinctrl-bcm2835 - -Use pinctrl-bcm2835 instead of the pinctrl-bcm2708 and bcm2708_gpio -combination. - -Signed-off-by: Noralf Tronnes ---- - arch/arm/boot/dts/bcm2708.dtsi | 7 ++++++- - arch/arm/mach-bcm2708/Kconfig | 4 ++-- - arch/arm/mach-bcm2708/bcm2708.c | 2 +- - drivers/pinctrl/pinctrl-bcm2835.c | 2 +- - 4 files changed, 10 insertions(+), 5 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi -index 4b86aaa..6b36128 100644 ---- a/arch/arm/boot/dts/bcm2708.dtsi -+++ b/arch/arm/boot/dts/bcm2708.dtsi -@@ -25,10 +25,15 @@ - }; - - gpio: gpio { -- compatible = "brcm,bcm2708-pinctrl"; -+ compatible = "brcm,bcm2835-gpio"; - reg = <0x7e200000 0xb4>; -+ interrupts = <2 17>, <2 18>; -+ - gpio-controller; - #gpio-cells = <2>; -+ -+ interrupt-controller; -+ #interrupt-cells = <2>; - }; - - i2s: i2s@7e203000 { -diff --git a/arch/arm/mach-bcm2708/Kconfig b/arch/arm/mach-bcm2708/Kconfig -index 05945d6..4cfae55 100644 ---- a/arch/arm/mach-bcm2708/Kconfig -+++ b/arch/arm/mach-bcm2708/Kconfig -@@ -14,9 +14,9 @@ config BCM2708_DT - depends on MACH_BCM2708 - default n - select USE_OF -+ select ARCH_REQUIRE_GPIOLIB - select PINCTRL -- select PINCTRL_BCM2708 -- select BCM2708_GPIO -+ select PINCTRL_BCM2835 - help - Enable Device Tree support for BCM2708 - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 199d8a5..2c6a29d 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -838,7 +838,7 @@ void __init bcm2708_init(void) - bcm_register_device(&bcm2708_dmaman_device); - bcm_register_device(&bcm2708_vcio_device); - #ifdef CONFIG_BCM2708_GPIO -- bcm_register_device(&bcm2708_gpio_device); -+ bcm_register_device_dt(&bcm2708_gpio_device); - #endif - #if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) - w1_gpio_pdata.pin = w1_gpio_pin; -diff --git a/drivers/pinctrl/pinctrl-bcm2835.c b/drivers/pinctrl/pinctrl-bcm2835.c -index eabba02..962e180 100644 ---- a/drivers/pinctrl/pinctrl-bcm2835.c -+++ b/drivers/pinctrl/pinctrl-bcm2835.c -@@ -382,7 +382,7 @@ static struct gpio_chip bcm2835_gpio_chip = { - .get = bcm2835_gpio_get, - .set = bcm2835_gpio_set, - .to_irq = bcm2835_gpio_to_irq, -- .base = -1, -+ .base = 0, - .ngpio = BCM2835_NUM_GPIOS, - .can_sleep = false, - }; - -From b2f0a5c45d74eb6c5a49e5e8065f6886375c42c5 Mon Sep 17 00:00:00 2001 -From: notro -Date: Sat, 27 Dec 2014 13:47:18 +0100 -Subject: [PATCH 79/87] pinctrl: remove bcm2708 driver - -There is no need for pinctrl-bcm2708 anymore with pinctrl-bcm2835 -working on ARCH_BCM2708. - -Signed-off-by: Noralf Tronnes ---- - drivers/pinctrl/Kconfig | 5 - - drivers/pinctrl/Makefile | 1 - - drivers/pinctrl/pinctrl-bcm2708.c | 762 -------------------------------------- - 3 files changed, 768 deletions(-) - delete mode 100644 drivers/pinctrl/pinctrl-bcm2708.c - -diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig -index dd631cc..c6a66de 100644 ---- a/drivers/pinctrl/Kconfig -+++ b/drivers/pinctrl/Kconfig -@@ -79,11 +79,6 @@ config PINCTRL_BAYTRAIL - - Requires ACPI device enumeration code to set up a platform device. - --config PINCTRL_BCM2708 -- bool -- select PINMUX -- select PINCONF -- - config PINCTRL_BCM2835 - bool - select PINMUX -diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile -index 12ae1bd..51f52d3 100644 ---- a/drivers/pinctrl/Makefile -+++ b/drivers/pinctrl/Makefile -@@ -14,7 +14,6 @@ obj-$(CONFIG_PINCTRL_AS3722) += pinctrl-as3722.o - obj-$(CONFIG_PINCTRL_BF54x) += pinctrl-adi2-bf54x.o - obj-$(CONFIG_PINCTRL_BF60x) += pinctrl-adi2-bf60x.o - obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o --obj-$(CONFIG_PINCTRL_BCM2708) += pinctrl-bcm2708.o - obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o - obj-$(CONFIG_PINCTRL_BAYTRAIL) += pinctrl-baytrail.o - obj-$(CONFIG_PINCTRL_BCM281XX) += pinctrl-bcm281xx.o -diff --git a/drivers/pinctrl/pinctrl-bcm2708.c b/drivers/pinctrl/pinctrl-bcm2708.c -deleted file mode 100644 -index f395e95..0000000 ---- a/drivers/pinctrl/pinctrl-bcm2708.c -+++ /dev/null -@@ -1,762 +0,0 @@ --/* -- * Driver for Broadcom BCM2708 GPIO unit (pinctrl only) -- * -- * Copyright (C) 2012 Chris Boot, Simon Arlott, Stephen Warren -- * Copyright (C) 2014 Noralf Tronnes -- * -- * This driver is a verbatim copy of the pinctrl-bcm2835 driver, except for: -- * - changed 2835 to 2708 -- * - gpio_chip and IRQ part are removed -- * - Probing function is changed. -- * -- * Because armctrl sets up the gpio irqs, we use the bcm2708_gpio driver. -- * This hack is used to be able to support both DT and non-DT builds. -- * It's not possible to set trigger type and level flags for IRQs in the DT. -- * -- * This driver is inspired by: -- * pinctrl-nomadik.c, please see original file for copyright information -- * pinctrl-tegra.c, please see original file for copyright information -- * -- * 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. -- */ -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#define MODULE_NAME "pinctrl-bcm2708" --#define BCM2708_NUM_GPIOS 54 --#define BCM2708_NUM_BANKS 2 -- --#define BCM2708_PIN_BITMAP_SZ \ -- DIV_ROUND_UP(BCM2708_NUM_GPIOS, sizeof(unsigned long) * 8) -- --/* GPIO register offsets */ --#define GPFSEL0 0x0 /* Function Select */ --#define GPSET0 0x1c /* Pin Output Set */ --#define GPCLR0 0x28 /* Pin Output Clear */ --#define GPLEV0 0x34 /* Pin Level */ --#define GPEDS0 0x40 /* Pin Event Detect Status */ --#define GPREN0 0x4c /* Pin Rising Edge Detect Enable */ --#define GPFEN0 0x58 /* Pin Falling Edge Detect Enable */ --#define GPHEN0 0x64 /* Pin High Detect Enable */ --#define GPLEN0 0x70 /* Pin Low Detect Enable */ --#define GPAREN0 0x7c /* Pin Async Rising Edge Detect */ --#define GPAFEN0 0x88 /* Pin Async Falling Edge Detect */ --#define GPPUD 0x94 /* Pin Pull-up/down Enable */ --#define GPPUDCLK0 0x98 /* Pin Pull-up/down Enable Clock */ -- --#define FSEL_REG(p) (GPFSEL0 + (((p) / 10) * 4)) --#define FSEL_SHIFT(p) (((p) % 10) * 3) --#define GPIO_REG_OFFSET(p) ((p) / 32) --#define GPIO_REG_SHIFT(p) ((p) % 32) -- --enum bcm2708_pinconf_param { -- /* argument: bcm2708_pinconf_pull */ -- BCM2708_PINCONF_PARAM_PULL, --}; -- --enum bcm2708_pinconf_pull { -- BCM2708_PINCONFIG_PULL_NONE, -- BCM2708_PINCONFIG_PULL_DOWN, -- BCM2708_PINCONFIG_PULL_UP, --}; -- --#define BCM2708_PINCONF_PACK(_param_, _arg_) ((_param_) << 16 | (_arg_)) --#define BCM2708_PINCONF_UNPACK_PARAM(_conf_) ((_conf_) >> 16) --#define BCM2708_PINCONF_UNPACK_ARG(_conf_) ((_conf_) & 0xffff) -- --struct bcm2708_gpio_irqdata { -- struct bcm2708_pinctrl *pc; -- int bank; --}; -- --struct bcm2708_pinctrl { -- struct device *dev; -- void __iomem *base; -- int irq[BCM2708_NUM_BANKS]; -- -- /* note: locking assumes each bank will have its own unsigned long */ -- unsigned long enabled_irq_map[BCM2708_NUM_BANKS]; -- unsigned int irq_type[BCM2708_NUM_GPIOS]; -- -- struct pinctrl_dev *pctl_dev; -- struct irq_domain *irq_domain; -- struct gpio_chip gpio_chip; -- struct pinctrl_gpio_range gpio_range; -- -- struct bcm2708_gpio_irqdata irq_data[BCM2708_NUM_BANKS]; -- spinlock_t irq_lock[BCM2708_NUM_BANKS]; --}; -- --/* pins are just named GPIO0..GPIO53 */ --#define BCM2708_GPIO_PIN(a) PINCTRL_PIN(a, "gpio" #a) --static struct pinctrl_pin_desc bcm2708_gpio_pins[] = { -- BCM2708_GPIO_PIN(0), -- BCM2708_GPIO_PIN(1), -- BCM2708_GPIO_PIN(2), -- BCM2708_GPIO_PIN(3), -- BCM2708_GPIO_PIN(4), -- BCM2708_GPIO_PIN(5), -- BCM2708_GPIO_PIN(6), -- BCM2708_GPIO_PIN(7), -- BCM2708_GPIO_PIN(8), -- BCM2708_GPIO_PIN(9), -- BCM2708_GPIO_PIN(10), -- BCM2708_GPIO_PIN(11), -- BCM2708_GPIO_PIN(12), -- BCM2708_GPIO_PIN(13), -- BCM2708_GPIO_PIN(14), -- BCM2708_GPIO_PIN(15), -- BCM2708_GPIO_PIN(16), -- BCM2708_GPIO_PIN(17), -- BCM2708_GPIO_PIN(18), -- BCM2708_GPIO_PIN(19), -- BCM2708_GPIO_PIN(20), -- BCM2708_GPIO_PIN(21), -- BCM2708_GPIO_PIN(22), -- BCM2708_GPIO_PIN(23), -- BCM2708_GPIO_PIN(24), -- BCM2708_GPIO_PIN(25), -- BCM2708_GPIO_PIN(26), -- BCM2708_GPIO_PIN(27), -- BCM2708_GPIO_PIN(28), -- BCM2708_GPIO_PIN(29), -- BCM2708_GPIO_PIN(30), -- BCM2708_GPIO_PIN(31), -- BCM2708_GPIO_PIN(32), -- BCM2708_GPIO_PIN(33), -- BCM2708_GPIO_PIN(34), -- BCM2708_GPIO_PIN(35), -- BCM2708_GPIO_PIN(36), -- BCM2708_GPIO_PIN(37), -- BCM2708_GPIO_PIN(38), -- BCM2708_GPIO_PIN(39), -- BCM2708_GPIO_PIN(40), -- BCM2708_GPIO_PIN(41), -- BCM2708_GPIO_PIN(42), -- BCM2708_GPIO_PIN(43), -- BCM2708_GPIO_PIN(44), -- BCM2708_GPIO_PIN(45), -- BCM2708_GPIO_PIN(46), -- BCM2708_GPIO_PIN(47), -- BCM2708_GPIO_PIN(48), -- BCM2708_GPIO_PIN(49), -- BCM2708_GPIO_PIN(50), -- BCM2708_GPIO_PIN(51), -- BCM2708_GPIO_PIN(52), -- BCM2708_GPIO_PIN(53), --}; -- --/* one pin per group */ --static const char * const bcm2708_gpio_groups[] = { -- "gpio0", -- "gpio1", -- "gpio2", -- "gpio3", -- "gpio4", -- "gpio5", -- "gpio6", -- "gpio7", -- "gpio8", -- "gpio9", -- "gpio10", -- "gpio11", -- "gpio12", -- "gpio13", -- "gpio14", -- "gpio15", -- "gpio16", -- "gpio17", -- "gpio18", -- "gpio19", -- "gpio20", -- "gpio21", -- "gpio22", -- "gpio23", -- "gpio24", -- "gpio25", -- "gpio26", -- "gpio27", -- "gpio28", -- "gpio29", -- "gpio30", -- "gpio31", -- "gpio32", -- "gpio33", -- "gpio34", -- "gpio35", -- "gpio36", -- "gpio37", -- "gpio38", -- "gpio39", -- "gpio40", -- "gpio41", -- "gpio42", -- "gpio43", -- "gpio44", -- "gpio45", -- "gpio46", -- "gpio47", -- "gpio48", -- "gpio49", -- "gpio50", -- "gpio51", -- "gpio52", -- "gpio53", --}; -- --enum bcm2708_fsel { -- BCM2708_FSEL_GPIO_IN = 0, -- BCM2708_FSEL_GPIO_OUT = 1, -- BCM2708_FSEL_ALT0 = 4, -- BCM2708_FSEL_ALT1 = 5, -- BCM2708_FSEL_ALT2 = 6, -- BCM2708_FSEL_ALT3 = 7, -- BCM2708_FSEL_ALT4 = 3, -- BCM2708_FSEL_ALT5 = 2, -- BCM2708_FSEL_COUNT = 8, -- BCM2708_FSEL_MASK = 0x7, --}; -- --static const char * const bcm2708_functions[BCM2708_FSEL_COUNT] = { -- [BCM2708_FSEL_GPIO_IN] = "gpio_in", -- [BCM2708_FSEL_GPIO_OUT] = "gpio_out", -- [BCM2708_FSEL_ALT0] = "alt0", -- [BCM2708_FSEL_ALT1] = "alt1", -- [BCM2708_FSEL_ALT2] = "alt2", -- [BCM2708_FSEL_ALT3] = "alt3", -- [BCM2708_FSEL_ALT4] = "alt4", -- [BCM2708_FSEL_ALT5] = "alt5", --}; -- --static const char * const irq_type_names[] = { -- [IRQ_TYPE_NONE] = "none", -- [IRQ_TYPE_EDGE_RISING] = "edge-rising", -- [IRQ_TYPE_EDGE_FALLING] = "edge-falling", -- [IRQ_TYPE_EDGE_BOTH] = "edge-both", -- [IRQ_TYPE_LEVEL_HIGH] = "level-high", -- [IRQ_TYPE_LEVEL_LOW] = "level-low", --}; -- --static inline u32 bcm2708_gpio_rd(struct bcm2708_pinctrl *pc, unsigned reg) --{ -- return readl(pc->base + reg); --} -- --static inline void bcm2708_gpio_wr(struct bcm2708_pinctrl *pc, unsigned reg, -- u32 val) --{ -- writel(val, pc->base + reg); --} -- --static inline int bcm2708_gpio_get_bit(struct bcm2708_pinctrl *pc, unsigned reg, -- unsigned bit) --{ -- reg += GPIO_REG_OFFSET(bit) * 4; -- return (bcm2708_gpio_rd(pc, reg) >> GPIO_REG_SHIFT(bit)) & 1; --} -- --/* note NOT a read/modify/write cycle */ --static inline void bcm2708_gpio_set_bit(struct bcm2708_pinctrl *pc, -- unsigned reg, unsigned bit) --{ -- reg += GPIO_REG_OFFSET(bit) * 4; -- bcm2708_gpio_wr(pc, reg, BIT(GPIO_REG_SHIFT(bit))); --} -- --static inline enum bcm2708_fsel bcm2708_pinctrl_fsel_get( -- struct bcm2708_pinctrl *pc, unsigned pin) --{ -- u32 val = bcm2708_gpio_rd(pc, FSEL_REG(pin)); -- enum bcm2708_fsel status = (val >> FSEL_SHIFT(pin)) & BCM2708_FSEL_MASK; -- -- dev_dbg(pc->dev, "get %08x (%u => %s)\n", val, pin, -- bcm2708_functions[status]); -- -- return status; --} -- --static inline void bcm2708_pinctrl_fsel_set( -- struct bcm2708_pinctrl *pc, unsigned pin, -- enum bcm2708_fsel fsel) --{ -- u32 val = bcm2708_gpio_rd(pc, FSEL_REG(pin)); -- enum bcm2708_fsel cur = (val >> FSEL_SHIFT(pin)) & BCM2708_FSEL_MASK; -- -- dev_dbg(pc->dev, "read %08x (%u => %s)\n", val, pin, -- bcm2708_functions[cur]); -- -- if (cur == fsel) -- return; -- -- if (cur != BCM2708_FSEL_GPIO_IN && fsel != BCM2708_FSEL_GPIO_IN) { -- /* always transition through GPIO_IN */ -- val &= ~(BCM2708_FSEL_MASK << FSEL_SHIFT(pin)); -- val |= BCM2708_FSEL_GPIO_IN << FSEL_SHIFT(pin); -- -- dev_dbg(pc->dev, "trans %08x (%u <= %s)\n", val, pin, -- bcm2708_functions[BCM2708_FSEL_GPIO_IN]); -- bcm2708_gpio_wr(pc, FSEL_REG(pin), val); -- } -- -- val &= ~(BCM2708_FSEL_MASK << FSEL_SHIFT(pin)); -- val |= fsel << FSEL_SHIFT(pin); -- -- dev_dbg(pc->dev, "write %08x (%u <= %s)\n", val, pin, -- bcm2708_functions[fsel]); -- bcm2708_gpio_wr(pc, FSEL_REG(pin), val); --} -- --static int bcm2708_pctl_get_groups_count(struct pinctrl_dev *pctldev) --{ -- return ARRAY_SIZE(bcm2708_gpio_groups); --} -- --static const char *bcm2708_pctl_get_group_name(struct pinctrl_dev *pctldev, -- unsigned selector) --{ -- return bcm2708_gpio_groups[selector]; --} -- --static int bcm2708_pctl_get_group_pins(struct pinctrl_dev *pctldev, -- unsigned selector, -- const unsigned **pins, -- unsigned *num_pins) --{ -- *pins = &bcm2708_gpio_pins[selector].number; -- *num_pins = 1; -- -- return 0; --} -- --static void bcm2708_pctl_pin_dbg_show(struct pinctrl_dev *pctldev, -- struct seq_file *s, -- unsigned offset) --{ -- struct bcm2708_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); -- enum bcm2708_fsel fsel = bcm2708_pinctrl_fsel_get(pc, offset); -- const char *fname = bcm2708_functions[fsel]; -- int value = bcm2708_gpio_get_bit(pc, GPLEV0, offset); -- int irq = irq_find_mapping(pc->irq_domain, offset); -- -- seq_printf(s, "function %s in %s; irq %d (%s)", -- fname, value ? "hi" : "lo", -- irq, irq_type_names[pc->irq_type[offset]]); --} -- --static void bcm2708_pctl_dt_free_map(struct pinctrl_dev *pctldev, -- struct pinctrl_map *maps, unsigned num_maps) --{ -- int i; -- -- for (i = 0; i < num_maps; i++) -- if (maps[i].type == PIN_MAP_TYPE_CONFIGS_PIN) -- kfree(maps[i].data.configs.configs); -- -- kfree(maps); --} -- --static int bcm2708_pctl_dt_node_to_map_func(struct bcm2708_pinctrl *pc, -- struct device_node *np, u32 pin, u32 fnum, -- struct pinctrl_map **maps) --{ -- struct pinctrl_map *map = *maps; -- -- if (fnum >= ARRAY_SIZE(bcm2708_functions)) { -- dev_err(pc->dev, "%s: invalid brcm,function %d\n", -- of_node_full_name(np), fnum); -- return -EINVAL; -- } -- -- map->type = PIN_MAP_TYPE_MUX_GROUP; -- map->data.mux.group = bcm2708_gpio_groups[pin]; -- map->data.mux.function = bcm2708_functions[fnum]; -- (*maps)++; -- -- return 0; --} -- --static int bcm2708_pctl_dt_node_to_map_pull(struct bcm2708_pinctrl *pc, -- struct device_node *np, u32 pin, u32 pull, -- struct pinctrl_map **maps) --{ -- struct pinctrl_map *map = *maps; -- unsigned long *configs; -- -- if (pull > 2) { -- dev_err(pc->dev, "%s: invalid brcm,pull %d\n", -- of_node_full_name(np), pull); -- return -EINVAL; -- } -- -- configs = kzalloc(sizeof(*configs), GFP_KERNEL); -- if (!configs) -- return -ENOMEM; -- configs[0] = BCM2708_PINCONF_PACK(BCM2708_PINCONF_PARAM_PULL, pull); -- -- map->type = PIN_MAP_TYPE_CONFIGS_PIN; -- map->data.configs.group_or_pin = bcm2708_gpio_pins[pin].name; -- map->data.configs.configs = configs; -- map->data.configs.num_configs = 1; -- (*maps)++; -- -- return 0; --} -- --static int bcm2708_pctl_dt_node_to_map(struct pinctrl_dev *pctldev, -- struct device_node *np, -- struct pinctrl_map **map, unsigned *num_maps) --{ -- struct bcm2708_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); -- struct property *pins, *funcs, *pulls; -- int num_pins, num_funcs, num_pulls, maps_per_pin; -- struct pinctrl_map *maps, *cur_map; -- int i, err; -- u32 pin, func, pull; -- -- pins = of_find_property(np, "brcm,pins", NULL); -- if (!pins) { -- dev_err(pc->dev, "%s: missing brcm,pins property\n", -- of_node_full_name(np)); -- return -EINVAL; -- } -- -- funcs = of_find_property(np, "brcm,function", NULL); -- pulls = of_find_property(np, "brcm,pull", NULL); -- -- if (!funcs && !pulls) { -- dev_err(pc->dev, -- "%s: neither brcm,function nor brcm,pull specified\n", -- of_node_full_name(np)); -- return -EINVAL; -- } -- -- num_pins = pins->length / 4; -- num_funcs = funcs ? (funcs->length / 4) : 0; -- num_pulls = pulls ? (pulls->length / 4) : 0; -- -- if (num_funcs > 1 && num_funcs != num_pins) { -- dev_err(pc->dev, -- "%s: brcm,function must have 1 or %d entries\n", -- of_node_full_name(np), num_pins); -- return -EINVAL; -- } -- -- if (num_pulls > 1 && num_pulls != num_pins) { -- dev_err(pc->dev, -- "%s: brcm,pull must have 1 or %d entries\n", -- of_node_full_name(np), num_pins); -- return -EINVAL; -- } -- -- maps_per_pin = 0; -- if (num_funcs) -- maps_per_pin++; -- if (num_pulls) -- maps_per_pin++; -- cur_map = maps = kzalloc(num_pins * maps_per_pin * sizeof(*maps), -- GFP_KERNEL); -- if (!maps) -- return -ENOMEM; -- -- for (i = 0; i < num_pins; i++) { -- err = of_property_read_u32_index(np, "brcm,pins", i, &pin); -- if (err) -- goto out; -- if (pin >= ARRAY_SIZE(bcm2708_gpio_pins)) { -- dev_err(pc->dev, "%s: invalid brcm,pins value %d\n", -- of_node_full_name(np), pin); -- err = -EINVAL; -- goto out; -- } -- -- if (num_funcs) { -- err = of_property_read_u32_index(np, "brcm,function", -- (num_funcs > 1) ? i : 0, &func); -- if (err) -- goto out; -- err = bcm2708_pctl_dt_node_to_map_func(pc, np, pin, -- func, &cur_map); -- if (err) -- goto out; -- } -- if (num_pulls) { -- err = of_property_read_u32_index(np, "brcm,pull", -- (num_funcs > 1) ? i : 0, &pull); -- if (err) -- goto out; -- err = bcm2708_pctl_dt_node_to_map_pull(pc, np, pin, -- pull, &cur_map); -- if (err) -- goto out; -- } -- } -- -- *map = maps; -- *num_maps = num_pins * maps_per_pin; -- -- return 0; -- --out: -- kfree(maps); -- return err; --} -- --static const struct pinctrl_ops bcm2708_pctl_ops = { -- .get_groups_count = bcm2708_pctl_get_groups_count, -- .get_group_name = bcm2708_pctl_get_group_name, -- .get_group_pins = bcm2708_pctl_get_group_pins, -- .pin_dbg_show = bcm2708_pctl_pin_dbg_show, -- .dt_node_to_map = bcm2708_pctl_dt_node_to_map, -- .dt_free_map = bcm2708_pctl_dt_free_map, --}; -- --static int bcm2708_pmx_get_functions_count(struct pinctrl_dev *pctldev) --{ -- return BCM2708_FSEL_COUNT; --} -- --static const char *bcm2708_pmx_get_function_name(struct pinctrl_dev *pctldev, -- unsigned selector) --{ -- return bcm2708_functions[selector]; --} -- --static int bcm2708_pmx_get_function_groups(struct pinctrl_dev *pctldev, -- unsigned selector, -- const char * const **groups, -- unsigned * const num_groups) --{ -- /* every pin can do every function */ -- *groups = bcm2708_gpio_groups; -- *num_groups = ARRAY_SIZE(bcm2708_gpio_groups); -- -- return 0; --} -- --static int bcm2708_pmx_set(struct pinctrl_dev *pctldev, -- unsigned func_selector, -- unsigned group_selector) --{ -- struct bcm2708_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); -- -- bcm2708_pinctrl_fsel_set(pc, group_selector, func_selector); -- -- return 0; --} -- --static void bcm2708_pmx_gpio_disable_free(struct pinctrl_dev *pctldev, -- struct pinctrl_gpio_range *range, -- unsigned offset) --{ -- struct bcm2708_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); -- -- /* disable by setting to GPIO_IN */ -- bcm2708_pinctrl_fsel_set(pc, offset, BCM2708_FSEL_GPIO_IN); --} -- --static int bcm2708_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, -- struct pinctrl_gpio_range *range, -- unsigned offset, -- bool input) --{ -- struct bcm2708_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); -- enum bcm2708_fsel fsel = input ? -- BCM2708_FSEL_GPIO_IN : BCM2708_FSEL_GPIO_OUT; -- -- bcm2708_pinctrl_fsel_set(pc, offset, fsel); -- -- return 0; --} -- --static const struct pinmux_ops bcm2708_pmx_ops = { -- .get_functions_count = bcm2708_pmx_get_functions_count, -- .get_function_name = bcm2708_pmx_get_function_name, -- .get_function_groups = bcm2708_pmx_get_function_groups, -- .set_mux = bcm2708_pmx_set, -- .gpio_disable_free = bcm2708_pmx_gpio_disable_free, -- .gpio_set_direction = bcm2708_pmx_gpio_set_direction, --}; -- --static int bcm2708_pinconf_get(struct pinctrl_dev *pctldev, -- unsigned pin, unsigned long *config) --{ -- /* No way to read back config in HW */ -- return -ENOTSUPP; --} -- --static int bcm2708_pinconf_set(struct pinctrl_dev *pctldev, -- unsigned pin, unsigned long *configs, -- unsigned num_configs) --{ -- struct bcm2708_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); -- enum bcm2708_pinconf_param param; -- u16 arg; -- u32 off, bit; -- int i; -- -- for (i = 0; i < num_configs; i++) { -- param = BCM2708_PINCONF_UNPACK_PARAM(configs[i]); -- arg = BCM2708_PINCONF_UNPACK_ARG(configs[i]); -- -- dev_dbg(pc->dev, "configure pin %u (%s) = %04X\n", pin, bcm2708_gpio_groups[pin], arg); -- if (param != BCM2708_PINCONF_PARAM_PULL) -- return -EINVAL; -- -- off = GPIO_REG_OFFSET(pin); -- bit = GPIO_REG_SHIFT(pin); -- -- bcm2708_gpio_wr(pc, GPPUD, arg & 3); -- /* -- * Docs say to wait 150 cycles, but not of what. We assume a -- * 1 MHz clock here, which is pretty slow... -- */ -- udelay(150); -- bcm2708_gpio_wr(pc, GPPUDCLK0 + (off * 4), BIT(bit)); -- udelay(150); -- bcm2708_gpio_wr(pc, GPPUDCLK0 + (off * 4), 0); -- } /* for each config */ -- -- return 0; --} -- --static const struct pinconf_ops bcm2708_pinconf_ops = { -- .pin_config_get = bcm2708_pinconf_get, -- .pin_config_set = bcm2708_pinconf_set, --}; -- --static struct pinctrl_desc bcm2708_pinctrl_desc = { -- .name = MODULE_NAME, -- .pins = bcm2708_gpio_pins, -- .npins = ARRAY_SIZE(bcm2708_gpio_pins), -- .pctlops = &bcm2708_pctl_ops, -- .pmxops = &bcm2708_pmx_ops, -- .confops = &bcm2708_pinconf_ops, -- .owner = THIS_MODULE, --}; -- --static struct pinctrl_gpio_range bcm2708_pinctrl_gpio_range = { -- .name = MODULE_NAME, -- .npins = BCM2708_NUM_GPIOS, --}; -- --/* bcm2708_gpio has base=0 */ --static int bcm2708_pinctrl_gpiochip_find(struct gpio_chip *gc, void *data) --{ -- pr_debug("%s: base = %d\n", __func__, gc->base); -- return gc->base == 0 ? 1 : 0; --} -- --static int bcm2708_pinctrl_probe(struct platform_device *pdev) --{ -- struct device *dev = &pdev->dev; -- struct device_node *np = dev->of_node; -- struct bcm2708_pinctrl *pc; -- struct gpio_chip *gc; -- struct resource iomem; -- int err; -- BUILD_BUG_ON(ARRAY_SIZE(bcm2708_gpio_pins) != BCM2708_NUM_GPIOS); -- BUILD_BUG_ON(ARRAY_SIZE(bcm2708_gpio_groups) != BCM2708_NUM_GPIOS); -- -- /* use gpio_chip registered by the bcm2708_gpio driver */ -- gc = gpiochip_find(NULL, bcm2708_pinctrl_gpiochip_find); -- if (!gc) -- return -EPROBE_DEFER; -- -- gc->of_node = np; -- gc->of_gpio_n_cells = 2; -- gc->of_xlate = of_gpio_simple_xlate; -- -- pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL); -- if (!pc) -- return -ENOMEM; -- -- platform_set_drvdata(pdev, pc); -- pc->dev = dev; -- -- err = of_address_to_resource(np, 0, &iomem); -- if (err) { -- dev_err(dev, "could not get IO memory\n"); -- return err; -- } -- -- pc->base = devm_ioremap_resource(dev, &iomem); -- if (IS_ERR(pc->base)) -- return PTR_ERR(pc->base); -- -- pc->gpio_chip = *gc; -- -- pc->pctl_dev = pinctrl_register(&bcm2708_pinctrl_desc, dev, pc); -- if (!pc->pctl_dev) -- return -EINVAL; -- -- pc->gpio_range = bcm2708_pinctrl_gpio_range; -- pc->gpio_range.base = pc->gpio_chip.base; -- pc->gpio_range.gc = &pc->gpio_chip; -- pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range); -- -- return 0; --} -- --static int bcm2708_pinctrl_remove(struct platform_device *pdev) --{ -- struct bcm2708_pinctrl *pc = platform_get_drvdata(pdev); -- -- pinctrl_unregister(pc->pctl_dev); -- gpiochip_remove(&pc->gpio_chip); -- -- return 0; --} -- --static struct of_device_id bcm2708_pinctrl_match[] = { -- { .compatible = "brcm,bcm2708-pinctrl" }, -- {} --}; --MODULE_DEVICE_TABLE(of, bcm2708_pinctrl_match); -- --static struct platform_driver bcm2708_pinctrl_driver = { -- .probe = bcm2708_pinctrl_probe, -- .remove = bcm2708_pinctrl_remove, -- .driver = { -- .name = MODULE_NAME, -- .owner = THIS_MODULE, -- .of_match_table = bcm2708_pinctrl_match, -- }, --}; --module_platform_driver(bcm2708_pinctrl_driver); -- --MODULE_AUTHOR("Chris Boot, Simon Arlott, Stephen Warren, Noralf Tronnes"); --MODULE_DESCRIPTION("BCM2708 Pin control driver"); --MODULE_LICENSE("GPL"); - -From b84d7687baa098135531e9df1c0ca4f58f9647ee Mon Sep 17 00:00:00 2001 -From: notro -Date: Sat, 27 Dec 2014 13:58:37 +0100 -Subject: [PATCH 80/87] BCM2708: armctrl: remove irq bank 3 - -irq bank 3 was needed by the pinctrl-bcm2708 and bcm2708_gpio -combination. It is no longer required. - -Signed-off-by: Noralf Tronnes ---- - arch/arm/mach-bcm2708/armctrl.c | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/armctrl.c b/arch/arm/mach-bcm2708/armctrl.c -index 9734b0d..74bacb3 100644 ---- a/arch/arm/mach-bcm2708/armctrl.c -+++ b/arch/arm/mach-bcm2708/armctrl.c -@@ -84,7 +84,7 @@ static void armctrl_unmask_irq(struct irq_data *d) - #ifdef CONFIG_OF - - #define NR_IRQS_BANK0 21 --#define NR_BANKS 3 + 1 /* bank 3 is used for GPIO interrupts */ -+#define NR_BANKS 3 - #define IRQS_PER_BANK 32 - - /* from drivers/irqchip/irq-bcm2835.c */ -@@ -108,10 +108,8 @@ static int armctrl_xlate(struct irq_domain *d, struct device_node *ctrlr, - *out_hwirq = ARM_IRQ0_BASE + intspec[1]; - else if (intspec[0] == 1) - *out_hwirq = ARM_IRQ1_BASE + intspec[1]; -- else if (intspec[0] == 2) -- *out_hwirq = ARM_IRQ2_BASE + intspec[1]; - else -- *out_hwirq = GPIO_IRQ_START + intspec[1]; -+ *out_hwirq = ARM_IRQ2_BASE + intspec[1]; - - /* reverse remap_irqs[] */ - switch (*out_hwirq) { - -From 73c3c557673da990e098bac2c13bc4668f1726e4 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 2 Jan 2015 17:27:33 +0000 -Subject: [PATCH 81/87] bcm2708-gpio: Revert the use of pinctrl_request_gpio - -In non-DT systems, pinctrl_request_gpio always fails causing -"requests probe deferral" messages. In DT systems, it isn't useful -because the reference counting is independent of the normal pinctrl -pin reservations. ---- - arch/arm/mach-bcm2708/bcm2708_gpio.c | 13 +------------ - 1 file changed, 1 insertion(+), 12 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/bcm2708_gpio.c b/arch/arm/mach-bcm2708/bcm2708_gpio.c -index a094fc2..6ea9b90 100644 ---- a/arch/arm/mach-bcm2708/bcm2708_gpio.c -+++ b/arch/arm/mach-bcm2708/bcm2708_gpio.c -@@ -21,6 +21,7 @@ - #include - #include - #include -+#include - - #include - -@@ -90,16 +91,6 @@ static int bcm2708_set_function(struct gpio_chip *gc, unsigned offset, - return 0; - } - --static int bcm2708_gpio_request(struct gpio_chip *chip, unsigned offset) --{ -- return pinctrl_request_gpio(chip->base + offset); --} -- --static void bcm2708_gpio_free(struct gpio_chip *chip, unsigned offset) --{ -- pinctrl_free_gpio(chip->base + offset); --} -- - static int bcm2708_gpio_dir_in(struct gpio_chip *gc, unsigned offset) - { - return bcm2708_set_function(gc, offset, GPIO_FSEL_INPUT); -@@ -355,8 +346,6 @@ static int bcm2708_gpio_probe(struct platform_device *dev) - ucb->gc.ngpio = BCM2708_NR_GPIOS; - ucb->gc.owner = THIS_MODULE; - -- ucb->gc.request = bcm2708_gpio_request; -- ucb->gc.free = bcm2708_gpio_free; - ucb->gc.direction_input = bcm2708_gpio_dir_in; - ucb->gc.direction_output = bcm2708_gpio_dir_out; - ucb->gc.get = bcm2708_gpio_get; - -From 1ec8e2818a9288b5d4f46286c3d8627eb3718dee Mon Sep 17 00:00:00 2001 +From 54f04b6e104d0a7fbd304e0e69d6a87a81d4e05c Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 6 Jan 2015 12:06:55 +0000 -Subject: [PATCH 82/87] Fix the activity LED in DT mode +Subject: [PATCH 69/76] Fix the activity LED in DT mode Add a "leds" node to the base DTBs, and a subnode for the activity LED. You can change the LED function like this: @@ -123044,300 +120942,5604 @@ index 6b36128..1b56cb5 100644 clocks { -From 3d3c643305b17f7addb66329e45772e90d2276e0 Mon Sep 17 00:00:00 2001 +From f105f830818642ac8bd15172bba17052c727d73a Mon Sep 17 00:00:00 2001 From: Phil Elwell -Date: Wed, 7 Jan 2015 12:06:05 +0000 -Subject: [PATCH 84/87] lirc-rpi: Also support pinctrl-bcm2835 in non-DT mode +Date: Thu, 15 Jan 2015 10:39:06 +0000 +Subject: [PATCH 70/76] Adding w1-gpio device tree overlays +N.B. Requires firmware supporting multi-target overrides + +w1-gpio-overlay: + Use if a pullup pin is not required. + Parameters: + gpiopin= // default 4 + +w1-gpio-pullup-overlay: + Use if a pullup pin is required. + Parameters: + gpiopin= // default 4 + pullup= // default 5 --- - drivers/staging/media/lirc/lirc_rpi.c | 15 ++++++++++++--- - 1 file changed, 12 insertions(+), 3 deletions(-) + arch/arm/boot/dts/w1-gpio-overlay.dts | 37 ++++++++++++++++++++++++++ + arch/arm/boot/dts/w1-gpio-pullup-overlay.dts | 39 ++++++++++++++++++++++++++++ + 2 files changed, 76 insertions(+) + create mode 100644 arch/arm/boot/dts/w1-gpio-overlay.dts + create mode 100644 arch/arm/boot/dts/w1-gpio-pullup-overlay.dts -diff --git a/drivers/staging/media/lirc/lirc_rpi.c b/drivers/staging/media/lirc/lirc_rpi.c -index b7d82ad..697c067 100644 ---- a/drivers/staging/media/lirc/lirc_rpi.c -+++ b/drivers/staging/media/lirc/lirc_rpi.c -@@ -344,12 +344,21 @@ static int init_port(void) - int i, nlow, nhigh, ret, irq; - struct device_node *node; - -+ node = lirc_rpi_dev->dev.of_node; +diff --git a/arch/arm/boot/dts/w1-gpio-overlay.dts b/arch/arm/boot/dts/w1-gpio-overlay.dts +new file mode 100644 +index 0000000..b2c5ee2 +--- /dev/null ++++ b/arch/arm/boot/dts/w1-gpio-overlay.dts +@@ -0,0 +1,37 @@ ++// Definitions for lirc-rpi module ++/dts-v1/; ++/plugin/; + - gpiochip = gpiochip_find("bcm2708_gpio", is_right_chip); - -- if (!gpiochip) -- return -ENODEV; -+ /* -+ * Because of the lack of a setpull function, only support -+ * pinctrl-bcm2835 if using device tree. -+ */ -+ if (!gpiochip && node) -+ gpiochip = gpiochip_find("pinctrl-bcm2835", is_right_chip); - -- node = lirc_rpi_dev->dev.of_node; -+ if (!gpiochip) { -+ pr_err(LIRC_DRIVER_NAME ": gpio chip not found!\n"); -+ return -ENODEV; -+ } - - if (node) { - struct device_node *pins_node; ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target-path = "/"; ++ __overlay__ { ++ ++ w1: onewire@0 { ++ compatible = "w1-gpio"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&w1_pins>; ++ gpios = <&gpio 4 0>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ w1_pins: w1_pins { ++ brcm,pins = <4>; ++ brcm,function = <0>; // in (initially) ++ brcm,pull = <0>; // off ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ gpiopin = <&w1>,"gpios:4", ++ <&w1_pins>,"brcm,pins:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/w1-gpio-pullup-overlay.dts b/arch/arm/boot/dts/w1-gpio-pullup-overlay.dts +new file mode 100644 +index 0000000..b3e97c2 +--- /dev/null ++++ b/arch/arm/boot/dts/w1-gpio-pullup-overlay.dts +@@ -0,0 +1,39 @@ ++// Definitions for lirc-rpi module ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target-path = "/"; ++ __overlay__ { ++ ++ w1: onewire@0 { ++ compatible = "w1-gpio"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&w1_pins>; ++ gpios = <&gpio 4 0>, <&gpio 5 1>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ w1_pins: w1_pins { ++ brcm,pins = <4 5>; ++ brcm,function = <0 1>; // in out ++ brcm,pull = <0 0>; // off off ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ gpiopin = <&w1>,"gpios:4", ++ <&w1_pins>,"brcm,pins:0"; ++ pullup = <&w1>,"gpios:16", ++ <&w1_pins>,"brcm,pins:4"; ++ }; ++}; -From d2b6b478cffd72de43fabe859c5be37063434791 Mon Sep 17 00:00:00 2001 +From a96c657cb56bc612f4dec5ca2faf0bda19e876cc Mon Sep 17 00:00:00 2001 From: popcornmix -Date: Wed, 7 Jan 2015 14:31:01 +0000 -Subject: [PATCH 85/87] gpio: Only clear the currently occurring interrupt. - Avoids losing interrupts +Date: Wed, 21 Jan 2015 22:46:02 +0000 +Subject: [PATCH 71/76] config: Enable CONFIG_PPS -See: linux #760 --- - arch/arm/mach-bcm2708/bcm2708_gpio.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) + arch/arm/configs/bcmrpi_defconfig | 3 +++ + 1 file changed, 3 insertions(+) -diff --git a/arch/arm/mach-bcm2708/bcm2708_gpio.c b/arch/arm/mach-bcm2708/bcm2708_gpio.c -index 6ea9b90..68f6ffd 100644 ---- a/arch/arm/mach-bcm2708/bcm2708_gpio.c -+++ b/arch/arm/mach-bcm2708/bcm2708_gpio.c -@@ -286,8 +286,8 @@ static irqreturn_t bcm2708_gpio_interrupt(int irq, void *dev_id) - for_each_set_bit(i, &edsr, 32) { - gpio = i + bank * 32; - generic_handle_irq(gpio_to_irq(gpio)); -+ writel(1< +Date: Wed, 21 Jan 2015 23:47:33 +0000 +Subject: [PATCH 72/76] config: Add CONFIG_IP_NF options + +--- + arch/arm/configs/bcmrpi_defconfig | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig +index 36aca2b..665b01e 100644 +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -208,13 +208,16 @@ CONFIG_IP_VS_NQ=m + CONFIG_IP_VS_FTP=m + CONFIG_IP_VS_PE_SIP=m + CONFIG_NF_CONNTRACK_IPV4=m +-CONFIG_NF_NAT_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_NAT=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 +@@ -223,7 +226,6 @@ CONFIG_IP_NF_ARPTABLES=m + CONFIG_IP_NF_ARPFILTER=m + CONFIG_IP_NF_ARP_MANGLE=m + CONFIG_NF_CONNTRACK_IPV6=m +-CONFIG_NF_NAT_IPV6=m + CONFIG_IP6_NF_IPTABLES=m + CONFIG_IP6_NF_MATCH_AH=m + CONFIG_IP6_NF_MATCH_EUI64=m +@@ -238,6 +240,9 @@ CONFIG_IP6_NF_FILTER=m + CONFIG_IP6_NF_TARGET_REJECT=m + CONFIG_IP6_NF_MANGLE=m + CONFIG_IP6_NF_RAW=m ++CONFIG_IP6_NF_NAT=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 + +From 192d9b82177b5f12c72e61491be9e25f45ad243d Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Fri, 23 Jan 2015 12:04:59 +0000 +Subject: [PATCH 73/76] config: Restore some missing options + +--- + arch/arm/configs/bcmrpi_defconfig | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig +index 665b01e..41b90b4 100644 +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -484,6 +484,8 @@ CONFIG_AR5523=m + CONFIG_B43=m + # CONFIG_B43_PHY_N is not set + CONFIG_B43LEGACY=m ++CONFIG_BRCMFMAC=m ++CONFIG_BRCMFMAC_USB=y + CONFIG_HOSTAP=m + CONFIG_LIBERTAS=m + CONFIG_LIBERTAS_USB=m +@@ -524,6 +526,7 @@ CONFIG_INPUT_POWERMATE=m + CONFIG_INPUT_YEALINK=m + CONFIG_INPUT_CM109=m + CONFIG_INPUT_UINPUT=m ++CONFIG_INPUT_GPIO_ROTARY_ENCODER=m + CONFIG_INPUT_ADXL34X=m + CONFIG_INPUT_CMA3000=m + CONFIG_SERIO=m +@@ -545,6 +548,7 @@ CONFIG_BCM_VC_CMA=y + CONFIG_BCM_VC_SM=y + CONFIG_I2C=y + CONFIG_I2C_CHARDEV=m ++CONFIG_I2C_MUX=m + CONFIG_I2C_BCM2708=m + CONFIG_SPI=y + CONFIG_SPI_BCM2708=m +@@ -724,6 +728,7 @@ CONFIG_RADIO_SI470X=y + CONFIG_USB_SI470X=m + CONFIG_I2C_SI470X=m + CONFIG_RADIO_SI4713=m ++CONFIG_I2C_SI4713=m + CONFIG_USB_MR800=m + CONFIG_USB_DSBR=m + CONFIG_RADIO_SHARK=m +@@ -735,6 +740,15 @@ CONFIG_RADIO_SAA7706H=m + CONFIG_RADIO_TEF6862=m + CONFIG_RADIO_WL1273=m + CONFIG_RADIO_WL128X=m ++# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set ++CONFIG_VIDEO_UDA1342=m ++CONFIG_VIDEO_SONY_BTF_MPX=m ++CONFIG_VIDEO_TVP5150=m ++CONFIG_VIDEO_TW2804=m ++CONFIG_VIDEO_TW9903=m ++CONFIG_VIDEO_TW9906=m ++CONFIG_VIDEO_OV7640=m ++CONFIG_VIDEO_MT9V011=m + CONFIG_FB=y + CONFIG_FB_BCM2708=y + # CONFIG_BACKLIGHT_GENERIC is not set +@@ -783,6 +797,7 @@ CONFIG_HID_CYPRESS=m + CONFIG_HID_DRAGONRISE=m + CONFIG_HID_EMS_FF=m + CONFIG_HID_ELECOM=m ++CONFIG_HID_ELO=m + CONFIG_HID_EZKEY=m + CONFIG_HID_HOLTEK=m + CONFIG_HID_KEYTOUCH=m +@@ -1042,6 +1057,7 @@ CONFIG_F2FS_FS=y + CONFIG_NFS_FS=y + CONFIG_NFS_V3_ACL=y + CONFIG_NFS_V4=y ++CONFIG_NFS_SWAP=y + CONFIG_ROOT_NFS=y + CONFIG_NFS_FSCACHE=y + CONFIG_NFSD=m +@@ -1116,8 +1132,6 @@ CONFIG_CRYPTO_CBC=y + CONFIG_CRYPTO_CTS=m + 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 + +From 56c24bc465fb65a5ab303ddbae63ea071ddb3768 Mon Sep 17 00:00:00 2001 +From: Daniel Matuschek +Date: Fri, 23 Jan 2015 16:41:17 +0100 +Subject: [PATCH 74/76] TAS5713: return error if initialisation fails + +Existing TAS5713 driver logs errors during initialisation, but does not return +an error code. Therefore even if initialisation fails, the driver will still be +loaded, but won't work. This patch fixes this. I2C communication error will now +reported correctly by a non-zero return code. +--- + sound/soc/codecs/tas5713.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/sound/soc/codecs/tas5713.c b/sound/soc/codecs/tas5713.c +index a24c1da..9b27138 100644 +--- a/sound/soc/codecs/tas5713.c ++++ b/sound/soc/codecs/tas5713.c +@@ -182,33 +182,40 @@ static int tas5713_probe(struct snd_soc_codec *codec) + + // Reset error + ret = snd_soc_write(codec, TAS5713_ERROR_STATUS, 0x00); ++ if (ret < 0) return ret; + + // Trim oscillator +- ret = snd_soc_write(codec, TAS5713_OSC_TRIM, 0x00); ++ ret = snd_soc_write(codec, TAS5713_OSC_TRIM, 0x00); ++ if (ret < 0) return ret; + msleep(1000); + + // Reset error + ret = snd_soc_write(codec, TAS5713_ERROR_STATUS, 0x00); ++ if (ret < 0) return ret; + + // Clock mode: 44/48kHz, MCLK=64xfs + ret = snd_soc_write(codec, TAS5713_CLOCK_CTRL, 0x60); ++ if (ret < 0) return ret; + + // I2S 24bit + ret = snd_soc_write(codec, TAS5713_SERIAL_DATA_INTERFACE, 0x05); ++ if (ret < 0) return ret; + + // Unmute + ret = snd_soc_write(codec, TAS5713_SYSTEM_CTRL2, 0x00); ++ if (ret < 0) return ret; + ret = snd_soc_write(codec, TAS5713_SOFT_MUTE, 0x00); ++ if (ret < 0) return ret; + + // Set volume to 0db + ret = snd_soc_write(codec, TAS5713_VOL_MASTER, 0x00); ++ if (ret < 0) return ret; + + // Now start programming the default initialization sequence + for (i = 0; i < ARRAY_SIZE(tas5713_init_sequence); ++i) { + ret = i2c_master_send(i2c, + tas5713_init_sequence[i].data, + tas5713_init_sequence[i].size); +- + if (ret < 0) { + printk(KERN_INFO "TAS5713 CODEC PROBE: InitSeq returns: %d\n", ret); } -- writel(0xffffffff, __io_address(GPIO_BASE) + GPIOEDS(bank)); +@@ -216,7 +223,7 @@ static int tas5713_probe(struct snd_soc_codec *codec) + + // Unmute + ret = snd_soc_write(codec, TAS5713_SYSTEM_CTRL2, 0x00); +- ++ if (ret < 0) return ret; + + return 0; + } + +From 58fbc9c5335f2510664f69ed8e68b6c2f159c2b5 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Fri, 23 Jan 2015 14:48:55 +0000 +Subject: [PATCH 75/76] scripts/dtc: Update to upstream version with overlay + patches + +--- + scripts/dtc/checks.c | 151 ++- + scripts/dtc/data.c | 12 +- + scripts/dtc/dtc-lexer.l | 70 +- + scripts/dtc/dtc-lexer.lex.c_shipped | 540 +++++----- + scripts/dtc/dtc-parser.tab.c_shipped | 1783 ++++++++++++++++------------------ + scripts/dtc/dtc-parser.tab.h_shipped | 116 ++- + scripts/dtc/dtc-parser.y | 158 +-- + scripts/dtc/dtc.c | 23 +- + scripts/dtc/dtc.h | 56 +- + scripts/dtc/flattree.c | 145 ++- + scripts/dtc/fstree.c | 16 +- + scripts/dtc/livetree.c | 4 +- + scripts/dtc/srcpos.c | 49 +- + scripts/dtc/srcpos.h | 15 +- + scripts/dtc/treesource.c | 14 +- + scripts/dtc/util.c | 18 +- + scripts/dtc/util.h | 4 +- + scripts/dtc/version_gen.h | 2 +- + 18 files changed, 1697 insertions(+), 1479 deletions(-) + +diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c +index ee96a25..27f45f1 100644 +--- a/scripts/dtc/checks.c ++++ b/scripts/dtc/checks.c +@@ -53,7 +53,7 @@ struct check { + void *data; + bool warn, error; + enum checkstatus status; +- int inprogress; ++ bool inprogress; + int num_prereqs; + struct check **prereq; + }; +@@ -113,6 +113,7 @@ static inline void check_msg(struct check *c, const char *fmt, ...) + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); } - return IRQ_HANDLED; - } - -From 9f32865b3232bc51f829b0d6ce555f043291ee02 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 8 Jan 2015 15:37:14 +0000 -Subject: [PATCH 86/87] lirc-rpi: Use the higher-level irq control functions - -This module used to access the irq_chip methods of the -gpio controller directly, rather than going through the -standard enable_irq/irq_set_irq_type functions. This -caused problems on pinctrl-bcm2835 which only implements -the irq_enable/disable methods and not irq_unmask/mask. ---- - drivers/staging/media/lirc/lirc_rpi.c | 52 ++++++++++------------------------- - 1 file changed, 15 insertions(+), 37 deletions(-) - -diff --git a/drivers/staging/media/lirc/lirc_rpi.c b/drivers/staging/media/lirc/lirc_rpi.c -index 697c067..126bf22 100644 ---- a/drivers/staging/media/lirc/lirc_rpi.c -+++ b/drivers/staging/media/lirc/lirc_rpi.c -@@ -79,8 +79,7 @@ static bool softcarrier = 1; - static bool invert = 0; - - struct gpio_chip *gpiochip; --struct irq_chip *irqchip; --struct irq_data *irqdata; -+static int irq_num; - - /* forward declarations */ - static long send_pulse(unsigned long length); -@@ -247,7 +246,7 @@ static irqreturn_t irq_handler(int i, void *blah, struct pt_regs *regs) - signal = gpiochip->get(gpiochip, gpio_in_pin); - - /* unmask the irq */ -- irqchip->irq_unmask(irqdata); -+ enable_irq(irq_num); - - if (sense != -1) { - /* get current time */ -@@ -341,7 +340,7 @@ static void read_pin_settings(struct device_node *node) - - static int init_port(void) - { -- int i, nlow, nhigh, ret, irq; -+ int i, nlow, nhigh, ret; - struct device_node *node; - - node = lirc_rpi_dev->dev.of_node; -@@ -413,16 +412,8 @@ static int init_port(void) - - gpiochip->set(gpiochip, gpio_out_pin, invert); - -- irq = gpiochip->to_irq(gpiochip, gpio_in_pin); -- dprintk("to_irq %d\n", irq); -- irqdata = irq_get_irq_data(irq); -- -- if (irqdata && irqdata->chip) { -- irqchip = irqdata->chip; -- } else { -- ret = -ENODEV; -- goto exit_gpio_free_in_pin; -- } -+ irq_num = gpiochip->to_irq(gpiochip, gpio_in_pin); -+ dprintk("to_irq %d\n", irq_num); - - /* if pin is high, then this must be an active low receiver. */ - if (sense == -1) { -@@ -454,7 +445,6 @@ static int init_port(void) - - return 0; - -- exit_gpio_free_in_pin: - gpio_free(gpio_in_pin); - - exit_gpio_free_out_pin: -@@ -468,12 +458,11 @@ static int init_port(void) - static int set_use_inc(void *data) - { - int result; -- unsigned long flags; - - /* initialize timestamp */ - do_gettimeofday(&lasttv); - -- result = request_irq(gpiochip->to_irq(gpiochip, gpio_in_pin), -+ result = request_irq(irq_num, - (irq_handler_t) irq_handler, 0, - LIRC_DRIVER_NAME, (void*) 0); - -@@ -481,7 +470,7 @@ static int set_use_inc(void *data) - case -EBUSY: - printk(KERN_ERR LIRC_DRIVER_NAME - ": IRQ %d is busy\n", -- gpiochip->to_irq(gpiochip, gpio_in_pin)); -+ irq_num); - return -EBUSY; - case -EINVAL: - printk(KERN_ERR LIRC_DRIVER_NAME -@@ -489,43 +478,32 @@ static int set_use_inc(void *data) - return -EINVAL; - default: - dprintk("Interrupt %d obtained\n", -- gpiochip->to_irq(gpiochip, gpio_in_pin)); -+ irq_num); - break; - }; - - /* initialize pulse/space widths */ - init_timing_params(duty_cycle, freq); - -- spin_lock_irqsave(&lock, flags); -- - /* GPIO Pin Falling/Rising Edge Detect Enable */ -- irqchip->irq_set_type(irqdata, -- IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING); -+ irq_set_irq_type(irq_num, IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING); - -- /* unmask the irq */ -- irqchip->irq_unmask(irqdata); -- -- spin_unlock_irqrestore(&lock, flags); -+ /* enable the irq */ -+ enable_irq(irq_num); - - return 0; ++ va_end(ap); } - static void set_use_dec(void *data) - { -- unsigned long flags; -- -- spin_lock_irqsave(&lock, flags); -- - /* GPIO Pin Falling/Rising Edge Detect Disable */ -- irqchip->irq_set_type(irqdata, 0); -- irqchip->irq_mask(irqdata); -- -- spin_unlock_irqrestore(&lock, flags); -+ irq_set_irq_type(irq_num, 0); -+ disable_irq(irq_num); - -- free_irq(gpiochip->to_irq(gpiochip, gpio_in_pin), (void *) 0); -+ free_irq(irq_num, (void *) 0); - - dprintk(KERN_INFO LIRC_DRIVER_NAME -- ": freed IRQ %d\n", gpiochip->to_irq(gpiochip, gpio_in_pin)); -+ ": freed IRQ %d\n", irq_num); + #define FAIL(c, ...) \ +@@ -141,9 +142,9 @@ static void check_nodes_props(struct check *c, struct node *dt, struct node *nod + check_nodes_props(c, dt, child); } - static ssize_t lirc_write(struct file *file, const char *buf, - -From adf178c0c4247e3689403fa6e3045049e4151732 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 9 Jan 2015 15:35:10 +0000 -Subject: [PATCH 87/87] lirc-rpi: Correct the interrupt usage - -1) Correct the use of enable_irq (i.e. don't call it so often) -2) Correct the shutdown sequence. -3) Avoid a bcm2708_gpio driver quirk by setting the irq flags earlier ---- - drivers/staging/media/lirc/lirc_rpi.c | 20 ++++++-------------- - 1 file changed, 6 insertions(+), 14 deletions(-) - -diff --git a/drivers/staging/media/lirc/lirc_rpi.c b/drivers/staging/media/lirc/lirc_rpi.c -index 126bf22..cd66ca2 100644 ---- a/drivers/staging/media/lirc/lirc_rpi.c -+++ b/drivers/staging/media/lirc/lirc_rpi.c -@@ -245,9 +245,6 @@ static irqreturn_t irq_handler(int i, void *blah, struct pt_regs *regs) - /* use the GPIO signal level */ - signal = gpiochip->get(gpiochip, gpio_in_pin); +-static int run_check(struct check *c, struct node *dt) ++static bool run_check(struct check *c, struct node *dt) + { +- int error = 0; ++ bool error = false; + int i; -- /* unmask the irq */ -- enable_irq(irq_num); -- - if (sense != -1) { - /* get current time */ - do_gettimeofday(&tv); -@@ -445,8 +442,6 @@ static int init_port(void) + assert(!c->inprogress); +@@ -151,11 +152,11 @@ static int run_check(struct check *c, struct node *dt) + if (c->status != UNCHECKED) + goto out; - return 0; +- c->inprogress = 1; ++ c->inprogress = true; -- gpio_free(gpio_in_pin); -- - exit_gpio_free_out_pin: - gpio_free(gpio_out_pin); + for (i = 0; i < c->num_prereqs; i++) { + struct check *prq = c->prereq[i]; +- error |= run_check(prq, dt); ++ error = error || run_check(prq, dt); + if (prq->status != PASSED) { + c->status = PREREQ; + check_msg(c, "Failed prerequisite '%s'", +@@ -177,9 +178,9 @@ static int run_check(struct check *c, struct node *dt) + TRACE(c, "\tCompleted, status %d", c->status); -@@ -463,7 +458,8 @@ static int set_use_inc(void *data) - do_gettimeofday(&lasttv); - - result = request_irq(irq_num, -- (irq_handler_t) irq_handler, 0, -+ (irq_handler_t) irq_handler, -+ IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING, - LIRC_DRIVER_NAME, (void*) 0); - - switch (result) { -@@ -485,12 +481,6 @@ static int set_use_inc(void *data) - /* initialize pulse/space widths */ - init_timing_params(duty_cycle, freq); - -- /* GPIO Pin Falling/Rising Edge Detect Enable */ -- irq_set_irq_type(irq_num, IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING); -- -- /* enable the irq */ -- enable_irq(irq_num); -- - return 0; + out: +- c->inprogress = 0; ++ c->inprogress = false; + if ((c->status != PASSED) && (c->error)) +- error = 1; ++ error = true; + return error; } -@@ -678,7 +668,8 @@ static int __init lirc_rpi_init(void) - - static void lirc_rpi_exit(void) +@@ -457,22 +458,93 @@ static void fixup_phandle_references(struct check *c, struct node *dt, + struct node *node, struct property *prop) { -- platform_device_unregister(lirc_rpi_dev); -+ if (!lirc_rpi_dev->dev.of_node) -+ platform_device_unregister(lirc_rpi_dev); - platform_driver_unregister(&lirc_rpi_driver); - lirc_buffer_free(&rbuf); - } -@@ -722,12 +713,13 @@ static int __init lirc_rpi_init_module(void) - - static void __exit lirc_rpi_exit_module(void) - { -+ lirc_unregister_driver(driver.minor); + struct marker *m = prop->val.markers; ++ struct fixup *f, **fp; ++ struct fixup_entry *fe, **fep; + struct node *refnode; + cell_t phandle; ++ int has_phandle_refs; + - gpio_free(gpio_out_pin); - gpio_free(gpio_in_pin); ++ has_phandle_refs = 0; ++ for_each_marker_of_type(m, REF_PHANDLE) { ++ has_phandle_refs = 1; ++ break; ++ } ++ ++ if (!has_phandle_refs) ++ return; - lirc_rpi_exit(); + for_each_marker_of_type(m, REF_PHANDLE) { + assert(m->offset + sizeof(cell_t) <= prop->val.len); -- lirc_unregister_driver(driver.minor); - printk(KERN_INFO LIRC_DRIVER_NAME ": cleaned up module\n"); + refnode = get_node_by_ref(dt, m->ref); +- if (! refnode) { ++ if (!refnode && !symbol_fixup_support) { + FAIL(c, "Reference to non-existent node or label \"%s\"\n", +- m->ref); ++ m->ref); + continue; + } + +- phandle = get_node_phandle(dt, refnode); +- *((cell_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle); ++ if (!refnode) { ++ /* allocate fixup entry */ ++ fe = xmalloc(sizeof(*fe)); ++ ++ fe->node = node; ++ fe->prop = prop; ++ fe->offset = m->offset; ++ fe->next = NULL; ++ ++ /* search for an already existing fixup */ ++ for_each_fixup(dt, f) ++ if (strcmp(f->ref, m->ref) == 0) ++ break; ++ ++ /* no fixup found, add new */ ++ if (f == NULL) { ++ f = xmalloc(sizeof(*f)); ++ f->ref = m->ref; ++ f->entries = NULL; ++ f->next = NULL; ++ ++ /* add it to the tree */ ++ fp = &dt->fixups; ++ while (*fp) ++ fp = &(*fp)->next; ++ *fp = f; ++ } ++ ++ /* and now append fixup entry */ ++ fep = &f->entries; ++ while (*fep) ++ fep = &(*fep)->next; ++ *fep = fe; ++ ++ /* mark the entry as unresolved */ ++ phandle = 0xdeadbeef; ++ } else { ++ phandle = get_node_phandle(dt, refnode); ++ ++ /* if it's a plugin, we need to record it */ ++ if (symbol_fixup_support && dt->is_plugin) { ++ ++ /* allocate a new local fixup entry */ ++ fe = xmalloc(sizeof(*fe)); ++ ++ fe->node = node; ++ fe->prop = prop; ++ fe->offset = m->offset; ++ fe->next = NULL; ++ ++ /* append it to the local fixups */ ++ fep = &dt->local_fixups; ++ while (*fep) ++ fep = &(*fep)->next; ++ *fep = fe; ++ } ++ } ++ ++ *((cell_t *)(prop->val.val + m->offset)) = ++ cpu_to_fdt32(phandle); + } ++ + } + ERROR(phandle_references, NULL, NULL, fixup_phandle_references, NULL, + &duplicate_node_names, &explicit_phandles); +@@ -624,11 +696,11 @@ static void check_avoid_default_addr_size(struct check *c, struct node *dt, + if (!reg && !ranges) + return; + +- if ((node->parent->addr_cells == -1)) ++ if (node->parent->addr_cells == -1) + FAIL(c, "Relying on default #address-cells value for %s", + node->fullpath); + +- if ((node->parent->size_cells == -1)) ++ if (node->parent->size_cells == -1) + FAIL(c, "Relying on default #size-cells value for %s", + node->fullpath); + } +@@ -651,6 +723,45 @@ static void check_obsolete_chosen_interrupt_controller(struct check *c, + } + TREE_WARNING(obsolete_chosen_interrupt_controller, NULL); + ++static void check_auto_label_phandles(struct check *c, struct node *dt, ++ struct node *node) ++{ ++ struct label *l; ++ struct symbol *s, **sp; ++ int has_label; ++ ++ if (!symbol_fixup_support) ++ return; ++ ++ has_label = 0; ++ for_each_label(node->labels, l) { ++ has_label = 1; ++ break; ++ } ++ ++ if (!has_label) ++ return; ++ ++ /* force allocation of a phandle for this node */ ++ (void)get_node_phandle(dt, node); ++ ++ /* add the symbol */ ++ for_each_label(node->labels, l) { ++ ++ s = xmalloc(sizeof(*s)); ++ s->label = l; ++ s->node = node; ++ s->next = NULL; ++ ++ /* add it to the symbols list */ ++ sp = &dt->symbols; ++ while (*sp) ++ sp = &((*sp)->next); ++ *sp = s; ++ } ++} ++NODE_WARNING(auto_label_phandles, NULL); ++ + static struct check *check_table[] = { + &duplicate_node_names, &duplicate_property_names, + &node_name_chars, &node_name_format, &property_name_chars, +@@ -669,6 +780,8 @@ static struct check *check_table[] = { + &avoid_default_addr_size, + &obsolete_chosen_interrupt_controller, + ++ &auto_label_phandles, ++ + &always_fail, + }; + +@@ -706,15 +819,15 @@ static void disable_warning_error(struct check *c, bool warn, bool error) + c->error = c->error && !error; } +-void parse_checks_option(bool warn, bool error, const char *optarg) ++void parse_checks_option(bool warn, bool error, const char *arg) + { + int i; +- const char *name = optarg; ++ const char *name = arg; + bool enable = true; + +- if ((strncmp(optarg, "no-", 3) == 0) +- || (strncmp(optarg, "no_", 3) == 0)) { +- name = optarg + 3; ++ if ((strncmp(arg, "no-", 3) == 0) ++ || (strncmp(arg, "no_", 3) == 0)) { ++ name = arg + 3; + enable = false; + } + +@@ -733,7 +846,7 @@ void parse_checks_option(bool warn, bool error, const char *optarg) + die("Unrecognized check name \"%s\"\n", name); + } + +-void process_checks(int force, struct boot_info *bi) ++void process_checks(bool force, struct boot_info *bi) + { + struct node *dt = bi->dt; + int i; +diff --git a/scripts/dtc/data.c b/scripts/dtc/data.c +index 4a40c5b..8cae237 100644 +--- a/scripts/dtc/data.c ++++ b/scripts/dtc/data.c +@@ -74,7 +74,7 @@ struct data data_copy_escape_string(const char *s, int len) + struct data d; + char *q; + +- d = data_grow_for(empty_data, strlen(s)+1); ++ d = data_grow_for(empty_data, len + 1); + + q = d.val; + while (i < len) { +@@ -250,20 +250,20 @@ struct data data_add_marker(struct data d, enum markertype type, char *ref) + return data_append_markers(d, m); + } + +-int data_is_one_string(struct data d) ++bool data_is_one_string(struct data d) + { + int i; + int len = d.len; + + if (len == 0) +- return 0; ++ return false; + + for (i = 0; i < len-1; i++) + if (d.val[i] == '\0') +- return 0; ++ return false; + + if (d.val[len-1] != '\0') +- return 0; ++ return false; + +- return 1; ++ return true; + } +diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l +index 3b41bfc..dd44ba2 100644 +--- a/scripts/dtc/dtc-lexer.l ++++ b/scripts/dtc/dtc-lexer.l +@@ -20,7 +20,6 @@ + + %option noyywrap nounput noinput never-interactive + +-%x INCLUDE + %x BYTESTRING + %x PROPNODENAME + %s V1 +@@ -40,6 +39,7 @@ LINECOMMENT "//".*\n + #include "dtc-parser.tab.h" + + YYLTYPE yylloc; ++extern bool treesource_error; + + /* CAUTION: this will stop working if we ever use yyless() or yyunput() */ + #define YY_USER_ACTION \ +@@ -61,7 +61,8 @@ static int dts_version = 1; + BEGIN(V1); \ + + static void push_input_file(const char *filename); +-static int pop_input_file(void); ++static bool pop_input_file(void); ++static void lexical_error(const char *fmt, ...); + %} + + %% +@@ -75,11 +76,11 @@ static int pop_input_file(void); + char *line, *tmp, *fn; + /* skip text before line # */ + line = yytext; +- while (!isdigit(*line)) ++ while (!isdigit((unsigned char)*line)) + line++; + /* skip digits in line # */ + tmp = line; +- while (!isspace(*tmp)) ++ while (!isspace((unsigned char)*tmp)) + tmp++; + /* "NULL"-terminate line # */ + *tmp = '\0'; +@@ -112,6 +113,11 @@ static int pop_input_file(void); + return DT_V1; + } + ++<*>"/plugin/" { ++ DPRINT("Keyword: /plugin/\n"); ++ return DT_PLUGIN; ++ } ++ + <*>"/memreserve/" { + DPRINT("Keyword: /memreserve/\n"); + BEGIN_DEFAULT(); +@@ -146,15 +152,42 @@ static int pop_input_file(void); + } + + ([0-9]+|0[xX][0-9a-fA-F]+)(U|L|UL|LL|ULL)? { +- yylval.literal = xstrdup(yytext); +- DPRINT("Literal: '%s'\n", yylval.literal); ++ char *e; ++ DPRINT("Integer Literal: '%s'\n", yytext); ++ ++ errno = 0; ++ yylval.integer = strtoull(yytext, &e, 0); ++ ++ assert(!(*e) || !e[strspn(e, "UL")]); ++ ++ if (errno == ERANGE) ++ lexical_error("Integer literal '%s' out of range", ++ yytext); ++ else ++ /* ERANGE is the only strtoull error triggerable ++ * by strings matching the pattern */ ++ assert(errno == 0); + return DT_LITERAL; + } + + <*>{CHAR_LITERAL} { +- yytext[yyleng-1] = '\0'; +- yylval.literal = xstrdup(yytext+1); +- DPRINT("Character literal: %s\n", yylval.literal); ++ struct data d; ++ DPRINT("Character literal: %s\n", yytext); ++ ++ d = data_copy_escape_string(yytext+1, yyleng-2); ++ if (d.len == 1) { ++ lexical_error("Empty character literal"); ++ yylval.integer = 0; ++ return DT_CHAR_LITERAL; ++ } ++ ++ yylval.integer = (unsigned char)d.val[0]; ++ ++ if (d.len > 2) ++ lexical_error("Character literal has %d" ++ " characters instead of 1", ++ d.len - 1); ++ + return DT_CHAR_LITERAL; + } + +@@ -164,7 +197,7 @@ static int pop_input_file(void); + return DT_REF; + } + +-<*>"&{/"{PATHCHAR}+\} { /* new-style path reference */ ++<*>"&{/"{PATHCHAR}*\} { /* new-style path reference */ + yytext[yyleng-1] = '\0'; + DPRINT("Ref: %s\n", yytext+2); + yylval.labelref = xstrdup(yytext+2); +@@ -238,13 +271,24 @@ static void push_input_file(const char *filename) + } + + +-static int pop_input_file(void) ++static bool pop_input_file(void) + { + if (srcfile_pop() == 0) +- return 0; ++ return false; + + yypop_buffer_state(); + yyin = current_srcfile->f; + +- return 1; ++ return true; ++} ++ ++static void lexical_error(const char *fmt, ...) ++{ ++ va_list ap; ++ ++ va_start(ap, fmt); ++ srcpos_verror(&yylloc, "Lexical error", fmt, ap); ++ va_end(ap); ++ ++ treesource_error = true; + } +diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped +index 2d30f41..1518525 100644 +--- a/scripts/dtc/dtc-lexer.lex.c_shipped ++++ b/scripts/dtc/dtc-lexer.lex.c_shipped +@@ -372,8 +372,8 @@ static void yy_fatal_error (yyconst char msg[] ); + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; + +-#define YY_NUM_RULES 30 +-#define YY_END_OF_BUFFER 31 ++#define YY_NUM_RULES 31 ++#define YY_END_OF_BUFFER 32 + /* This struct is not used in this scanner, + but its presence is necessary. */ + struct yy_trans_info +@@ -381,25 +381,26 @@ struct yy_trans_info + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +-static yyconst flex_int16_t yy_accept[161] = ++static yyconst flex_int16_t yy_accept[166] = + { 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 32, 30, ++ 19, 19, 30, 30, 30, 30, 30, 30, 30, 30, ++ 30, 30, 30, 30, 30, 30, 16, 17, 17, 30, ++ 17, 11, 11, 19, 27, 0, 3, 0, 28, 13, ++ 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, ++ 0, 22, 24, 26, 25, 23, 0, 10, 29, 0, ++ 0, 0, 15, 15, 17, 17, 17, 11, 11, 11, ++ 0, 13, 0, 12, 0, 0, 0, 21, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 17, 11, 11, ++ 11, 0, 14, 20, 0, 0, 0, 0, 0, 0, ++ ++ 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 17, 7, 0, 0, 0, ++ 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 4, 18, 0, 0, 5, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 31, 29, 18, 18, 29, 29, 29, 29, 29, 29, +- 29, 29, 29, 29, 29, 29, 29, 29, 15, 16, +- 16, 29, 16, 10, 10, 18, 26, 0, 3, 0, +- 27, 12, 0, 0, 11, 0, 0, 0, 0, 0, +- 0, 0, 21, 23, 25, 24, 22, 0, 9, 28, +- 0, 0, 0, 14, 14, 16, 16, 16, 10, 10, +- 10, 0, 12, 0, 11, 0, 0, 0, 20, 0, +- 0, 0, 0, 0, 0, 0, 0, 16, 10, 10, +- 10, 0, 19, 0, 0, 0, 0, 0, 0, 0, +- +- 0, 0, 16, 13, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 16, 6, 0, 0, 0, 0, 0, +- 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, +- 4, 17, 0, 0, 2, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, +- 0, 0, 5, 8, 0, 0, 0, 0, 7, 0 ++ 0, 0, 1, 0, 0, 0, 0, 6, 9, 0, ++ 0, 0, 0, 8, 0 + } ; + + static yyconst flex_int32_t yy_ec[256] = +@@ -415,9 +416,9 @@ static yyconst flex_int32_t yy_ec[256] = + 22, 22, 22, 22, 24, 22, 22, 25, 22, 22, + 1, 26, 27, 1, 22, 1, 21, 28, 29, 30, + +- 31, 21, 22, 22, 32, 22, 22, 33, 34, 35, +- 36, 37, 22, 38, 39, 40, 41, 42, 22, 25, +- 43, 22, 44, 45, 46, 1, 1, 1, 1, 1, ++ 31, 21, 32, 22, 33, 22, 22, 34, 35, 36, ++ 37, 38, 22, 39, 40, 41, 42, 43, 22, 25, ++ 44, 22, 45, 46, 47, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +@@ -434,163 +435,165 @@ static yyconst flex_int32_t yy_ec[256] = + 1, 1, 1, 1, 1 + } ; + +-static yyconst flex_int32_t yy_meta[47] = ++static yyconst flex_int32_t yy_meta[48] = + { 0, + 1, 1, 1, 1, 1, 1, 2, 3, 1, 2, + 2, 2, 4, 5, 5, 5, 6, 1, 1, 1, + 7, 8, 8, 8, 8, 1, 1, 7, 7, 7, + 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, +- 8, 8, 8, 3, 1, 1 ++ 8, 8, 8, 8, 3, 1, 4 + } ; + +-static yyconst flex_int16_t yy_base[175] = ++static yyconst flex_int16_t yy_base[180] = + { 0, +- 0, 385, 378, 40, 41, 383, 72, 382, 34, 44, +- 388, 393, 61, 117, 368, 116, 115, 115, 115, 48, +- 367, 107, 368, 339, 127, 120, 0, 147, 393, 0, +- 127, 0, 133, 156, 168, 153, 393, 125, 393, 380, +- 393, 0, 369, 127, 393, 160, 371, 377, 347, 21, +- 343, 346, 393, 393, 393, 393, 393, 359, 393, 393, +- 183, 343, 339, 393, 356, 0, 183, 340, 187, 348, +- 347, 0, 0, 0, 178, 359, 195, 365, 354, 326, +- 332, 325, 334, 328, 204, 326, 331, 324, 393, 335, +- 150, 311, 343, 342, 315, 322, 340, 179, 313, 207, +- +- 319, 316, 317, 393, 337, 333, 305, 302, 311, 301, +- 310, 190, 338, 337, 393, 307, 322, 301, 305, 277, +- 208, 311, 307, 278, 271, 270, 248, 246, 213, 130, +- 393, 393, 263, 235, 207, 221, 218, 229, 213, 213, +- 206, 234, 218, 210, 208, 193, 219, 393, 223, 204, +- 176, 157, 393, 393, 120, 106, 97, 119, 393, 393, +- 245, 251, 259, 263, 267, 273, 280, 284, 292, 300, +- 304, 310, 318, 326 ++ 0, 393, 35, 392, 66, 391, 38, 107, 397, 401, ++ 55, 113, 377, 112, 111, 111, 114, 42, 376, 106, ++ 377, 347, 126, 120, 0, 147, 401, 0, 124, 0, ++ 137, 158, 170, 163, 401, 153, 401, 389, 401, 0, ++ 378, 120, 401, 131, 380, 386, 355, 139, 351, 355, ++ 351, 401, 401, 401, 401, 401, 367, 401, 401, 185, ++ 350, 346, 401, 364, 0, 185, 347, 189, 356, 355, ++ 0, 0, 330, 180, 366, 141, 372, 361, 332, 338, ++ 331, 341, 334, 326, 205, 331, 337, 329, 401, 341, ++ 167, 316, 401, 349, 348, 320, 328, 346, 180, 318, ++ ++ 324, 209, 324, 320, 322, 342, 338, 309, 306, 315, ++ 305, 315, 312, 192, 342, 341, 401, 293, 306, 282, ++ 268, 252, 255, 203, 285, 282, 272, 268, 252, 233, ++ 232, 239, 208, 107, 401, 401, 238, 211, 401, 211, ++ 212, 208, 228, 203, 215, 207, 233, 222, 212, 211, ++ 203, 227, 401, 237, 225, 204, 185, 401, 401, 149, ++ 128, 88, 42, 401, 401, 253, 259, 267, 271, 275, ++ 281, 288, 292, 300, 308, 312, 318, 326, 334 + } ; + +-static yyconst flex_int16_t yy_def[175] = ++static yyconst flex_int16_t yy_def[180] = + { 0, +- 160, 1, 1, 1, 1, 5, 160, 7, 1, 1, +- 160, 160, 160, 160, 160, 161, 162, 163, 160, 160, +- 160, 160, 164, 160, 160, 160, 165, 164, 160, 166, +- 167, 166, 166, 160, 160, 160, 160, 161, 160, 161, +- 160, 168, 160, 163, 160, 163, 169, 170, 160, 160, +- 160, 160, 160, 160, 160, 160, 160, 164, 160, 160, +- 160, 160, 160, 160, 164, 166, 167, 166, 160, 160, +- 160, 171, 168, 172, 163, 169, 169, 170, 160, 160, +- 160, 160, 160, 160, 160, 160, 160, 166, 160, 160, +- 171, 172, 160, 160, 160, 160, 160, 160, 160, 160, +- +- 160, 160, 166, 160, 160, 160, 160, 160, 160, 160, +- 160, 173, 160, 166, 160, 160, 160, 160, 160, 160, +- 173, 160, 173, 160, 160, 160, 160, 160, 160, 160, +- 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, +- 160, 160, 174, 160, 160, 160, 174, 160, 174, 160, +- 160, 160, 160, 160, 160, 160, 160, 160, 160, 0, +- 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, +- 160, 160, 160, 160 ++ 165, 1, 1, 3, 165, 5, 1, 1, 165, 165, ++ 165, 165, 165, 166, 167, 168, 165, 165, 165, 165, ++ 169, 165, 165, 165, 170, 169, 165, 171, 172, 171, ++ 171, 165, 165, 165, 165, 166, 165, 166, 165, 173, ++ 165, 168, 165, 168, 174, 175, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 169, 165, 165, 165, ++ 165, 165, 165, 169, 171, 172, 171, 165, 165, 165, ++ 176, 173, 177, 168, 174, 174, 175, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 171, 165, 165, ++ 176, 177, 165, 165, 165, 165, 165, 165, 165, 165, ++ ++ 165, 165, 165, 165, 171, 165, 165, 165, 165, 165, ++ 165, 165, 165, 178, 165, 171, 165, 165, 165, 165, ++ 165, 165, 165, 178, 165, 178, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 179, 165, 165, ++ 165, 179, 165, 179, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 0, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165, 165 + } ; + +-static yyconst flex_int16_t yy_nxt[440] = ++static yyconst flex_int16_t yy_nxt[449] = + { 0, +- 12, 13, 14, 13, 15, 16, 12, 17, 18, 12, +- 12, 12, 19, 12, 12, 12, 12, 20, 21, 22, +- 23, 23, 23, 23, 23, 12, 12, 23, 23, 23, +- 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, +- 23, 23, 23, 12, 24, 12, 25, 34, 35, 35, +- 25, 81, 26, 26, 27, 27, 27, 34, 35, 35, +- 82, 28, 36, 36, 36, 53, 54, 29, 28, 28, +- 28, 28, 12, 13, 14, 13, 15, 16, 30, 17, +- 18, 30, 30, 30, 26, 30, 30, 30, 12, 20, +- 21, 22, 31, 31, 31, 31, 31, 32, 12, 31, +- +- 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, +- 31, 31, 31, 31, 31, 12, 24, 12, 36, 36, +- 36, 39, 41, 45, 47, 56, 57, 48, 61, 47, +- 39, 159, 48, 66, 61, 45, 66, 66, 66, 158, +- 46, 40, 49, 59, 50, 157, 51, 49, 52, 50, +- 40, 63, 46, 52, 36, 36, 36, 156, 43, 62, +- 65, 65, 65, 59, 136, 68, 137, 65, 75, 69, +- 69, 69, 70, 71, 65, 65, 65, 65, 70, 71, +- 72, 69, 69, 69, 61, 46, 45, 155, 154, 66, +- 70, 71, 66, 66, 66, 122, 85, 85, 85, 59, +- +- 69, 69, 69, 46, 77, 100, 109, 93, 100, 70, +- 71, 110, 112, 122, 129, 123, 153, 85, 85, 85, +- 135, 135, 135, 148, 148, 160, 135, 135, 135, 152, +- 142, 142, 142, 123, 143, 142, 142, 142, 151, 143, +- 150, 146, 145, 149, 149, 38, 38, 38, 38, 38, +- 38, 38, 38, 42, 144, 141, 140, 42, 42, 44, +- 44, 44, 44, 44, 44, 44, 44, 58, 58, 58, +- 58, 64, 139, 64, 66, 138, 134, 66, 133, 66, +- 66, 67, 132, 131, 67, 67, 67, 67, 73, 130, +- 73, 73, 76, 76, 76, 76, 76, 76, 76, 76, +- +- 78, 78, 78, 78, 78, 78, 78, 78, 91, 160, +- 91, 92, 129, 92, 92, 128, 92, 92, 121, 121, +- 121, 121, 121, 121, 121, 121, 147, 147, 147, 147, +- 147, 147, 147, 147, 127, 126, 125, 124, 61, 61, +- 120, 119, 118, 117, 116, 115, 47, 114, 110, 113, +- 111, 108, 107, 106, 48, 105, 104, 89, 103, 102, +- 101, 99, 98, 97, 96, 95, 94, 79, 77, 90, +- 89, 88, 59, 87, 86, 59, 84, 83, 80, 79, +- 77, 74, 160, 60, 59, 55, 37, 160, 33, 25, +- 26, 25, 11, 160, 160, 160, 160, 160, 160, 160, +- +- 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, +- 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, +- 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, +- 160, 160, 160, 160, 160, 160, 160, 160, 160 ++ 10, 11, 12, 11, 13, 14, 10, 15, 16, 10, ++ 10, 10, 17, 10, 10, 10, 10, 18, 19, 20, ++ 21, 21, 21, 21, 21, 10, 10, 21, 21, 21, ++ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, ++ 21, 21, 21, 21, 10, 22, 10, 24, 25, 25, ++ 25, 32, 33, 33, 164, 26, 34, 34, 34, 52, ++ 53, 27, 26, 26, 26, 26, 10, 11, 12, 11, ++ 13, 14, 28, 15, 16, 28, 28, 28, 24, 28, ++ 28, 28, 10, 18, 19, 20, 29, 29, 29, 29, ++ 29, 30, 10, 29, 29, 29, 29, 29, 29, 29, ++ ++ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, ++ 10, 22, 10, 23, 34, 34, 34, 37, 39, 43, ++ 32, 33, 33, 45, 55, 56, 46, 60, 43, 45, ++ 65, 163, 46, 65, 65, 65, 44, 38, 60, 74, ++ 58, 47, 141, 48, 142, 44, 49, 47, 50, 48, ++ 76, 51, 62, 94, 50, 41, 44, 51, 37, 61, ++ 64, 64, 64, 58, 34, 34, 34, 64, 162, 80, ++ 67, 68, 68, 68, 64, 64, 64, 64, 38, 81, ++ 69, 70, 71, 68, 68, 68, 60, 161, 43, 69, ++ 70, 65, 69, 70, 65, 65, 65, 125, 85, 85, ++ ++ 85, 58, 68, 68, 68, 44, 102, 110, 125, 133, ++ 102, 69, 70, 111, 114, 160, 159, 126, 85, 85, ++ 85, 140, 140, 140, 140, 140, 140, 153, 126, 147, ++ 147, 147, 153, 148, 147, 147, 147, 158, 148, 165, ++ 157, 156, 155, 151, 150, 149, 146, 154, 145, 144, ++ 143, 139, 154, 36, 36, 36, 36, 36, 36, 36, ++ 36, 40, 138, 137, 136, 40, 40, 42, 42, 42, ++ 42, 42, 42, 42, 42, 57, 57, 57, 57, 63, ++ 135, 63, 65, 134, 165, 65, 133, 65, 65, 66, ++ 132, 131, 66, 66, 66, 66, 72, 130, 72, 72, ++ ++ 75, 75, 75, 75, 75, 75, 75, 75, 77, 77, ++ 77, 77, 77, 77, 77, 77, 91, 129, 91, 92, ++ 128, 92, 92, 127, 92, 92, 124, 124, 124, 124, ++ 124, 124, 124, 124, 152, 152, 152, 152, 152, 152, ++ 152, 152, 60, 60, 123, 122, 121, 120, 119, 118, ++ 117, 45, 116, 111, 115, 113, 112, 109, 108, 107, ++ 46, 106, 93, 89, 105, 104, 103, 101, 100, 99, ++ 98, 97, 96, 95, 78, 76, 93, 90, 89, 88, ++ 58, 87, 86, 58, 84, 83, 82, 79, 78, 76, ++ 73, 165, 59, 58, 54, 35, 165, 31, 23, 23, ++ ++ 9, 165, 165, 165, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165 + } ; + +-static yyconst flex_int16_t yy_chk[440] = ++static yyconst flex_int16_t yy_chk[449] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 4, 9, 9, 9, +- 10, 50, 4, 5, 5, 5, 5, 10, 10, 10, +- 50, 5, 13, 13, 13, 20, 20, 5, 5, 5, +- 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, +- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, +- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, +- +- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, +- 7, 7, 7, 7, 7, 7, 7, 7, 14, 14, +- 14, 16, 17, 18, 19, 22, 22, 19, 25, 26, +- 38, 158, 26, 31, 33, 44, 31, 31, 31, 157, +- 18, 16, 19, 31, 19, 156, 19, 26, 19, 26, +- 38, 26, 44, 26, 36, 36, 36, 155, 17, 25, +- 28, 28, 28, 28, 130, 33, 130, 28, 46, 34, +- 34, 34, 91, 91, 28, 28, 28, 28, 34, 34, +- 34, 35, 35, 35, 61, 46, 75, 152, 151, 67, +- 35, 35, 67, 67, 67, 112, 61, 61, 61, 67, +- +- 69, 69, 69, 75, 77, 85, 98, 77, 100, 69, +- 69, 98, 100, 121, 129, 112, 150, 85, 85, 85, +- 135, 135, 135, 143, 147, 149, 129, 129, 129, 146, +- 138, 138, 138, 121, 138, 142, 142, 142, 145, 142, +- 144, 141, 140, 143, 147, 161, 161, 161, 161, 161, +- 161, 161, 161, 162, 139, 137, 136, 162, 162, 163, +- 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, +- 164, 165, 134, 165, 166, 133, 128, 166, 127, 166, +- 166, 167, 126, 125, 167, 167, 167, 167, 168, 124, +- 168, 168, 169, 169, 169, 169, 169, 169, 169, 169, +- +- 170, 170, 170, 170, 170, 170, 170, 170, 171, 123, +- 171, 172, 122, 172, 172, 120, 172, 172, 173, 173, +- 173, 173, 173, 173, 173, 173, 174, 174, 174, 174, +- 174, 174, 174, 174, 119, 118, 117, 116, 114, 113, +- 111, 110, 109, 108, 107, 106, 105, 103, 102, 101, +- 99, 97, 96, 95, 94, 93, 92, 90, 88, 87, +- 86, 84, 83, 82, 81, 80, 79, 78, 76, 71, +- 70, 68, 65, 63, 62, 58, 52, 51, 49, 48, +- 47, 43, 40, 24, 23, 21, 15, 11, 8, 6, +- 3, 2, 160, 160, 160, 160, 160, 160, 160, 160, +- +- 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, +- 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, +- 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, +- 160, 160, 160, 160, 160, 160, 160, 160, 160 ++ 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, ++ 3, 7, 7, 7, 163, 3, 11, 11, 11, 18, ++ 18, 3, 3, 3, 3, 3, 5, 5, 5, 5, ++ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, ++ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, ++ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, ++ ++ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, ++ 5, 5, 5, 8, 12, 12, 12, 14, 15, 16, ++ 8, 8, 8, 17, 20, 20, 17, 23, 42, 24, ++ 29, 162, 24, 29, 29, 29, 16, 14, 31, 44, ++ 29, 17, 134, 17, 134, 42, 17, 24, 17, 24, ++ 76, 17, 24, 76, 24, 15, 44, 24, 36, 23, ++ 26, 26, 26, 26, 34, 34, 34, 26, 161, 48, ++ 31, 32, 32, 32, 26, 26, 26, 26, 36, 48, ++ 32, 32, 32, 33, 33, 33, 60, 160, 74, 91, ++ 91, 66, 33, 33, 66, 66, 66, 114, 60, 60, ++ ++ 60, 66, 68, 68, 68, 74, 85, 99, 124, 133, ++ 102, 68, 68, 99, 102, 157, 156, 114, 85, 85, ++ 85, 133, 133, 133, 140, 140, 140, 148, 124, 143, ++ 143, 143, 152, 143, 147, 147, 147, 155, 147, 154, ++ 151, 150, 149, 146, 145, 144, 142, 148, 141, 138, ++ 137, 132, 152, 166, 166, 166, 166, 166, 166, 166, ++ 166, 167, 131, 130, 129, 167, 167, 168, 168, 168, ++ 168, 168, 168, 168, 168, 169, 169, 169, 169, 170, ++ 128, 170, 171, 127, 126, 171, 125, 171, 171, 172, ++ 123, 122, 172, 172, 172, 172, 173, 121, 173, 173, ++ ++ 174, 174, 174, 174, 174, 174, 174, 174, 175, 175, ++ 175, 175, 175, 175, 175, 175, 176, 120, 176, 177, ++ 119, 177, 177, 118, 177, 177, 178, 178, 178, 178, ++ 178, 178, 178, 178, 179, 179, 179, 179, 179, 179, ++ 179, 179, 116, 115, 113, 112, 111, 110, 109, 108, ++ 107, 106, 105, 104, 103, 101, 100, 98, 97, 96, ++ 95, 94, 92, 90, 88, 87, 86, 84, 83, 82, ++ 81, 80, 79, 78, 77, 75, 73, 70, 69, 67, ++ 64, 62, 61, 57, 51, 50, 49, 47, 46, 45, ++ 41, 38, 22, 21, 19, 13, 9, 6, 4, 2, ++ ++ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165 + } ; + + static yy_state_type yy_last_accepting_state; +@@ -631,13 +634,13 @@ char *yytext; + + + +- +-#line 38 "dtc-lexer.l" ++#line 37 "dtc-lexer.l" + #include "dtc.h" + #include "srcpos.h" + #include "dtc-parser.tab.h" + + YYLTYPE yylloc; ++extern bool treesource_error; + + /* CAUTION: this will stop working if we ever use yyless() or yyunput() */ + #define YY_USER_ACTION \ +@@ -659,14 +662,14 @@ static int dts_version = 1; + BEGIN(V1); \ + + static void push_input_file(const char *filename); +-static int pop_input_file(void); +-#line 664 "dtc-lexer.lex.c" ++static bool pop_input_file(void); ++static void lexical_error(const char *fmt, ...); ++#line 668 "dtc-lexer.lex.c" + + #define INITIAL 0 +-#define INCLUDE 1 +-#define BYTESTRING 2 +-#define PROPNODENAME 3 +-#define V1 4 ++#define BYTESTRING 1 ++#define PROPNODENAME 2 ++#define V1 3 + + #ifndef YY_NO_UNISTD_H + /* Special case for "unistd.h", since it is non-ANSI. We include it way +@@ -852,9 +855,9 @@ YY_DECL + register char *yy_cp, *yy_bp; + register int yy_act; + +-#line 67 "dtc-lexer.l" ++#line 68 "dtc-lexer.l" + +-#line 858 "dtc-lexer.lex.c" ++#line 861 "dtc-lexer.lex.c" + + if ( !(yy_init) ) + { +@@ -908,13 +911,13 @@ yy_match: + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; +- if ( yy_current_state >= 161 ) ++ if ( yy_current_state >= 166 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } +- while ( yy_current_state != 160 ); ++ while ( yy_current_state != 165 ); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + +@@ -937,7 +940,7 @@ do_action: /* This label is used only to access EOF actions. */ + case 1: + /* rule 1 can match eol */ + YY_RULE_SETUP +-#line 68 "dtc-lexer.l" ++#line 69 "dtc-lexer.l" + { + char *name = strchr(yytext, '\"') + 1; + yytext[yyleng-1] = '\0'; +@@ -947,16 +950,16 @@ YY_RULE_SETUP + case 2: + /* rule 2 can match eol */ + YY_RULE_SETUP +-#line 74 "dtc-lexer.l" ++#line 75 "dtc-lexer.l" + { + char *line, *tmp, *fn; + /* skip text before line # */ + line = yytext; +- while (!isdigit(*line)) ++ while (!isdigit((unsigned char)*line)) + line++; + /* skip digits in line # */ + tmp = line; +- while (!isspace(*tmp)) ++ while (!isspace((unsigned char)*tmp)) + tmp++; + /* "NULL"-terminate line # */ + *tmp = '\0'; +@@ -970,11 +973,10 @@ YY_RULE_SETUP + } + YY_BREAK + case YY_STATE_EOF(INITIAL): +-case YY_STATE_EOF(INCLUDE): + case YY_STATE_EOF(BYTESTRING): + case YY_STATE_EOF(PROPNODENAME): + case YY_STATE_EOF(V1): +-#line 95 "dtc-lexer.l" ++#line 96 "dtc-lexer.l" + { + if (!pop_input_file()) { + yyterminate(); +@@ -984,7 +986,7 @@ case YY_STATE_EOF(V1): + case 3: + /* rule 3 can match eol */ + YY_RULE_SETUP +-#line 101 "dtc-lexer.l" ++#line 102 "dtc-lexer.l" + { + DPRINT("String: %s\n", yytext); + yylval.data = data_copy_escape_string(yytext+1, +@@ -994,7 +996,7 @@ YY_RULE_SETUP + YY_BREAK + case 4: + YY_RULE_SETUP +-#line 108 "dtc-lexer.l" ++#line 109 "dtc-lexer.l" + { + DPRINT("Keyword: /dts-v1/\n"); + dts_version = 1; +@@ -1004,25 +1006,33 @@ YY_RULE_SETUP + YY_BREAK + case 5: + YY_RULE_SETUP +-#line 115 "dtc-lexer.l" ++#line 116 "dtc-lexer.l" ++{ ++ DPRINT("Keyword: /plugin/\n"); ++ return DT_PLUGIN; ++ } ++ YY_BREAK ++case 6: ++YY_RULE_SETUP ++#line 121 "dtc-lexer.l" + { + DPRINT("Keyword: /memreserve/\n"); + BEGIN_DEFAULT(); + return DT_MEMRESERVE; + } + YY_BREAK +-case 6: ++case 7: + YY_RULE_SETUP +-#line 121 "dtc-lexer.l" ++#line 127 "dtc-lexer.l" + { + DPRINT("Keyword: /bits/\n"); + BEGIN_DEFAULT(); + return DT_BITS; + } + YY_BREAK +-case 7: ++case 8: + YY_RULE_SETUP +-#line 127 "dtc-lexer.l" ++#line 133 "dtc-lexer.l" + { + DPRINT("Keyword: /delete-property/\n"); + DPRINT("\n"); +@@ -1030,9 +1040,9 @@ YY_RULE_SETUP + return DT_DEL_PROP; + } + YY_BREAK +-case 8: ++case 9: + YY_RULE_SETUP +-#line 134 "dtc-lexer.l" ++#line 140 "dtc-lexer.l" + { + DPRINT("Keyword: /delete-node/\n"); + DPRINT("\n"); +@@ -1040,9 +1050,9 @@ YY_RULE_SETUP + return DT_DEL_NODE; + } + YY_BREAK +-case 9: ++case 10: + YY_RULE_SETUP +-#line 141 "dtc-lexer.l" ++#line 147 "dtc-lexer.l" + { + DPRINT("Label: %s\n", yytext); + yylval.labelref = xstrdup(yytext); +@@ -1050,38 +1060,65 @@ YY_RULE_SETUP + return DT_LABEL; + } + YY_BREAK +-case 10: ++case 11: + YY_RULE_SETUP +-#line 148 "dtc-lexer.l" ++#line 154 "dtc-lexer.l" + { +- yylval.literal = xstrdup(yytext); +- DPRINT("Literal: '%s'\n", yylval.literal); ++ char *e; ++ DPRINT("Integer Literal: '%s'\n", yytext); ++ ++ errno = 0; ++ yylval.integer = strtoull(yytext, &e, 0); ++ ++ assert(!(*e) || !e[strspn(e, "UL")]); ++ ++ if (errno == ERANGE) ++ lexical_error("Integer literal '%s' out of range", ++ yytext); ++ else ++ /* ERANGE is the only strtoull error triggerable ++ * by strings matching the pattern */ ++ assert(errno == 0); + return DT_LITERAL; + } + YY_BREAK +-case 11: +-/* rule 11 can match eol */ ++case 12: ++/* rule 12 can match eol */ + YY_RULE_SETUP +-#line 154 "dtc-lexer.l" ++#line 173 "dtc-lexer.l" + { +- yytext[yyleng-1] = '\0'; +- yylval.literal = xstrdup(yytext+1); +- DPRINT("Character literal: %s\n", yylval.literal); ++ struct data d; ++ DPRINT("Character literal: %s\n", yytext); ++ ++ d = data_copy_escape_string(yytext+1, yyleng-2); ++ if (d.len == 1) { ++ lexical_error("Empty character literal"); ++ yylval.integer = 0; ++ return DT_CHAR_LITERAL; ++ } ++ ++ yylval.integer = (unsigned char)d.val[0]; ++ ++ if (d.len > 2) ++ lexical_error("Character literal has %d" ++ " characters instead of 1", ++ d.len - 1); ++ + return DT_CHAR_LITERAL; + } + YY_BREAK +-case 12: ++case 13: + YY_RULE_SETUP +-#line 161 "dtc-lexer.l" ++#line 194 "dtc-lexer.l" + { /* label reference */ + DPRINT("Ref: %s\n", yytext+1); + yylval.labelref = xstrdup(yytext+1); + return DT_REF; + } + YY_BREAK +-case 13: ++case 14: + YY_RULE_SETUP +-#line 167 "dtc-lexer.l" ++#line 200 "dtc-lexer.l" + { /* new-style path reference */ + yytext[yyleng-1] = '\0'; + DPRINT("Ref: %s\n", yytext+2); +@@ -1089,27 +1126,27 @@ YY_RULE_SETUP + return DT_REF; + } + YY_BREAK +-case 14: ++case 15: + YY_RULE_SETUP +-#line 174 "dtc-lexer.l" ++#line 207 "dtc-lexer.l" + { + yylval.byte = strtol(yytext, NULL, 16); + DPRINT("Byte: %02x\n", (int)yylval.byte); + return DT_BYTE; + } + YY_BREAK +-case 15: ++case 16: + YY_RULE_SETUP +-#line 180 "dtc-lexer.l" ++#line 213 "dtc-lexer.l" + { + DPRINT("/BYTESTRING\n"); + BEGIN_DEFAULT(); + return ']'; + } + YY_BREAK +-case 16: ++case 17: + YY_RULE_SETUP +-#line 186 "dtc-lexer.l" ++#line 219 "dtc-lexer.l" + { + DPRINT("PropNodeName: %s\n", yytext); + yylval.propnodename = xstrdup((yytext[0] == '\\') ? +@@ -1118,75 +1155,75 @@ YY_RULE_SETUP + return DT_PROPNODENAME; + } + YY_BREAK +-case 17: ++case 18: + YY_RULE_SETUP +-#line 194 "dtc-lexer.l" ++#line 227 "dtc-lexer.l" + { + DPRINT("Binary Include\n"); + return DT_INCBIN; + } + YY_BREAK +-case 18: +-/* rule 18 can match eol */ +-YY_RULE_SETUP +-#line 199 "dtc-lexer.l" +-/* eat whitespace */ +- YY_BREAK + case 19: + /* rule 19 can match eol */ + YY_RULE_SETUP +-#line 200 "dtc-lexer.l" +-/* eat C-style comments */ ++#line 232 "dtc-lexer.l" ++/* eat whitespace */ + YY_BREAK + case 20: + /* rule 20 can match eol */ + YY_RULE_SETUP +-#line 201 "dtc-lexer.l" +-/* eat C++-style comments */ ++#line 233 "dtc-lexer.l" ++/* eat C-style comments */ + YY_BREAK + case 21: ++/* rule 21 can match eol */ + YY_RULE_SETUP +-#line 203 "dtc-lexer.l" +-{ return DT_LSHIFT; }; ++#line 234 "dtc-lexer.l" ++/* eat C++-style comments */ + YY_BREAK + case 22: + YY_RULE_SETUP +-#line 204 "dtc-lexer.l" +-{ return DT_RSHIFT; }; ++#line 236 "dtc-lexer.l" ++{ return DT_LSHIFT; }; + YY_BREAK + case 23: + YY_RULE_SETUP +-#line 205 "dtc-lexer.l" +-{ return DT_LE; }; ++#line 237 "dtc-lexer.l" ++{ return DT_RSHIFT; }; + YY_BREAK + case 24: + YY_RULE_SETUP +-#line 206 "dtc-lexer.l" +-{ return DT_GE; }; ++#line 238 "dtc-lexer.l" ++{ return DT_LE; }; + YY_BREAK + case 25: + YY_RULE_SETUP +-#line 207 "dtc-lexer.l" +-{ return DT_EQ; }; ++#line 239 "dtc-lexer.l" ++{ return DT_GE; }; + YY_BREAK + case 26: + YY_RULE_SETUP +-#line 208 "dtc-lexer.l" +-{ return DT_NE; }; ++#line 240 "dtc-lexer.l" ++{ return DT_EQ; }; + YY_BREAK + case 27: + YY_RULE_SETUP +-#line 209 "dtc-lexer.l" +-{ return DT_AND; }; ++#line 241 "dtc-lexer.l" ++{ return DT_NE; }; + YY_BREAK + case 28: + YY_RULE_SETUP +-#line 210 "dtc-lexer.l" +-{ return DT_OR; }; ++#line 242 "dtc-lexer.l" ++{ return DT_AND; }; + YY_BREAK + case 29: + YY_RULE_SETUP +-#line 212 "dtc-lexer.l" ++#line 243 "dtc-lexer.l" ++{ return DT_OR; }; ++ YY_BREAK ++case 30: ++YY_RULE_SETUP ++#line 245 "dtc-lexer.l" + { + DPRINT("Char: %c (\\x%02x)\n", yytext[0], + (unsigned)yytext[0]); +@@ -1202,12 +1239,12 @@ YY_RULE_SETUP + return yytext[0]; + } + YY_BREAK +-case 30: ++case 31: + YY_RULE_SETUP +-#line 227 "dtc-lexer.l" ++#line 260 "dtc-lexer.l" + ECHO; + YY_BREAK +-#line 1211 "dtc-lexer.lex.c" ++#line 1248 "dtc-lexer.lex.c" + + case YY_END_OF_BUFFER: + { +@@ -1499,7 +1536,7 @@ static int yy_get_next_buffer (void) + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; +- if ( yy_current_state >= 161 ) ++ if ( yy_current_state >= 166 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; +@@ -1527,11 +1564,11 @@ static int yy_get_next_buffer (void) + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; +- if ( yy_current_state >= 161 ) ++ if ( yy_current_state >= 166 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; +- yy_is_jam = (yy_current_state == 160); ++ yy_is_jam = (yy_current_state == 165); + + return yy_is_jam ? 0 : yy_current_state; + } +@@ -2166,7 +2203,7 @@ void yyfree (void * ptr ) + + #define YYTABLES_NAME "yytables" + +-#line 227 "dtc-lexer.l" ++#line 260 "dtc-lexer.l" + + + +@@ -2182,14 +2219,25 @@ static void push_input_file(const char *filename) + } + + +-static int pop_input_file(void) ++static bool pop_input_file(void) + { + if (srcfile_pop() == 0) +- return 0; ++ return false; + + yypop_buffer_state(); + yyin = current_srcfile->f; + +- return 1; ++ return true; ++} ++ ++static void lexical_error(const char *fmt, ...) ++{ ++ va_list ap; ++ ++ va_start(ap, fmt); ++ srcpos_verror(&yylloc, "Lexical error", fmt, ap); ++ va_end(ap); ++ ++ treesource_error = true; + } + +diff --git a/scripts/dtc/dtc-parser.tab.c_shipped b/scripts/dtc/dtc-parser.tab.c_shipped +index c8769d5..1938d20 100644 +--- a/scripts/dtc/dtc-parser.tab.c_shipped ++++ b/scripts/dtc/dtc-parser.tab.c_shipped +@@ -1,19 +1,19 @@ +-/* A Bison parser, made by GNU Bison 2.7.12-4996. */ ++/* A Bison parser, made by GNU Bison 3.0.2. */ + + /* Bison implementation for Yacc-like parsers in C +- +- Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. +- ++ ++ Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. ++ + 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 3 of the License, or + (at your option) any later version. +- ++ + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. +- ++ + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +@@ -26,7 +26,7 @@ + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. +- ++ + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +@@ -44,7 +44,7 @@ + #define YYBISON 1 + + /* Bison version. */ +-#define YYBISON_VERSION "2.7.12-4996" ++#define YYBISON_VERSION "3.0.2" + + /* Skeleton name. */ + #define YYSKELETON_NAME "yacc.c" +@@ -62,34 +62,32 @@ + + + /* Copy the first part of user declarations. */ +-/* Line 371 of yacc.c */ +-#line 21 "dtc-parser.y" ++#line 20 "dtc-parser.y" /* yacc.c:339 */ + + #include ++#include + + #include "dtc.h" + #include "srcpos.h" + +-YYLTYPE yylloc; +- + extern int yylex(void); +-extern void print_error(char const *fmt, ...); + extern void yyerror(char const *s); ++#define ERROR(loc, ...) \ ++ do { \ ++ srcpos_error((loc), "Error", __VA_ARGS__); \ ++ treesource_error = true; \ ++ } while (0) + + extern struct boot_info *the_boot_info; +-extern int treesource_error; +- +-static unsigned long long eval_literal(const char *s, int base, int bits); +-static unsigned char eval_char_literal(const char *s); ++extern bool treesource_error; + +-/* Line 371 of yacc.c */ +-#line 87 "dtc-parser.tab.c" ++#line 85 "dtc-parser.tab.c" /* yacc.c:339 */ + +-# ifndef YY_NULL ++# ifndef YY_NULLPTR + # if defined __cplusplus && 201103L <= __cplusplus +-# define YY_NULL nullptr ++# define YY_NULLPTR nullptr + # else +-# define YY_NULL 0 ++# define YY_NULLPTR 0 + # endif + # endif + +@@ -105,7 +103,7 @@ static unsigned char eval_char_literal(const char *s); + by #include "dtc-parser.tab.h". */ + #ifndef YY_YY_DTC_PARSER_TAB_H_INCLUDED + # define YY_YY_DTC_PARSER_TAB_H_INCLUDED +-/* Enabling traces. */ ++/* Debug traces. */ + #ifndef YYDEBUG + # define YYDEBUG 0 + #endif +@@ -113,48 +111,45 @@ static unsigned char eval_char_literal(const char *s); + extern int yydebug; + #endif + +-/* Tokens. */ ++/* Token type. */ + #ifndef YYTOKENTYPE + # define YYTOKENTYPE +- /* Put the tokens into the symbol table, so that GDB and other debuggers +- know about them. */ +- enum yytokentype { +- DT_V1 = 258, +- DT_MEMRESERVE = 259, +- DT_LSHIFT = 260, +- DT_RSHIFT = 261, +- DT_LE = 262, +- DT_GE = 263, +- DT_EQ = 264, +- DT_NE = 265, +- DT_AND = 266, +- DT_OR = 267, +- DT_BITS = 268, +- DT_DEL_PROP = 269, +- DT_DEL_NODE = 270, +- DT_PROPNODENAME = 271, +- DT_LITERAL = 272, +- DT_CHAR_LITERAL = 273, +- DT_BASE = 274, +- DT_BYTE = 275, +- DT_STRING = 276, +- DT_LABEL = 277, +- DT_REF = 278, +- DT_INCBIN = 279 +- }; ++ enum yytokentype ++ { ++ DT_V1 = 258, ++ DT_PLUGIN = 259, ++ DT_MEMRESERVE = 260, ++ DT_LSHIFT = 261, ++ DT_RSHIFT = 262, ++ DT_LE = 263, ++ DT_GE = 264, ++ DT_EQ = 265, ++ DT_NE = 266, ++ DT_AND = 267, ++ DT_OR = 268, ++ DT_BITS = 269, ++ DT_DEL_PROP = 270, ++ DT_DEL_NODE = 271, ++ DT_PROPNODENAME = 272, ++ DT_LITERAL = 273, ++ DT_CHAR_LITERAL = 274, ++ DT_BYTE = 275, ++ DT_STRING = 276, ++ DT_LABEL = 277, ++ DT_REF = 278, ++ DT_INCBIN = 279 ++ }; + #endif + +- ++/* Value type. */ + #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +-typedef union YYSTYPE ++typedef union YYSTYPE YYSTYPE; ++union YYSTYPE + { +-/* Line 387 of yacc.c */ +-#line 40 "dtc-parser.y" ++#line 39 "dtc-parser.y" /* yacc.c:355 */ + + char *propnodename; +- char *literal; + char *labelref; +- unsigned int cbase; + uint8_t byte; + struct data data; + +@@ -169,38 +164,38 @@ typedef union YYSTYPE + struct node *nodelist; + struct reserve_info *re; + uint64_t integer; ++ int is_plugin; + +- +-/* Line 387 of yacc.c */ +-#line 176 "dtc-parser.tab.c" +-} YYSTYPE; ++#line 170 "dtc-parser.tab.c" /* yacc.c:355 */ ++}; + # define YYSTYPE_IS_TRIVIAL 1 +-# define yystype YYSTYPE /* obsolescent; will be withdrawn */ + # define YYSTYPE_IS_DECLARED 1 + #endif + +-extern YYSTYPE yylval; +- +-#ifdef YYPARSE_PARAM +-#if defined __STDC__ || defined __cplusplus +-int yyparse (void *YYPARSE_PARAM); +-#else +-int yyparse (); ++/* Location type. */ ++#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED ++typedef struct YYLTYPE YYLTYPE; ++struct YYLTYPE ++{ ++ int first_line; ++ int first_column; ++ int last_line; ++ int last_column; ++}; ++# define YYLTYPE_IS_DECLARED 1 ++# define YYLTYPE_IS_TRIVIAL 1 + #endif +-#else /* ! YYPARSE_PARAM */ +-#if defined __STDC__ || defined __cplusplus ++ ++ ++extern YYSTYPE yylval; ++extern YYLTYPE yylloc; + int yyparse (void); +-#else +-int yyparse (); +-#endif +-#endif /* ! YYPARSE_PARAM */ + + #endif /* !YY_YY_DTC_PARSER_TAB_H_INCLUDED */ + + /* Copy the second part of user declarations. */ + +-/* Line 390 of yacc.c */ +-#line 204 "dtc-parser.tab.c" ++#line 199 "dtc-parser.tab.c" /* yacc.c:358 */ + + #ifdef short + # undef short +@@ -214,11 +209,8 @@ typedef unsigned char yytype_uint8; + + #ifdef YYTYPE_INT8 + typedef YYTYPE_INT8 yytype_int8; +-#elif (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-typedef signed char yytype_int8; + #else +-typedef short int yytype_int8; ++typedef signed char yytype_int8; + #endif + + #ifdef YYTYPE_UINT16 +@@ -238,8 +230,7 @@ typedef short int yytype_int16; + # define YYSIZE_T __SIZE_TYPE__ + # elif defined size_t + # define YYSIZE_T size_t +-# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) ++# elif ! defined YYSIZE_T + # include /* INFRINGES ON USER NAME SPACE */ + # define YYSIZE_T size_t + # else +@@ -261,11 +252,30 @@ typedef short int yytype_int16; + # endif + #endif + +-#ifndef __attribute__ +-/* This feature is available in gcc versions 2.5 and later. */ +-# if (! defined __GNUC__ || __GNUC__ < 2 \ +- || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)) +-# define __attribute__(Spec) /* empty */ ++#ifndef YY_ATTRIBUTE ++# if (defined __GNUC__ \ ++ && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ ++ || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C ++# define YY_ATTRIBUTE(Spec) __attribute__(Spec) ++# else ++# define YY_ATTRIBUTE(Spec) /* empty */ ++# endif ++#endif ++ ++#ifndef YY_ATTRIBUTE_PURE ++# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) ++#endif ++ ++#ifndef YY_ATTRIBUTE_UNUSED ++# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) ++#endif ++ ++#if !defined _Noreturn \ ++ && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) ++# if defined _MSC_VER && 1200 <= _MSC_VER ++# define _Noreturn __declspec (noreturn) ++# else ++# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) + # endif + #endif + +@@ -276,25 +286,26 @@ typedef short int yytype_int16; + # define YYUSE(E) /* empty */ + #endif + +- +-/* Identity function, used to suppress warnings about constant conditions. */ +-#ifndef lint +-# define YYID(N) (N) +-#else +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static int +-YYID (int yyi) ++#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ ++/* Suppress an incorrect diagnostic about yylval being uninitialized. */ ++# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ ++ _Pragma ("GCC diagnostic push") \ ++ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ ++ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") ++# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ ++ _Pragma ("GCC diagnostic pop") + #else +-static int +-YYID (yyi) +- int yyi; ++# define YY_INITIAL_VALUE(Value) Value + #endif +-{ +- return yyi; +-} ++#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN ++# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN ++# define YY_IGNORE_MAYBE_UNINITIALIZED_END ++#endif ++#ifndef YY_INITIAL_VALUE ++# define YY_INITIAL_VALUE(Value) /* Nothing. */ + #endif + ++ + #if ! defined yyoverflow || YYERROR_VERBOSE + + /* The parser invokes alloca or malloc; define the necessary symbols. */ +@@ -312,8 +323,7 @@ YYID (yyi) + # define alloca _alloca + # else + # define YYSTACK_ALLOC alloca +-# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) ++# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS + # include /* INFRINGES ON USER NAME SPACE */ + /* Use EXIT_SUCCESS as a witness for stdlib.h. */ + # ifndef EXIT_SUCCESS +@@ -325,8 +335,8 @@ YYID (yyi) + # endif + + # ifdef YYSTACK_ALLOC +- /* Pacify GCC's `empty if-body' warning. */ +-# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) ++ /* Pacify GCC's 'empty if-body' warning. */ ++# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) + # ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely +@@ -342,7 +352,7 @@ YYID (yyi) + # endif + # if (defined __cplusplus && ! defined EXIT_SUCCESS \ + && ! ((defined YYMALLOC || defined malloc) \ +- && (defined YYFREE || defined free))) ++ && (defined YYFREE || defined free))) + # include /* INFRINGES ON USER NAME SPACE */ + # ifndef EXIT_SUCCESS + # define EXIT_SUCCESS 0 +@@ -350,15 +360,13 @@ YYID (yyi) + # endif + # ifndef YYMALLOC + # define YYMALLOC malloc +-# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) ++# if ! defined malloc && ! defined EXIT_SUCCESS + void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ + # endif + # endif + # ifndef YYFREE + # define YYFREE free +-# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) ++# if ! defined free && ! defined EXIT_SUCCESS + void free (void *); /* INFRINGES ON USER NAME SPACE */ + # endif + # endif +@@ -368,13 +376,15 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ + + #if (! defined yyoverflow \ + && (! defined __cplusplus \ +- || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) ++ || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ ++ && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + + /* A type that is properly aligned for any stack member. */ + union yyalloc + { + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; ++ YYLTYPE yyls_alloc; + }; + + /* The size of the maximum gap between one aligned stack and the next. */ +@@ -383,8 +393,8 @@ union yyalloc + /* The size of an array large to enough to hold all stacks, each with + N elements. */ + # define YYSTACK_BYTES(N) \ +- ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ +- + YYSTACK_GAP_MAXIMUM) ++ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ ++ + 2 * YYSTACK_GAP_MAXIMUM) + + # define YYCOPY_NEEDED 1 + +@@ -393,16 +403,16 @@ union yyalloc + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +-# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ +- do \ +- { \ +- YYSIZE_T yynewbytes; \ +- YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ +- Stack = &yyptr->Stack_alloc; \ +- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ +- yyptr += yynewbytes / sizeof (*yyptr); \ +- } \ +- while (YYID (0)) ++# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ ++ do \ ++ { \ ++ YYSIZE_T yynewbytes; \ ++ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ ++ Stack = &yyptr->Stack_alloc; \ ++ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ ++ yyptr += yynewbytes / sizeof (*yyptr); \ ++ } \ ++ while (0) + + #endif + +@@ -421,7 +431,7 @@ union yyalloc + for (yyi = 0; yyi < (Count); yyi++) \ + (Dst)[yyi] = (Src)[yyi]; \ + } \ +- while (YYID (0)) ++ while (0) + # endif + # endif + #endif /* !YYCOPY_NEEDED */ +@@ -429,25 +439,27 @@ union yyalloc + /* YYFINAL -- State number of the termination state. */ + #define YYFINAL 4 + /* YYLAST -- Last index in YYTABLE. */ +-#define YYLAST 133 ++#define YYLAST 135 + + /* YYNTOKENS -- Number of terminals. */ + #define YYNTOKENS 48 + /* YYNNTS -- Number of nonterminals. */ +-#define YYNNTS 28 ++#define YYNNTS 29 + /* YYNRULES -- Number of rules. */ +-#define YYNRULES 79 +-/* YYNRULES -- Number of states. */ +-#define YYNSTATES 141 ++#define YYNRULES 81 ++/* YYNSTATES -- Number of states. */ ++#define YYNSTATES 144 + +-/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ ++/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned ++ by yylex, with out-of-bounds checking. */ + #define YYUNDEFTOK 2 + #define YYMAXUTOK 279 + +-#define YYTRANSLATE(YYX) \ ++#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +-/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ ++/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM ++ as returned by yylex, without out-of-bounds checking. */ + static const yytype_uint8 yytranslate[] = + { + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, +@@ -481,63 +493,18 @@ static const yytype_uint8 yytranslate[] = + }; + + #if YYDEBUG +-/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in +- YYRHS. */ +-static const yytype_uint16 yyprhs[] = +-{ +- 0, 0, 3, 8, 9, 12, 17, 20, 23, 27, +- 31, 36, 42, 43, 46, 51, 54, 58, 61, 64, +- 68, 73, 76, 86, 92, 95, 96, 99, 102, 106, +- 108, 111, 114, 117, 119, 121, 125, 127, 129, 135, +- 137, 141, 143, 147, 149, 153, 155, 159, 161, 165, +- 167, 171, 175, 177, 181, 185, 189, 193, 197, 201, +- 203, 207, 211, 213, 217, 221, 225, 227, 229, 232, +- 235, 238, 239, 242, 245, 246, 249, 252, 255, 259 +-}; +- +-/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +-static const yytype_int8 yyrhs[] = +-{ +- 49, 0, -1, 3, 25, 50, 52, -1, -1, 51, +- 50, -1, 4, 59, 59, 25, -1, 22, 51, -1, +- 26, 53, -1, 52, 26, 53, -1, 52, 23, 53, +- -1, 52, 15, 23, 25, -1, 27, 54, 74, 28, +- 25, -1, -1, 54, 55, -1, 16, 29, 56, 25, +- -1, 16, 25, -1, 14, 16, 25, -1, 22, 55, +- -1, 57, 21, -1, 57, 58, 30, -1, 57, 31, +- 73, 32, -1, 57, 23, -1, 57, 24, 33, 21, +- 34, 59, 34, 59, 35, -1, 57, 24, 33, 21, +- 35, -1, 56, 22, -1, -1, 56, 34, -1, 57, +- 22, -1, 13, 17, 36, -1, 36, -1, 58, 59, +- -1, 58, 23, -1, 58, 22, -1, 17, -1, 18, +- -1, 33, 60, 35, -1, 61, -1, 62, -1, 62, +- 37, 60, 38, 61, -1, 63, -1, 62, 12, 63, +- -1, 64, -1, 63, 11, 64, -1, 65, -1, 64, +- 39, 65, -1, 66, -1, 65, 40, 66, -1, 67, +- -1, 66, 41, 67, -1, 68, -1, 67, 9, 68, +- -1, 67, 10, 68, -1, 69, -1, 68, 36, 69, +- -1, 68, 30, 69, -1, 68, 7, 69, -1, 68, +- 8, 69, -1, 69, 5, 70, -1, 69, 6, 70, +- -1, 70, -1, 70, 42, 71, -1, 70, 43, 71, +- -1, 71, -1, 71, 44, 72, -1, 71, 26, 72, +- -1, 71, 45, 72, -1, 72, -1, 59, -1, 43, +- 72, -1, 46, 72, -1, 47, 72, -1, -1, 73, +- 20, -1, 73, 22, -1, -1, 75, 74, -1, 75, +- 55, -1, 16, 53, -1, 15, 16, 25, -1, 22, +- 75, -1 +-}; +- +-/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ ++ /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ + static const yytype_uint16 yyrline[] = + { +- 0, 109, 109, 118, 121, 128, 132, 140, 144, 148, +- 158, 172, 180, 183, 190, 194, 198, 202, 210, 214, +- 218, 222, 226, 243, 253, 261, 264, 268, 275, 290, +- 295, 315, 329, 336, 340, 344, 351, 355, 356, 360, +- 361, 365, 366, 370, 371, 375, 376, 380, 381, 385, +- 386, 387, 391, 392, 393, 394, 395, 399, 400, 401, +- 405, 406, 407, 411, 412, 413, 414, 418, 419, 420, +- 421, 426, 429, 433, 441, 444, 448, 456, 460, 464 ++ 0, 108, 108, 119, 122, 130, 133, 140, 144, 152, ++ 156, 160, 170, 185, 193, 196, 203, 207, 211, 215, ++ 223, 227, 231, 235, 239, 255, 265, 273, 276, 280, ++ 287, 303, 308, 327, 341, 348, 349, 350, 357, 361, ++ 362, 366, 367, 371, 372, 376, 377, 381, 382, 386, ++ 387, 391, 392, 393, 397, 398, 399, 400, 401, 405, ++ 406, 407, 411, 412, 413, 417, 418, 419, 420, 424, ++ 425, 426, 427, 432, 435, 439, 447, 450, 454, 462, ++ 466, 470 + }; + #endif + +@@ -546,25 +513,25 @@ static const yytype_uint16 yyrline[] = + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ + static const char *const yytname[] = + { +- "$end", "error", "$undefined", "DT_V1", "DT_MEMRESERVE", "DT_LSHIFT", +- "DT_RSHIFT", "DT_LE", "DT_GE", "DT_EQ", "DT_NE", "DT_AND", "DT_OR", +- "DT_BITS", "DT_DEL_PROP", "DT_DEL_NODE", "DT_PROPNODENAME", "DT_LITERAL", +- "DT_CHAR_LITERAL", "DT_BASE", "DT_BYTE", "DT_STRING", "DT_LABEL", ++ "$end", "error", "$undefined", "DT_V1", "DT_PLUGIN", "DT_MEMRESERVE", ++ "DT_LSHIFT", "DT_RSHIFT", "DT_LE", "DT_GE", "DT_EQ", "DT_NE", "DT_AND", ++ "DT_OR", "DT_BITS", "DT_DEL_PROP", "DT_DEL_NODE", "DT_PROPNODENAME", ++ "DT_LITERAL", "DT_CHAR_LITERAL", "DT_BYTE", "DT_STRING", "DT_LABEL", + "DT_REF", "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='", "'>'", "'['", + "']'", "'('", "','", "')'", "'<'", "'?'", "':'", "'|'", "'^'", "'&'", + "'+'", "'-'", "'*'", "'%'", "'~'", "'!'", "$accept", "sourcefile", +- "memreserves", "memreserve", "devicetree", "nodedef", "proplist", +- "propdef", "propdata", "propdataprefix", "arrayprefix", "integer_prim", +- "integer_expr", "integer_trinary", "integer_or", "integer_and", +- "integer_bitor", "integer_bitxor", "integer_bitand", "integer_eq", +- "integer_rela", "integer_shift", "integer_add", "integer_mul", +- "integer_unary", "bytestring", "subnodes", "subnode", YY_NULL ++ "plugindecl", "memreserves", "memreserve", "devicetree", "nodedef", ++ "proplist", "propdef", "propdata", "propdataprefix", "arrayprefix", ++ "integer_prim", "integer_expr", "integer_trinary", "integer_or", ++ "integer_and", "integer_bitor", "integer_bitxor", "integer_bitand", ++ "integer_eq", "integer_rela", "integer_shift", "integer_add", ++ "integer_mul", "integer_unary", "bytestring", "subnodes", "subnode", YY_NULLPTR + }; + #endif + + # ifdef YYPRINT +-/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to +- token YYLEX-NUM. */ ++/* YYTOKNUM[NUM] -- (External) token number corresponding to the ++ (internal) symbol number NUM (which must be that of a token). */ + static const yytype_uint16 yytoknum[] = + { + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, +@@ -575,183 +542,173 @@ static const yytype_uint16 yytoknum[] = + }; + # endif + +-/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +-static const yytype_uint8 yyr1[] = +-{ +- 0, 48, 49, 50, 50, 51, 51, 52, 52, 52, +- 52, 53, 54, 54, 55, 55, 55, 55, 56, 56, +- 56, 56, 56, 56, 56, 57, 57, 57, 58, 58, +- 58, 58, 58, 59, 59, 59, 60, 61, 61, 62, +- 62, 63, 63, 64, 64, 65, 65, 66, 66, 67, +- 67, 67, 68, 68, 68, 68, 68, 69, 69, 69, +- 70, 70, 70, 71, 71, 71, 71, 72, 72, 72, +- 72, 73, 73, 73, 74, 74, 74, 75, 75, 75 +-}; ++#define YYPACT_NINF -41 + +-/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +-static const yytype_uint8 yyr2[] = ++#define yypact_value_is_default(Yystate) \ ++ (!!((Yystate) == (-41))) ++ ++#define YYTABLE_NINF -1 ++ ++#define yytable_value_is_error(Yytable_value) \ ++ 0 ++ ++ /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing ++ STATE-NUM. */ ++static const yytype_int8 yypact[] = + { +- 0, 2, 4, 0, 2, 4, 2, 2, 3, 3, +- 4, 5, 0, 2, 4, 2, 3, 2, 2, 3, +- 4, 2, 9, 5, 2, 0, 2, 2, 3, 1, +- 2, 2, 2, 1, 1, 3, 1, 1, 5, 1, +- 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, +- 3, 3, 1, 3, 3, 3, 3, 3, 3, 1, +- 3, 3, 1, 3, 3, 3, 1, 1, 2, 2, +- 2, 0, 2, 2, 0, 2, 2, 2, 3, 2 ++ 37, 10, 24, 78, -41, 20, 9, -41, 8, 9, ++ 59, 9, -41, -41, -10, 8, -41, 60, 39, -41, ++ -10, -10, -10, -41, 51, -41, -7, 76, 50, 52, ++ 53, 49, 2, 65, 32, -1, -41, 66, -41, -41, ++ 67, 60, 60, -41, -41, -41, -41, -10, -10, -10, ++ -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, ++ -10, -10, -10, -10, -10, -10, -41, 41, 68, -41, ++ -41, 76, 57, 50, 52, 53, 49, 2, 2, 65, ++ 65, 65, 65, 32, 32, -1, -1, -41, -41, -41, ++ 79, 80, -12, 41, -41, 70, 41, -41, -10, 74, ++ 75, -41, -41, -41, -41, -41, 77, -41, -41, -41, ++ -41, -41, 17, -2, -41, -41, -41, -41, 83, -41, ++ -41, -41, 71, -41, -41, 31, 69, 82, -4, -41, ++ -41, -41, -41, -41, 42, -41, -41, -41, 8, -41, ++ 72, 8, 73, -41 + }; + +-/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. +- Performed when YYTABLE doesn't specify something else to do. Zero +- means the default is an error. */ ++ /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. ++ Performed when YYTABLE does not specify something else to do. Zero ++ means the default is an error. */ + static const yytype_uint8 yydefact[] = + { +- 0, 0, 0, 3, 1, 0, 0, 0, 3, 33, +- 34, 0, 0, 6, 0, 2, 4, 0, 0, 0, +- 67, 0, 36, 37, 39, 41, 43, 45, 47, 49, +- 52, 59, 62, 66, 0, 12, 7, 0, 0, 0, +- 68, 69, 70, 35, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 3, 1, 0, 5, 4, 0, 0, ++ 0, 5, 35, 36, 0, 0, 8, 0, 2, 6, ++ 0, 0, 0, 69, 0, 38, 39, 41, 43, 45, ++ 47, 49, 51, 54, 61, 64, 68, 0, 14, 9, ++ 0, 0, 0, 70, 71, 72, 37, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 5, 74, 0, 9, 8, 40, 0, +- 42, 44, 46, 48, 50, 51, 55, 56, 54, 53, +- 57, 58, 60, 61, 64, 63, 65, 0, 0, 0, +- 0, 13, 0, 74, 10, 0, 0, 0, 15, 25, +- 77, 17, 79, 0, 76, 75, 38, 16, 78, 0, +- 0, 11, 24, 14, 26, 0, 18, 27, 21, 0, +- 71, 29, 0, 0, 0, 0, 32, 31, 19, 30, +- 28, 0, 72, 73, 20, 0, 23, 0, 0, 0, +- 22 ++ 0, 0, 0, 0, 0, 0, 7, 76, 0, 11, ++ 10, 42, 0, 44, 46, 48, 50, 52, 53, 57, ++ 58, 56, 55, 59, 60, 62, 63, 66, 65, 67, ++ 0, 0, 0, 0, 15, 0, 76, 12, 0, 0, ++ 0, 17, 27, 79, 19, 81, 0, 78, 77, 40, ++ 18, 80, 0, 0, 13, 26, 16, 28, 0, 20, ++ 29, 23, 0, 73, 31, 0, 0, 0, 0, 34, ++ 33, 21, 32, 30, 0, 74, 75, 22, 0, 25, ++ 0, 0, 0, 24 + }; + +-/* YYDEFGOTO[NTERM-NUM]. */ +-static const yytype_int8 yydefgoto[] = ++ /* YYPGOTO[NTERM-NUM]. */ ++static const yytype_int8 yypgoto[] = + { +- -1, 2, 7, 8, 15, 36, 64, 91, 109, 110, +- 122, 20, 21, 22, 23, 24, 25, 26, 27, 28, +- 29, 30, 31, 32, 33, 125, 92, 93 ++ -41, -41, -41, 96, 100, -41, -40, -41, -23, -41, ++ -41, -41, -8, 62, 13, -41, 81, 63, 64, 84, ++ 61, 25, 11, 21, 22, -17, -41, 19, 23 + }; + +-/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing +- STATE-NUM. */ +-#define YYPACT_NINF -78 +-static const yytype_int8 yypact[] = ++ /* YYDEFGOTO[NTERM-NUM]. */ ++static const yytype_int16 yydefgoto[] = + { +- 22, 11, 51, 10, -78, 23, 10, 2, 10, -78, +- -78, -9, 23, -78, 30, 38, -78, -9, -9, -9, +- -78, 35, -78, -6, 52, 29, 48, 49, 33, 3, +- 71, 36, 0, -78, 64, -78, -78, 68, 30, 30, +- -78, -78, -78, -78, -9, -9, -9, -9, -9, -9, +- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, +- -9, -9, -9, -78, 44, 67, -78, -78, 52, 55, +- 29, 48, 49, 33, 3, 3, 71, 71, 71, 71, +- 36, 36, 0, 0, -78, -78, -78, 78, 79, 42, +- 44, -78, 69, 44, -78, -9, 73, 74, -78, -78, +- -78, -78, -78, 75, -78, -78, -78, -78, -78, -7, +- -1, -78, -78, -78, -78, 84, -78, -78, -78, 63, +- -78, -78, 32, 66, 82, -3, -78, -78, -78, -78, +- -78, 46, -78, -78, -78, 23, -78, 70, 23, 72, +- -78 ++ -1, 2, 6, 10, 11, 18, 39, 67, 94, 112, ++ 113, 125, 23, 24, 25, 26, 27, 28, 29, 30, ++ 31, 32, 33, 34, 35, 36, 128, 95, 96 + }; + +-/* YYPGOTO[NTERM-NUM]. */ +-static const yytype_int8 yypgoto[] = ++ /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If ++ positive, shift that token. If negative, reduce the rule whose ++ number is the opposite. If YYTABLE_NINF, syntax error. */ ++static const yytype_uint8 yytable[] = + { +- -78, -78, 97, 100, -78, -37, -78, -77, -78, -78, +- -78, -5, 65, 13, -78, 76, 77, 62, 80, 83, +- 34, 20, 26, 28, -14, -78, 18, 24 ++ 15, 69, 70, 43, 44, 45, 47, 37, 12, 13, ++ 55, 56, 118, 101, 8, 38, 135, 102, 136, 119, ++ 120, 121, 122, 14, 4, 63, 12, 13, 137, 123, ++ 48, 9, 57, 20, 124, 3, 21, 22, 58, 115, ++ 1, 14, 116, 64, 65, 7, 87, 88, 89, 12, ++ 13, 117, 103, 129, 130, 40, 90, 91, 92, 53, ++ 54, 131, 41, 93, 14, 42, 79, 80, 81, 82, ++ 104, 59, 60, 107, 61, 62, 138, 139, 77, 78, ++ 83, 84, 5, 85, 86, 17, 46, 38, 49, 50, ++ 68, 66, 51, 97, 52, 98, 99, 100, 106, 110, ++ 111, 126, 114, 134, 127, 133, 141, 19, 143, 16, ++ 72, 109, 73, 76, 74, 108, 105, 132, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, ++ 140, 0, 0, 142, 0, 75 + }; + +-/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If +- positive, shift that token. If negative, reduce the rule which +- number is the opposite. If YYTABLE_NINF, syntax error. */ +-#define YYTABLE_NINF -1 +-static const yytype_uint8 yytable[] = ++static const yytype_int16 yycheck[] = + { +- 12, 66, 67, 40, 41, 42, 44, 34, 9, 10, +- 52, 53, 115, 101, 5, 112, 104, 132, 113, 133, +- 116, 117, 118, 119, 11, 1, 60, 114, 14, 134, +- 120, 45, 6, 54, 17, 121, 3, 18, 19, 55, +- 9, 10, 50, 51, 61, 62, 84, 85, 86, 9, +- 10, 4, 100, 37, 126, 127, 11, 35, 87, 88, +- 89, 38, 128, 46, 39, 11, 90, 98, 47, 35, +- 43, 99, 76, 77, 78, 79, 56, 57, 58, 59, +- 135, 136, 80, 81, 74, 75, 82, 83, 48, 63, +- 49, 65, 94, 95, 96, 97, 124, 103, 107, 108, +- 111, 123, 130, 131, 138, 16, 13, 140, 106, 71, +- 69, 105, 0, 0, 102, 0, 0, 129, 0, 0, +- 68, 0, 0, 70, 0, 0, 0, 0, 72, 0, +- 137, 0, 73, 139 ++ 8, 41, 42, 20, 21, 22, 13, 15, 18, 19, ++ 8, 9, 14, 25, 5, 27, 20, 29, 22, 21, ++ 22, 23, 24, 33, 0, 26, 18, 19, 32, 31, ++ 37, 22, 30, 43, 36, 25, 46, 47, 36, 22, ++ 3, 33, 25, 44, 45, 25, 63, 64, 65, 18, ++ 19, 34, 92, 22, 23, 16, 15, 16, 17, 10, ++ 11, 30, 23, 22, 33, 26, 55, 56, 57, 58, ++ 93, 6, 7, 96, 42, 43, 34, 35, 53, 54, ++ 59, 60, 4, 61, 62, 26, 35, 27, 12, 39, ++ 23, 25, 40, 25, 41, 38, 17, 17, 28, 25, ++ 25, 18, 25, 21, 33, 36, 34, 11, 35, 9, ++ 48, 98, 49, 52, 50, 96, 93, 125, -1, -1, ++ -1, -1, -1, -1, -1, -1, -1, -1, 47, -1, ++ 138, -1, -1, 141, -1, 51 + }; + +-#define yypact_value_is_default(Yystate) \ +- (!!((Yystate) == (-78))) +- +-#define yytable_value_is_error(Yytable_value) \ +- YYID (0) ++ /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing ++ symbol of state STATE-NUM. */ ++static const yytype_uint8 yystos[] = ++{ ++ 0, 3, 49, 25, 0, 4, 50, 25, 5, 22, ++ 51, 52, 18, 19, 33, 60, 52, 26, 53, 51, ++ 43, 46, 47, 60, 61, 62, 63, 64, 65, 66, ++ 67, 68, 69, 70, 71, 72, 73, 60, 27, 54, ++ 16, 23, 26, 73, 73, 73, 35, 13, 37, 12, ++ 39, 40, 41, 10, 11, 8, 9, 30, 36, 6, ++ 7, 42, 43, 26, 44, 45, 25, 55, 23, 54, ++ 54, 64, 61, 65, 66, 67, 68, 69, 69, 70, ++ 70, 70, 70, 71, 71, 72, 72, 73, 73, 73, ++ 15, 16, 17, 22, 56, 75, 76, 25, 38, 17, ++ 17, 25, 29, 54, 56, 76, 28, 56, 75, 62, ++ 25, 25, 57, 58, 25, 22, 25, 34, 14, 21, ++ 22, 23, 24, 31, 36, 59, 18, 33, 74, 22, ++ 23, 30, 60, 36, 21, 20, 22, 32, 34, 35, ++ 60, 34, 60, 35 ++}; + +-static const yytype_int16 yycheck[] = ++ /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ ++static const yytype_uint8 yyr1[] = + { +- 5, 38, 39, 17, 18, 19, 12, 12, 17, 18, +- 7, 8, 13, 90, 4, 22, 93, 20, 25, 22, +- 21, 22, 23, 24, 33, 3, 26, 34, 26, 32, +- 31, 37, 22, 30, 43, 36, 25, 46, 47, 36, +- 17, 18, 9, 10, 44, 45, 60, 61, 62, 17, +- 18, 0, 89, 15, 22, 23, 33, 27, 14, 15, +- 16, 23, 30, 11, 26, 33, 22, 25, 39, 27, +- 35, 29, 52, 53, 54, 55, 5, 6, 42, 43, +- 34, 35, 56, 57, 50, 51, 58, 59, 40, 25, +- 41, 23, 25, 38, 16, 16, 33, 28, 25, 25, +- 25, 17, 36, 21, 34, 8, 6, 35, 95, 47, +- 45, 93, -1, -1, 90, -1, -1, 122, -1, -1, +- 44, -1, -1, 46, -1, -1, -1, -1, 48, -1, +- 135, -1, 49, 138 ++ 0, 48, 49, 50, 50, 51, 51, 52, 52, 53, ++ 53, 53, 53, 54, 55, 55, 56, 56, 56, 56, ++ 57, 57, 57, 57, 57, 57, 57, 58, 58, 58, ++ 59, 59, 59, 59, 59, 60, 60, 60, 61, 62, ++ 62, 63, 63, 64, 64, 65, 65, 66, 66, 67, ++ 67, 68, 68, 68, 69, 69, 69, 69, 69, 70, ++ 70, 70, 71, 71, 71, 72, 72, 72, 72, 73, ++ 73, 73, 73, 74, 74, 74, 75, 75, 75, 76, ++ 76, 76 + }; + +-/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing +- symbol of state STATE-NUM. */ +-static const yytype_uint8 yystos[] = ++ /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ ++static const yytype_uint8 yyr2[] = + { +- 0, 3, 49, 25, 0, 4, 22, 50, 51, 17, +- 18, 33, 59, 51, 26, 52, 50, 43, 46, 47, +- 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, +- 69, 70, 71, 72, 59, 27, 53, 15, 23, 26, +- 72, 72, 72, 35, 12, 37, 11, 39, 40, 41, +- 9, 10, 7, 8, 30, 36, 5, 6, 42, 43, +- 26, 44, 45, 25, 54, 23, 53, 53, 63, 60, +- 64, 65, 66, 67, 68, 68, 69, 69, 69, 69, +- 70, 70, 71, 71, 72, 72, 72, 14, 15, 16, +- 22, 55, 74, 75, 25, 38, 16, 16, 25, 29, +- 53, 55, 75, 28, 55, 74, 61, 25, 25, 56, +- 57, 25, 22, 25, 34, 13, 21, 22, 23, 24, +- 31, 36, 58, 17, 33, 73, 22, 23, 30, 59, +- 36, 21, 20, 22, 32, 34, 35, 59, 34, 59, +- 35 ++ 0, 2, 5, 0, 2, 0, 2, 4, 2, 2, ++ 3, 3, 4, 5, 0, 2, 4, 2, 3, 2, ++ 2, 3, 4, 2, 9, 5, 2, 0, 2, 2, ++ 3, 1, 2, 2, 2, 1, 1, 3, 1, 1, ++ 5, 1, 3, 1, 3, 1, 3, 1, 3, 1, ++ 3, 1, 3, 3, 1, 3, 3, 3, 3, 3, ++ 3, 1, 3, 3, 1, 3, 3, 3, 1, 1, ++ 2, 2, 2, 0, 2, 2, 0, 2, 2, 2, ++ 3, 2 + }; + +-#define yyerrok (yyerrstatus = 0) +-#define yyclearin (yychar = YYEMPTY) +-#define YYEMPTY (-2) +-#define YYEOF 0 +- +-#define YYACCEPT goto yyacceptlab +-#define YYABORT goto yyabortlab +-#define YYERROR goto yyerrorlab +- +- +-/* Like YYERROR except do call yyerror. This remains here temporarily +- to ease the transition to the new meaning of YYERROR, for GCC. +- Once GCC version 2 has supplanted version 1, this can go. However, +- YYFAIL appears to be in use. Nevertheless, it is formally deprecated +- in Bison 2.4.2's NEWS entry, where a plan to phase it out is +- discussed. */ +- +-#define YYFAIL goto yyerrlab +-#if defined YYFAIL +- /* This is here to suppress warnings from the GCC cpp's +- -Wunused-macros. Normally we don't worry about that warning, but +- some users do, and we want to make it easy for users to remove +- YYFAIL uses, which will produce warnings from Bison 2.5. */ +-#endif ++ ++#define yyerrok (yyerrstatus = 0) ++#define yyclearin (yychar = YYEMPTY) ++#define YYEMPTY (-2) ++#define YYEOF 0 ++ ++#define YYACCEPT goto yyacceptlab ++#define YYABORT goto yyabortlab ++#define YYERROR goto yyerrorlab ++ + + #define YYRECOVERING() (!!yyerrstatus) + +@@ -768,27 +725,41 @@ do \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ +- YYERROR; \ +- } \ +-while (YYID (0)) ++ YYERROR; \ ++ } \ ++while (0) + + /* Error token number */ +-#define YYTERROR 1 +-#define YYERRCODE 256 +- +- +-/* This macro is provided for backward compatibility. */ +-#ifndef YY_LOCATION_PRINT +-# define YY_LOCATION_PRINT(File, Loc) ((void) 0) ++#define YYTERROR 1 ++#define YYERRCODE 256 ++ ++ ++/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. ++ If N is 0, then set CURRENT to the empty location which ends ++ the previous symbol: RHS[0] (always defined). */ ++ ++#ifndef YYLLOC_DEFAULT ++# define YYLLOC_DEFAULT(Current, Rhs, N) \ ++ do \ ++ if (N) \ ++ { \ ++ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ ++ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ ++ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ ++ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ ++ } \ ++ else \ ++ { \ ++ (Current).first_line = (Current).last_line = \ ++ YYRHSLOC (Rhs, 0).last_line; \ ++ (Current).first_column = (Current).last_column = \ ++ YYRHSLOC (Rhs, 0).last_column; \ ++ } \ ++ while (0) + #endif + ++#define YYRHSLOC(Rhs, K) ((Rhs)[K]) + +-/* YYLEX -- calling `yylex' with the right arguments. */ +-#ifdef YYLEX_PARAM +-# define YYLEX yylex (YYLEX_PARAM) +-#else +-# define YYLEX yylex () +-#endif + + /* Enable debugging if requested. */ + #if YYDEBUG +@@ -798,50 +769,84 @@ while (YYID (0)) + # define YYFPRINTF fprintf + # endif + +-# define YYDPRINTF(Args) \ +-do { \ +- if (yydebug) \ +- YYFPRINTF Args; \ +-} while (YYID (0)) ++# define YYDPRINTF(Args) \ ++do { \ ++ if (yydebug) \ ++ YYFPRINTF Args; \ ++} while (0) + +-# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +-do { \ +- if (yydebug) \ +- { \ +- YYFPRINTF (stderr, "%s ", Title); \ +- yy_symbol_print (stderr, \ +- Type, Value); \ +- YYFPRINTF (stderr, "\n"); \ +- } \ +-} while (YYID (0)) + ++/* YY_LOCATION_PRINT -- Print the location on the stream. ++ This macro was not mandated originally: define only if we know ++ we won't break user code: when these are the locations we know. */ + +-/*--------------------------------. +-| Print this symbol on YYOUTPUT. | +-`--------------------------------*/ ++#ifndef YY_LOCATION_PRINT ++# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL + +-/*ARGSUSED*/ +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static void +-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +-#else +-static void +-yy_symbol_value_print (yyoutput, yytype, yyvaluep) +- FILE *yyoutput; +- int yytype; +- YYSTYPE const * const yyvaluep; ++/* Print *YYLOCP on YYO. Private, do not rely on its existence. */ ++ ++YY_ATTRIBUTE_UNUSED ++static unsigned ++yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp) ++{ ++ unsigned res = 0; ++ int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0; ++ if (0 <= yylocp->first_line) ++ { ++ res += YYFPRINTF (yyo, "%d", yylocp->first_line); ++ if (0 <= yylocp->first_column) ++ res += YYFPRINTF (yyo, ".%d", yylocp->first_column); ++ } ++ if (0 <= yylocp->last_line) ++ { ++ if (yylocp->first_line < yylocp->last_line) ++ { ++ res += YYFPRINTF (yyo, "-%d", yylocp->last_line); ++ if (0 <= end_col) ++ res += YYFPRINTF (yyo, ".%d", end_col); ++ } ++ else if (0 <= end_col && yylocp->first_column < end_col) ++ res += YYFPRINTF (yyo, "-%d", end_col); ++ } ++ return res; ++ } ++ ++# define YY_LOCATION_PRINT(File, Loc) \ ++ yy_location_print_ (File, &(Loc)) ++ ++# else ++# define YY_LOCATION_PRINT(File, Loc) ((void) 0) ++# endif + #endif ++ ++ ++# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ ++do { \ ++ if (yydebug) \ ++ { \ ++ YYFPRINTF (stderr, "%s ", Title); \ ++ yy_symbol_print (stderr, \ ++ Type, Value, Location); \ ++ YYFPRINTF (stderr, "\n"); \ ++ } \ ++} while (0) ++ ++ ++/*----------------------------------------. ++| Print this symbol's value on YYOUTPUT. | ++`----------------------------------------*/ ++ ++static void ++yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp) + { + FILE *yyo = yyoutput; + YYUSE (yyo); ++ YYUSE (yylocationp); + if (!yyvaluep) + return; + # ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +-# else +- YYUSE (yyoutput); + # endif + YYUSE (yytype); + } +@@ -851,24 +856,15 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep) + | Print this symbol on YYOUTPUT. | + `--------------------------------*/ + +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static void +-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +-#else + static void +-yy_symbol_print (yyoutput, yytype, yyvaluep) +- FILE *yyoutput; +- int yytype; +- YYSTYPE const * const yyvaluep; +-#endif ++yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp) + { +- if (yytype < YYNTOKENS) +- YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); +- else +- YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); ++ YYFPRINTF (yyoutput, "%s %s (", ++ yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); + +- yy_symbol_value_print (yyoutput, yytype, yyvaluep); ++ YY_LOCATION_PRINT (yyoutput, *yylocationp); ++ YYFPRINTF (yyoutput, ": "); ++ yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp); + YYFPRINTF (yyoutput, ")"); + } + +@@ -877,16 +873,8 @@ yy_symbol_print (yyoutput, yytype, yyvaluep) + | TOP (included). | + `------------------------------------------------------------------*/ + +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) + static void + yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +-#else +-static void +-yy_stack_print (yybottom, yytop) +- yytype_int16 *yybottom; +- yytype_int16 *yytop; +-#endif + { + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) +@@ -897,49 +885,42 @@ yy_stack_print (yybottom, yytop) + YYFPRINTF (stderr, "\n"); + } + +-# define YY_STACK_PRINT(Bottom, Top) \ +-do { \ +- if (yydebug) \ +- yy_stack_print ((Bottom), (Top)); \ +-} while (YYID (0)) ++# define YY_STACK_PRINT(Bottom, Top) \ ++do { \ ++ if (yydebug) \ ++ yy_stack_print ((Bottom), (Top)); \ ++} while (0) + + + /*------------------------------------------------. + | Report that the YYRULE is going to be reduced. | + `------------------------------------------------*/ + +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) + static void +-yy_reduce_print (YYSTYPE *yyvsp, int yyrule) +-#else +-static void +-yy_reduce_print (yyvsp, yyrule) +- YYSTYPE *yyvsp; +- int yyrule; +-#endif ++yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule) + { ++ unsigned long int yylno = yyrline[yyrule]; + int yynrhs = yyr2[yyrule]; + int yyi; +- unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", +- yyrule - 1, yylno); ++ yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); +- yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], +- &(yyvsp[(yyi + 1) - (yynrhs)]) +- ); ++ yy_symbol_print (stderr, ++ yystos[yyssp[yyi + 1 - yynrhs]], ++ &(yyvsp[(yyi + 1) - (yynrhs)]) ++ , &(yylsp[(yyi + 1) - (yynrhs)]) ); + YYFPRINTF (stderr, "\n"); + } + } + +-# define YY_REDUCE_PRINT(Rule) \ +-do { \ +- if (yydebug) \ +- yy_reduce_print (yyvsp, Rule); \ +-} while (YYID (0)) ++# define YY_REDUCE_PRINT(Rule) \ ++do { \ ++ if (yydebug) \ ++ yy_reduce_print (yyssp, yyvsp, yylsp, Rule); \ ++} while (0) + + /* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +@@ -953,7 +934,7 @@ int yydebug; + + + /* YYINITDEPTH -- initial size of the parser's stacks. */ +-#ifndef YYINITDEPTH ++#ifndef YYINITDEPTH + # define YYINITDEPTH 200 + #endif + +@@ -976,15 +957,8 @@ int yydebug; + # define yystrlen strlen + # else + /* Return the length of YYSTR. */ +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) + static YYSIZE_T + yystrlen (const char *yystr) +-#else +-static YYSIZE_T +-yystrlen (yystr) +- const char *yystr; +-#endif + { + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) +@@ -1000,16 +974,8 @@ yystrlen (yystr) + # else + /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) + static char * + yystpcpy (char *yydest, const char *yysrc) +-#else +-static char * +-yystpcpy (yydest, yysrc) +- char *yydest; +- const char *yysrc; +-#endif + { + char *yyd = yydest; + const char *yys = yysrc; +@@ -1039,27 +1005,27 @@ yytnamerr (char *yyres, const char *yystr) + char const *yyp = yystr; + + for (;;) +- switch (*++yyp) +- { +- case '\'': +- case ',': +- goto do_not_strip_quotes; +- +- case '\\': +- if (*++yyp != '\\') +- goto do_not_strip_quotes; +- /* Fall through. */ +- default: +- if (yyres) +- yyres[yyn] = *yyp; +- yyn++; +- break; +- +- case '"': +- if (yyres) +- yyres[yyn] = '\0'; +- return yyn; +- } ++ switch (*++yyp) ++ { ++ case '\'': ++ case ',': ++ goto do_not_strip_quotes; ++ ++ case '\\': ++ if (*++yyp != '\\') ++ goto do_not_strip_quotes; ++ /* Fall through. */ ++ default: ++ if (yyres) ++ yyres[yyn] = *yyp; ++ yyn++; ++ break; ++ ++ case '"': ++ if (yyres) ++ yyres[yyn] = '\0'; ++ return yyn; ++ } + do_not_strip_quotes: ; + } + +@@ -1082,11 +1048,11 @@ static int + yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + yytype_int16 *yyssp, int yytoken) + { +- YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]); ++ YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); + YYSIZE_T yysize = yysize0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + /* Internationalized format string. */ +- const char *yyformat = YY_NULL; ++ const char *yyformat = YY_NULLPTR; + /* Arguments of yyformat. */ + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + /* Number of reported tokens (one for the "unexpected", one per +@@ -1094,10 +1060,6 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + int yycount = 0; + + /* There are many possibilities here to consider: +- - Assume YYFAIL is not used. It's too flawed to consider. See +- +- for details. YYERROR is fine as it does not invoke this +- function. + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected +@@ -1147,7 +1109,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + } + yyarg[yycount++] = yytname[yyx]; + { +- YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]); ++ YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); + if (! (yysize <= yysize1 + && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; +@@ -1214,26 +1176,18 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + | Release the memory associated to this symbol. | + `-----------------------------------------------*/ + +-/*ARGSUSED*/ +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) + static void +-yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +-#else +-static void +-yydestruct (yymsg, yytype, yyvaluep) +- const char *yymsg; +- int yytype; +- YYSTYPE *yyvaluep; +-#endif ++yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp) + { + YYUSE (yyvaluep); +- ++ YYUSE (yylocationp); + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + ++ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + YYUSE (yytype); ++ YY_IGNORE_MAYBE_UNINITIALIZED_END + } + + +@@ -1242,18 +1196,14 @@ yydestruct (yymsg, yytype, yyvaluep) + /* The lookahead symbol. */ + int yychar; + +- +-#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +-# define YY_IGNORE_MAYBE_UNINITIALIZED_END +-#endif +-#ifndef YY_INITIAL_VALUE +-# define YY_INITIAL_VALUE(Value) /* Nothing. */ +-#endif +- + /* The semantic value of the lookahead symbol. */ +-YYSTYPE yylval YY_INITIAL_VALUE(yyval_default); +- ++YYSTYPE yylval; ++/* Location data for the lookahead symbol. */ ++YYLTYPE yylloc ++# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL ++ = { 1, 1, 1, 1 } ++# endif ++; + /* Number of syntax errors so far. */ + int yynerrs; + +@@ -1262,35 +1212,17 @@ int yynerrs; + | yyparse. | + `----------*/ + +-#ifdef YYPARSE_PARAM +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-int +-yyparse (void *YYPARSE_PARAM) +-#else +-int +-yyparse (YYPARSE_PARAM) +- void *YYPARSE_PARAM; +-#endif +-#else /* ! YYPARSE_PARAM */ +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) + int + yyparse (void) +-#else +-int +-yyparse () +- +-#endif +-#endif + { + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: +- `yyss': related to states. +- `yyvs': related to semantic values. ++ 'yyss': related to states. ++ 'yyvs': related to semantic values. ++ 'yyls': related to locations. + + Refer to the stacks through separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ +@@ -1305,6 +1237,14 @@ yyparse () + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + ++ /* The location stack. */ ++ YYLTYPE yylsa[YYINITDEPTH]; ++ YYLTYPE *yyls; ++ YYLTYPE *yylsp; ++ ++ /* The locations where the error started and ended. */ ++ YYLTYPE yyerror_range[3]; ++ + YYSIZE_T yystacksize; + + int yyn; +@@ -1314,6 +1254,7 @@ yyparse () + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; ++ YYLTYPE yyloc; + + #if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ +@@ -1322,7 +1263,7 @@ yyparse () + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; + #endif + +-#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) ++#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ +@@ -1330,6 +1271,7 @@ yyparse () + + yyssp = yyss = yyssa; + yyvsp = yyvs = yyvsa; ++ yylsp = yyls = yylsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); +@@ -1338,6 +1280,7 @@ yyparse () + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ ++ yylsp[0] = yylloc; + goto yysetstate; + + /*------------------------------------------------------------. +@@ -1358,23 +1301,26 @@ yyparse () + + #ifdef yyoverflow + { +- /* Give user a chance to reallocate the stack. Use copies of +- these so that the &'s don't force the real ones into +- memory. */ +- YYSTYPE *yyvs1 = yyvs; +- yytype_int16 *yyss1 = yyss; +- +- /* Each stack pointer address is followed by the size of the +- data in use in that stack, in bytes. This used to be a +- conditional around just the two extra args, but that might +- be undefined if yyoverflow is a macro. */ +- yyoverflow (YY_("memory exhausted"), +- &yyss1, yysize * sizeof (*yyssp), +- &yyvs1, yysize * sizeof (*yyvsp), +- &yystacksize); +- +- yyss = yyss1; +- yyvs = yyvs1; ++ /* Give user a chance to reallocate the stack. Use copies of ++ these so that the &'s don't force the real ones into ++ memory. */ ++ YYSTYPE *yyvs1 = yyvs; ++ yytype_int16 *yyss1 = yyss; ++ YYLTYPE *yyls1 = yyls; ++ ++ /* Each stack pointer address is followed by the size of the ++ data in use in that stack, in bytes. This used to be a ++ conditional around just the two extra args, but that might ++ be undefined if yyoverflow is a macro. */ ++ yyoverflow (YY_("memory exhausted"), ++ &yyss1, yysize * sizeof (*yyssp), ++ &yyvs1, yysize * sizeof (*yyvsp), ++ &yyls1, yysize * sizeof (*yylsp), ++ &yystacksize); ++ ++ yyls = yyls1; ++ yyss = yyss1; ++ yyvs = yyvs1; + } + #else /* no yyoverflow */ + # ifndef YYSTACK_RELOCATE +@@ -1382,34 +1328,36 @@ yyparse () + # else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) +- goto yyexhaustedlab; ++ goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) +- yystacksize = YYMAXDEPTH; ++ yystacksize = YYMAXDEPTH; + + { +- yytype_int16 *yyss1 = yyss; +- union yyalloc *yyptr = +- (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); +- if (! yyptr) +- goto yyexhaustedlab; +- YYSTACK_RELOCATE (yyss_alloc, yyss); +- YYSTACK_RELOCATE (yyvs_alloc, yyvs); ++ yytype_int16 *yyss1 = yyss; ++ union yyalloc *yyptr = ++ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); ++ if (! yyptr) ++ goto yyexhaustedlab; ++ YYSTACK_RELOCATE (yyss_alloc, yyss); ++ YYSTACK_RELOCATE (yyvs_alloc, yyvs); ++ YYSTACK_RELOCATE (yyls_alloc, yyls); + # undef YYSTACK_RELOCATE +- if (yyss1 != yyssa) +- YYSTACK_FREE (yyss1); ++ if (yyss1 != yyssa) ++ YYSTACK_FREE (yyss1); + } + # endif + #endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; ++ yylsp = yyls + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", +- (unsigned long int) yystacksize)); ++ (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) +- YYABORT; ++ YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); +@@ -1438,7 +1386,7 @@ yybackup: + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); +- yychar = YYLEX; ++ yychar = yylex (); + } + + if (yychar <= YYEOF) +@@ -1481,7 +1429,7 @@ yybackup: + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END +- ++ *++yylsp = yylloc; + goto yynewstate; + + +@@ -1503,7 +1451,7 @@ yyreduce: + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: +- `$$ = $1'. ++ '$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison +@@ -1512,287 +1460,306 @@ yyreduce: + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + +- ++ /* Default location. */ ++ YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 2: +-/* Line 1787 of yacc.c */ +-#line 110 "dtc-parser.y" ++#line 109 "dtc-parser.y" /* yacc.c:1646 */ + { +- the_boot_info = build_boot_info((yyvsp[(3) - (4)].re), (yyvsp[(4) - (4)].node), +- guess_boot_cpuid((yyvsp[(4) - (4)].node))); ++ (yyvsp[0].node)->is_plugin = (yyvsp[-2].is_plugin); ++ (yyvsp[0].node)->is_root = 1; ++ the_boot_info = build_boot_info((yyvsp[-1].re), (yyvsp[0].node), ++ guess_boot_cpuid((yyvsp[0].node))); + } ++#line 1477 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 3: +-/* Line 1787 of yacc.c */ +-#line 118 "dtc-parser.y" ++#line 119 "dtc-parser.y" /* yacc.c:1646 */ + { +- (yyval.re) = NULL; ++ (yyval.is_plugin) = 0; + } ++#line 1485 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 4: +-/* Line 1787 of yacc.c */ +-#line 122 "dtc-parser.y" ++#line 123 "dtc-parser.y" /* yacc.c:1646 */ + { +- (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re)); ++ (yyval.is_plugin) = 1; + } ++#line 1493 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 5: +-/* Line 1787 of yacc.c */ +-#line 129 "dtc-parser.y" ++#line 130 "dtc-parser.y" /* yacc.c:1646 */ + { +- (yyval.re) = build_reserve_entry((yyvsp[(2) - (4)].integer), (yyvsp[(3) - (4)].integer)); ++ (yyval.re) = NULL; + } ++#line 1501 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 6: +-/* Line 1787 of yacc.c */ +-#line 133 "dtc-parser.y" ++#line 134 "dtc-parser.y" /* yacc.c:1646 */ + { +- add_label(&(yyvsp[(2) - (2)].re)->labels, (yyvsp[(1) - (2)].labelref)); +- (yyval.re) = (yyvsp[(2) - (2)].re); ++ (yyval.re) = chain_reserve_entry((yyvsp[-1].re), (yyvsp[0].re)); + } ++#line 1509 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 7: +-/* Line 1787 of yacc.c */ +-#line 141 "dtc-parser.y" ++#line 141 "dtc-parser.y" /* yacc.c:1646 */ + { +- (yyval.node) = name_node((yyvsp[(2) - (2)].node), ""); ++ (yyval.re) = build_reserve_entry((yyvsp[-2].integer), (yyvsp[-1].integer)); + } ++#line 1517 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 8: +-/* Line 1787 of yacc.c */ +-#line 145 "dtc-parser.y" ++#line 145 "dtc-parser.y" /* yacc.c:1646 */ + { +- (yyval.node) = merge_nodes((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); ++ add_label(&(yyvsp[0].re)->labels, (yyvsp[-1].labelref)); ++ (yyval.re) = (yyvsp[0].re); + } ++#line 1526 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 9: +-/* Line 1787 of yacc.c */ +-#line 149 "dtc-parser.y" ++#line 153 "dtc-parser.y" /* yacc.c:1646 */ + { +- struct node *target = get_node_by_ref((yyvsp[(1) - (3)].node), (yyvsp[(2) - (3)].labelref)); +- +- if (target) +- merge_nodes(target, (yyvsp[(3) - (3)].node)); +- else +- print_error("label or path, '%s', not found", (yyvsp[(2) - (3)].labelref)); +- (yyval.node) = (yyvsp[(1) - (3)].node); ++ (yyval.node) = name_node((yyvsp[0].node), ""); + } ++#line 1534 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 10: +-/* Line 1787 of yacc.c */ +-#line 159 "dtc-parser.y" ++#line 157 "dtc-parser.y" /* yacc.c:1646 */ + { +- struct node *target = get_node_by_ref((yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].labelref)); +- +- if (!target) +- print_error("label or path, '%s', not found", (yyvsp[(3) - (4)].labelref)); +- else +- delete_node(target); +- +- (yyval.node) = (yyvsp[(1) - (4)].node); ++ (yyval.node) = merge_nodes((yyvsp[-2].node), (yyvsp[0].node)); + } ++#line 1542 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 11: +-/* Line 1787 of yacc.c */ +-#line 173 "dtc-parser.y" ++#line 161 "dtc-parser.y" /* yacc.c:1646 */ + { +- (yyval.node) = build_node((yyvsp[(2) - (5)].proplist), (yyvsp[(3) - (5)].nodelist)); ++ struct node *target = get_node_by_ref((yyvsp[-2].node), (yyvsp[-1].labelref)); ++ ++ if (target) ++ merge_nodes(target, (yyvsp[0].node)); ++ else ++ ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); ++ (yyval.node) = (yyvsp[-2].node); + } ++#line 1556 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 12: +-/* Line 1787 of yacc.c */ +-#line 180 "dtc-parser.y" ++#line 171 "dtc-parser.y" /* yacc.c:1646 */ + { +- (yyval.proplist) = NULL; ++ struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref)); ++ ++ if (target) ++ delete_node(target); ++ else ++ ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); ++ ++ ++ (yyval.node) = (yyvsp[-3].node); + } ++#line 1572 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 13: +-/* Line 1787 of yacc.c */ +-#line 184 "dtc-parser.y" ++#line 186 "dtc-parser.y" /* yacc.c:1646 */ + { +- (yyval.proplist) = chain_property((yyvsp[(2) - (2)].prop), (yyvsp[(1) - (2)].proplist)); ++ (yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist)); + } ++#line 1580 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 14: +-/* Line 1787 of yacc.c */ +-#line 191 "dtc-parser.y" ++#line 193 "dtc-parser.y" /* yacc.c:1646 */ + { +- (yyval.prop) = build_property((yyvsp[(1) - (4)].propnodename), (yyvsp[(3) - (4)].data)); ++ (yyval.proplist) = NULL; + } ++#line 1588 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 15: +-/* Line 1787 of yacc.c */ +-#line 195 "dtc-parser.y" ++#line 197 "dtc-parser.y" /* yacc.c:1646 */ + { +- (yyval.prop) = build_property((yyvsp[(1) - (2)].propnodename), empty_data); ++ (yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist)); + } ++#line 1596 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 16: +-/* Line 1787 of yacc.c */ +-#line 199 "dtc-parser.y" ++#line 204 "dtc-parser.y" /* yacc.c:1646 */ + { +- (yyval.prop) = build_property_delete((yyvsp[(2) - (3)].propnodename)); ++ (yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data)); + } ++#line 1604 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 17: +-/* Line 1787 of yacc.c */ +-#line 203 "dtc-parser.y" ++#line 208 "dtc-parser.y" /* yacc.c:1646 */ + { +- add_label(&(yyvsp[(2) - (2)].prop)->labels, (yyvsp[(1) - (2)].labelref)); +- (yyval.prop) = (yyvsp[(2) - (2)].prop); ++ (yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data); + } ++#line 1612 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 18: +-/* Line 1787 of yacc.c */ +-#line 211 "dtc-parser.y" ++#line 212 "dtc-parser.y" /* yacc.c:1646 */ + { +- (yyval.data) = data_merge((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].data)); ++ (yyval.prop) = build_property_delete((yyvsp[-1].propnodename)); + } ++#line 1620 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 19: +-/* Line 1787 of yacc.c */ +-#line 215 "dtc-parser.y" ++#line 216 "dtc-parser.y" /* yacc.c:1646 */ + { +- (yyval.data) = data_merge((yyvsp[(1) - (3)].data), (yyvsp[(2) - (3)].array).data); ++ add_label(&(yyvsp[0].prop)->labels, (yyvsp[-1].labelref)); ++ (yyval.prop) = (yyvsp[0].prop); + } ++#line 1629 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 20: +-/* Line 1787 of yacc.c */ +-#line 219 "dtc-parser.y" ++#line 224 "dtc-parser.y" /* yacc.c:1646 */ + { +- (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data)); ++ (yyval.data) = data_merge((yyvsp[-1].data), (yyvsp[0].data)); + } ++#line 1637 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 21: +-/* Line 1787 of yacc.c */ +-#line 223 "dtc-parser.y" ++#line 228 "dtc-parser.y" /* yacc.c:1646 */ + { +- (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), REF_PATH, (yyvsp[(2) - (2)].labelref)); ++ (yyval.data) = data_merge((yyvsp[-2].data), (yyvsp[-1].array).data); + } ++#line 1645 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 22: +-/* Line 1787 of yacc.c */ +-#line 227 "dtc-parser.y" ++#line 232 "dtc-parser.y" /* yacc.c:1646 */ + { +- FILE *f = srcfile_relative_open((yyvsp[(4) - (9)].data).val, NULL); ++ (yyval.data) = data_merge((yyvsp[-3].data), (yyvsp[-1].data)); ++ } ++#line 1653 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ break; ++ ++ case 23: ++#line 236 "dtc-parser.y" /* yacc.c:1646 */ ++ { ++ (yyval.data) = data_add_marker((yyvsp[-1].data), REF_PATH, (yyvsp[0].labelref)); ++ } ++#line 1661 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ break; ++ ++ case 24: ++#line 240 "dtc-parser.y" /* yacc.c:1646 */ ++ { ++ FILE *f = srcfile_relative_open((yyvsp[-5].data).val, NULL); + struct data d; + +- if ((yyvsp[(6) - (9)].integer) != 0) +- if (fseek(f, (yyvsp[(6) - (9)].integer), SEEK_SET) != 0) +- print_error("Couldn't seek to offset %llu in \"%s\": %s", +- (unsigned long long)(yyvsp[(6) - (9)].integer), +- (yyvsp[(4) - (9)].data).val, +- strerror(errno)); ++ if ((yyvsp[-3].integer) != 0) ++ if (fseek(f, (yyvsp[-3].integer), SEEK_SET) != 0) ++ die("Couldn't seek to offset %llu in \"%s\": %s", ++ (unsigned long long)(yyvsp[-3].integer), (yyvsp[-5].data).val, ++ strerror(errno)); + +- d = data_copy_file(f, (yyvsp[(8) - (9)].integer)); ++ d = data_copy_file(f, (yyvsp[-1].integer)); + +- (yyval.data) = data_merge((yyvsp[(1) - (9)].data), d); ++ (yyval.data) = data_merge((yyvsp[-8].data), d); + fclose(f); + } ++#line 1681 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 23: +-/* Line 1787 of yacc.c */ +-#line 244 "dtc-parser.y" ++ case 25: ++#line 256 "dtc-parser.y" /* yacc.c:1646 */ + { +- FILE *f = srcfile_relative_open((yyvsp[(4) - (5)].data).val, NULL); ++ FILE *f = srcfile_relative_open((yyvsp[-1].data).val, NULL); + struct data d = empty_data; + + d = data_copy_file(f, -1); + +- (yyval.data) = data_merge((yyvsp[(1) - (5)].data), d); ++ (yyval.data) = data_merge((yyvsp[-4].data), d); + fclose(f); + } ++#line 1695 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 24: +-/* Line 1787 of yacc.c */ +-#line 254 "dtc-parser.y" ++ case 26: ++#line 266 "dtc-parser.y" /* yacc.c:1646 */ + { +- (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); ++ (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); + } ++#line 1703 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 25: +-/* Line 1787 of yacc.c */ +-#line 261 "dtc-parser.y" ++ case 27: ++#line 273 "dtc-parser.y" /* yacc.c:1646 */ + { + (yyval.data) = empty_data; + } ++#line 1711 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 26: +-/* Line 1787 of yacc.c */ +-#line 265 "dtc-parser.y" ++ case 28: ++#line 277 "dtc-parser.y" /* yacc.c:1646 */ + { +- (yyval.data) = (yyvsp[(1) - (2)].data); ++ (yyval.data) = (yyvsp[-1].data); + } ++#line 1719 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 27: +-/* Line 1787 of yacc.c */ +-#line 269 "dtc-parser.y" ++ case 29: ++#line 281 "dtc-parser.y" /* yacc.c:1646 */ + { +- (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); ++ (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); + } ++#line 1727 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 28: +-/* Line 1787 of yacc.c */ +-#line 276 "dtc-parser.y" ++ case 30: ++#line 288 "dtc-parser.y" /* yacc.c:1646 */ + { +- (yyval.array).data = empty_data; +- (yyval.array).bits = eval_literal((yyvsp[(2) - (3)].literal), 0, 7); +- +- if (((yyval.array).bits != 8) && +- ((yyval.array).bits != 16) && +- ((yyval.array).bits != 32) && +- ((yyval.array).bits != 64)) +- { +- print_error("Only 8, 16, 32 and 64-bit elements" +- " are currently supported"); +- (yyval.array).bits = 32; ++ unsigned long long bits; ++ ++ bits = (yyvsp[-1].integer); ++ ++ if ((bits != 8) && (bits != 16) && ++ (bits != 32) && (bits != 64)) { ++ ERROR(&(yylsp[-1]), "Array elements must be" ++ " 8, 16, 32 or 64-bits"); ++ bits = 32; + } ++ ++ (yyval.array).data = empty_data; ++ (yyval.array).bits = bits; + } ++#line 1747 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 29: +-/* Line 1787 of yacc.c */ +-#line 291 "dtc-parser.y" ++ case 31: ++#line 304 "dtc-parser.y" /* yacc.c:1646 */ + { + (yyval.array).data = empty_data; + (yyval.array).bits = 32; + } ++#line 1756 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 30: +-/* Line 1787 of yacc.c */ +-#line 296 "dtc-parser.y" ++ case 32: ++#line 309 "dtc-parser.y" /* yacc.c:1646 */ + { +- if ((yyvsp[(1) - (2)].array).bits < 64) { +- uint64_t mask = (1ULL << (yyvsp[(1) - (2)].array).bits) - 1; ++ if ((yyvsp[-1].array).bits < 64) { ++ uint64_t mask = (1ULL << (yyvsp[-1].array).bits) - 1; + /* + * Bits above mask must either be all zero + * (positive within range of mask) or all one +@@ -1801,275 +1768,258 @@ yyreduce: + * within the mask to one (i.e. | in the + * mask), all bits are one. + */ +- if (((yyvsp[(2) - (2)].integer) > mask) && (((yyvsp[(2) - (2)].integer) | mask) != -1ULL)) +- print_error( +- "integer value out of range " +- "%016lx (%d bits)", (yyvsp[(1) - (2)].array).bits); ++ if (((yyvsp[0].integer) > mask) && (((yyvsp[0].integer) | mask) != -1ULL)) ++ ERROR(&(yylsp[0]), "Value out of range for" ++ " %d-bit array element", (yyvsp[-1].array).bits); + } + +- (yyval.array).data = data_append_integer((yyvsp[(1) - (2)].array).data, (yyvsp[(2) - (2)].integer), (yyvsp[(1) - (2)].array).bits); ++ (yyval.array).data = data_append_integer((yyvsp[-1].array).data, (yyvsp[0].integer), (yyvsp[-1].array).bits); + } ++#line 1779 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 31: +-/* Line 1787 of yacc.c */ +-#line 316 "dtc-parser.y" ++ case 33: ++#line 328 "dtc-parser.y" /* yacc.c:1646 */ + { +- uint64_t val = ~0ULL >> (64 - (yyvsp[(1) - (2)].array).bits); ++ uint64_t val = ~0ULL >> (64 - (yyvsp[-1].array).bits); + +- if ((yyvsp[(1) - (2)].array).bits == 32) +- (yyvsp[(1) - (2)].array).data = data_add_marker((yyvsp[(1) - (2)].array).data, ++ if ((yyvsp[-1].array).bits == 32) ++ (yyvsp[-1].array).data = data_add_marker((yyvsp[-1].array).data, + REF_PHANDLE, +- (yyvsp[(2) - (2)].labelref)); ++ (yyvsp[0].labelref)); + else +- print_error("References are only allowed in " ++ ERROR(&(yylsp[0]), "References are only allowed in " + "arrays with 32-bit elements."); + +- (yyval.array).data = data_append_integer((yyvsp[(1) - (2)].array).data, val, (yyvsp[(1) - (2)].array).bits); +- } +- break; +- +- case 32: +-/* Line 1787 of yacc.c */ +-#line 330 "dtc-parser.y" +- { +- (yyval.array).data = data_add_marker((yyvsp[(1) - (2)].array).data, LABEL, (yyvsp[(2) - (2)].labelref)); +- } +- break; +- +- case 33: +-/* Line 1787 of yacc.c */ +-#line 337 "dtc-parser.y" +- { +- (yyval.integer) = eval_literal((yyvsp[(1) - (1)].literal), 0, 64); ++ (yyval.array).data = data_append_integer((yyvsp[-1].array).data, val, (yyvsp[-1].array).bits); + } ++#line 1797 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 34: +-/* Line 1787 of yacc.c */ +-#line 341 "dtc-parser.y" ++#line 342 "dtc-parser.y" /* yacc.c:1646 */ + { +- (yyval.integer) = eval_char_literal((yyvsp[(1) - (1)].literal)); ++ (yyval.array).data = data_add_marker((yyvsp[-1].array).data, LABEL, (yyvsp[0].labelref)); + } ++#line 1805 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 35: +-/* Line 1787 of yacc.c */ +-#line 345 "dtc-parser.y" ++ case 37: ++#line 351 "dtc-parser.y" /* yacc.c:1646 */ + { +- (yyval.integer) = (yyvsp[(2) - (3)].integer); ++ (yyval.integer) = (yyvsp[-1].integer); + } +- break; +- +- case 38: +-/* Line 1787 of yacc.c */ +-#line 356 "dtc-parser.y" +- { (yyval.integer) = (yyvsp[(1) - (5)].integer) ? (yyvsp[(3) - (5)].integer) : (yyvsp[(5) - (5)].integer); } ++#line 1813 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 40: +-/* Line 1787 of yacc.c */ +-#line 361 "dtc-parser.y" +- { (yyval.integer) = (yyvsp[(1) - (3)].integer) || (yyvsp[(3) - (3)].integer); } ++#line 362 "dtc-parser.y" /* yacc.c:1646 */ ++ { (yyval.integer) = (yyvsp[-4].integer) ? (yyvsp[-2].integer) : (yyvsp[0].integer); } ++#line 1819 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 42: +-/* Line 1787 of yacc.c */ +-#line 366 "dtc-parser.y" +- { (yyval.integer) = (yyvsp[(1) - (3)].integer) && (yyvsp[(3) - (3)].integer); } ++#line 367 "dtc-parser.y" /* yacc.c:1646 */ ++ { (yyval.integer) = (yyvsp[-2].integer) || (yyvsp[0].integer); } ++#line 1825 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 44: +-/* Line 1787 of yacc.c */ +-#line 371 "dtc-parser.y" +- { (yyval.integer) = (yyvsp[(1) - (3)].integer) | (yyvsp[(3) - (3)].integer); } ++#line 372 "dtc-parser.y" /* yacc.c:1646 */ ++ { (yyval.integer) = (yyvsp[-2].integer) && (yyvsp[0].integer); } ++#line 1831 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 46: +-/* Line 1787 of yacc.c */ +-#line 376 "dtc-parser.y" +- { (yyval.integer) = (yyvsp[(1) - (3)].integer) ^ (yyvsp[(3) - (3)].integer); } ++#line 377 "dtc-parser.y" /* yacc.c:1646 */ ++ { (yyval.integer) = (yyvsp[-2].integer) | (yyvsp[0].integer); } ++#line 1837 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 48: +-/* Line 1787 of yacc.c */ +-#line 381 "dtc-parser.y" +- { (yyval.integer) = (yyvsp[(1) - (3)].integer) & (yyvsp[(3) - (3)].integer); } ++#line 382 "dtc-parser.y" /* yacc.c:1646 */ ++ { (yyval.integer) = (yyvsp[-2].integer) ^ (yyvsp[0].integer); } ++#line 1843 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 50: +-/* Line 1787 of yacc.c */ +-#line 386 "dtc-parser.y" +- { (yyval.integer) = (yyvsp[(1) - (3)].integer) == (yyvsp[(3) - (3)].integer); } ++#line 387 "dtc-parser.y" /* yacc.c:1646 */ ++ { (yyval.integer) = (yyvsp[-2].integer) & (yyvsp[0].integer); } ++#line 1849 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 51: +-/* Line 1787 of yacc.c */ +-#line 387 "dtc-parser.y" +- { (yyval.integer) = (yyvsp[(1) - (3)].integer) != (yyvsp[(3) - (3)].integer); } ++ case 52: ++#line 392 "dtc-parser.y" /* yacc.c:1646 */ ++ { (yyval.integer) = (yyvsp[-2].integer) == (yyvsp[0].integer); } ++#line 1855 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 53: +-/* Line 1787 of yacc.c */ +-#line 392 "dtc-parser.y" +- { (yyval.integer) = (yyvsp[(1) - (3)].integer) < (yyvsp[(3) - (3)].integer); } +- break; +- +- case 54: +-/* Line 1787 of yacc.c */ +-#line 393 "dtc-parser.y" +- { (yyval.integer) = (yyvsp[(1) - (3)].integer) > (yyvsp[(3) - (3)].integer); } ++#line 393 "dtc-parser.y" /* yacc.c:1646 */ ++ { (yyval.integer) = (yyvsp[-2].integer) != (yyvsp[0].integer); } ++#line 1861 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 55: +-/* Line 1787 of yacc.c */ +-#line 394 "dtc-parser.y" +- { (yyval.integer) = (yyvsp[(1) - (3)].integer) <= (yyvsp[(3) - (3)].integer); } ++#line 398 "dtc-parser.y" /* yacc.c:1646 */ ++ { (yyval.integer) = (yyvsp[-2].integer) < (yyvsp[0].integer); } ++#line 1867 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 56: +-/* Line 1787 of yacc.c */ +-#line 395 "dtc-parser.y" +- { (yyval.integer) = (yyvsp[(1) - (3)].integer) >= (yyvsp[(3) - (3)].integer); } ++#line 399 "dtc-parser.y" /* yacc.c:1646 */ ++ { (yyval.integer) = (yyvsp[-2].integer) > (yyvsp[0].integer); } ++#line 1873 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 57: +-/* Line 1787 of yacc.c */ +-#line 399 "dtc-parser.y" +- { (yyval.integer) = (yyvsp[(1) - (3)].integer) << (yyvsp[(3) - (3)].integer); } ++#line 400 "dtc-parser.y" /* yacc.c:1646 */ ++ { (yyval.integer) = (yyvsp[-2].integer) <= (yyvsp[0].integer); } ++#line 1879 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 58: +-/* Line 1787 of yacc.c */ +-#line 400 "dtc-parser.y" +- { (yyval.integer) = (yyvsp[(1) - (3)].integer) >> (yyvsp[(3) - (3)].integer); } ++#line 401 "dtc-parser.y" /* yacc.c:1646 */ ++ { (yyval.integer) = (yyvsp[-2].integer) >= (yyvsp[0].integer); } ++#line 1885 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 60: +-/* Line 1787 of yacc.c */ +-#line 405 "dtc-parser.y" +- { (yyval.integer) = (yyvsp[(1) - (3)].integer) + (yyvsp[(3) - (3)].integer); } ++ case 59: ++#line 405 "dtc-parser.y" /* yacc.c:1646 */ ++ { (yyval.integer) = (yyvsp[-2].integer) << (yyvsp[0].integer); } ++#line 1891 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 61: +-/* Line 1787 of yacc.c */ +-#line 406 "dtc-parser.y" +- { (yyval.integer) = (yyvsp[(1) - (3)].integer) - (yyvsp[(3) - (3)].integer); } ++ case 60: ++#line 406 "dtc-parser.y" /* yacc.c:1646 */ ++ { (yyval.integer) = (yyvsp[-2].integer) >> (yyvsp[0].integer); } ++#line 1897 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 63: +-/* Line 1787 of yacc.c */ +-#line 411 "dtc-parser.y" +- { (yyval.integer) = (yyvsp[(1) - (3)].integer) * (yyvsp[(3) - (3)].integer); } ++ case 62: ++#line 411 "dtc-parser.y" /* yacc.c:1646 */ ++ { (yyval.integer) = (yyvsp[-2].integer) + (yyvsp[0].integer); } ++#line 1903 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 64: +-/* Line 1787 of yacc.c */ +-#line 412 "dtc-parser.y" +- { (yyval.integer) = (yyvsp[(1) - (3)].integer) / (yyvsp[(3) - (3)].integer); } ++ case 63: ++#line 412 "dtc-parser.y" /* yacc.c:1646 */ ++ { (yyval.integer) = (yyvsp[-2].integer) - (yyvsp[0].integer); } ++#line 1909 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 65: +-/* Line 1787 of yacc.c */ +-#line 413 "dtc-parser.y" +- { (yyval.integer) = (yyvsp[(1) - (3)].integer) % (yyvsp[(3) - (3)].integer); } ++#line 417 "dtc-parser.y" /* yacc.c:1646 */ ++ { (yyval.integer) = (yyvsp[-2].integer) * (yyvsp[0].integer); } ++#line 1915 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 68: +-/* Line 1787 of yacc.c */ +-#line 419 "dtc-parser.y" +- { (yyval.integer) = -(yyvsp[(2) - (2)].integer); } ++ case 66: ++#line 418 "dtc-parser.y" /* yacc.c:1646 */ ++ { (yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer); } ++#line 1921 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + +- case 69: +-/* Line 1787 of yacc.c */ +-#line 420 "dtc-parser.y" +- { (yyval.integer) = ~(yyvsp[(2) - (2)].integer); } ++ case 67: ++#line 419 "dtc-parser.y" /* yacc.c:1646 */ ++ { (yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer); } ++#line 1927 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 70: +-/* Line 1787 of yacc.c */ +-#line 421 "dtc-parser.y" +- { (yyval.integer) = !(yyvsp[(2) - (2)].integer); } ++#line 425 "dtc-parser.y" /* yacc.c:1646 */ ++ { (yyval.integer) = -(yyvsp[0].integer); } ++#line 1933 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 71: +-/* Line 1787 of yacc.c */ +-#line 426 "dtc-parser.y" +- { +- (yyval.data) = empty_data; +- } ++#line 426 "dtc-parser.y" /* yacc.c:1646 */ ++ { (yyval.integer) = ~(yyvsp[0].integer); } ++#line 1939 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 72: +-/* Line 1787 of yacc.c */ +-#line 430 "dtc-parser.y" +- { +- (yyval.data) = data_append_byte((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].byte)); +- } ++#line 427 "dtc-parser.y" /* yacc.c:1646 */ ++ { (yyval.integer) = !(yyvsp[0].integer); } ++#line 1945 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 73: +-/* Line 1787 of yacc.c */ +-#line 434 "dtc-parser.y" ++#line 432 "dtc-parser.y" /* yacc.c:1646 */ + { +- (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); ++ (yyval.data) = empty_data; + } ++#line 1953 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 74: +-/* Line 1787 of yacc.c */ +-#line 441 "dtc-parser.y" ++#line 436 "dtc-parser.y" /* yacc.c:1646 */ + { +- (yyval.nodelist) = NULL; ++ (yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte)); + } ++#line 1961 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 75: +-/* Line 1787 of yacc.c */ +-#line 445 "dtc-parser.y" ++#line 440 "dtc-parser.y" /* yacc.c:1646 */ + { +- (yyval.nodelist) = chain_node((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].nodelist)); ++ (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); + } ++#line 1969 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 76: +-/* Line 1787 of yacc.c */ +-#line 449 "dtc-parser.y" ++#line 447 "dtc-parser.y" /* yacc.c:1646 */ + { +- print_error("syntax error: properties must precede subnodes"); +- YYERROR; ++ (yyval.nodelist) = NULL; + } ++#line 1977 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 77: +-/* Line 1787 of yacc.c */ +-#line 457 "dtc-parser.y" ++#line 451 "dtc-parser.y" /* yacc.c:1646 */ + { +- (yyval.node) = name_node((yyvsp[(2) - (2)].node), (yyvsp[(1) - (2)].propnodename)); ++ (yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist)); + } ++#line 1985 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 78: +-/* Line 1787 of yacc.c */ +-#line 461 "dtc-parser.y" ++#line 455 "dtc-parser.y" /* yacc.c:1646 */ + { +- (yyval.node) = name_node(build_node_delete(), (yyvsp[(2) - (3)].propnodename)); ++ ERROR(&(yylsp[0]), "Properties must precede subnodes"); ++ YYERROR; + } ++#line 1994 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + + case 79: +-/* Line 1787 of yacc.c */ +-#line 465 "dtc-parser.y" ++#line 463 "dtc-parser.y" /* yacc.c:1646 */ + { +- add_label(&(yyvsp[(2) - (2)].node)->labels, (yyvsp[(1) - (2)].labelref)); +- (yyval.node) = (yyvsp[(2) - (2)].node); ++ (yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename)); + } ++#line 2002 "dtc-parser.tab.c" /* yacc.c:1646 */ + break; + ++ case 80: ++#line 467 "dtc-parser.y" /* yacc.c:1646 */ ++ { ++ (yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename)); ++ } ++#line 2010 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ break; + +-/* Line 1787 of yacc.c */ +-#line 2073 "dtc-parser.tab.c" ++ case 81: ++#line 471 "dtc-parser.y" /* yacc.c:1646 */ ++ { ++ add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref)); ++ (yyval.node) = (yyvsp[0].node); ++ } ++#line 2019 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ break; ++ ++ ++#line 2023 "dtc-parser.tab.c" /* yacc.c:1646 */ + default: break; + } + /* User semantic actions sometimes alter yychar, and that requires +@@ -2090,8 +2040,9 @@ yyreduce: + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; ++ *++yylsp = yyloc; + +- /* Now `shift' the result of the reduction. Determine what state ++ /* Now 'shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + +@@ -2106,9 +2057,9 @@ yyreduce: + goto yynewstate; + + +-/*------------------------------------. +-| yyerrlab -- here on detecting error | +-`------------------------------------*/ ++/*--------------------------------------. ++| yyerrlab -- here on detecting error. | ++`--------------------------------------*/ + yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ +@@ -2154,25 +2105,25 @@ yyerrlab: + #endif + } + +- ++ yyerror_range[1] = yylloc; + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an +- error, discard it. */ ++ error, discard it. */ + + if (yychar <= YYEOF) +- { +- /* Return failure if at end of input. */ +- if (yychar == YYEOF) +- YYABORT; +- } ++ { ++ /* Return failure if at end of input. */ ++ if (yychar == YYEOF) ++ YYABORT; ++ } + else +- { +- yydestruct ("Error: discarding", +- yytoken, &yylval); +- yychar = YYEMPTY; +- } ++ { ++ yydestruct ("Error: discarding", ++ yytoken, &yylval, &yylloc); ++ yychar = YYEMPTY; ++ } + } + + /* Else will try to reuse lookahead token after shifting the error +@@ -2191,7 +2142,8 @@ yyerrorlab: + if (/*CONSTCOND*/ 0) + goto yyerrorlab; + +- /* Do not reclaim the symbols of the rule which action triggered ++ yyerror_range[1] = yylsp[1-yylen]; ++ /* Do not reclaim the symbols of the rule whose action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; +@@ -2204,29 +2156,29 @@ yyerrorlab: + | yyerrlab1 -- common code for both syntax error and YYERROR. | + `-------------------------------------------------------------*/ + yyerrlab1: +- yyerrstatus = 3; /* Each real token shifted decrements this. */ ++ yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (!yypact_value_is_default (yyn)) +- { +- yyn += YYTERROR; +- if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) +- { +- yyn = yytable[yyn]; +- if (0 < yyn) +- break; +- } +- } ++ { ++ yyn += YYTERROR; ++ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) ++ { ++ yyn = yytable[yyn]; ++ if (0 < yyn) ++ break; ++ } ++ } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) +- YYABORT; +- ++ YYABORT; + ++ yyerror_range[1] = *yylsp; + yydestruct ("Error: popping", +- yystos[yystate], yyvsp); ++ yystos[yystate], yyvsp, yylsp); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); +@@ -2236,6 +2188,11 @@ yyerrlab1: + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + ++ yyerror_range[2] = yylloc; ++ /* Using YYLLOC is tempting, but would change the location of ++ the lookahead. YYLOC is available though. */ ++ YYLLOC_DEFAULT (yyloc, yyerror_range, 2); ++ *++yylsp = yyloc; + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); +@@ -2275,16 +2232,16 @@ yyreturn: + user semantic actions for why this is necessary. */ + yytoken = YYTRANSLATE (yychar); + yydestruct ("Cleanup: discarding lookahead", +- yytoken, &yylval); ++ yytoken, &yylval, &yylloc); + } +- /* Do not reclaim the symbols of the rule which action triggered ++ /* Do not reclaim the symbols of the rule whose action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", +- yystos[*yyssp], yyvsp); ++ yystos[*yyssp], yyvsp, yylsp); + YYPOPSTACK (1); + } + #ifndef yyoverflow +@@ -2295,72 +2252,12 @@ yyreturn: + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + #endif +- /* Make sure YYID is used. */ +- return YYID (yyresult); ++ return yyresult; + } ++#line 477 "dtc-parser.y" /* yacc.c:1906 */ + + +-/* Line 2050 of yacc.c */ +-#line 471 "dtc-parser.y" +- +- +-void print_error(char const *fmt, ...) +-{ +- va_list va; +- +- va_start(va, fmt); +- srcpos_verror(&yylloc, fmt, va); +- va_end(va); +- +- treesource_error = 1; +-} +- +-void yyerror(char const *s) { +- print_error("%s", s); +-} +- +-static unsigned long long eval_literal(const char *s, int base, int bits) +-{ +- unsigned long long val; +- char *e; +- +- errno = 0; +- val = strtoull(s, &e, base); +- if (*e) { +- size_t uls = strspn(e, "UL"); +- if (e[uls]) +- print_error("bad characters in literal"); +- } +- if ((errno == ERANGE) +- || ((bits < 64) && (val >= (1ULL << bits)))) +- print_error("literal out of range"); +- else if (errno != 0) +- print_error("bad literal"); +- return val; +-} +- +-static unsigned char eval_char_literal(const char *s) ++void yyerror(char const *s) + { +- int i = 1; +- char c = s[0]; +- +- if (c == '\0') +- { +- print_error("empty character literal"); +- return 0; +- } +- +- /* +- * If the first character in the character literal is a \ then process +- * the remaining characters as an escape encoding. If the first +- * character is neither an escape or a terminator it should be the only +- * character in the literal and will be returned. +- */ +- if (c == '\\') +- c = get_escape_char(s, &i); +- +- if (s[i] != '\0') +- print_error("malformed character literal"); +- +- return c; ++ ERROR(&yylloc, "%s", s); + } +diff --git a/scripts/dtc/dtc-parser.tab.h_shipped b/scripts/dtc/dtc-parser.tab.h_shipped +index b2e7a86..b497956 100644 +--- a/scripts/dtc/dtc-parser.tab.h_shipped ++++ b/scripts/dtc/dtc-parser.tab.h_shipped +@@ -1,19 +1,19 @@ +-/* A Bison parser, made by GNU Bison 2.7.12-4996. */ ++/* A Bison parser, made by GNU Bison 3.0.2. */ + + /* Bison interface for Yacc-like parsers in C +- +- Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. +- ++ ++ Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. ++ + 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 3 of the License, or + (at your option) any later version. +- ++ + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. +- ++ + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +@@ -26,13 +26,13 @@ + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. +- ++ + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + + #ifndef YY_YY_DTC_PARSER_TAB_H_INCLUDED + # define YY_YY_DTC_PARSER_TAB_H_INCLUDED +-/* Enabling traces. */ ++/* Debug traces. */ + #ifndef YYDEBUG + # define YYDEBUG 0 + #endif +@@ -40,48 +40,45 @@ + extern int yydebug; + #endif + +-/* Tokens. */ ++/* Token type. */ + #ifndef YYTOKENTYPE + # define YYTOKENTYPE +- /* Put the tokens into the symbol table, so that GDB and other debuggers +- know about them. */ +- enum yytokentype { +- DT_V1 = 258, +- DT_MEMRESERVE = 259, +- DT_LSHIFT = 260, +- DT_RSHIFT = 261, +- DT_LE = 262, +- DT_GE = 263, +- DT_EQ = 264, +- DT_NE = 265, +- DT_AND = 266, +- DT_OR = 267, +- DT_BITS = 268, +- DT_DEL_PROP = 269, +- DT_DEL_NODE = 270, +- DT_PROPNODENAME = 271, +- DT_LITERAL = 272, +- DT_CHAR_LITERAL = 273, +- DT_BASE = 274, +- DT_BYTE = 275, +- DT_STRING = 276, +- DT_LABEL = 277, +- DT_REF = 278, +- DT_INCBIN = 279 +- }; ++ enum yytokentype ++ { ++ DT_V1 = 258, ++ DT_PLUGIN = 259, ++ DT_MEMRESERVE = 260, ++ DT_LSHIFT = 261, ++ DT_RSHIFT = 262, ++ DT_LE = 263, ++ DT_GE = 264, ++ DT_EQ = 265, ++ DT_NE = 266, ++ DT_AND = 267, ++ DT_OR = 268, ++ DT_BITS = 269, ++ DT_DEL_PROP = 270, ++ DT_DEL_NODE = 271, ++ DT_PROPNODENAME = 272, ++ DT_LITERAL = 273, ++ DT_CHAR_LITERAL = 274, ++ DT_BYTE = 275, ++ DT_STRING = 276, ++ DT_LABEL = 277, ++ DT_REF = 278, ++ DT_INCBIN = 279 ++ }; + #endif + +- ++/* Value type. */ + #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +-typedef union YYSTYPE ++typedef union YYSTYPE YYSTYPE; ++union YYSTYPE + { +-/* Line 2053 of yacc.c */ +-#line 40 "dtc-parser.y" ++#line 39 "dtc-parser.y" /* yacc.c:1909 */ + + char *propnodename; +- char *literal; + char *labelref; +- unsigned int cbase; + uint8_t byte; + struct data data; + +@@ -96,30 +93,31 @@ typedef union YYSTYPE + struct node *nodelist; + struct reserve_info *re; + uint64_t integer; ++ int is_plugin; + +- +-/* Line 2053 of yacc.c */ +-#line 103 "dtc-parser.tab.h" +-} YYSTYPE; ++#line 99 "dtc-parser.tab.h" /* yacc.c:1909 */ ++}; + # define YYSTYPE_IS_TRIVIAL 1 +-# define yystype YYSTYPE /* obsolescent; will be withdrawn */ + # define YYSTYPE_IS_DECLARED 1 + #endif + +-extern YYSTYPE yylval; +- +-#ifdef YYPARSE_PARAM +-#if defined __STDC__ || defined __cplusplus +-int yyparse (void *YYPARSE_PARAM); +-#else +-int yyparse (); ++/* Location type. */ ++#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED ++typedef struct YYLTYPE YYLTYPE; ++struct YYLTYPE ++{ ++ int first_line; ++ int first_column; ++ int last_line; ++ int last_column; ++}; ++# define YYLTYPE_IS_DECLARED 1 ++# define YYLTYPE_IS_TRIVIAL 1 + #endif +-#else /* ! YYPARSE_PARAM */ +-#if defined __STDC__ || defined __cplusplus ++ ++ ++extern YYSTYPE yylval; ++extern YYLTYPE yylloc; + int yyparse (void); +-#else +-int yyparse (); +-#endif +-#endif /* ! YYPARSE_PARAM */ + + #endif /* !YY_YY_DTC_PARSER_TAB_H_INCLUDED */ +diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y +index f412460..687ccad 100644 +--- a/scripts/dtc/dtc-parser.y ++++ b/scripts/dtc/dtc-parser.y +@@ -17,31 +17,28 @@ + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ +- + %{ + #include ++#include + + #include "dtc.h" + #include "srcpos.h" + +-YYLTYPE yylloc; +- + extern int yylex(void); +-extern void print_error(char const *fmt, ...); + extern void yyerror(char const *s); ++#define ERROR(loc, ...) \ ++ do { \ ++ srcpos_error((loc), "Error", __VA_ARGS__); \ ++ treesource_error = true; \ ++ } while (0) + + extern struct boot_info *the_boot_info; +-extern int treesource_error; +- +-static unsigned long long eval_literal(const char *s, int base, int bits); +-static unsigned char eval_char_literal(const char *s); ++extern bool treesource_error; + %} + + %union { + char *propnodename; +- char *literal; + char *labelref; +- unsigned int cbase; + uint8_t byte; + struct data data; + +@@ -56,18 +53,19 @@ static unsigned char eval_char_literal(const char *s); + struct node *nodelist; + struct reserve_info *re; + uint64_t integer; ++ int is_plugin; + } + + %token DT_V1 ++%token DT_PLUGIN + %token DT_MEMRESERVE + %token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ DT_NE DT_AND DT_OR + %token DT_BITS + %token DT_DEL_PROP + %token DT_DEL_NODE + %token DT_PROPNODENAME +-%token DT_LITERAL +-%token DT_CHAR_LITERAL +-%token DT_BASE ++%token DT_LITERAL ++%token DT_CHAR_LITERAL + %token DT_BYTE + %token DT_STRING + %token DT_LABEL +@@ -76,6 +74,7 @@ static unsigned char eval_char_literal(const char *s); + + %type propdata + %type propdataprefix ++%type plugindecl + %type memreserve + %type memreserves + %type arrayprefix +@@ -106,10 +105,23 @@ static unsigned char eval_char_literal(const char *s); + %% + + sourcefile: +- DT_V1 ';' memreserves devicetree ++ DT_V1 ';' plugindecl memreserves devicetree ++ { ++ $5->is_plugin = $3; ++ $5->is_root = 1; ++ the_boot_info = build_boot_info($4, $5, ++ guess_boot_cpuid($5)); ++ } ++ ; ++ ++plugindecl: ++ /* empty */ ++ { ++ $$ = 0; ++ } ++ | DT_PLUGIN ';' + { +- the_boot_info = build_boot_info($3, $4, +- guess_boot_cpuid($4)); ++ $$ = 1; + } + ; + +@@ -152,17 +164,18 @@ devicetree: + if (target) + merge_nodes(target, $3); + else +- print_error("label or path, '%s', not found", $2); ++ ERROR(&@2, "Label or path %s not found", $2); + $$ = $1; + } + | devicetree DT_DEL_NODE DT_REF ';' + { + struct node *target = get_node_by_ref($1, $3); + +- if (!target) +- print_error("label or path, '%s', not found", $3); +- else ++ if (target) + delete_node(target); ++ else ++ ERROR(&@3, "Label or path %s not found", $3); ++ + + $$ = $1; + } +@@ -230,10 +243,9 @@ propdata: + + if ($6 != 0) + if (fseek(f, $6, SEEK_SET) != 0) +- print_error("Couldn't seek to offset %llu in \"%s\": %s", +- (unsigned long long)$6, +- $4.val, +- strerror(errno)); ++ die("Couldn't seek to offset %llu in \"%s\": %s", ++ (unsigned long long)$6, $4.val, ++ strerror(errno)); + + d = data_copy_file(f, $8); + +@@ -274,18 +286,19 @@ propdataprefix: + arrayprefix: + DT_BITS DT_LITERAL '<' + { +- $$.data = empty_data; +- $$.bits = eval_literal($2, 0, 7); +- +- if (($$.bits != 8) && +- ($$.bits != 16) && +- ($$.bits != 32) && +- ($$.bits != 64)) +- { +- print_error("Only 8, 16, 32 and 64-bit elements" +- " are currently supported"); +- $$.bits = 32; ++ unsigned long long bits; ++ ++ bits = $2; ++ ++ if ((bits != 8) && (bits != 16) && ++ (bits != 32) && (bits != 64)) { ++ ERROR(&@2, "Array elements must be" ++ " 8, 16, 32 or 64-bits"); ++ bits = 32; + } ++ ++ $$.data = empty_data; ++ $$.bits = bits; + } + | '<' + { +@@ -305,9 +318,8 @@ arrayprefix: + * mask), all bits are one. + */ + if (($2 > mask) && (($2 | mask) != -1ULL)) +- print_error( +- "integer value out of range " +- "%016lx (%d bits)", $1.bits); ++ ERROR(&@2, "Value out of range for" ++ " %d-bit array element", $1.bits); + } + + $$.data = data_append_integer($1.data, $2, $1.bits); +@@ -321,7 +333,7 @@ arrayprefix: + REF_PHANDLE, + $2); + else +- print_error("References are only allowed in " ++ ERROR(&@2, "References are only allowed in " + "arrays with 32-bit elements."); + + $$.data = data_append_integer($1.data, val, $1.bits); +@@ -334,13 +346,7 @@ arrayprefix: + + integer_prim: + DT_LITERAL +- { +- $$ = eval_literal($1, 0, 64); +- } + | DT_CHAR_LITERAL +- { +- $$ = eval_char_literal($1); +- } + | '(' integer_expr ')' + { + $$ = $2; +@@ -447,7 +453,7 @@ subnodes: + } + | subnode propdef + { +- print_error("syntax error: properties must precede subnodes"); ++ ERROR(&@2, "Properties must precede subnodes"); + YYERROR; + } + ; +@@ -470,63 +476,7 @@ subnode: + + %% + +-void print_error(char const *fmt, ...) +-{ +- va_list va; +- +- va_start(va, fmt); +- srcpos_verror(&yylloc, fmt, va); +- va_end(va); +- +- treesource_error = 1; +-} +- +-void yyerror(char const *s) { +- print_error("%s", s); +-} +- +-static unsigned long long eval_literal(const char *s, int base, int bits) +-{ +- unsigned long long val; +- char *e; +- +- errno = 0; +- val = strtoull(s, &e, base); +- if (*e) { +- size_t uls = strspn(e, "UL"); +- if (e[uls]) +- print_error("bad characters in literal"); +- } +- if ((errno == ERANGE) +- || ((bits < 64) && (val >= (1ULL << bits)))) +- print_error("literal out of range"); +- else if (errno != 0) +- print_error("bad literal"); +- return val; +-} +- +-static unsigned char eval_char_literal(const char *s) ++void yyerror(char const *s) + { +- int i = 1; +- char c = s[0]; +- +- if (c == '\0') +- { +- print_error("empty character literal"); +- return 0; +- } +- +- /* +- * If the first character in the character literal is a \ then process +- * the remaining characters as an escape encoding. If the first +- * character is neither an escape or a terminator it should be the only +- * character in the literal and will be returned. +- */ +- if (c == '\\') +- c = get_escape_char(s, &i); +- +- if (s[i] != '\0') +- print_error("malformed character literal"); +- +- return c; ++ ERROR(&yylloc, "%s", s); + } +diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c +index e3c9653..0cbb14c 100644 +--- a/scripts/dtc/dtc.c ++++ b/scripts/dtc/dtc.c +@@ -29,6 +29,7 @@ int reservenum; /* Number of memory reservation slots */ + int minsize; /* Minimum blob size */ + int padsize; /* Additional padding to blob */ + int phandle_format = PHANDLE_BOTH; /* Use linux,phandle or phandle properties */ ++int symbol_fixup_support = 0; + + static void fill_fullpaths(struct node *tree, const char *prefix) + { +@@ -48,8 +49,10 @@ static void fill_fullpaths(struct node *tree, const char *prefix) + } + + /* Usage related data. */ ++#define FDT_VERSION(version) _FDT_VERSION(version) ++#define _FDT_VERSION(version) #version + static const char usage_synopsis[] = "dtc [options] "; +-static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:hv"; ++static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:hv@"; + static struct option const usage_long_opts[] = { + {"quiet", no_argument, NULL, 'q'}, + {"in-format", a_argument, NULL, 'I'}, +@@ -67,6 +70,7 @@ static struct option const usage_long_opts[] = { + {"phandle", a_argument, NULL, 'H'}, + {"warning", a_argument, NULL, 'W'}, + {"error", a_argument, NULL, 'E'}, ++ {"symbols", a_argument, NULL, '@'}, + {"help", no_argument, NULL, 'h'}, + {"version", no_argument, NULL, 'v'}, + {NULL, no_argument, NULL, 0x0}, +@@ -82,9 +86,9 @@ static const char * const usage_opts_help[] = { + "\t\tdts - device tree source text\n" + "\t\tdtb - device tree blob\n" + "\t\tasm - assembler source", +- "\n\tBlob version to produce, defaults to %d (for dtb and asm output)", //, DEFAULT_FDT_VERSION); ++ "\n\tBlob version to produce, defaults to "FDT_VERSION(DEFAULT_FDT_VERSION)" (for dtb and asm output)", + "\n\tOutput dependency file", +- "\n\ttMake space for reserve map entries (for dtb and asm output)", ++ "\n\tMake space for reserve map entries (for dtb and asm output)", + "\n\tMake the blob at least long (extra space)", + "\n\tAdd padding to the blob of long (extra space)", + "\n\tSet the physical boot cpu", +@@ -97,6 +101,7 @@ static const char * const usage_opts_help[] = { + "\t\tboth - Both \"linux,phandle\" and \"phandle\" properties", + "\n\tEnable/disable warnings (prefix with \"no-\")", + "\n\tEnable/disable errors (prefix with \"no-\")", ++ "\n\tSymbols and Fixups support", + "\n\tPrint this help and exit", + "\n\tPrint version and exit", + NULL, +@@ -109,7 +114,7 @@ int main(int argc, char *argv[]) + const char *outform = "dts"; + const char *outname = "-"; + const char *depname = NULL; +- int force = 0, sort = 0; ++ bool force = false, sort = false; + const char *arg; + int opt; + FILE *outf = NULL; +@@ -148,7 +153,7 @@ int main(int argc, char *argv[]) + padsize = strtol(optarg, NULL, 0); + break; + case 'f': +- force = 1; ++ force = true; + break; + case 'q': + quiet++; +@@ -174,7 +179,7 @@ int main(int argc, char *argv[]) + break; + + case 's': +- sort = 1; ++ sort = true; + break; + + case 'W': +@@ -184,7 +189,9 @@ int main(int argc, char *argv[]) + case 'E': + parse_checks_option(false, true, optarg); + break; +- ++ case '@': ++ symbol_fixup_support = 1; ++ break; + case 'h': + usage(NULL); + default: +@@ -237,7 +244,7 @@ int main(int argc, char *argv[]) + if (streq(outname, "-")) { + outf = stdout; + } else { +- outf = fopen(outname, "w"); ++ outf = fopen(outname, "wb"); + if (! outf) + die("Couldn't open output file %s: %s\n", + outname, strerror(errno)); +diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h +index 264a20c..fe45748 100644 +--- a/scripts/dtc/dtc.h ++++ b/scripts/dtc/dtc.h +@@ -38,9 +38,9 @@ + #include "util.h" + + #ifdef DEBUG +-#define debug(fmt,args...) printf(fmt, ##args) ++#define debug(...) printf(__VA_ARGS__) + #else +-#define debug(fmt,args...) ++#define debug(...) + #endif + + +@@ -54,6 +54,7 @@ extern int reservenum; /* Number of memory reservation slots */ + extern int minsize; /* Minimum blob size */ + extern int padsize; /* Additional padding to blob */ + extern int phandle_format; /* Use linux,phandle or phandle properties */ ++extern int symbol_fixup_support;/* enable symbols & fixup support */ + + #define PHANDLE_LEGACY 0x1 + #define PHANDLE_EPAPR 0x2 +@@ -88,7 +89,7 @@ struct data { + }; + + +-#define empty_data ((struct data){ /* all .members = 0 or NULL */ }) ++#define empty_data ((struct data){ 0 /* all .members = 0 or NULL */ }) + + #define for_each_marker(m) \ + for (; (m); (m) = (m)->next) +@@ -118,7 +119,7 @@ struct data data_append_align(struct data d, int align); + + struct data data_add_marker(struct data d, enum markertype type, char *ref); + +-int data_is_one_string(struct data d); ++bool data_is_one_string(struct data d); + + /* DT constraints */ + +@@ -127,13 +128,32 @@ int data_is_one_string(struct data d); + + /* Live trees */ + struct label { +- int deleted; ++ bool deleted; + char *label; + struct label *next; + }; + ++struct fixup_entry { ++ int offset; ++ struct node *node; ++ struct property *prop; ++ struct fixup_entry *next; ++}; ++ ++struct fixup { ++ char *ref; ++ struct fixup_entry *entries; ++ struct fixup *next; ++}; ++ ++struct symbol { ++ struct label *label; ++ struct node *node; ++ struct symbol *next; ++}; ++ + struct property { +- int deleted; ++ bool deleted; + char *name; + struct data val; + +@@ -143,7 +163,7 @@ struct property { + }; + + struct node { +- int deleted; ++ bool deleted; + char *name; + struct property *proplist; + struct node *children; +@@ -158,6 +178,12 @@ struct node { + int addr_cells, size_cells; + + struct label *labels; ++ ++ int is_root; ++ int is_plugin; ++ struct fixup *fixups; ++ struct symbol *symbols; ++ struct fixup_entry *local_fixups; + }; + + #define for_each_label_withdel(l0, l) \ +@@ -181,6 +207,18 @@ struct node { + for_each_child_withdel(n, c) \ + if (!(c)->deleted) + ++#define for_each_fixup(n, f) \ ++ for ((f) = (n)->fixups; (f); (f) = (f)->next) ++ ++#define for_each_fixup_entry(f, fe) \ ++ for ((fe) = (f)->entries; (fe); (fe) = (fe)->next) ++ ++#define for_each_symbol(n, s) \ ++ for ((s) = (n)->symbols; (s); (s) = (s)->next) ++ ++#define for_each_local_fixup_entry(n, fe) \ ++ for ((fe) = (n)->local_fixups; (fe); (fe) = (fe)->next) ++ + void add_label(struct label **labels, char *label); + void delete_labels(struct label **labels); + +@@ -247,8 +285,8 @@ void sort_tree(struct boot_info *bi); + + /* Checks */ + +-void parse_checks_option(bool warn, bool error, const char *optarg); +-void process_checks(int force, struct boot_info *bi); ++void parse_checks_option(bool warn, bool error, const char *arg); ++void process_checks(bool force, struct boot_info *bi); + + /* Flattened trees */ + +diff --git a/scripts/dtc/flattree.c b/scripts/dtc/flattree.c +index 665dad7..f439b40 100644 +--- a/scripts/dtc/flattree.c ++++ b/scripts/dtc/flattree.c +@@ -261,7 +261,13 @@ static void flatten_tree(struct node *tree, struct emitter *emit, + { + struct property *prop; + struct node *child; +- int seen_name_prop = 0; ++ bool seen_name_prop = false; ++ struct symbol *sym; ++ struct fixup *f; ++ struct fixup_entry *fe; ++ char *name, *s; ++ const char *fullpath; ++ int namesz, nameoff, vallen; + + if (tree->deleted) + return; +@@ -276,10 +282,8 @@ static void flatten_tree(struct node *tree, struct emitter *emit, + emit->align(etarget, sizeof(cell_t)); + + for_each_property(tree, prop) { +- int nameoff; +- + if (streq(prop->name, "name")) +- seen_name_prop = 1; ++ seen_name_prop = true; + + nameoff = stringtable_insert(strbuf, prop->name); + +@@ -310,6 +314,139 @@ static void flatten_tree(struct node *tree, struct emitter *emit, + flatten_tree(child, emit, etarget, strbuf, vi); + } + ++ if (!symbol_fixup_support) ++ goto no_symbols; ++ ++ /* add the symbol nodes (if any) */ ++ if (tree->symbols) { ++ ++ emit->beginnode(etarget, NULL); ++ emit->string(etarget, "__symbols__", 0); ++ emit->align(etarget, sizeof(cell_t)); ++ ++ for_each_symbol(tree, sym) { ++ ++ vallen = strlen(sym->node->fullpath); ++ ++ nameoff = stringtable_insert(strbuf, sym->label->label); ++ ++ emit->property(etarget, NULL); ++ emit->cell(etarget, vallen + 1); ++ emit->cell(etarget, nameoff); ++ ++ if ((vi->flags & FTF_VARALIGN) && vallen >= 8) ++ emit->align(etarget, 8); ++ ++ emit->string(etarget, sym->node->fullpath, ++ strlen(sym->node->fullpath)); ++ emit->align(etarget, sizeof(cell_t)); ++ } ++ ++ emit->endnode(etarget, NULL); ++ } ++ ++ /* add the fixup nodes */ ++ if (tree->fixups) { ++ ++ /* emit the external fixups */ ++ emit->beginnode(etarget, NULL); ++ emit->string(etarget, "__fixups__", 0); ++ emit->align(etarget, sizeof(cell_t)); ++ ++ for_each_fixup(tree, f) { ++ ++ namesz = 0; ++ for_each_fixup_entry(f, fe) { ++ fullpath = fe->node->fullpath; ++ if (fullpath[0] == '\0') ++ fullpath = "/"; ++ namesz += strlen(fullpath) + 1; ++ namesz += strlen(fe->prop->name) + 1; ++ namesz += 32; /* space for : + '\0' */ ++ } ++ ++ name = xmalloc(namesz); ++ ++ s = name; ++ for_each_fixup_entry(f, fe) { ++ fullpath = fe->node->fullpath; ++ if (fullpath[0] == '\0') ++ fullpath = "/"; ++ snprintf(s, name + namesz - s, "%s:%s:%d", ++ fullpath, ++ fe->prop->name, fe->offset); ++ s += strlen(s) + 1; ++ } ++ ++ nameoff = stringtable_insert(strbuf, f->ref); ++ vallen = s - name - 1; ++ ++ emit->property(etarget, NULL); ++ emit->cell(etarget, vallen + 1); ++ emit->cell(etarget, nameoff); ++ ++ if ((vi->flags & FTF_VARALIGN) && vallen >= 8) ++ emit->align(etarget, 8); ++ ++ emit->string(etarget, name, vallen); ++ emit->align(etarget, sizeof(cell_t)); ++ ++ free(name); ++ } ++ ++ emit->endnode(etarget, tree->labels); ++ } ++ ++ /* add the local fixup property */ ++ if (tree->local_fixups) { ++ ++ /* emit the external fixups */ ++ emit->beginnode(etarget, NULL); ++ emit->string(etarget, "__local_fixups__", 0); ++ emit->align(etarget, sizeof(cell_t)); ++ ++ namesz = 0; ++ for_each_local_fixup_entry(tree, fe) { ++ fullpath = fe->node->fullpath; ++ if (fullpath[0] == '\0') ++ fullpath = "/"; ++ namesz += strlen(fullpath) + 1; ++ namesz += strlen(fe->prop->name) + 1; ++ namesz += 32; /* space for : + '\0' */ ++ } ++ ++ name = xmalloc(namesz); ++ ++ s = name; ++ for_each_local_fixup_entry(tree, fe) { ++ fullpath = fe->node->fullpath; ++ if (fullpath[0] == '\0') ++ fullpath = "/"; ++ snprintf(s, name + namesz - s, "%s:%s:%d", ++ fullpath, fe->prop->name, ++ fe->offset); ++ s += strlen(s) + 1; ++ } ++ ++ nameoff = stringtable_insert(strbuf, "fixup"); ++ vallen = s - name - 1; ++ ++ emit->property(etarget, NULL); ++ emit->cell(etarget, vallen + 1); ++ emit->cell(etarget, nameoff); ++ ++ if ((vi->flags & FTF_VARALIGN) && vallen >= 8) ++ emit->align(etarget, 8); ++ ++ emit->string(etarget, name, vallen); ++ emit->align(etarget, sizeof(cell_t)); ++ ++ free(name); ++ ++ emit->endnode(etarget, tree->labels); ++ } ++ ++no_symbols: + emit->endnode(etarget, tree->labels); + } + +diff --git a/scripts/dtc/fstree.c b/scripts/dtc/fstree.c +index e464727..6e5878a 100644 +--- a/scripts/dtc/fstree.c ++++ b/scripts/dtc/fstree.c +@@ -37,26 +37,26 @@ static struct node *read_fstree(const char *dirname) + tree = build_node(NULL, NULL); + + while ((de = readdir(d)) != NULL) { +- char *tmpnam; ++ char *tmpname; + + if (streq(de->d_name, ".") + || streq(de->d_name, "..")) + continue; + +- tmpnam = join_path(dirname, de->d_name); ++ tmpname = join_path(dirname, de->d_name); + +- if (lstat(tmpnam, &st) < 0) +- die("stat(%s): %s\n", tmpnam, strerror(errno)); ++ if (lstat(tmpname, &st) < 0) ++ die("stat(%s): %s\n", tmpname, strerror(errno)); + + if (S_ISREG(st.st_mode)) { + struct property *prop; + FILE *pfile; + +- pfile = fopen(tmpnam, "r"); ++ pfile = fopen(tmpname, "rb"); + if (! pfile) { + fprintf(stderr, + "WARNING: Cannot open %s: %s\n", +- tmpnam, strerror(errno)); ++ tmpname, strerror(errno)); + } else { + prop = build_property(xstrdup(de->d_name), + data_copy_file(pfile, +@@ -67,12 +67,12 @@ static struct node *read_fstree(const char *dirname) + } else if (S_ISDIR(st.st_mode)) { + struct node *newchild; + +- newchild = read_fstree(tmpnam); ++ newchild = read_fstree(tmpname); + newchild = name_node(newchild, xstrdup(de->d_name)); + add_child(tree, newchild); + } + +- free(tmpnam); ++ free(tmpname); + } + + closedir(d); +diff --git a/scripts/dtc/livetree.c b/scripts/dtc/livetree.c +index b61465f..e229b84 100644 +--- a/scripts/dtc/livetree.c ++++ b/scripts/dtc/livetree.c +@@ -511,7 +511,9 @@ struct node *get_node_by_phandle(struct node *tree, cell_t phandle) + + struct node *get_node_by_ref(struct node *tree, const char *ref) + { +- if (ref[0] == '/') ++ if (streq(ref, "/")) ++ return tree; ++ else if (ref[0] == '/') + return get_node_by_path(tree, ref); + else + return get_node_by_label(tree, ref); +diff --git a/scripts/dtc/srcpos.c b/scripts/dtc/srcpos.c +index c20bc53..f534c22 100644 +--- a/scripts/dtc/srcpos.c ++++ b/scripts/dtc/srcpos.c +@@ -34,7 +34,7 @@ struct search_path { + static struct search_path *search_path_head, **search_path_tail; + + +-static char *dirname(const char *path) ++static char *get_dirname(const char *path) + { + const char *slash = strrchr(path, '/'); + +@@ -77,7 +77,7 @@ static char *try_open(const char *dirname, const char *fname, FILE **fp) + else + fullname = join_path(dirname, fname); + +- *fp = fopen(fullname, "r"); ++ *fp = fopen(fullname, "rb"); + if (!*fp) { + free(fullname); + fullname = NULL; +@@ -150,7 +150,7 @@ void srcfile_push(const char *fname) + srcfile = xmalloc(sizeof(*srcfile)); + + srcfile->f = srcfile_relative_open(fname, &srcfile->name); +- srcfile->dir = dirname(srcfile->name); ++ srcfile->dir = get_dirname(srcfile->name); + srcfile->prev = current_srcfile; + + srcfile->lineno = 1; +@@ -159,7 +159,7 @@ void srcfile_push(const char *fname) + current_srcfile = srcfile; + } + +-int srcfile_pop(void) ++bool srcfile_pop(void) + { + struct srcfile_state *srcfile = current_srcfile; + +@@ -177,7 +177,7 @@ int srcfile_pop(void) + * fix this we could either allocate all the files from a + * table, or use a pool allocator. */ + +- return current_srcfile ? 1 : 0; ++ return current_srcfile ? true : false; + } + + void srcfile_add_search_path(const char *dirname) +@@ -290,42 +290,27 @@ srcpos_string(struct srcpos *pos) + return pos_str; + } + +-void +-srcpos_verror(struct srcpos *pos, char const *fmt, va_list va) ++void srcpos_verror(struct srcpos *pos, const char *prefix, ++ const char *fmt, va_list va) + { +- const char *srcstr; +- +- srcstr = srcpos_string(pos); ++ char *srcstr; + +- fprintf(stderr, "Error: %s ", srcstr); +- vfprintf(stderr, fmt, va); +- fprintf(stderr, "\n"); +-} ++ srcstr = srcpos_string(pos); + +-void +-srcpos_error(struct srcpos *pos, char const *fmt, ...) +-{ +- va_list va; ++ fprintf(stderr, "%s: %s ", prefix, srcstr); ++ vfprintf(stderr, fmt, va); ++ fprintf(stderr, "\n"); + +- va_start(va, fmt); +- srcpos_verror(pos, fmt, va); +- va_end(va); ++ free(srcstr); + } + +- +-void +-srcpos_warn(struct srcpos *pos, char const *fmt, ...) ++void srcpos_error(struct srcpos *pos, const char *prefix, ++ const char *fmt, ...) + { +- const char *srcstr; + va_list va; +- va_start(va, fmt); +- +- srcstr = srcpos_string(pos); +- +- fprintf(stderr, "Warning: %s ", srcstr); +- vfprintf(stderr, fmt, va); +- fprintf(stderr, "\n"); + ++ va_start(va, fmt); ++ srcpos_verror(pos, prefix, fmt, va); + va_end(va); + } + +diff --git a/scripts/dtc/srcpos.h b/scripts/dtc/srcpos.h +index 93a2712..f81827b 100644 +--- a/scripts/dtc/srcpos.h ++++ b/scripts/dtc/srcpos.h +@@ -21,6 +21,7 @@ + #define _SRCPOS_H_ + + #include ++#include + + struct srcfile_state { + FILE *f; +@@ -55,7 +56,7 @@ extern struct srcfile_state *current_srcfile; /* = NULL */ + FILE *srcfile_relative_open(const char *fname, char **fullnamep); + + void srcfile_push(const char *fname); +-int srcfile_pop(void); ++bool srcfile_pop(void); + + /** + * Add a new directory to the search path for input files +@@ -106,12 +107,12 @@ extern struct srcpos *srcpos_copy(struct srcpos *pos); + extern char *srcpos_string(struct srcpos *pos); + extern void srcpos_dump(struct srcpos *pos); + +-extern void srcpos_verror(struct srcpos *pos, char const *, va_list va) +- __attribute__((format(printf, 2, 0))); +-extern void srcpos_error(struct srcpos *pos, char const *, ...) +- __attribute__((format(printf, 2, 3))); +-extern void srcpos_warn(struct srcpos *pos, char const *, ...) +- __attribute__((format(printf, 2, 3))); ++extern void srcpos_verror(struct srcpos *pos, const char *prefix, ++ const char *fmt, va_list va) ++ __attribute__((format(printf, 3, 0))); ++extern void srcpos_error(struct srcpos *pos, const char *prefix, ++ const char *fmt, ...) ++ __attribute__((format(printf, 3, 4))); + + extern void srcpos_set_line(char *f, int l); + +diff --git a/scripts/dtc/treesource.c b/scripts/dtc/treesource.c +index 5740e69..a146f2d 100644 +--- a/scripts/dtc/treesource.c ++++ b/scripts/dtc/treesource.c +@@ -26,12 +26,12 @@ extern int yyparse(void); + extern YYLTYPE yylloc; + + struct boot_info *the_boot_info; +-int treesource_error; ++bool treesource_error; + + struct boot_info *dt_from_source(const char *fname) + { + the_boot_info = NULL; +- treesource_error = 0; ++ treesource_error = false; + + srcfile_push(fname); + yyin = current_srcfile->f; +@@ -54,9 +54,9 @@ static void write_prefix(FILE *f, int level) + fputc('\t', f); + } + +-static int isstring(char c) ++static bool isstring(char c) + { +- return (isprint(c) ++ return (isprint((unsigned char)c) + || (c == '\0') + || strchr("\a\b\t\n\v\f\r", c)); + } +@@ -109,7 +109,7 @@ static void write_propval_string(FILE *f, struct data val) + break; + case '\0': + fprintf(f, "\", "); +- while (m && (m->offset < i)) { ++ while (m && (m->offset <= (i + 1))) { + if (m->type == LABEL) { + assert(m->offset == (i+1)); + fprintf(f, "%s: ", m->ref); +@@ -119,7 +119,7 @@ static void write_propval_string(FILE *f, struct data val) + fprintf(f, "\""); + break; + default: +- if (isprint(c)) ++ if (isprint((unsigned char)c)) + fprintf(f, "%c", c); + else + fprintf(f, "\\x%02hhx", c); +@@ -178,7 +178,7 @@ static void write_propval_bytes(FILE *f, struct data val) + m = m->next; + } + +- fprintf(f, "%02hhx", *bp++); ++ fprintf(f, "%02hhx", (unsigned char)(*bp++)); + if ((const void *)bp >= propend) + break; + fprintf(f, " "); +diff --git a/scripts/dtc/util.c b/scripts/dtc/util.c +index 3055c16..9d65226 100644 +--- a/scripts/dtc/util.c ++++ b/scripts/dtc/util.c +@@ -39,11 +39,11 @@ + char *xstrdup(const char *s) + { + int len = strlen(s) + 1; +- char *dup = xmalloc(len); ++ char *d = xmalloc(len); + +- memcpy(dup, s, len); ++ memcpy(d, s, len); + +- return dup; ++ return d; + } + + char *join_path(const char *path, const char *name) +@@ -70,7 +70,7 @@ char *join_path(const char *path, const char *name) + return str; + } + +-int util_is_printable_string(const void *data, int len) ++bool util_is_printable_string(const void *data, int len) + { + const char *s = data; + const char *ss, *se; +@@ -87,7 +87,7 @@ int util_is_printable_string(const void *data, int len) + + while (s < se) { + ss = s; +- while (s < se && *s && isprint(*s)) ++ while (s < se && *s && isprint((unsigned char)*s)) + s++; + + /* not zero, or not done yet */ +@@ -219,10 +219,6 @@ int utilfdt_read_err_len(const char *filename, char **buffp, off_t *len) + if (offset == bufsize) { + bufsize *= 2; + buf = xrealloc(buf, bufsize); +- if (!buf) { +- ret = ENOMEM; +- break; +- } + } + + ret = read(fd, &buf[offset], bufsize - offset); +@@ -375,9 +371,9 @@ void utilfdt_print_data(const char *data, int len) + const uint32_t *cell = (const uint32_t *)data; + + printf(" = <"); +- for (i = 0; i < len; i += 4) ++ for (i = 0, len /= 4; i < len; i++) + printf("0x%08x%s", fdt32_to_cpu(cell[i]), +- i < (len - 4) ? " " : ""); ++ i < (len - 1) ? " " : ""); + printf(">"); + } else { + printf(" = ["); +diff --git a/scripts/dtc/util.h b/scripts/dtc/util.h +index 8f40b44..f800b60 100644 +--- a/scripts/dtc/util.h ++++ b/scripts/dtc/util.h +@@ -2,6 +2,7 @@ + #define _UTIL_H + + #include ++#include + #include + + /* +@@ -33,6 +34,7 @@ static inline void __attribute__((noreturn)) die(const char *str, ...) + va_start(ap, str); + fprintf(stderr, "FATAL ERROR: "); + vfprintf(stderr, str, ap); ++ va_end(ap); + exit(1); + } + +@@ -68,7 +70,7 @@ extern char *join_path(const char *path, const char *name); + * @param len The string length including terminator + * @return 1 if a valid printable string, 0 if not + */ +-int util_is_printable_string(const void *data, int len); ++bool util_is_printable_string(const void *data, int len); + + /* + * Parse an escaped character starting at index i in string s. The resulting +diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h +index 54d4e90..d644002 100644 +--- a/scripts/dtc/version_gen.h ++++ b/scripts/dtc/version_gen.h +@@ -1 +1 @@ +-#define DTC_VERSION "DTC 1.4.0-dirty" ++#define DTC_VERSION "DTC 1.4.1-g36c70742" + +From a762170ddcfcd6ea26ee23c2e5846b483b466600 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Fri, 23 Jan 2015 15:18:03 +0000 +Subject: [PATCH 76/76] BCM2708_DT: Build the overlays as well + +--- + arch/arm/boot/dts/Makefile | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile +index adaebbb..3c7f539 100644 +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -55,6 +55,14 @@ dtb-$(CONFIG_ARCH_ATLAS6) += atlas6-evb.dtb + dtb-$(CONFIG_ARCH_AXXIA) += axm5516-amarillo.dtb + dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-b.dtb + dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-b-plus.dtb ++dtb-$(CONFIG_BCM2708_DT) += hifiberry-dac-overlay.dtb ++dtb-$(CONFIG_BCM2708_DT) += hifiberry-dacplus-overlay.dtb ++dtb-$(CONFIG_BCM2708_DT) += hifiberry-digi-overlay.dtb ++dtb-$(CONFIG_BCM2708_DT) += iqaudio-dac-overlay.dtb ++dtb-$(CONFIG_BCM2708_DT) += iqaudio-dacplus-overlay.dtb ++dtb-$(CONFIG_BCM2708_DT) += lirc-rpi-overlay.dtb ++dtb-$(CONFIG_BCM2708_DT) += w1-gpio-overlay.dtb ++dtb-$(CONFIG_BCM2708_DT) += w1-gpio-pullup-overlay.dtb + dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb + dtb-$(CONFIG_ARCH_BCM_5301X) += bcm4708-netgear-r6250.dtb + dtb-$(CONFIG_ARCH_BCM_63XX) += bcm963138dvt.dtb +@@ -524,6 +532,11 @@ targets += $(dtb-y) + + endif + ++# Enable fixups to support overlays on BCM2708 platforms ++ifeq ($(CONFIG_BCM2708_DT),y) ++ DTC_FLAGS ?= -@ ++endif ++ + # *.dtb used to be generated in the directory above. Clean out the + # old build results so people don't accidentally use them. + dtbs: $(addprefix $(obj)/, $(dtb-y))