Linux v4.12.3

This commit is contained in:
Justin M. Forbes 2017-07-24 16:25:32 -05:00
parent 884e6796eb
commit 3ff7c261fb
399 changed files with 9680 additions and 13209 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

48
CVE-2017-11473.patch Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 = <&reg_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 = <&reg_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 = <&reg_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 = <&reg_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 = <&reg_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

View File

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

View File

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

View File

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

224
arm-thermal-fixes.patch Normal file
View File

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

View File

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

View File

@ -0,0 +1 @@
# CONFIG_ADXL345_I2C is not set

View File

@ -0,0 +1 @@
# CONFIG_ADXL345_SPI is not set

View File

@ -0,0 +1 @@
CONFIG_ARM64_ERRATUM_858921=y

View File

@ -0,0 +1 @@
CONFIG_BACKLIGHT_ARCXCNN=m

View File

@ -0,0 +1 @@
# CONFIG_BATTERY_LEGO_EV3 is not set

View File

@ -0,0 +1 @@
# CONFIG_BCM_FLEXRM_MBOX is not set

View File

@ -0,0 +1 @@
CONFIG_BFQ_GROUP_IOSCHED=y

View File

@ -1 +0,0 @@
# CONFIG_BLK_DEV_HD is not set

View File

@ -0,0 +1 @@
# CONFIG_BLK_DEV_THROTTLING_LOW is not set

View File

@ -0,0 +1 @@
CONFIG_BT_HCIUART_SERDEV=y

View File

@ -0,0 +1 @@
CONFIG_CAN_HI311X=m

View File

@ -0,0 +1 @@
CONFIG_CAN_MCBA_USB=m

View File

@ -0,0 +1 @@
CONFIG_CAN_PEAK_PCIEFD=m

View File

@ -0,0 +1 @@
CONFIG_CAN_VXCAN=m

View File

@ -0,0 +1 @@
CONFIG_CEC_PLATFORM_DRIVERS=y

View File

@ -0,0 +1 @@
# CONFIG_CRYPTO_DEV_CCREE is not set

View File

@ -1 +1 @@
CONFIG_CRYPTO_DH=m
CONFIG_CRYPTO_DH=y

View File

@ -0,0 +1 @@
CONFIG_DM_INTEGRITY=m

View File

@ -0,0 +1 @@
# CONFIG_DRM_DW_HDMI_AHB_AUDIO is not set

View File

@ -1 +1 @@
CONFIG_DRM_DW_HDMI_I2S_AUDIO=m
# CONFIG_DRM_DW_HDMI_I2S_AUDIO is not set

View File

@ -0,0 +1 @@
CONFIG_DRM_FBDEV_OVERALLOC=100

View File

@ -0,0 +1 @@
# CONFIG_DRM_LVDS_ENCODER is not set

View File

@ -0,0 +1 @@
# CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW is not set

View File

@ -0,0 +1 @@
# CONFIG_DRM_PANEL_LVDS is not set

View File

@ -0,0 +1 @@
# CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2 is not set

View File

@ -0,0 +1 @@
# CONFIG_DRM_PANEL_SITRONIX_ST7789V is not set

View File

@ -0,0 +1 @@
# CONFIG_DRM_RCAR_DW_HDMI is not set

View File

@ -0,0 +1 @@
CONFIG_EARLY_PRINTK_USB_XDBC=y

View File

@ -0,0 +1 @@
CONFIG_EDAC_GHES=y

View File

@ -1 +0,0 @@
CONFIG_EDAC_MM_EDAC=m

View File

@ -0,0 +1 @@
# CONFIG_GPIO_FTGPIO010 is not set

View File

@ -0,0 +1 @@
CONFIG_HD44780=m

View File

@ -0,0 +1 @@
CONFIG_HID_ACCUTOUCH=m

View File

@ -0,0 +1 @@
CONFIG_HID_NTI=m

View File

@ -0,0 +1 @@
CONFIG_HID_SENSOR_HUMIDITY=m

View File

@ -0,0 +1 @@
CONFIG_HID_SENSOR_TEMP=m

View File

@ -0,0 +1 @@
CONFIG_I2C_MUX_LTC4306=m

View File

@ -0,0 +1 @@
CONFIG_IEEE802154_CA8210=m

View File

@ -0,0 +1 @@
# CONFIG_IEEE802154_CA8210_DEBUGFS is not set

View File

@ -1 +0,0 @@
CONFIG_INPUT_MPU3050=m

View File

@ -0,0 +1 @@
CONFIG_IOSCHED_BFQ=m

1
baseconfig/CONFIG_IR_SIR Normal file
View File

@ -0,0 +1 @@
CONFIG_IR_SIR=m

View File

@ -0,0 +1 @@
CONFIG_JOYSTICK_PSXPAD_SPI=m

View File

@ -0,0 +1 @@
CONFIG_JOYSTICK_PSXPAD_SPI_FF=y

View File

@ -1 +0,0 @@
CONFIG_LEDS_DELL_NETBOOKS=m

View File

@ -1 +0,0 @@
CONFIG_LIRC_SASEM=m

View File

@ -0,0 +1 @@
# CONFIG_LOAD_UEFI_KEYS is not set

View File

@ -0,0 +1 @@
# CONFIG_LTC2497 is not set

View File

@ -0,0 +1 @@
# CONFIG_LTC2632 is not set

View File

@ -0,0 +1 @@
# CONFIG_MAX1118 is not set

View File

@ -0,0 +1 @@
# CONFIG_MAX30102 is not set

Some files were not shown because too many files have changed in this diff Show More