aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-11-27 17:45:38 -0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-11-27 17:45:38 -0800
commitbf65fa1dcae4aa4a65f9cdcab45aa013b2054ab3 (patch)
tree8f4c98ec456ace005c132623e38b996fbc6af04e
parentab2fa693c905f2dd6ad435082fa8c175a1ddbd23 (diff)
downloadltsi-kernel-bf65fa1dcae4aa4a65f9cdcab45aa013b2054ab3.tar.gz
More altera and a "misc" patch
-rw-r--r--patches.altera/0001-nios2-Export-get_cycles.patch38
-rw-r--r--patches.altera/0002-nios2-check-number-of-timer-instances.patch48
-rw-r--r--patches.altera/0003-nios2-time-Migrate-to-new-set-state-interface.patch113
-rw-r--r--patches.altera/0004-nios2-fixed-variable-imm16-to-s16.patch29
-rw-r--r--patches.altera/0005-nios2-remove-unused-statistic-counters.patch112
-rw-r--r--patches.altera/0006-nios2-Add-Max10-device-tree.patch272
-rw-r--r--patches.altera/0007-nios2-add-Max10-defconfig.patch105
-rw-r--r--patches.altera/0008-nios2-Fix-unused-variable-warning.patch36
-rw-r--r--patches.altera/0009-nios2-Switch-to-generic-__xchg.patch76
-rw-r--r--patches.misc/input-add-support-for-rohm-bu21023-24-touchscreen.patch1254
-rw-r--r--series28
11 files changed, 2097 insertions, 14 deletions
diff --git a/patches.altera/0001-nios2-Export-get_cycles.patch b/patches.altera/0001-nios2-Export-get_cycles.patch
new file mode 100644
index 00000000000000..6e6c3d94c31700
--- /dev/null
+++ b/patches.altera/0001-nios2-Export-get_cycles.patch
@@ -0,0 +1,38 @@
+From b0d9b942747467745e6035caa5272a6c919141c2 Mon Sep 17 00:00:00 2001
+From: Herbert Xu <herbert@gondor.apana.org.au>
+Date: Tue, 9 Jun 2015 12:46:46 +0800
+Subject: [PATCH 1/9] nios2: Export get_cycles
+
+nios2 is the only architecture that does not inline get_cycles
+and does not export it. This breaks crypto as it uses get_cycles
+in a number of modules.
+
+Reported-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+---
+ arch/nios2/kernel/time.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/nios2/kernel/time.c b/arch/nios2/kernel/time.c
+index 7f4547418ee1..be186a75f622 100644
+--- a/arch/nios2/kernel/time.c
++++ b/arch/nios2/kernel/time.c
+@@ -8,6 +8,7 @@
+ * for more details.
+ */
+
++#include <linux/export.h>
+ #include <linux/interrupt.h>
+ #include <linux/clockchips.h>
+ #include <linux/clocksource.h>
+@@ -106,6 +107,7 @@ cycles_t get_cycles(void)
+ {
+ return nios2_timer_read(&nios2_cs.cs);
+ }
++EXPORT_SYMBOL(get_cycles);
+
+ static void nios2_timer_start(struct nios2_timer *timer)
+ {
+--
+2.6.2
+
diff --git a/patches.altera/0002-nios2-check-number-of-timer-instances.patch b/patches.altera/0002-nios2-check-number-of-timer-instances.patch
new file mode 100644
index 00000000000000..047757cd990a71
--- /dev/null
+++ b/patches.altera/0002-nios2-check-number-of-timer-instances.patch
@@ -0,0 +1,48 @@
+From f842e15b14fca61686a1d6488f9edaedecb302ee Mon Sep 17 00:00:00 2001
+From: Ley Foon Tan <lftan@altera.com>
+Date: Wed, 24 Jun 2015 17:52:44 +0800
+Subject: [PATCH 2/9] nios2: check number of timer instances
+
+Display error message if number of timers is less than 2.
+
+Signed-off-by: Ley Foon Tan <lftan@altera.com>
+---
+ arch/nios2/kernel/time.c | 15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
+
+diff --git a/arch/nios2/kernel/time.c b/arch/nios2/kernel/time.c
+index be186a75f622..9e3cc8a40ee9 100644
+--- a/arch/nios2/kernel/time.c
++++ b/arch/nios2/kernel/time.c
+@@ -19,7 +19,9 @@
+ #include <linux/io.h>
+ #include <linux/slab.h>
+
+-#define ALTERA_TIMER_STATUS_REG 0
++#define ALTR_TIMER_COMPATIBLE "altr,timer-1.0"
++
++#define ALTERA_TIMER_STATUS_REG 0
+ #define ALTERA_TIMER_CONTROL_REG 4
+ #define ALTERA_TIMER_PERIODL_REG 8
+ #define ALTERA_TIMER_PERIODH_REG 12
+@@ -304,7 +306,16 @@ void read_persistent_clock(struct timespec *ts)
+
+ void __init time_init(void)
+ {
++ struct device_node *np;
++ int count = 0;
++
++ for_each_compatible_node(np, NULL, ALTR_TIMER_COMPATIBLE)
++ count++;
++
++ if (count < 2)
++ panic("%d timer is found, it needs 2 timers in system\n", count);
++
+ clocksource_of_init();
+ }
+
+-CLOCKSOURCE_OF_DECLARE(nios2_timer, "altr,timer-1.0", nios2_time_init);
++CLOCKSOURCE_OF_DECLARE(nios2_timer, ALTR_TIMER_COMPATIBLE, nios2_time_init);
+--
+2.6.2
+
diff --git a/patches.altera/0003-nios2-time-Migrate-to-new-set-state-interface.patch b/patches.altera/0003-nios2-time-Migrate-to-new-set-state-interface.patch
new file mode 100644
index 00000000000000..675af3d75546ec
--- /dev/null
+++ b/patches.altera/0003-nios2-time-Migrate-to-new-set-state-interface.patch
@@ -0,0 +1,113 @@
+From be2926f60f84ffc870e5b57c255e9a5d236c7cbf Mon Sep 17 00:00:00 2001
+From: Viresh Kumar <viresh.kumar@linaro.org>
+Date: Tue, 18 Aug 2015 13:59:28 +0800
+Subject: [PATCH 3/9] nios2/time: Migrate to new 'set-state' interface
+
+Migrate nios2 driver to the new 'set-state' interface provided by clockevents core, the earlier 'set-mode' interface is marked obsolete now.
+
+This also enables us to implement callbacks for new states of clockevent devices, for example: ONESHOT_STOPPED.
+
+Cc: Ley Foon Tan <lftan@altera.com>
+Cc: Tobias Klauser <tklauser@distanz.ch>
+Cc: Herbert Xu <herbert@gondor.apana.org.au>
+Cc: Dmitry Torokhov <dtor@chromium.org>
+Cc: nios2-dev@lists.rocketboards.org
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Acked-by: Ley Foon Tan <lftan@altera.com>
+---
+ arch/nios2/kernel/time.c | 49 ++++++++++++++++++++++++++++--------------------
+ 1 file changed, 29 insertions(+), 20 deletions(-)
+
+diff --git a/arch/nios2/kernel/time.c b/arch/nios2/kernel/time.c
+index 9e3cc8a40ee9..bbc3f9157f9c 100644
+--- a/arch/nios2/kernel/time.c
++++ b/arch/nios2/kernel/time.c
+@@ -130,7 +130,7 @@ static void nios2_timer_stop(struct nios2_timer *timer)
+ }
+
+ static void nios2_timer_config(struct nios2_timer *timer, unsigned long period,
+- enum clock_event_mode mode)
++ bool periodic)
+ {
+ u16 ctrl;
+
+@@ -148,7 +148,7 @@ static void nios2_timer_config(struct nios2_timer *timer, unsigned long period,
+ timer_writew(timer, period >> 16, ALTERA_TIMER_PERIODH_REG);
+
+ ctrl |= ALTERA_TIMER_CONTROL_START_MSK | ALTERA_TIMER_CONTROL_ITO_MSK;
+- if (mode == CLOCK_EVT_MODE_PERIODIC)
++ if (periodic)
+ ctrl |= ALTERA_TIMER_CONTROL_CONT_MSK;
+ else
+ ctrl &= ~ALTERA_TIMER_CONTROL_CONT_MSK;
+@@ -160,32 +160,38 @@ static int nios2_timer_set_next_event(unsigned long delta,
+ {
+ struct nios2_clockevent_dev *nios2_ced = to_nios2_clkevent(evt);
+
+- nios2_timer_config(&nios2_ced->timer, delta, evt->mode);
++ nios2_timer_config(&nios2_ced->timer, delta, false);
+
+ return 0;
+ }
+
+-static void nios2_timer_set_mode(enum clock_event_mode mode,
+- struct clock_event_device *evt)
++static int nios2_timer_shutdown(struct clock_event_device *evt)
++{
++ struct nios2_clockevent_dev *nios2_ced = to_nios2_clkevent(evt);
++ struct nios2_timer *timer = &nios2_ced->timer;
++
++ nios2_timer_stop(timer);
++ return 0;
++}
++
++static int nios2_timer_set_periodic(struct clock_event_device *evt)
+ {
+ unsigned long period;
+ struct nios2_clockevent_dev *nios2_ced = to_nios2_clkevent(evt);
+ struct nios2_timer *timer = &nios2_ced->timer;
+
+- switch (mode) {
+- case CLOCK_EVT_MODE_PERIODIC:
+- period = DIV_ROUND_UP(timer->freq, HZ);
+- nios2_timer_config(timer, period, CLOCK_EVT_MODE_PERIODIC);
+- break;
+- case CLOCK_EVT_MODE_ONESHOT:
+- case CLOCK_EVT_MODE_UNUSED:
+- case CLOCK_EVT_MODE_SHUTDOWN:
+- nios2_timer_stop(timer);
+- break;
+- case CLOCK_EVT_MODE_RESUME:
+- nios2_timer_start(timer);
+- break;
+- }
++ period = DIV_ROUND_UP(timer->freq, HZ);
++ nios2_timer_config(timer, period, true);
++ return 0;
++}
++
++static int nios2_timer_resume(struct clock_event_device *evt)
++{
++ struct nios2_clockevent_dev *nios2_ced = to_nios2_clkevent(evt);
++ struct nios2_timer *timer = &nios2_ced->timer;
++
++ nios2_timer_start(timer);
++ return 0;
+ }
+
+ irqreturn_t timer_interrupt(int irq, void *dev_id)
+@@ -218,7 +224,10 @@ static struct nios2_clockevent_dev nios2_ce = {
+ .rating = 250,
+ .shift = 32,
+ .set_next_event = nios2_timer_set_next_event,
+- .set_mode = nios2_timer_set_mode,
++ .set_state_shutdown = nios2_timer_shutdown,
++ .set_state_periodic = nios2_timer_set_periodic,
++ .set_state_oneshot = nios2_timer_shutdown,
++ .tick_resume = nios2_timer_resume,
+ },
+ };
+
+--
+2.6.2
+
diff --git a/patches.altera/0004-nios2-fixed-variable-imm16-to-s16.patch b/patches.altera/0004-nios2-fixed-variable-imm16-to-s16.patch
new file mode 100644
index 00000000000000..baa96df37877dc
--- /dev/null
+++ b/patches.altera/0004-nios2-fixed-variable-imm16-to-s16.patch
@@ -0,0 +1,29 @@
+From 503c5aa3817e2c566ecc6fd6dae4e20d7d4da259 Mon Sep 17 00:00:00 2001
+From: Bernd Weiberg <bernd.weiberg@siemens.com>
+Date: Fri, 4 Sep 2015 17:03:03 +0800
+Subject: [PATCH 4/9] nios2: fixed variable imm16 to s16
+
+Fxid variable imm16 to s16 instead of u16, offset might be negative.
+
+Signed-off-by: Bernd Weiberg <bernd.weiberg@siemens.com>
+Signed-off-by: Ley Foon Tan <lftan@altera.com>
+---
+ arch/nios2/kernel/misaligned.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/nios2/kernel/misaligned.c b/arch/nios2/kernel/misaligned.c
+index 4e5907a0cabe..89fe0b6ee339 100644
+--- a/arch/nios2/kernel/misaligned.c
++++ b/arch/nios2/kernel/misaligned.c
+@@ -71,7 +71,7 @@ asmlinkage void handle_unaligned_c(struct pt_regs *fp, int cause)
+ u32 isn, addr, val;
+ int in_kernel;
+ u8 a, b, d0, d1, d2, d3;
+- u16 imm16;
++ s16 imm16;
+ unsigned int fault;
+
+ /* back up one instruction */
+--
+2.6.2
+
diff --git a/patches.altera/0005-nios2-remove-unused-statistic-counters.patch b/patches.altera/0005-nios2-remove-unused-statistic-counters.patch
new file mode 100644
index 00000000000000..6a957025026107
--- /dev/null
+++ b/patches.altera/0005-nios2-remove-unused-statistic-counters.patch
@@ -0,0 +1,112 @@
+From 4fda2c0976d428ba8b33c733e8439c3846161dd6 Mon Sep 17 00:00:00 2001
+From: Bernd Weiberg <bernd.weiberg@siemens.com>
+Date: Fri, 4 Sep 2015 16:59:45 +0800
+Subject: [PATCH 5/9] nios2: remove unused statistic counters
+
+Removed some statistic counters to improve the performance of the handler.
+
+Signed-off-by: Bernd Weiberg <bernd.weiberg@siemens.com>
+Signed-off-by: Ley Foon Tan <lftan@altera.com>
+---
+ arch/nios2/kernel/misaligned.c | 18 ------------------
+ 1 file changed, 18 deletions(-)
+
+diff --git a/arch/nios2/kernel/misaligned.c b/arch/nios2/kernel/misaligned.c
+index 89fe0b6ee339..23e0544e117c 100644
+--- a/arch/nios2/kernel/misaligned.c
++++ b/arch/nios2/kernel/misaligned.c
+@@ -32,8 +32,6 @@
+ #define INST_STW 0x15
+ #define INST_LDW 0x17
+
+-static unsigned long ma_user, ma_kern, ma_skipped, ma_half, ma_word;
+-
+ static unsigned int ma_usermode;
+ #define UM_WARN 0x01
+ #define UM_FIXUP 0x02
+@@ -53,7 +51,6 @@ static int reg_offsets[32];
+ static inline u32 get_reg_val(struct pt_regs *fp, int reg)
+ {
+ u8 *p = ((u8 *)fp) + reg_offsets[reg];
+-
+ return *(u32 *)p;
+ }
+
+@@ -78,7 +75,6 @@ asmlinkage void handle_unaligned_c(struct pt_regs *fp, int cause)
+ fp->ea -= 4;
+
+ if (fixup_exception(fp)) {
+- ma_skipped++;
+ return;
+ }
+
+@@ -103,18 +99,11 @@ asmlinkage void handle_unaligned_c(struct pt_regs *fp, int cause)
+ fault |= __get_user(d1, (u8 *)(addr+1));
+ val = (d1 << 8) | d0;
+ put_reg_val(fp, b, val);
+- ma_half++;
+ break;
+ case INST_STH:
+ val = get_reg_val(fp, b);
+ d1 = val >> 8;
+ d0 = val >> 0;
+-
+- pr_debug("sth: ra=%d (%08x) rb=%d (%08x), imm16 %04x addr %08x val %08x\n",
+- a, get_reg_val(fp, a),
+- b, get_reg_val(fp, b),
+- imm16, addr, val);
+-
+ if (in_kernel) {
+ *(u8 *)(addr+0) = d0;
+ *(u8 *)(addr+1) = d1;
+@@ -122,14 +111,12 @@ asmlinkage void handle_unaligned_c(struct pt_regs *fp, int cause)
+ fault |= __put_user(d0, (u8 *)(addr+0));
+ fault |= __put_user(d1, (u8 *)(addr+1));
+ }
+- ma_half++;
+ break;
+ case INST_LDH:
+ fault |= __get_user(d0, (u8 *)(addr+0));
+ fault |= __get_user(d1, (u8 *)(addr+1));
+ val = (short)((d1 << 8) | d0);
+ put_reg_val(fp, b, val);
+- ma_half++;
+ break;
+ case INST_STW:
+ val = get_reg_val(fp, b);
+@@ -148,7 +135,6 @@ asmlinkage void handle_unaligned_c(struct pt_regs *fp, int cause)
+ fault |= __put_user(d2, (u8 *)(addr+2));
+ fault |= __put_user(d3, (u8 *)(addr+3));
+ }
+- ma_word++;
+ break;
+ case INST_LDW:
+ fault |= __get_user(d0, (u8 *)(addr+0));
+@@ -157,7 +143,6 @@ asmlinkage void handle_unaligned_c(struct pt_regs *fp, int cause)
+ fault |= __get_user(d3, (u8 *)(addr+3));
+ val = (d3 << 24) | (d2 << 16) | (d1 << 8) | d0;
+ put_reg_val(fp, b, val);
+- ma_word++;
+ break;
+ }
+ }
+@@ -186,7 +171,6 @@ asmlinkage void handle_unaligned_c(struct pt_regs *fp, int cause)
+ * note exception and skip bad instruction (return)
+ */
+ if (in_kernel) {
+- ma_kern++;
+ fp->ea += 4;
+
+ if (ma_usermode & KM_WARN) {
+@@ -200,8 +184,6 @@ asmlinkage void handle_unaligned_c(struct pt_regs *fp, int cause)
+ return;
+ }
+
+- ma_user++;
+-
+ /*
+ * user mode -
+ * possibly warn,
+--
+2.6.2
+
diff --git a/patches.altera/0006-nios2-Add-Max10-device-tree.patch b/patches.altera/0006-nios2-Add-Max10-device-tree.patch
new file mode 100644
index 00000000000000..358f2d78856dbb
--- /dev/null
+++ b/patches.altera/0006-nios2-Add-Max10-device-tree.patch
@@ -0,0 +1,272 @@
+From 1ed6d08bf81a5feef41266d49ca6ee93bfd85f86 Mon Sep 17 00:00:00 2001
+From: Chee Nouk Phoon <cnphoon@altera.com>
+Date: Tue, 8 Sep 2015 18:07:44 +0800
+Subject: [PATCH 6/9] nios2: Add Max10 device tree
+
+Max10 is a FPGA device. This patch adds Nios2 support for Max10.
+This device tree is based on Max10 hardware reference design.
+
+Signed-off-by: Chee Nouk Phoon <cnphoon@altera.com>
+Signed-off-by: Ley Foon Tan <lftan@altera.com>
+---
+ arch/nios2/boot/dts/10m50_devboard.dts | 248 +++++++++++++++++++++++++++++++++
+ 1 file changed, 248 insertions(+)
+ create mode 100755 arch/nios2/boot/dts/10m50_devboard.dts
+
+diff --git a/arch/nios2/boot/dts/10m50_devboard.dts b/arch/nios2/boot/dts/10m50_devboard.dts
+new file mode 100755
+index 000000000000..3e411c644824
+--- /dev/null
++++ b/arch/nios2/boot/dts/10m50_devboard.dts
+@@ -0,0 +1,248 @@
++/*
++ * Copyright (C) 2015 Altera Corporation. All rights reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope 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 <http://www.gnu.org/licenses/>.
++ */
++
++/dts-v1/;
++
++/ {
++ model = "Altera NiosII Max10";
++ compatible = "altr,niosii-max10";
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ cpus {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ cpu: cpu@0 {
++ device_type = "cpu";
++ compatible = "altr,nios2-1.1";
++ reg = <0x00000000>;
++ interrupt-controller;
++ #interrupt-cells = <1>;
++ altr,exception-addr = <0xc8000120>;
++ altr,fast-tlb-miss-addr = <0xc0000100>;
++ altr,has-div = <1>;
++ altr,has-initda = <1>;
++ altr,has-mmu = <1>;
++ altr,has-mul = <1>;
++ altr,implementation = "fast";
++ altr,pid-num-bits = <8>;
++ altr,reset-addr = <0xd4000000>;
++ altr,tlb-num-entries = <256>;
++ altr,tlb-num-ways = <16>;
++ altr,tlb-ptr-sz = <8>;
++ clock-frequency = <75000000>;
++ dcache-line-size = <32>;
++ dcache-size = <32768>;
++ icache-line-size = <32>;
++ icache-size = <32768>;
++ };
++ };
++
++ memory {
++ device_type = "memory";
++ reg = <0x08000000 0x08000000>,
++ <0x00000000 0x00000400>;
++ };
++
++ sopc0: sopc@0 {
++ device_type = "soc";
++ ranges;
++ #address-cells = <1>;
++ #size-cells = <1>;
++ compatible = "altr,avalon", "simple-bus";
++ bus-frequency = <75000000>;
++
++ jtag_uart: serial@18001530 {
++ compatible = "altr,juart-1.0";
++ reg = <0x18001530 0x00000008>;
++ interrupt-parent = <&cpu>;
++ interrupts = <7>;
++ };
++
++ a_16550_uart_0: serial@18001600 {
++ compatible = "altr,16550-FIFO32", "ns16550a";
++ reg = <0x18001600 0x00000200>;
++ interrupt-parent = <&cpu>;
++ interrupts = <1>;
++ auto-flow-control = <1>;
++ clock-frequency = <50000000>;
++ fifo-size = <32>;
++ reg-io-width = <4>;
++ reg-shift = <2>;
++ };
++
++ sysid: sysid@18001528 {
++ compatible = "altr,sysid-1.0";
++ reg = <0x18001528 0x00000008>;
++ id = <4207856382>;
++ timestamp = <1431309290>;
++ };
++
++ rgmii_0_eth_tse_0: ethernet@400 {
++ compatible = "altr,tse-msgdma-1.0", "altr,tse-1.0";
++ reg = <0x00000400 0x00000400>,
++ <0x00000820 0x00000020>,
++ <0x00000800 0x00000020>,
++ <0x000008c0 0x00000008>,
++ <0x00000840 0x00000020>,
++ <0x00000860 0x00000020>;
++ reg-names = "control_port", "rx_csr", "rx_desc", "rx_resp", "tx_csr", "tx_desc";
++ interrupt-parent = <&cpu>;
++ interrupts = <2 3>;
++ interrupt-names = "rx_irq", "tx_irq";
++ rx-fifo-depth = <8192>;
++ tx-fifo-depth = <8192>;
++ address-bits = <48>;
++ max-frame-size = <1518>;
++ local-mac-address = [00 00 00 00 00 00];
++ altr,has-supplementary-unicast;
++ altr,enable-sup-addr = <1>;
++ altr,has-hash-multicast-filter;
++ altr,enable-hash = <1>;
++ phy-mode = "rgmii-id";
++ phy-handle = <&phy0>;
++ rgmii_0_eth_tse_0_mdio: mdio {
++ compatible = "altr,tse-mdio";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ phy0: ethernet-phy@0 {
++ reg = <0>;
++ device_type = "ethernet-phy";
++ };
++ };
++ };
++
++ enet_pll: clock@0 {
++ compatible = "altr,pll-1.0";
++ #clock-cells = <1>;
++
++ enet_pll_c0: enet_pll_c0 {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <125000000>;
++ clock-output-names = "enet_pll-c0";
++ };
++
++ enet_pll_c1: enet_pll_c1 {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <25000000>;
++ clock-output-names = "enet_pll-c1";
++ };
++
++ enet_pll_c2: enet_pll_c2 {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <2500000>;
++ clock-output-names = "enet_pll-c2";
++ };
++ };
++
++ sys_pll: clock@1 {
++ compatible = "altr,pll-1.0";
++ #clock-cells = <1>;
++
++ sys_pll_c0: sys_pll_c0 {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <100000000>;
++ clock-output-names = "sys_pll-c0";
++ };
++
++ sys_pll_c1: sys_pll_c1 {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <50000000>;
++ clock-output-names = "sys_pll-c1";
++ };
++
++ sys_pll_c2: sys_pll_c2 {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <75000000>;
++ clock-output-names = "sys_pll-c2";
++ };
++ };
++
++ sys_clk_timer: timer@18001440 {
++ compatible = "altr,timer-1.0";
++ reg = <0x18001440 0x00000020>;
++ interrupt-parent = <&cpu>;
++ interrupts = <0>;
++ clock-frequency = <75000000>;
++ };
++
++ led_pio: gpio@180014d0 {
++ compatible = "altr,pio-1.0";
++ reg = <0x180014d0 0x00000010>;
++ altr,gpio-bank-width = <4>;
++ resetvalue = <15>;
++ #gpio-cells = <2>;
++ gpio-controller;
++ };
++
++ button_pio: gpio@180014c0 {
++ compatible = "altr,pio-1.0";
++ reg = <0x180014c0 0x00000010>;
++ interrupt-parent = <&cpu>;
++ interrupts = <6>;
++ altr,gpio-bank-width = <3>;
++ altr,interrupt-type = <2>;
++ edge_type = <1>;
++ level_trigger = <0>;
++ resetvalue = <0>;
++ #gpio-cells = <2>;
++ gpio-controller;
++ };
++
++ sys_clk_timer_1: timer@880 {
++ compatible = "altr,timer-1.0";
++ reg = <0x00000880 0x00000020>;
++ interrupt-parent = <&cpu>;
++ interrupts = <5>;
++ clock-frequency = <75000000>;
++ };
++
++ fpga_leds: leds {
++ compatible = "gpio-leds";
++
++ led_fpga0: fpga0 {
++ label = "fpga_led0";
++ gpios = <&led_pio 0 1>;
++ };
++
++ led_fpga1: fpga1 {
++ label = "fpga_led1";
++ gpios = <&led_pio 1 1>;
++ };
++
++ led_fpga2: fpga2 {
++ label = "fpga_led2";
++ gpios = <&led_pio 2 1>;
++ };
++
++ led_fpga3: fpga3 {
++ label = "fpga_led3";
++ gpios = <&led_pio 3 1>;
++ };
++ };
++ };
++
++ chosen {
++ bootargs = "debug console=ttyS0,115200";
++ };
++};
+--
+2.6.2
+
diff --git a/patches.altera/0007-nios2-add-Max10-defconfig.patch b/patches.altera/0007-nios2-add-Max10-defconfig.patch
new file mode 100644
index 00000000000000..d8e96180ed3779
--- /dev/null
+++ b/patches.altera/0007-nios2-add-Max10-defconfig.patch
@@ -0,0 +1,105 @@
+From f8a56cef689111e5bec8f600b7748ef15ec5f0f2 Mon Sep 17 00:00:00 2001
+From: Chee Nouk Phoon <cnphoon@altera.com>
+Date: Tue, 8 Sep 2015 18:08:56 +0800
+Subject: [PATCH 7/9] nios2: add Max10 defconfig
+
+Max10 is a FPGA device. This patch adds defconfig based on Max10 hardware
+reference design. Design is intended to run on Max10 development kit.
+
+Signed-off-by: Chee Nouk Phoon <cnphoon@altera.com>
+Signed-off-by: Ley Foon Tan <lftan@altera.com>
+---
+ arch/nios2/configs/10m50_defconfig | 81 ++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 81 insertions(+)
+ create mode 100755 arch/nios2/configs/10m50_defconfig
+
+diff --git a/arch/nios2/configs/10m50_defconfig b/arch/nios2/configs/10m50_defconfig
+new file mode 100755
+index 000000000000..8b2a30b3b34f
+--- /dev/null
++++ b/arch/nios2/configs/10m50_defconfig
+@@ -0,0 +1,81 @@
++CONFIG_SYSVIPC=y
++CONFIG_NO_HZ_IDLE=y
++CONFIG_BSD_PROCESS_ACCT=y
++CONFIG_LOG_BUF_SHIFT=14
++CONFIG_SYSCTL_SYSCALL=y
++# CONFIG_ELF_CORE is not set
++# CONFIG_EPOLL is not set
++# CONFIG_SIGNALFD is not set
++# CONFIG_TIMERFD is not set
++# CONFIG_EVENTFD is not set
++# CONFIG_SHMEM is not set
++# CONFIG_AIO is not set
++CONFIG_EMBEDDED=y
++CONFIG_SLAB=y
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++CONFIG_NIOS2_MEM_BASE=0x8000000
++CONFIG_NIOS2_HW_MUL_SUPPORT=y
++CONFIG_NIOS2_HW_DIV_SUPPORT=y
++CONFIG_CUSTOM_CACHE_SETTINGS=y
++CONFIG_NIOS2_DCACHE_SIZE=0x8000
++CONFIG_NIOS2_ICACHE_SIZE=0x8000
++# CONFIG_NIOS2_CMDLINE_IGNORE_DTB is not set
++CONFIG_NET=y
++CONFIG_PACKET=y
++CONFIG_UNIX=y
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++CONFIG_IP_PNP_RARP=y
++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
++# CONFIG_INET_XFRM_MODE_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_BEET is not set
++# CONFIG_INET_LRO is not set
++# CONFIG_IPV6 is not set
++# CONFIG_WIRELESS is not set
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_DEVTMPFS=y
++CONFIG_DEVTMPFS_MOUNT=y
++# CONFIG_FW_LOADER is not set
++CONFIG_MTD=y
++CONFIG_MTD_CMDLINE_PARTS=y
++CONFIG_MTD_BLOCK=y
++CONFIG_MTD_CFI=y
++CONFIG_MTD_CFI_INTELEXT=y
++CONFIG_MTD_CFI_AMDSTD=y
++CONFIG_BLK_DEV_LOOP=y
++CONFIG_NETDEVICES=y
++CONFIG_ALTERA_TSE=y
++CONFIG_MARVELL_PHY=y
++# CONFIG_WLAN is not set
++# CONFIG_INPUT_MOUSE is not set
++# CONFIG_SERIO_SERPORT is not set
++# CONFIG_VT is not set
++CONFIG_SERIAL_8250=y
++# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
++CONFIG_SERIAL_8250_CONSOLE=y
++CONFIG_SERIAL_OF_PLATFORM=y
++CONFIG_SERIAL_ALTERA_JTAGUART=y
++# CONFIG_HW_RANDOM is not set
++CONFIG_GPIOLIB=y
++CONFIG_GPIO_SYSFS=y
++CONFIG_GPIO_ALTERA=y
++# CONFIG_HWMON is not set
++# CONFIG_USB_SUPPORT is not set
++CONFIG_NEW_LEDS=y
++CONFIG_LEDS_CLASS=y
++CONFIG_LEDS_GPIO=y
++CONFIG_LEDS_TRIGGERS=y
++CONFIG_LEDS_TRIGGER_HEARTBEAT=y
++# CONFIG_DNOTIFY is not set
++# CONFIG_INOTIFY_USER is not set
++CONFIG_JFFS2_FS=y
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3_ACL=y
++CONFIG_ROOT_NFS=y
++CONFIG_SUNRPC_DEBUG=y
++CONFIG_DEBUG_INFO=y
++# CONFIG_ENABLE_WARN_DEPRECATED is not set
+--
+2.6.2
+
diff --git a/patches.altera/0008-nios2-Fix-unused-variable-warning.patch b/patches.altera/0008-nios2-Fix-unused-variable-warning.patch
new file mode 100644
index 00000000000000..2d86f8f993cd48
--- /dev/null
+++ b/patches.altera/0008-nios2-Fix-unused-variable-warning.patch
@@ -0,0 +1,36 @@
+From 577da9b93378b056215d239ba2216401bfd5a069 Mon Sep 17 00:00:00 2001
+From: Marek Vasut <marex@denx.de>
+Date: Wed, 30 Sep 2015 22:06:46 +0800
+Subject: [PATCH 8/9] nios2: Fix unused variable warning
+
+Fix the following compiler splat by adding __maybe_unused annotation to
+the variable. Using this particular annotation has the least ugly impact
+on the code compared to using ifdeffery.
+
+arch/nios2/kernel/setup.c: In function 'nios2_boot_init':
+arch/nios2/kernel/setup.c:107:7: warning: unused variable 'cmdline_passed' [-Wunused-variable]
+ char cmdline_passed[COMMAND_LINE_SIZE] = { 0, };
+ ^
+
+Signed-off-by: Marek Vasut <marex@denx.de>
+Acked-by: Ley Foon Tan <lftan@altera.com>
+---
+ arch/nios2/kernel/setup.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/nios2/kernel/setup.c b/arch/nios2/kernel/setup.c
+index b101a43d3c5a..a4ff86d58d5c 100644
+--- a/arch/nios2/kernel/setup.c
++++ b/arch/nios2/kernel/setup.c
+@@ -104,7 +104,7 @@ asmlinkage void __init nios2_boot_init(unsigned r4, unsigned r5, unsigned r6,
+ unsigned r7)
+ {
+ unsigned dtb_passed = 0;
+- char cmdline_passed[COMMAND_LINE_SIZE] = { 0, };
++ char cmdline_passed[COMMAND_LINE_SIZE] __maybe_unused = { 0, };
+
+ #if defined(CONFIG_NIOS2_PASS_CMDLINE)
+ if (r4 == 0x534f494e) { /* r4 is magic NIOS */
+--
+2.6.2
+
diff --git a/patches.altera/0009-nios2-Switch-to-generic-__xchg.patch b/patches.altera/0009-nios2-Switch-to-generic-__xchg.patch
new file mode 100644
index 00000000000000..109ba8570d7758
--- /dev/null
+++ b/patches.altera/0009-nios2-Switch-to-generic-__xchg.patch
@@ -0,0 +1,76 @@
+From 90df4ef19e6dfb7521e05ece60546677491c9e32 Mon Sep 17 00:00:00 2001
+From: Marek Vasut <marex@denx.de>
+Date: Wed, 30 Sep 2015 22:08:00 +0800
+Subject: [PATCH 9/9] nios2: Switch to generic __xchg()
+
+The generic __xchg() implementation present in asm-generic/cmpxchg.h is
+correct on nios2 and even generates the same code. Switch to this generic
+implementation to trim down the amount of ad-hoc copies of the code.
+
+Signed-off-by: Marek Vasut <marex@denx.de>
+Acked-by: Ley Foon Tan <lftan@altera.com>
+---
+ arch/nios2/include/asm/cmpxchg.h | 47 ----------------------------------------
+ 1 file changed, 47 deletions(-)
+
+diff --git a/arch/nios2/include/asm/cmpxchg.h b/arch/nios2/include/asm/cmpxchg.h
+index 85938711542d..a7978f14d157 100644
+--- a/arch/nios2/include/asm/cmpxchg.h
++++ b/arch/nios2/include/asm/cmpxchg.h
+@@ -9,53 +9,6 @@
+ #ifndef _ASM_NIOS2_CMPXCHG_H
+ #define _ASM_NIOS2_CMPXCHG_H
+
+-#include <linux/irqflags.h>
+-
+-#define xchg(ptr, x) \
+- ((__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), sizeof(*(ptr))))
+-
+-struct __xchg_dummy { unsigned long a[100]; };
+-#define __xg(x) ((volatile struct __xchg_dummy *)(x))
+-
+-static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
+- int size)
+-{
+- unsigned long tmp, flags;
+-
+- local_irq_save(flags);
+-
+- switch (size) {
+- case 1:
+- __asm__ __volatile__(
+- "ldb %0, %2\n"
+- "stb %1, %2\n"
+- : "=&r" (tmp)
+- : "r" (x), "m" (*__xg(ptr))
+- : "memory");
+- break;
+- case 2:
+- __asm__ __volatile__(
+- "ldh %0, %2\n"
+- "sth %1, %2\n"
+- : "=&r" (tmp)
+- : "r" (x), "m" (*__xg(ptr))
+- : "memory");
+- break;
+- case 4:
+- __asm__ __volatile__(
+- "ldw %0, %2\n"
+- "stw %1, %2\n"
+- : "=&r" (tmp)
+- : "r" (x), "m" (*__xg(ptr))
+- : "memory");
+- break;
+- }
+-
+- local_irq_restore(flags);
+- return tmp;
+-}
+-
+ #include <asm-generic/cmpxchg.h>
+-#include <asm-generic/cmpxchg-local.h>
+
+ #endif /* _ASM_NIOS2_CMPXCHG_H */
+--
+2.6.2
+
diff --git a/patches.misc/input-add-support-for-rohm-bu21023-24-touchscreen.patch b/patches.misc/input-add-support-for-rohm-bu21023-24-touchscreen.patch
new file mode 100644
index 00000000000000..2dfc9c31413706
--- /dev/null
+++ b/patches.misc/input-add-support-for-rohm-bu21023-24-touchscreen.patch
@@ -0,0 +1,1254 @@
+From c7efd123500b11568ce928a5cd91ad132ec36df5 Mon Sep 17 00:00:00 2001
+From: Yoichi Yuasa <yuasa@linux-mips.org>
+Date: Sat, 19 Sep 2015 11:34:30 -0700
+Subject: [PATCH] Input: add support for ROHM BU21023/24 touchscreen
+
+This adds support for ROHM BU21023/24 Dual touch resistive touchscreens.
+
+Signed-off-by: Yoichi Yuasa <yuasa@linux-mips.org>
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+
+---
+ drivers/input/touchscreen/Kconfig | 11
+ drivers/input/touchscreen/rohm_bu21023.c | 1218 +++++++++++++++++++++++++++++++
+ 2 files changed, 1229 insertions(+)
+
+--- a/drivers/input/touchscreen/Kconfig
++++ b/drivers/input/touchscreen/Kconfig
+@@ -1027,4 +1027,15 @@ config TOUCHSCREEN_ZFORCE
+ To compile this driver as a module, choose M here: the
+ module will be called zforce_ts.
+
++config TOUCHSCREEN_ROHM_BU21023
++ tristate "ROHM BU21023/24 Dual touch support resistive touchscreens"
++ depends on I2C
++ help
++ Say Y here if you have a touchscreen using ROHM BU21023/24.
++
++ If unsure, say N.
++
++ To compile this driver as a module, choose M here: the
++ module will be called bu21023_ts.
++
+ endif
+--- /dev/null
++++ b/drivers/input/touchscreen/rohm_bu21023.c
+@@ -0,0 +1,1218 @@
++/*
++ * ROHM BU21023/24 Dual touch support resistive touch screen driver
++ * Copyright (C) 2012 ROHM CO.,LTD.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * 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 <linux/delay.h>
++#include <linux/firmware.h>
++#include <linux/i2c.h>
++#include <linux/input.h>
++#include <linux/input/mt.h>
++#include <linux/interrupt.h>
++#include <linux/module.h>
++#include <linux/slab.h>
++
++#define BU21023_NAME "bu21023_ts"
++#define BU21023_FIRMWARE_NAME "bu21023.bin"
++
++#define MAX_CONTACTS 2
++
++#define AXIS_ADJUST 4
++#define AXIS_OFFSET 8
++
++#define FIRMWARE_BLOCK_SIZE 32U
++#define FIRMWARE_RETRY_MAX 4
++
++#define SAMPLING_DELAY 12 /* msec */
++
++#define CALIBRATION_RETRY_MAX 6
++
++#define ROHM_TS_ABS_X_MIN 40
++#define ROHM_TS_ABS_X_MAX 990
++#define ROHM_TS_ABS_Y_MIN 160
++#define ROHM_TS_ABS_Y_MAX 920
++#define ROHM_TS_DISPLACEMENT_MAX 0 /* zero for infinite */
++
++/*
++ * BU21023GUL/BU21023MUV/BU21024FV-M registers map
++ */
++#define VADOUT_YP_H 0x00
++#define VADOUT_YP_L 0x01
++#define VADOUT_XP_H 0x02
++#define VADOUT_XP_L 0x03
++#define VADOUT_YN_H 0x04
++#define VADOUT_YN_L 0x05
++#define VADOUT_XN_H 0x06
++#define VADOUT_XN_L 0x07
++
++#define PRM1_X_H 0x08
++#define PRM1_X_L 0x09
++#define PRM1_Y_H 0x0a
++#define PRM1_Y_L 0x0b
++#define PRM2_X_H 0x0c
++#define PRM2_X_L 0x0d
++#define PRM2_Y_H 0x0e
++#define PRM2_Y_L 0x0f
++
++#define MLT_PRM_MONI_X 0x10
++#define MLT_PRM_MONI_Y 0x11
++
++#define DEBUG_MONI_1 0x12
++#define DEBUG_MONI_2 0x13
++
++#define VADOUT_ZX_H 0x14
++#define VADOUT_ZX_L 0x15
++#define VADOUT_ZY_H 0x16
++#define VADOUT_ZY_L 0x17
++
++#define Z_PARAM_H 0x18
++#define Z_PARAM_L 0x19
++
++/*
++ * Value for VADOUT_*_L
++ */
++#define VADOUT_L_MASK 0x01
++
++/*
++ * Value for PRM*_*_L
++ */
++#define PRM_L_MASK 0x01
++
++#define POS_X1_H 0x20
++#define POS_X1_L 0x21
++#define POS_Y1_H 0x22
++#define POS_Y1_L 0x23
++#define POS_X2_H 0x24
++#define POS_X2_L 0x25
++#define POS_Y2_H 0x26
++#define POS_Y2_L 0x27
++
++/*
++ * Value for POS_*_L
++ */
++#define POS_L_MASK 0x01
++
++#define TOUCH 0x28
++#define TOUCH_DETECT 0x01
++
++#define TOUCH_GESTURE 0x29
++#define SINGLE_TOUCH 0x01
++#define DUAL_TOUCH 0x03
++#define TOUCH_MASK 0x03
++#define CALIBRATION_REQUEST 0x04
++#define CALIBRATION_STATUS 0x08
++#define CALIBRATION_MASK 0x0c
++#define GESTURE_SPREAD 0x10
++#define GESTURE_PINCH 0x20
++#define GESTURE_ROTATE_R 0x40
++#define GESTURE_ROTATE_L 0x80
++
++#define INT_STATUS 0x2a
++#define INT_MASK 0x3d
++#define INT_CLEAR 0x3e
++
++/*
++ * Values for INT_*
++ */
++#define COORD_UPDATE 0x01
++#define CALIBRATION_DONE 0x02
++#define SLEEP_IN 0x04
++#define SLEEP_OUT 0x08
++#define PROGRAM_LOAD_DONE 0x10
++#define ERROR 0x80
++#define INT_ALL 0x9f
++
++#define ERR_STATUS 0x2b
++#define ERR_MASK 0x3f
++
++/*
++ * Values for ERR_*
++ */
++#define ADC_TIMEOUT 0x01
++#define CPU_TIMEOUT 0x02
++#define CALIBRATION_ERR 0x04
++#define PROGRAM_LOAD_ERR 0x10
++
++#define COMMON_SETUP1 0x30
++#define PROGRAM_LOAD_HOST 0x02
++#define PROGRAM_LOAD_EEPROM 0x03
++#define CENSOR_4PORT 0x04
++#define CENSOR_8PORT 0x00 /* Not supported by BU21023 */
++#define CALIBRATION_TYPE_DEFAULT 0x08
++#define CALIBRATION_TYPE_SPECIAL 0x00
++#define INT_ACTIVE_HIGH 0x10
++#define INT_ACTIVE_LOW 0x00
++#define AUTO_CALIBRATION 0x40
++#define MANUAL_CALIBRATION 0x00
++#define COMMON_SETUP1_DEFAULT 0x4e
++
++#define COMMON_SETUP2 0x31
++#define MAF_NONE 0x00
++#define MAF_1SAMPLE 0x01
++#define MAF_3SAMPLES 0x02
++#define MAF_5SAMPLES 0x03
++#define INV_Y 0x04
++#define INV_X 0x08
++#define SWAP_XY 0x10
++
++#define COMMON_SETUP3 0x32
++#define EN_SLEEP 0x01
++#define EN_MULTI 0x02
++#define EN_GESTURE 0x04
++#define EN_INTVL 0x08
++#define SEL_STEP 0x10
++#define SEL_MULTI 0x20
++#define SEL_TBL_DEFAULT 0x40
++
++#define INTERVAL_TIME 0x33
++#define INTERVAL_TIME_DEFAULT 0x10
++
++#define STEP_X 0x34
++#define STEP_X_DEFAULT 0x41
++
++#define STEP_Y 0x35
++#define STEP_Y_DEFAULT 0x8d
++
++#define OFFSET_X 0x38
++#define OFFSET_X_DEFAULT 0x0c
++
++#define OFFSET_Y 0x39
++#define OFFSET_Y_DEFAULT 0x0c
++
++#define THRESHOLD_TOUCH 0x3a
++#define THRESHOLD_TOUCH_DEFAULT 0xa0
++
++#define THRESHOLD_GESTURE 0x3b
++#define THRESHOLD_GESTURE_DEFAULT 0x17
++
++#define SYSTEM 0x40
++#define ANALOG_POWER_ON 0x01
++#define ANALOG_POWER_OFF 0x00
++#define CPU_POWER_ON 0x02
++#define CPU_POWER_OFF 0x00
++
++#define FORCE_CALIBRATION 0x42
++#define FORCE_CALIBRATION_ON 0x01
++#define FORCE_CALIBRATION_OFF 0x00
++
++#define CPU_FREQ 0x50 /* 10 / (reg + 1) MHz */
++#define CPU_FREQ_10MHZ 0x00
++#define CPU_FREQ_5MHZ 0x01
++#define CPU_FREQ_1MHZ 0x09
++
++#define EEPROM_ADDR 0x51
++
++#define CALIBRATION_ADJUST 0x52
++#define CALIBRATION_ADJUST_DEFAULT 0x00
++
++#define THRESHOLD_SLEEP_IN 0x53
++
++#define EVR_XY 0x56
++#define EVR_XY_DEFAULT 0x10
++
++#define PRM_SWOFF_TIME 0x57
++#define PRM_SWOFF_TIME_DEFAULT 0x04
++
++#define PROGRAM_VERSION 0x5f
++
++#define ADC_CTRL 0x60
++#define ADC_DIV_MASK 0x1f /* The minimum value is 4 */
++#define ADC_DIV_DEFAULT 0x08
++
++#define ADC_WAIT 0x61
++#define ADC_WAIT_DEFAULT 0x0a
++
++#define SWCONT 0x62
++#define SWCONT_DEFAULT 0x0f
++
++#define EVR_X 0x63
++#define EVR_X_DEFAULT 0x86
++
++#define EVR_Y 0x64
++#define EVR_Y_DEFAULT 0x64
++
++#define TEST1 0x65
++#define DUALTOUCH_STABILIZE_ON 0x01
++#define DUALTOUCH_STABILIZE_OFF 0x00
++#define DUALTOUCH_REG_ON 0x20
++#define DUALTOUCH_REG_OFF 0x00
++
++#define CALIBRATION_REG1 0x68
++#define CALIBRATION_REG1_DEFAULT 0xd9
++
++#define CALIBRATION_REG2 0x69
++#define CALIBRATION_REG2_DEFAULT 0x36
++
++#define CALIBRATION_REG3 0x6a
++#define CALIBRATION_REG3_DEFAULT 0x32
++
++#define EX_ADDR_H 0x70
++#define EX_ADDR_L 0x71
++#define EX_WDAT 0x72
++#define EX_RDAT 0x73
++#define EX_CHK_SUM1 0x74
++#define EX_CHK_SUM2 0x75
++#define EX_CHK_SUM3 0x76
++
++struct rohm_ts_data {
++ struct i2c_client *client;
++ struct input_dev *input;
++
++ bool initialized;
++
++ unsigned int contact_count[MAX_CONTACTS + 1];
++ int finger_count;
++
++ u8 setup2;
++};
++
++/*
++ * rohm_i2c_burst_read - execute combined I2C message for ROHM BU21023/24
++ * @client: Handle to ROHM BU21023/24
++ * @start: Where to start read address from ROHM BU21023/24
++ * @buf: Where to store read data from ROHM BU21023/24
++ * @len: How many bytes to read
++ *
++ * Returns negative errno, else zero on success.
++ *
++ * Note
++ * In BU21023/24 burst read, stop condition is needed after "address write".
++ * Therefore, transmission is performed in 2 steps.
++ */
++static int rohm_i2c_burst_read(struct i2c_client *client, u8 start, void *buf,
++ size_t len)
++{
++ struct i2c_adapter *adap = client->adapter;
++ struct i2c_msg msg[2];
++ int i, ret = 0;
++
++ msg[0].addr = client->addr;
++ msg[0].flags = 0;
++ msg[0].len = 1;
++ msg[0].buf = &start;
++
++ msg[1].addr = client->addr;
++ msg[1].flags = I2C_M_RD;
++ msg[1].len = len;
++ msg[1].buf = buf;
++
++ i2c_lock_adapter(adap);
++
++ for (i = 0; i < 2; i++) {
++ if (__i2c_transfer(adap, &msg[i], 1) < 0) {
++ ret = -EIO;
++ break;
++ }
++ }
++
++ i2c_unlock_adapter(adap);
++
++ return ret;
++}
++
++static int rohm_ts_manual_calibration(struct rohm_ts_data *ts)
++{
++ struct i2c_client *client = ts->client;
++ struct device *dev = &client->dev;
++ u8 buf[33]; /* for PRM1_X_H(0x08)-TOUCH(0x28) */
++
++ int retry;
++ bool success = false;
++ bool first_time = true;
++ bool calibration_done;
++
++ u8 reg1, reg2, reg3;
++ s32 reg1_orig, reg2_orig, reg3_orig;
++ s32 val;
++
++ int calib_x = 0, calib_y = 0;
++ int reg_x, reg_y;
++ int err_x, err_y;
++
++ int error, error2;
++ int i;
++
++ reg1_orig = i2c_smbus_read_byte_data(client, CALIBRATION_REG1);
++ if (reg1_orig < 0)
++ return reg1_orig;
++
++ reg2_orig = i2c_smbus_read_byte_data(client, CALIBRATION_REG2);
++ if (reg2_orig < 0)
++ return reg2_orig;
++
++ reg3_orig = i2c_smbus_read_byte_data(client, CALIBRATION_REG3);
++ if (reg3_orig < 0)
++ return reg3_orig;
++
++ error = i2c_smbus_write_byte_data(client, INT_MASK,
++ COORD_UPDATE | SLEEP_IN | SLEEP_OUT |
++ PROGRAM_LOAD_DONE);
++ if (error)
++ goto out;
++
++ error = i2c_smbus_write_byte_data(client, TEST1,
++ DUALTOUCH_STABILIZE_ON);
++ if (error)
++ goto out;
++
++ for (retry = 0; retry < CALIBRATION_RETRY_MAX; retry++) {
++ /* wait 2 sampling for update */
++ mdelay(2 * SAMPLING_DELAY);
++
++#define READ_CALIB_BUF(reg) buf[((reg) - PRM1_X_H)]
++
++ error = rohm_i2c_burst_read(client, PRM1_X_H, buf, sizeof(buf));
++ if (error)
++ goto out;
++
++ if (READ_CALIB_BUF(TOUCH) & TOUCH_DETECT)
++ continue;
++
++ if (first_time) {
++ /* generate calibration parameter */
++ calib_x = ((int)READ_CALIB_BUF(PRM1_X_H) << 2 |
++ READ_CALIB_BUF(PRM1_X_L)) - AXIS_OFFSET;
++ calib_y = ((int)READ_CALIB_BUF(PRM1_Y_H) << 2 |
++ READ_CALIB_BUF(PRM1_Y_L)) - AXIS_OFFSET;
++
++ error = i2c_smbus_write_byte_data(client, TEST1,
++ DUALTOUCH_STABILIZE_ON | DUALTOUCH_REG_ON);
++ if (error)
++ goto out;
++
++ first_time = false;
++ } else {
++ /* generate adjustment parameter */
++ err_x = (int)READ_CALIB_BUF(PRM1_X_H) << 2 |
++ READ_CALIB_BUF(PRM1_X_L);
++ err_y = (int)READ_CALIB_BUF(PRM1_Y_H) << 2 |
++ READ_CALIB_BUF(PRM1_Y_L);
++
++ /* X axis ajust */
++ if (err_x <= 4)
++ calib_x -= AXIS_ADJUST;
++ else if (err_x >= 60)
++ calib_x += AXIS_ADJUST;
++
++ /* Y axis ajust */
++ if (err_y <= 4)
++ calib_y -= AXIS_ADJUST;
++ else if (err_y >= 60)
++ calib_y += AXIS_ADJUST;
++ }
++
++ /* generate calibration setting value */
++ reg_x = calib_x + ((calib_x & 0x200) << 1);
++ reg_y = calib_y + ((calib_y & 0x200) << 1);
++
++ /* convert for register format */
++ reg1 = reg_x >> 3;
++ reg2 = (reg_y & 0x7) << 4 | (reg_x & 0x7);
++ reg3 = reg_y >> 3;
++
++ error = i2c_smbus_write_byte_data(client,
++ CALIBRATION_REG1, reg1);
++ if (error)
++ goto out;
++
++ error = i2c_smbus_write_byte_data(client,
++ CALIBRATION_REG2, reg2);
++ if (error)
++ goto out;
++
++ error = i2c_smbus_write_byte_data(client,
++ CALIBRATION_REG3, reg3);
++ if (error)
++ goto out;
++
++ /*
++ * force calibration sequcence
++ */
++ error = i2c_smbus_write_byte_data(client, FORCE_CALIBRATION,
++ FORCE_CALIBRATION_OFF);
++ if (error)
++ goto out;
++
++ error = i2c_smbus_write_byte_data(client, FORCE_CALIBRATION,
++ FORCE_CALIBRATION_ON);
++ if (error)
++ goto out;
++
++ /* clear all interrupts */
++ error = i2c_smbus_write_byte_data(client, INT_CLEAR, 0xff);
++ if (error)
++ goto out;
++
++ /*
++ * Wait for the status change of calibration, max 10 sampling
++ */
++ calibration_done = false;
++
++ for (i = 0; i < 10; i++) {
++ mdelay(SAMPLING_DELAY);
++
++ val = i2c_smbus_read_byte_data(client, TOUCH_GESTURE);
++ if (!(val & CALIBRATION_MASK)) {
++ calibration_done = true;
++ break;
++ } else if (val < 0) {
++ error = val;
++ goto out;
++ }
++ }
++
++ if (calibration_done) {
++ val = i2c_smbus_read_byte_data(client, INT_STATUS);
++ if (val == CALIBRATION_DONE) {
++ success = true;
++ break;
++ } else if (val < 0) {
++ error = val;
++ goto out;
++ }
++ } else {
++ dev_warn(dev, "calibration timeout\n");
++ }
++ }
++
++ if (!success) {
++ error = i2c_smbus_write_byte_data(client, CALIBRATION_REG1,
++ reg1_orig);
++ if (error)
++ goto out;
++
++ error = i2c_smbus_write_byte_data(client, CALIBRATION_REG2,
++ reg2_orig);
++ if (error)
++ goto out;
++
++ error = i2c_smbus_write_byte_data(client, CALIBRATION_REG3,
++ reg3_orig);
++ if (error)
++ goto out;
++
++ /* calibration data enable */
++ error = i2c_smbus_write_byte_data(client, TEST1,
++ DUALTOUCH_STABILIZE_ON |
++ DUALTOUCH_REG_ON);
++ if (error)
++ goto out;
++
++ /* wait 10 sampling */
++ mdelay(10 * SAMPLING_DELAY);
++
++ error = -EBUSY;
++ }
++
++out:
++ error2 = i2c_smbus_write_byte_data(client, INT_MASK, INT_ALL);
++ if (!error2)
++ /* Clear all interrupts */
++ error2 = i2c_smbus_write_byte_data(client, INT_CLEAR, 0xff);
++
++ return error ? error : error2;
++}
++
++static const unsigned int untouch_threshold[3] = { 0, 1, 5 };
++static const unsigned int single_touch_threshold[3] = { 0, 0, 4 };
++static const unsigned int dual_touch_threshold[3] = { 10, 8, 0 };
++
++static irqreturn_t rohm_ts_soft_irq(int irq, void *dev_id)
++{
++ struct rohm_ts_data *ts = dev_id;
++ struct i2c_client *client = ts->client;
++ struct input_dev *input_dev = ts->input;
++ struct device *dev = &client->dev;
++
++ u8 buf[10]; /* for POS_X1_H(0x20)-TOUCH_GESTURE(0x29) */
++
++ struct input_mt_pos pos[MAX_CONTACTS];
++ int slots[MAX_CONTACTS];
++ u8 touch_flags;
++ unsigned int threshold;
++ int finger_count = -1;
++ int prev_finger_count = ts->finger_count;
++ int count;
++ int error;
++ int i;
++
++ error = i2c_smbus_write_byte_data(client, INT_MASK, INT_ALL);
++ if (error)
++ return IRQ_HANDLED;
++
++ /* Clear all interrupts */
++ error = i2c_smbus_write_byte_data(client, INT_CLEAR, 0xff);
++ if (error)
++ return IRQ_HANDLED;
++
++#define READ_POS_BUF(reg) buf[((reg) - POS_X1_H)]
++
++ error = rohm_i2c_burst_read(client, POS_X1_H, buf, sizeof(buf));
++ if (error)
++ return IRQ_HANDLED;
++
++ touch_flags = READ_POS_BUF(TOUCH_GESTURE) & TOUCH_MASK;
++ if (touch_flags) {
++ /* generate coordinates */
++ pos[0].x = ((s16)READ_POS_BUF(POS_X1_H) << 2) |
++ READ_POS_BUF(POS_X1_L);
++ pos[0].y = ((s16)READ_POS_BUF(POS_Y1_H) << 2) |
++ READ_POS_BUF(POS_Y1_L);
++ pos[1].x = ((s16)READ_POS_BUF(POS_X2_H) << 2) |
++ READ_POS_BUF(POS_X2_L);
++ pos[1].y = ((s16)READ_POS_BUF(POS_Y2_H) << 2) |
++ READ_POS_BUF(POS_Y2_L);
++ }
++
++ switch (touch_flags) {
++ case 0:
++ threshold = untouch_threshold[prev_finger_count];
++ if (++ts->contact_count[0] >= threshold)
++ finger_count = 0;
++ break;
++
++ case SINGLE_TOUCH:
++ threshold = single_touch_threshold[prev_finger_count];
++ if (++ts->contact_count[1] >= threshold)
++ finger_count = 1;
++
++ if (finger_count == 1) {
++ if (pos[1].x != 0 && pos[1].y != 0) {
++ pos[0].x = pos[1].x;
++ pos[0].y = pos[1].y;
++ pos[1].x = 0;
++ pos[1].y = 0;
++ }
++ }
++ break;
++
++ case DUAL_TOUCH:
++ threshold = dual_touch_threshold[prev_finger_count];
++ if (++ts->contact_count[2] >= threshold)
++ finger_count = 2;
++ break;
++
++ default:
++ dev_dbg(dev,
++ "Three or more touches are not supported\n");
++ return IRQ_HANDLED;
++ }
++
++ if (finger_count >= 0) {
++ if (prev_finger_count != finger_count) {
++ count = ts->contact_count[finger_count];
++ memset(ts->contact_count, 0, sizeof(ts->contact_count));
++ ts->contact_count[finger_count] = count;
++ }
++
++ input_mt_assign_slots(input_dev, slots, pos,
++ finger_count, ROHM_TS_DISPLACEMENT_MAX);
++
++ for (i = 0; i < finger_count; i++) {
++ input_mt_slot(input_dev, slots[i]);
++ input_mt_report_slot_state(input_dev,
++ MT_TOOL_FINGER, true);
++ input_report_abs(input_dev,
++ ABS_MT_POSITION_X, pos[i].x);
++ input_report_abs(input_dev,
++ ABS_MT_POSITION_Y, pos[i].y);
++ }
++
++ input_mt_sync_frame(input_dev);
++ input_mt_report_pointer_emulation(input_dev, true);
++ input_sync(input_dev);
++
++ ts->finger_count = finger_count;
++ }
++
++ if (READ_POS_BUF(TOUCH_GESTURE) & CALIBRATION_REQUEST) {
++ error = rohm_ts_manual_calibration(ts);
++ if (error)
++ dev_warn(dev, "manual calibration failed: %d\n",
++ error);
++ }
++
++ i2c_smbus_write_byte_data(client, INT_MASK,
++ CALIBRATION_DONE | SLEEP_OUT | SLEEP_IN |
++ PROGRAM_LOAD_DONE);
++
++ return IRQ_HANDLED;
++}
++
++static int rohm_ts_load_firmware(struct i2c_client *client,
++ const char *firmware_name)
++{
++ struct device *dev = &client->dev;
++ const struct firmware *fw;
++ s32 status;
++ unsigned int offset, len, xfer_len;
++ unsigned int retry = 0;
++ int error, error2;
++
++ error = request_firmware(&fw, firmware_name, dev);
++ if (error) {
++ dev_err(dev, "unable to retrieve firmware %s: %d\n",
++ firmware_name, error);
++ return error;
++ }
++
++ error = i2c_smbus_write_byte_data(client, INT_MASK,
++ COORD_UPDATE | CALIBRATION_DONE |
++ SLEEP_IN | SLEEP_OUT);
++ if (error)
++ goto out;
++
++ do {
++ if (retry) {
++ dev_warn(dev, "retrying firmware load\n");
++
++ /* settings for retry */
++ error = i2c_smbus_write_byte_data(client, EX_WDAT, 0);
++ if (error)
++ goto out;
++ }
++
++ error = i2c_smbus_write_byte_data(client, EX_ADDR_H, 0);
++ if (error)
++ goto out;
++
++ error = i2c_smbus_write_byte_data(client, EX_ADDR_L, 0);
++ if (error)
++ goto out;
++
++ error = i2c_smbus_write_byte_data(client, COMMON_SETUP1,
++ COMMON_SETUP1_DEFAULT);
++ if (error)
++ goto out;
++
++ /* firmware load to the device */
++ offset = 0;
++ len = fw->size;
++
++ while (len) {
++ xfer_len = min(FIRMWARE_BLOCK_SIZE, len);
++
++ error = i2c_smbus_write_i2c_block_data(client, EX_WDAT,
++ xfer_len, &fw->data[offset]);
++ if (error)
++ goto out;
++
++ len -= xfer_len;
++ offset += xfer_len;
++ }
++
++ /* check firmware load result */
++ status = i2c_smbus_read_byte_data(client, INT_STATUS);
++ if (status < 0) {
++ error = status;
++ goto out;
++ }
++
++ /* clear all interrupts */
++ error = i2c_smbus_write_byte_data(client, INT_CLEAR, 0xff);
++ if (error)
++ goto out;
++
++ if (status == PROGRAM_LOAD_DONE)
++ break;
++
++ error = -EIO;
++ } while (++retry >= FIRMWARE_RETRY_MAX);
++
++out:
++ error2 = i2c_smbus_write_byte_data(client, INT_MASK, INT_ALL);
++
++ release_firmware(fw);
++
++ return error ? error : error2;
++}
++
++static ssize_t swap_xy_show(struct device *dev, struct device_attribute *attr,
++ char *buf)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct rohm_ts_data *ts = i2c_get_clientdata(client);
++
++ return sprintf(buf, "%d\n", !!(ts->setup2 & SWAP_XY));
++}
++
++static ssize_t swap_xy_store(struct device *dev, struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct rohm_ts_data *ts = i2c_get_clientdata(client);
++ unsigned int val;
++ int error;
++
++ error = kstrtouint(buf, 0, &val);
++ if (error)
++ return error;
++
++ error = mutex_lock_interruptible(&ts->input->mutex);
++ if (error)
++ return error;
++
++ if (val)
++ ts->setup2 |= SWAP_XY;
++ else
++ ts->setup2 &= ~SWAP_XY;
++
++ if (ts->initialized)
++ error = i2c_smbus_write_byte_data(ts->client, COMMON_SETUP2,
++ ts->setup2);
++
++ mutex_unlock(&ts->input->mutex);
++
++ return error ? error : count;
++}
++
++static ssize_t inv_x_show(struct device *dev, struct device_attribute *attr,
++ char *buf)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct rohm_ts_data *ts = i2c_get_clientdata(client);
++
++ return sprintf(buf, "%d\n", !!(ts->setup2 & INV_X));
++}
++
++static ssize_t inv_x_store(struct device *dev, struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct rohm_ts_data *ts = i2c_get_clientdata(client);
++ unsigned int val;
++ int error;
++
++ error = kstrtouint(buf, 0, &val);
++ if (error)
++ return error;
++
++ error = mutex_lock_interruptible(&ts->input->mutex);
++ if (error)
++ return error;
++
++ if (val)
++ ts->setup2 |= INV_X;
++ else
++ ts->setup2 &= ~INV_X;
++
++ if (ts->initialized)
++ error = i2c_smbus_write_byte_data(ts->client, COMMON_SETUP2,
++ ts->setup2);
++
++ mutex_unlock(&ts->input->mutex);
++
++ return error ? error : count;
++}
++
++static ssize_t inv_y_show(struct device *dev, struct device_attribute *attr,
++ char *buf)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct rohm_ts_data *ts = i2c_get_clientdata(client);
++
++ return sprintf(buf, "%d\n", !!(ts->setup2 & INV_Y));
++}
++
++static ssize_t inv_y_store(struct device *dev, struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct rohm_ts_data *ts = i2c_get_clientdata(client);
++ unsigned int val;
++ int error;
++
++ error = kstrtouint(buf, 0, &val);
++ if (error)
++ return error;
++
++ error = mutex_lock_interruptible(&ts->input->mutex);
++ if (error)
++ return error;
++
++ if (val)
++ ts->setup2 |= INV_Y;
++ else
++ ts->setup2 &= ~INV_Y;
++
++ if (ts->initialized)
++ error = i2c_smbus_write_byte_data(client, COMMON_SETUP2,
++ ts->setup2);
++
++ mutex_unlock(&ts->input->mutex);
++
++ return error ? error : count;
++}
++
++static DEVICE_ATTR_RW(swap_xy);
++static DEVICE_ATTR_RW(inv_x);
++static DEVICE_ATTR_RW(inv_y);
++
++static struct attribute *rohm_ts_attrs[] = {
++ &dev_attr_swap_xy.attr,
++ &dev_attr_inv_x.attr,
++ &dev_attr_inv_y.attr,
++ NULL,
++};
++
++static const struct attribute_group rohm_ts_attr_group = {
++ .attrs = rohm_ts_attrs,
++};
++
++static int rohm_ts_device_init(struct i2c_client *client, u8 setup2)
++{
++ struct device *dev = &client->dev;
++ int error;
++
++ disable_irq(client->irq);
++
++ /*
++ * Wait 200usec for reset
++ */
++ udelay(200);
++
++ /* Release analog reset */
++ error = i2c_smbus_write_byte_data(client, SYSTEM,
++ ANALOG_POWER_ON | CPU_POWER_OFF);
++ if (error)
++ return error;
++
++ /* Waiting for the analog warm-up, max. 200usec */
++ udelay(200);
++
++ /* clear all interrupts */
++ error = i2c_smbus_write_byte_data(client, INT_CLEAR, 0xff);
++ if (error)
++ return error;
++
++ error = i2c_smbus_write_byte_data(client, EX_WDAT, 0);
++ if (error)
++ return error;
++
++ error = i2c_smbus_write_byte_data(client, COMMON_SETUP1, 0);
++ if (error)
++ return error;
++
++ error = i2c_smbus_write_byte_data(client, COMMON_SETUP2, setup2);
++ if (error)
++ return error;
++
++ error = i2c_smbus_write_byte_data(client, COMMON_SETUP3,
++ SEL_TBL_DEFAULT | EN_MULTI);
++ if (error)
++ return error;
++
++ error = i2c_smbus_write_byte_data(client, THRESHOLD_GESTURE,
++ THRESHOLD_GESTURE_DEFAULT);
++ if (error)
++ return error;
++
++ error = i2c_smbus_write_byte_data(client, INTERVAL_TIME,
++ INTERVAL_TIME_DEFAULT);
++ if (error)
++ return error;
++
++ error = i2c_smbus_write_byte_data(client, CPU_FREQ, CPU_FREQ_10MHZ);
++ if (error)
++ return error;
++
++ error = i2c_smbus_write_byte_data(client, PRM_SWOFF_TIME,
++ PRM_SWOFF_TIME_DEFAULT);
++ if (error)
++ return error;
++
++ error = i2c_smbus_write_byte_data(client, ADC_CTRL, ADC_DIV_DEFAULT);
++ if (error)
++ return error;
++
++ error = i2c_smbus_write_byte_data(client, ADC_WAIT, ADC_WAIT_DEFAULT);
++ if (error)
++ return error;
++
++ /*
++ * Panel setup, these values change with the panel.
++ */
++ error = i2c_smbus_write_byte_data(client, STEP_X, STEP_X_DEFAULT);
++ if (error)
++ return error;
++
++ error = i2c_smbus_write_byte_data(client, STEP_Y, STEP_Y_DEFAULT);
++ if (error)
++ return error;
++
++ error = i2c_smbus_write_byte_data(client, OFFSET_X, OFFSET_X_DEFAULT);
++ if (error)
++ return error;
++
++ error = i2c_smbus_write_byte_data(client, OFFSET_Y, OFFSET_Y_DEFAULT);
++ if (error)
++ return error;
++
++ error = i2c_smbus_write_byte_data(client, THRESHOLD_TOUCH,
++ THRESHOLD_TOUCH_DEFAULT);
++ if (error)
++ return error;
++
++ error = i2c_smbus_write_byte_data(client, EVR_XY, EVR_XY_DEFAULT);
++ if (error)
++ return error;
++
++ error = i2c_smbus_write_byte_data(client, EVR_X, EVR_X_DEFAULT);
++ if (error)
++ return error;
++
++ error = i2c_smbus_write_byte_data(client, EVR_Y, EVR_Y_DEFAULT);
++ if (error)
++ return error;
++
++ /* Fixed value settings */
++ error = i2c_smbus_write_byte_data(client, CALIBRATION_ADJUST,
++ CALIBRATION_ADJUST_DEFAULT);
++ if (error)
++ return error;
++
++ error = i2c_smbus_write_byte_data(client, SWCONT, SWCONT_DEFAULT);
++ if (error)
++ return error;
++
++ error = i2c_smbus_write_byte_data(client, TEST1,
++ DUALTOUCH_STABILIZE_ON |
++ DUALTOUCH_REG_ON);
++ if (error)
++ return error;
++
++ error = rohm_ts_load_firmware(client, BU21023_FIRMWARE_NAME);
++ if (error) {
++ dev_err(dev, "failed to load firmware: %d\n", error);
++ return error;
++ }
++
++ /*
++ * Manual calibration results are not changed in same environment.
++ * If the force calibration is performed,
++ * the controller will not require calibration request interrupt
++ * when the typical values are set to the calibration registers.
++ */
++ error = i2c_smbus_write_byte_data(client, CALIBRATION_REG1,
++ CALIBRATION_REG1_DEFAULT);
++ if (error)
++ return error;
++
++ error = i2c_smbus_write_byte_data(client, CALIBRATION_REG2,
++ CALIBRATION_REG2_DEFAULT);
++ if (error)
++ return error;
++
++ error = i2c_smbus_write_byte_data(client, CALIBRATION_REG3,
++ CALIBRATION_REG3_DEFAULT);
++ if (error)
++ return error;
++
++ error = i2c_smbus_write_byte_data(client, FORCE_CALIBRATION,
++ FORCE_CALIBRATION_OFF);
++ if (error)
++ return error;
++
++ error = i2c_smbus_write_byte_data(client, FORCE_CALIBRATION,
++ FORCE_CALIBRATION_ON);
++ if (error)
++ return error;
++
++ /* Clear all interrupts */
++ error = i2c_smbus_write_byte_data(client, INT_CLEAR, 0xff);
++ if (error)
++ return error;
++
++ /* Enable coordinates update interrupt */
++ error = i2c_smbus_write_byte_data(client, INT_MASK,
++ CALIBRATION_DONE | SLEEP_OUT |
++ SLEEP_IN | PROGRAM_LOAD_DONE);
++ if (error)
++ return error;
++
++ error = i2c_smbus_write_byte_data(client, ERR_MASK,
++ PROGRAM_LOAD_ERR | CPU_TIMEOUT |
++ ADC_TIMEOUT);
++ if (error)
++ return error;
++
++ /* controller CPU power on */
++ error = i2c_smbus_write_byte_data(client, SYSTEM,
++ ANALOG_POWER_ON | CPU_POWER_ON);
++
++ enable_irq(client->irq);
++
++ return error;
++}
++
++static int rohm_ts_power_off(struct i2c_client *client)
++{
++ int error;
++
++ error = i2c_smbus_write_byte_data(client, SYSTEM,
++ ANALOG_POWER_ON | CPU_POWER_OFF);
++ if (error) {
++ dev_err(&client->dev,
++ "failed to power off device CPU: %d\n", error);
++ return error;
++ }
++
++ error = i2c_smbus_write_byte_data(client, SYSTEM,
++ ANALOG_POWER_OFF | CPU_POWER_OFF);
++ if (error)
++ dev_err(&client->dev,
++ "failed to power off the device: %d\n", error);
++
++ return error;
++}
++
++static int rohm_ts_open(struct input_dev *input_dev)
++{
++ struct rohm_ts_data *ts = input_get_drvdata(input_dev);
++ struct i2c_client *client = ts->client;
++ int error;
++
++ if (!ts->initialized) {
++ error = rohm_ts_device_init(client, ts->setup2);
++ if (error) {
++ dev_err(&client->dev,
++ "device initialization failed: %d\n", error);
++ return error;
++ }
++
++ ts->initialized = true;
++ }
++
++ return 0;
++}
++
++static void rohm_ts_close(struct input_dev *input_dev)
++{
++ struct rohm_ts_data *ts = input_get_drvdata(input_dev);
++
++ rohm_ts_power_off(ts->client);
++
++ ts->initialized = false;
++}
++
++static void rohm_ts_remove_sysfs_group(void *_dev)
++{
++ struct device *dev = _dev;
++
++ sysfs_remove_group(&dev->kobj, &rohm_ts_attr_group);
++}
++
++static int rohm_bu21023_i2c_probe(struct i2c_client *client,
++ const struct i2c_device_id *id)
++{
++ struct device *dev = &client->dev;
++ struct rohm_ts_data *ts;
++ struct input_dev *input;
++ int error;
++
++ if (!client->irq) {
++ dev_err(dev, "IRQ is not assigned\n");
++ return -EINVAL;
++ }
++
++ if (!client->adapter->algo->master_xfer) {
++ dev_err(dev, "I2C level transfers not supported\n");
++ return -EOPNOTSUPP;
++ }
++
++ /* Turn off CPU just in case */
++ error = rohm_ts_power_off(client);
++ if (error)
++ return error;
++
++ ts = devm_kzalloc(dev, sizeof(struct rohm_ts_data), GFP_KERNEL);
++ if (!ts)
++ return -ENOMEM;
++
++ ts->client = client;
++ ts->setup2 = MAF_1SAMPLE;
++ i2c_set_clientdata(client, ts);
++
++ input = devm_input_allocate_device(dev);
++ if (!input)
++ return -ENOMEM;
++
++ input->name = BU21023_NAME;
++ input->id.bustype = BUS_I2C;
++ input->open = rohm_ts_open;
++ input->close = rohm_ts_close;
++
++ ts->input = input;
++ input_set_drvdata(input, ts);
++
++ input_set_abs_params(input, ABS_MT_POSITION_X,
++ ROHM_TS_ABS_X_MIN, ROHM_TS_ABS_X_MAX, 0, 0);
++ input_set_abs_params(input, ABS_MT_POSITION_Y,
++ ROHM_TS_ABS_Y_MIN, ROHM_TS_ABS_Y_MAX, 0, 0);
++
++ error = input_mt_init_slots(input, MAX_CONTACTS,
++ INPUT_MT_DIRECT | INPUT_MT_TRACK |
++ INPUT_MT_DROP_UNUSED);
++ if (error) {
++ dev_err(dev, "failed to multi touch slots initialization\n");
++ return error;
++ }
++
++ error = devm_request_threaded_irq(dev, client->irq,
++ NULL, rohm_ts_soft_irq,
++ IRQF_ONESHOT, client->name, ts);
++ if (error) {
++ dev_err(dev, "failed to request IRQ: %d\n", error);
++ return error;
++ }
++
++ error = input_register_device(input);
++ if (error) {
++ dev_err(dev, "failed to register input device: %d\n", error);
++ return error;
++ }
++
++ error = sysfs_create_group(&dev->kobj, &rohm_ts_attr_group);
++ if (error) {
++ dev_err(dev, "failed to create sysfs group: %d\n", error);
++ return error;
++ }
++
++ error = devm_add_action(dev, rohm_ts_remove_sysfs_group, dev);
++ if (error) {
++ rohm_ts_remove_sysfs_group(dev);
++ dev_err(&client->dev,
++ "Failed to add sysfs cleanup action: %d\n",
++ error);
++ return error;
++ }
++
++ return error;
++}
++
++static const struct i2c_device_id rohm_bu21023_i2c_id[] = {
++ { BU21023_NAME, 0 },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(i2c, rohm_bu21023_i2c_id);
++
++static struct i2c_driver rohm_bu21023_i2c_driver = {
++ .driver = {
++ .name = BU21023_NAME,
++ },
++ .probe = rohm_bu21023_i2c_probe,
++ .id_table = rohm_bu21023_i2c_id,
++};
++module_i2c_driver(rohm_bu21023_i2c_driver);
++
++MODULE_DESCRIPTION("ROHM BU21023/24 Touchscreen driver");
++MODULE_LICENSE("GPL v2");
++MODULE_AUTHOR("ROHM Co., Ltd.");
diff --git a/series b/series
index a9dedde6b29d94..2cff7f0760032c 100644
--- a/series
+++ b/series
@@ -18,15 +18,6 @@ patches.ltsi/ltsi-makefile-addition.patch
#############################################################################
-# ktap
-#
-# 0.4 version of ktap, taken from the upstream:
-# https://github.com/ktap/ktap.git
-# repo.
-#
-#patches.ktap/ktap-0.4.patch
-
-#############################################################################
# Renesas patches
#
patches.renesas/0001-ARM-shmobile-r8a73a4-Add-IRQC-clock-to-device-tree.patch
@@ -413,13 +404,22 @@ patches.altera/0004-fpga-manager-add-driver-for-socfpga-fpga-manager.patch
patches.altera/0005-MAINTAINERS-add-fpga-manager-framework.patch
patches.altera/0006-ARM-socfpga_defconfig-enable-fpga-manager.patch
patches.altera/0007-ARM-socfpga-dts-add-fpga-manager.patch
-
+patches.altera/0001-nios2-Export-get_cycles.patch
+patches.altera/0002-nios2-check-number-of-timer-instances.patch
+patches.altera/0003-nios2-time-Migrate-to-new-set-state-interface.patch
+patches.altera/0004-nios2-fixed-variable-imm16-to-s16.patch
+patches.altera/0005-nios2-remove-unused-statistic-counters.patch
+patches.altera/0006-nios2-Add-Max10-device-tree.patch
+patches.altera/0007-nios2-add-Max10-defconfig.patch
+patches.altera/0008-nios2-Fix-unused-variable-warning.patch
+patches.altera/0009-nios2-Switch-to-generic-__xchg.patch
#############################################################################
-# fixes that go after all of the above
-#
-
-
+# Misc patches
+patches.misc/input-add-support-for-rohm-bu21023-24-touchscreen.patch
+##############################################################################
+# fixes that go after all of the above
+#