Linux v4.12.3
This commit is contained in:
parent
884e6796eb
commit
3ff7c261fb
|
@ -1,70 +0,0 @@
|
|||
From 92fe05e58babf15d7ddadfccd8bc383ea7e46e55 Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Wed, 5 Jul 2017 22:02:59 +0200
|
||||
Subject: [PATCH] ACPI / LPSS: Only call pwm_add_table for the first PWM
|
||||
controller
|
||||
|
||||
At least on the UP board SBC both PWMs are enabled leading to us
|
||||
trying to add the same pwm_lookup twice, which leads to the following:
|
||||
|
||||
[ 0.902224] list_add double add: new=ffffffffb8efd400,
|
||||
prev=ffffffffb8efd400, next=ffffffffb8eeede0.
|
||||
[ 0.912466] ------------[ cut here ]------------
|
||||
[ 0.917624] kernel BUG at lib/list_debug.c:31!
|
||||
[ 0.922588] invalid opcode: 0000 [#1] SMP
|
||||
...
|
||||
[ 1.027450] Call Trace:
|
||||
[ 1.030185] pwm_add_table+0x4c/0x90
|
||||
[ 1.034181] bsw_pwm_setup+0x1a/0x20
|
||||
[ 1.038175] acpi_lpss_create_device+0xfe/0x420
|
||||
...
|
||||
|
||||
This commit fixes this by only calling pwm_add_table for the first
|
||||
PWM controller (which is the one used for the backlight).
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1458599
|
||||
Fixes: bf7696a12071 ("acpi: lpss: call pwm_add_table() for BSW...")
|
||||
Fixes: 04434ab5120a ("ACPI / LPSS: Call pwm_add_table() for Bay Trail...")
|
||||
[labbott@redhat.com: Rebase to 4.11]
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
drivers/acpi/acpi_lpss.c | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
|
||||
index 5edfd9c..d973e56 100644
|
||||
--- a/drivers/acpi/acpi_lpss.c
|
||||
+++ b/drivers/acpi/acpi_lpss.c
|
||||
@@ -85,6 +85,7 @@ static const struct lpss_device_desc lpss_dma_desc = {
|
||||
};
|
||||
|
||||
struct lpss_private_data {
|
||||
+ struct acpi_device *adev;
|
||||
void __iomem *mmio_base;
|
||||
resource_size_t mmio_size;
|
||||
unsigned int fixed_clk_rate;
|
||||
@@ -164,6 +165,12 @@ static struct pwm_lookup bsw_pwm_lookup[] = {
|
||||
|
||||
static void bsw_pwm_setup(struct lpss_private_data *pdata)
|
||||
{
|
||||
+ struct acpi_device *adev = pdata->adev;
|
||||
+
|
||||
+ /* Only call pwm_add_table for the first PWM controller */
|
||||
+ if (!adev->pnp.unique_id || strcmp(adev->pnp.unique_id, "1"))
|
||||
+ return;
|
||||
+
|
||||
pwm_add_table(bsw_pwm_lookup, ARRAY_SIZE(bsw_pwm_lookup));
|
||||
}
|
||||
|
||||
@@ -439,6 +446,7 @@ static int acpi_lpss_create_device(struct acpi_device *adev,
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
+ pdata->adev = adev;
|
||||
pdata->dev_desc = dev_desc;
|
||||
|
||||
if (dev_desc->setup)
|
||||
--
|
||||
2.7.5
|
||||
|
|
@ -1,156 +0,0 @@
|
|||
From 9e0d87680d689f1758185851c3da6eafb16e71e1 Mon Sep 17 00:00:00 2001
|
||||
From: Trond Myklebust <trond.myklebust@primarydata.com>
|
||||
Date: Wed, 26 Apr 2017 11:55:26 -0400
|
||||
Subject: [PATCH] SUNRPC: Refactor svc_set_num_threads()
|
||||
|
||||
Refactor to separate out the functions of starting and stopping threads
|
||||
so that they can be used in other helpers.
|
||||
|
||||
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
|
||||
Tested-and-reviewed-by: Kinglong Mee <kinglongmee@gmail.com>
|
||||
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
|
||||
---
|
||||
net/sunrpc/svc.c | 96 ++++++++++++++++++++++++++++++++++----------------------
|
||||
1 file changed, 58 insertions(+), 38 deletions(-)
|
||||
|
||||
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
|
||||
index a08aeb5..98dc33a 100644
|
||||
--- a/net/sunrpc/svc.c
|
||||
+++ b/net/sunrpc/svc.c
|
||||
@@ -702,59 +702,32 @@ choose_victim(struct svc_serv *serv, struct svc_pool *pool, unsigned int *state)
|
||||
return task;
|
||||
}
|
||||
|
||||
-/*
|
||||
- * Create or destroy enough new threads to make the number
|
||||
- * of threads the given number. If `pool' is non-NULL, applies
|
||||
- * only to threads in that pool, otherwise round-robins between
|
||||
- * all pools. Caller must ensure that mutual exclusion between this and
|
||||
- * server startup or shutdown.
|
||||
- *
|
||||
- * Destroying threads relies on the service threads filling in
|
||||
- * rqstp->rq_task, which only the nfs ones do. Assumes the serv
|
||||
- * has been created using svc_create_pooled().
|
||||
- *
|
||||
- * Based on code that used to be in nfsd_svc() but tweaked
|
||||
- * to be pool-aware.
|
||||
- */
|
||||
-int
|
||||
-svc_set_num_threads(struct svc_serv *serv, struct svc_pool *pool, int nrservs)
|
||||
+/* create new threads */
|
||||
+static int
|
||||
+svc_start_kthreads(struct svc_serv *serv, struct svc_pool *pool, int nrservs)
|
||||
{
|
||||
struct svc_rqst *rqstp;
|
||||
struct task_struct *task;
|
||||
struct svc_pool *chosen_pool;
|
||||
- int error = 0;
|
||||
unsigned int state = serv->sv_nrthreads-1;
|
||||
int node;
|
||||
|
||||
- if (pool == NULL) {
|
||||
- /* The -1 assumes caller has done a svc_get() */
|
||||
- nrservs -= (serv->sv_nrthreads-1);
|
||||
- } else {
|
||||
- spin_lock_bh(&pool->sp_lock);
|
||||
- nrservs -= pool->sp_nrthreads;
|
||||
- spin_unlock_bh(&pool->sp_lock);
|
||||
- }
|
||||
-
|
||||
- /* create new threads */
|
||||
- while (nrservs > 0) {
|
||||
+ do {
|
||||
nrservs--;
|
||||
chosen_pool = choose_pool(serv, pool, &state);
|
||||
|
||||
node = svc_pool_map_get_node(chosen_pool->sp_id);
|
||||
rqstp = svc_prepare_thread(serv, chosen_pool, node);
|
||||
- if (IS_ERR(rqstp)) {
|
||||
- error = PTR_ERR(rqstp);
|
||||
- break;
|
||||
- }
|
||||
+ if (IS_ERR(rqstp))
|
||||
+ return PTR_ERR(rqstp);
|
||||
|
||||
__module_get(serv->sv_ops->svo_module);
|
||||
task = kthread_create_on_node(serv->sv_ops->svo_function, rqstp,
|
||||
node, "%s", serv->sv_name);
|
||||
if (IS_ERR(task)) {
|
||||
- error = PTR_ERR(task);
|
||||
module_put(serv->sv_ops->svo_module);
|
||||
svc_exit_thread(rqstp);
|
||||
- break;
|
||||
+ return PTR_ERR(task);
|
||||
}
|
||||
|
||||
rqstp->rq_task = task;
|
||||
@@ -763,15 +736,62 @@ svc_set_num_threads(struct svc_serv *serv, struct svc_pool *pool, int nrservs)
|
||||
|
||||
svc_sock_update_bufs(serv);
|
||||
wake_up_process(task);
|
||||
- }
|
||||
+ } while (nrservs > 0);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* destroy old threads */
|
||||
+static int
|
||||
+svc_signal_kthreads(struct svc_serv *serv, struct svc_pool *pool, int nrservs)
|
||||
+{
|
||||
+ struct task_struct *task;
|
||||
+ unsigned int state = serv->sv_nrthreads-1;
|
||||
+
|
||||
/* destroy old threads */
|
||||
- while (nrservs < 0 &&
|
||||
- (task = choose_victim(serv, pool, &state)) != NULL) {
|
||||
+ do {
|
||||
+ task = choose_victim(serv, pool, &state);
|
||||
+ if (task == NULL)
|
||||
+ break;
|
||||
send_sig(SIGINT, task, 1);
|
||||
nrservs++;
|
||||
+ } while (nrservs < 0);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Create or destroy enough new threads to make the number
|
||||
+ * of threads the given number. If `pool' is non-NULL, applies
|
||||
+ * only to threads in that pool, otherwise round-robins between
|
||||
+ * all pools. Caller must ensure that mutual exclusion between this and
|
||||
+ * server startup or shutdown.
|
||||
+ *
|
||||
+ * Destroying threads relies on the service threads filling in
|
||||
+ * rqstp->rq_task, which only the nfs ones do. Assumes the serv
|
||||
+ * has been created using svc_create_pooled().
|
||||
+ *
|
||||
+ * Based on code that used to be in nfsd_svc() but tweaked
|
||||
+ * to be pool-aware.
|
||||
+ */
|
||||
+int
|
||||
+svc_set_num_threads(struct svc_serv *serv, struct svc_pool *pool, int nrservs)
|
||||
+{
|
||||
+ if (pool == NULL) {
|
||||
+ /* The -1 assumes caller has done a svc_get() */
|
||||
+ nrservs -= (serv->sv_nrthreads-1);
|
||||
+ } else {
|
||||
+ spin_lock_bh(&pool->sp_lock);
|
||||
+ nrservs -= pool->sp_nrthreads;
|
||||
+ spin_unlock_bh(&pool->sp_lock);
|
||||
}
|
||||
|
||||
- return error;
|
||||
+ if (nrservs > 0)
|
||||
+ return svc_start_kthreads(serv, pool, nrservs);
|
||||
+ if (nrservs < 0)
|
||||
+ return svc_signal_kthreads(serv, pool, nrservs);
|
||||
+ return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(svc_set_num_threads);
|
||||
|
||||
--
|
||||
2.9.4
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
From 6399f1fae4ec29fab5ec76070435555e256ca3a6 Mon Sep 17 00:00:00 2001
|
||||
From: Sabrina Dubroca <sd@queasysnail.net>
|
||||
Date: Wed, 19 Jul 2017 22:28:55 +0200
|
||||
Subject: [PATCH] ipv6: avoid overflow of offset in ip6_find_1stfragopt
|
||||
|
||||
In some cases, offset can overflow and can cause an infinite loop in
|
||||
ip6_find_1stfragopt(). Make it unsigned int to prevent the overflow, and
|
||||
cap it at IPV6_MAXPLEN, since packets larger than that should be invalid.
|
||||
|
||||
This problem has been here since before the beginning of git history.
|
||||
|
||||
Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
|
||||
Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
net/ipv6/output_core.c | 8 ++++++--
|
||||
1 file changed, 6 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/net/ipv6/output_core.c b/net/ipv6/output_core.c
|
||||
index e9065b8..abb2c30 100644
|
||||
--- a/net/ipv6/output_core.c
|
||||
+++ b/net/ipv6/output_core.c
|
||||
@@ -78,7 +78,7 @@ EXPORT_SYMBOL(ipv6_select_ident);
|
||||
|
||||
int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
|
||||
{
|
||||
- u16 offset = sizeof(struct ipv6hdr);
|
||||
+ unsigned int offset = sizeof(struct ipv6hdr);
|
||||
unsigned int packet_len = skb_tail_pointer(skb) -
|
||||
skb_network_header(skb);
|
||||
int found_rhdr = 0;
|
||||
@@ -86,6 +86,7 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
|
||||
|
||||
while (offset <= packet_len) {
|
||||
struct ipv6_opt_hdr *exthdr;
|
||||
+ unsigned int len;
|
||||
|
||||
switch (**nexthdr) {
|
||||
|
||||
@@ -111,7 +112,10 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
|
||||
|
||||
exthdr = (struct ipv6_opt_hdr *)(skb_network_header(skb) +
|
||||
offset);
|
||||
- offset += ipv6_optlen(exthdr);
|
||||
+ len = ipv6_optlen(exthdr);
|
||||
+ if (len + offset >= IPV6_MAXPLEN)
|
||||
+ return -EINVAL;
|
||||
+ offset += len;
|
||||
*nexthdr = &exthdr->nexthdr;
|
||||
}
|
||||
|
||||
--
|
||||
2.9.4
|
||||
|
|
@ -0,0 +1,339 @@
|
|||
From 3bbfe49a1d965b951527cde0da48f5d7677db264 Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Sun, 21 May 2017 13:15:11 +0200
|
||||
Subject: [PATCH 01/16] platform/x86: Add driver for ACPI INT0002 Virtual GPIO
|
||||
device
|
||||
|
||||
Some peripherals on Bay Trail and Cherry Trail platforms signal a
|
||||
Power Management Event (PME) to the Power Management Controller (PMC)
|
||||
to wakeup the system. When this happens software needs to explicitly
|
||||
clear the PME bus 0 status bit in the GPE0a_STS register to avoid an
|
||||
IRQ storm on IRQ 9.
|
||||
|
||||
This is modelled in ACPI through the INT0002 ACPI device, which is
|
||||
called a "Virtual GPIO controller" in ACPI because it defines the
|
||||
event handler to call when the PME triggers through _AEI and _L02
|
||||
methods as would be done for a real GPIO interrupt in ACPI.
|
||||
|
||||
This commit adds a driver which registers the Virtual GPIOs expected
|
||||
by the DSDT on these devices, letting gpiolib-acpi claim the
|
||||
virtual GPIO and install a GPIO-interrupt handler which call the _L02
|
||||
handler as it would for a real GPIO controller.
|
||||
|
||||
Cc: joeyli <jlee@suse.com>
|
||||
Cc: Takashi Iwai <tiwai@suse.de>
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
||||
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
---
|
||||
Changes in v2:
|
||||
-Remove dev_err after malloc failure
|
||||
-Remove unused empty runtime pm callbacks
|
||||
-s/GPE0A_PME_/GPE0A_PME_B0_/
|
||||
-Fixed some checkpatch warnings (I forgot to run checkpatch on v1)
|
||||
|
||||
Changes in v3:
|
||||
-Rewrite as gpiochip driver letting gpiolib-acpi deal with claiming the pin
|
||||
0x0002 and calling the _L02 event handler when the virtual gpio-irq triggers
|
||||
-Rebase on 4.12-rc1
|
||||
|
||||
Changes in v4:
|
||||
-Drop device_init_wakeup() from _probe(), use pm_system_wakeup() instead
|
||||
of pm_wakeup_hard_event(chip->parent)
|
||||
-Improve commit message
|
||||
|
||||
Changes in v5:
|
||||
-Use BIT() macro for FOO_BIT defines
|
||||
-Drop unneeded ACPI_PTR macro usage
|
||||
|
||||
Changes in v6:
|
||||
-Move back to drivers/platform/x86
|
||||
-Expand certain acronyms (PME, PMC)
|
||||
-Use linux/gpio/driver.h include instead of linux/gpio.h
|
||||
-Document why the get / set / direction_output functions are dummys
|
||||
-No functional changes
|
||||
|
||||
Changes in v7:
|
||||
-Some minor cleanups from Andy:
|
||||
-Move asm/ includes below linux/ includes
|
||||
-s/APCI/ACPI/
|
||||
-Use bitmap_clear on chip->irq_valid_mask
|
||||
-Add Linus Walleij's Reviewed-by
|
||||
---
|
||||
drivers/platform/x86/Kconfig | 19 +++
|
||||
drivers/platform/x86/Makefile | 1 +
|
||||
drivers/platform/x86/intel_int0002_vgpio.c | 219 +++++++++++++++++++++++++++++
|
||||
3 files changed, 239 insertions(+)
|
||||
create mode 100644 drivers/platform/x86/intel_int0002_vgpio.c
|
||||
|
||||
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
|
||||
index 8489020ecf44..a3ccc3c795a5 100644
|
||||
--- a/drivers/platform/x86/Kconfig
|
||||
+++ b/drivers/platform/x86/Kconfig
|
||||
@@ -794,6 +794,25 @@ config INTEL_CHT_INT33FE
|
||||
This driver instantiates i2c-clients for these, so that standard
|
||||
i2c drivers for these chips can bind to the them.
|
||||
|
||||
+config INTEL_INT0002_VGPIO
|
||||
+ tristate "Intel ACPI INT0002 Virtual GPIO driver"
|
||||
+ depends on GPIOLIB && ACPI
|
||||
+ select GPIOLIB_IRQCHIP
|
||||
+ ---help---
|
||||
+ Some peripherals on Bay Trail and Cherry Trail platforms signal a
|
||||
+ Power Management Event (PME) to the Power Management Controller (PMC)
|
||||
+ to wakeup the system. When this happens software needs to explicitly
|
||||
+ clear the PME bus 0 status bit in the GPE0a_STS register to avoid an
|
||||
+ IRQ storm on IRQ 9.
|
||||
+
|
||||
+ This is modelled in ACPI through the INT0002 ACPI device, which is
|
||||
+ called a "Virtual GPIO controller" in ACPI because it defines the
|
||||
+ event handler to call when the PME triggers through _AEI and _L02
|
||||
+ methods as would be done for a real GPIO interrupt in ACPI.
|
||||
+
|
||||
+ To compile this driver as a module, choose M here: the module will
|
||||
+ be called intel_int0002_vgpio.
|
||||
+
|
||||
config INTEL_HID_EVENT
|
||||
tristate "INTEL HID Event"
|
||||
depends on ACPI
|
||||
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
|
||||
index 182a3ed6605a..ab22ce77fb66 100644
|
||||
--- a/drivers/platform/x86/Makefile
|
||||
+++ b/drivers/platform/x86/Makefile
|
||||
@@ -46,6 +46,7 @@ obj-$(CONFIG_TOSHIBA_BT_RFKILL) += toshiba_bluetooth.o
|
||||
obj-$(CONFIG_TOSHIBA_HAPS) += toshiba_haps.o
|
||||
obj-$(CONFIG_TOSHIBA_WMI) += toshiba-wmi.o
|
||||
obj-$(CONFIG_INTEL_CHT_INT33FE) += intel_cht_int33fe.o
|
||||
+obj-$(CONFIG_INTEL_INT0002_VGPIO) += intel_int0002_vgpio.o
|
||||
obj-$(CONFIG_INTEL_HID_EVENT) += intel-hid.o
|
||||
obj-$(CONFIG_INTEL_VBTN) += intel-vbtn.o
|
||||
obj-$(CONFIG_INTEL_SCU_IPC) += intel_scu_ipc.o
|
||||
diff --git a/drivers/platform/x86/intel_int0002_vgpio.c b/drivers/platform/x86/intel_int0002_vgpio.c
|
||||
new file mode 100644
|
||||
index 000000000000..92dc230ef5b2
|
||||
--- /dev/null
|
||||
+++ b/drivers/platform/x86/intel_int0002_vgpio.c
|
||||
@@ -0,0 +1,219 @@
|
||||
+/*
|
||||
+ * Intel INT0002 "Virtual GPIO" driver
|
||||
+ *
|
||||
+ * Copyright (C) 2017 Hans de Goede <hdegoede@redhat.com>
|
||||
+ *
|
||||
+ * Loosely based on android x86 kernel code which is:
|
||||
+ *
|
||||
+ * Copyright (c) 2014, Intel Corporation.
|
||||
+ *
|
||||
+ * Author: Dyut Kumar Sil <dyut.k.sil@intel.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * Some peripherals on Bay Trail and Cherry Trail platforms signal a Power
|
||||
+ * Management Event (PME) to the Power Management Controller (PMC) to wakeup
|
||||
+ * the system. When this happens software needs to clear the PME bus 0 status
|
||||
+ * bit in the GPE0a_STS register to avoid an IRQ storm on IRQ 9.
|
||||
+ *
|
||||
+ * This is modelled in ACPI through the INT0002 ACPI device, which is
|
||||
+ * called a "Virtual GPIO controller" in ACPI because it defines the event
|
||||
+ * handler to call when the PME triggers through _AEI and _L02 / _E02
|
||||
+ * methods as would be done for a real GPIO interrupt in ACPI. Note this
|
||||
+ * is a hack to define an AML event handler for the PME while using existing
|
||||
+ * ACPI mechanisms, this is not a real GPIO at all.
|
||||
+ *
|
||||
+ * This driver will bind to the INT0002 device, and register as a GPIO
|
||||
+ * controller, letting gpiolib-acpi.c call the _L02 handler as it would
|
||||
+ * for a real GPIO controller.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/acpi.h>
|
||||
+#include <linux/bitmap.h>
|
||||
+#include <linux/gpio/driver.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/suspend.h>
|
||||
+
|
||||
+#include <asm/cpu_device_id.h>
|
||||
+#include <asm/intel-family.h>
|
||||
+
|
||||
+#define DRV_NAME "INT0002 Virtual GPIO"
|
||||
+
|
||||
+/* For some reason the virtual GPIO pin tied to the GPE is numbered pin 2 */
|
||||
+#define GPE0A_PME_B0_VIRT_GPIO_PIN 2
|
||||
+
|
||||
+#define GPE0A_PME_B0_STS_BIT BIT(13)
|
||||
+#define GPE0A_PME_B0_EN_BIT BIT(13)
|
||||
+#define GPE0A_STS_PORT 0x420
|
||||
+#define GPE0A_EN_PORT 0x428
|
||||
+
|
||||
+#define ICPU(model) { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, }
|
||||
+
|
||||
+static const struct x86_cpu_id int0002_cpu_ids[] = {
|
||||
+/*
|
||||
+ * Limit ourselves to Cherry Trail for now, until testing shows we
|
||||
+ * need to handle the INT0002 device on Baytrail too.
|
||||
+ * ICPU(INTEL_FAM6_ATOM_SILVERMONT1), * Valleyview, Bay Trail *
|
||||
+ */
|
||||
+ ICPU(INTEL_FAM6_ATOM_AIRMONT), /* Braswell, Cherry Trail */
|
||||
+ {}
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * As this is not a real GPIO at all, but just a hack to model an event in
|
||||
+ * ACPI the get / set functions are dummy functions.
|
||||
+ */
|
||||
+
|
||||
+static int int0002_gpio_get(struct gpio_chip *chip, unsigned int offset)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void int0002_gpio_set(struct gpio_chip *chip, unsigned int offset,
|
||||
+ int value)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static int int0002_gpio_direction_output(struct gpio_chip *chip,
|
||||
+ unsigned int offset, int value)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void int0002_irq_ack(struct irq_data *data)
|
||||
+{
|
||||
+ outl(GPE0A_PME_B0_STS_BIT, GPE0A_STS_PORT);
|
||||
+}
|
||||
+
|
||||
+static void int0002_irq_unmask(struct irq_data *data)
|
||||
+{
|
||||
+ u32 gpe_en_reg;
|
||||
+
|
||||
+ gpe_en_reg = inl(GPE0A_EN_PORT);
|
||||
+ gpe_en_reg |= GPE0A_PME_B0_EN_BIT;
|
||||
+ outl(gpe_en_reg, GPE0A_EN_PORT);
|
||||
+}
|
||||
+
|
||||
+static void int0002_irq_mask(struct irq_data *data)
|
||||
+{
|
||||
+ u32 gpe_en_reg;
|
||||
+
|
||||
+ gpe_en_reg = inl(GPE0A_EN_PORT);
|
||||
+ gpe_en_reg &= ~GPE0A_PME_B0_EN_BIT;
|
||||
+ outl(gpe_en_reg, GPE0A_EN_PORT);
|
||||
+}
|
||||
+
|
||||
+static irqreturn_t int0002_irq(int irq, void *data)
|
||||
+{
|
||||
+ struct gpio_chip *chip = data;
|
||||
+ u32 gpe_sts_reg;
|
||||
+
|
||||
+ gpe_sts_reg = inl(GPE0A_STS_PORT);
|
||||
+ if (!(gpe_sts_reg & GPE0A_PME_B0_STS_BIT))
|
||||
+ return IRQ_NONE;
|
||||
+
|
||||
+ generic_handle_irq(irq_find_mapping(chip->irqdomain,
|
||||
+ GPE0A_PME_B0_VIRT_GPIO_PIN));
|
||||
+
|
||||
+ pm_system_wakeup();
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static struct irq_chip int0002_irqchip = {
|
||||
+ .name = DRV_NAME,
|
||||
+ .irq_ack = int0002_irq_ack,
|
||||
+ .irq_mask = int0002_irq_mask,
|
||||
+ .irq_unmask = int0002_irq_unmask,
|
||||
+};
|
||||
+
|
||||
+static int int0002_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct device *dev = &pdev->dev;
|
||||
+ const struct x86_cpu_id *cpu_id;
|
||||
+ struct gpio_chip *chip;
|
||||
+ int irq, ret;
|
||||
+
|
||||
+ /* Menlow has a different INT0002 device? <sigh> */
|
||||
+ cpu_id = x86_match_cpu(int0002_cpu_ids);
|
||||
+ if (!cpu_id)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ irq = platform_get_irq(pdev, 0);
|
||||
+ if (irq < 0) {
|
||||
+ dev_err(dev, "Error getting IRQ: %d\n", irq);
|
||||
+ return irq;
|
||||
+ }
|
||||
+
|
||||
+ chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
|
||||
+ if (!chip)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ chip->label = DRV_NAME;
|
||||
+ chip->parent = dev;
|
||||
+ chip->owner = THIS_MODULE;
|
||||
+ chip->get = int0002_gpio_get;
|
||||
+ chip->set = int0002_gpio_set;
|
||||
+ chip->direction_input = int0002_gpio_get;
|
||||
+ chip->direction_output = int0002_gpio_direction_output;
|
||||
+ chip->base = -1;
|
||||
+ chip->ngpio = GPE0A_PME_B0_VIRT_GPIO_PIN + 1;
|
||||
+ chip->irq_need_valid_mask = true;
|
||||
+
|
||||
+ ret = devm_gpiochip_add_data(&pdev->dev, chip, NULL);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "Error adding gpio chip: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ bitmap_clear(chip->irq_valid_mask, 0, GPE0A_PME_B0_VIRT_GPIO_PIN);
|
||||
+
|
||||
+ /*
|
||||
+ * We manually request the irq here instead of passing a flow-handler
|
||||
+ * to gpiochip_set_chained_irqchip, because the irq is shared.
|
||||
+ */
|
||||
+ ret = devm_request_irq(dev, irq, int0002_irq,
|
||||
+ IRQF_SHARED | IRQF_NO_THREAD, "INT0002", chip);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "Error requesting IRQ %d: %d\n", irq, ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = gpiochip_irqchip_add(chip, &int0002_irqchip, 0, handle_edge_irq,
|
||||
+ IRQ_TYPE_NONE);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "Error adding irqchip: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ gpiochip_set_chained_irqchip(chip, &int0002_irqchip, irq, NULL);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct acpi_device_id int0002_acpi_ids[] = {
|
||||
+ { "INT0002", 0 },
|
||||
+ { },
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(acpi, int0002_acpi_ids);
|
||||
+
|
||||
+static struct platform_driver int0002_driver = {
|
||||
+ .driver = {
|
||||
+ .name = DRV_NAME,
|
||||
+ .acpi_match_table = int0002_acpi_ids,
|
||||
+ },
|
||||
+ .probe = int0002_probe,
|
||||
+};
|
||||
+
|
||||
+module_platform_driver(int0002_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
|
||||
+MODULE_DESCRIPTION("Intel INT0002 Virtual GPIO driver");
|
||||
+MODULE_LICENSE("GPL");
|
||||
--
|
||||
2.13.0
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
From 6bb84c0f9da1144e0d443798a76d5769b7d554af Mon Sep 17 00:00:00 2001
|
||||
From: Christian Kellner <christian@kellner.me>
|
||||
Date: Tue, 28 Feb 2017 17:10:56 +0100
|
||||
Subject: [PATCH 1/2] platform/x86: thinkpad_acpi: guard generic hotkey case
|
||||
|
||||
Currently when dispatching hotkeys we check if the scancode is in
|
||||
the range of 0 and TPACPI_HOTKEY_MAP_LEN, although the bottom 20
|
||||
entries in the hotkey keymap are already adaptive keycodes.
|
||||
Therefore we introduce a TP_ACPI_HOTKEYSCAN_ADAPTIVE_START and
|
||||
ensure that we are in the range 0 and ADAPTIVE_START for the generic
|
||||
keycode case.
|
||||
|
||||
Signed-off-by: Christian Kellner <ckellner@redhat.com>
|
||||
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
|
||||
Acked-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
|
||||
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
---
|
||||
drivers/platform/x86/thinkpad_acpi.c | 12 +++++++-----
|
||||
1 file changed, 7 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
|
||||
index 1d18b32..e2b962f 100644
|
||||
--- a/drivers/platform/x86/thinkpad_acpi.c
|
||||
+++ b/drivers/platform/x86/thinkpad_acpi.c
|
||||
@@ -1922,7 +1922,9 @@ enum { /* hot key scan codes (derived from ACPI DSDT) */
|
||||
TP_ACPI_HOTKEYSCAN_UNK7,
|
||||
TP_ACPI_HOTKEYSCAN_UNK8,
|
||||
|
||||
- TP_ACPI_HOTKEYSCAN_MUTE2,
|
||||
+ /* Adaptive keyboard keycodes */
|
||||
+ TP_ACPI_HOTKEYSCAN_ADAPTIVE_START,
|
||||
+ TP_ACPI_HOTKEYSCAN_MUTE2 = TP_ACPI_HOTKEYSCAN_ADAPTIVE_START,
|
||||
TP_ACPI_HOTKEYSCAN_BRIGHTNESS_ZERO,
|
||||
TP_ACPI_HOTKEYSCAN_CLIPPING_TOOL,
|
||||
TP_ACPI_HOTKEYSCAN_CLOUD,
|
||||
@@ -3656,7 +3658,6 @@ static const int adaptive_keyboard_modes[] = {
|
||||
#define DFR_CHANGE_ROW 0x101
|
||||
#define DFR_SHOW_QUICKVIEW_ROW 0x102
|
||||
#define FIRST_ADAPTIVE_KEY 0x103
|
||||
-#define ADAPTIVE_KEY_OFFSET 0x020
|
||||
|
||||
/* press Fn key a while second, it will switch to Function Mode. Then
|
||||
* release Fn key, previous mode be restored.
|
||||
@@ -3747,12 +3748,13 @@ static bool adaptive_keyboard_hotkey_notify_hotkey(unsigned int scancode)
|
||||
default:
|
||||
if (scancode < FIRST_ADAPTIVE_KEY ||
|
||||
scancode >= FIRST_ADAPTIVE_KEY + TPACPI_HOTKEY_MAP_LEN -
|
||||
- ADAPTIVE_KEY_OFFSET) {
|
||||
+ TP_ACPI_HOTKEYSCAN_ADAPTIVE_START) {
|
||||
pr_info("Unhandled adaptive keyboard key: 0x%x\n",
|
||||
scancode);
|
||||
return false;
|
||||
}
|
||||
- keycode = hotkey_keycode_map[scancode - FIRST_ADAPTIVE_KEY + ADAPTIVE_KEY_OFFSET];
|
||||
+ keycode = hotkey_keycode_map[scancode - FIRST_ADAPTIVE_KEY +
|
||||
+ TP_ACPI_HOTKEYSCAN_ADAPTIVE_START];
|
||||
if (keycode != KEY_RESERVED) {
|
||||
mutex_lock(&tpacpi_inputdev_send_mutex);
|
||||
|
||||
@@ -3778,7 +3780,7 @@ static bool hotkey_notify_hotkey(const u32 hkey,
|
||||
*ignore_acpi_ev = false;
|
||||
|
||||
/* HKEY event 0x1001 is scancode 0x00 */
|
||||
- if (scancode > 0 && scancode <= TPACPI_HOTKEY_MAP_LEN) {
|
||||
+ if (scancode > 0 && scancode <= TP_ACPI_HOTKEYSCAN_ADAPTIVE_START) {
|
||||
scancode--;
|
||||
if (!(hotkey_source_mask & (1 << scancode))) {
|
||||
tpacpi_input_send_key_masked(scancode);
|
||||
--
|
||||
2.9.4
|
||||
|
|
@ -1,155 +0,0 @@
|
|||
From ed6473ddc704a2005b9900ca08e236ebb2d8540a Mon Sep 17 00:00:00 2001
|
||||
From: Trond Myklebust <trond.myklebust@primarydata.com>
|
||||
Date: Wed, 26 Apr 2017 11:55:27 -0400
|
||||
Subject: [PATCH] NFSv4: Fix callback server shutdown
|
||||
|
||||
We want to use kthread_stop() in order to ensure the threads are
|
||||
shut down before we tear down the nfs_callback_info in nfs_callback_down.
|
||||
|
||||
Tested-and-reviewed-by: Kinglong Mee <kinglongmee@gmail.com>
|
||||
Reported-by: Kinglong Mee <kinglongmee@gmail.com>
|
||||
Fixes: bb6aeba736ba9 ("NFSv4.x: Switch to using svc_set_num_threads()...")
|
||||
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
|
||||
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
|
||||
---
|
||||
fs/nfs/callback.c | 24 ++++++++++++++++--------
|
||||
include/linux/sunrpc/svc.h | 1 +
|
||||
net/sunrpc/svc.c | 38 ++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 55 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
|
||||
index c5e27eb..73a1f92 100644
|
||||
--- a/fs/nfs/callback.c
|
||||
+++ b/fs/nfs/callback.c
|
||||
@@ -76,7 +76,10 @@ nfs4_callback_svc(void *vrqstp)
|
||||
|
||||
set_freezable();
|
||||
|
||||
- while (!kthread_should_stop()) {
|
||||
+ while (!kthread_freezable_should_stop(NULL)) {
|
||||
+
|
||||
+ if (signal_pending(current))
|
||||
+ flush_signals(current);
|
||||
/*
|
||||
* Listen for a request on the socket
|
||||
*/
|
||||
@@ -85,6 +88,8 @@ nfs4_callback_svc(void *vrqstp)
|
||||
continue;
|
||||
svc_process(rqstp);
|
||||
}
|
||||
+ svc_exit_thread(rqstp);
|
||||
+ module_put_and_exit(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -103,9 +108,10 @@ nfs41_callback_svc(void *vrqstp)
|
||||
|
||||
set_freezable();
|
||||
|
||||
- while (!kthread_should_stop()) {
|
||||
- if (try_to_freeze())
|
||||
- continue;
|
||||
+ while (!kthread_freezable_should_stop(NULL)) {
|
||||
+
|
||||
+ if (signal_pending(current))
|
||||
+ flush_signals(current);
|
||||
|
||||
prepare_to_wait(&serv->sv_cb_waitq, &wq, TASK_INTERRUPTIBLE);
|
||||
spin_lock_bh(&serv->sv_cb_lock);
|
||||
@@ -121,11 +127,13 @@ nfs41_callback_svc(void *vrqstp)
|
||||
error);
|
||||
} else {
|
||||
spin_unlock_bh(&serv->sv_cb_lock);
|
||||
- schedule();
|
||||
+ if (!kthread_should_stop())
|
||||
+ schedule();
|
||||
finish_wait(&serv->sv_cb_waitq, &wq);
|
||||
}
|
||||
- flush_signals(current);
|
||||
}
|
||||
+ svc_exit_thread(rqstp);
|
||||
+ module_put_and_exit(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -221,14 +229,14 @@ static int nfs_callback_up_net(int minorversion, struct svc_serv *serv,
|
||||
static struct svc_serv_ops nfs40_cb_sv_ops = {
|
||||
.svo_function = nfs4_callback_svc,
|
||||
.svo_enqueue_xprt = svc_xprt_do_enqueue,
|
||||
- .svo_setup = svc_set_num_threads,
|
||||
+ .svo_setup = svc_set_num_threads_sync,
|
||||
.svo_module = THIS_MODULE,
|
||||
};
|
||||
#if defined(CONFIG_NFS_V4_1)
|
||||
static struct svc_serv_ops nfs41_cb_sv_ops = {
|
||||
.svo_function = nfs41_callback_svc,
|
||||
.svo_enqueue_xprt = svc_xprt_do_enqueue,
|
||||
- .svo_setup = svc_set_num_threads,
|
||||
+ .svo_setup = svc_set_num_threads_sync,
|
||||
.svo_module = THIS_MODULE,
|
||||
};
|
||||
|
||||
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
|
||||
index 6ef19cf..9463102 100644
|
||||
--- a/include/linux/sunrpc/svc.h
|
||||
+++ b/include/linux/sunrpc/svc.h
|
||||
@@ -473,6 +473,7 @@ void svc_pool_map_put(void);
|
||||
struct svc_serv * svc_create_pooled(struct svc_program *, unsigned int,
|
||||
struct svc_serv_ops *);
|
||||
int svc_set_num_threads(struct svc_serv *, struct svc_pool *, int);
|
||||
+int svc_set_num_threads_sync(struct svc_serv *, struct svc_pool *, int);
|
||||
int svc_pool_stats_open(struct svc_serv *serv, struct file *file);
|
||||
void svc_destroy(struct svc_serv *);
|
||||
void svc_shutdown_net(struct svc_serv *, struct net *);
|
||||
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
|
||||
index 98dc33a..bc0f5a0 100644
|
||||
--- a/net/sunrpc/svc.c
|
||||
+++ b/net/sunrpc/svc.c
|
||||
@@ -795,6 +795,44 @@ svc_set_num_threads(struct svc_serv *serv, struct svc_pool *pool, int nrservs)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(svc_set_num_threads);
|
||||
|
||||
+/* destroy old threads */
|
||||
+static int
|
||||
+svc_stop_kthreads(struct svc_serv *serv, struct svc_pool *pool, int nrservs)
|
||||
+{
|
||||
+ struct task_struct *task;
|
||||
+ unsigned int state = serv->sv_nrthreads-1;
|
||||
+
|
||||
+ /* destroy old threads */
|
||||
+ do {
|
||||
+ task = choose_victim(serv, pool, &state);
|
||||
+ if (task == NULL)
|
||||
+ break;
|
||||
+ kthread_stop(task);
|
||||
+ nrservs++;
|
||||
+ } while (nrservs < 0);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+svc_set_num_threads_sync(struct svc_serv *serv, struct svc_pool *pool, int nrservs)
|
||||
+{
|
||||
+ if (pool == NULL) {
|
||||
+ /* The -1 assumes caller has done a svc_get() */
|
||||
+ nrservs -= (serv->sv_nrthreads-1);
|
||||
+ } else {
|
||||
+ spin_lock_bh(&pool->sp_lock);
|
||||
+ nrservs -= pool->sp_nrthreads;
|
||||
+ spin_unlock_bh(&pool->sp_lock);
|
||||
+ }
|
||||
+
|
||||
+ if (nrservs > 0)
|
||||
+ return svc_start_kthreads(serv, pool, nrservs);
|
||||
+ if (nrservs < 0)
|
||||
+ return svc_stop_kthreads(serv, pool, nrservs);
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(svc_set_num_threads_sync);
|
||||
+
|
||||
/*
|
||||
* Called from a server thread as it's exiting. Caller must hold the "service
|
||||
* mutex" for the service.
|
||||
--
|
||||
2.9.4
|
||||
|
|
@ -0,0 +1,355 @@
|
|||
From c0f9254fdd0703ade018b2ff3a8cca433f781a11 Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Sun, 26 Feb 2017 21:07:29 +0100
|
||||
Subject: [PATCH 02/16] mfd: Add Cherry Trail Whiskey Cove PMIC driver
|
||||
|
||||
Add mfd driver for Intel CHT Whiskey Cove PMIC, based on various non
|
||||
upstreamed CHT Whiskey Cove PMIC patches.
|
||||
|
||||
This is a somewhat minimal version which adds irqchip support and cells
|
||||
for: ACPI PMIC opregion support, the i2c-controller driving the external
|
||||
charger irc and the pwrsrc/extcon block.
|
||||
|
||||
Further cells can be added in the future if/when drivers are upstreamed
|
||||
for them.
|
||||
|
||||
Cc: Bin Gao <bin.gao@intel.com>
|
||||
Cc: Felipe Balbi <felipe.balbi@linux.intel.com>
|
||||
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
---
|
||||
Changes in v2:
|
||||
-Since this uses plain mfd and not the intel_soc_pmic stuff give it
|
||||
its own Kconfig and allow this to be built as a module
|
||||
-Add missing #include <acpi/acpi_bus.h>
|
||||
|
||||
Changes in v3:
|
||||
-Drop #include <acpi/acpi_bus.h> again, not the right fix for the build errors
|
||||
-Error out when the upper byte of the register-address passed to the regmap
|
||||
functions is 0 rather then hardcoding an address in that case
|
||||
-Various minor style tweaks / cleanups
|
||||
-Move defines of regulator register addresses to intel_pmic_chtwc.c,
|
||||
it is the only place where they are used
|
||||
-Drop now empty include/linux/mfd/intel_chtwc.h
|
||||
-Rename intel_soc_pmic_chtwc.c to intel_cht_wc.c to match Kconfig option name
|
||||
-Add irqchip support
|
||||
-Add external charger cell
|
||||
-Add pwrsrc cell
|
||||
|
||||
Changes in v4:
|
||||
-Use PLATFORM_DEVID_NONE
|
||||
|
||||
Changes in v5:
|
||||
-Change Kconfig option from tristate to boolean and add a select for the
|
||||
i2c-bus driver, this is necessary because the chtwc PMIC provides an ACPI
|
||||
OPRegion handler, which must be available before other drivers using it
|
||||
are loaded, which can only be ensured if the mfd, opregion and i2c-bus
|
||||
drivers are built in. This fixes errors like these during boot:
|
||||
mmc0: SDHCI controller on ACPI [80860F14:00] using ADMA
|
||||
ACPI Error: No handler for Region [REGS] (ffff93543b0cc3a8) [UserDefinedRegion] (20170119/evregion-166)
|
||||
ACPI Error: Region UserDefinedRegion (ID=143) has no handler (20170119/exfldio-299)
|
||||
ACPI Error: Method parse/execution failed [\_SB.PCI0.I2C7.PMI5.GET] (Node ffff93543b0cde10), AE_NOT_EXIST (20170119/psparse-543)
|
||||
ACPI Error: Method parse/execution failed [\_SB.PCI0.SHC1._PS0] (Node ffff93543b0b5cd0), AE_NOT_EXIST (20170119/psparse-543)
|
||||
acpi 80860F14:02: Failed to change power state to D0
|
||||
-Some minor style and capitalization fixes from review by Lee Jones
|
||||
|
||||
Changes in v6:
|
||||
-Fix Kconfig depends and selects to fix warning reported by kbuild test robot
|
||||
|
||||
Changes in v7:
|
||||
-Add explanation why this is a bool and why it selects i2c-designwaree
|
||||
to the help text rather then as comments in the Kconfig
|
||||
|
||||
Changes in v8:
|
||||
-Remove MODULE macros, etc. now that this driver is a bool in Kconfig
|
||||
|
||||
Changes in v9:
|
||||
-Some whitespace tweaks
|
||||
-Return -EINVAL from probe on invalid irq
|
||||
-Use probe_new i2c_driver callback
|
||||
---
|
||||
drivers/mfd/Kconfig | 16 +++
|
||||
drivers/mfd/Makefile | 1 +
|
||||
drivers/mfd/intel_soc_pmic_chtwc.c | 230 +++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 247 insertions(+)
|
||||
create mode 100644 drivers/mfd/intel_soc_pmic_chtwc.c
|
||||
|
||||
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
|
||||
index 3eb5c93595f6..5203a86b8f6c 100644
|
||||
--- a/drivers/mfd/Kconfig
|
||||
+++ b/drivers/mfd/Kconfig
|
||||
@@ -470,6 +470,22 @@ config INTEL_SOC_PMIC_BXTWC
|
||||
thermal, charger and related power management functions
|
||||
on these systems.
|
||||
|
||||
+config INTEL_SOC_PMIC_CHTWC
|
||||
+ bool "Support for Intel Cherry Trail Whiskey Cove PMIC"
|
||||
+ depends on ACPI && HAS_IOMEM && I2C=y && COMMON_CLK
|
||||
+ depends on X86 || COMPILE_TEST
|
||||
+ select MFD_CORE
|
||||
+ select REGMAP_I2C
|
||||
+ select REGMAP_IRQ
|
||||
+ select I2C_DESIGNWARE_PLATFORM
|
||||
+ help
|
||||
+ Select this option to enable support for the Intel Cherry Trail
|
||||
+ Whiskey Cove PMIC found on some Intel Cherry Trail systems.
|
||||
+
|
||||
+ This option is a bool as it provides an ACPI OpRegion which must be
|
||||
+ available before any devices using it are probed. This option also
|
||||
+ causes the designware-i2c driver to be builtin for the same reason.
|
||||
+
|
||||
config MFD_INTEL_LPSS
|
||||
tristate
|
||||
select COMMON_CLK
|
||||
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
|
||||
index c16bf1ea0ea9..6f6aed8cfccc 100644
|
||||
--- a/drivers/mfd/Makefile
|
||||
+++ b/drivers/mfd/Makefile
|
||||
@@ -214,6 +214,7 @@ obj-$(CONFIG_MFD_SKY81452) += sky81452.o
|
||||
intel-soc-pmic-objs := intel_soc_pmic_core.o intel_soc_pmic_crc.o
|
||||
obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o
|
||||
obj-$(CONFIG_INTEL_SOC_PMIC_BXTWC) += intel_soc_pmic_bxtwc.o
|
||||
+obj-$(CONFIG_INTEL_SOC_PMIC_CHTWC) += intel_soc_pmic_chtwc.o
|
||||
obj-$(CONFIG_MFD_MT6397) += mt6397-core.o
|
||||
|
||||
obj-$(CONFIG_MFD_ALTERA_A10SR) += altera-a10sr.o
|
||||
diff --git a/drivers/mfd/intel_soc_pmic_chtwc.c b/drivers/mfd/intel_soc_pmic_chtwc.c
|
||||
new file mode 100644
|
||||
index 000000000000..b35da01d5bcf
|
||||
--- /dev/null
|
||||
+++ b/drivers/mfd/intel_soc_pmic_chtwc.c
|
||||
@@ -0,0 +1,230 @@
|
||||
+/*
|
||||
+ * MFD core driver for Intel Cherrytrail Whiskey Cove PMIC
|
||||
+ *
|
||||
+ * Copyright (C) 2017 Hans de Goede <hdegoede@redhat.com>
|
||||
+ *
|
||||
+ * Based on various non upstream patches to support the CHT Whiskey Cove PMIC:
|
||||
+ * Copyright (C) 2013-2015 Intel Corporation. All rights reserved.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/acpi.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/i2c.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/mfd/core.h>
|
||||
+#include <linux/mfd/intel_soc_pmic.h>
|
||||
+#include <linux/regmap.h>
|
||||
+
|
||||
+/* PMIC device registers */
|
||||
+#define REG_OFFSET_MASK GENMASK(7, 0)
|
||||
+#define REG_ADDR_MASK GENMASK(15, 8)
|
||||
+#define REG_ADDR_SHIFT 8
|
||||
+
|
||||
+#define CHT_WC_IRQLVL1 0x6e02
|
||||
+#define CHT_WC_IRQLVL1_MASK 0x6e0e
|
||||
+
|
||||
+/* Whiskey Cove PMIC share same ACPI ID between different platforms */
|
||||
+#define CHT_WC_HRV 3
|
||||
+
|
||||
+/* Level 1 IRQs (level 2 IRQs are handled in the child device drivers) */
|
||||
+enum {
|
||||
+ CHT_WC_PWRSRC_IRQ = 0,
|
||||
+ CHT_WC_THRM_IRQ,
|
||||
+ CHT_WC_BCU_IRQ,
|
||||
+ CHT_WC_ADC_IRQ,
|
||||
+ CHT_WC_EXT_CHGR_IRQ,
|
||||
+ CHT_WC_GPIO_IRQ,
|
||||
+ /* There is no irq 6 */
|
||||
+ CHT_WC_CRIT_IRQ = 7,
|
||||
+};
|
||||
+
|
||||
+static struct resource cht_wc_pwrsrc_resources[] = {
|
||||
+ DEFINE_RES_IRQ(CHT_WC_PWRSRC_IRQ),
|
||||
+};
|
||||
+
|
||||
+static struct resource cht_wc_ext_charger_resources[] = {
|
||||
+ DEFINE_RES_IRQ(CHT_WC_EXT_CHGR_IRQ),
|
||||
+};
|
||||
+
|
||||
+static struct mfd_cell cht_wc_dev[] = {
|
||||
+ {
|
||||
+ .name = "cht_wcove_pwrsrc",
|
||||
+ .num_resources = ARRAY_SIZE(cht_wc_pwrsrc_resources),
|
||||
+ .resources = cht_wc_pwrsrc_resources,
|
||||
+ }, {
|
||||
+ .name = "cht_wcove_ext_chgr",
|
||||
+ .num_resources = ARRAY_SIZE(cht_wc_ext_charger_resources),
|
||||
+ .resources = cht_wc_ext_charger_resources,
|
||||
+ },
|
||||
+ { .name = "cht_wcove_region", },
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * The CHT Whiskey Cove covers multiple I2C addresses, with a 1 Byte
|
||||
+ * register address space per I2C address, so we use 16 bit register
|
||||
+ * addresses where the high 8 bits contain the I2C client address.
|
||||
+ */
|
||||
+static int cht_wc_byte_reg_read(void *context, unsigned int reg,
|
||||
+ unsigned int *val)
|
||||
+{
|
||||
+ struct i2c_client *client = context;
|
||||
+ int ret, orig_addr = client->addr;
|
||||
+
|
||||
+ if (!(reg & REG_ADDR_MASK)) {
|
||||
+ dev_err(&client->dev, "Error I2C address not specified\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ client->addr = (reg & REG_ADDR_MASK) >> REG_ADDR_SHIFT;
|
||||
+ ret = i2c_smbus_read_byte_data(client, reg & REG_OFFSET_MASK);
|
||||
+ client->addr = orig_addr;
|
||||
+
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ *val = ret;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int cht_wc_byte_reg_write(void *context, unsigned int reg,
|
||||
+ unsigned int val)
|
||||
+{
|
||||
+ struct i2c_client *client = context;
|
||||
+ int ret, orig_addr = client->addr;
|
||||
+
|
||||
+ if (!(reg & REG_ADDR_MASK)) {
|
||||
+ dev_err(&client->dev, "Error I2C address not specified\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ client->addr = (reg & REG_ADDR_MASK) >> REG_ADDR_SHIFT;
|
||||
+ ret = i2c_smbus_write_byte_data(client, reg & REG_OFFSET_MASK, val);
|
||||
+ client->addr = orig_addr;
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static const struct regmap_config cht_wc_regmap_cfg = {
|
||||
+ .reg_bits = 16,
|
||||
+ .val_bits = 8,
|
||||
+ .reg_write = cht_wc_byte_reg_write,
|
||||
+ .reg_read = cht_wc_byte_reg_read,
|
||||
+};
|
||||
+
|
||||
+static const struct regmap_irq cht_wc_regmap_irqs[] = {
|
||||
+ REGMAP_IRQ_REG(CHT_WC_PWRSRC_IRQ, 0, BIT(CHT_WC_PWRSRC_IRQ)),
|
||||
+ REGMAP_IRQ_REG(CHT_WC_THRM_IRQ, 0, BIT(CHT_WC_THRM_IRQ)),
|
||||
+ REGMAP_IRQ_REG(CHT_WC_BCU_IRQ, 0, BIT(CHT_WC_BCU_IRQ)),
|
||||
+ REGMAP_IRQ_REG(CHT_WC_ADC_IRQ, 0, BIT(CHT_WC_ADC_IRQ)),
|
||||
+ REGMAP_IRQ_REG(CHT_WC_EXT_CHGR_IRQ, 0, BIT(CHT_WC_EXT_CHGR_IRQ)),
|
||||
+ REGMAP_IRQ_REG(CHT_WC_GPIO_IRQ, 0, BIT(CHT_WC_GPIO_IRQ)),
|
||||
+ REGMAP_IRQ_REG(CHT_WC_CRIT_IRQ, 0, BIT(CHT_WC_CRIT_IRQ)),
|
||||
+};
|
||||
+
|
||||
+static const struct regmap_irq_chip cht_wc_regmap_irq_chip = {
|
||||
+ .name = "cht_wc_irq_chip",
|
||||
+ .status_base = CHT_WC_IRQLVL1,
|
||||
+ .mask_base = CHT_WC_IRQLVL1_MASK,
|
||||
+ .irqs = cht_wc_regmap_irqs,
|
||||
+ .num_irqs = ARRAY_SIZE(cht_wc_regmap_irqs),
|
||||
+ .num_regs = 1,
|
||||
+};
|
||||
+
|
||||
+static int cht_wc_probe(struct i2c_client *client)
|
||||
+{
|
||||
+ struct device *dev = &client->dev;
|
||||
+ struct intel_soc_pmic *pmic;
|
||||
+ acpi_status status;
|
||||
+ unsigned long long hrv;
|
||||
+ int ret;
|
||||
+
|
||||
+ status = acpi_evaluate_integer(ACPI_HANDLE(dev), "_HRV", NULL, &hrv);
|
||||
+ if (ACPI_FAILURE(status)) {
|
||||
+ dev_err(dev, "Failed to get PMIC hardware revision\n");
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+ if (hrv != CHT_WC_HRV) {
|
||||
+ dev_err(dev, "Invalid PMIC hardware revision: %llu\n", hrv);
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+ if (client->irq < 0) {
|
||||
+ dev_err(dev, "Invalid IRQ\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL);
|
||||
+ if (!pmic)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ pmic->irq = client->irq;
|
||||
+ pmic->dev = dev;
|
||||
+ i2c_set_clientdata(client, pmic);
|
||||
+
|
||||
+ pmic->regmap = devm_regmap_init(dev, NULL, client, &cht_wc_regmap_cfg);
|
||||
+ if (IS_ERR(pmic->regmap))
|
||||
+ return PTR_ERR(pmic->regmap);
|
||||
+
|
||||
+ ret = devm_regmap_add_irq_chip(dev, pmic->regmap, pmic->irq,
|
||||
+ IRQF_ONESHOT | IRQF_SHARED, 0,
|
||||
+ &cht_wc_regmap_irq_chip,
|
||||
+ &pmic->irq_chip_data);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
|
||||
+ cht_wc_dev, ARRAY_SIZE(cht_wc_dev), NULL, 0,
|
||||
+ regmap_irq_get_domain(pmic->irq_chip_data));
|
||||
+}
|
||||
+
|
||||
+static void cht_wc_shutdown(struct i2c_client *client)
|
||||
+{
|
||||
+ struct intel_soc_pmic *pmic = i2c_get_clientdata(client);
|
||||
+
|
||||
+ disable_irq(pmic->irq);
|
||||
+}
|
||||
+
|
||||
+static int __maybe_unused cht_wc_suspend(struct device *dev)
|
||||
+{
|
||||
+ struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
|
||||
+
|
||||
+ disable_irq(pmic->irq);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int __maybe_unused cht_wc_resume(struct device *dev)
|
||||
+{
|
||||
+ struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
|
||||
+
|
||||
+ enable_irq(pmic->irq);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+static SIMPLE_DEV_PM_OPS(cht_wc_pm_ops, cht_wc_suspend, cht_wc_resume);
|
||||
+
|
||||
+static const struct i2c_device_id cht_wc_i2c_id[] = {
|
||||
+ { }
|
||||
+};
|
||||
+
|
||||
+static const struct acpi_device_id cht_wc_acpi_ids[] = {
|
||||
+ { "INT34D3", },
|
||||
+ { }
|
||||
+};
|
||||
+
|
||||
+static struct i2c_driver cht_wc_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "CHT Whiskey Cove PMIC",
|
||||
+ .pm = &cht_wc_pm_ops,
|
||||
+ .acpi_match_table = cht_wc_acpi_ids,
|
||||
+ },
|
||||
+ .probe_new = cht_wc_probe,
|
||||
+ .shutdown = cht_wc_shutdown,
|
||||
+ .id_table = cht_wc_i2c_id,
|
||||
+};
|
||||
+builtin_i2c_driver(cht_wc_driver);
|
||||
--
|
||||
2.13.0
|
||||
|
|
@ -1,158 +0,0 @@
|
|||
From 82e71b57b1b4347126b1ffd7b2beed2bc8b795bd Mon Sep 17 00:00:00 2001
|
||||
From: Christian Kellner <christian@kellner.me>
|
||||
Date: Tue, 28 Feb 2017 17:10:57 +0100
|
||||
Subject: [PATCH 2/2] platform/x86: thinkpad_acpi: add mapping for new hotkeys
|
||||
|
||||
The T470, X270 emits new hkey events in the 0x1311 - 0x1315 range.
|
||||
According to the user manual they should launch a user selected
|
||||
favorite application (star icon, 0x1311), snipping tool (0x1312,
|
||||
currently ignored), enable/disable bluetooth (0x1314) and open they
|
||||
keyboard settings (0x1315).
|
||||
|
||||
The third nibble (0xf00) is used to differentiate between the original
|
||||
hotkeys, the adaptive keyboard codes and the new, additional ones.
|
||||
|
||||
Signed-off-by: Christian Kellner <ckellner@redhat.com>
|
||||
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
|
||||
Acked-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
|
||||
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
---
|
||||
drivers/platform/x86/thinkpad_acpi.c | 91 +++++++++++++++++++++++++++++++-----
|
||||
1 file changed, 79 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
|
||||
index e2b962f..7b6cb0c 100644
|
||||
--- a/drivers/platform/x86/thinkpad_acpi.c
|
||||
+++ b/drivers/platform/x86/thinkpad_acpi.c
|
||||
@@ -1945,6 +1945,15 @@ enum { /* hot key scan codes (derived from ACPI DSDT) */
|
||||
TP_ACPI_HOTKEYSCAN_CAMERA_MODE,
|
||||
TP_ACPI_HOTKEYSCAN_ROTATE_DISPLAY,
|
||||
|
||||
+ /* Lenovo extended keymap, starting at 0x1300 */
|
||||
+ TP_ACPI_HOTKEYSCAN_EXTENDED_START,
|
||||
+ /* first new observed key (star, favorites) is 0x1311 */
|
||||
+ TP_ACPI_HOTKEYSCAN_STAR = 69,
|
||||
+ TP_ACPI_HOTKEYSCAN_CLIPPING_TOOL2,
|
||||
+ TP_ACPI_HOTKEYSCAN_UNK25,
|
||||
+ TP_ACPI_HOTKEYSCAN_BLUETOOTH,
|
||||
+ TP_ACPI_HOTKEYSCAN_KEYBOARD,
|
||||
+
|
||||
/* Hotkey keymap size */
|
||||
TPACPI_HOTKEY_MAP_LEN
|
||||
};
|
||||
@@ -3252,6 +3261,15 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
|
||||
KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
|
||||
KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
|
||||
KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
|
||||
+
|
||||
+ /* No assignment, used for newer Lenovo models */
|
||||
+ KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
|
||||
+ KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
|
||||
+ KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
|
||||
+ KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
|
||||
+ KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
|
||||
+ KEY_UNKNOWN, KEY_UNKNOWN
|
||||
+
|
||||
},
|
||||
|
||||
/* Generic keymap for Lenovo ThinkPads */
|
||||
@@ -3337,6 +3355,29 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
|
||||
KEY_RESERVED, /* Microphone cancellation */
|
||||
KEY_RESERVED, /* Camera mode */
|
||||
KEY_RESERVED, /* Rotate display, 0x116 */
|
||||
+
|
||||
+ /*
|
||||
+ * These are found in 2017 models (e.g. T470s, X270).
|
||||
+ * The lowest known value is 0x311, which according to
|
||||
+ * the manual should launch a user defined favorite
|
||||
+ * application.
|
||||
+ *
|
||||
+ * The offset for these is TP_ACPI_HOTKEYSCAN_EXTENDED_START,
|
||||
+ * corresponding to 0x34.
|
||||
+ */
|
||||
+
|
||||
+ /* (assignments unknown, please report if found) */
|
||||
+ KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
|
||||
+ KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
|
||||
+ KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
|
||||
+ KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
|
||||
+ KEY_UNKNOWN,
|
||||
+
|
||||
+ KEY_FAVORITES, /* Favorite app, 0x311 */
|
||||
+ KEY_RESERVED, /* Clipping tool */
|
||||
+ KEY_RESERVED,
|
||||
+ KEY_BLUETOOTH, /* Bluetooth */
|
||||
+ KEY_KEYBOARD /* Keyboard, 0x315 */
|
||||
},
|
||||
};
|
||||
|
||||
@@ -3747,8 +3788,9 @@ static bool adaptive_keyboard_hotkey_notify_hotkey(unsigned int scancode)
|
||||
|
||||
default:
|
||||
if (scancode < FIRST_ADAPTIVE_KEY ||
|
||||
- scancode >= FIRST_ADAPTIVE_KEY + TPACPI_HOTKEY_MAP_LEN -
|
||||
- TP_ACPI_HOTKEYSCAN_ADAPTIVE_START) {
|
||||
+ scancode >= FIRST_ADAPTIVE_KEY +
|
||||
+ TP_ACPI_HOTKEYSCAN_EXTENDED_START -
|
||||
+ TP_ACPI_HOTKEYSCAN_ADAPTIVE_START) {
|
||||
pr_info("Unhandled adaptive keyboard key: 0x%x\n",
|
||||
scancode);
|
||||
return false;
|
||||
@@ -3779,19 +3821,44 @@ static bool hotkey_notify_hotkey(const u32 hkey,
|
||||
*send_acpi_ev = true;
|
||||
*ignore_acpi_ev = false;
|
||||
|
||||
- /* HKEY event 0x1001 is scancode 0x00 */
|
||||
- if (scancode > 0 && scancode <= TP_ACPI_HOTKEYSCAN_ADAPTIVE_START) {
|
||||
- scancode--;
|
||||
- if (!(hotkey_source_mask & (1 << scancode))) {
|
||||
- tpacpi_input_send_key_masked(scancode);
|
||||
- *send_acpi_ev = false;
|
||||
- } else {
|
||||
- *ignore_acpi_ev = true;
|
||||
+ /*
|
||||
+ * Original events are in the 0x10XX range, the adaptive keyboard
|
||||
+ * found in 2014 X1 Carbon emits events are of 0x11XX. In 2017
|
||||
+ * models, additional keys are emitted through 0x13XX.
|
||||
+ */
|
||||
+ switch ((hkey >> 8) & 0xf) {
|
||||
+ case 0:
|
||||
+ if (scancode > 0 &&
|
||||
+ scancode <= TP_ACPI_HOTKEYSCAN_ADAPTIVE_START) {
|
||||
+ /* HKEY event 0x1001 is scancode 0x00 */
|
||||
+ scancode--;
|
||||
+ if (!(hotkey_source_mask & (1 << scancode))) {
|
||||
+ tpacpi_input_send_key_masked(scancode);
|
||||
+ *send_acpi_ev = false;
|
||||
+ } else {
|
||||
+ *ignore_acpi_ev = true;
|
||||
+ }
|
||||
+ return true;
|
||||
}
|
||||
- return true;
|
||||
- } else {
|
||||
+ break;
|
||||
+
|
||||
+ case 1:
|
||||
return adaptive_keyboard_hotkey_notify_hotkey(scancode);
|
||||
+
|
||||
+ case 3:
|
||||
+ /* Extended keycodes start at 0x300 and our offset into the map
|
||||
+ * TP_ACPI_HOTKEYSCAN_EXTENDED_START. The calculated scancode
|
||||
+ * will be positive, but might not be in the correct range.
|
||||
+ */
|
||||
+ scancode -= (0x300 - TP_ACPI_HOTKEYSCAN_EXTENDED_START);
|
||||
+ if (scancode >= TP_ACPI_HOTKEYSCAN_EXTENDED_START &&
|
||||
+ scancode < TPACPI_HOTKEY_MAP_LEN) {
|
||||
+ tpacpi_input_send_key(scancode);
|
||||
+ return true;
|
||||
+ }
|
||||
+ break;
|
||||
}
|
||||
+
|
||||
return false;
|
||||
}
|
||||
|
||||
--
|
||||
2.9.4
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
From 69dd0606a0d8680fe0a5e9b959f6662e582e1674 Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Tue, 2 May 2017 13:43:34 +0200
|
||||
Subject: [PATCH 03/16] power: supply: core: Add support for supplied-from
|
||||
device-property
|
||||
|
||||
On devicetree using platforms the devicetree can provide info on which
|
||||
power-supplies supply another power-supply through phandles.
|
||||
|
||||
This commit adds support for providing this info on non devicetree
|
||||
platforms through the platform code setting a supplied-from
|
||||
device-property on the power-supplies parent device.
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
drivers/power/supply/power_supply_core.c | 24 +++++++++++++++++++++++-
|
||||
1 file changed, 23 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c
|
||||
index 7ec7c7c202bd..0c09144193a6 100644
|
||||
--- a/drivers/power/supply/power_supply_core.c
|
||||
+++ b/drivers/power/supply/power_supply_core.c
|
||||
@@ -274,8 +274,30 @@ static int power_supply_check_supplies(struct power_supply *psy)
|
||||
return power_supply_populate_supplied_from(psy);
|
||||
}
|
||||
#else
|
||||
-static inline int power_supply_check_supplies(struct power_supply *psy)
|
||||
+static int power_supply_check_supplies(struct power_supply *psy)
|
||||
{
|
||||
+ int nval, ret;
|
||||
+
|
||||
+ if (!psy->dev.parent)
|
||||
+ return 0;
|
||||
+
|
||||
+ nval = device_property_read_string_array(psy->dev.parent,
|
||||
+ "supplied-from", NULL, 0);
|
||||
+ if (nval <= 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ psy->supplied_from = devm_kmalloc_array(&psy->dev, nval,
|
||||
+ sizeof(char *), GFP_KERNEL);
|
||||
+ if (!psy->supplied_from)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ ret = device_property_read_string_array(psy->dev.parent,
|
||||
+ "supplied-from", (const char **)psy->supplied_from, nval);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ psy->num_supplies = nval;
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
--
|
||||
2.13.0
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
From 99c44df299d96db6a170ccce9b8108fc2e7f8bae Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Tue, 2 May 2017 13:40:44 +0200
|
||||
Subject: [PATCH 04/16] platform/x86: intel_cht_int33fe: Set supplied-from
|
||||
property on max17047 dev
|
||||
|
||||
Devices with the intel_cht_int33fe ACPI device use a max17047 fuel-gauge
|
||||
combined with a bq24272i charger, in order for the fuel-gauge driver to
|
||||
correctly display charging / discharging status it needs to know which
|
||||
charger is supplying the battery.
|
||||
|
||||
This commit sets the supplied-from device property to the name of the
|
||||
bq24272i charger for this.
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
drivers/platform/x86/intel_cht_int33fe.c | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/drivers/platform/x86/intel_cht_int33fe.c b/drivers/platform/x86/intel_cht_int33fe.c
|
||||
index 6a1b2ca5b6fe..da706e2c4232 100644
|
||||
--- a/drivers/platform/x86/intel_cht_int33fe.c
|
||||
+++ b/drivers/platform/x86/intel_cht_int33fe.c
|
||||
@@ -34,6 +34,13 @@ struct cht_int33fe_data {
|
||||
struct i2c_client *pi3usb30532;
|
||||
};
|
||||
|
||||
+static const char * const max17047_suppliers[] = { "bq24190-charger" };
|
||||
+
|
||||
+static const struct property_entry max17047_props[] = {
|
||||
+ PROPERTY_ENTRY_STRING_ARRAY("supplied-from", max17047_suppliers),
|
||||
+ { }
|
||||
+};
|
||||
+
|
||||
static int cht_int33fe_probe(struct i2c_client *client)
|
||||
{
|
||||
struct device *dev = &client->dev;
|
||||
@@ -70,6 +77,7 @@ static int cht_int33fe_probe(struct i2c_client *client)
|
||||
|
||||
memset(&board_info, 0, sizeof(board_info));
|
||||
strlcpy(board_info.type, "max17047", I2C_NAME_SIZE);
|
||||
+ board_info.properties = max17047_props;
|
||||
|
||||
data->max17047 = i2c_acpi_new_device(dev, 1, &board_info);
|
||||
if (!data->max17047)
|
||||
--
|
||||
2.13.0
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
From cc2b0e2c164d02ab42efa736f91f53baf8d8bc36 Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Thu, 20 Apr 2017 22:41:20 +0200
|
||||
Subject: [PATCH 05/16] ACPI / PMIC: xpower: Add support for the GPI1 regulator
|
||||
to the OpRegion handler
|
||||
|
||||
Some Bay Trail devices use a GPI1 regulator field (address 0x4c) in
|
||||
their 0x8d power OpRegion, add support for this.
|
||||
|
||||
This fixes AE_BAD_PARAMETER errors getting thrown on these devices and
|
||||
fixes these errors causing these devices to not suspend.
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
---
|
||||
Changes in v2:
|
||||
-Simplify reg == 0x92 handling (suggested by Andy Shevchenko)
|
||||
-Add special handling for reg == 0x92 to intel_xpower_pmic_get_power() too
|
||||
Changes in v3:
|
||||
-Use defines for GPI1 reg and bits, rather then hardcoded hex values
|
||||
---
|
||||
drivers/acpi/pmic/intel_pmic_xpower.c | 21 ++++++++++++++++++++-
|
||||
1 file changed, 20 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/acpi/pmic/intel_pmic_xpower.c b/drivers/acpi/pmic/intel_pmic_xpower.c
|
||||
index 1a76c784cd4c..3b7d5be5b7ed 100644
|
||||
--- a/drivers/acpi/pmic/intel_pmic_xpower.c
|
||||
+++ b/drivers/acpi/pmic/intel_pmic_xpower.c
|
||||
@@ -21,6 +21,11 @@
|
||||
#include "intel_pmic.h"
|
||||
|
||||
#define XPOWER_GPADC_LOW 0x5b
|
||||
+#define XPOWER_GPI1_CTRL 0x92
|
||||
+
|
||||
+#define GPI1_LDO_MASK GENMASK(2, 0)
|
||||
+#define GPI1_LDO_ON (3 << 0)
|
||||
+#define GPI1_LDO_OFF (4 << 0)
|
||||
|
||||
static struct pmic_table power_table[] = {
|
||||
{
|
||||
@@ -118,6 +123,10 @@ static struct pmic_table power_table[] = {
|
||||
.reg = 0x10,
|
||||
.bit = 0x00
|
||||
}, /* BUC6 */
|
||||
+ {
|
||||
+ .address = 0x4c,
|
||||
+ .reg = 0x92,
|
||||
+ }, /* GPI1 */
|
||||
};
|
||||
|
||||
/* TMP0 - TMP5 are the same, all from GPADC */
|
||||
@@ -156,7 +165,12 @@ static int intel_xpower_pmic_get_power(struct regmap *regmap, int reg,
|
||||
if (regmap_read(regmap, reg, &data))
|
||||
return -EIO;
|
||||
|
||||
- *value = (data & BIT(bit)) ? 1 : 0;
|
||||
+ /* GPIO1 LDO regulator needs special handling */
|
||||
+ if (reg == XPOWER_GPI1_CTRL)
|
||||
+ *value = ((data & GPI1_LDO_MASK) == GPI1_LDO_ON);
|
||||
+ else
|
||||
+ *value = (data & BIT(bit)) ? 1 : 0;
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -165,6 +179,11 @@ static int intel_xpower_pmic_update_power(struct regmap *regmap, int reg,
|
||||
{
|
||||
int data;
|
||||
|
||||
+ /* GPIO1 LDO regulator needs special handling */
|
||||
+ if (reg == XPOWER_GPI1_CTRL)
|
||||
+ return regmap_update_bits(regmap, reg, GPI1_LDO_MASK,
|
||||
+ on ? GPI1_LDO_ON : GPI1_LDO_OFF);
|
||||
+
|
||||
if (regmap_read(regmap, reg, &data))
|
||||
return -EIO;
|
||||
|
||||
--
|
||||
2.13.0
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
From fbac4c05ec1d7c2d949f50baf1e934cbfbb6a494 Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Mon, 17 Apr 2017 22:06:25 +0200
|
||||
Subject: [PATCH 06/16] Input: axp20x-pek - Add wakeup support
|
||||
|
||||
At least on devices with the AXP288 PMIC the device is expected to
|
||||
wakeup from suspend when the power-button gets pressed, add support
|
||||
for this.
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
drivers/input/misc/axp20x-pek.c | 28 ++++++++++++++++++++++++++++
|
||||
1 file changed, 28 insertions(+)
|
||||
|
||||
diff --git a/drivers/input/misc/axp20x-pek.c b/drivers/input/misc/axp20x-pek.c
|
||||
index 400869e61a06..5f16fceaae83 100644
|
||||
--- a/drivers/input/misc/axp20x-pek.c
|
||||
+++ b/drivers/input/misc/axp20x-pek.c
|
||||
@@ -253,6 +253,9 @@ static int axp20x_pek_probe_input_device(struct axp20x_pek *axp20x_pek,
|
||||
return error;
|
||||
}
|
||||
|
||||
+ if (axp20x_pek->axp20x->variant == AXP288_ID)
|
||||
+ enable_irq_wake(axp20x_pek->irq_dbr);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -331,10 +334,35 @@ static int axp20x_pek_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int __maybe_unused axp20x_pek_resume_noirq(struct device *dev)
|
||||
+{
|
||||
+ struct axp20x_pek *axp20x_pek = dev_get_drvdata(dev);
|
||||
+
|
||||
+ if (axp20x_pek->axp20x->variant != AXP288_ID)
|
||||
+ return 0;
|
||||
+
|
||||
+ /*
|
||||
+ * Clear interrupts from button presses during suspend, to avoid
|
||||
+ * a wakeup power-button press getting reported to userspace.
|
||||
+ */
|
||||
+ regmap_write(axp20x_pek->axp20x->regmap,
|
||||
+ AXP20X_IRQ1_STATE + AXP288_IRQ_POKN / 8,
|
||||
+ BIT(AXP288_IRQ_POKN % 8));
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+const struct dev_pm_ops axp20x_pek_pm_ops = {
|
||||
+#ifdef CONFIG_PM_SLEEP
|
||||
+ .resume_noirq = axp20x_pek_resume_noirq,
|
||||
+#endif
|
||||
+};
|
||||
+
|
||||
static struct platform_driver axp20x_pek_driver = {
|
||||
.probe = axp20x_pek_probe,
|
||||
.driver = {
|
||||
.name = "axp20x-pek",
|
||||
+ .pm = &axp20x_pek_pm_ops,
|
||||
},
|
||||
};
|
||||
module_platform_driver(axp20x_pek_driver);
|
||||
--
|
||||
2.13.0
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
From d95c127c48ef784214671359a41ac505ac30098a Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Sun, 7 May 2017 12:32:11 +0200
|
||||
Subject: [PATCH 07/16] platform/x86: silead_dmi: Add touchscreen info for
|
||||
GP-electronic T701
|
||||
|
||||
Add touchscreen info for the GP-electronic T701 tablet.
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
drivers/platform/x86/silead_dmi.c | 22 ++++++++++++++++++++++
|
||||
1 file changed, 22 insertions(+)
|
||||
|
||||
diff --git a/drivers/platform/x86/silead_dmi.c b/drivers/platform/x86/silead_dmi.c
|
||||
index a3a57d93cf06..db3a877d2160 100644
|
||||
--- a/drivers/platform/x86/silead_dmi.c
|
||||
+++ b/drivers/platform/x86/silead_dmi.c
|
||||
@@ -80,6 +80,19 @@ static const struct silead_ts_dmi_data surftab_wintron70_st70416_6_data = {
|
||||
.properties = surftab_wintron70_st70416_6_props,
|
||||
};
|
||||
|
||||
+static const struct property_entry gp_electronic_t701_props[] = {
|
||||
+ PROPERTY_ENTRY_U32("touchscreen-size-x", 960),
|
||||
+ PROPERTY_ENTRY_U32("touchscreen-size-y", 640),
|
||||
+ PROPERTY_ENTRY_STRING("firmware-name",
|
||||
+ "gsl1680-gp-electronic-t701.fw"),
|
||||
+ { }
|
||||
+};
|
||||
+
|
||||
+static const struct silead_ts_dmi_data gp_electronic_t701_data = {
|
||||
+ .acpi_name = "MSSL1680:00",
|
||||
+ .properties = gp_electronic_t701_props,
|
||||
+};
|
||||
+
|
||||
static const struct dmi_system_id silead_ts_dmi_table[] = {
|
||||
{
|
||||
/* CUBE iwork8 Air */
|
||||
@@ -117,6 +130,15 @@ static const struct dmi_system_id silead_ts_dmi_table[] = {
|
||||
DMI_MATCH(DMI_BIOS_VERSION, "TREK.G.WI71C.JGBMRBA04"),
|
||||
},
|
||||
},
|
||||
+ {
|
||||
+ /* GP-electronic T701 */
|
||||
+ .driver_data = (void *)&gp_electronic_t701_data,
|
||||
+ .matches = {
|
||||
+ DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
|
||||
+ DMI_MATCH(DMI_PRODUCT_NAME, "T701"),
|
||||
+ DMI_MATCH(DMI_BIOS_VERSION, "BYT70A.YNCHENG.WIN.007"),
|
||||
+ },
|
||||
+ },
|
||||
{ },
|
||||
};
|
||||
|
||||
--
|
||||
2.13.0
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
From 55b347c61b2850d1e11e159ab02dc71f13b06481 Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Sun, 11 Jun 2017 17:42:31 +0200
|
||||
Subject: [PATCH 08/16] platform/x86: silead_dmi: Add touchscreen info for PoV
|
||||
mobii wintab p800w
|
||||
|
||||
Add touchscreen info for the Point of View mobii wintab p800w tablet.
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
drivers/platform/x86/silead_dmi.c | 25 +++++++++++++++++++++++++
|
||||
1 file changed, 25 insertions(+)
|
||||
|
||||
diff --git a/drivers/platform/x86/silead_dmi.c b/drivers/platform/x86/silead_dmi.c
|
||||
index db3a877d2160..46c5e1ebfb53 100644
|
||||
--- a/drivers/platform/x86/silead_dmi.c
|
||||
+++ b/drivers/platform/x86/silead_dmi.c
|
||||
@@ -93,6 +93,20 @@ static const struct silead_ts_dmi_data gp_electronic_t701_data = {
|
||||
.properties = gp_electronic_t701_props,
|
||||
};
|
||||
|
||||
+static const struct property_entry pov_mobii_wintab_p800w_props[] = {
|
||||
+ PROPERTY_ENTRY_U32("touchscreen-size-x", 1800),
|
||||
+ PROPERTY_ENTRY_U32("touchscreen-size-y", 1150),
|
||||
+ PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
|
||||
+ PROPERTY_ENTRY_STRING("firmware-name",
|
||||
+ "gsl3692-pov-mobii-wintab-p800w.fw"),
|
||||
+ { }
|
||||
+};
|
||||
+
|
||||
+static const struct silead_ts_dmi_data pov_mobii_wintab_p800w_data = {
|
||||
+ .acpi_name = "MSSL1680:00",
|
||||
+ .properties = pov_mobii_wintab_p800w_props,
|
||||
+};
|
||||
+
|
||||
static const struct dmi_system_id silead_ts_dmi_table[] = {
|
||||
{
|
||||
/* CUBE iwork8 Air */
|
||||
@@ -139,6 +153,17 @@ static const struct dmi_system_id silead_ts_dmi_table[] = {
|
||||
DMI_MATCH(DMI_BIOS_VERSION, "BYT70A.YNCHENG.WIN.007"),
|
||||
},
|
||||
},
|
||||
+ {
|
||||
+ /* Point of View mobii wintab p800w */
|
||||
+ .driver_data = (void *)&pov_mobii_wintab_p800w_data,
|
||||
+ .matches = {
|
||||
+ DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
|
||||
+ DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
|
||||
+ DMI_MATCH(DMI_BIOS_VERSION, "3BAIR1013"),
|
||||
+ /* Above matches are too generic, add bios-date match */
|
||||
+ DMI_MATCH(DMI_BIOS_DATE, "08/22/2014"),
|
||||
+ },
|
||||
+ },
|
||||
{ },
|
||||
};
|
||||
|
||||
--
|
||||
2.13.0
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
From b239a7a0c2a1435aa5cbab3f233e0c37e82943dd Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Tue, 13 Jun 2017 18:17:07 +0200
|
||||
Subject: [PATCH 09/16] platform/x86: silead_dmi: Add touchscreen info for Pipo
|
||||
W2S tablet
|
||||
|
||||
Add touchscreen info for Pipo W2S tablet.
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
drivers/platform/x86/silead_dmi.c | 23 +++++++++++++++++++++++
|
||||
1 file changed, 23 insertions(+)
|
||||
|
||||
diff --git a/drivers/platform/x86/silead_dmi.c b/drivers/platform/x86/silead_dmi.c
|
||||
index 46c5e1ebfb53..25cbea307a5e 100644
|
||||
--- a/drivers/platform/x86/silead_dmi.c
|
||||
+++ b/drivers/platform/x86/silead_dmi.c
|
||||
@@ -107,6 +107,21 @@ static const struct silead_ts_dmi_data pov_mobii_wintab_p800w_data = {
|
||||
.properties = pov_mobii_wintab_p800w_props,
|
||||
};
|
||||
|
||||
+static const struct property_entry pipo_w2s_props[] = {
|
||||
+ PROPERTY_ENTRY_U32("touchscreen-size-x", 1660),
|
||||
+ PROPERTY_ENTRY_U32("touchscreen-size-y", 880),
|
||||
+ PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"),
|
||||
+ PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
|
||||
+ PROPERTY_ENTRY_STRING("firmware-name",
|
||||
+ "gsl1680-pipo-w2s.fw"),
|
||||
+ { }
|
||||
+};
|
||||
+
|
||||
+static const struct silead_ts_dmi_data pipo_w2s_data = {
|
||||
+ .acpi_name = "MSSL1680:00",
|
||||
+ .properties = pipo_w2s_props,
|
||||
+};
|
||||
+
|
||||
static const struct dmi_system_id silead_ts_dmi_table[] = {
|
||||
{
|
||||
/* CUBE iwork8 Air */
|
||||
@@ -164,6 +179,14 @@ static const struct dmi_system_id silead_ts_dmi_table[] = {
|
||||
DMI_MATCH(DMI_BIOS_DATE, "08/22/2014"),
|
||||
},
|
||||
},
|
||||
+ {
|
||||
+ /* Pipo W2S */
|
||||
+ .driver_data = (void *)&pipo_w2s_data,
|
||||
+ .matches = {
|
||||
+ DMI_MATCH(DMI_SYS_VENDOR, "PIPO"),
|
||||
+ DMI_MATCH(DMI_PRODUCT_NAME, "W2S"),
|
||||
+ },
|
||||
+ },
|
||||
{ },
|
||||
};
|
||||
|
||||
--
|
||||
2.13.0
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
From 33fc16fd8aa3684e19b1d1f0a712593e2e570ab1 Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Sun, 11 Jun 2017 21:24:50 +0200
|
||||
Subject: [PATCH 10/16] Input: silead: Add support for capactive home button
|
||||
found on some x86 tablets
|
||||
|
||||
On some x86 tablets with a silead touchscreen the windows logo on the
|
||||
front is a capacitive home button. Touching this button results in a touch
|
||||
with bits 12-15 of the Y coordinates set, while normally only the lower 12
|
||||
are used.
|
||||
|
||||
Detect this and report a KEY_LEFTMETA press when this happens. Note for
|
||||
now we only respond to the Y coordinate bits 12-15 containing 0x01, on some
|
||||
tablets *without* a capacative button I've noticed these bits containing
|
||||
0x04 when crossing the edges of the screen.
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
drivers/input/touchscreen/silead.c | 45 ++++++++++++++++++++++++++++----------
|
||||
1 file changed, 34 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/drivers/input/touchscreen/silead.c b/drivers/input/touchscreen/silead.c
|
||||
index 0dbcf105f7db..c0ba40c09699 100644
|
||||
--- a/drivers/input/touchscreen/silead.c
|
||||
+++ b/drivers/input/touchscreen/silead.c
|
||||
@@ -56,7 +56,7 @@
|
||||
#define SILEAD_POINT_Y_MSB_OFF 0x01
|
||||
#define SILEAD_POINT_X_OFF 0x02
|
||||
#define SILEAD_POINT_X_MSB_OFF 0x03
|
||||
-#define SILEAD_TOUCH_ID_MASK 0xF0
|
||||
+#define SILEAD_EXTRA_DATA_MASK 0xF0
|
||||
|
||||
#define SILEAD_CMD_SLEEP_MIN 10000
|
||||
#define SILEAD_CMD_SLEEP_MAX 20000
|
||||
@@ -109,6 +109,8 @@ static int silead_ts_request_input_dev(struct silead_ts_data *data)
|
||||
INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED |
|
||||
INPUT_MT_TRACK);
|
||||
|
||||
+ input_set_capability(data->input, EV_KEY, KEY_LEFTMETA);
|
||||
+
|
||||
data->input->name = SILEAD_TS_NAME;
|
||||
data->input->phys = "input/ts";
|
||||
data->input->id.bustype = BUS_I2C;
|
||||
@@ -139,7 +141,8 @@ static void silead_ts_read_data(struct i2c_client *client)
|
||||
struct input_dev *input = data->input;
|
||||
struct device *dev = &client->dev;
|
||||
u8 *bufp, buf[SILEAD_TS_DATA_LEN];
|
||||
- int touch_nr, error, i;
|
||||
+ int touch_nr, softbutton, error, i;
|
||||
+ bool softbutton_pressed = false;
|
||||
|
||||
error = i2c_smbus_read_i2c_block_data(client, SILEAD_REG_DATA,
|
||||
SILEAD_TS_DATA_LEN, buf);
|
||||
@@ -148,21 +151,40 @@ static void silead_ts_read_data(struct i2c_client *client)
|
||||
return;
|
||||
}
|
||||
|
||||
- touch_nr = buf[0];
|
||||
- if (touch_nr > data->max_fingers) {
|
||||
+ if (buf[0] > data->max_fingers) {
|
||||
dev_warn(dev, "More touches reported then supported %d > %d\n",
|
||||
- touch_nr, data->max_fingers);
|
||||
- touch_nr = data->max_fingers;
|
||||
+ buf[0], data->max_fingers);
|
||||
+ buf[0] = data->max_fingers;
|
||||
}
|
||||
|
||||
+ touch_nr = 0;
|
||||
bufp = buf + SILEAD_POINT_DATA_LEN;
|
||||
- for (i = 0; i < touch_nr; i++, bufp += SILEAD_POINT_DATA_LEN) {
|
||||
- /* Bits 4-7 are the touch id */
|
||||
- data->id[i] = (bufp[SILEAD_POINT_X_MSB_OFF] &
|
||||
- SILEAD_TOUCH_ID_MASK) >> 4;
|
||||
- touchscreen_set_mt_pos(&data->pos[i], &data->prop,
|
||||
+ for (i = 0; i < buf[0]; i++, bufp += SILEAD_POINT_DATA_LEN) {
|
||||
+ softbutton = (bufp[SILEAD_POINT_Y_MSB_OFF] &
|
||||
+ SILEAD_EXTRA_DATA_MASK) >> 4;
|
||||
+
|
||||
+ if (softbutton) {
|
||||
+ /*
|
||||
+ * For now only respond to softbutton == 0x01, some
|
||||
+ * tablets *without* a capacative button send 0x04
|
||||
+ * when crossing the edges of the screen.
|
||||
+ */
|
||||
+ if (softbutton == 0x01)
|
||||
+ softbutton_pressed = true;
|
||||
+
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Bits 4-7 are the touch id, note not all models have
|
||||
+ * hardware touch ids so atm we don't use these.
|
||||
+ */
|
||||
+ data->id[touch_nr] = (bufp[SILEAD_POINT_X_MSB_OFF] &
|
||||
+ SILEAD_EXTRA_DATA_MASK) >> 4;
|
||||
+ touchscreen_set_mt_pos(&data->pos[touch_nr], &data->prop,
|
||||
get_unaligned_le16(&bufp[SILEAD_POINT_X_OFF]) & 0xfff,
|
||||
get_unaligned_le16(&bufp[SILEAD_POINT_Y_OFF]) & 0xfff);
|
||||
+ touch_nr++;
|
||||
}
|
||||
|
||||
input_mt_assign_slots(input, data->slots, data->pos, touch_nr, 0);
|
||||
@@ -178,6 +200,7 @@ static void silead_ts_read_data(struct i2c_client *client)
|
||||
}
|
||||
|
||||
input_mt_sync_frame(input);
|
||||
+ input_report_key(input, KEY_LEFTMETA, softbutton_pressed);
|
||||
input_sync(input);
|
||||
}
|
||||
|
||||
--
|
||||
2.13.0
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
From 2a99775c336303d2efc43eab4f24b34722a28faa Mon Sep 17 00:00:00 2001
|
||||
From: "Sergei A. Trusov" <sergei.a.trusov@ya.ru>
|
||||
Date: Tue, 20 Jun 2017 18:08:35 +0200
|
||||
Subject: [PATCH 11/16] Input: goodix: Add support for capacitive home button
|
||||
|
||||
On some x86 tablets with a Goodix touchscreen, the Windows logo on the
|
||||
front is a capacitive home button. Touching this button results in a touch
|
||||
with bit 4 of the first byte set, while only the lower 4 bits (0-3) are
|
||||
used to indicate the number of touches.
|
||||
|
||||
Report a KEY_LEFTMETA press when this happens.
|
||||
|
||||
Note that the hardware might support more than one button, in which
|
||||
case the "id" byte of coor_data would identify the button in question.
|
||||
This is not implemented as we don't have access to hardware with
|
||||
multiple buttons.
|
||||
|
||||
Signed-off-by: Sergei A. Trusov <sergei.a.trusov@ya.ru>
|
||||
Acked-by: Bastien Nocera <hadess@hadess.net>
|
||||
---
|
||||
drivers/input/touchscreen/goodix.c | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c
|
||||
index 240b16f3ee97..903137d9cf7d 100644
|
||||
--- a/drivers/input/touchscreen/goodix.c
|
||||
+++ b/drivers/input/touchscreen/goodix.c
|
||||
@@ -267,6 +267,12 @@ static void goodix_process_events(struct goodix_ts_data *ts)
|
||||
if (touch_num < 0)
|
||||
return;
|
||||
|
||||
+ /*
|
||||
+ * Bit 4 of the first byte reports the status of the capacitive
|
||||
+ * Windows/Home button.
|
||||
+ */
|
||||
+ input_report_key(ts->input_dev, KEY_LEFTMETA, !!(point_data[0] & BIT(4)));
|
||||
+
|
||||
for (i = 0; i < touch_num; i++)
|
||||
goodix_ts_report_touch(ts,
|
||||
&point_data[1 + GOODIX_CONTACT_SIZE * i]);
|
||||
@@ -612,6 +618,9 @@ static int goodix_request_input_dev(struct goodix_ts_data *ts)
|
||||
ts->input_dev->id.product = ts->id;
|
||||
ts->input_dev->id.version = ts->version;
|
||||
|
||||
+ /* Capacitive Windows/Home button on some devices */
|
||||
+ input_set_capability(ts->input_dev, EV_KEY, KEY_LEFTMETA);
|
||||
+
|
||||
error = input_register_device(ts->input_dev);
|
||||
if (error) {
|
||||
dev_err(&ts->client->dev,
|
||||
--
|
||||
2.13.0
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
From 02b823a4d28ffb5fde5192799abd934d9de95630 Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Fri, 6 Jan 2017 20:08:11 +0100
|
||||
Subject: [PATCH 12/16] Input: gpio_keys - Do not report wake button presses as
|
||||
evdev events
|
||||
|
||||
If a button is a wake button, it may still be bouncing from the press
|
||||
to wakeup the device by the time the gpio interrupts get enabled again
|
||||
and / or the gpio_keys_report_state call from gpio_keys_resume may
|
||||
find the button still pressed and report this as a new press.
|
||||
|
||||
This is undesirable, esp. since the powerbutton on tablets is typically
|
||||
a wakeup source and uses the gpio_keys driver on some tablets, leading
|
||||
to userspace immediately re-suspending the tablet after the powerbutton
|
||||
is pressed, due to it seeing a powerbutton press.
|
||||
|
||||
This commit ignores wakeup button presses for the first 1 second after
|
||||
resume (and while resumed, as the workqueue may run before the resume
|
||||
function runs), avoiding this problem.
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
Note: maybe we should make WAKE_DEBOUNCE part of gpio_keys_button and
|
||||
only do this when drivers / platform-data set this to a non-zero value ?
|
||||
---
|
||||
drivers/input/keyboard/gpio_keys.c | 49 ++++++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 47 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
|
||||
index da3d362f21b1..e1488b534e7d 100644
|
||||
--- a/drivers/input/keyboard/gpio_keys.c
|
||||
+++ b/drivers/input/keyboard/gpio_keys.c
|
||||
@@ -31,6 +31,8 @@
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
+#define WAKE_DEBOUNCE msecs_to_jiffies(1000)
|
||||
+
|
||||
struct gpio_button_data {
|
||||
const struct gpio_keys_button *button;
|
||||
struct input_dev *input;
|
||||
@@ -44,10 +46,14 @@ struct gpio_button_data {
|
||||
struct delayed_work work;
|
||||
unsigned int software_debounce; /* in msecs, for GPIO-driven buttons */
|
||||
|
||||
+ unsigned long resume_time; /* in jiffies, for wakeup buttons */
|
||||
+
|
||||
unsigned int irq;
|
||||
spinlock_t lock;
|
||||
bool disabled;
|
||||
bool key_pressed;
|
||||
+ bool suspended;
|
||||
+ bool resume_time_valid;
|
||||
};
|
||||
|
||||
struct gpio_keys_drvdata {
|
||||
@@ -356,6 +362,27 @@ static struct attribute_group gpio_keys_attr_group = {
|
||||
.attrs = gpio_keys_attrs,
|
||||
};
|
||||
|
||||
+static bool gpio_keys_ignore_wakeup_button_press(struct gpio_button_data *bdata)
|
||||
+{
|
||||
+ unsigned long flags;
|
||||
+ bool ret = false;
|
||||
+
|
||||
+ if (!bdata->button->wakeup)
|
||||
+ return ret;
|
||||
+
|
||||
+ spin_lock_irqsave(&bdata->lock, flags);
|
||||
+
|
||||
+ if (bdata->suspended)
|
||||
+ ret = true; /* Our resume method did not run yet */
|
||||
+ else if (bdata->resume_time_valid &&
|
||||
+ time_before(jiffies, bdata->resume_time + WAKE_DEBOUNCE))
|
||||
+ ret = true; /* Assume this is a wakeup press and ignore */
|
||||
+
|
||||
+ spin_unlock_irqrestore(&bdata->lock, flags);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static void gpio_keys_gpio_report_event(struct gpio_button_data *bdata)
|
||||
{
|
||||
const struct gpio_keys_button *button = bdata->button;
|
||||
@@ -370,6 +397,9 @@ static void gpio_keys_gpio_report_event(struct gpio_button_data *bdata)
|
||||
return;
|
||||
}
|
||||
|
||||
+ if (state && gpio_keys_ignore_wakeup_button_press(bdata))
|
||||
+ return;
|
||||
+
|
||||
if (type == EV_ABS) {
|
||||
if (state)
|
||||
input_event(input, type, button->code, button->value);
|
||||
@@ -429,6 +459,9 @@ static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id)
|
||||
|
||||
BUG_ON(irq != bdata->irq);
|
||||
|
||||
+ if (gpio_keys_ignore_wakeup_button_press(bdata))
|
||||
+ return IRQ_HANDLED;
|
||||
+
|
||||
spin_lock_irqsave(&bdata->lock, flags);
|
||||
|
||||
if (!bdata->key_pressed) {
|
||||
@@ -848,13 +881,18 @@ static int __maybe_unused gpio_keys_suspend(struct device *dev)
|
||||
{
|
||||
struct gpio_keys_drvdata *ddata = dev_get_drvdata(dev);
|
||||
struct input_dev *input = ddata->input;
|
||||
+ unsigned long flags;
|
||||
int i;
|
||||
|
||||
if (device_may_wakeup(dev)) {
|
||||
for (i = 0; i < ddata->pdata->nbuttons; i++) {
|
||||
struct gpio_button_data *bdata = &ddata->data[i];
|
||||
- if (bdata->button->wakeup)
|
||||
+ if (bdata->button->wakeup) {
|
||||
+ spin_lock_irqsave(&bdata->lock, flags);
|
||||
+ bdata->suspended = true;
|
||||
+ spin_unlock_irqrestore(&bdata->lock, flags);
|
||||
enable_irq_wake(bdata->irq);
|
||||
+ }
|
||||
}
|
||||
} else {
|
||||
mutex_lock(&input->mutex);
|
||||
@@ -870,14 +908,21 @@ static int __maybe_unused gpio_keys_resume(struct device *dev)
|
||||
{
|
||||
struct gpio_keys_drvdata *ddata = dev_get_drvdata(dev);
|
||||
struct input_dev *input = ddata->input;
|
||||
+ unsigned long flags;
|
||||
int error = 0;
|
||||
int i;
|
||||
|
||||
if (device_may_wakeup(dev)) {
|
||||
for (i = 0; i < ddata->pdata->nbuttons; i++) {
|
||||
struct gpio_button_data *bdata = &ddata->data[i];
|
||||
- if (bdata->button->wakeup)
|
||||
+ if (bdata->button->wakeup) {
|
||||
disable_irq_wake(bdata->irq);
|
||||
+ spin_lock_irqsave(&bdata->lock, flags);
|
||||
+ bdata->resume_time = jiffies;
|
||||
+ bdata->resume_time_valid = true;
|
||||
+ bdata->suspended = false;
|
||||
+ spin_unlock_irqrestore(&bdata->lock, flags);
|
||||
+ }
|
||||
}
|
||||
} else {
|
||||
mutex_lock(&input->mutex);
|
||||
--
|
||||
2.13.0
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
From bf3e9581e10a19b2ce77a45fe001116d269b4c7f Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Sun, 18 Jun 2017 12:47:38 +0200
|
||||
Subject: [PATCH 13/16] iio: accel: bmc150: Add support for BOSC0200 ACPI
|
||||
device id
|
||||
|
||||
Add support for the BOSC0200 ACPI device id used on some x86 tablets.
|
||||
note driver_data is not set to a specific model, driver_data is not
|
||||
used anyways (instead detection is done on the chip_id reg) and the
|
||||
2 tablets with a BOSC0200 ACPI device id I've have 2 different chips,
|
||||
one has a BMA250E, the other a BMA222E.
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
drivers/iio/accel/bmc150-accel-i2c.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/drivers/iio/accel/bmc150-accel-i2c.c b/drivers/iio/accel/bmc150-accel-i2c.c
|
||||
index 8ca8041267ef..f85014fbaa12 100644
|
||||
--- a/drivers/iio/accel/bmc150-accel-i2c.c
|
||||
+++ b/drivers/iio/accel/bmc150-accel-i2c.c
|
||||
@@ -64,6 +64,7 @@ static const struct acpi_device_id bmc150_accel_acpi_match[] = {
|
||||
{"BMA250E", bma250e},
|
||||
{"BMA222E", bma222e},
|
||||
{"BMA0280", bma280},
|
||||
+ {"BOSC0200"},
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, bmc150_accel_acpi_match);
|
||||
--
|
||||
2.13.0
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
From 51eb7454942c68c84b82782e47637de3ba37f113 Mon Sep 17 00:00:00 2001
|
||||
From: Adrian Hunter <adrian.hunter@intel.com>
|
||||
Date: Wed, 21 Jun 2017 15:08:39 +0300
|
||||
Subject: [PATCH 14/16] mmc: sdhci-acpi: Workaround conflict with PCI wifi on
|
||||
GPD Win handheld
|
||||
|
||||
GPDwin uses PCI wifi which conflicts with SDIO's use of
|
||||
acpi_device_fix_up_power() on child device nodes. Specifically
|
||||
acpi_device_fix_up_power() causes the wifi module to get turned off.
|
||||
Identifying GPDwin is problematic, but since SDIO is only used for wifi,
|
||||
the presence of the PCI wifi card in the expected slot with an ACPI
|
||||
companion node, is used to indicate that acpi_device_fix_up_power() should
|
||||
be avoided.
|
||||
|
||||
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
|
||||
Acked-by: Hans de Goede <hdegoede@redhat.com>
|
||||
Tested-by: Hans de Goede <hdegoede@redhat.com>
|
||||
Cc: stable@vger.kernel.org
|
||||
---
|
||||
drivers/mmc/host/sdhci-acpi.c | 70 +++++++++++++++++++++++++++++++++++++++----
|
||||
1 file changed, 64 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c
|
||||
index c6a9a1bfaa22..b3fb155f50e4 100644
|
||||
--- a/drivers/mmc/host/sdhci-acpi.c
|
||||
+++ b/drivers/mmc/host/sdhci-acpi.c
|
||||
@@ -45,6 +45,7 @@
|
||||
#include <asm/cpu_device_id.h>
|
||||
#include <asm/intel-family.h>
|
||||
#include <asm/iosf_mbi.h>
|
||||
+#include <linux/pci.h>
|
||||
#endif
|
||||
|
||||
#include "sdhci.h"
|
||||
@@ -134,6 +135,16 @@ static bool sdhci_acpi_byt(void)
|
||||
return x86_match_cpu(byt);
|
||||
}
|
||||
|
||||
+static bool sdhci_acpi_cht(void)
|
||||
+{
|
||||
+ static const struct x86_cpu_id cht[] = {
|
||||
+ { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_AIRMONT },
|
||||
+ {}
|
||||
+ };
|
||||
+
|
||||
+ return x86_match_cpu(cht);
|
||||
+}
|
||||
+
|
||||
#define BYT_IOSF_SCCEP 0x63
|
||||
#define BYT_IOSF_OCP_NETCTRL0 0x1078
|
||||
#define BYT_IOSF_OCP_TIMEOUT_BASE GENMASK(10, 8)
|
||||
@@ -178,6 +189,45 @@ static bool sdhci_acpi_byt_defer(struct device *dev)
|
||||
return false;
|
||||
}
|
||||
|
||||
+static bool sdhci_acpi_cht_pci_wifi(unsigned int vendor, unsigned int device,
|
||||
+ unsigned int slot, unsigned int parent_slot)
|
||||
+{
|
||||
+ struct pci_dev *dev, *parent, *from = NULL;
|
||||
+
|
||||
+ while (1) {
|
||||
+ dev = pci_get_device(vendor, device, from);
|
||||
+ pci_dev_put(from);
|
||||
+ if (!dev)
|
||||
+ break;
|
||||
+ parent = pci_upstream_bridge(dev);
|
||||
+ if (ACPI_COMPANION(&dev->dev) && PCI_SLOT(dev->devfn) == slot &&
|
||||
+ parent && PCI_SLOT(parent->devfn) == parent_slot &&
|
||||
+ !pci_upstream_bridge(parent)) {
|
||||
+ pci_dev_put(dev);
|
||||
+ return true;
|
||||
+ }
|
||||
+ from = dev;
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * GPDwin uses PCI wifi which conflicts with SDIO's use of
|
||||
+ * acpi_device_fix_up_power() on child device nodes. Identifying GPDwin is
|
||||
+ * problematic, but since SDIO is only used for wifi, the presence of the PCI
|
||||
+ * wifi card in the expected slot with an ACPI companion node, is used to
|
||||
+ * indicate that acpi_device_fix_up_power() should be avoided.
|
||||
+ */
|
||||
+static inline bool sdhci_acpi_no_fixup_child_power(const char *hid,
|
||||
+ const char *uid)
|
||||
+{
|
||||
+ return sdhci_acpi_cht() &&
|
||||
+ !strcmp(hid, "80860F14") &&
|
||||
+ !strcmp(uid, "2") &&
|
||||
+ sdhci_acpi_cht_pci_wifi(0x14e4, 0x43ec, 0, 28);
|
||||
+}
|
||||
+
|
||||
#else
|
||||
|
||||
static inline void sdhci_acpi_byt_setting(struct device *dev)
|
||||
@@ -189,6 +239,12 @@ static inline bool sdhci_acpi_byt_defer(struct device *dev)
|
||||
return false;
|
||||
}
|
||||
|
||||
+static inline bool sdhci_acpi_no_fixup_child_power(const char *hid,
|
||||
+ const char *uid)
|
||||
+{
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
#endif
|
||||
|
||||
static int bxt_get_cd(struct mmc_host *mmc)
|
||||
@@ -390,11 +446,16 @@ static int sdhci_acpi_probe(struct platform_device *pdev)
|
||||
if (acpi_bus_get_device(handle, &device))
|
||||
return -ENODEV;
|
||||
|
||||
+ hid = acpi_device_hid(device);
|
||||
+ uid = device->pnp.unique_id;
|
||||
+
|
||||
/* Power on the SDHCI controller and its children */
|
||||
acpi_device_fix_up_power(device);
|
||||
- list_for_each_entry(child, &device->children, node)
|
||||
- if (child->status.present && child->status.enabled)
|
||||
- acpi_device_fix_up_power(child);
|
||||
+ if (!sdhci_acpi_no_fixup_child_power(hid, uid)) {
|
||||
+ list_for_each_entry(child, &device->children, node)
|
||||
+ if (child->status.present && child->status.enabled)
|
||||
+ acpi_device_fix_up_power(child);
|
||||
+ }
|
||||
|
||||
if (acpi_bus_get_status(device) || !device->status.present)
|
||||
return -ENODEV;
|
||||
@@ -402,9 +463,6 @@ static int sdhci_acpi_probe(struct platform_device *pdev)
|
||||
if (sdhci_acpi_byt_defer(dev))
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
- hid = acpi_device_hid(device);
|
||||
- uid = device->pnp.unique_id;
|
||||
-
|
||||
iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!iomem)
|
||||
return -ENOMEM;
|
||||
--
|
||||
2.13.0
|
||||
|
|
@ -0,0 +1,410 @@
|
|||
From bd0d7169342e47919f68e75d659968f02b62f84b Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Fri, 3 Mar 2017 23:48:50 +0100
|
||||
Subject: [PATCH 15/16] i2c-cht-wc: Add Intel Cherry Trail Whiskey Cove SMBUS
|
||||
controller driver
|
||||
|
||||
The Intel Cherry Trail Whiskey Cove PMIC does not contain a builtin
|
||||
battery charger, instead boards with this PMIC use an external TI
|
||||
bq24292i charger IC, which is connected to a SMBUS controller built into
|
||||
the PMIC.
|
||||
|
||||
This commit adds an i2c-bus driver for the PMIC's builtin SMBUS
|
||||
controller. The probe function for this i2c-bus will also register an
|
||||
i2c-client for the TI bq24292i charger after the i2c-bus has been
|
||||
registered.
|
||||
|
||||
Note that several device-properties are set on the client-device to
|
||||
tell the bq24190 power-supply driver to integrate the Whiskey Cove PMIC
|
||||
and e.g. use the PMIC's BC1.2 detection (through extcon) to determine
|
||||
the maximum input current.
|
||||
|
||||
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
Changes in v2:
|
||||
-Various style (mostly captialization and variable name) fixes
|
||||
-Use device-properties instead of platform_data for the i2c_board_info
|
||||
---
|
||||
drivers/i2c/busses/Kconfig | 8 +
|
||||
drivers/i2c/busses/Makefile | 1 +
|
||||
drivers/i2c/busses/i2c-cht-wc.c | 336 ++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 345 insertions(+)
|
||||
create mode 100644 drivers/i2c/busses/i2c-cht-wc.c
|
||||
|
||||
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
|
||||
index 144cbadc7c72..18c96178b177 100644
|
||||
--- a/drivers/i2c/busses/Kconfig
|
||||
+++ b/drivers/i2c/busses/Kconfig
|
||||
@@ -187,6 +187,14 @@ config I2C_PIIX4
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called i2c-piix4.
|
||||
|
||||
+config I2C_CHT_WC
|
||||
+ tristate "Intel Cherry Trail Whiskey Cove PMIC smbus controller"
|
||||
+ depends on INTEL_SOC_PMIC_CHTWC
|
||||
+ help
|
||||
+ If you say yes to this option, support will be included for the
|
||||
+ SMBus controller found in the Intel Cherry Trail Whiskey Cove PMIC
|
||||
+ found on some Intel Cherry Trail systems.
|
||||
+
|
||||
config I2C_NFORCE2
|
||||
tristate "Nvidia nForce2, nForce3 and nForce4"
|
||||
depends on PCI
|
||||
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
|
||||
index 30b60855fbcd..f6443fa44f61 100644
|
||||
--- a/drivers/i2c/busses/Makefile
|
||||
+++ b/drivers/i2c/busses/Makefile
|
||||
@@ -12,6 +12,7 @@ obj-$(CONFIG_I2C_ALI15X3) += i2c-ali15x3.o
|
||||
obj-$(CONFIG_I2C_AMD756) += i2c-amd756.o
|
||||
obj-$(CONFIG_I2C_AMD756_S4882) += i2c-amd756-s4882.o
|
||||
obj-$(CONFIG_I2C_AMD8111) += i2c-amd8111.o
|
||||
+obj-$(CONFIG_I2C_CHT_WC) += i2c-cht-wc.o
|
||||
obj-$(CONFIG_I2C_I801) += i2c-i801.o
|
||||
obj-$(CONFIG_I2C_ISCH) += i2c-isch.o
|
||||
obj-$(CONFIG_I2C_ISMT) += i2c-ismt.o
|
||||
diff --git a/drivers/i2c/busses/i2c-cht-wc.c b/drivers/i2c/busses/i2c-cht-wc.c
|
||||
new file mode 100644
|
||||
index 000000000000..ccf0785bcb75
|
||||
--- /dev/null
|
||||
+++ b/drivers/i2c/busses/i2c-cht-wc.c
|
||||
@@ -0,0 +1,336 @@
|
||||
+/*
|
||||
+ * Intel CHT Whiskey Cove PMIC I2C Master driver
|
||||
+ * Copyright (C) 2017 Hans de Goede <hdegoede@redhat.com>
|
||||
+ *
|
||||
+ * Based on various non upstream patches to support the CHT Whiskey Cove PMIC:
|
||||
+ * Copyright (C) 2011 - 2014 Intel Corporation. All rights reserved.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU General Public License version
|
||||
+ * 2 as published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * 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/completion.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/i2c.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/irq.h>
|
||||
+#include <linux/irqdomain.h>
|
||||
+#include <linux/mfd/intel_soc_pmic.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/slab.h>
|
||||
+
|
||||
+#define CHT_WC_I2C_CTRL 0x5e24
|
||||
+#define CHT_WC_I2C_CTRL_WR BIT(0)
|
||||
+#define CHT_WC_I2C_CTRL_RD BIT(1)
|
||||
+#define CHT_WC_I2C_CLIENT_ADDR 0x5e25
|
||||
+#define CHT_WC_I2C_REG_OFFSET 0x5e26
|
||||
+#define CHT_WC_I2C_WRDATA 0x5e27
|
||||
+#define CHT_WC_I2C_RDDATA 0x5e28
|
||||
+
|
||||
+#define CHT_WC_EXTCHGRIRQ 0x6e0a
|
||||
+#define CHT_WC_EXTCHGRIRQ_CLIENT_IRQ BIT(0)
|
||||
+#define CHT_WC_EXTCHGRIRQ_WRITE_IRQ BIT(1)
|
||||
+#define CHT_WC_EXTCHGRIRQ_READ_IRQ BIT(2)
|
||||
+#define CHT_WC_EXTCHGRIRQ_NACK_IRQ BIT(3)
|
||||
+#define CHT_WC_EXTCHGRIRQ_ADAP_IRQMASK ((u8)GENMASK(3, 1))
|
||||
+#define CHT_WC_EXTCHGRIRQ_MSK 0x6e17
|
||||
+
|
||||
+struct cht_wc_i2c_adap {
|
||||
+ struct i2c_adapter adapter;
|
||||
+ wait_queue_head_t wait;
|
||||
+ struct irq_chip irqchip;
|
||||
+ struct mutex irqchip_lock;
|
||||
+ struct regmap *regmap;
|
||||
+ struct irq_domain *irq_domain;
|
||||
+ struct i2c_client *client;
|
||||
+ int client_irq;
|
||||
+ u8 irq_mask;
|
||||
+ u8 old_irq_mask;
|
||||
+ bool nack;
|
||||
+ bool done;
|
||||
+};
|
||||
+
|
||||
+static irqreturn_t cht_wc_i2c_adap_thread_handler(int id, void *data)
|
||||
+{
|
||||
+ struct cht_wc_i2c_adap *adap = data;
|
||||
+ int ret, reg;
|
||||
+
|
||||
+ /* Read IRQs */
|
||||
+ ret = regmap_read(adap->regmap, CHT_WC_EXTCHGRIRQ, ®);
|
||||
+ if (ret) {
|
||||
+ dev_err(&adap->adapter.dev, "Error reading extchgrirq reg\n");
|
||||
+ return IRQ_NONE;
|
||||
+ }
|
||||
+
|
||||
+ reg &= ~adap->irq_mask;
|
||||
+
|
||||
+ /*
|
||||
+ * Immediately ack IRQs, so that if new IRQs arrives while we're
|
||||
+ * handling the previous ones our irq will re-trigger when we're done.
|
||||
+ */
|
||||
+ ret = regmap_write(adap->regmap, CHT_WC_EXTCHGRIRQ, reg);
|
||||
+ if (ret)
|
||||
+ dev_err(&adap->adapter.dev, "Error writing extchgrirq reg\n");
|
||||
+
|
||||
+ /*
|
||||
+ * Do NOT use handle_nested_irq here, the client irq handler will
|
||||
+ * likely want to do i2c transfers and the i2c controller uses this
|
||||
+ * interrupt handler as well, so running the client irq handler from
|
||||
+ * this thread will cause things to lock up.
|
||||
+ */
|
||||
+ if (reg & CHT_WC_EXTCHGRIRQ_CLIENT_IRQ) {
|
||||
+ /*
|
||||
+ * generic_handle_irq expects local IRQs to be disabled
|
||||
+ * as normally it is called from interrupt context.
|
||||
+ */
|
||||
+ local_irq_disable();
|
||||
+ generic_handle_irq(adap->client_irq);
|
||||
+ local_irq_enable();
|
||||
+ }
|
||||
+
|
||||
+ if (reg & CHT_WC_EXTCHGRIRQ_ADAP_IRQMASK) {
|
||||
+ adap->nack = !!(reg & CHT_WC_EXTCHGRIRQ_NACK_IRQ);
|
||||
+ adap->done = true;
|
||||
+ wake_up(&adap->wait);
|
||||
+ }
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static u32 cht_wc_i2c_adap_master_func(struct i2c_adapter *adap)
|
||||
+{
|
||||
+ /* This i2c adapter only supports SMBUS byte transfers */
|
||||
+ return I2C_FUNC_SMBUS_BYTE_DATA;
|
||||
+}
|
||||
+
|
||||
+static int cht_wc_i2c_adap_smbus_xfer(struct i2c_adapter *_adap, u16 addr,
|
||||
+ unsigned short flags, char read_write,
|
||||
+ u8 command, int size,
|
||||
+ union i2c_smbus_data *data)
|
||||
+{
|
||||
+ struct cht_wc_i2c_adap *adap = i2c_get_adapdata(_adap);
|
||||
+ int ret, reg;
|
||||
+
|
||||
+ adap->nack = false;
|
||||
+ adap->done = false;
|
||||
+
|
||||
+ ret = regmap_write(adap->regmap, CHT_WC_I2C_CLIENT_ADDR, addr);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (read_write == I2C_SMBUS_WRITE) {
|
||||
+ ret = regmap_write(adap->regmap, CHT_WC_I2C_WRDATA, data->byte);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = regmap_write(adap->regmap, CHT_WC_I2C_REG_OFFSET, command);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = regmap_write(adap->regmap, CHT_WC_I2C_CTRL,
|
||||
+ (read_write == I2C_SMBUS_WRITE) ?
|
||||
+ CHT_WC_I2C_CTRL_WR : CHT_WC_I2C_CTRL_RD);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* 3 second timeout, during cable plug the PMIC responds quite slow */
|
||||
+ ret = wait_event_timeout(adap->wait, adap->done, 3 * HZ);
|
||||
+ if (ret == 0)
|
||||
+ return -ETIMEDOUT;
|
||||
+ if (adap->nack)
|
||||
+ return -EIO;
|
||||
+
|
||||
+ if (read_write == I2C_SMBUS_READ) {
|
||||
+ ret = regmap_read(adap->regmap, CHT_WC_I2C_RDDATA, ®);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ data->byte = reg;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct i2c_algorithm cht_wc_i2c_adap_algo = {
|
||||
+ .functionality = cht_wc_i2c_adap_master_func,
|
||||
+ .smbus_xfer = cht_wc_i2c_adap_smbus_xfer,
|
||||
+};
|
||||
+
|
||||
+/**** irqchip for the client connected to the extchgr i2c adapter ****/
|
||||
+static void cht_wc_i2c_irq_lock(struct irq_data *data)
|
||||
+{
|
||||
+ struct cht_wc_i2c_adap *adap = irq_data_get_irq_chip_data(data);
|
||||
+
|
||||
+ mutex_lock(&adap->irqchip_lock);
|
||||
+}
|
||||
+
|
||||
+static void cht_wc_i2c_irq_sync_unlock(struct irq_data *data)
|
||||
+{
|
||||
+ struct cht_wc_i2c_adap *adap = irq_data_get_irq_chip_data(data);
|
||||
+ int ret;
|
||||
+
|
||||
+ if (adap->irq_mask != adap->old_irq_mask) {
|
||||
+ ret = regmap_write(adap->regmap, CHT_WC_EXTCHGRIRQ_MSK,
|
||||
+ adap->irq_mask);
|
||||
+ if (ret == 0)
|
||||
+ adap->old_irq_mask = adap->irq_mask;
|
||||
+ else
|
||||
+ dev_err(&adap->adapter.dev, "Error writing EXTCHGRIRQ_MSK\n");
|
||||
+ }
|
||||
+
|
||||
+ mutex_unlock(&adap->irqchip_lock);
|
||||
+}
|
||||
+
|
||||
+static void cht_wc_i2c_irq_enable(struct irq_data *data)
|
||||
+{
|
||||
+ struct cht_wc_i2c_adap *adap = irq_data_get_irq_chip_data(data);
|
||||
+
|
||||
+ adap->irq_mask &= ~CHT_WC_EXTCHGRIRQ_CLIENT_IRQ;
|
||||
+}
|
||||
+
|
||||
+static void cht_wc_i2c_irq_disable(struct irq_data *data)
|
||||
+{
|
||||
+ struct cht_wc_i2c_adap *adap = irq_data_get_irq_chip_data(data);
|
||||
+
|
||||
+ adap->irq_mask |= CHT_WC_EXTCHGRIRQ_CLIENT_IRQ;
|
||||
+}
|
||||
+
|
||||
+static const struct irq_chip cht_wc_i2c_irq_chip = {
|
||||
+ .irq_bus_lock = cht_wc_i2c_irq_lock,
|
||||
+ .irq_bus_sync_unlock = cht_wc_i2c_irq_sync_unlock,
|
||||
+ .irq_disable = cht_wc_i2c_irq_disable,
|
||||
+ .irq_enable = cht_wc_i2c_irq_enable,
|
||||
+ .name = "cht_wc_ext_chrg_irq_chip",
|
||||
+};
|
||||
+
|
||||
+static const struct property_entry bq24190_props[] = {
|
||||
+ PROPERTY_ENTRY_STRING("extcon-name", "cht_wcove_pwrsrc"),
|
||||
+ PROPERTY_ENTRY_BOOL("omit-battery-class"),
|
||||
+ PROPERTY_ENTRY_BOOL("disable-reset"),
|
||||
+ { }
|
||||
+};
|
||||
+
|
||||
+static int cht_wc_i2c_adap_i2c_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct intel_soc_pmic *pmic = dev_get_drvdata(pdev->dev.parent);
|
||||
+ struct cht_wc_i2c_adap *adap;
|
||||
+ struct i2c_board_info board_info = {
|
||||
+ .type = "bq24190",
|
||||
+ .addr = 0x6b,
|
||||
+ .properties = bq24190_props,
|
||||
+ };
|
||||
+ int ret, irq;
|
||||
+
|
||||
+ irq = platform_get_irq(pdev, 0);
|
||||
+ if (irq < 0) {
|
||||
+ dev_err(&pdev->dev, "Error missing irq resource\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ adap = devm_kzalloc(&pdev->dev, sizeof(*adap), GFP_KERNEL);
|
||||
+ if (!adap)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ init_waitqueue_head(&adap->wait);
|
||||
+ mutex_init(&adap->irqchip_lock);
|
||||
+ adap->irqchip = cht_wc_i2c_irq_chip;
|
||||
+ adap->regmap = pmic->regmap;
|
||||
+ adap->adapter.owner = THIS_MODULE;
|
||||
+ adap->adapter.class = I2C_CLASS_HWMON;
|
||||
+ adap->adapter.algo = &cht_wc_i2c_adap_algo;
|
||||
+ strlcpy(adap->adapter.name, "PMIC I2C Adapter",
|
||||
+ sizeof(adap->adapter.name));
|
||||
+ adap->adapter.dev.parent = &pdev->dev;
|
||||
+
|
||||
+ /* Clear and activate i2c-adapter interrupts, disable client IRQ */
|
||||
+ adap->old_irq_mask = adap->irq_mask = ~CHT_WC_EXTCHGRIRQ_ADAP_IRQMASK;
|
||||
+ ret = regmap_write(adap->regmap, CHT_WC_EXTCHGRIRQ, ~adap->irq_mask);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = regmap_write(adap->regmap, CHT_WC_EXTCHGRIRQ_MSK, adap->irq_mask);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Alloc and register client IRQ */
|
||||
+ adap->irq_domain = irq_domain_add_linear(pdev->dev.of_node, 1,
|
||||
+ &irq_domain_simple_ops, NULL);
|
||||
+ if (!adap->irq_domain)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ adap->client_irq = irq_create_mapping(adap->irq_domain, 0);
|
||||
+ if (!adap->client_irq) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto remove_irq_domain;
|
||||
+ }
|
||||
+
|
||||
+ irq_set_chip_data(adap->client_irq, adap);
|
||||
+ irq_set_chip_and_handler(adap->client_irq, &adap->irqchip,
|
||||
+ handle_simple_irq);
|
||||
+
|
||||
+ ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
|
||||
+ cht_wc_i2c_adap_thread_handler,
|
||||
+ IRQF_ONESHOT, "PMIC I2C Adapter", adap);
|
||||
+ if (ret)
|
||||
+ goto remove_irq_domain;
|
||||
+
|
||||
+ i2c_set_adapdata(&adap->adapter, adap);
|
||||
+ ret = i2c_add_adapter(&adap->adapter);
|
||||
+ if (ret)
|
||||
+ goto remove_irq_domain;
|
||||
+
|
||||
+ board_info.irq = adap->client_irq;
|
||||
+ adap->client = i2c_new_device(&adap->adapter, &board_info);
|
||||
+ if (!adap->client) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto del_adapter;
|
||||
+ }
|
||||
+
|
||||
+ platform_set_drvdata(pdev, adap);
|
||||
+ return 0;
|
||||
+
|
||||
+del_adapter:
|
||||
+ i2c_del_adapter(&adap->adapter);
|
||||
+remove_irq_domain:
|
||||
+ irq_domain_remove(adap->irq_domain);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int cht_wc_i2c_adap_i2c_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct cht_wc_i2c_adap *adap = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ i2c_unregister_device(adap->client);
|
||||
+ i2c_del_adapter(&adap->adapter);
|
||||
+ irq_domain_remove(adap->irq_domain);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_device_id cht_wc_i2c_adap_id_table[] = {
|
||||
+ { .name = "cht_wcove_ext_chgr" },
|
||||
+ {},
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(platform, cht_wc_i2c_adap_id_table);
|
||||
+
|
||||
+struct platform_driver cht_wc_i2c_adap_driver = {
|
||||
+ .probe = cht_wc_i2c_adap_i2c_probe,
|
||||
+ .remove = cht_wc_i2c_adap_i2c_remove,
|
||||
+ .driver = {
|
||||
+ .name = "cht_wcove_ext_chgr",
|
||||
+ },
|
||||
+ .id_table = cht_wc_i2c_adap_id_table,
|
||||
+};
|
||||
+module_platform_driver(cht_wc_i2c_adap_driver);
|
||||
+
|
||||
+MODULE_DESCRIPTION("Intel CHT Whiskey Cove PMIC I2C Master driver");
|
||||
+MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
|
||||
+MODULE_LICENSE("GPL");
|
||||
--
|
||||
2.13.0
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
From fd4fb1f6633b21042ff084868323e15e708fe1cd Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Sun, 1 Jan 2017 22:11:20 +0100
|
||||
Subject: [PATCH 16/16] Input: silead: Do not try to directly access the GPIO
|
||||
when using ACPI pm
|
||||
|
||||
On some x86 tablets we cannot directly access the GPIOs as they are
|
||||
claimed by the ACPI tables, so check it the i2c client is not being
|
||||
power-managed by ACPI before trying to get the power pin GPIO.
|
||||
|
||||
Note this is a workaround patch to fix this until Andy' gpiolib-ACPI
|
||||
patches which make gpiolib more strict land, once those are landed this
|
||||
patch is no longer needed.
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
drivers/input/touchscreen/silead.c | 22 ++++++++++++++++------
|
||||
1 file changed, 16 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/drivers/input/touchscreen/silead.c b/drivers/input/touchscreen/silead.c
|
||||
index c0ba40c09699..30fba3cbe277 100644
|
||||
--- a/drivers/input/touchscreen/silead.c
|
||||
+++ b/drivers/input/touchscreen/silead.c
|
||||
@@ -517,12 +518,21 @@ static int silead_ts_probe(struct i2c_client *client,
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
- /* Power GPIO pin */
|
||||
- data->gpio_power = devm_gpiod_get_optional(dev, "power", GPIOD_OUT_LOW);
|
||||
- if (IS_ERR(data->gpio_power)) {
|
||||
- if (PTR_ERR(data->gpio_power) != -EPROBE_DEFER)
|
||||
- dev_err(dev, "Shutdown GPIO request failed\n");
|
||||
- return PTR_ERR(data->gpio_power);
|
||||
+ /*
|
||||
+ * If device power is not managed by ACPI, get the power_gpio
|
||||
+ * and manage it ourselves.
|
||||
+ */
|
||||
+#ifdef CONFIG_ACPI
|
||||
+ if (!acpi_bus_power_manageable(ACPI_HANDLE(dev)))
|
||||
+#endif
|
||||
+ {
|
||||
+ data->gpio_power = devm_gpiod_get_optional(dev, "power",
|
||||
+ GPIOD_OUT_LOW);
|
||||
+ if (IS_ERR(data->gpio_power)) {
|
||||
+ if (PTR_ERR(data->gpio_power) != -EPROBE_DEFER)
|
||||
+ dev_err(dev, "Power GPIO request failed\n");
|
||||
+ return PTR_ERR(data->gpio_power);
|
||||
+ }
|
||||
}
|
||||
|
||||
error = silead_ts_setup(client);
|
||||
--
|
||||
2.13.0
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
From 596bbd8d3752b0a922b7a5a059f47607a36ecc2e Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Lutomirski <luto@kernel.org>
|
||||
Date: Wed, 24 May 2017 15:06:31 -0700
|
||||
Subject: [PATCH] nvme: Quirk APST on Intel 600P/P3100 devices
|
||||
|
||||
They have known firmware bugs. A fix is apparently in the works --
|
||||
once fixed firmware is available, someone from Intel (Hi, Keith!)
|
||||
can adjust the quirk accordingly.
|
||||
|
||||
Cc: stable@vger.kernel.org # v4.11
|
||||
Cc: Kai-Heng Feng <kai.heng.feng@canonical.com>
|
||||
Cc: Mario Limonciello <mario_limonciello@dell.com>
|
||||
Signed-off-by: Andy Lutomirski <luto@kernel.org>
|
||||
---
|
||||
drivers/nvme/host/pci.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
|
||||
index d8a1707..993d16c 100644
|
||||
--- a/drivers/nvme/host/pci.c
|
||||
+++ b/drivers/nvme/host/pci.c
|
||||
@@ -2171,6 +2171,8 @@ static const struct pci_device_id nvme_id_table[] = {
|
||||
{ PCI_VDEVICE(INTEL, 0x0a54),
|
||||
.driver_data = NVME_QUIRK_STRIPE_SIZE |
|
||||
NVME_QUIRK_DISCARD_ZEROES, },
|
||||
+ { PCI_VDEVICE(INTEL, 0xf1a5), /* Intel 600P/P3100 */
|
||||
+ .driver_data = NVME_QUIRK_NO_DEEPEST_PS },
|
||||
{ PCI_VDEVICE(INTEL, 0x5845), /* Qemu emulated controller */
|
||||
.driver_data = NVME_QUIRK_IDENTIFY_CNS, },
|
||||
{ PCI_DEVICE(0x1c58, 0x0003), /* HGST adapter */
|
||||
--
|
||||
2.7.5
|
||||
|
|
@ -1,37 +1,36 @@
|
|||
From ba3f737b8521314b62edaa7d4cc4bdc9aeefe394 Mon Sep 17 00:00:00 2001
|
||||
From 0451d4e795929a69a0fda6d960aa4b077c5bd179 Mon Sep 17 00:00:00 2001
|
||||
From: Dave Howells <dhowells@redhat.com>
|
||||
Date: Tue, 23 Oct 2012 09:30:54 -0400
|
||||
Subject: [PATCH 15/20] Add EFI signature data types
|
||||
Date: Fri, 5 May 2017 08:21:58 +0100
|
||||
Subject: [PATCH 1/4] efi: Add EFI signature data types
|
||||
|
||||
Add the data types that are used for containing hashes, keys and certificates
|
||||
for cryptographic verification.
|
||||
|
||||
Bugzilla: N/A
|
||||
Upstream-status: Fedora mustard for now
|
||||
Add the data types that are used for containing hashes, keys and
|
||||
certificates for cryptographic verification along with their corresponding
|
||||
type GUIDs.
|
||||
|
||||
Signed-off-by: David Howells <dhowells@redhat.com>
|
||||
---
|
||||
include/linux/efi.h | 17 +++++++++++++++++
|
||||
1 file changed, 17 insertions(+)
|
||||
include/linux/efi.h | 25 +++++++++++++++++++++++++
|
||||
1 file changed, 25 insertions(+)
|
||||
|
||||
diff --git a/include/linux/efi.h b/include/linux/efi.h
|
||||
index 5af91b58afae..190858d62fe3 100644
|
||||
index ec36f42..3259ad6 100644
|
||||
--- a/include/linux/efi.h
|
||||
+++ b/include/linux/efi.h
|
||||
@@ -603,6 +603,9 @@ void efi_native_runtime_setup(void);
|
||||
#define LINUX_EFI_LOADER_ENTRY_GUID EFI_GUID(0x4a67b082, 0x0a4c, 0x41cf, 0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f)
|
||||
#define LINUX_EFI_RANDOM_SEED_TABLE_GUID EFI_GUID(0x1ce1e5bc, 0x7ceb, 0x42f2, 0x81, 0xe5, 0x8a, 0xad, 0xf1, 0x80, 0xf5, 0x7b)
|
||||
|
||||
+#define EFI_CERT_SHA256_GUID EFI_GUID(0xc1c41626, 0x504c, 0x4092, 0xac, 0xa9, 0x41, 0xf9, 0x36, 0x93, 0x43, 0x28)
|
||||
+#define EFI_CERT_X509_GUID EFI_GUID(0xa5c059a1, 0x94e4, 0x4aa7, 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72)
|
||||
@@ -614,6 +614,10 @@ void efi_native_runtime_setup(void);
|
||||
#define EFI_IMAGE_SECURITY_DATABASE_GUID EFI_GUID(0xd719b2cb, 0x3d3a, 0x4596, 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f)
|
||||
#define EFI_SHIM_LOCK_GUID EFI_GUID(0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23)
|
||||
|
||||
+#define EFI_CERT_SHA256_GUID EFI_GUID(0xc1c41626, 0x504c, 0x4092, 0xac, 0xa9, 0x41, 0xf9, 0x36, 0x93, 0x43, 0x28)
|
||||
+#define EFI_CERT_X509_GUID EFI_GUID(0xa5c059a1, 0x94e4, 0x4aa7, 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72)
|
||||
+#define EFI_CERT_X509_SHA256_GUID EFI_GUID(0x3bd2a492, 0x96c0, 0x4079, 0xb4, 0x20, 0xfc, 0xf9, 0x8e, 0xf1, 0x03, 0xed)
|
||||
+
|
||||
typedef struct {
|
||||
efi_guid_t guid;
|
||||
u64 table;
|
||||
@@ -853,6 +856,20 @@ typedef struct {
|
||||
/*
|
||||
* This GUID is used to pass to the kernel proper the struct screen_info
|
||||
* structure that was populated by the stub based on the GOP protocol instance
|
||||
@@ -873,6 +877,27 @@ typedef struct {
|
||||
efi_memory_desc_t entry[0];
|
||||
} efi_memory_attributes_table_t;
|
||||
|
||||
|
||||
+typedef struct {
|
||||
+ efi_guid_t signature_owner;
|
||||
+ u8 signature_data[];
|
||||
|
@ -45,6 +44,13 @@ index 5af91b58afae..190858d62fe3 100644
|
|||
+ u8 signature_header[];
|
||||
+ /* efi_signature_data_t signatures[][] */
|
||||
+} efi_signature_list_t;
|
||||
+
|
||||
+typedef u8 efi_sha256_hash_t[32];
|
||||
+
|
||||
+typedef struct {
|
||||
+ efi_sha256_hash_t to_be_signed_hash;
|
||||
+ efi_time_t time_of_revocation;
|
||||
+} efi_cert_x509_sha256_t;
|
||||
+
|
||||
/*
|
||||
* All runtime access to EFI goes through this structure:
|
||||
|
|
|
@ -1,29 +1,38 @@
|
|||
From 822b4b3eb76ca451a416a51f0a7bfedfa5c5ea39 Mon Sep 17 00:00:00 2001
|
||||
From e4c62c12635a371e43bd17e8d33a936668264491 Mon Sep 17 00:00:00 2001
|
||||
From: Dave Howells <dhowells@redhat.com>
|
||||
Date: Tue, 23 Oct 2012 09:36:28 -0400
|
||||
Subject: [PATCH 16/20] Add an EFI signature blob parser and key loader.
|
||||
Date: Fri, 5 May 2017 08:21:58 +0100
|
||||
Subject: [PATCH 2/4] efi: Add an EFI signature blob parser
|
||||
|
||||
X.509 certificates are loaded into the specified keyring as asymmetric type
|
||||
keys.
|
||||
Add a function to parse an EFI signature blob looking for elements of
|
||||
interest. A list is made up of a series of sublists, where all the
|
||||
elements in a sublist are of the same type, but sublists can be of
|
||||
different types.
|
||||
|
||||
For each sublist encountered, the function pointed to by the
|
||||
get_handler_for_guid argument is called with the type specifier GUID and
|
||||
returns either a pointer to a function to handle elements of that type or
|
||||
NULL if the type is not of interest.
|
||||
|
||||
If the sublist is of interest, each element is passed to the handler
|
||||
function in turn.
|
||||
|
||||
[labbott@fedoraproject.org: Drop KEY_ALLOC_TRUSTED]
|
||||
Signed-off-by: David Howells <dhowells@redhat.com>
|
||||
---
|
||||
crypto/asymmetric_keys/Kconfig | 8 +++
|
||||
crypto/asymmetric_keys/Makefile | 1 +
|
||||
crypto/asymmetric_keys/efi_parser.c | 108 ++++++++++++++++++++++++++++++++++++
|
||||
include/linux/efi.h | 4 ++
|
||||
4 files changed, 121 insertions(+)
|
||||
create mode 100644 crypto/asymmetric_keys/efi_parser.c
|
||||
certs/Kconfig | 8 ++++
|
||||
certs/Makefile | 1 +
|
||||
certs/efi_parser.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
include/linux/efi.h | 9 +++++
|
||||
4 files changed, 130 insertions(+)
|
||||
create mode 100644 certs/efi_parser.c
|
||||
|
||||
diff --git a/certs/Kconfig b/certs/Kconfig
|
||||
index 6ce51ed..630ae09 100644
|
||||
--- a/certs/Kconfig
|
||||
+++ b/certs/Kconfig
|
||||
@@ -82,4 +82,12 @@ config SYSTEM_BLACKLIST_HASH_LIST
|
||||
wrapper to incorporate the list into the kernel. Each <hash> should
|
||||
be a string of hex digits.
|
||||
|
||||
diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig
|
||||
index 331f6baf2df8..5f9002d3192e 100644
|
||||
--- a/crypto/asymmetric_keys/Kconfig
|
||||
+++ b/crypto/asymmetric_keys/Kconfig
|
||||
@@ -61,4 +61,12 @@ config SIGNED_PE_FILE_VERIFICATION
|
||||
This option provides support for verifying the signature(s) on a
|
||||
signed PE binary.
|
||||
|
||||
+config EFI_SIGNATURE_LIST_PARSER
|
||||
+ bool "EFI signature list parser"
|
||||
+ depends on EFI
|
||||
|
@ -32,28 +41,28 @@ index 331f6baf2df8..5f9002d3192e 100644
|
|||
+ This option provides support for parsing EFI signature lists for
|
||||
+ X.509 certificates and turning them into keys.
|
||||
+
|
||||
endif # ASYMMETRIC_KEY_TYPE
|
||||
diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile
|
||||
index 6516855bec18..c099fe15ed6d 100644
|
||||
--- a/crypto/asymmetric_keys/Makefile
|
||||
+++ b/crypto/asymmetric_keys/Makefile
|
||||
@@ -10,6 +10,7 @@ asymmetric_keys-y := \
|
||||
signature.o
|
||||
|
||||
obj-$(CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += public_key.o
|
||||
endmenu
|
||||
diff --git a/certs/Makefile b/certs/Makefile
|
||||
index 4119bb3..738151a 100644
|
||||
--- a/certs/Makefile
|
||||
+++ b/certs/Makefile
|
||||
@@ -9,6 +9,7 @@ obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist_hashes.o
|
||||
else
|
||||
obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist_nohashes.o
|
||||
endif
|
||||
+obj-$(CONFIG_EFI_SIGNATURE_LIST_PARSER) += efi_parser.o
|
||||
|
||||
#
|
||||
# X.509 Certificate handling
|
||||
diff --git a/crypto/asymmetric_keys/efi_parser.c b/crypto/asymmetric_keys/efi_parser.c
|
||||
|
||||
ifeq ($(CONFIG_SYSTEM_TRUSTED_KEYRING),y)
|
||||
|
||||
diff --git a/certs/efi_parser.c b/certs/efi_parser.c
|
||||
new file mode 100644
|
||||
index 000000000000..636feb18b733
|
||||
index 0000000..4e396f9
|
||||
--- /dev/null
|
||||
+++ b/crypto/asymmetric_keys/efi_parser.c
|
||||
@@ -0,0 +1,108 @@
|
||||
+++ b/certs/efi_parser.c
|
||||
@@ -0,0 +1,112 @@
|
||||
+/* EFI signature/key/certificate list parser
|
||||
+ *
|
||||
+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
|
||||
+ * Copyright (C) 2012, 2016 Red Hat, Inc. All Rights Reserved.
|
||||
+ * Written by David Howells (dhowells@redhat.com)
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or
|
||||
|
@ -67,27 +76,44 @@ index 000000000000..636feb18b733
|
|||
+#include <linux/printk.h>
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/efi.h>
|
||||
+#include <keys/asymmetric-type.h>
|
||||
+
|
||||
+static __initdata efi_guid_t efi_cert_x509_guid = EFI_CERT_X509_GUID;
|
||||
+
|
||||
+/**
|
||||
+ * parse_efi_signature_list - Parse an EFI signature list for certificates
|
||||
+ * @source: The source of the key
|
||||
+ * @data: The data blob to parse
|
||||
+ * @size: The size of the data blob
|
||||
+ * @keyring: The keyring to add extracted keys to
|
||||
+ * @get_handler_for_guid: Get the handler func for the sig type (or NULL)
|
||||
+ *
|
||||
+ * Parse an EFI signature list looking for elements of interest. A list is
|
||||
+ * made up of a series of sublists, where all the elements in a sublist are of
|
||||
+ * the same type, but sublists can be of different types.
|
||||
+ *
|
||||
+ * For each sublist encountered, the @get_handler_for_guid function is called
|
||||
+ * with the type specifier GUID and returns either a pointer to a function to
|
||||
+ * handle elements of that type or NULL if the type is not of interest.
|
||||
+ *
|
||||
+ * If the sublist is of interest, each element is passed to the handler
|
||||
+ * function in turn.
|
||||
+ *
|
||||
+ * Error EBADMSG is returned if the list doesn't parse correctly and 0 is
|
||||
+ * returned if the list was parsed correctly. No error can be returned from
|
||||
+ * the @get_handler_for_guid function or the element handler function it
|
||||
+ * returns.
|
||||
+ */
|
||||
+int __init parse_efi_signature_list(const void *data, size_t size, struct key *keyring)
|
||||
+int __init parse_efi_signature_list(
|
||||
+ const char *source,
|
||||
+ const void *data, size_t size,
|
||||
+ efi_element_handler_t (*get_handler_for_guid)(const efi_guid_t *))
|
||||
+{
|
||||
+ efi_element_handler_t handler;
|
||||
+ unsigned offs = 0;
|
||||
+ size_t lsize, esize, hsize, elsize;
|
||||
+
|
||||
+ pr_devel("-->%s(,%zu)\n", __func__, size);
|
||||
+
|
||||
+ while (size > 0) {
|
||||
+ efi_signature_list_t list;
|
||||
+ const efi_signature_data_t *elem;
|
||||
+ key_ref_t key;
|
||||
+ efi_signature_list_t list;
|
||||
+ size_t lsize, esize, hsize, elsize;
|
||||
+
|
||||
+ if (size < sizeof(list))
|
||||
+ return -EBADMSG;
|
||||
|
@ -108,6 +134,7 @@ index 000000000000..636feb18b733
|
|||
+ __func__, offs);
|
||||
+ return -EBADMSG;
|
||||
+ }
|
||||
+
|
||||
+ if (lsize < sizeof(list) ||
|
||||
+ lsize - sizeof(list) < hsize ||
|
||||
+ esize < sizeof(*elem) ||
|
||||
|
@ -117,7 +144,8 @@ index 000000000000..636feb18b733
|
|||
+ return -EBADMSG;
|
||||
+ }
|
||||
+
|
||||
+ if (efi_guidcmp(list.signature_type, efi_cert_x509_guid) != 0) {
|
||||
+ handler = get_handler_for_guid(&list.signature_type);
|
||||
+ if (!handler) {
|
||||
+ data += lsize;
|
||||
+ size -= lsize;
|
||||
+ offs += lsize;
|
||||
|
@ -132,24 +160,9 @@ index 000000000000..636feb18b733
|
|||
+ elem = data;
|
||||
+
|
||||
+ pr_devel("ELEM[%04x]\n", offs);
|
||||
+
|
||||
+ key = key_create_or_update(
|
||||
+ make_key_ref(keyring, 1),
|
||||
+ "asymmetric",
|
||||
+ NULL,
|
||||
+ handler(source,
|
||||
+ &elem->signature_data,
|
||||
+ esize - sizeof(*elem),
|
||||
+ (KEY_POS_ALL & ~KEY_POS_SETATTR) |
|
||||
+ KEY_USR_VIEW,
|
||||
+ KEY_ALLOC_NOT_IN_QUOTA);
|
||||
+
|
||||
+ if (IS_ERR(key))
|
||||
+ pr_err("Problem loading in-kernel X.509 certificate (%ld)\n",
|
||||
+ PTR_ERR(key));
|
||||
+ else
|
||||
+ pr_notice("Loaded cert '%s' linked to '%s'\n",
|
||||
+ key_ref_to_ptr(key)->description,
|
||||
+ keyring->description);
|
||||
+ esize - sizeof(*elem));
|
||||
+
|
||||
+ data += esize;
|
||||
+ size -= esize;
|
||||
|
@ -160,16 +173,21 @@ index 000000000000..636feb18b733
|
|||
+ return 0;
|
||||
+}
|
||||
diff --git a/include/linux/efi.h b/include/linux/efi.h
|
||||
index 190858d62fe3..668aa1244885 100644
|
||||
index 3259ad6..08024c6 100644
|
||||
--- a/include/linux/efi.h
|
||||
+++ b/include/linux/efi.h
|
||||
@@ -1025,6 +1025,10 @@ extern int efi_memattr_apply_permissions(struct mm_struct *mm,
|
||||
@@ -1055,6 +1055,15 @@ extern int efi_memattr_apply_permissions(struct mm_struct *mm,
|
||||
char * __init efi_md_typeattr_format(char *buf, size_t size,
|
||||
const efi_memory_desc_t *md);
|
||||
|
||||
+struct key;
|
||||
+extern int __init parse_efi_signature_list(const void *data, size_t size,
|
||||
+ struct key *keyring);
|
||||
|
||||
+
|
||||
+typedef void (*efi_element_handler_t)(const char *source,
|
||||
+ const void *element_data,
|
||||
+ size_t element_size);
|
||||
+extern int __init parse_efi_signature_list(
|
||||
+ const char *source,
|
||||
+ const void *data, size_t size,
|
||||
+ efi_element_handler_t (*get_handler_for_guid)(const efi_guid_t *));
|
||||
+
|
||||
/**
|
||||
* efi_range_is_wc - check the WC bit on an address range
|
||||
|
|
1080
AllWinner-h3.patch
1080
AllWinner-h3.patch
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,48 @@
|
|||
From 70ac67826602edf8c0ccb413e5ba7eacf597a60c Mon Sep 17 00:00:00 2001
|
||||
From: Seunghun Han <kkamagui@gmail.com>
|
||||
Date: Tue, 18 Jul 2017 20:03:51 +0900
|
||||
Subject: x86/acpi: Prevent out of bound access caused by broken ACPI tables
|
||||
|
||||
The bus_irq argument of mp_override_legacy_irq() is used as the index into
|
||||
the isa_irq_to_gsi[] array. The bus_irq argument originates from
|
||||
ACPI_MADT_TYPE_IO_APIC and ACPI_MADT_TYPE_INTERRUPT items in the ACPI
|
||||
tables, but is nowhere sanity checked.
|
||||
|
||||
That allows broken or malicious ACPI tables to overwrite memory, which
|
||||
might cause malfunction, panic or arbitrary code execution.
|
||||
|
||||
Add a sanity check and emit a warning when that triggers.
|
||||
|
||||
[ tglx: Added warning and rewrote changelog ]
|
||||
|
||||
Signed-off-by: Seunghun Han <kkamagui@gmail.com>
|
||||
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
|
||||
Cc: security@kernel.org
|
||||
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
|
||||
Cc: stable@vger.kernel.org
|
||||
---
|
||||
arch/x86/kernel/acpi/boot.c | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
|
||||
index 6bb6806..7491e73 100644
|
||||
--- a/arch/x86/kernel/acpi/boot.c
|
||||
+++ b/arch/x86/kernel/acpi/boot.c
|
||||
@@ -347,6 +347,14 @@ static void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger,
|
||||
struct mpc_intsrc mp_irq;
|
||||
|
||||
/*
|
||||
+ * Check bus_irq boundary.
|
||||
+ */
|
||||
+ if (bus_irq >= NR_IRQS_LEGACY) {
|
||||
+ pr_warn("Invalid bus_irq %u for legacy override\n", bus_irq);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
* Convert 'gsi' to 'ioapic.pin'.
|
||||
*/
|
||||
ioapic = mp_find_ioapic(gsi);
|
||||
--
|
||||
cgit v1.1
|
||||
|
|
@ -1,180 +0,0 @@
|
|||
From: "J. Bruce Fields" <bfields@redhat.com>
|
||||
Date: 2017-04-14 15:04:40
|
||||
Subject: [PATCH] nfsd: check for oversized NFSv2/v3 arguments
|
||||
|
||||
A client can append random data to the end of an NFSv2 or NFSv3 RPC call
|
||||
without our complaining; we'll just stop parsing at the end of the
|
||||
expected data and ignore the rest.
|
||||
|
||||
Encoded arguments and replies are stored together in an array of pages,
|
||||
and if a call is too large it could leave inadequate space for the
|
||||
reply. This is normally OK because NFS RPC's typically have either
|
||||
short arguments and long replies (like READ) or long arguments and short
|
||||
replies (like WRITE). But a client that sends an incorrectly long reply
|
||||
can violate those assumptions. This was observed to cause crashes.
|
||||
|
||||
So, insist that the argument not be any longer than we expect.
|
||||
|
||||
Also, several operations increment rq_next_page in the decode routine
|
||||
before checking the argument size, which can leave rq_next_page pointing
|
||||
well past the end of the page array, causing trouble later in
|
||||
svc_free_pages.
|
||||
|
||||
As followup we may also want to rewrite the encoding routines to check
|
||||
more carefully that they aren't running off the end of the page array.
|
||||
|
||||
Reported-by: Tuomas Haanpää <thaan@synopsys.com>
|
||||
Reported-by: Ari Kauppi <ari@synopsys.com>
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
|
||||
---
|
||||
fs/nfsd/nfs3xdr.c | 23 +++++++++++++++++------
|
||||
fs/nfsd/nfsxdr.c | 13 ++++++++++---
|
||||
include/linux/sunrpc/svc.h | 3 +--
|
||||
3 files changed, 28 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
|
||||
index dba2ff8eaa68..be66bcadfaea 100644
|
||||
--- a/fs/nfsd/nfs3xdr.c
|
||||
+++ b/fs/nfsd/nfs3xdr.c
|
||||
@@ -334,8 +334,11 @@ nfs3svc_decode_readargs(struct svc_rqst *rqstp, __be32 *p,
|
||||
if (!p)
|
||||
return 0;
|
||||
p = xdr_decode_hyper(p, &args->offset);
|
||||
-
|
||||
args->count = ntohl(*p++);
|
||||
+
|
||||
+ if (!xdr_argsize_check(rqstp, p))
|
||||
+ return 0;
|
||||
+
|
||||
len = min(args->count, max_blocksize);
|
||||
|
||||
/* set up the kvec */
|
||||
@@ -349,7 +352,7 @@ nfs3svc_decode_readargs(struct svc_rqst *rqstp, __be32 *p,
|
||||
v++;
|
||||
}
|
||||
args->vlen = v;
|
||||
- return xdr_argsize_check(rqstp, p);
|
||||
+ return 1;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -536,9 +539,11 @@ nfs3svc_decode_readlinkargs(struct svc_rqst *rqstp, __be32 *p,
|
||||
p = decode_fh(p, &args->fh);
|
||||
if (!p)
|
||||
return 0;
|
||||
+ if (!xdr_argsize_check(rqstp, p))
|
||||
+ return 0;
|
||||
args->buffer = page_address(*(rqstp->rq_next_page++));
|
||||
|
||||
- return xdr_argsize_check(rqstp, p);
|
||||
+ return 1;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -564,10 +569,14 @@ nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p,
|
||||
args->verf = p; p += 2;
|
||||
args->dircount = ~0;
|
||||
args->count = ntohl(*p++);
|
||||
+
|
||||
+ if (!xdr_argsize_check(rqstp, p))
|
||||
+ return 0;
|
||||
+
|
||||
args->count = min_t(u32, args->count, PAGE_SIZE);
|
||||
args->buffer = page_address(*(rqstp->rq_next_page++));
|
||||
|
||||
- return xdr_argsize_check(rqstp, p);
|
||||
+ return 1;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -585,6 +594,9 @@ nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, __be32 *p,
|
||||
args->dircount = ntohl(*p++);
|
||||
args->count = ntohl(*p++);
|
||||
|
||||
+ if (!xdr_argsize_check(rqstp, p))
|
||||
+ return 0;
|
||||
+
|
||||
len = args->count = min(args->count, max_blocksize);
|
||||
while (len > 0) {
|
||||
struct page *p = *(rqstp->rq_next_page++);
|
||||
@@ -592,8 +604,7 @@ nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, __be32 *p,
|
||||
args->buffer = page_address(p);
|
||||
len -= PAGE_SIZE;
|
||||
}
|
||||
-
|
||||
- return xdr_argsize_check(rqstp, p);
|
||||
+ return 1;
|
||||
}
|
||||
|
||||
int
|
||||
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
|
||||
index 41b468a6a90f..79268369f7b3 100644
|
||||
--- a/fs/nfsd/nfsxdr.c
|
||||
+++ b/fs/nfsd/nfsxdr.c
|
||||
@@ -257,6 +257,9 @@ nfssvc_decode_readargs(struct svc_rqst *rqstp, __be32 *p,
|
||||
len = args->count = ntohl(*p++);
|
||||
p++; /* totalcount - unused */
|
||||
|
||||
+ if (!xdr_argsize_check(rqstp, p))
|
||||
+ return 0;
|
||||
+
|
||||
len = min_t(unsigned int, len, NFSSVC_MAXBLKSIZE_V2);
|
||||
|
||||
/* set up somewhere to store response.
|
||||
@@ -272,7 +275,7 @@ nfssvc_decode_readargs(struct svc_rqst *rqstp, __be32 *p,
|
||||
v++;
|
||||
}
|
||||
args->vlen = v;
|
||||
- return xdr_argsize_check(rqstp, p);
|
||||
+ return 1;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -360,9 +363,11 @@ nfssvc_decode_readlinkargs(struct svc_rqst *rqstp, __be32 *p, struct nfsd_readli
|
||||
p = decode_fh(p, &args->fh);
|
||||
if (!p)
|
||||
return 0;
|
||||
+ if (!xdr_argsize_check(rqstp, p))
|
||||
+ return 0;
|
||||
args->buffer = page_address(*(rqstp->rq_next_page++));
|
||||
|
||||
- return xdr_argsize_check(rqstp, p);
|
||||
+ return 1;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -400,9 +405,11 @@ nfssvc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p,
|
||||
args->cookie = ntohl(*p++);
|
||||
args->count = ntohl(*p++);
|
||||
args->count = min_t(u32, args->count, PAGE_SIZE);
|
||||
+ if (!xdr_argsize_check(rqstp, p))
|
||||
+ return 0;
|
||||
args->buffer = page_address(*(rqstp->rq_next_page++));
|
||||
|
||||
- return xdr_argsize_check(rqstp, p);
|
||||
+ return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
|
||||
index e770abeed32d..6ef19cf658b4 100644
|
||||
--- a/include/linux/sunrpc/svc.h
|
||||
+++ b/include/linux/sunrpc/svc.h
|
||||
@@ -336,8 +336,7 @@ xdr_argsize_check(struct svc_rqst *rqstp, __be32 *p)
|
||||
{
|
||||
char *cp = (char *)p;
|
||||
struct kvec *vec = &rqstp->rq_arg.head[0];
|
||||
- return cp >= (char*)vec->iov_base
|
||||
- && cp <= (char*)vec->iov_base + vec->iov_len;
|
||||
+ return cp == (char *)vec->iov_base + vec->iov_len;
|
||||
}
|
||||
|
||||
static inline int
|
||||
--
|
||||
2.9.3
|
||||
|
||||
--
|
||||
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
|
||||
the body of a message to majordomo@vger.kernel.org
|
||||
More majordomo info at http://vger.kernel.org/majordomo-info.html
|
|
@ -0,0 +1,74 @@
|
|||
From patchwork Sun Jul 23 01:15:09 2017
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
MIME-Version: 1.0
|
||||
Content-Transfer-Encoding: 7bit
|
||||
Subject: HID: rmi: Make sure the HID device is opened on resume
|
||||
From: Lyude <lyude@redhat.com>
|
||||
X-Patchwork-Id: 9858267
|
||||
Message-Id: <20170723011509.23651-1-lyude@redhat.com>
|
||||
To: linux-input@vger.kernel.org
|
||||
Cc: Lyude <lyude@redhat.com>, Andrew Duggan <aduggan@synaptics.com>,
|
||||
stable@vger.kernel.org, Jiri Kosina <jikos@kernel.org>,
|
||||
Benjamin Tissoires <benjamin.tissoires@redhat.com>,
|
||||
linux-kernel@vger.kernel.org
|
||||
Date: Sat, 22 Jul 2017 21:15:09 -0400
|
||||
|
||||
So it looks like that suspend/resume has actually always been broken on
|
||||
hid-rmi. The fact it worked was a rather silly coincidence that was
|
||||
relying on the HID device to already be opened upon resume. This means
|
||||
that so long as anything was reading the /dev/input/eventX node for for
|
||||
an RMI device, it would suspend and resume correctly. As well, if
|
||||
nothing happened to be keeping the HID device away it would shut off,
|
||||
then the RMI driver would get confused on resume when it stopped
|
||||
responding and explode.
|
||||
|
||||
So, call hid_hw_open() in rmi_post_resume() so we make sure that the
|
||||
device is alive before we try talking to it.
|
||||
|
||||
This fixes RMI device suspend/resume over HID.
|
||||
|
||||
Signed-off-by: Lyude <lyude@redhat.com>
|
||||
Cc: Andrew Duggan <aduggan@synaptics.com>
|
||||
Cc: stable@vger.kernel.org
|
||||
---
|
||||
drivers/hid/hid-rmi.c | 15 +++++++++++----
|
||||
1 file changed, 11 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c
|
||||
index 5b40c2614599..e7d124f9a27f 100644
|
||||
--- a/drivers/hid/hid-rmi.c
|
||||
+++ b/drivers/hid/hid-rmi.c
|
||||
@@ -431,22 +431,29 @@ static int rmi_post_resume(struct hid_device *hdev)
|
||||
{
|
||||
struct rmi_data *data = hid_get_drvdata(hdev);
|
||||
struct rmi_device *rmi_dev = data->xport.rmi_dev;
|
||||
- int ret;
|
||||
+ int ret = 0;
|
||||
|
||||
if (!(data->device_flags & RMI_DEVICE))
|
||||
return 0;
|
||||
|
||||
- ret = rmi_reset_attn_mode(hdev);
|
||||
+ /* Make sure the HID device is ready to receive events */
|
||||
+ ret = hid_hw_open(hdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
+ ret = rmi_reset_attn_mode(hdev);
|
||||
+ if (ret)
|
||||
+ goto out;
|
||||
+
|
||||
ret = rmi_driver_resume(rmi_dev, false);
|
||||
if (ret) {
|
||||
hid_warn(hdev, "Failed to resume device: %d\n", ret);
|
||||
- return ret;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
- return 0;
|
||||
+out:
|
||||
+ hid_hw_close(hdev);
|
||||
+ return ret;
|
||||
}
|
||||
#endif /* CONFIG_PM */
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
From fb2ac204a70da565de9ef9a9d6d69a40c2d59727 Mon Sep 17 00:00:00 2001
|
||||
From: David Howells <dhowells@redhat.com>
|
||||
Date: Fri, 5 May 2017 08:21:56 +0100
|
||||
Subject: [PATCH] KEYS: Allow unrestricted boot-time addition of keys to
|
||||
secondary keyring
|
||||
|
||||
Allow keys to be added to the system secondary certificates keyring during
|
||||
kernel initialisation in an unrestricted fashion. Such keys are implicitly
|
||||
trusted and don't have their trust chains checked on link.
|
||||
|
||||
This allows keys in the UEFI database to be added in secure boot mode for
|
||||
the purposes of module signing.
|
||||
|
||||
Signed-off-by: David Howells <dhowells@redhat.com>
|
||||
---
|
||||
certs/internal.h | 18 ++++++++++++++++++
|
||||
certs/system_keyring.c | 33 +++++++++++++++++++++++++++++++++
|
||||
2 files changed, 51 insertions(+)
|
||||
create mode 100644 certs/internal.h
|
||||
|
||||
diff --git a/certs/internal.h b/certs/internal.h
|
||||
new file mode 100644
|
||||
index 0000000..5dcbefb
|
||||
--- /dev/null
|
||||
+++ b/certs/internal.h
|
||||
@@ -0,0 +1,18 @@
|
||||
+/* Internal definitions
|
||||
+ *
|
||||
+ * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved.
|
||||
+ * Written by David Howells (dhowells@redhat.com)
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU General Public Licence
|
||||
+ * as published by the Free Software Foundation; either version
|
||||
+ * 2 of the Licence, or (at your option) any later version.
|
||||
+ */
|
||||
+
|
||||
+/*
|
||||
+ * system_keyring.c
|
||||
+ */
|
||||
+#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
|
||||
+extern void __init add_trusted_secondary_key(const char *source,
|
||||
+ const void *data, size_t len);
|
||||
+#endif
|
||||
diff --git a/certs/system_keyring.c b/certs/system_keyring.c
|
||||
index 6251d1b..5ac8ba6 100644
|
||||
--- a/certs/system_keyring.c
|
||||
+++ b/certs/system_keyring.c
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <keys/asymmetric-type.h>
|
||||
#include <keys/system_keyring.h>
|
||||
#include <crypto/pkcs7.h>
|
||||
+#include "internal.h"
|
||||
|
||||
static struct key *builtin_trusted_keys;
|
||||
#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
|
||||
@@ -265,3 +266,35 @@ int verify_pkcs7_signature(const void *data, size_t len,
|
||||
EXPORT_SYMBOL_GPL(verify_pkcs7_signature);
|
||||
|
||||
#endif /* CONFIG_SYSTEM_DATA_VERIFICATION */
|
||||
+
|
||||
+#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
|
||||
+/**
|
||||
+ * add_trusted_secondary_key - Add to secondary keyring with no validation
|
||||
+ * @source: Source of key
|
||||
+ * @data: The blob holding the key
|
||||
+ * @len: The length of the data blob
|
||||
+ *
|
||||
+ * Add a key to the secondary keyring without checking its trust chain. This
|
||||
+ * is available only during kernel initialisation.
|
||||
+ */
|
||||
+void __init add_trusted_secondary_key(const char *source,
|
||||
+ const void *data, size_t len)
|
||||
+{
|
||||
+ key_ref_t key;
|
||||
+
|
||||
+ key = key_create_or_update(make_key_ref(secondary_trusted_keys, 1),
|
||||
+ "asymmetric",
|
||||
+ NULL, data, len,
|
||||
+ (KEY_POS_ALL & ~KEY_POS_SETATTR) |
|
||||
+ KEY_USR_VIEW,
|
||||
+ KEY_ALLOC_NOT_IN_QUOTA |
|
||||
+ KEY_ALLOC_BYPASS_RESTRICTION);
|
||||
+
|
||||
+ if (IS_ERR(key))
|
||||
+ pr_err("Problem loading %s X.509 certificate (%ld)\n",
|
||||
+ source, PTR_ERR(key));
|
||||
+ else
|
||||
+ pr_notice("Loaded %s cert '%s' linked to secondary sys keyring\n",
|
||||
+ source, key_ref_to_ptr(key)->description);
|
||||
+}
|
||||
+#endif /* CONFIG_SECONDARY_TRUSTED_KEYRING */
|
||||
--
|
||||
2.9.3
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
From 71db1b222ecdf6cb4356f6f1e2bd45cd2f0e85e1 Mon Sep 17 00:00:00 2001
|
||||
From: Laura Abbott <labbott@redhat.com>
|
||||
Date: Tue, 18 Oct 2016 13:58:44 -0700
|
||||
Subject: [PATCH] MODSIGN: Don't try secure boot if EFI runtime is disabled
|
||||
|
||||
Secure boot depends on having EFI runtime variable access. The code
|
||||
does not handle a lack of runtime variables gracefully. Add a check
|
||||
to just bail out of EFI runtime is disabled.
|
||||
|
||||
Signed-off-by: Laura Abbott <labbott@redhat.com>
|
||||
---
|
||||
kernel/modsign_uefi.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/kernel/modsign_uefi.c b/kernel/modsign_uefi.c
|
||||
index a41da14..2bdaf76 100644
|
||||
--- a/kernel/modsign_uefi.c
|
||||
+++ b/kernel/modsign_uefi.c
|
||||
@@ -71,6 +71,10 @@ static int __init load_uefi_certs(void)
|
||||
if (!efi_enabled(EFI_SECURE_BOOT))
|
||||
return 0;
|
||||
|
||||
+ /* Things blow up if efi runtime is disabled */
|
||||
+ if (efi_runtime_disabled())
|
||||
+ return 0;
|
||||
+
|
||||
keyring = get_system_keyring();
|
||||
if (!keyring) {
|
||||
pr_err("MODSIGN: Couldn't get system keyring\n");
|
||||
--
|
||||
2.7.4
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
From 8a4535bcfe24d317be675e53cdc8c61d22fdc7f3 Mon Sep 17 00:00:00 2001
|
||||
From 90dc66270b02981b19a085c6a9184e3452b7b3e8 Mon Sep 17 00:00:00 2001
|
||||
From: Josh Boyer <jwboyer@fedoraproject.org>
|
||||
Date: Fri, 26 Oct 2012 12:42:16 -0400
|
||||
Subject: [PATCH 18/20] MODSIGN: Import certificates from UEFI Secure Boot
|
||||
Date: Fri, 5 May 2017 08:21:59 +0100
|
||||
Subject: [PATCH 3/4] MODSIGN: Import certificates from UEFI Secure Boot
|
||||
|
||||
Secure Boot stores a list of allowed certificates in the 'db' variable.
|
||||
This imports those certificates into the system trusted keyring. This
|
||||
|
@ -11,104 +11,68 @@ variable, a user can allow a module signed with that certificate to
|
|||
load. The shim UEFI bootloader has a similar certificate list stored
|
||||
in the 'MokListRT' variable. We import those as well.
|
||||
|
||||
In the opposite case, Secure Boot maintains a list of disallowed
|
||||
certificates in the 'dbx' variable. We load those certificates into
|
||||
the newly introduced system blacklist keyring and forbid any module
|
||||
signed with those from loading.
|
||||
Secure Boot also maintains a list of disallowed certificates in the 'dbx'
|
||||
variable. We load those certificates into the newly introduced system
|
||||
blacklist keyring and forbid any module signed with those from loading and
|
||||
forbid the use within the kernel of any key with a matching hash.
|
||||
|
||||
This facility is enabled by setting CONFIG_LOAD_UEFI_KEYS.
|
||||
|
||||
Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org>
|
||||
Signed-off-by: David Howells <dhowells@redhat.com>
|
||||
---
|
||||
certs/system_keyring.c | 13 ++++++
|
||||
include/keys/system_keyring.h | 1 +
|
||||
init/Kconfig | 9 ++++
|
||||
kernel/Makefile | 3 ++
|
||||
kernel/modsign_uefi.c | 99 +++++++++++++++++++++++++++++++++++++++++++
|
||||
5 files changed, 125 insertions(+)
|
||||
create mode 100644 kernel/modsign_uefi.c
|
||||
certs/Kconfig | 16 ++++++
|
||||
certs/Makefile | 4 ++
|
||||
certs/load_uefi.c | 168 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 188 insertions(+)
|
||||
create mode 100644 certs/load_uefi.c
|
||||
|
||||
diff --git a/certs/system_keyring.c b/certs/system_keyring.c
|
||||
index 787eeead2f57..4d9123ed5c07 100644
|
||||
--- a/certs/system_keyring.c
|
||||
+++ b/certs/system_keyring.c
|
||||
@@ -30,6 +30,19 @@ extern __initconst const u8 system_certificate_list[];
|
||||
extern __initconst const unsigned long system_certificate_list_size;
|
||||
|
||||
/**
|
||||
+ * get_system_keyring - Return a pointer to the system keyring
|
||||
+ *
|
||||
+ */
|
||||
+struct key *get_system_keyring(void)
|
||||
+{
|
||||
+ struct key *system_keyring = NULL;
|
||||
+
|
||||
+ system_keyring = builtin_trusted_keys;
|
||||
+ return system_keyring;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(get_system_keyring);
|
||||
+
|
||||
+/**
|
||||
* restrict_link_to_builtin_trusted - Restrict keyring addition by built in CA
|
||||
*
|
||||
* Restrict the addition of keys into a keyring based on the key-to-be-added
|
||||
diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h
|
||||
index 5bc291a3d261..56ff5715ab67 100644
|
||||
--- a/include/keys/system_keyring.h
|
||||
+++ b/include/keys/system_keyring.h
|
||||
@@ -36,6 +36,7 @@ extern int restrict_link_by_builtin_and_secondary_trusted(
|
||||
#ifdef CONFIG_SYSTEM_BLACKLIST_KEYRING
|
||||
extern struct key *system_blacklist_keyring;
|
||||
#endif
|
||||
+extern struct key *get_system_keyring(void);
|
||||
|
||||
#ifdef CONFIG_IMA_BLACKLIST_KEYRING
|
||||
extern struct key *ima_blacklist_keyring;
|
||||
diff --git a/init/Kconfig b/init/Kconfig
|
||||
index 461ad575a608..93646fd7b1c8 100644
|
||||
--- a/init/Kconfig
|
||||
+++ b/init/Kconfig
|
||||
@@ -2009,6 +2009,15 @@ config MODULE_SIG_ALL
|
||||
comment "Do not forget to sign required modules with scripts/sign-file"
|
||||
depends on MODULE_SIG_FORCE && !MODULE_SIG_ALL
|
||||
|
||||
+config MODULE_SIG_UEFI
|
||||
+ bool "Allow modules signed with certs stored in UEFI"
|
||||
+ depends on MODULE_SIG && SYSTEM_BLACKLIST_KEYRING && EFI
|
||||
+ select EFI_SIGNATURE_LIST_PARSER
|
||||
diff --git a/certs/Kconfig b/certs/Kconfig
|
||||
index 630ae09..edf9f75 100644
|
||||
--- a/certs/Kconfig
|
||||
+++ b/certs/Kconfig
|
||||
@@ -90,4 +90,20 @@ config EFI_SIGNATURE_LIST_PARSER
|
||||
This option provides support for parsing EFI signature lists for
|
||||
X.509 certificates and turning them into keys.
|
||||
|
||||
+config LOAD_UEFI_KEYS
|
||||
+ bool "Load certs and blacklist from UEFI db for module checking"
|
||||
+ depends on SYSTEM_BLACKLIST_KEYRING
|
||||
+ depends on SECONDARY_TRUSTED_KEYRING
|
||||
+ depends on EFI
|
||||
+ depends on EFI_SIGNATURE_LIST_PARSER
|
||||
+ help
|
||||
+ This will import certificates stored in UEFI and allow modules
|
||||
+ signed with those to be loaded. It will also disallow loading
|
||||
+ of modules stored in the UEFI dbx variable.
|
||||
+ If the kernel is booted in secure boot mode, this option will cause
|
||||
+ the kernel to load the certificates from the UEFI db and MokListRT
|
||||
+ into the secondary trusted keyring. It will also load any X.509
|
||||
+ SHA256 hashes in the dbx list into the blacklist.
|
||||
+
|
||||
choice
|
||||
prompt "Which hash algorithm should modules be signed with?"
|
||||
depends on MODULE_SIG
|
||||
diff --git a/kernel/Makefile b/kernel/Makefile
|
||||
index eb26e12c6c2a..e0c2268cb97e 100644
|
||||
--- a/kernel/Makefile
|
||||
+++ b/kernel/Makefile
|
||||
@@ -57,6 +57,7 @@ endif
|
||||
obj-$(CONFIG_UID16) += uid16.o
|
||||
obj-$(CONFIG_MODULES) += module.o
|
||||
obj-$(CONFIG_MODULE_SIG) += module_signing.o
|
||||
+obj-$(CONFIG_MODULE_SIG_UEFI) += modsign_uefi.o
|
||||
obj-$(CONFIG_KALLSYMS) += kallsyms.o
|
||||
obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
|
||||
obj-$(CONFIG_KEXEC_CORE) += kexec_core.o
|
||||
@@ -113,6 +114,8 @@ obj-$(CONFIG_MEMBARRIER) += membarrier.o
|
||||
|
||||
obj-$(CONFIG_HAS_IOMEM) += memremap.o
|
||||
|
||||
+$(obj)/modsign_uefi.o: KBUILD_CFLAGS += -fshort-wchar
|
||||
+ The effect of this is that, if the kernel is booted in secure boot
|
||||
+ mode, modules signed with UEFI-stored keys will be permitted to be
|
||||
+ loaded and keys that match the blacklist will be rejected.
|
||||
+
|
||||
$(obj)/configs.o: $(obj)/config_data.h
|
||||
|
||||
targets += config_data.gz
|
||||
diff --git a/kernel/modsign_uefi.c b/kernel/modsign_uefi.c
|
||||
endmenu
|
||||
diff --git a/certs/Makefile b/certs/Makefile
|
||||
index 738151a..a5e057a 100644
|
||||
--- a/certs/Makefile
|
||||
+++ b/certs/Makefile
|
||||
@@ -11,6 +11,10 @@ obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist_nohashes.o
|
||||
endif
|
||||
obj-$(CONFIG_EFI_SIGNATURE_LIST_PARSER) += efi_parser.o
|
||||
|
||||
+obj-$(CONFIG_LOAD_UEFI_KEYS) += load_uefi.o
|
||||
+$(obj)/load_uefi.o: KBUILD_CFLAGS += -fshort-wchar
|
||||
+
|
||||
+
|
||||
ifeq ($(CONFIG_SYSTEM_TRUSTED_KEYRING),y)
|
||||
|
||||
$(eval $(call config_filename,SYSTEM_TRUSTED_KEYS))
|
||||
diff --git a/certs/load_uefi.c b/certs/load_uefi.c
|
||||
new file mode 100644
|
||||
index 000000000000..fe4a6f2bf10a
|
||||
index 0000000..b44e464
|
||||
--- /dev/null
|
||||
+++ b/kernel/modsign_uefi.c
|
||||
@@ -0,0 +1,99 @@
|
||||
+++ b/certs/load_uefi.c
|
||||
@@ -0,0 +1,168 @@
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/sched.h>
|
||||
+#include <linux/cred.h>
|
||||
|
@ -117,14 +81,22 @@ index 000000000000..fe4a6f2bf10a
|
|||
+#include <linux/slab.h>
|
||||
+#include <keys/asymmetric-type.h>
|
||||
+#include <keys/system_keyring.h>
|
||||
+#include "module-internal.h"
|
||||
+#include "internal.h"
|
||||
+
|
||||
+static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid, unsigned long *size)
|
||||
+static __initdata efi_guid_t efi_cert_x509_guid = EFI_CERT_X509_GUID;
|
||||
+static __initdata efi_guid_t efi_cert_x509_sha256_guid = EFI_CERT_X509_SHA256_GUID;
|
||||
+static __initdata efi_guid_t efi_cert_sha256_guid = EFI_CERT_SHA256_GUID;
|
||||
+
|
||||
+/*
|
||||
+ * Get a certificate list blob from the named EFI variable.
|
||||
+ */
|
||||
+static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid,
|
||||
+ unsigned long *size)
|
||||
+{
|
||||
+ efi_status_t status;
|
||||
+ unsigned long lsize = 4;
|
||||
+ unsigned long tmpdb[4];
|
||||
+ void *db = NULL;
|
||||
+ void *db;
|
||||
+
|
||||
+ status = efi.get_variable(name, guid, NULL, &lsize, &tmpdb);
|
||||
+ if (status != EFI_BUFFER_TOO_SMALL) {
|
||||
|
@ -135,23 +107,89 @@ index 000000000000..fe4a6f2bf10a
|
|||
+ db = kmalloc(lsize, GFP_KERNEL);
|
||||
+ if (!db) {
|
||||
+ pr_err("Couldn't allocate memory for uefi cert list\n");
|
||||
+ goto out;
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ status = efi.get_variable(name, guid, NULL, &lsize, db);
|
||||
+ if (status != EFI_SUCCESS) {
|
||||
+ kfree(db);
|
||||
+ db = NULL;
|
||||
+ pr_err("Error reading db var: 0x%lx\n", status);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+out:
|
||||
+
|
||||
+ *size = lsize;
|
||||
+ return db;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * * Load the certs contained in the UEFI databases
|
||||
+ * */
|
||||
+ * Blacklist an X509 TBS hash.
|
||||
+ */
|
||||
+static __init void uefi_blacklist_x509_tbs(const char *source,
|
||||
+ const void *data, size_t len)
|
||||
+{
|
||||
+ char *hash, *p;
|
||||
+
|
||||
+ hash = kmalloc(4 + len * 2 + 1, GFP_KERNEL);
|
||||
+ if (!hash)
|
||||
+ return;
|
||||
+ p = memcpy(hash, "tbs:", 4);
|
||||
+ p += 4;
|
||||
+ bin2hex(p, data, len);
|
||||
+ p += len * 2;
|
||||
+ *p = 0;
|
||||
+
|
||||
+ mark_hash_blacklisted(hash);
|
||||
+ kfree(hash);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Blacklist the hash of an executable.
|
||||
+ */
|
||||
+static __init void uefi_blacklist_binary(const char *source,
|
||||
+ const void *data, size_t len)
|
||||
+{
|
||||
+ char *hash, *p;
|
||||
+
|
||||
+ hash = kmalloc(4 + len * 2 + 1, GFP_KERNEL);
|
||||
+ if (!hash)
|
||||
+ return;
|
||||
+ p = memcpy(hash, "bin:", 4);
|
||||
+ p += 4;
|
||||
+ bin2hex(p, data, len);
|
||||
+ p += len * 2;
|
||||
+ *p = 0;
|
||||
+
|
||||
+ mark_hash_blacklisted(hash);
|
||||
+ kfree(hash);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Return the appropriate handler for particular signature list types found in
|
||||
+ * the UEFI db and MokListRT tables.
|
||||
+ */
|
||||
+static __init efi_element_handler_t get_handler_for_db(const efi_guid_t *sig_type)
|
||||
+{
|
||||
+ if (efi_guidcmp(*sig_type, efi_cert_x509_guid) == 0)
|
||||
+ return add_trusted_secondary_key;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Return the appropriate handler for particular signature list types found in
|
||||
+ * the UEFI dbx and MokListXRT tables.
|
||||
+ */
|
||||
+static __init efi_element_handler_t get_handler_for_dbx(const efi_guid_t *sig_type)
|
||||
+{
|
||||
+ if (efi_guidcmp(*sig_type, efi_cert_x509_sha256_guid) == 0)
|
||||
+ return uefi_blacklist_x509_tbs;
|
||||
+ if (efi_guidcmp(*sig_type, efi_cert_sha256_guid) == 0)
|
||||
+ return uefi_blacklist_binary;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Load the certs contained in the UEFI databases
|
||||
+ */
|
||||
+static int __init load_uefi_certs(void)
|
||||
+{
|
||||
+ efi_guid_t secure_var = EFI_IMAGE_SECURITY_DATABASE_GUID;
|
||||
|
@ -159,17 +197,9 @@ index 000000000000..fe4a6f2bf10a
|
|||
+ void *db = NULL, *dbx = NULL, *mok = NULL;
|
||||
+ unsigned long dbsize = 0, dbxsize = 0, moksize = 0;
|
||||
+ int rc = 0;
|
||||
+ struct key *keyring = NULL;
|
||||
+
|
||||
+ /* Check if SB is enabled and just return if not */
|
||||
+ if (!efi_enabled(EFI_SECURE_BOOT))
|
||||
+ return 0;
|
||||
+
|
||||
+ keyring = get_system_keyring();
|
||||
+ if (!keyring) {
|
||||
+ pr_err("MODSIGN: Couldn't get system keyring\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ if (!efi.get_variable)
|
||||
+ return false;
|
||||
+
|
||||
+ /* Get db, MokListRT, and dbx. They might not exist, so it isn't
|
||||
+ * an error if we can't get them.
|
||||
|
@ -178,7 +208,8 @@ index 000000000000..fe4a6f2bf10a
|
|||
+ if (!db) {
|
||||
+ pr_err("MODSIGN: Couldn't get UEFI db list\n");
|
||||
+ } else {
|
||||
+ rc = parse_efi_signature_list(db, dbsize, keyring);
|
||||
+ rc = parse_efi_signature_list("UEFI:db",
|
||||
+ db, dbsize, get_handler_for_db);
|
||||
+ if (rc)
|
||||
+ pr_err("Couldn't parse db signatures: %d\n", rc);
|
||||
+ kfree(db);
|
||||
|
@ -188,7 +219,8 @@ index 000000000000..fe4a6f2bf10a
|
|||
+ if (!mok) {
|
||||
+ pr_info("MODSIGN: Couldn't get UEFI MokListRT\n");
|
||||
+ } else {
|
||||
+ rc = parse_efi_signature_list(mok, moksize, keyring);
|
||||
+ rc = parse_efi_signature_list("UEFI:MokListRT",
|
||||
+ mok, moksize, get_handler_for_db);
|
||||
+ if (rc)
|
||||
+ pr_err("Couldn't parse MokListRT signatures: %d\n", rc);
|
||||
+ kfree(mok);
|
||||
|
@ -198,8 +230,9 @@ index 000000000000..fe4a6f2bf10a
|
|||
+ if (!dbx) {
|
||||
+ pr_info("MODSIGN: Couldn't get UEFI dbx list\n");
|
||||
+ } else {
|
||||
+ rc = parse_efi_signature_list(dbx, dbxsize,
|
||||
+ system_blacklist_keyring);
|
||||
+ rc = parse_efi_signature_list("UEFI:dbx",
|
||||
+ dbx, dbxsize,
|
||||
+ get_handler_for_dbx);
|
||||
+ if (rc)
|
||||
+ pr_err("Couldn't parse dbx signatures: %d\n", rc);
|
||||
+ kfree(dbx);
|
||||
|
|
|
@ -1,62 +1,62 @@
|
|||
From 9d2e5c61d5adcf7911f67ed44a1b0ff881f175bb Mon Sep 17 00:00:00 2001
|
||||
From 9f1958a0cc911e1f79b2733ee5029dbd819ff328 Mon Sep 17 00:00:00 2001
|
||||
From: Josh Boyer <jwboyer@fedoraproject.org>
|
||||
Date: Thu, 3 Oct 2013 10:14:23 -0400
|
||||
Subject: [PATCH 19/20] MODSIGN: Support not importing certs from db
|
||||
Date: Fri, 5 May 2017 08:21:59 +0100
|
||||
Subject: [PATCH 4/4] MODSIGN: Allow the "db" UEFI variable to be suppressed
|
||||
|
||||
If a user tells shim to not use the certs/hashes in the UEFI db variable
|
||||
for verification purposes, shim will set a UEFI variable called MokIgnoreDB.
|
||||
Have the uefi import code look for this and not import things from the db
|
||||
variable.
|
||||
for verification purposes, shim will set a UEFI variable called
|
||||
MokIgnoreDB. Have the uefi import code look for this and ignore the db
|
||||
variable if it is found.
|
||||
|
||||
Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org>
|
||||
Signed-off-by: David Howells <dhowells@redhat.com>
|
||||
---
|
||||
kernel/modsign_uefi.c | 40 +++++++++++++++++++++++++++++++---------
|
||||
1 file changed, 31 insertions(+), 9 deletions(-)
|
||||
certs/load_uefi.c | 44 ++++++++++++++++++++++++++++++++++----------
|
||||
1 file changed, 34 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/kernel/modsign_uefi.c b/kernel/modsign_uefi.c
|
||||
index fe4a6f2bf10a..a41da14b1ffd 100644
|
||||
--- a/kernel/modsign_uefi.c
|
||||
+++ b/kernel/modsign_uefi.c
|
||||
@@ -8,6 +8,23 @@
|
||||
#include <keys/system_keyring.h>
|
||||
#include "module-internal.h"
|
||||
|
||||
+static __init int check_ignore_db(void)
|
||||
diff --git a/certs/load_uefi.c b/certs/load_uefi.c
|
||||
index b44e464..3d88459 100644
|
||||
--- a/certs/load_uefi.c
|
||||
+++ b/certs/load_uefi.c
|
||||
@@ -13,6 +13,26 @@ static __initdata efi_guid_t efi_cert_x509_sha256_guid = EFI_CERT_X509_SHA256_GU
|
||||
static __initdata efi_guid_t efi_cert_sha256_guid = EFI_CERT_SHA256_GUID;
|
||||
|
||||
/*
|
||||
+ * Look to see if a UEFI variable called MokIgnoreDB exists and return true if
|
||||
+ * it does.
|
||||
+ *
|
||||
+ * This UEFI variable is set by the shim if a user tells the shim to not use
|
||||
+ * the certs/hashes in the UEFI db variable for verification purposes. If it
|
||||
+ * is set, we should ignore the db variable also and the true return indicates
|
||||
+ * this.
|
||||
+ */
|
||||
+static __init bool uefi_check_ignore_db(void)
|
||||
+{
|
||||
+ efi_status_t status;
|
||||
+ unsigned int db = 0;
|
||||
+ unsigned long size = sizeof(db);
|
||||
+ efi_guid_t guid = EFI_SHIM_LOCK_GUID;
|
||||
+
|
||||
+ /* Check and see if the MokIgnoreDB variable exists. If that fails
|
||||
+ * then we don't ignore DB. If it succeeds, we do.
|
||||
+ */
|
||||
+ status = efi.get_variable(L"MokIgnoreDB", &guid, NULL, &size, &db);
|
||||
+ if (status != EFI_SUCCESS)
|
||||
+ return 0;
|
||||
+
|
||||
+ return 1;
|
||||
+ return status == EFI_SUCCESS;
|
||||
+}
|
||||
+
|
||||
static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid, unsigned long *size)
|
||||
+/*
|
||||
* Get a certificate list blob from the named EFI variable.
|
||||
*/
|
||||
static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid,
|
||||
@@ -113,7 +133,9 @@ static __init efi_element_handler_t get_handler_for_dbx(const efi_guid_t *sig_ty
|
||||
}
|
||||
|
||||
/*
|
||||
- * Load the certs contained in the UEFI databases
|
||||
+ * Load the certs contained in the UEFI databases into the secondary trusted
|
||||
+ * keyring and the UEFI blacklisted X.509 cert SHA256 hashes into the blacklist
|
||||
+ * keyring.
|
||||
*/
|
||||
static int __init load_uefi_certs(void)
|
||||
{
|
||||
efi_status_t status;
|
||||
@@ -47,7 +64,7 @@ static int __init load_uefi_certs(void)
|
||||
efi_guid_t mok_var = EFI_SHIM_LOCK_GUID;
|
||||
void *db = NULL, *dbx = NULL, *mok = NULL;
|
||||
unsigned long dbsize = 0, dbxsize = 0, moksize = 0;
|
||||
- int rc = 0;
|
||||
+ int ignore_db, rc = 0;
|
||||
struct key *keyring = NULL;
|
||||
|
||||
/* Check if SB is enabled and just return if not */
|
||||
@@ -60,17 +77,22 @@ static int __init load_uefi_certs(void)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
+ /* See if the user has setup Ignore DB mode */
|
||||
+ ignore_db = check_ignore_db();
|
||||
+
|
||||
@@ -129,15 +151,17 @@ static int __init load_uefi_certs(void)
|
||||
/* Get db, MokListRT, and dbx. They might not exist, so it isn't
|
||||
* an error if we can't get them.
|
||||
*/
|
||||
|
@ -64,22 +64,24 @@ index fe4a6f2bf10a..a41da14b1ffd 100644
|
|||
- if (!db) {
|
||||
- pr_err("MODSIGN: Couldn't get UEFI db list\n");
|
||||
- } else {
|
||||
- rc = parse_efi_signature_list(db, dbsize, keyring);
|
||||
- rc = parse_efi_signature_list("UEFI:db",
|
||||
- db, dbsize, get_handler_for_db);
|
||||
- if (rc)
|
||||
- pr_err("Couldn't parse db signatures: %d\n", rc);
|
||||
- kfree(db);
|
||||
+ if (!ignore_db) {
|
||||
+ if (!uefi_check_ignore_db()) {
|
||||
+ db = get_cert_list(L"db", &secure_var, &dbsize);
|
||||
+ if (!db) {
|
||||
+ pr_err("MODSIGN: Couldn't get UEFI db list\n");
|
||||
+ } else {
|
||||
+ rc = parse_efi_signature_list(db, dbsize, keyring);
|
||||
+ rc = parse_efi_signature_list("UEFI:db",
|
||||
+ db, dbsize, get_handler_for_db);
|
||||
+ if (rc)
|
||||
+ pr_err("Couldn't parse db signatures: %d\n", rc);
|
||||
+ kfree(db);
|
||||
+ }
|
||||
}
|
||||
|
||||
|
||||
mok = get_cert_list(L"MokListRT", &mok_var, &moksize);
|
||||
--
|
||||
2.9.3
|
||||
|
|
52
README.txt
52
README.txt
|
@ -31,29 +31,30 @@ by make verrel
|
|||
config heirarchy.
|
||||
-----------------
|
||||
Instead of having to maintain a config file for every arch variant we build on,
|
||||
the kernel spec uses a nested system of configs. Each option CONFIG_FOO is
|
||||
represented by a single file named CONFIG_FOO which contains the state (=y, =m,
|
||||
=n). These options are collected in the folder baseconfig. Architecture specifi
|
||||
options are set in nested folders. An option set in a nested folder will
|
||||
override the same option set in one of the higher levels.
|
||||
the kernel spec uses a nested system of configs. At the top level, is
|
||||
config-generic. Add options here that should be present in every possible
|
||||
config on all architectures.
|
||||
|
||||
The individual CONFIG_FOO files only exist in the pkg-git repository. The RPM
|
||||
contains kernel-foo.config files which are the result of combining all the
|
||||
CONFIG_FOO files. The files are combined by running build_configs.sh. This
|
||||
script _must_ be run each time one of the options is changed.
|
||||
Beneath this are per-arch overrides. For example config-x86-generic add
|
||||
additional x86 specific options, and also _override_ any options that were
|
||||
set in config-generic.
|
||||
|
||||
Example flow:
|
||||
The heirarchy looks like this..
|
||||
|
||||
# Enable the option CONFIG_ABC123 as a module for all arches
|
||||
echo "CONFIG_ABC123=m" > baseconfig/CONFIG_ABC1234
|
||||
# enable the option CONFIG_XYZ321 for only x86
|
||||
echo "# CONFIG_XYZ321 is not set" > baseconfig/CONFIG_XYZ321
|
||||
echo "CONFIG_XYZ321=m" > baseconfig/x86/CONFIG_XYZ321
|
||||
# regenerate the combined config files
|
||||
./build_configs.sh
|
||||
config-generic
|
||||
|
|
||||
config-x86-generic
|
||||
| |
|
||||
config-x86-32-generic config-x86-64-generic
|
||||
|
||||
An option set in a lower level will override the same option set in one
|
||||
of the higher levels.
|
||||
|
||||
|
||||
There exist two additional overrides, config-debug, and config-nodebug,
|
||||
which override -generic, and the per-arch overrides. It is documented
|
||||
further below.
|
||||
|
||||
The file config_generation gives a listing of what folders go into each
|
||||
config file generated.
|
||||
|
||||
debug options.
|
||||
--------------
|
||||
|
@ -68,11 +69,14 @@ typically been run already, which sets up the following..
|
|||
If we are building for rawhide, 'make debug' has been run, which changes
|
||||
the status quo to:
|
||||
- We only build one kernel 'kernel'
|
||||
- The debug options are always turned on.
|
||||
- The debug options from 'config-debug' are always turned on.
|
||||
This is done to increase coverage testing, as not many people actually
|
||||
run kernel-debug.
|
||||
|
||||
The debug options are managed in a separate heierarchy under debugconfig. This
|
||||
works in a similar manner to baseconfig. More deeply nested folders, again,
|
||||
override options. The file config_generation gives a listing of what folders
|
||||
go into each config file generated.
|
||||
To add new debug options, add an option to _both_ config-debug and config-nodebug,
|
||||
and also new stanzas to the Makefile 'debug' and 'release' targets.
|
||||
|
||||
Sometimes debug options get added to config-generic, or per-arch overrides
|
||||
instead of config-[no]debug. In this instance, the options should have no
|
||||
discernable performance impact, otherwise they belong in the debug files.
|
||||
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
From 7d9e74c53a4376245b4f05006f42184a1540dee8 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Robinson <pbrobinson@gmail.com>
|
||||
Date: Tue, 18 Jul 2017 23:21:50 +0100
|
||||
Subject: [PATCH] Revert "ARM: dts: bcm2835: Add the DSI module nodes and
|
||||
clocks."
|
||||
|
||||
This reverts commit 4aba4cf820545ca8ec23785c7bac40bba7e505c5.
|
||||
---
|
||||
arch/arm/boot/dts/bcm2835-rpi.dtsi | 8 -------
|
||||
arch/arm/boot/dts/bcm283x.dtsi | 48 +++-----------------------------------
|
||||
2 files changed, 3 insertions(+), 53 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi
|
||||
index a7b5ce133784..e99bb149065f 100644
|
||||
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
|
||||
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
|
||||
@@ -98,11 +98,3 @@
|
||||
power-domains = <&power RPI_POWER_DOMAIN_VEC>;
|
||||
status = "okay";
|
||||
};
|
||||
-
|
||||
-&dsi0 {
|
||||
- power-domains = <&power RPI_POWER_DOMAIN_DSI0>;
|
||||
-};
|
||||
-
|
||||
-&dsi1 {
|
||||
- power-domains = <&power RPI_POWER_DOMAIN_DSI1>;
|
||||
-};
|
||||
diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi
|
||||
index 9444a9a9ba10..ce14c9ddf574 100644
|
||||
--- a/arch/arm/boot/dts/bcm283x.dtsi
|
||||
+++ b/arch/arm/boot/dts/bcm283x.dtsi
|
||||
@@ -98,13 +98,10 @@
|
||||
#clock-cells = <1>;
|
||||
reg = <0x7e101000 0x2000>;
|
||||
|
||||
- /* CPRMAN derives almost everything from the
|
||||
- * platform's oscillator. However, the DSI
|
||||
- * pixel clocks come from the DSI analog PHY.
|
||||
+ /* CPRMAN derives everything from the platform's
|
||||
+ * oscillator.
|
||||
*/
|
||||
- clocks = <&clk_osc>,
|
||||
- <&dsi0 0>, <&dsi0 1>, <&dsi0 2>,
|
||||
- <&dsi1 0>, <&dsi1 1>, <&dsi1 2>;
|
||||
+ clocks = <&clk_osc>;
|
||||
};
|
||||
|
||||
rng@7e104000 {
|
||||
@@ -412,25 +409,6 @@
|
||||
interrupts = <2 14>; /* pwa1 */
|
||||
};
|
||||
|
||||
- dsi0: dsi@7e209000 {
|
||||
- compatible = "brcm,bcm2835-dsi0";
|
||||
- reg = <0x7e209000 0x78>;
|
||||
- interrupts = <2 4>;
|
||||
- #address-cells = <1>;
|
||||
- #size-cells = <0>;
|
||||
- #clock-cells = <1>;
|
||||
-
|
||||
- clocks = <&clocks BCM2835_PLLA_DSI0>,
|
||||
- <&clocks BCM2835_CLOCK_DSI0E>,
|
||||
- <&clocks BCM2835_CLOCK_DSI0P>;
|
||||
- clock-names = "phy", "escape", "pixel";
|
||||
-
|
||||
- clock-output-names = "dsi0_byte",
|
||||
- "dsi0_ddr2",
|
||||
- "dsi0_ddr";
|
||||
-
|
||||
- };
|
||||
-
|
||||
thermal: thermal@7e212000 {
|
||||
compatible = "brcm,bcm2835-thermal";
|
||||
reg = <0x7e212000 0x8>;
|
||||
@@ -497,26 +475,6 @@
|
||||
interrupts = <2 1>;
|
||||
};
|
||||
|
||||
- dsi1: dsi@7e700000 {
|
||||
- compatible = "brcm,bcm2835-dsi1";
|
||||
- reg = <0x7e700000 0x8c>;
|
||||
- interrupts = <2 12>;
|
||||
- #address-cells = <1>;
|
||||
- #size-cells = <0>;
|
||||
- #clock-cells = <1>;
|
||||
-
|
||||
- clocks = <&clocks BCM2835_PLLD_DSI1>,
|
||||
- <&clocks BCM2835_CLOCK_DSI1E>,
|
||||
- <&clocks BCM2835_CLOCK_DSI1P>;
|
||||
- clock-names = "phy", "escape", "pixel";
|
||||
-
|
||||
- clock-output-names = "dsi1_byte",
|
||||
- "dsi1_ddr2",
|
||||
- "dsi1_ddr";
|
||||
-
|
||||
- status = "disabled";
|
||||
- };
|
||||
-
|
||||
i2c1: i2c@7e804000 {
|
||||
compatible = "brcm,bcm2835-i2c";
|
||||
reg = <0x7e804000 0x1000>;
|
||||
--
|
||||
2.13.3
|
||||
|
|
@ -1,500 +0,0 @@
|
|||
From c477ebe21fabe0010a2ed324ce3a1762c757d867 Mon Sep 17 00:00:00 2001
|
||||
From: Ulf Hansson <ulf.hansson@linaro.org>
|
||||
Date: Sat, 6 May 2017 11:41:30 +0200
|
||||
Subject: [PATCH 179/554] mmc: dt: pwrseq-simple: Invent power-off-delay-us
|
||||
|
||||
During power off, after the GPIO pin has been asserted, some devices like
|
||||
the Wifi chip from TI, Wl18xx, needs a delay before the host continues with
|
||||
clock gating and turning off regulators as to follow a graceful shutdown
|
||||
sequence.
|
||||
|
||||
Therefore invent an optional power-off-delay-us DT binding for
|
||||
mmc-pwrseq-simple, to allow us to support this constraint.
|
||||
|
||||
Cc: devicetree@vger.kernel.org
|
||||
Cc: Rob Herring <robh+dt@kernel.org>
|
||||
Cc: linux-mmc@vger.kernel.org
|
||||
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
|
||||
Acked-by: Arnd Bergmann <arnd@arndb.de>
|
||||
---
|
||||
Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
|
||||
index e25436861867..9029b45b8a22 100644
|
||||
--- a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
|
||||
+++ b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
|
||||
@@ -18,6 +18,8 @@ Optional properties:
|
||||
"ext_clock" (External clock provided to the card).
|
||||
- post-power-on-delay-ms : Delay in ms after powering the card and
|
||||
de-asserting the reset-gpios (if any)
|
||||
+- power-off-delay-us : Delay in us after asserting the reset-gpios (if any)
|
||||
+ during power off of the card.
|
||||
|
||||
Example:
|
||||
|
||||
--
|
||||
2.13.0
|
||||
|
||||
From e9256e142f597edf90c68cec22db4c4aebaa27de Mon Sep 17 00:00:00 2001
|
||||
From: Ulf Hansson <ulf.hansson@linaro.org>
|
||||
Date: Sat, 6 May 2017 11:43:05 +0200
|
||||
Subject: [PATCH 180/554] mmc: pwrseq_simple: Parse DTS for the
|
||||
power-off-delay-us property
|
||||
|
||||
If the optional power-off-delay-us property is found, insert the
|
||||
corresponding delay after asserting the GPIO during power off. This enables
|
||||
a graceful shutdown sequence for some devices.
|
||||
|
||||
Cc: linux-mmc@vger.kernel.org
|
||||
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
|
||||
Acked-by: Arnd Bergmann <arnd@arndb.de>
|
||||
---
|
||||
drivers/mmc/core/pwrseq_simple.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c
|
||||
index 1304160de168..13ef162cf066 100644
|
||||
--- a/drivers/mmc/core/pwrseq_simple.c
|
||||
+++ b/drivers/mmc/core/pwrseq_simple.c
|
||||
@@ -27,6 +27,7 @@ struct mmc_pwrseq_simple {
|
||||
struct mmc_pwrseq pwrseq;
|
||||
bool clk_enabled;
|
||||
u32 post_power_on_delay_ms;
|
||||
+ u32 power_off_delay_us;
|
||||
struct clk *ext_clk;
|
||||
struct gpio_descs *reset_gpios;
|
||||
};
|
||||
@@ -78,6 +79,10 @@ static void mmc_pwrseq_simple_power_off(struct mmc_host *host)
|
||||
|
||||
mmc_pwrseq_simple_set_gpios_value(pwrseq, 1);
|
||||
|
||||
+ if (pwrseq->power_off_delay_us)
|
||||
+ usleep_range(pwrseq->power_off_delay_us,
|
||||
+ 2 * pwrseq->power_off_delay_us);
|
||||
+
|
||||
if (!IS_ERR(pwrseq->ext_clk) && pwrseq->clk_enabled) {
|
||||
clk_disable_unprepare(pwrseq->ext_clk);
|
||||
pwrseq->clk_enabled = false;
|
||||
@@ -119,6 +124,8 @@ static int mmc_pwrseq_simple_probe(struct platform_device *pdev)
|
||||
|
||||
device_property_read_u32(dev, "post-power-on-delay-ms",
|
||||
&pwrseq->post_power_on_delay_ms);
|
||||
+ device_property_read_u32(dev, "power-off-delay-us",
|
||||
+ &pwrseq->power_off_delay_us);
|
||||
|
||||
pwrseq->pwrseq.dev = dev;
|
||||
pwrseq->pwrseq.ops = &mmc_pwrseq_simple_ops;
|
||||
--
|
||||
2.13.0
|
||||
|
||||
From f74ac688c981138c914f9afba50b646146e35585 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Lezcano <daniel.lezcano@linaro.org>
|
||||
Date: Mon, 24 Apr 2017 22:40:22 +0200
|
||||
Subject: [PATCH 181/554] mfd: dts: hi655x: Add clock binding for the pmic
|
||||
|
||||
The hi655x PMIC provides the regulators but also a clock. The latter is
|
||||
missing in the definition, so extend the documentation to include this as
|
||||
well.
|
||||
|
||||
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
|
||||
Acked-by: Rob Herring <robh@kernel.org>
|
||||
Acked-by: Lee Jones <lee.jones@linaro.org>
|
||||
[Ulf: Split patch and updated changelog]
|
||||
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
|
||||
Acked-by: Arnd Bergmann <arnd@arndb.de>
|
||||
---
|
||||
Documentation/devicetree/bindings/mfd/hisilicon,hi655x.txt | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/mfd/hisilicon,hi655x.txt b/Documentation/devicetree/bindings/mfd/hisilicon,hi655x.txt
|
||||
index 05485699d70e..9630ac0e4b56 100644
|
||||
--- a/Documentation/devicetree/bindings/mfd/hisilicon,hi655x.txt
|
||||
+++ b/Documentation/devicetree/bindings/mfd/hisilicon,hi655x.txt
|
||||
@@ -16,6 +16,11 @@ Required properties:
|
||||
- reg: Base address of PMIC on Hi6220 SoC.
|
||||
- interrupt-controller: Hi655x has internal IRQs (has own IRQ domain).
|
||||
- pmic-gpios: The GPIO used by PMIC IRQ.
|
||||
+- #clock-cells: From common clock binding; shall be set to 0
|
||||
+
|
||||
+Optional properties:
|
||||
+- clock-output-names: From common clock binding to override the
|
||||
+ default output clock name
|
||||
|
||||
Example:
|
||||
pmic: pmic@f8000000 {
|
||||
@@ -24,4 +29,5 @@ Example:
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
pmic-gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
|
||||
+ #clock-cells = <0>;
|
||||
}
|
||||
--
|
||||
2.13.0
|
||||
|
||||
From 307ded8968868e55343e063fbe96cff1efd77eb6 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Lezcano <daniel.lezcano@linaro.org>
|
||||
Date: Mon, 24 Apr 2017 22:40:22 +0200
|
||||
Subject: [PATCH 182/554] arm64: dts: hikey: Add clock for the pmic mfd
|
||||
|
||||
The hi655x PMIC provides the regulators but also a clock. The latter is
|
||||
missing so let's add it. This clock is used by WiFi/Bluetooth chip, but
|
||||
that connection is done in a separate change on top of this one.
|
||||
|
||||
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
|
||||
Acked-by: Rob Herring <robh@kernel.org>
|
||||
Acked-by: Lee Jones <lee.jones@linaro.org>
|
||||
[Ulf: Split patch and updated changelog]
|
||||
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
|
||||
Acked-by: Arnd Bergmann <arnd@arndb.de>
|
||||
---
|
||||
arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
|
||||
index 75bce2d0b1a8..d22eb3a646c4 100644
|
||||
--- a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
|
||||
+++ b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
|
||||
@@ -330,6 +330,7 @@
|
||||
pmic: pmic@f8000000 {
|
||||
compatible = "hisilicon,hi655x-pmic";
|
||||
reg = <0x0 0xf8000000 0x0 0x1000>;
|
||||
+ #clock-cells = <0>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
pmic-gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
|
||||
--
|
||||
2.13.0
|
||||
|
||||
From 1b32a5ff98fbb271d2235ddcfe3b58f514f8260a Mon Sep 17 00:00:00 2001
|
||||
From: Ulf Hansson <ulf.hansson@linaro.org>
|
||||
Date: Wed, 3 May 2017 12:46:55 +0200
|
||||
Subject: [PATCH 183/554] arm64: dts: hi6220: Move the fixed_5v_hub regulator
|
||||
to the hikey dts
|
||||
|
||||
The regulator is a part of the hikey board, therefore let's move it from
|
||||
the hi6220 SoC dtsi file into the hikey dts file . Let's also rename the
|
||||
regulator according to the datasheet (5V_HUB) to better reflect the HW.
|
||||
|
||||
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
|
||||
Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
|
||||
Acked-by: Arnd Bergmann <arnd@arndb.de>
|
||||
---
|
||||
arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts | 10 ++++++++++
|
||||
arch/arm64/boot/dts/hisilicon/hi6220.dtsi | 12 +-----------
|
||||
2 files changed, 11 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
|
||||
index d22eb3a646c4..0f6cba77fc76 100644
|
||||
--- a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
|
||||
+++ b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
|
||||
@@ -81,6 +81,16 @@
|
||||
};
|
||||
};
|
||||
|
||||
+ reg_5v_hub: regulator@0 {
|
||||
+ compatible = "regulator-fixed";
|
||||
+ regulator-name = "5V_HUB";
|
||||
+ regulator-min-microvolt = <5000000>;
|
||||
+ regulator-max-microvolt = <5000000>;
|
||||
+ regulator-boot-on;
|
||||
+ gpio = <&gpio0 7 0>;
|
||||
+ regulator-always-on;
|
||||
+ };
|
||||
+
|
||||
soc {
|
||||
spi0: spi@f7106000 {
|
||||
status = "ok";
|
||||
diff --git a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
|
||||
index 1e5129b19280..951152d44c02 100644
|
||||
--- a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
|
||||
+++ b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
|
||||
@@ -725,20 +725,10 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
- fixed_5v_hub: regulator@0 {
|
||||
- compatible = "regulator-fixed";
|
||||
- regulator-name = "fixed_5v_hub";
|
||||
- regulator-min-microvolt = <5000000>;
|
||||
- regulator-max-microvolt = <5000000>;
|
||||
- regulator-boot-on;
|
||||
- gpio = <&gpio0 7 0>;
|
||||
- regulator-always-on;
|
||||
- };
|
||||
-
|
||||
usb_phy: usbphy {
|
||||
compatible = "hisilicon,hi6220-usb-phy";
|
||||
#phy-cells = <0>;
|
||||
- phy-supply = <&fixed_5v_hub>;
|
||||
+ phy-supply = <®_5v_hub>;
|
||||
hisilicon,peripheral-syscon = <&sys_ctrl>;
|
||||
};
|
||||
|
||||
--
|
||||
2.13.0
|
||||
|
||||
From 84f7c60b31f10e3a438153bc7408ad536f585641 Mon Sep 17 00:00:00 2001
|
||||
From: Ulf Hansson <ulf.hansson@linaro.org>
|
||||
Date: Wed, 3 May 2017 13:51:27 +0200
|
||||
Subject: [PATCH 184/554] arm64: dts: hikey: Add the SYS_5V and the VDD_3V3
|
||||
regulators
|
||||
|
||||
Add these regulators to better describe the HW, but also because those is
|
||||
needed in following changes.
|
||||
|
||||
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
|
||||
Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
|
||||
Acked-by: Arnd Bergmann <arnd@arndb.de>
|
||||
---
|
||||
arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts | 22 +++++++++++++++++++++-
|
||||
1 file changed, 21 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
|
||||
index 0f6cba77fc76..802f4a4bed30 100644
|
||||
--- a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
|
||||
+++ b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
|
||||
@@ -81,7 +81,26 @@
|
||||
};
|
||||
};
|
||||
|
||||
- reg_5v_hub: regulator@0 {
|
||||
+ reg_sys_5v: regulator@0 {
|
||||
+ compatible = "regulator-fixed";
|
||||
+ regulator-name = "SYS_5V";
|
||||
+ regulator-min-microvolt = <5000000>;
|
||||
+ regulator-max-microvolt = <5000000>;
|
||||
+ regulator-boot-on;
|
||||
+ regulator-always-on;
|
||||
+ };
|
||||
+
|
||||
+ reg_vdd_3v3: regulator@1 {
|
||||
+ compatible = "regulator-fixed";
|
||||
+ regulator-name = "VDD_3V3";
|
||||
+ regulator-min-microvolt = <3300000>;
|
||||
+ regulator-max-microvolt = <3300000>;
|
||||
+ regulator-boot-on;
|
||||
+ regulator-always-on;
|
||||
+ vin-supply = <®_sys_5v>;
|
||||
+ };
|
||||
+
|
||||
+ reg_5v_hub: regulator@2 {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "5V_HUB";
|
||||
regulator-min-microvolt = <5000000>;
|
||||
@@ -89,6 +108,7 @@
|
||||
regulator-boot-on;
|
||||
gpio = <&gpio0 7 0>;
|
||||
regulator-always-on;
|
||||
+ vin-supply = <®_sys_5v>;
|
||||
};
|
||||
|
||||
soc {
|
||||
--
|
||||
2.13.0
|
||||
|
||||
From 76f1dfb687150e852aa74573962cfc158a9570cc Mon Sep 17 00:00:00 2001
|
||||
From: Ulf Hansson <ulf.hansson@linaro.org>
|
||||
Date: Wed, 3 May 2017 14:18:26 +0200
|
||||
Subject: [PATCH 185/554] arm64: dts: hi6220: Move board data from the dwmmc
|
||||
nodes to hikey dts
|
||||
|
||||
Move the board specific descriptions for the dwmmc nodes in the hi6220 SoC
|
||||
dtsi, into the hikey dts as it's there these belongs.
|
||||
|
||||
While changing this, let's take the opportunity to drop the use of the
|
||||
"ti,non-removable" binding for one of the dwmmc device nodes, as it's not a
|
||||
valid binding and not used. Drop also the unnecessary use of "num-slots =
|
||||
<0x1>" for all of the dwmmc nodes, as there is no need to set this since
|
||||
when default number of slots is one.
|
||||
|
||||
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
|
||||
Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
|
||||
Acked-by: Arnd Bergmann <arnd@arndb.de>
|
||||
---
|
||||
arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts | 23 ++++++++++++++++++++++-
|
||||
arch/arm64/boot/dts/hisilicon/hi6220.dtsi | 19 -------------------
|
||||
2 files changed, 22 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
|
||||
index 802f4a4bed30..5132d8ed4664 100644
|
||||
--- a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
|
||||
+++ b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
|
||||
@@ -286,8 +286,29 @@
|
||||
|
||||
/* GPIO blocks 16 thru 19 do not appear to be routed to pins */
|
||||
|
||||
+ dwmmc_0: dwmmc0@f723d000 {
|
||||
+ cap-mmc-highspeed;
|
||||
+ non-removable;
|
||||
+ bus-width = <0x8>;
|
||||
+ vmmc-supply = <&ldo19>;
|
||||
+ };
|
||||
+
|
||||
+ dwmmc_1: dwmmc1@f723e000 {
|
||||
+ card-detect-delay = <200>;
|
||||
+ cap-sd-highspeed;
|
||||
+ sd-uhs-sdr12;
|
||||
+ sd-uhs-sdr25;
|
||||
+ sd-uhs-sdr50;
|
||||
+ vqmmc-supply = <&ldo7>;
|
||||
+ vmmc-supply = <&ldo10>;
|
||||
+ bus-width = <0x4>;
|
||||
+ disable-wp;
|
||||
+ cd-gpios = <&gpio1 0 1>;
|
||||
+ };
|
||||
+
|
||||
dwmmc_2: dwmmc2@f723f000 {
|
||||
- ti,non-removable;
|
||||
+ broken-cd;
|
||||
+ bus-width = <0x4>;
|
||||
non-removable;
|
||||
/* WL_EN */
|
||||
vmmc-supply = <&wlan_en_reg>;
|
||||
diff --git a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
|
||||
index 951152d44c02..5013e4b2ea71 100644
|
||||
--- a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
|
||||
+++ b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
|
||||
@@ -756,17 +756,12 @@
|
||||
|
||||
dwmmc_0: dwmmc0@f723d000 {
|
||||
compatible = "hisilicon,hi6220-dw-mshc";
|
||||
- num-slots = <0x1>;
|
||||
- cap-mmc-highspeed;
|
||||
- non-removable;
|
||||
reg = <0x0 0xf723d000 0x0 0x1000>;
|
||||
interrupts = <0x0 0x48 0x4>;
|
||||
clocks = <&sys_ctrl 2>, <&sys_ctrl 1>;
|
||||
clock-names = "ciu", "biu";
|
||||
resets = <&sys_ctrl PERIPH_RSTDIS0_MMC0>;
|
||||
reset-names = "reset";
|
||||
- bus-width = <0x8>;
|
||||
- vmmc-supply = <&ldo19>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&emmc_pmx_func &emmc_clk_cfg_func
|
||||
&emmc_cfg_func &emmc_rst_cfg_func>;
|
||||
@@ -774,13 +769,7 @@
|
||||
|
||||
dwmmc_1: dwmmc1@f723e000 {
|
||||
compatible = "hisilicon,hi6220-dw-mshc";
|
||||
- num-slots = <0x1>;
|
||||
- card-detect-delay = <200>;
|
||||
hisilicon,peripheral-syscon = <&ao_ctrl>;
|
||||
- cap-sd-highspeed;
|
||||
- sd-uhs-sdr12;
|
||||
- sd-uhs-sdr25;
|
||||
- sd-uhs-sdr50;
|
||||
reg = <0x0 0xf723e000 0x0 0x1000>;
|
||||
interrupts = <0x0 0x49 0x4>;
|
||||
#address-cells = <0x1>;
|
||||
@@ -789,11 +778,6 @@
|
||||
clock-names = "ciu", "biu";
|
||||
resets = <&sys_ctrl PERIPH_RSTDIS0_MMC1>;
|
||||
reset-names = "reset";
|
||||
- vqmmc-supply = <&ldo7>;
|
||||
- vmmc-supply = <&ldo10>;
|
||||
- bus-width = <0x4>;
|
||||
- disable-wp;
|
||||
- cd-gpios = <&gpio1 0 1>;
|
||||
pinctrl-names = "default", "idle";
|
||||
pinctrl-0 = <&sd_pmx_func &sd_clk_cfg_func &sd_cfg_func>;
|
||||
pinctrl-1 = <&sd_pmx_idle &sd_clk_cfg_idle &sd_cfg_idle>;
|
||||
@@ -801,15 +785,12 @@
|
||||
|
||||
dwmmc_2: dwmmc2@f723f000 {
|
||||
compatible = "hisilicon,hi6220-dw-mshc";
|
||||
- num-slots = <0x1>;
|
||||
reg = <0x0 0xf723f000 0x0 0x1000>;
|
||||
interrupts = <0x0 0x4a 0x4>;
|
||||
clocks = <&sys_ctrl HI6220_MMC2_CIUCLK>, <&sys_ctrl HI6220_MMC2_CLK>;
|
||||
clock-names = "ciu", "biu";
|
||||
resets = <&sys_ctrl PERIPH_RSTDIS0_MMC2>;
|
||||
reset-names = "reset";
|
||||
- bus-width = <0x4>;
|
||||
- broken-cd;
|
||||
pinctrl-names = "default", "idle";
|
||||
pinctrl-0 = <&sdio_pmx_func &sdio_clk_cfg_func &sdio_cfg_func>;
|
||||
pinctrl-1 = <&sdio_pmx_idle &sdio_clk_cfg_idle &sdio_cfg_idle>;
|
||||
--
|
||||
2.13.0
|
||||
|
||||
From ea452678734eb782126f999bf5c4fb3e71d3b196 Mon Sep 17 00:00:00 2001
|
||||
From: Ulf Hansson <ulf.hansson@linaro.org>
|
||||
Date: Wed, 3 May 2017 16:11:33 +0200
|
||||
Subject: [PATCH 186/554] arm64: dts: hikey: Fix WiFi support
|
||||
|
||||
The description of the connection between the dwmmc (SDIO) controller and
|
||||
the Wifi chip, which is attached to the SDIO bus is wrong. Currently the
|
||||
SDIO card can't be detected and thus the Wifi doesn't work.
|
||||
|
||||
Let's fix this by assigning the correct vmmc supply, which is the always on
|
||||
regulator VDD_3V3 and remove the WLAN enable regulator altogether. Then to
|
||||
properly deal with the power on/off sequence, add a mmc-pwrseq node to
|
||||
describe the resources needed to detect the SDIO card.
|
||||
|
||||
Except for the WLAN enable GPIO and its corresponding assert/de-assert
|
||||
delays, the mmc-pwrseq node also contains a handle to a clock provided by
|
||||
the hi655x pmic. This clock is also needed to be able to turn on the WiFi
|
||||
chip.
|
||||
|
||||
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
|
||||
Acked-by: Arnd Bergmann <arnd@arndb.de>
|
||||
---
|
||||
arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts | 26 +++++++++++---------------
|
||||
1 file changed, 11 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
|
||||
index 5132d8ed4664..49f6a6242cf9 100644
|
||||
--- a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
|
||||
+++ b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
|
||||
@@ -111,6 +111,15 @@
|
||||
vin-supply = <®_sys_5v>;
|
||||
};
|
||||
|
||||
+ wl1835_pwrseq: wl1835-pwrseq {
|
||||
+ compatible = "mmc-pwrseq-simple";
|
||||
+ /* WLAN_EN GPIO */
|
||||
+ reset-gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
|
||||
+ clocks = <&pmic>;
|
||||
+ clock-names = "ext_clock";
|
||||
+ power-off-delay-us = <10>;
|
||||
+ };
|
||||
+
|
||||
soc {
|
||||
spi0: spi@f7106000 {
|
||||
status = "ok";
|
||||
@@ -307,11 +316,10 @@
|
||||
};
|
||||
|
||||
dwmmc_2: dwmmc2@f723f000 {
|
||||
- broken-cd;
|
||||
bus-width = <0x4>;
|
||||
non-removable;
|
||||
- /* WL_EN */
|
||||
- vmmc-supply = <&wlan_en_reg>;
|
||||
+ vmmc-supply = <®_vdd_3v3>;
|
||||
+ mmc-pwrseq = <&wl1835_pwrseq>;
|
||||
|
||||
#address-cells = <0x1>;
|
||||
#size-cells = <0x0>;
|
||||
@@ -323,18 +331,6 @@
|
||||
interrupts = <3 IRQ_TYPE_EDGE_RISING>;
|
||||
};
|
||||
};
|
||||
-
|
||||
- wlan_en_reg: regulator@1 {
|
||||
- compatible = "regulator-fixed";
|
||||
- regulator-name = "wlan-en-regulator";
|
||||
- regulator-min-microvolt = <1800000>;
|
||||
- regulator-max-microvolt = <1800000>;
|
||||
- /* WLAN_EN GPIO */
|
||||
- gpio = <&gpio0 5 0>;
|
||||
- /* WLAN card specific delay */
|
||||
- startup-delay-us = <70000>;
|
||||
- enable-active-high;
|
||||
- };
|
||||
};
|
||||
|
||||
leds {
|
||||
--
|
||||
2.13.0
|
|
@ -26,21 +26,21 @@ index 011808490fed..ccdff6650541 100644
|
|||
--- a/arch/arm/boot/dts/Makefile
|
||||
+++ b/arch/arm/boot/dts/Makefile
|
||||
@@ -353,6 +353,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
|
||||
imx6dl-gw552x.dtb \
|
||||
imx6dl-gw553x.dtb \
|
||||
imx6dl-gw5903.dtb \
|
||||
imx6dl-gw5904.dtb \
|
||||
imx6dl-hummingboard.dtb \
|
||||
+ imx6dl-hummingboard2.dtb \
|
||||
imx6dl-icore.dtb \
|
||||
imx6dl-icore-rqs.dtb \
|
||||
imx6dl-nit6xlite.dtb \
|
||||
@@ -397,6 +398,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
|
||||
imx6q-gw553x.dtb \
|
||||
imx6q-gw5904.dtb \
|
||||
imx6q-h100.dtb \
|
||||
imx6q-hummingboard.dtb \
|
||||
+ imx6q-hummingboard2.dtb \
|
||||
imx6q-icore.dtb \
|
||||
imx6q-icore-rqs.dtb \
|
||||
imx6q-marsboard.dtb \
|
||||
imx6q-icore-ofcap10.dtb \
|
||||
imx6q-icore-ofcap12.dtb \
|
||||
diff --git a/arch/arm/boot/dts/imx6dl-hummingboard2.dts b/arch/arm/boot/dts/imx6dl-hummingboard2.dts
|
||||
new file mode 100644
|
||||
index 000000000000..990b5050de5b
|
||||
|
|
|
@ -1,573 +0,0 @@
|
|||
From 223599514133293bb9afe7b82937140c3b275877 Mon Sep 17 00:00:00 2001
|
||||
From: Eddie Cai <eddie.cai.linux@gmail.com>
|
||||
Date: Tue, 14 Feb 2017 18:07:31 +0800
|
||||
Subject: ARM: dts: rockchip: add dts for RK3288-Tinker board
|
||||
|
||||
This patch add basic support for RK3288-Tinker board. We can boot in to rootfs
|
||||
with this patch.
|
||||
|
||||
Signed-off-by: Eddie Cai <eddie.cai.linux@gmail.com>
|
||||
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
|
||||
---
|
||||
arch/arm/boot/dts/Makefile | 1 +
|
||||
arch/arm/boot/dts/rk3288-tinker.dts | 536 ++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 537 insertions(+)
|
||||
create mode 100644 arch/arm/boot/dts/rk3288-tinker.dts
|
||||
|
||||
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
|
||||
index 0118084..fb46849 100644
|
||||
--- a/arch/arm/boot/dts/Makefile
|
||||
+++ b/arch/arm/boot/dts/Makefile
|
||||
@@ -695,6 +695,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \
|
||||
rk3288-popmetal.dtb \
|
||||
rk3288-r89.dtb \
|
||||
rk3288-rock2-square.dtb \
|
||||
+ rk3288-tinker.dtb \
|
||||
rk3288-veyron-brain.dtb \
|
||||
rk3288-veyron-jaq.dtb \
|
||||
rk3288-veyron-jerry.dtb \
|
||||
diff --git a/arch/arm/boot/dts/rk3288-tinker.dts b/arch/arm/boot/dts/rk3288-tinker.dts
|
||||
new file mode 100644
|
||||
index 0000000..f601c78
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/boot/dts/rk3288-tinker.dts
|
||||
@@ -0,0 +1,536 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd.
|
||||
+ *
|
||||
+ * This file is dual-licensed: you can use it either under the terms
|
||||
+ * of the GPL or the X11 license, at your option. Note that this dual
|
||||
+ * licensing only applies to this file, and not this project as a
|
||||
+ * whole.
|
||||
+ *
|
||||
+ * a) This file 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 file 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.
|
||||
+ *
|
||||
+ * Or, alternatively,
|
||||
+ *
|
||||
+ * b) Permission is hereby granted, free of charge, to any person
|
||||
+ * obtaining a copy of this software and associated documentation
|
||||
+ * files (the "Software"), to deal in the Software without
|
||||
+ * restriction, including without limitation the rights to use,
|
||||
+ * copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
+ * sell copies of the Software, and to permit persons to whom the
|
||||
+ * Software is furnished to do so, subject to the following
|
||||
+ * conditions:
|
||||
+ *
|
||||
+ * The above copyright notice and this permission notice shall be
|
||||
+ * included in all copies or substantial portions of the Software.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
+ * OTHER DEALINGS IN THE SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+/dts-v1/;
|
||||
+
|
||||
+#include "rk3288.dtsi"
|
||||
+#include <dt-bindings/input/input.h>
|
||||
+
|
||||
+/ {
|
||||
+ model = "Rockchip RK3288 Tinker Board";
|
||||
+ compatible = "asus,rk3288-tinker", "rockchip,rk3288";
|
||||
+
|
||||
+ memory {
|
||||
+ reg = <0x0 0x80000000>;
|
||||
+ device_type = "memory";
|
||||
+ };
|
||||
+
|
||||
+ ext_gmac: external-gmac-clock {
|
||||
+ compatible = "fixed-clock";
|
||||
+ #clock-cells = <0>;
|
||||
+ clock-frequency = <125000000>;
|
||||
+ clock-output-names = "ext_gmac";
|
||||
+ };
|
||||
+
|
||||
+ gpio-keys {
|
||||
+ compatible = "gpio-keys";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ autorepeat;
|
||||
+
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&pwrbtn>;
|
||||
+
|
||||
+ button@0 {
|
||||
+ gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>;
|
||||
+ linux,code = <KEY_POWER>;
|
||||
+ label = "GPIO Key Power";
|
||||
+ linux,input-type = <1>;
|
||||
+ wakeup-source;
|
||||
+ debounce-interval = <100>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ gpio-leds {
|
||||
+ compatible = "gpio-leds";
|
||||
+
|
||||
+ act-led {
|
||||
+ gpios=<&gpio1 RK_PD0 GPIO_ACTIVE_HIGH>;
|
||||
+ linux,default-trigger="mmc0";
|
||||
+ };
|
||||
+
|
||||
+ heartbeat-led {
|
||||
+ gpios=<&gpio1 RK_PD1 GPIO_ACTIVE_HIGH>;
|
||||
+ linux,default-trigger="heartbeat";
|
||||
+ };
|
||||
+
|
||||
+ pwr-led {
|
||||
+ gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_HIGH>;
|
||||
+ linux,default-trigger = "default-on";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ sound {
|
||||
+ compatible = "simple-audio-card";
|
||||
+ simple-audio-card,format = "i2s";
|
||||
+ simple-audio-card,name = "rockchip,tinker-codec";
|
||||
+ simple-audio-card,mclk-fs = <512>;
|
||||
+
|
||||
+ simple-audio-card,codec {
|
||||
+ sound-dai = <&hdmi>;
|
||||
+ };
|
||||
+
|
||||
+ simple-audio-card,cpu {
|
||||
+ sound-dai = <&i2s>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ vcc_sys: vsys-regulator {
|
||||
+ compatible = "regulator-fixed";
|
||||
+ regulator-name = "vcc_sys";
|
||||
+ regulator-min-microvolt = <5000000>;
|
||||
+ regulator-max-microvolt = <5000000>;
|
||||
+ regulator-always-on;
|
||||
+ regulator-boot-on;
|
||||
+ };
|
||||
+
|
||||
+ vcc_sd: sdmmc-regulator {
|
||||
+ compatible = "regulator-fixed";
|
||||
+ gpio = <&gpio7 11 GPIO_ACTIVE_LOW>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&sdmmc_pwr>;
|
||||
+ regulator-name = "vcc_sd";
|
||||
+ regulator-min-microvolt = <3300000>;
|
||||
+ regulator-max-microvolt = <3300000>;
|
||||
+ startup-delay-us = <100000>;
|
||||
+ vin-supply = <&vcc_io>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&cpu0 {
|
||||
+ cpu0-supply = <&vdd_cpu>;
|
||||
+};
|
||||
+
|
||||
+&gmac {
|
||||
+ assigned-clocks = <&cru SCLK_MAC>;
|
||||
+ assigned-clock-parents = <&ext_gmac>;
|
||||
+ clock_in_out = "input";
|
||||
+ phy-mode = "rgmii";
|
||||
+ phy-supply = <&vcc33_lan>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&rgmii_pins>;
|
||||
+ snps,reset-gpio = <&gpio4 7 0>;
|
||||
+ snps,reset-active-low;
|
||||
+ snps,reset-delays-us = <0 10000 1000000>;
|
||||
+ tx_delay = <0x30>;
|
||||
+ rx_delay = <0x10>;
|
||||
+ status = "ok";
|
||||
+};
|
||||
+
|
||||
+&hdmi {
|
||||
+ ddc-i2c-bus = <&i2c5>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&i2c0 {
|
||||
+ clock-frequency = <400000>;
|
||||
+ status = "okay";
|
||||
+
|
||||
+ rk808: pmic@1b {
|
||||
+ compatible = "rockchip,rk808";
|
||||
+ reg = <0x1b>;
|
||||
+ interrupt-parent = <&gpio0>;
|
||||
+ interrupts = <4 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ #clock-cells = <1>;
|
||||
+ clock-output-names = "xin32k", "rk808-clkout2";
|
||||
+ dvs-gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>,
|
||||
+ <&gpio0 12 GPIO_ACTIVE_HIGH>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&pmic_int &global_pwroff &dvs_1 &dvs_2>;
|
||||
+ rockchip,system-power-controller;
|
||||
+ wakeup-source;
|
||||
+
|
||||
+ vcc1-supply = <&vcc_sys>;
|
||||
+ vcc2-supply = <&vcc_sys>;
|
||||
+ vcc3-supply = <&vcc_sys>;
|
||||
+ vcc4-supply = <&vcc_sys>;
|
||||
+ vcc6-supply = <&vcc_sys>;
|
||||
+ vcc7-supply = <&vcc_sys>;
|
||||
+ vcc8-supply = <&vcc_io>;
|
||||
+ vcc9-supply = <&vcc_io>;
|
||||
+ vcc10-supply = <&vcc_io>;
|
||||
+ vcc11-supply = <&vcc_sys>;
|
||||
+ vcc12-supply = <&vcc_io>;
|
||||
+ vddio-supply = <&vcc_io>;
|
||||
+
|
||||
+ regulators {
|
||||
+ vdd_cpu: DCDC_REG1 {
|
||||
+ regulator-always-on;
|
||||
+ regulator-boot-on;
|
||||
+ regulator-min-microvolt = <750000>;
|
||||
+ regulator-max-microvolt = <1350000>;
|
||||
+ regulator-name = "vdd_arm";
|
||||
+ regulator-ramp-delay = <6000>;
|
||||
+ regulator-state-mem {
|
||||
+ regulator-off-in-suspend;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ vdd_gpu: DCDC_REG2 {
|
||||
+ regulator-always-on;
|
||||
+ regulator-boot-on;
|
||||
+ regulator-min-microvolt = <850000>;
|
||||
+ regulator-max-microvolt = <1250000>;
|
||||
+ regulator-name = "vdd_gpu";
|
||||
+ regulator-ramp-delay = <6000>;
|
||||
+ regulator-state-mem {
|
||||
+ regulator-on-in-suspend;
|
||||
+ regulator-suspend-microvolt = <1000000>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ vcc_ddr: DCDC_REG3 {
|
||||
+ regulator-always-on;
|
||||
+ regulator-boot-on;
|
||||
+ regulator-name = "vcc_ddr";
|
||||
+ regulator-state-mem {
|
||||
+ regulator-on-in-suspend;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ vcc_io: DCDC_REG4 {
|
||||
+ regulator-always-on;
|
||||
+ regulator-boot-on;
|
||||
+ regulator-min-microvolt = <3300000>;
|
||||
+ regulator-max-microvolt = <3300000>;
|
||||
+ regulator-name = "vcc_io";
|
||||
+ regulator-state-mem {
|
||||
+ regulator-on-in-suspend;
|
||||
+ regulator-suspend-microvolt = <3300000>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ vcc18_ldo1: LDO_REG1 {
|
||||
+ regulator-always-on;
|
||||
+ regulator-boot-on;
|
||||
+ regulator-min-microvolt = <1800000>;
|
||||
+ regulator-max-microvolt = <1800000>;
|
||||
+ regulator-name = "vcc18_ldo1";
|
||||
+ regulator-state-mem {
|
||||
+ regulator-on-in-suspend;
|
||||
+ regulator-suspend-microvolt = <1800000>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ vcc33_mipi: LDO_REG2 {
|
||||
+ regulator-always-on;
|
||||
+ regulator-boot-on;
|
||||
+ regulator-min-microvolt = <3300000>;
|
||||
+ regulator-max-microvolt = <3300000>;
|
||||
+ regulator-name = "vcc33_mipi";
|
||||
+ regulator-state-mem {
|
||||
+ regulator-off-in-suspend;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ vdd_10: LDO_REG3 {
|
||||
+ regulator-always-on;
|
||||
+ regulator-boot-on;
|
||||
+ regulator-min-microvolt = <1000000>;
|
||||
+ regulator-max-microvolt = <1000000>;
|
||||
+ regulator-name = "vdd_10";
|
||||
+ regulator-state-mem {
|
||||
+ regulator-on-in-suspend;
|
||||
+ regulator-suspend-microvolt = <1000000>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ vcc18_codec: LDO_REG4 {
|
||||
+ regulator-always-on;
|
||||
+ regulator-boot-on;
|
||||
+ regulator-min-microvolt = <1800000>;
|
||||
+ regulator-max-microvolt = <1800000>;
|
||||
+ regulator-name = "vcc18_codec";
|
||||
+ regulator-state-mem {
|
||||
+ regulator-on-in-suspend;
|
||||
+ regulator-suspend-microvolt = <1800000>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ vccio_sd: LDO_REG5 {
|
||||
+ regulator-min-microvolt = <1800000>;
|
||||
+ regulator-max-microvolt = <3300000>;
|
||||
+ regulator-name = "vccio_sd";
|
||||
+ regulator-state-mem {
|
||||
+ regulator-on-in-suspend;
|
||||
+ regulator-suspend-microvolt = <3300000>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ vdd10_lcd: LDO_REG6 {
|
||||
+ regulator-always-on;
|
||||
+ regulator-boot-on;
|
||||
+ regulator-min-microvolt = <1000000>;
|
||||
+ regulator-max-microvolt = <1000000>;
|
||||
+ regulator-name = "vdd10_lcd";
|
||||
+ regulator-state-mem {
|
||||
+ regulator-on-in-suspend;
|
||||
+ regulator-suspend-microvolt = <1000000>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ vcc_18: LDO_REG7 {
|
||||
+ regulator-always-on;
|
||||
+ regulator-boot-on;
|
||||
+ regulator-min-microvolt = <1800000>;
|
||||
+ regulator-max-microvolt = <1800000>;
|
||||
+ regulator-name = "vcc_18";
|
||||
+ regulator-state-mem {
|
||||
+ regulator-on-in-suspend;
|
||||
+ regulator-suspend-microvolt = <1800000>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ vcc18_lcd: LDO_REG8 {
|
||||
+ regulator-always-on;
|
||||
+ regulator-boot-on;
|
||||
+ regulator-min-microvolt = <1800000>;
|
||||
+ regulator-max-microvolt = <1800000>;
|
||||
+ regulator-name = "vcc18_lcd";
|
||||
+ regulator-state-mem {
|
||||
+ regulator-on-in-suspend;
|
||||
+ regulator-suspend-microvolt = <1800000>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ vcc33_sd: SWITCH_REG1 {
|
||||
+ regulator-always-on;
|
||||
+ regulator-boot-on;
|
||||
+ regulator-name = "vcc33_sd";
|
||||
+ regulator-state-mem {
|
||||
+ regulator-on-in-suspend;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ vcc33_lan: SWITCH_REG2 {
|
||||
+ regulator-always-on;
|
||||
+ regulator-boot-on;
|
||||
+ regulator-name = "vcc33_lan";
|
||||
+ regulator-state-mem {
|
||||
+ regulator-on-in-suspend;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&i2c2 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&i2c5 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&i2s {
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&io_domains {
|
||||
+ status = "okay";
|
||||
+
|
||||
+ sdcard-supply = <&vccio_sd>;
|
||||
+};
|
||||
+
|
||||
+&pinctrl {
|
||||
+ pcfg_pull_none_drv_8ma: pcfg-pull-none-drv-8ma {
|
||||
+ drive-strength = <8>;
|
||||
+ };
|
||||
+
|
||||
+ pcfg_pull_up_drv_8ma: pcfg-pull-up-drv-8ma {
|
||||
+ bias-pull-up;
|
||||
+ drive-strength = <8>;
|
||||
+ };
|
||||
+
|
||||
+ backlight {
|
||||
+ bl_en: bl-en {
|
||||
+ rockchip,pins = <7 2 RK_FUNC_GPIO &pcfg_pull_none>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ buttons {
|
||||
+ pwrbtn: pwrbtn {
|
||||
+ rockchip,pins = <0 5 RK_FUNC_GPIO &pcfg_pull_up>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ eth_phy {
|
||||
+ eth_phy_pwr: eth-phy-pwr {
|
||||
+ rockchip,pins = <0 6 RK_FUNC_GPIO &pcfg_pull_none>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ pmic {
|
||||
+ pmic_int: pmic-int {
|
||||
+ rockchip,pins = <RK_GPIO0 4 RK_FUNC_GPIO \
|
||||
+ &pcfg_pull_up>;
|
||||
+ };
|
||||
+
|
||||
+ dvs_1: dvs-1 {
|
||||
+ rockchip,pins = <RK_GPIO0 11 RK_FUNC_GPIO \
|
||||
+ &pcfg_pull_down>;
|
||||
+ };
|
||||
+
|
||||
+ dvs_2: dvs-2 {
|
||||
+ rockchip,pins = <RK_GPIO0 12 RK_FUNC_GPIO \
|
||||
+ &pcfg_pull_down>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ sdmmc {
|
||||
+ sdmmc_bus4: sdmmc-bus4 {
|
||||
+ rockchip,pins = <6 16 RK_FUNC_1 &pcfg_pull_up_drv_8ma>,
|
||||
+ <6 17 RK_FUNC_1 &pcfg_pull_up_drv_8ma>,
|
||||
+ <6 18 RK_FUNC_1 &pcfg_pull_up_drv_8ma>,
|
||||
+ <6 19 RK_FUNC_1 &pcfg_pull_up_drv_8ma>;
|
||||
+ };
|
||||
+
|
||||
+ sdmmc_clk: sdmmc-clk {
|
||||
+ rockchip,pins = <6 20 RK_FUNC_1 \
|
||||
+ &pcfg_pull_none_drv_8ma>;
|
||||
+ };
|
||||
+
|
||||
+ sdmmc_cmd: sdmmc-cmd {
|
||||
+ rockchip,pins = <6 21 RK_FUNC_1 &pcfg_pull_up_drv_8ma>;
|
||||
+ };
|
||||
+
|
||||
+ sdmmc_pwr: sdmmc-pwr {
|
||||
+ rockchip,pins = <7 11 RK_FUNC_GPIO &pcfg_pull_none>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ usb {
|
||||
+ host_vbus_drv: host-vbus-drv {
|
||||
+ rockchip,pins = <0 14 RK_FUNC_GPIO &pcfg_pull_none>;
|
||||
+ };
|
||||
+
|
||||
+ pwr_3g: pwr-3g {
|
||||
+ rockchip,pins = <7 8 RK_FUNC_GPIO &pcfg_pull_none>;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&pwm0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&saradc {
|
||||
+ vref-supply = <&vcc18_ldo1>;
|
||||
+ status ="okay";
|
||||
+};
|
||||
+
|
||||
+&sdmmc {
|
||||
+ bus-width = <4>;
|
||||
+ cap-mmc-highspeed;
|
||||
+ cap-sd-highspeed;
|
||||
+ card-detect-delay = <200>;
|
||||
+ disable-wp; /* wp not hooked up */
|
||||
+ num-slots = <1>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>;
|
||||
+ status = "okay";
|
||||
+ vmmc-supply = <&vcc33_sd>;
|
||||
+ vqmmc-supply = <&vccio_sd>;
|
||||
+};
|
||||
+
|
||||
+&tsadc {
|
||||
+ rockchip,hw-tshut-mode = <1>; /* tshut mode 0:CRU 1:GPIO */
|
||||
+ rockchip,hw-tshut-polarity = <1>; /* tshut polarity 0:LOW 1:HIGH */
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&uart0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&uart1 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&uart2 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&uart3 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&uart4 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&usbphy {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&usb_host0_ehci {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&usb_host1 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&usb_otg {
|
||||
+ status= "okay";
|
||||
+};
|
||||
+
|
||||
+&vopb {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&vopb_mmu {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&vopl {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&vopl_mmu {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&wdt {
|
||||
+ status = "okay";
|
||||
+};
|
||||
--
|
||||
cgit v1.1
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
From patchwork Sun Jul 9 16:36:14 2017
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
MIME-Version: 1.0
|
||||
Content-Transfer-Encoding: 7bit
|
||||
Subject: ARM: tegra: Register host1x node with iommu binding on tegra124
|
||||
From: Paul Kocialkowski <contact@paulk.fr>
|
||||
X-Patchwork-Id: 9831825
|
||||
Message-Id: <20170709163614.6746-1-contact@paulk.fr>
|
||||
To: linux-arm-kernel@lists.infradead.org, linux-tegra@vger.kernel.org,
|
||||
linux-kernel@vger.kernel.org
|
||||
Cc: Thierry Reding <thierry.reding@gmail.com>,
|
||||
Stephen Warren <swarren@wwwdotorg.org>,
|
||||
Mikko Perttunen <mperttunen@nvidia.com>,
|
||||
Paul Kocialkowski <contact@paulk.fr>,
|
||||
Jonathan Hunter <jonathanh@nvidia.com>
|
||||
Date: Sun, 9 Jul 2017 19:36:14 +0300
|
||||
|
||||
This registers the host1x node with the SMMU (as HC swgroup) to allow
|
||||
the host1x code to attach to it. It avoid failing the probe sequence,
|
||||
which resulted in the tegra drm driver not probing and thus nothing
|
||||
being displayed on-screen.
|
||||
|
||||
Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
|
||||
---
|
||||
arch/arm/boot/dts/tegra124.dtsi | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/tegra124.dtsi b/arch/arm/boot/dts/tegra124.dtsi
|
||||
index 187a36c6d0fc..b3b89befffeb 100644
|
||||
--- a/arch/arm/boot/dts/tegra124.dtsi
|
||||
+++ b/arch/arm/boot/dts/tegra124.dtsi
|
||||
@@ -85,6 +85,7 @@
|
||||
clocks = <&tegra_car TEGRA124_CLK_HOST1X>;
|
||||
resets = <&tegra_car 28>;
|
||||
reset-names = "host1x";
|
||||
+ iommus = <&mc TEGRA_SWGROUP_HC>;
|
||||
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
From patchwork Mon Jul 10 19:33:05 2017
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
MIME-Version: 1.0
|
||||
Content-Transfer-Encoding: 7bit
|
||||
Subject: gpu: host1x: Free the IOMMU domain when there is no device to attach
|
||||
From: Paul Kocialkowski <contact@paulk.fr>
|
||||
X-Patchwork-Id: 9833721
|
||||
Message-Id: <20170710193305.5987-1-contact@paulk.fr>
|
||||
To: linux-arm-kernel@lists.infradead.org, linux-tegra@vger.kernel.org,
|
||||
linux-kernel@vger.kernel.org
|
||||
Cc: Thierry Reding <thierry.reding@gmail.com>,
|
||||
Stephen Warren <swarren@wwwdotorg.org>,
|
||||
Mikko Perttunen <mperttunen@nvidia.com>,
|
||||
Paul Kocialkowski <contact@paulk.fr>,
|
||||
Jonathan Hunter <jonathanh@nvidia.com>
|
||||
Date: Mon, 10 Jul 2017 21:33:05 +0200
|
||||
|
||||
When there is no device to attach to the IOMMU domain, as may be the
|
||||
case when the device-tree does not contain the proper iommu node, it is
|
||||
best to keep going without IOMMU support rather than failing.
|
||||
This allows the driver to probe and function instead of taking down
|
||||
all of the tegra drm driver, leading to missing display support.
|
||||
|
||||
Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
|
||||
Reviewed-by: Mikko Perttunen <mperttunen@nvidia.com>
|
||||
---
|
||||
drivers/gpu/host1x/dev.c | 8 +++++++-
|
||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
|
||||
index ac65f52850a6..f296738d0de8 100644
|
||||
--- a/drivers/gpu/host1x/dev.c
|
||||
+++ b/drivers/gpu/host1x/dev.c
|
||||
@@ -186,8 +186,13 @@ static int host1x_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
err = iommu_attach_device(host->domain, &pdev->dev);
|
||||
- if (err)
|
||||
+ if (err == -ENODEV) {
|
||||
+ iommu_domain_free(host->domain);
|
||||
+ host->domain = NULL;
|
||||
+ goto iommu_skip;
|
||||
+ } else if (err) {
|
||||
goto fail_free_domain;
|
||||
+ }
|
||||
|
||||
geometry = &host->domain->geometry;
|
||||
|
||||
@@ -198,6 +203,7 @@ static int host1x_probe(struct platform_device *pdev)
|
||||
host->iova_end = geometry->aperture_end;
|
||||
}
|
||||
|
||||
+iommu_skip:
|
||||
err = host1x_channel_list_init(host);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "failed to initialize channel list\n");
|
|
@ -0,0 +1,224 @@
|
|||
From 0fe4d2181cc4cb3eba303c0e03f878d2558d0f3a Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Wahren <stefan.wahren@i2se.com>
|
||||
Date: Fri, 31 Mar 2017 20:03:04 +0000
|
||||
Subject: [PATCH] ARM: dts: bcm283x: Add CPU thermal zone with 1
|
||||
trip point
|
||||
|
||||
As suggested by Eduardo Valentin this adds the thermal zone for
|
||||
the bcm2835 SoC with its single thermal sensor. We start with
|
||||
the criticial trip point and leave the cooling devices empty
|
||||
since we don't have any at the moment. Since the coefficients
|
||||
could vary depending on the SoC we need to define them separate.
|
||||
|
||||
Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
|
||||
Signed-off-by: Eric Anholt <eric@anholt.net>
|
||||
Acked-by: Eduardo Valentin <edubezval@gmail.com>
|
||||
---
|
||||
arch/arm/boot/dts/bcm2835.dtsi | 4 ++++
|
||||
arch/arm/boot/dts/bcm2836.dtsi | 4 ++++
|
||||
arch/arm/boot/dts/bcm283x.dtsi | 21 +++++++++++++++++++++
|
||||
3 files changed, 29 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
|
||||
index 0890d97e674d..659b6e9513b1 100644
|
||||
--- a/arch/arm/boot/dts/bcm2835.dtsi
|
||||
+++ b/arch/arm/boot/dts/bcm2835.dtsi
|
||||
@@ -24,6 +24,10 @@
|
||||
};
|
||||
};
|
||||
|
||||
+&cpu_thermal {
|
||||
+ coefficients = <(-538) 407000>;
|
||||
+};
|
||||
+
|
||||
/* enable thermal sensor with the correct compatible property set */
|
||||
&thermal {
|
||||
compatible = "brcm,bcm2835-thermal";
|
||||
diff --git a/arch/arm/boot/dts/bcm2836.dtsi b/arch/arm/boot/dts/bcm2836.dtsi
|
||||
index 519a44f5d25a..da3deeb42592 100644
|
||||
--- a/arch/arm/boot/dts/bcm2836.dtsi
|
||||
+++ b/arch/arm/boot/dts/bcm2836.dtsi
|
||||
@@ -77,6 +77,10 @@
|
||||
interrupts = <8>;
|
||||
};
|
||||
|
||||
+&cpu_thermal {
|
||||
+ coefficients = <(-538) 407000>;
|
||||
+};
|
||||
+
|
||||
/* enable thermal sensor with the correct compatible property set */
|
||||
&thermal {
|
||||
compatible = "brcm,bcm2836-thermal";
|
||||
diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi
|
||||
index 561f27d8d922..86a5db53da8f 100644
|
||||
--- a/arch/arm/boot/dts/bcm283x.dtsi
|
||||
+++ b/arch/arm/boot/dts/bcm283x.dtsi
|
||||
@@ -19,6 +19,26 @@
|
||||
bootargs = "earlyprintk console=ttyAMA0";
|
||||
};
|
||||
|
||||
+ thermal-zones {
|
||||
+ cpu_thermal: cpu-thermal {
|
||||
+ polling-delay-passive = <0>;
|
||||
+ polling-delay = <1000>;
|
||||
+
|
||||
+ thermal-sensors = <&thermal>;
|
||||
+
|
||||
+ trips {
|
||||
+ cpu-crit {
|
||||
+ temperature = <80000>;
|
||||
+ hysteresis = <0>;
|
||||
+ type = "critical";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ cooling-maps {
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
soc {
|
||||
compatible = "simple-bus";
|
||||
#address-cells = <1>;
|
||||
@@ -430,6 +450,7 @@
|
||||
compatible = "brcm,bcm2835-thermal";
|
||||
reg = <0x7e212000 0x8>;
|
||||
clocks = <&clocks BCM2835_CLOCK_TSENS>;
|
||||
+ #thermal-sensor-cells = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
--
|
||||
2.13.3
|
||||
|
||||
From 4ae6f954b96c1fea86c6f21ae8fc413f5fc3444e Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Wahren <stefan.wahren@i2se.com>
|
||||
Date: Fri, 31 Mar 2017 20:03:05 +0000
|
||||
Subject: [PATCH] ARM64: dts: bcm2837: Define CPU thermal coefficients
|
||||
|
||||
This defines the bcm2837 SoC specific thermal coefficients in
|
||||
order to initialize the thermal driver correctly.
|
||||
|
||||
Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
|
||||
Signed-off-by: Eric Anholt <eric@anholt.net>
|
||||
Acked-by: Eduardo Valentin <edubezval@gmail.com>
|
||||
---
|
||||
arch/arm64/boot/dts/broadcom/bcm2837.dtsi | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/broadcom/bcm2837.dtsi b/arch/arm64/boot/dts/broadcom/bcm2837.dtsi
|
||||
index 19f2fe620a21..2d5de6f0f78d 100644
|
||||
--- a/arch/arm64/boot/dts/broadcom/bcm2837.dtsi
|
||||
+++ b/arch/arm64/boot/dts/broadcom/bcm2837.dtsi
|
||||
@@ -75,6 +75,10 @@
|
||||
interrupts = <8>;
|
||||
};
|
||||
|
||||
+&cpu_thermal {
|
||||
+ coefficients = <(-538) 412000>;
|
||||
+};
|
||||
+
|
||||
/* enable thermal sensor with the correct compatible property set */
|
||||
&thermal {
|
||||
compatible = "brcm,bcm2837-thermal";
|
||||
--
|
||||
2.13.3
|
||||
|
||||
From 1fe3854a83b580727c9464b37b62ba77ead1d6f6 Mon Sep 17 00:00:00 2001
|
||||
From: Dan Carpenter <dan.carpenter@oracle.com>
|
||||
Date: Wed, 14 Jun 2017 12:13:27 +0300
|
||||
Subject: [PATCH] thermal: bcm2835: fix an error code in probe()
|
||||
|
||||
This causes a static checker because we're passing a valid pointer to
|
||||
PTR_ERR(). "err" is already the correct error code, so we can just
|
||||
delete this line.
|
||||
|
||||
Fixes: bcb7dd9ef206 ("thermal: bcm2835: add thermal driver for bcm2835 SoC")
|
||||
Acked-by: Stefan Wahren <stefan.wahren@i2se.com>
|
||||
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
|
||||
Signed-off-by: Eduardo Valentin <edubezval@gmail.com>
|
||||
---
|
||||
drivers/thermal/broadcom/bcm2835_thermal.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/thermal/broadcom/bcm2835_thermal.c b/drivers/thermal/broadcom/bcm2835_thermal.c
|
||||
index 0ecf80890c84..e6863c841662 100644
|
||||
--- a/drivers/thermal/broadcom/bcm2835_thermal.c
|
||||
+++ b/drivers/thermal/broadcom/bcm2835_thermal.c
|
||||
@@ -245,7 +245,6 @@ static int bcm2835_thermal_probe(struct platform_device *pdev)
|
||||
*/
|
||||
err = tz->ops->get_trip_temp(tz, 0, &trip_temp);
|
||||
if (err < 0) {
|
||||
- err = PTR_ERR(tz);
|
||||
dev_err(&pdev->dev,
|
||||
"Not able to read trip_temp: %d\n",
|
||||
err);
|
||||
--
|
||||
2.13.3
|
||||
|
||||
From e3bdc8d7623d5875403ad40443e7b049ae200fcd Mon Sep 17 00:00:00 2001
|
||||
From: Arvind Yadav <arvind.yadav.cs@gmail.com>
|
||||
Date: Tue, 6 Jun 2017 15:12:37 +0530
|
||||
Subject: [PATCH] thermal: imx: Handle return value of clk_prepare_enable
|
||||
|
||||
clk_prepare_enable() can fail here and we must check its return value.
|
||||
|
||||
Signed-off-by: Arvind Yadav <arvind.yadav.cs@gmail.com>
|
||||
Signed-off-by: Eduardo Valentin <edubezval@gmail.com>
|
||||
---
|
||||
drivers/thermal/imx_thermal.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c
|
||||
index f7ec39f46ee4..4798b4b1fd77 100644
|
||||
--- a/drivers/thermal/imx_thermal.c
|
||||
+++ b/drivers/thermal/imx_thermal.c
|
||||
@@ -660,8 +660,11 @@ static int imx_thermal_resume(struct device *dev)
|
||||
{
|
||||
struct imx_thermal_data *data = dev_get_drvdata(dev);
|
||||
struct regmap *map = data->tempmon;
|
||||
+ int ret;
|
||||
|
||||
- clk_prepare_enable(data->thermal_clk);
|
||||
+ ret = clk_prepare_enable(data->thermal_clk);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
/* Enabled thermal sensor after resume */
|
||||
regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN);
|
||||
regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_MEASURE_TEMP);
|
||||
--
|
||||
2.13.3
|
||||
|
||||
From 919054fdfc8adf58c5512fe9872eb53ea0f5525d Mon Sep 17 00:00:00 2001
|
||||
From: Arvind Yadav <arvind.yadav.cs@gmail.com>
|
||||
Date: Tue, 6 Jun 2017 15:04:46 +0530
|
||||
Subject: [PATCH] thermal: hisilicon: Handle return value of clk_prepare_enable
|
||||
|
||||
clk_prepare_enable() can fail here and we must check its return value.
|
||||
|
||||
Signed-off-by: Arvind Yadav <arvind.yadav.cs@gmail.com>
|
||||
Signed-off-by: Eduardo Valentin <edubezval@gmail.com>
|
||||
---
|
||||
drivers/thermal/hisi_thermal.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/thermal/hisi_thermal.c b/drivers/thermal/hisi_thermal.c
|
||||
index f6429666a1cf..9c3ce341eb97 100644
|
||||
--- a/drivers/thermal/hisi_thermal.c
|
||||
+++ b/drivers/thermal/hisi_thermal.c
|
||||
@@ -397,8 +397,11 @@ static int hisi_thermal_suspend(struct device *dev)
|
||||
static int hisi_thermal_resume(struct device *dev)
|
||||
{
|
||||
struct hisi_thermal_data *data = dev_get_drvdata(dev);
|
||||
+ int ret;
|
||||
|
||||
- clk_prepare_enable(data->clk);
|
||||
+ ret = clk_prepare_enable(data->clk);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
|
||||
data->irq_enabled = true;
|
||||
hisi_thermal_enable_bind_irq_sensor(data);
|
||||
--
|
||||
2.13.3
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -1,77 +0,0 @@
|
|||
From patchwork Sat Apr 8 07:18:40 2017
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
MIME-Version: 1.0
|
||||
Content-Transfer-Encoding: 7bit
|
||||
Subject: reset: hi6220: Set module license so that it can be loaded
|
||||
From: Jeremy Linton <lintonrjeremy@gmail.com>
|
||||
X-Patchwork-Id: 9670985
|
||||
Message-Id: <20170408071840.29380-1-lintonrjeremy@gmail.com>
|
||||
To: linux-kernel@vger.kernel.org
|
||||
Cc: p.zabel@pengutronix.de, saberlily.xia@hisilicon.com,
|
||||
puck.chen@hisilicon.com, xinliang.liu@linaro.org,
|
||||
Jeremy Linton <lintonrjeremy@gmail.com>
|
||||
Date: Sat, 8 Apr 2017 02:18:40 -0500
|
||||
|
||||
The hi6220_reset driver can be built as a standalone module
|
||||
yet it cannot be loaded because it depends on GPL exported symbols.
|
||||
|
||||
Lets set the module license so that the module loads, and things like
|
||||
the on-board kirin drm starts working.
|
||||
|
||||
Signed-off-by: Jeremy Linton <lintonrjeremy@gmail.com>
|
||||
reviewed-by: Xinliang Liu <xinliang.liu@linaro.org>
|
||||
---
|
||||
drivers/reset/hisilicon/hi6220_reset.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/drivers/reset/hisilicon/hi6220_reset.c b/drivers/reset/hisilicon/hi6220_reset.c
|
||||
index 35ce53e..d5e5229 100644
|
||||
--- a/drivers/reset/hisilicon/hi6220_reset.c
|
||||
+++ b/drivers/reset/hisilicon/hi6220_reset.c
|
||||
@@ -155,3 +155,5 @@ static int __init hi6220_reset_init(void)
|
||||
}
|
||||
|
||||
postcore_initcall(hi6220_reset_init);
|
||||
+
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
From patchwork Mon Apr 3 05:28:42 2017
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
MIME-Version: 1.0
|
||||
Content-Transfer-Encoding: 7bit
|
||||
Subject: [v2,1/2] regulator: hi655x: Describe consumed platform device
|
||||
From: Jeremy Linton <lintonrjeremy@gmail.com>
|
||||
X-Patchwork-Id: 9658793
|
||||
Message-Id: <20170403052843.12711-2-lintonrjeremy@gmail.com>
|
||||
To: linux-kernel@vger.kernel.org
|
||||
Cc: broonie@kernel.org, lgirdwood@gmail.com, puck.chen@hisilicon.com,
|
||||
lee.jones@linaro.org, Jeremy Linton <lintonrjeremy@gmail.com>
|
||||
Date: Mon, 3 Apr 2017 00:28:42 -0500
|
||||
|
||||
The hi655x-regulator driver consumes a similarly named platform device.
|
||||
Adding that to the module device table, allows modprobe to locate this
|
||||
driver once the device is created.
|
||||
|
||||
Signed-off-by: Jeremy Linton <lintonrjeremy@gmail.com>
|
||||
---
|
||||
drivers/regulator/hi655x-regulator.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/drivers/regulator/hi655x-regulator.c b/drivers/regulator/hi655x-regulator.c
|
||||
index 065c100..36ae54b 100644
|
||||
--- a/drivers/regulator/hi655x-regulator.c
|
||||
+++ b/drivers/regulator/hi655x-regulator.c
|
||||
@@ -214,7 +214,14 @@ static int hi655x_regulator_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static const struct platform_device_id hi655x_regulator_table[] = {
|
||||
+ { .name = "hi655x-regulator" },
|
||||
+ {},
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(platform, hi655x_regulator_table);
|
||||
+
|
||||
static struct platform_driver hi655x_regulator_driver = {
|
||||
+ .id_table = hi655x_regulator_table,
|
||||
.driver = {
|
||||
.name = "hi655x-regulator",
|
||||
},
|
|
@ -0,0 +1 @@
|
|||
# CONFIG_ADXL345_I2C is not set
|
|
@ -0,0 +1 @@
|
|||
# CONFIG_ADXL345_SPI is not set
|
|
@ -0,0 +1 @@
|
|||
CONFIG_ARM64_ERRATUM_858921=y
|
|
@ -0,0 +1 @@
|
|||
CONFIG_BACKLIGHT_ARCXCNN=m
|
|
@ -0,0 +1 @@
|
|||
# CONFIG_BATTERY_LEGO_EV3 is not set
|
|
@ -0,0 +1 @@
|
|||
# CONFIG_BCM_FLEXRM_MBOX is not set
|
|
@ -0,0 +1 @@
|
|||
CONFIG_BFQ_GROUP_IOSCHED=y
|
|
@ -1 +0,0 @@
|
|||
# CONFIG_BLK_DEV_HD is not set
|
|
@ -0,0 +1 @@
|
|||
# CONFIG_BLK_DEV_THROTTLING_LOW is not set
|
|
@ -0,0 +1 @@
|
|||
CONFIG_BT_HCIUART_SERDEV=y
|
|
@ -0,0 +1 @@
|
|||
CONFIG_CAN_HI311X=m
|
|
@ -0,0 +1 @@
|
|||
CONFIG_CAN_MCBA_USB=m
|
|
@ -0,0 +1 @@
|
|||
CONFIG_CAN_PEAK_PCIEFD=m
|
|
@ -0,0 +1 @@
|
|||
CONFIG_CAN_VXCAN=m
|
|
@ -0,0 +1 @@
|
|||
CONFIG_CEC_PLATFORM_DRIVERS=y
|
|
@ -0,0 +1 @@
|
|||
# CONFIG_CRYPTO_DEV_CCREE is not set
|
|
@ -1 +1 @@
|
|||
CONFIG_CRYPTO_DH=m
|
||||
CONFIG_CRYPTO_DH=y
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
CONFIG_DM_INTEGRITY=m
|
|
@ -0,0 +1 @@
|
|||
# CONFIG_DRM_DW_HDMI_AHB_AUDIO is not set
|
|
@ -1 +1 @@
|
|||
CONFIG_DRM_DW_HDMI_I2S_AUDIO=m
|
||||
# CONFIG_DRM_DW_HDMI_I2S_AUDIO is not set
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
CONFIG_DRM_FBDEV_OVERALLOC=100
|
|
@ -0,0 +1 @@
|
|||
# CONFIG_DRM_LVDS_ENCODER is not set
|
|
@ -0,0 +1 @@
|
|||
# CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW is not set
|
|
@ -0,0 +1 @@
|
|||
# CONFIG_DRM_PANEL_LVDS is not set
|
|
@ -0,0 +1 @@
|
|||
# CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2 is not set
|
|
@ -0,0 +1 @@
|
|||
# CONFIG_DRM_PANEL_SITRONIX_ST7789V is not set
|
|
@ -0,0 +1 @@
|
|||
# CONFIG_DRM_RCAR_DW_HDMI is not set
|
|
@ -0,0 +1 @@
|
|||
CONFIG_EARLY_PRINTK_USB_XDBC=y
|
|
@ -0,0 +1 @@
|
|||
CONFIG_EDAC_GHES=y
|
|
@ -1 +0,0 @@
|
|||
CONFIG_EDAC_MM_EDAC=m
|
|
@ -0,0 +1 @@
|
|||
# CONFIG_GPIO_FTGPIO010 is not set
|
|
@ -0,0 +1 @@
|
|||
CONFIG_HD44780=m
|
|
@ -0,0 +1 @@
|
|||
CONFIG_HID_ACCUTOUCH=m
|
|
@ -0,0 +1 @@
|
|||
CONFIG_HID_NTI=m
|
|
@ -0,0 +1 @@
|
|||
CONFIG_HID_SENSOR_HUMIDITY=m
|
|
@ -0,0 +1 @@
|
|||
CONFIG_HID_SENSOR_TEMP=m
|
|
@ -0,0 +1 @@
|
|||
CONFIG_I2C_MUX_LTC4306=m
|
|
@ -0,0 +1 @@
|
|||
CONFIG_IEEE802154_CA8210=m
|
|
@ -0,0 +1 @@
|
|||
# CONFIG_IEEE802154_CA8210_DEBUGFS is not set
|
|
@ -1 +0,0 @@
|
|||
CONFIG_INPUT_MPU3050=m
|
|
@ -0,0 +1 @@
|
|||
CONFIG_IOSCHED_BFQ=m
|
|
@ -0,0 +1 @@
|
|||
CONFIG_IR_SIR=m
|
|
@ -0,0 +1 @@
|
|||
CONFIG_JOYSTICK_PSXPAD_SPI=m
|
|
@ -0,0 +1 @@
|
|||
CONFIG_JOYSTICK_PSXPAD_SPI_FF=y
|
|
@ -1 +0,0 @@
|
|||
CONFIG_LEDS_DELL_NETBOOKS=m
|
|
@ -1 +0,0 @@
|
|||
CONFIG_LIRC_SASEM=m
|
|
@ -0,0 +1 @@
|
|||
# CONFIG_LOAD_UEFI_KEYS is not set
|
|
@ -0,0 +1 @@
|
|||
# CONFIG_LTC2497 is not set
|
|
@ -0,0 +1 @@
|
|||
# CONFIG_LTC2632 is not set
|
|
@ -0,0 +1 @@
|
|||
# CONFIG_MAX1118 is not set
|
|
@ -0,0 +1 @@
|
|||
# CONFIG_MAX30102 is not set
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue