Commit 6a992437 authored by Federico Vaga's avatar Federico Vaga Committed by Adam Wujek

patch:kernel: add 3.16.37 patches

Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
parent c623e3d6
From 18ec233fbabab2b296ad0ed2a41ceda0cafb5b59 Mon Sep 17 00:00:00 2001
From: Alessandro Rubini <rubini@gnudd.com>
Date: Sat, 20 Nov 2010 13:15:48 +0100
Subject: [PATCH 1/9] initramfs: stop after one cpio archive
Update to 3.16.37
=================
This patch has been ported from 2.6.39.
Signed-off-by: Alessandro Rubini <rubini@gnudd.com>
Signed-off-by: Federico Vaga <federico.vaga@cern.ch>
---
init/initramfs.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/init/initramfs.c b/init/initramfs.c
index a8497fa..619187f 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -472,6 +472,7 @@ static char * __init unpack_to_rootfs(char *buf, unsigned len)
error("junk in compressed archive");
if (state != Reset)
error("junk in compressed archive");
+ break; /* so we can use a bigger initrd size in the cmdline */
this_header = saved_offset + my_inptr;
buf += my_inptr;
len -= my_inptr;
--
2.7.4
From f544884365b48caa5b35e369a1386bfbb237517a Mon Sep 17 00:00:00 2001
From: Benoit Rat <benoit@sevensols.com>
Date: Fri, 14 Oct 2016 10:16:25 +0200
Subject: [PATCH 2/8] mtd_dataflash: Read EDI bytes in JEDEC to support
AT45DB641E
Standard JEDEC ID is only 24bits to identify a DF chip.
It also has an optional Extended Device Info (EDI) on bytes 4 and/or 5
that need to be read in order differentiate some DF chips. (i.e, the
difference between AT45DB641E and AT45DB642D is made by byte 4).
We have had two new fields in the struct flash_info:
* edi_nbytes: number of optional bytes to read (1 or 2)
* edi_jedec: EDI value for a given chip
Update to 3.16.37
=================
This patch has been ported from 2.6.39.
Signed-off-by: Benoit Rat <benoit@sevensols.com>
Signed-off-by: Federico Vaga <federico.vaga@cern.ch>
---
drivers/mtd/devices/mtd_dataflash.c | 100 +++++++++++++++++++++++-------------
1 file changed, 63 insertions(+), 37 deletions(-)
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c
index dd22ce2..3cb38d2 100644
--- a/drivers/mtd/devices/mtd_dataflash.c
+++ b/drivers/mtd/devices/mtd_dataflash.c
@@ -698,6 +698,13 @@ struct flash_info {
uint16_t pageoffset;
uint16_t flags;
+
+ /* JEDEC has an optional Extended Device Info (EDI) on bytes
+ * 4 and/or 5 that need to be read to differentiate some DF chips
+ */
+ uint8_t edi_nbytes;
+ uint16_t edi_jedec;
+
#define SUP_POW2PS 0x0002 /* supports 2^N byte pages */
#define IS_POW2PS 0x0001 /* uses 2^N byte pages */
};
@@ -713,36 +720,40 @@ static struct flash_info dataflash_data[] = {
* These newer chips also support 128-byte security registers (with
* 64 bytes one-time-programmable) and software write-protection.
*/
- { "AT45DB011B", 0x1f2200, 512, 264, 9, SUP_POW2PS},
+ { "AT45DB011B", 0x1f2200, 512, 264, 9, SUP_POW2PS, 0, 0x0},
{ "at45db011d", 0x1f2200, 512, 256, 8, SUP_POW2PS | IS_POW2PS},
- { "AT45DB021B", 0x1f2300, 1024, 264, 9, SUP_POW2PS},
- { "at45db021d", 0x1f2300, 1024, 256, 8, SUP_POW2PS | IS_POW2PS},
+ { "AT45DB021B", 0x1f2300, 1024, 264, 9, SUP_POW2PS, 0, 0x0},
+ { "at45db021d", 0x1f2300, 1024, 256, 8, SUP_POW2PS | IS_POW2PS, 0, 0x0},
- { "AT45DB041x", 0x1f2400, 2048, 264, 9, SUP_POW2PS},
- { "at45db041d", 0x1f2400, 2048, 256, 8, SUP_POW2PS | IS_POW2PS},
+ { "AT45DB041x", 0x1f2400, 2048, 264, 9, SUP_POW2PS, 0, 0x0},
+ { "at45db041d", 0x1f2400, 2048, 256, 8, SUP_POW2PS | IS_POW2PS, 0, 0x0},
- { "AT45DB081B", 0x1f2500, 4096, 264, 9, SUP_POW2PS},
- { "at45db081d", 0x1f2500, 4096, 256, 8, SUP_POW2PS | IS_POW2PS},
+ { "AT45DB081B", 0x1f2500, 4096, 264, 9, SUP_POW2PS, 0, 0x0},
+ { "at45db081d", 0x1f2500, 4096, 256, 8, SUP_POW2PS | IS_POW2PS, 0, 0x0},
- { "AT45DB161x", 0x1f2600, 4096, 528, 10, SUP_POW2PS},
- { "at45db161d", 0x1f2600, 4096, 512, 9, SUP_POW2PS | IS_POW2PS},
+ { "AT45DB161x", 0x1f2600, 4096, 528, 10, SUP_POW2PS, 0, 0x0},
+ { "at45db161d", 0x1f2600, 4096, 512, 9, SUP_POW2PS | IS_POW2PS, 0, 0x0},
- { "AT45DB321x", 0x1f2700, 8192, 528, 10, 0}, /* rev C */
+ { "AT45DB321x", 0x1f2700, 8192, 528, 10, 0, 0, 0x0}, /* rev C */
- { "AT45DB321x", 0x1f2701, 8192, 528, 10, SUP_POW2PS},
- { "at45db321d", 0x1f2701, 8192, 512, 9, SUP_POW2PS | IS_POW2PS},
+ { "AT45DB321x", 0x1f2701, 8192, 528, 10, SUP_POW2PS, 0, 0x0},
+ { "at45db321d", 0x1f2701, 8192, 512, 9, SUP_POW2PS | IS_POW2PS, 0, 0x0},
- { "AT45DB642x", 0x1f2800, 8192, 1056, 11, SUP_POW2PS},
- { "at45db642d", 0x1f2800, 8192, 1024, 10, SUP_POW2PS | IS_POW2PS},
+ { "AT45DB642x", 0x1f2800, 8192, 1056, 11, SUP_POW2PS, 1, 0x0},
+ { "at45db642d", 0x1f2800, 8192, 1024, 10, SUP_POW2PS | IS_POW2PS, 1, 0x0},
+
+ { "AT45DB641E", 0x1f2800, 32768, 264, 9, SUP_POW2PS, 1, 0x1},
+ { "at45db641e", 0x1f2800, 32768, 256, 8, SUP_POW2PS | IS_POW2PS, 1, 0x1},
};
static struct flash_info *jedec_probe(struct spi_device *spi)
{
int tmp;
uint8_t code = OP_READ_ID;
- uint8_t id[3];
+ uint8_t id[5];
uint32_t jedec;
+ uint16_t jedec_edi;
struct flash_info *info;
int status;
@@ -754,7 +765,7 @@ static struct flash_info *jedec_probe(struct spi_device *spi)
* That's not an error; only rev C and newer chips handle it, and
* only Atmel sells these chips.
*/
- tmp = spi_write_then_read(spi, &code, 1, id, 3);
+ tmp = spi_write_then_read(spi, &code, 1, id, 5);
if (tmp < 0) {
pr_debug("%s: error %d reading JEDEC ID\n",
dev_name(&spi->dev), tmp);
@@ -769,31 +780,39 @@ static struct flash_info *jedec_probe(struct spi_device *spi)
jedec = jedec << 8;
jedec |= id[2];
+ /* EDI bytes to support newest chips */
+ jedec_edi = id[3];
+ jedec_edi = jedec_edi << 8;
+ jedec_edi |= id[4];
+
+
for (tmp = 0, info = dataflash_data;
tmp < ARRAY_SIZE(dataflash_data);
tmp++, info++) {
if (info->jedec_id == jedec) {
- pr_debug("%s: OTP, sector protect%s\n",
- dev_name(&spi->dev),
- (info->flags & SUP_POW2PS)
- ? ", binary pagesize" : ""
- );
- if (info->flags & SUP_POW2PS) {
- status = dataflash_status(spi);
- if (status < 0) {
- pr_debug("%s: status error %d\n",
- dev_name(&spi->dev), status);
- return ERR_PTR(status);
- }
- if (status & 0x1) {
- if (info->flags & IS_POW2PS)
- return info;
- } else {
- if (!(info->flags & IS_POW2PS))
- return info;
- }
- } else
- return info;
+ if (info->edi_jedec == (jedec_edi >> (16 - 8 * info->edi_nbytes))) {
+ pr_debug("%s: OTP, sector protect%s\n",
+ dev_name(&spi->dev),
+ (info->flags & SUP_POW2PS)
+ ? ", binary pagesize" : ""
+ );
+ if (info->flags & SUP_POW2PS) {
+ status = dataflash_status(spi);
+ if (status < 0) {
+ pr_debug("%s: status error %d\n",
+ dev_name(&spi->dev), status);
+ return ERR_PTR(status);
+ }
+ if (status & 0x1) {
+ if (info->flags & IS_POW2PS)
+ return info;
+ } else {
+ if (!(info->flags & IS_POW2PS))
+ return info;
+ }
+ } else
+ return info;
+ }
}
}
@@ -819,6 +838,7 @@ static struct flash_info *jedec_probe(struct spi_device *spi)
* AT45DB0321B 32Mbit (4M) xx1101xx (0x34) 8192 528 10
* AT45DB0642 64Mbit (8M) xx111xxx (0x3c) 8192 1056 11
* AT45DB1282 128Mbit (16M) xx0100xx (0x10) 16384 1056 11
+ * AT45DB0641E 64Mbit (8M) xx111xxx (0x3c) 32768 264 9
*/
static int dataflash_probe(struct spi_device *spi)
{
@@ -833,6 +853,12 @@ static int dataflash_probe(struct spi_device *spi)
* write procedures.
*/
info = jedec_probe(spi);
+
+ printk("MTD: %s 0x%08x %d %d %d %x\n",
+ info->name,info->jedec_id,
+ info->nr_pages,info->pagesize,info->pageoffset,info->flags);
+
+
if (IS_ERR(info))
return PTR_ERR(info);
if (info != NULL)
--
2.7.4
From 6e431fcaed49be557b0721e6f9f4f22151a74838 Mon Sep 17 00:00:00 2001
From: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
Date: Thu, 31 May 2012 13:26:20 +0200
Subject: [PATCH 3/8] wr-switch (sam9m10g45ek): change USB vbus_pin from PB19
to PB8
We are builing our environment on top of the sam9m10g45
evaluation-kit board. In the EK design the pin PB19 is used
but on the switch we use PB8.
Signed-off-by: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
Signed-off-by: Federico Vaga <federico.vaga@cern.ch>
---
arch/arm/mach-at91/board-sam9m10g45ek.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c
index 74ae268..824ae43 100644
--- a/arch/arm/mach-at91/board-sam9m10g45ek.c
+++ b/arch/arm/mach-at91/board-sam9m10g45ek.c
@@ -74,7 +74,7 @@ static struct at91_usbh_data __initdata ek_usbh_hs_data = {
* USB HS Device port
*/
static struct usba_platform_data __initdata ek_usba_udc_data = {
- .vbus_pin = AT91_PIN_PB19,
+ .vbus_pin = AT91_PIN_PB8,
};
--
2.7.4
From eeb910ba9c084ca9dbe7e87f986c2d091538a693 Mon Sep 17 00:00:00 2001
From: Federico Vaga <federico.vaga@cern.ch>
Date: Thu, 27 Oct 2016 14:13:42 +0200
Subject: [PATCH 4/8] wr-switch (sam9m10g45ek): enable FPGA access from EBI1
(SMC)
Configure the EBI1 to in order to be used to access the FPGA
address space.
The EBI1 is, by design, controlled by the Static Memory
Controller (SMC) component.
Signed-off-by: Federico Vaga <federico.vaga@cern.ch>
Signed-off-by: Alessandro Rubini <rubini@gnudd.com>
---
arch/arm/mach-at91/board-sam9m10g45ek.c | 50 +++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c
index 1ea6132..74ae268 100644
--- a/arch/arm/mach-at91/board-sam9m10g45ek.c
+++ b/arch/arm/mach-at91/board-sam9m10g45ek.c
@@ -448,6 +448,53 @@ static struct platform_device *devices[] __initdata = {
#endif
};
+static struct sam9_smc_config __initdata wrs_fpga_smc_config = {
+ .ncs_read_setup = 2,
+ .nrd_setup = 4,
+ .ncs_write_setup = 2,
+ .nwe_setup = 4,
+
+ .ncs_read_pulse = 34,
+ .nrd_pulse = 30,
+ .ncs_write_pulse = 34,
+ .nwe_pulse = 30,
+
+ .read_cycle = 40,
+ .write_cycle = 40,
+
+ .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_DBW_32,
+ .tdf_cycles = 0,
+};
+
+/**
+ * Configure the EBI1 pins for the wr switch FPGA
+ *
+ * This enable the External Bus Interface 1 (EBI1) and configure
+ * the Static Memory Controller (SMC) in order to allow the user
+ * to access the FPGA address space at the offset 0x1000000 by
+ * using chip-select 0 [NCS0].
+ *
+ * NCS0 is always and SMC controller, it cannot be configured in
+ * any other ways (pag 162 SAM9G45 datasheet)
+ */
+static void __init wrs_fpga_init(void)
+{
+ int i;
+
+ /* PC16..31: periphA as EBI1_D16..31 */
+ for (i = AT91_PIN_PC16; i <= AT91_PIN_PC31; i++)
+ at91_set_A_periph(i, 0);
+ /* PC2 and PC3 too: EBI1_A19 EBI1_A20 */
+ at91_set_A_periph(AT91_PIN_PC2, 0);
+ at91_set_A_periph(AT91_PIN_PC3, 0);
+
+ /* FIXME: We should pull rst high for when it is programmed */
+
+ /* Then, write the EBI1 configuration (NCS0 == 0x1000.0000) */
+ /*TODO check if the ID 0 is fine */
+ sam9_smc_configure(0, 0, &wrs_fpga_smc_config);
+}
+
static void __init ek_board_init(void)
{
/* Serial */
@@ -487,6 +534,9 @@ static void __init ek_board_init(void)
/* LEDs */
at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
at91_pwm_leds(ek_pwm_led, ARRAY_SIZE(ek_pwm_led));
+
+ wrs_fpga_init();
+
/* Other platform devices */
platform_add_devices(devices, ARRAY_SIZE(devices));
}
--
2.7.4
From 068d6e63814ec292b1e886a2570bb90390c7dc64 Mon Sep 17 00:00:00 2001
From: Alessandro Rubini <rubini@gnudd.com>
Date: Tue, 7 Aug 2012 12:42:36 +0200
Subject: [PATCH 5/8] wr-switch (sam9m10g45ek): store device partitioning
It prepare partitions in the dataflash to reflect actual
placement of the stuff and ease replacing barebox or at91boot from a
running system (useful for release work, nobody else is expected to
change dataflash).
The NAND has one partition for barebox environment (1M: 5 blocks to
protect against bad blocks) and one big partition fro UBI volumes.
Real stuff is then split in UBI volumes. Please see documentation
(in a later commit) for details.
And hwinfo is not read-only, as we need to change it sometimes.
Though rarely.
Signed-off-by: Alessandro Rubini <rubini@gnudd.com>
Signed-off-by: Federico Vaga <federico.vaga@cern.ch>
---
arch/arm/mach-at91/board-sam9m10g45ek.c | 47 +++++++++++++++++++++++++++++----
1 file changed, 42 insertions(+), 5 deletions(-)
diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c
index 824ae43..ebd8ebd 100644
--- a/arch/arm/mach-at91/board-sam9m10g45ek.c
+++ b/arch/arm/mach-at91/board-sam9m10g45ek.c
@@ -25,6 +25,8 @@
#include <linux/input.h>
#include <linux/leds.h>
#include <linux/atmel-mci.h>
+#include <linux/spi/flash.h>
+#include <linux/mtd/mtd.h>
#include <linux/delay.h>
#include <linux/platform_data/at91_adc.h>
@@ -81,12 +83,47 @@ static struct usba_platform_data __initdata ek_usba_udc_data = {
/*
* SPI devices.
*/
+static struct mtd_partition wrs_df_parts[] = {
+ {
+ .name = "at91boot",
+ .offset = 0,
+ .size = 0x8400,
+ },
+ {
+ .name = "Barebox",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 0x84000,
+ },
+ {
+ .name = "Barebox-Environment",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 0x8400,
+ },
+ {
+ .name = "hwinfo",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 0x840,
+ },
+ {
+ .name = "Available-dataflash",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct flash_platform_data wrs_df_pdata = {
+ .name = "wrs-dataflash",
+ .parts = wrs_df_parts,
+ .nr_parts = ARRAY_SIZE(wrs_df_parts),
+};
+
static struct spi_board_info ek_spi_devices[] = {
{ /* DataFlash chip */
.modalias = "mtd_dataflash",
.chip_select = 0,
.max_speed_hz = 15 * 1000 * 1000,
.bus_num = 0,
+ .platform_data = &wrs_df_pdata,
},
};
@@ -125,13 +162,13 @@ static struct macb_platform_data __initdata ek_macb_data = {
*/
static struct mtd_partition __initdata ek_nand_partition[] = {
{
- .name = "Partition 1",
- .offset = 0,
- .size = SZ_64M,
+ .name = "Barebox-environment-backup",
+ .offset = 0,
+ .size = SZ_1M,
},
{
- .name = "Partition 2",
- .offset = MTDPART_OFS_NXTBLK,
+ .name = "UBIfied-NAND",
+ .offset = 1 << 20,
.size = MTDPART_SIZ_FULL,
},
};
--
2.7.4
From bfb2592942a4e490cf8b6530dfbf16ece33d5767 Mon Sep 17 00:00:00 2001
From: Alessandro Rubini <rubini@gnudd.com>
Date: Mon, 28 Jul 2014 15:20:59 +0200
Subject: [PATCH 6/8] wr-switch (sam9m10g45ek): more relaxed nand timings
Update to 3.16.37
=================
This patch has been ported from 2.6.39.
Signed-off-by: Alessandro Rubini <rubini@gnudd.com>
Signed-off-by: Federico Vaga <federico.vaga@cern.ch>
---
arch/arm/mach-at91/board-sam9m10g45ek.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c
index ebd8ebd..5686a87 100644
--- a/arch/arm/mach-at91/board-sam9m10g45ek.c
+++ b/arch/arm/mach-at91/board-sam9m10g45ek.c
@@ -187,21 +187,21 @@ static struct atmel_nand_data __initdata ek_nand_data = {
};
static struct sam9_smc_config __initdata ek_nand_smc_config = {
- .ncs_read_setup = 0,
- .nrd_setup = 2,
- .ncs_write_setup = 0,
- .nwe_setup = 2,
+ .ncs_read_setup = 2,
+ .nrd_setup = 4,
+ .ncs_write_setup = 2,
+ .nwe_setup = 4,
.ncs_read_pulse = 4,
.nrd_pulse = 4,
.ncs_write_pulse = 4,
.nwe_pulse = 4,
- .read_cycle = 7,
- .write_cycle = 7,
+ .read_cycle = 12,
+ .write_cycle = 12,
.mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE,
- .tdf_cycles = 3,
+ .tdf_cycles = 4,
};
static void __init ek_add_device_nand(void)
--
2.7.4
From 71546ce5ad13e8c2f7de155cc8a17dada9028839 Mon Sep 17 00:00:00 2001
From: Alessandro Rubini <rubini@gnudd.com>
Date: Fri, 28 Nov 2014 14:18:27 +0100
Subject: [PATCH 7/8] wr-switch (sam9m10g45ek): provide bootcount using scratch
registers
Update to 3.16.37
=================
This patch has been ported from 2.6.39.
The functions at91_sys_read/write() have been removed
by the patch 8c428b8d33. Use __raw_readl/writel() and reproduce
the original behavior
The patch b3af8b49be changes the address to the GPBR. To solve this
I created a GPBR resource and mapped it
Signed-off-by: Alessandro Rubini <rubini@gnudd.com>
Signed-off-by: Federico Vaga <federico.vaga@cern.ch>
---
arch/arm/kernel/process.c | 15 +++++
arch/arm/mach-at91/Makefile | 1 +
arch/arm/mach-at91/wrs-bootcount.c | 122 +++++++++++++++++++++++++++++++++++++
3 files changed, 138 insertions(+)
create mode 100644 arch/arm/mach-at91/wrs-bootcount.c
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 3f688b7..c8cff71 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -41,6 +41,7 @@
#include <asm/system_misc.h>
#include <asm/mach/time.h>
#include <asm/tls.h>
+#include <mach/hardware.h>
#include "reboot.h"
#ifdef CONFIG_CC_STACKPROTECTOR
@@ -117,6 +118,20 @@ void _soft_restart(unsigned long addr, bool disable_l2)
static void null_restart(enum reboot_mode reboot_mode, const char *cmd)
{
+ uint32_t gpbr_val;
+ char *gpbr_str = (void *)&gpbr_val;
+ unsigned short *gpbr_short = (void *)&gpbr_val;
+ void __iomem *addr = (void __iomem *)AT91_VA_BASE_SYS;
+ unsigned long gpbr = AT91SAM9G45_BASE_GPBR - AT91_BASE_SYS;
+
+ /* WRS: Change the static registers. See wrs-bootcount.c for details */
+ gpbr_val = __raw_readl(addr + gpbr);
+ gpbr_str[3] = 'R'; /* reboot requested by user */
+ __raw_writel(gpbr_val, addr + gpbr);
+
+ gpbr_val = __raw_readl(addr + gpbr + 4);
+ gpbr_short[1]++; /* count the user-requeted reboots */
+ __raw_writel(gpbr_val, addr + gpbr + 4);
}
void soft_restart(unsigned long addr)
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index 78e9cec..7d385bc 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -80,6 +80,7 @@ obj-$(CONFIG_MACH_SNAPPER_9260) += board-snapper9260.o
# AT91SAM9G45 board-specific support
obj-$(CONFIG_MACH_AT91SAM9M10G45EK) += board-sam9m10g45ek.o
+obj-$(CONFIG_MACH_AT91SAM9M10G45EK) += wrs-bootcount.o
# AT91SAM board with device-tree
obj-$(CONFIG_MACH_AT91RM9200_DT) += board-dt-rm9200.o
diff --git a/arch/arm/mach-at91/wrs-bootcount.c b/arch/arm/mach-at91/wrs-bootcount.c
new file mode 100644
index 0000000..c4305b9
--- /dev/null
+++ b/arch/arm/mach-at91/wrs-bootcount.c
@@ -0,0 +1,122 @@
+/* Alessandro Rubini for CERN 2014 */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+
+#include <mach/hardware.h>
+#include <asm/mach/map.h>
+
+#ifdef CONFIG_RTC_DRV_AT91SAM9
+#error "This is incompatible with CONFIG_RTC_DRV_AT91SAM9"
+#endif
+
+/* This structures is mapped over the general purpose registers */
+struct wrs_bc {
+ unsigned char magic[3];
+ unsigned char last_is_reboot;
+ unsigned short boot_count;
+ unsigned short reboot_count;
+ uint32_t fault_ip;
+ uint32_t fault_lr;
+};
+
+static struct wrs_bc __bc_soft, __bc_hard;
+
+/* bc_regs points there, bc_hw is a local tmp working copy, bc_sw is sw */
+static struct wrs_bc __iomem *bc_regs;
+static struct wrs_bc *bc_hw = &__bc_hard;
+static struct wrs_bc *bc_sw = &__bc_soft;
+
+/*
+ * For some reason, memcpy_fromio and toio is not working. The MSB
+ * is repeated 4 times in the resulting word. So do it by hand
+ */
+static void copy16_fromio(void *dest, void __iomem *src)
+{
+ uint32_t __iomem *s = src;
+ uint32_t *d = dest;
+ int i;
+ for (i = 0; i < 4; i++)
+ d[i] = __raw_readl(s + i);
+}
+
+static void copy16_toio(void __iomem *dest, void *src)
+{
+ uint32_t __iomem *d = dest;
+ uint32_t *s = src;
+ int i;
+ for (i = 0; i < 4; i++)
+ __raw_writel(s[i], d + i);
+}
+
+/**
+ * List of necessary resources
+ */
+static struct resource wrs_r[] = {
+ {
+ .name = "GPBR",
+ .start = AT91SAM9G45_BASE_GPBR,
+ .end = AT91SAM9G45_BASE_GPBR + 0x10,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+/* As soon as possible, copy stuff over */
+static int __init wrs_bc_early_init(void)
+{
+ bc_regs = ioremap(wrs_r[0].start, resource_size(&wrs_r[0]));
+ copy16_fromio(bc_hw, bc_regs);
+
+ if (strncmp(bc_hw->magic, "WRS", 3)) /* power on */
+ memset(bc_hw, 0, sizeof(*bc_hw));
+
+ strncpy(bc_hw->magic, "WRS", 3);
+ bc_hw->boot_count++;
+
+ /* save sw for printing, fix hw and copy back */
+ memcpy(bc_sw, bc_hw, sizeof(*bc_sw));
+ bc_hw->last_is_reboot = 'U';
+ bc_hw->fault_ip = bc_hw->fault_lr = 0;
+ copy16_toio(bc_regs, bc_hw);
+ return 0;
+}
+early_initcall(wrs_bc_early_init);
+
+/* Over time, export in proc */
+static int wrs_bc_proc_show(struct seq_file *m, void *v)
+{
+ seq_printf(m, "boot_count: %i\n"
+ "reboot_count: %i\n"
+ "last_is_reboot: %i\n"
+ "fault_ip: 0x%08x\n"
+ "fault_lr: 0x%08x\n",
+ bc_sw->boot_count,
+ bc_sw->reboot_count,
+ bc_sw->last_is_reboot == 'R',
+ bc_sw->fault_ip,
+ bc_sw->fault_lr);
+ return 0;
+}
+
+static int wrs_bc_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, wrs_bc_proc_show, NULL);
+}
+
+static const struct file_operations wrs_bc_proc_fops = {
+ .open = wrs_bc_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int __init proc_wrs_bc_init(void)
+{
+ /* two files use dash and two use underscore in /proc. Pick one */
+ proc_create("wrs-bootcount", 0, NULL, &wrs_bc_proc_fops);
+ return 0;
+}
+module_init(proc_wrs_bc_init);
--
2.7.4
From 036bcbd702ca7129ce72871b62c67291022ae6f4 Mon Sep 17 00:00:00 2001
From: Federico Vaga <federico.vaga@cern.ch>
Date: Thu, 13 Oct 2016 17:06:35 +0200
Subject: [PATCH 8/8] wr-switch (at91 udc): force full speed
Some WRS speciments won't work correctly with automatic speed setup.
This patch forces full-speed on the device (instead of the
autodetected high-speed), and thus they work.
Speed is not a problem anyways, because it is just a serial port.
Update to 3.16.37
=================
This patch has been ported from 2.6.39.
Signed-off-by: Alessandro Rubini <rubini@gnudd.com>
Signed-off-by: Federico Vaga <federico.vaga@cern.ch>
---
drivers/usb/gadget/atmel_usba_udc.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c
index 892bd97..34b0e87 100644
--- a/drivers/usb/gadget/atmel_usba_udc.c
+++ b/drivers/usb/gadget/atmel_usba_udc.c
@@ -1149,12 +1149,12 @@ static int do_test_mode(struct usba_udc *udc)
break;
case 0x0300:
/*
- * Test_SE0_NAK: Force high-speed mode and set up ep0
+ * Test_SE0_NAK: Force full-speed mode and set up ep0
* for Bulk IN transfers
*/
ep = &udc->usba_ep[0];
usba_writel(udc, TST,
- USBA_BF(SPEED_CFG, USBA_SPEED_CFG_FORCE_HIGH));
+ USBA_BF(SPEED_CFG, USBA_SPEED_CFG_FORCE_FULL));
usba_ep_writel(ep, CFG,
USBA_BF(EPT_SIZE, USBA_EPT_SIZE_64)
| USBA_EPT_DIR_IN
@@ -1812,6 +1812,9 @@ static int atmel_usba_start(struct usb_gadget *gadget,
toggle_bias(1);
usba_writel(udc, CTRL, USBA_ENABLE_MASK);
usba_writel(udc, INT_ENB, USBA_END_OF_RESET);
+ /* Also, force full spedd or sometimes it won't work on WRS */
+ usba_writel(udc, TST,
+ USBA_BF(SPEED_CFG, USBA_SPEED_CFG_FORCE_FULL));
}
spin_unlock_irqrestore(&udc->lock, flags);
--
2.7.4
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment