mirror of
https://github.com/archlinuxarm/PKGBUILDs.git
synced 2025-02-16 23:57:11 +00:00
core/linux-armv7 to 4.18.13-1
This commit is contained in:
parent
edec685288
commit
87abec7d60
16 changed files with 31 additions and 1203 deletions
|
@ -1,7 +1,7 @@
|
|||
From 6224b22e9cee18409420b6afcbea455a44ab8432 Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@xxxxxx>
|
||||
Date: Sun, 2 Dec 2012 19:59:28 +0100
|
||||
Subject: [PATCH 01/14] ARM: atags: add support for Marvell's u-boot
|
||||
Subject: [PATCH 1/9] ARM: atags: add support for Marvell's u-boot
|
||||
|
||||
Marvell uses a specific atag in its u-boot which includes among other
|
||||
information the MAC addresses for up to 4 network interfaces.
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
From 35efb3ef775746d24439855fb3ceab2a494067a5 Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@xxxxxx>
|
||||
Date: Sun, 2 Dec 2012 19:56:58 +0100
|
||||
Subject: [PATCH 02/14] ARM: atags/fdt: retrieve MAC addresses from Marvell
|
||||
boot loader
|
||||
Subject: [PATCH 2/9] ARM: atags/fdt: retrieve MAC addresses from Marvell boot
|
||||
loader
|
||||
|
||||
The atags are parsed and if a Marvell atag is found, up to 4 MAC
|
||||
addresses are extracted there and assigned to node aliases eth0..3
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
From 4b7d62ac895d119d77a19d7424a1ee0aae6e2e06 Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Mihelich <kevin@archlinuxarm.org>
|
||||
Date: Fri, 5 Sep 2014 15:41:19 -0600
|
||||
Subject: [PATCH 03/14] SMILE Plug device tree file
|
||||
Subject: [PATCH 3/9] SMILE Plug device tree file
|
||||
|
||||
This adds a dts file for the SMILE Plug, which only differs from the Mirabox
|
||||
dts with the LED definitions.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
From 9d43507a5440306db90fc73ab93ef02f71d05f55 Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Mihelich <kevin@archlinuxarm.org>
|
||||
Date: Fri, 5 Sep 2014 15:43:56 -0600
|
||||
Subject: [PATCH 04/14] fix mvsdio eMMC timing
|
||||
Subject: [PATCH 4/9] fix mvsdio eMMC timing
|
||||
|
||||
These changes from Globalscale change the MMC timing to allow the eMMC versions
|
||||
of the Mirabox and SMILE Plug to work.
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
From aff9778d098775518d28ae13f3569345986439ae Mon Sep 17 00:00:00 2001
|
||||
From: popcornmix <popcornmix@gmail.com>
|
||||
Date: Tue, 18 Feb 2014 01:43:50 -0300
|
||||
Subject: [PATCH 05/14] net/smsc95xx: Allow mac address to be set as a
|
||||
parameter
|
||||
Subject: [PATCH 5/9] net/smsc95xx: Allow mac address to be set as a parameter
|
||||
|
||||
---
|
||||
drivers/net/usb/smsc95xx.c | 56 ++++++++++++++++++++++++++++++++++++++
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
From d41a1997e872ccccc6bebc01934224a763901b2e Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Mihelich <kevin@archlinuxarm.org>
|
||||
Date: Sat, 14 Feb 2015 12:32:27 +0100
|
||||
Subject: [PATCH 06/14] set default cubietruck led triggers
|
||||
Subject: [PATCH 6/9] set default cubietruck led triggers
|
||||
|
||||
Signed-off-by: Kevin Mihelich <kevin@archlinuxarm.org>
|
||||
---
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
From f9ca16df1a08bff0130b5635a4ded4efc985d287 Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Mihelich <kevin@archlinuxarm.org>
|
||||
Date: Thu, 11 Aug 2016 00:42:37 -0600
|
||||
Subject: [PATCH 07/14] exynos4412-odroid: set higher minimum buck2 regulator
|
||||
Subject: [PATCH 7/9] exynos4412-odroid: set higher minimum buck2 regulator
|
||||
voltage
|
||||
|
||||
Set a higher minimum voltage to help reboot issue.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
From 3ab4beffef5dba9464bbbf602e26b0de956b5858 Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Mihelich <kevin@archlinuxarm.org>
|
||||
Date: Sun, 7 May 2017 13:32:25 -0600
|
||||
Subject: [PATCH 08/14] ARM: dove: enable ethernet on D3Plug
|
||||
Subject: [PATCH 8/9] ARM: dove: enable ethernet on D3Plug
|
||||
|
||||
Signed-off-by: Kevin Mihelich <kevin@archlinuxarm.org>
|
||||
---
|
||||
|
|
|
@ -1,790 +0,0 @@
|
|||
From bd8a33c8e2e066c662c318dae6f87e02f97667c7 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Chen <peter.chen@nxp.com>
|
||||
Date: Wed, 21 Jun 2017 14:42:03 +0800
|
||||
Subject: [PATCH 09/14] power: add power sequence library
|
||||
|
||||
We have an well-known problem that the device needs to do some power
|
||||
sequence before it can be recognized by related host, the typical
|
||||
example like hard-wired mmc devices and usb devices.
|
||||
|
||||
This power sequence is hard to be described at device tree and handled by
|
||||
related host driver, so we have created a common power sequence
|
||||
library to cover this requirement. The core code has supplied
|
||||
some common helpers for host driver, and individual power sequence
|
||||
libraries handle kinds of power sequence for devices. The pwrseq
|
||||
librares always need to allocate extra instance for compatible
|
||||
string match.
|
||||
|
||||
pwrseq_generic is intended for general purpose of power sequence, which
|
||||
handles gpios and clocks currently, and can cover other controls in
|
||||
future. The host driver just needs to call of_pwrseq_on/of_pwrseq_off
|
||||
if only one power sequence is needed, else call of_pwrseq_on_list
|
||||
/of_pwrseq_off_list instead (eg, USB hub driver).
|
||||
|
||||
For new power sequence library, it needs to add its compatible string
|
||||
and allocation function at pwrseq_match_table_list, then the pwrseq
|
||||
core will match it with DT's, and choose this library at runtime.
|
||||
|
||||
Signed-off-by: Peter Chen <peter.chen@nxp.com>
|
||||
Tested-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name>
|
||||
Tested-by Joshua Clayton <stillcompiling@gmail.com>
|
||||
Reviewed-by: Matthias Kaehlcke <mka@chromium.org>
|
||||
Tested-by: Matthias Kaehlcke <mka@chromium.org>
|
||||
---
|
||||
Documentation/power/power-sequence/design.rst | 54 ++++
|
||||
MAINTAINERS | 9 +
|
||||
drivers/power/Kconfig | 1 +
|
||||
drivers/power/Makefile | 1 +
|
||||
drivers/power/pwrseq/Kconfig | 20 ++
|
||||
drivers/power/pwrseq/Makefile | 2 +
|
||||
drivers/power/pwrseq/core.c | 293 ++++++++++++++++++
|
||||
drivers/power/pwrseq/pwrseq_generic.c | 210 +++++++++++++
|
||||
include/linux/power/pwrseq.h | 84 +++++
|
||||
9 files changed, 674 insertions(+)
|
||||
create mode 100644 Documentation/power/power-sequence/design.rst
|
||||
create mode 100644 drivers/power/pwrseq/Kconfig
|
||||
create mode 100644 drivers/power/pwrseq/Makefile
|
||||
create mode 100644 drivers/power/pwrseq/core.c
|
||||
create mode 100644 drivers/power/pwrseq/pwrseq_generic.c
|
||||
create mode 100644 include/linux/power/pwrseq.h
|
||||
|
||||
diff --git a/Documentation/power/power-sequence/design.rst b/Documentation/power/power-sequence/design.rst
|
||||
new file mode 100644
|
||||
index 000000000000..554608e5f3b6
|
||||
--- /dev/null
|
||||
+++ b/Documentation/power/power-sequence/design.rst
|
||||
@@ -0,0 +1,54 @@
|
||||
+====================================
|
||||
+Power Sequence Library
|
||||
+====================================
|
||||
+
|
||||
+:Date: Feb, 2017
|
||||
+:Author: Peter Chen <peter.chen@nxp.com>
|
||||
+
|
||||
+
|
||||
+Introduction
|
||||
+============
|
||||
+
|
||||
+We have an well-known problem that the device needs to do a power
|
||||
+sequence before it can be recognized by related host, the typical
|
||||
+examples are hard-wired mmc devices and usb devices. The host controller
|
||||
+can't know what kinds of this device is in its bus if the power
|
||||
+sequence has not done, since the related devices driver's probe calling
|
||||
+is determined by runtime according to eunumeration results. Besides,
|
||||
+the devices may have custom power sequence, so the power sequence library
|
||||
+which is independent with the devices is needed.
|
||||
+
|
||||
+Design
|
||||
+============
|
||||
+
|
||||
+The power sequence library includes the core file and customer power
|
||||
+sequence library. The core file exports interfaces are called by
|
||||
+host controller driver for power sequence and customer power sequence
|
||||
+library files to register its power sequence instance to global
|
||||
+power sequence list. The custom power sequence library creates power
|
||||
+sequence instance and implement custom power sequence.
|
||||
+
|
||||
+Since the power sequence describes hardware design, the description is
|
||||
+located at board description file, eg, device tree dts file. And
|
||||
+a specific power sequence belongs to device, so its description
|
||||
+is under the device node, please refer to:
|
||||
+Documentation/devicetree/bindings/power/pwrseq/pwrseq-generic.txt
|
||||
+
|
||||
+Custom power sequence library allocates one power sequence instance at
|
||||
+bootup periods using postcore_initcall, this static allocated instance is
|
||||
+used to compare with device-tree (DT) node to see if this library can be
|
||||
+used for the node or not. When the result is matched, the core API will
|
||||
+try to get resourses (->get, implemented at each library) for power
|
||||
+sequence, if all resources are got, it will try to allocate another
|
||||
+instance for next possible request from host driver.
|
||||
+
|
||||
+Then, the host controller driver can carry out power sequence on for this
|
||||
+DT node, the library will do corresponding operations, like open clocks,
|
||||
+toggle gpio, etc. The power sequence off routine will close and free the
|
||||
+resources, and is called when the parent is removed. And the power
|
||||
+sequence suspend and resume routine can be called at host driver's
|
||||
+suspend and resume routine if needed.
|
||||
+
|
||||
+The exported interfaces
|
||||
+.. kernel-doc:: drivers/power/pwrseq/core.c
|
||||
+ :export:
|
||||
diff --git a/MAINTAINERS b/MAINTAINERS
|
||||
index 544cac829cf4..ac1c64ba20fa 100644
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -11402,6 +11402,15 @@ F: drivers/firmware/psci*.c
|
||||
F: include/linux/psci.h
|
||||
F: include/uapi/linux/psci.h
|
||||
|
||||
+POWER SEQUENCE LIBRARY
|
||||
+M: Peter Chen <Peter.Chen@nxp.com>
|
||||
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb.git
|
||||
+L: linux-pm@vger.kernel.org
|
||||
+S: Maintained
|
||||
+F: Documentation/devicetree/bindings/power/pwrseq/
|
||||
+F: drivers/power/pwrseq/
|
||||
+F: include/linux/power/pwrseq.h
|
||||
+
|
||||
POWER SUPPLY CLASS/SUBSYSTEM and DRIVERS
|
||||
M: Sebastian Reichel <sre@kernel.org>
|
||||
L: linux-pm@vger.kernel.org
|
||||
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
|
||||
index 63454b5cac27..c1bb0465f956 100644
|
||||
--- a/drivers/power/Kconfig
|
||||
+++ b/drivers/power/Kconfig
|
||||
@@ -1,3 +1,4 @@
|
||||
source "drivers/power/avs/Kconfig"
|
||||
source "drivers/power/reset/Kconfig"
|
||||
source "drivers/power/supply/Kconfig"
|
||||
+source "drivers/power/pwrseq/Kconfig"
|
||||
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
|
||||
index ff35c712d824..7db80354b691 100644
|
||||
--- a/drivers/power/Makefile
|
||||
+++ b/drivers/power/Makefile
|
||||
@@ -1,3 +1,4 @@
|
||||
obj-$(CONFIG_POWER_AVS) += avs/
|
||||
obj-$(CONFIG_POWER_RESET) += reset/
|
||||
obj-$(CONFIG_POWER_SUPPLY) += supply/
|
||||
+obj-$(CONFIG_POWER_SEQUENCE) += pwrseq/
|
||||
diff --git a/drivers/power/pwrseq/Kconfig b/drivers/power/pwrseq/Kconfig
|
||||
new file mode 100644
|
||||
index 000000000000..c6b356926cca
|
||||
--- /dev/null
|
||||
+++ b/drivers/power/pwrseq/Kconfig
|
||||
@@ -0,0 +1,20 @@
|
||||
+#
|
||||
+# Power Sequence library
|
||||
+#
|
||||
+
|
||||
+menuconfig POWER_SEQUENCE
|
||||
+ bool "Power sequence control"
|
||||
+ help
|
||||
+ It is used for drivers which needs to do power sequence
|
||||
+ (eg, turn on clock, toggle reset gpio) before the related
|
||||
+ devices can be found by hardware, eg, USB bus.
|
||||
+
|
||||
+if POWER_SEQUENCE
|
||||
+
|
||||
+config PWRSEQ_GENERIC
|
||||
+ bool "Generic power sequence control"
|
||||
+ depends on OF
|
||||
+ help
|
||||
+ This is the generic power sequence control library, and is
|
||||
+ supposed to support common power sequence usage.
|
||||
+endif
|
||||
diff --git a/drivers/power/pwrseq/Makefile b/drivers/power/pwrseq/Makefile
|
||||
new file mode 100644
|
||||
index 000000000000..ad82389028c2
|
||||
--- /dev/null
|
||||
+++ b/drivers/power/pwrseq/Makefile
|
||||
@@ -0,0 +1,2 @@
|
||||
+obj-$(CONFIG_POWER_SEQUENCE) += core.o
|
||||
+obj-$(CONFIG_PWRSEQ_GENERIC) += pwrseq_generic.o
|
||||
diff --git a/drivers/power/pwrseq/core.c b/drivers/power/pwrseq/core.c
|
||||
new file mode 100644
|
||||
index 000000000000..6b78a6691683
|
||||
--- /dev/null
|
||||
+++ b/drivers/power/pwrseq/core.c
|
||||
@@ -0,0 +1,293 @@
|
||||
+/*
|
||||
+ * core.c power sequence core file
|
||||
+ *
|
||||
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
|
||||
+ * Author: Peter Chen <peter.chen@nxp.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 of
|
||||
+ * the License 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.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/list.h>
|
||||
+#include <linux/mutex.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/power/pwrseq.h>
|
||||
+
|
||||
+/*
|
||||
+ * Static power sequence match table
|
||||
+ * - Add compatible (the same with dts node) and related allocation function.
|
||||
+ * - Update related binding doc.
|
||||
+ */
|
||||
+static const struct of_device_id pwrseq_match_table_list[] = {
|
||||
+ { .compatible = "usb424,2513", .data = &pwrseq_generic_alloc_instance},
|
||||
+ { .compatible = "usb424,2514", .data = &pwrseq_generic_alloc_instance},
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+
|
||||
+static int pwrseq_get(struct device_node *np, struct pwrseq *p)
|
||||
+{
|
||||
+ if (p && p->get)
|
||||
+ return p->get(np, p);
|
||||
+
|
||||
+ return -ENOTSUPP;
|
||||
+}
|
||||
+
|
||||
+static int pwrseq_on(struct pwrseq *p)
|
||||
+{
|
||||
+ if (p && p->on)
|
||||
+ return p->on(p);
|
||||
+
|
||||
+ return -ENOTSUPP;
|
||||
+}
|
||||
+
|
||||
+static void pwrseq_off(struct pwrseq *p)
|
||||
+{
|
||||
+ if (p && p->off)
|
||||
+ p->off(p);
|
||||
+}
|
||||
+
|
||||
+static void pwrseq_put(struct pwrseq *p)
|
||||
+{
|
||||
+ if (p && p->put)
|
||||
+ p->put(p);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * of_pwrseq_on - Carry out power sequence on for device node
|
||||
+ *
|
||||
+ * @np: the device node would like to power on
|
||||
+ *
|
||||
+ * Carry out a single device power on. If multiple devices
|
||||
+ * need to be handled, use of_pwrseq_on_list() instead.
|
||||
+ *
|
||||
+ * Return a pointer to the power sequence instance on success, or NULL if
|
||||
+ * not exist, or an error code on failure.
|
||||
+ */
|
||||
+struct pwrseq *of_pwrseq_on(struct device_node *np)
|
||||
+{
|
||||
+ struct pwrseq *pwrseq;
|
||||
+ int ret;
|
||||
+ const struct of_device_id *of_id;
|
||||
+ struct pwrseq *(*alloc_instance)(void);
|
||||
+
|
||||
+ of_id = of_match_node(pwrseq_match_table_list, np);
|
||||
+ if (!of_id)
|
||||
+ return NULL;
|
||||
+
|
||||
+ alloc_instance = of_id->data;
|
||||
+ /* Allocate pwrseq instance */
|
||||
+ pwrseq = alloc_instance();
|
||||
+ if (IS_ERR(pwrseq))
|
||||
+ return pwrseq;
|
||||
+
|
||||
+ ret = pwrseq_get(np, pwrseq);
|
||||
+ if (ret)
|
||||
+ goto pwr_put;
|
||||
+
|
||||
+ ret = pwrseq_on(pwrseq);
|
||||
+ if (ret)
|
||||
+ goto pwr_put;
|
||||
+
|
||||
+ return pwrseq;
|
||||
+
|
||||
+pwr_put:
|
||||
+ pwrseq_put(pwrseq);
|
||||
+ return ERR_PTR(ret);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(of_pwrseq_on);
|
||||
+
|
||||
+/**
|
||||
+ * of_pwrseq_off - Carry out power sequence off for this pwrseq instance
|
||||
+ *
|
||||
+ * @pwrseq: the pwrseq instance which related device would like to be off
|
||||
+ *
|
||||
+ * This API is used to power off single device, it is the opposite
|
||||
+ * operation for of_pwrseq_on.
|
||||
+ */
|
||||
+void of_pwrseq_off(struct pwrseq *pwrseq)
|
||||
+{
|
||||
+ pwrseq_off(pwrseq);
|
||||
+ pwrseq_put(pwrseq);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(of_pwrseq_off);
|
||||
+
|
||||
+/**
|
||||
+ * of_pwrseq_on_list - Carry out power sequence on for list
|
||||
+ *
|
||||
+ * @np: the device node would like to power on
|
||||
+ * @head: the list head for pwrseq list on this bus
|
||||
+ *
|
||||
+ * This API is used to power on multiple devices at single bus.
|
||||
+ * If there are several devices on bus (eg, USB bus), uses this
|
||||
+ * this API. Otherwise, use of_pwrseq_on instead. After the device
|
||||
+ * is powered on successfully, it will be added to pwrseq list for
|
||||
+ * this bus. The caller needs to use mutex_lock for concurrent.
|
||||
+ *
|
||||
+ * Return 0 on success, or -ENOENT if not exist, or an error value on failure.
|
||||
+ */
|
||||
+int of_pwrseq_on_list(struct device_node *np, struct list_head *head)
|
||||
+{
|
||||
+ struct pwrseq *pwrseq;
|
||||
+ struct pwrseq_list_per_dev *pwrseq_list_node;
|
||||
+
|
||||
+ pwrseq_list_node = kzalloc(sizeof(*pwrseq_list_node), GFP_KERNEL);
|
||||
+ if (!pwrseq_list_node)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ pwrseq = of_pwrseq_on(np);
|
||||
+ if (!pwrseq)
|
||||
+ return -ENOENT;
|
||||
+
|
||||
+ if (IS_ERR(pwrseq)) {
|
||||
+ kfree(pwrseq_list_node);
|
||||
+ return PTR_ERR(pwrseq);
|
||||
+ }
|
||||
+
|
||||
+ pwrseq_list_node->pwrseq = pwrseq;
|
||||
+ list_add(&pwrseq_list_node->list, head);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(of_pwrseq_on_list);
|
||||
+
|
||||
+/**
|
||||
+ * of_pwrseq_off_list - Carry out power sequence off for the list
|
||||
+ *
|
||||
+ * @head: the list head for pwrseq instance list on this bus
|
||||
+ *
|
||||
+ * This API is used to power off all devices on this bus, it is
|
||||
+ * the opposite operation for of_pwrseq_on_list.
|
||||
+ * The caller needs to use mutex_lock for concurrent.
|
||||
+ */
|
||||
+void of_pwrseq_off_list(struct list_head *head)
|
||||
+{
|
||||
+ struct pwrseq *pwrseq;
|
||||
+ struct pwrseq_list_per_dev *pwrseq_list_node, *tmp_node;
|
||||
+
|
||||
+ list_for_each_entry_safe(pwrseq_list_node, tmp_node, head, list) {
|
||||
+ pwrseq = pwrseq_list_node->pwrseq;
|
||||
+ of_pwrseq_off(pwrseq);
|
||||
+ list_del(&pwrseq_list_node->list);
|
||||
+ kfree(pwrseq_list_node);
|
||||
+ }
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(of_pwrseq_off_list);
|
||||
+
|
||||
+/**
|
||||
+ * pwrseq_suspend - Carry out power sequence suspend for this pwrseq instance
|
||||
+ *
|
||||
+ * @pwrseq: the pwrseq instance
|
||||
+ *
|
||||
+ * This API is used to do suspend operation on pwrseq instance.
|
||||
+ *
|
||||
+ * Return 0 on success, or an error value otherwise.
|
||||
+ */
|
||||
+int pwrseq_suspend(struct pwrseq *p)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ if (p && p->suspend)
|
||||
+ ret = p->suspend(p);
|
||||
+ else
|
||||
+ return ret;
|
||||
+
|
||||
+ if (!ret)
|
||||
+ p->suspended = true;
|
||||
+ else
|
||||
+ pr_err("%s failed\n", __func__);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(pwrseq_suspend);
|
||||
+
|
||||
+/**
|
||||
+ * pwrseq_resume - Carry out power sequence resume for this pwrseq instance
|
||||
+ *
|
||||
+ * @pwrseq: the pwrseq instance
|
||||
+ *
|
||||
+ * This API is used to do resume operation on pwrseq instance.
|
||||
+ *
|
||||
+ * Return 0 on success, or an error value otherwise.
|
||||
+ */
|
||||
+int pwrseq_resume(struct pwrseq *p)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ if (p && p->resume)
|
||||
+ ret = p->resume(p);
|
||||
+ else
|
||||
+ return ret;
|
||||
+
|
||||
+ if (!ret)
|
||||
+ p->suspended = false;
|
||||
+ else
|
||||
+ pr_err("%s failed\n", __func__);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(pwrseq_resume);
|
||||
+
|
||||
+/**
|
||||
+ * pwrseq_suspend_list - Carry out power sequence suspend for list
|
||||
+ *
|
||||
+ * @head: the list head for pwrseq instance list on this bus
|
||||
+ *
|
||||
+ * This API is used to do suspend on all power sequence instances on this bus.
|
||||
+ * The caller needs to use mutex_lock for concurrent.
|
||||
+ */
|
||||
+int pwrseq_suspend_list(struct list_head *head)
|
||||
+{
|
||||
+ struct pwrseq *pwrseq;
|
||||
+ struct pwrseq_list_per_dev *pwrseq_list_node;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ list_for_each_entry(pwrseq_list_node, head, list) {
|
||||
+ ret = pwrseq_suspend(pwrseq_list_node->pwrseq);
|
||||
+ if (ret)
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (ret) {
|
||||
+ list_for_each_entry(pwrseq_list_node, head, list) {
|
||||
+ pwrseq = pwrseq_list_node->pwrseq;
|
||||
+ if (pwrseq->suspended)
|
||||
+ pwrseq_resume(pwrseq);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(pwrseq_suspend_list);
|
||||
+
|
||||
+/**
|
||||
+ * pwrseq_resume_list - Carry out power sequence resume for the list
|
||||
+ *
|
||||
+ * @head: the list head for pwrseq instance list on this bus
|
||||
+ *
|
||||
+ * This API is used to do resume on all power sequence instances on this bus.
|
||||
+ * The caller needs to use mutex_lock for concurrent.
|
||||
+ */
|
||||
+int pwrseq_resume_list(struct list_head *head)
|
||||
+{
|
||||
+ struct pwrseq_list_per_dev *pwrseq_list_node;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ list_for_each_entry(pwrseq_list_node, head, list) {
|
||||
+ ret = pwrseq_resume(pwrseq_list_node->pwrseq);
|
||||
+ if (ret)
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(pwrseq_resume_list);
|
||||
diff --git a/drivers/power/pwrseq/pwrseq_generic.c b/drivers/power/pwrseq/pwrseq_generic.c
|
||||
new file mode 100644
|
||||
index 000000000000..b7bbd6c5b47d
|
||||
--- /dev/null
|
||||
+++ b/drivers/power/pwrseq/pwrseq_generic.c
|
||||
@@ -0,0 +1,210 @@
|
||||
+/*
|
||||
+ * pwrseq_generic.c Generic power sequence handling
|
||||
+ *
|
||||
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
|
||||
+ * Author: Peter Chen <peter.chen@nxp.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 of
|
||||
+ * the License 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.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/gpio.h>
|
||||
+#include <linux/gpio/consumer.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/of_gpio.h>
|
||||
+#include <linux/slab.h>
|
||||
+
|
||||
+#include <linux/power/pwrseq.h>
|
||||
+
|
||||
+struct pwrseq_generic {
|
||||
+ struct pwrseq pwrseq;
|
||||
+ struct gpio_desc *gpiod_reset;
|
||||
+ struct clk *clks[PWRSEQ_MAX_CLKS];
|
||||
+ u32 duration_us;
|
||||
+ bool suspended;
|
||||
+};
|
||||
+
|
||||
+#define to_generic_pwrseq(p) container_of(p, struct pwrseq_generic, pwrseq)
|
||||
+
|
||||
+static int pwrseq_generic_suspend(struct pwrseq *pwrseq)
|
||||
+{
|
||||
+ struct pwrseq_generic *pwrseq_gen = to_generic_pwrseq(pwrseq);
|
||||
+ int clk;
|
||||
+
|
||||
+ for (clk = PWRSEQ_MAX_CLKS - 1; clk >= 0; clk--)
|
||||
+ clk_disable_unprepare(pwrseq_gen->clks[clk]);
|
||||
+
|
||||
+ pwrseq_gen->suspended = true;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int pwrseq_generic_resume(struct pwrseq *pwrseq)
|
||||
+{
|
||||
+ struct pwrseq_generic *pwrseq_gen = to_generic_pwrseq(pwrseq);
|
||||
+ int clk, ret = 0;
|
||||
+
|
||||
+ for (clk = 0; clk < PWRSEQ_MAX_CLKS && pwrseq_gen->clks[clk]; clk++) {
|
||||
+ ret = clk_prepare_enable(pwrseq_gen->clks[clk]);
|
||||
+ if (ret) {
|
||||
+ pr_err("Can't enable clock, ret=%d\n", ret);
|
||||
+ goto err_disable_clks;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ pwrseq_gen->suspended = false;
|
||||
+ return ret;
|
||||
+
|
||||
+err_disable_clks:
|
||||
+ while (--clk >= 0)
|
||||
+ clk_disable_unprepare(pwrseq_gen->clks[clk]);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void pwrseq_generic_put(struct pwrseq *pwrseq)
|
||||
+{
|
||||
+ struct pwrseq_generic *pwrseq_gen = to_generic_pwrseq(pwrseq);
|
||||
+ int clk;
|
||||
+
|
||||
+ if (pwrseq_gen->gpiod_reset)
|
||||
+ gpiod_put(pwrseq_gen->gpiod_reset);
|
||||
+
|
||||
+ for (clk = 0; clk < PWRSEQ_MAX_CLKS; clk++)
|
||||
+ clk_put(pwrseq_gen->clks[clk]);
|
||||
+
|
||||
+ kfree(pwrseq_gen);
|
||||
+}
|
||||
+
|
||||
+static void pwrseq_generic_off(struct pwrseq *pwrseq)
|
||||
+{
|
||||
+ struct pwrseq_generic *pwrseq_gen = to_generic_pwrseq(pwrseq);
|
||||
+ int clk;
|
||||
+
|
||||
+ if (pwrseq_gen->suspended)
|
||||
+ return;
|
||||
+
|
||||
+ for (clk = PWRSEQ_MAX_CLKS - 1; clk >= 0; clk--)
|
||||
+ clk_disable_unprepare(pwrseq_gen->clks[clk]);
|
||||
+}
|
||||
+
|
||||
+static int pwrseq_generic_on(struct pwrseq *pwrseq)
|
||||
+{
|
||||
+ struct pwrseq_generic *pwrseq_gen = to_generic_pwrseq(pwrseq);
|
||||
+ int clk, ret = 0;
|
||||
+ struct gpio_desc *gpiod_reset = pwrseq_gen->gpiod_reset;
|
||||
+
|
||||
+ for (clk = 0; clk < PWRSEQ_MAX_CLKS && pwrseq_gen->clks[clk]; clk++) {
|
||||
+ ret = clk_prepare_enable(pwrseq_gen->clks[clk]);
|
||||
+ if (ret) {
|
||||
+ pr_err("Can't enable clock, ret=%d\n", ret);
|
||||
+ goto err_disable_clks;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (gpiod_reset) {
|
||||
+ u32 duration_us = pwrseq_gen->duration_us;
|
||||
+
|
||||
+ if (duration_us <= 10)
|
||||
+ udelay(10);
|
||||
+ else
|
||||
+ usleep_range(duration_us, duration_us + 100);
|
||||
+ gpiod_set_value(gpiod_reset, 0);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+
|
||||
+err_disable_clks:
|
||||
+ while (--clk >= 0)
|
||||
+ clk_disable_unprepare(pwrseq_gen->clks[clk]);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int pwrseq_generic_get(struct device_node *np, struct pwrseq *pwrseq)
|
||||
+{
|
||||
+ struct pwrseq_generic *pwrseq_gen = to_generic_pwrseq(pwrseq);
|
||||
+ enum of_gpio_flags flags;
|
||||
+ int reset_gpio, clk, ret = 0;
|
||||
+
|
||||
+ for (clk = 0; clk < PWRSEQ_MAX_CLKS; clk++) {
|
||||
+ pwrseq_gen->clks[clk] = of_clk_get(np, clk);
|
||||
+ if (IS_ERR(pwrseq_gen->clks[clk])) {
|
||||
+ ret = PTR_ERR(pwrseq_gen->clks[clk]);
|
||||
+ if (ret != -ENOENT)
|
||||
+ goto err_put_clks;
|
||||
+ pwrseq_gen->clks[clk] = NULL;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ reset_gpio = of_get_named_gpio_flags(np, "reset-gpios", 0, &flags);
|
||||
+ if (gpio_is_valid(reset_gpio)) {
|
||||
+ unsigned long gpio_flags;
|
||||
+
|
||||
+ if (flags & OF_GPIO_ACTIVE_LOW)
|
||||
+ gpio_flags = GPIOF_ACTIVE_LOW | GPIOF_OUT_INIT_LOW;
|
||||
+ else
|
||||
+ gpio_flags = GPIOF_OUT_INIT_HIGH;
|
||||
+
|
||||
+ ret = gpio_request_one(reset_gpio, gpio_flags,
|
||||
+ "pwrseq-reset-gpios");
|
||||
+ if (ret)
|
||||
+ goto err_put_clks;
|
||||
+
|
||||
+ pwrseq_gen->gpiod_reset = gpio_to_desc(reset_gpio);
|
||||
+ of_property_read_u32(np, "reset-duration-us",
|
||||
+ &pwrseq_gen->duration_us);
|
||||
+ } else if (reset_gpio == -ENOENT) {
|
||||
+ ; /* no such gpio */
|
||||
+ } else {
|
||||
+ ret = reset_gpio;
|
||||
+ pr_err("Failed to get reset gpio on %s, err = %d\n",
|
||||
+ np->full_name, reset_gpio);
|
||||
+ goto err_put_clks;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_put_clks:
|
||||
+ while (--clk >= 0)
|
||||
+ clk_put(pwrseq_gen->clks[clk]);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * pwrseq_generic_alloc_instance - power sequence instance allocation
|
||||
+ *
|
||||
+ * This function is used to allocate one generic power sequence instance,
|
||||
+ * it is called when the system boots up and after one power sequence
|
||||
+ * instance is got successfully.
|
||||
+ *
|
||||
+ * Return zero on success or an error code otherwise.
|
||||
+ */
|
||||
+struct pwrseq *pwrseq_generic_alloc_instance(void)
|
||||
+{
|
||||
+ struct pwrseq_generic *pwrseq_gen;
|
||||
+
|
||||
+ pwrseq_gen = kzalloc(sizeof(*pwrseq_gen), GFP_KERNEL);
|
||||
+ if (!pwrseq_gen)
|
||||
+ return ERR_PTR(-ENOMEM);
|
||||
+
|
||||
+ pwrseq_gen->pwrseq.get = pwrseq_generic_get;
|
||||
+ pwrseq_gen->pwrseq.on = pwrseq_generic_on;
|
||||
+ pwrseq_gen->pwrseq.off = pwrseq_generic_off;
|
||||
+ pwrseq_gen->pwrseq.put = pwrseq_generic_put;
|
||||
+ pwrseq_gen->pwrseq.suspend = pwrseq_generic_suspend;
|
||||
+ pwrseq_gen->pwrseq.resume = pwrseq_generic_resume;
|
||||
+
|
||||
+ return &pwrseq_gen->pwrseq;
|
||||
+}
|
||||
diff --git a/include/linux/power/pwrseq.h b/include/linux/power/pwrseq.h
|
||||
new file mode 100644
|
||||
index 000000000000..c5b278f5f2ae
|
||||
--- /dev/null
|
||||
+++ b/include/linux/power/pwrseq.h
|
||||
@@ -0,0 +1,84 @@
|
||||
+#ifndef __LINUX_PWRSEQ_H
|
||||
+#define __LINUX_PWRSEQ_H
|
||||
+
|
||||
+#include <linux/of.h>
|
||||
+
|
||||
+#define PWRSEQ_MAX_CLKS 3
|
||||
+
|
||||
+/**
|
||||
+ * struct pwrseq - the power sequence structure
|
||||
+ * @pwrseq_of_match_table: the OF device id table this pwrseq library supports
|
||||
+ * @node: the list pointer to be added to pwrseq list
|
||||
+ * @get: the API is used to get pwrseq instance from the device node
|
||||
+ * @on: do power on for this pwrseq instance
|
||||
+ * @off: do power off for this pwrseq instance
|
||||
+ * @put: release the resources on this pwrseq instance
|
||||
+ * @suspend: do suspend operation on this pwrseq instance
|
||||
+ * @resume: do resume operation on this pwrseq instance
|
||||
+ */
|
||||
+struct pwrseq {
|
||||
+ const struct of_device_id *pwrseq_of_match_table;
|
||||
+ struct list_head node;
|
||||
+ int (*get)(struct device_node *np, struct pwrseq *p);
|
||||
+ int (*on)(struct pwrseq *p);
|
||||
+ void (*off)(struct pwrseq *p);
|
||||
+ void (*put)(struct pwrseq *p);
|
||||
+ int (*suspend)(struct pwrseq *p);
|
||||
+ int (*resume)(struct pwrseq *p);
|
||||
+ bool suspended;
|
||||
+};
|
||||
+
|
||||
+/* used for power sequence instance list in one driver */
|
||||
+struct pwrseq_list_per_dev {
|
||||
+ struct pwrseq *pwrseq;
|
||||
+ struct list_head list;
|
||||
+};
|
||||
+
|
||||
+#if IS_ENABLED(CONFIG_POWER_SEQUENCE)
|
||||
+struct pwrseq *of_pwrseq_on(struct device_node *np);
|
||||
+void of_pwrseq_off(struct pwrseq *pwrseq);
|
||||
+int of_pwrseq_on_list(struct device_node *np, struct list_head *head);
|
||||
+void of_pwrseq_off_list(struct list_head *head);
|
||||
+int pwrseq_suspend(struct pwrseq *p);
|
||||
+int pwrseq_resume(struct pwrseq *p);
|
||||
+int pwrseq_suspend_list(struct list_head *head);
|
||||
+int pwrseq_resume_list(struct list_head *head);
|
||||
+#else
|
||||
+static inline struct pwrseq *of_pwrseq_on(struct device_node *np)
|
||||
+{
|
||||
+ return NULL;
|
||||
+}
|
||||
+static void of_pwrseq_off(struct pwrseq *pwrseq) {}
|
||||
+static int of_pwrseq_on_list(struct device_node *np, struct list_head *head)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+static void of_pwrseq_off_list(struct list_head *head) {}
|
||||
+static int pwrseq_suspend(struct pwrseq *p)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+static int pwrseq_resume(struct pwrseq *p)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+static int pwrseq_suspend_list(struct list_head *head)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+static int pwrseq_resume_list(struct list_head *head)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+#endif /* CONFIG_POWER_SEQUENCE */
|
||||
+
|
||||
+#if IS_ENABLED(CONFIG_PWRSEQ_GENERIC)
|
||||
+extern struct pwrseq *pwrseq_generic_alloc_instance(void);
|
||||
+#else
|
||||
+static inline struct pwrseq *pwrseq_generic_alloc_instance(void)
|
||||
+{
|
||||
+ return ERR_PTR(-ENOTSUPP);
|
||||
+}
|
||||
+#endif /* CONFIG_PWRSEQ_GENERIC */
|
||||
+
|
||||
+#endif /* __LINUX_PWRSEQ_H */
|
||||
--
|
||||
2.19.0
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
From 917f2c7ef10029386dc0a0e3046aa5087499e94a Mon Sep 17 00:00:00 2001
|
||||
From 0bd732a6983c94f1dc241f75b5fdbc8d62e9834d Mon Sep 17 00:00:00 2001
|
||||
From: Hal Emmerich <hal@halemmerich.com>
|
||||
Date: Thu, 19 Jul 2018 21:48:08 -0500
|
||||
Subject: [PATCH 14/14] usb: dwc2: disable power_down on rockchip devices
|
||||
Subject: [PATCH 9/9] usb: dwc2: disable power_down on rockchip devices
|
||||
|
||||
The bug would let the usb controller enter partial power down,
|
||||
which was formally known as hibernate, upon boot if nothing was plugged
|
|
@ -1,164 +0,0 @@
|
|||
From b8a4a0686bf56ac41d3eab86b1397968bca5aea9 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Chen <peter.chen@nxp.com>
|
||||
Date: Wed, 21 Jun 2017 14:42:05 +0800
|
||||
Subject: [PATCH 10/14] usb: core: add power sequence handling for USB devices
|
||||
|
||||
Some hard-wired USB devices need to do power sequence to let the
|
||||
device work normally, the typical power sequence like: enable USB
|
||||
PHY clock, toggle reset pin, etc. But current Linux USB driver
|
||||
lacks of such code to do it, it may cause some hard-wired USB devices
|
||||
works abnormal or can't be recognized by controller at all.
|
||||
|
||||
In this patch, it calls power sequence library APIs to finish
|
||||
the power sequence events. It will do power on sequence at hub's
|
||||
probe for all devices under this hub (includes root hub).
|
||||
At hub_disconnect, it will do power off sequence which is at powered
|
||||
on list.
|
||||
|
||||
Signed-off-by: Peter Chen <peter.chen@nxp.com>
|
||||
Tested-by Joshua Clayton <stillcompiling@gmail.com>
|
||||
Tested-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name>
|
||||
Reviewed-by: Vaibhav Hiremath <hvaibhav.linux@gmail.com>
|
||||
Acked-by: Alan Stern <stern@rowland.harvard.edu>
|
||||
---
|
||||
drivers/usb/Kconfig | 1 +
|
||||
drivers/usb/core/hub.c | 49 ++++++++++++++++++++++++++++++++++++++----
|
||||
drivers/usb/core/hub.h | 1 +
|
||||
3 files changed, 47 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
|
||||
index 987fc5ba6321..bd09fc8ff763 100644
|
||||
--- a/drivers/usb/Kconfig
|
||||
+++ b/drivers/usb/Kconfig
|
||||
@@ -45,6 +45,7 @@ config USB
|
||||
tristate "Support for Host-side USB"
|
||||
depends on USB_ARCH_HAS_HCD
|
||||
select USB_COMMON
|
||||
+ select POWER_SEQUENCE
|
||||
select NLS # for UTF-8 strings
|
||||
---help---
|
||||
Universal Serial Bus (USB) is a specification for a serial bus
|
||||
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
|
||||
index 1fb266809966..3003d482109b 100644
|
||||
--- a/drivers/usb/core/hub.c
|
||||
+++ b/drivers/usb/core/hub.c
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/pm_qos.h>
|
||||
+#include <linux/power/pwrseq.h>
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/byteorder.h>
|
||||
@@ -1658,6 +1659,7 @@ static void hub_disconnect(struct usb_interface *intf)
|
||||
hub->error = 0;
|
||||
hub_quiesce(hub, HUB_DISCONNECT);
|
||||
|
||||
+ of_pwrseq_off_list(&hub->pwrseq_list);
|
||||
mutex_lock(&usb_port_peer_mutex);
|
||||
|
||||
/* Avoid races with recursively_mark_NOTATTACHED() */
|
||||
@@ -1704,11 +1706,41 @@ static bool hub_descriptor_is_sane(struct usb_host_interface *desc)
|
||||
return true;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_OF
|
||||
+static int hub_of_pwrseq_on(struct usb_hub *hub)
|
||||
+{
|
||||
+ struct device *parent;
|
||||
+ struct usb_device *hdev = hub->hdev;
|
||||
+ struct device_node *np;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (hdev->parent)
|
||||
+ parent = &hdev->dev;
|
||||
+ else
|
||||
+ parent = bus_to_hcd(hdev->bus)->self.sysdev;
|
||||
+
|
||||
+ for_each_child_of_node(parent->of_node, np) {
|
||||
+ ret = of_pwrseq_on_list(np, &hub->pwrseq_list);
|
||||
+ /* Maybe no power sequence library is chosen */
|
||||
+ if (ret && ret != -ENOENT)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+#else
|
||||
+static int hub_of_pwrseq_on(struct usb_hub *hub)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
||||
{
|
||||
struct usb_host_interface *desc;
|
||||
struct usb_device *hdev;
|
||||
struct usb_hub *hub;
|
||||
+ int ret = -ENODEV;
|
||||
|
||||
desc = intf->cur_altsetting;
|
||||
hdev = interface_to_usbdev(intf);
|
||||
@@ -1799,6 +1831,7 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
||||
INIT_DELAYED_WORK(&hub->leds, led_work);
|
||||
INIT_DELAYED_WORK(&hub->init_work, NULL);
|
||||
INIT_WORK(&hub->events, hub_event);
|
||||
+ INIT_LIST_HEAD(&hub->pwrseq_list);
|
||||
usb_get_intf(intf);
|
||||
usb_get_dev(hdev);
|
||||
|
||||
@@ -1812,11 +1845,14 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
||||
if (id->driver_info & HUB_QUIRK_CHECK_PORT_AUTOSUSPEND)
|
||||
hub->quirk_check_port_auto_suspend = 1;
|
||||
|
||||
- if (hub_configure(hub, &desc->endpoint[0].desc) >= 0)
|
||||
- return 0;
|
||||
+ if (hub_configure(hub, &desc->endpoint[0].desc) >= 0) {
|
||||
+ ret = hub_of_pwrseq_on(hub);
|
||||
+ if (!ret)
|
||||
+ return 0;
|
||||
+ }
|
||||
|
||||
hub_disconnect(intf);
|
||||
- return -ENODEV;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -3657,14 +3693,19 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
|
||||
|
||||
/* stop hub_wq and related activity */
|
||||
hub_quiesce(hub, HUB_SUSPEND);
|
||||
- return 0;
|
||||
+ return pwrseq_suspend_list(&hub->pwrseq_list);
|
||||
}
|
||||
|
||||
static int hub_resume(struct usb_interface *intf)
|
||||
{
|
||||
struct usb_hub *hub = usb_get_intfdata(intf);
|
||||
+ int ret;
|
||||
|
||||
dev_dbg(&intf->dev, "%s\n", __func__);
|
||||
+ ret = pwrseq_resume_list(&hub->pwrseq_list);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
hub_activate(hub, HUB_RESUME);
|
||||
return 0;
|
||||
}
|
||||
diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h
|
||||
index 4accfb63f7dc..abe71c5e84cb 100644
|
||||
--- a/drivers/usb/core/hub.h
|
||||
+++ b/drivers/usb/core/hub.h
|
||||
@@ -70,6 +70,7 @@ struct usb_hub {
|
||||
struct delayed_work init_work;
|
||||
struct work_struct events;
|
||||
struct usb_port **ports;
|
||||
+ struct list_head pwrseq_list; /* powered pwrseq node list */
|
||||
};
|
||||
|
||||
/**
|
||||
--
|
||||
2.19.0
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
From f1eed409a101441d63efaa49dee661e909f1a761 Mon Sep 17 00:00:00 2001
|
||||
From: Joshua Clayton <stillcompiling@gmail.com>
|
||||
Date: Wed, 21 Jun 2017 14:42:06 +0800
|
||||
Subject: [PATCH 11/14] ARM: dts: imx6qdl: Enable usb node children with <reg>
|
||||
|
||||
Give usb nodes #address and #size attributes, so that a child node
|
||||
representing a permanently connected device such as an onboard hub may
|
||||
be addressed with a <reg> attribute
|
||||
|
||||
Signed-off-by: Joshua Clayton <stillcompiling@gmail.com>
|
||||
Signed-off-by: Peter Chen <peter.chen@nxp.com>
|
||||
---
|
||||
arch/arm/boot/dts/imx6qdl.dtsi | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
|
||||
index 911141e24681..c74e9c7a83bf 100644
|
||||
--- a/arch/arm/boot/dts/imx6qdl.dtsi
|
||||
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
|
||||
@@ -965,6 +965,8 @@
|
||||
|
||||
usbh1: usb@2184200 {
|
||||
compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
reg = <0x02184200 0x200>;
|
||||
interrupts = <0 40 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&clks IMX6QDL_CLK_USBOH3>;
|
||||
@@ -979,6 +981,8 @@
|
||||
|
||||
usbh2: usb@2184400 {
|
||||
compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
reg = <0x02184400 0x200>;
|
||||
interrupts = <0 41 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&clks IMX6QDL_CLK_USBOH3>;
|
||||
@@ -992,6 +996,8 @@
|
||||
|
||||
usbh3: usb@2184600 {
|
||||
compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
reg = <0x02184600 0x200>;
|
||||
interrupts = <0 42 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&clks IMX6QDL_CLK_USBOH3>;
|
||||
--
|
||||
2.19.0
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
From a154b0eeb6953a096afc7ee940feea11c3b2c6b5 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Chen <peter.chen@nxp.com>
|
||||
Date: Wed, 21 Jun 2017 14:42:07 +0800
|
||||
Subject: [PATCH 12/14] ARM: dts: imx6qdl-udoo.dtsi: fix onboard USB HUB
|
||||
property
|
||||
|
||||
The current dts describes USB HUB's property at USB controller's
|
||||
entry, it is improper. The USB HUB should be the child node
|
||||
under USB controller, and power sequence properties are under
|
||||
it. Besides, using gpio pinctrl setting for USB2415's reset pin.
|
||||
|
||||
Signed-off-by: Peter Chen <peter.chen@nxp.com>
|
||||
Signed-off-by: Joshua Clayton <stillcompiling@gmail.com>
|
||||
Tested-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name>
|
||||
---
|
||||
arch/arm/boot/dts/imx6qdl-udoo.dtsi | 26 ++++++++++++--------------
|
||||
1 file changed, 12 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/imx6qdl-udoo.dtsi b/arch/arm/boot/dts/imx6qdl-udoo.dtsi
|
||||
index 4f27861bbb32..dead14b0d4bf 100644
|
||||
--- a/arch/arm/boot/dts/imx6qdl-udoo.dtsi
|
||||
+++ b/arch/arm/boot/dts/imx6qdl-udoo.dtsi
|
||||
@@ -5,6 +5,8 @@
|
||||
* Author: Fabio Estevam <fabio.estevam@freescale.com>
|
||||
*/
|
||||
|
||||
+#include <dt-bindings/gpio/gpio.h>
|
||||
+
|
||||
/ {
|
||||
aliases {
|
||||
backlight = &backlight;
|
||||
@@ -61,17 +63,6 @@
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
- reg_usb_h1_vbus: regulator@0 {
|
||||
- compatible = "regulator-fixed";
|
||||
- reg = <0>;
|
||||
- regulator-name = "usb_h1_vbus";
|
||||
- regulator-min-microvolt = <5000000>;
|
||||
- regulator-max-microvolt = <5000000>;
|
||||
- enable-active-high;
|
||||
- startup-delay-us = <2>; /* USB2415 requires a POR of 1 us minimum */
|
||||
- gpio = <&gpio7 12 0>;
|
||||
- };
|
||||
-
|
||||
reg_panel: regulator@1 {
|
||||
compatible = "regulator-fixed";
|
||||
reg = <1>;
|
||||
@@ -197,7 +188,7 @@
|
||||
|
||||
pinctrl_usbh: usbhgrp {
|
||||
fsl,pins = <
|
||||
- MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x80000000
|
||||
+ MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x1b0b0
|
||||
MX6QDL_PAD_NANDF_CS2__CCM_CLKO2 0x130b0
|
||||
>;
|
||||
};
|
||||
@@ -268,9 +259,16 @@
|
||||
&usbh1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_usbh>;
|
||||
- vbus-supply = <®_usb_h1_vbus>;
|
||||
- clocks = <&clks IMX6QDL_CLK_CKO>;
|
||||
status = "okay";
|
||||
+
|
||||
+ usb2415: hub@1 {
|
||||
+ compatible = "usb424,2514";
|
||||
+ reg = <1>;
|
||||
+
|
||||
+ clocks = <&clks IMX6QDL_CLK_CKO>;
|
||||
+ reset-gpios = <&gpio7 12 GPIO_ACTIVE_LOW>;
|
||||
+ reset-duration-us = <3000>;
|
||||
+ };
|
||||
};
|
||||
|
||||
&usdhc3 {
|
||||
--
|
||||
2.19.0
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
From eec27ce353f52898b5341814f403441b0b254097 Mon Sep 17 00:00:00 2001
|
||||
From: Joshua Clayton <stillcompiling@gmail.com>
|
||||
Date: Wed, 21 Jun 2017 14:42:08 +0800
|
||||
Subject: [PATCH 13/14] ARM: dts: imx6q-evi: Fix onboard hub reset line
|
||||
|
||||
Previously the onboard hub was made to work by treating its
|
||||
reset gpio as a regulator enable.
|
||||
Get rid of that kludge now that pwseq has added reset gpio support
|
||||
Move pin muxing the hub reset pin into the usbh1 group
|
||||
|
||||
Signed-off-by: Joshua Clayton <stillcompiling@gmail.com>
|
||||
Signed-off-by: Peter Chen <peter.chen@nxp.com>
|
||||
---
|
||||
arch/arm/boot/dts/imx6q-evi.dts | 25 +++++++------------------
|
||||
1 file changed, 7 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/imx6q-evi.dts b/arch/arm/boot/dts/imx6q-evi.dts
|
||||
index fcd257bc5ac3..d32fa81bba95 100644
|
||||
--- a/arch/arm/boot/dts/imx6q-evi.dts
|
||||
+++ b/arch/arm/boot/dts/imx6q-evi.dts
|
||||
@@ -54,18 +54,6 @@
|
||||
reg = <0x10000000 0x40000000>;
|
||||
};
|
||||
|
||||
- reg_usbh1_vbus: regulator-usbhubreset {
|
||||
- compatible = "regulator-fixed";
|
||||
- regulator-name = "usbh1_vbus";
|
||||
- regulator-min-microvolt = <5000000>;
|
||||
- regulator-max-microvolt = <5000000>;
|
||||
- enable-active-high;
|
||||
- startup-delay-us = <2>;
|
||||
- pinctrl-names = "default";
|
||||
- pinctrl-0 = <&pinctrl_usbh1_hubreset>;
|
||||
- gpio = <&gpio7 12 GPIO_ACTIVE_HIGH>;
|
||||
- };
|
||||
-
|
||||
reg_usb_otg_vbus: regulator-usbotgvbus {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "usb_otg_vbus";
|
||||
@@ -213,12 +201,18 @@
|
||||
};
|
||||
|
||||
&usbh1 {
|
||||
- vbus-supply = <®_usbh1_vbus>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_usbh1>;
|
||||
dr_mode = "host";
|
||||
disable-over-current;
|
||||
status = "okay";
|
||||
+
|
||||
+ usb2415host: hub@1 {
|
||||
+ compatible = "usb424,2513";
|
||||
+ reg = <1>;
|
||||
+ reset-gpios = <&gpio7 12 GPIO_ACTIVE_LOW>;
|
||||
+ reset-duration-us = <3000>;
|
||||
+ };
|
||||
};
|
||||
|
||||
&usbotg {
|
||||
@@ -481,11 +475,6 @@
|
||||
MX6QDL_PAD_GPIO_3__USB_H1_OC 0x1b0b0
|
||||
/* usbh1_b OC */
|
||||
MX6QDL_PAD_GPIO_0__GPIO1_IO00 0x1b0b0
|
||||
- >;
|
||||
- };
|
||||
-
|
||||
- pinctrl_usbh1_hubreset: usbh1hubresetgrp {
|
||||
- fsl,pins = <
|
||||
MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x1b0b0
|
||||
>;
|
||||
};
|
||||
--
|
||||
2.19.0
|
||||
|
|
@ -7,9 +7,9 @@ pkgbase=linux-armv7
|
|||
_srcname=linux-4.18
|
||||
_kernelname=${pkgbase#linux}
|
||||
_desc="ARMv7 multi-platform"
|
||||
pkgver=4.18.12
|
||||
pkgrel=2
|
||||
rcnrel=armv7-x13
|
||||
pkgver=4.18.13
|
||||
pkgrel=1
|
||||
rcnrel=armv7-x14
|
||||
arch=('armv7h')
|
||||
url="http://www.kernel.org/"
|
||||
license=('GPL2')
|
||||
|
@ -26,12 +26,7 @@ source=("http://www.kernel.org/pub/linux/kernel/v4.x/${_srcname}.tar.xz"
|
|||
'0006-set-default-cubietruck-led-triggers.patch'
|
||||
'0007-exynos4412-odroid-set-higher-minimum-buck2-regulator.patch'
|
||||
'0008-ARM-dove-enable-ethernet-on-D3Plug.patch'
|
||||
'0009-power-add-power-sequence-library.patch'
|
||||
'0010-usb-core-add-power-sequence-handling-for-USB-devices.patch'
|
||||
'0011-ARM-dts-imx6qdl-Enable-usb-node-children-with-reg.patch'
|
||||
'0012-ARM-dts-imx6qdl-udoo.dtsi-fix-onboard-USB-HUB-proper.patch'
|
||||
'0013-ARM-dts-imx6q-evi-Fix-onboard-hub-reset-line.patch'
|
||||
'0014-usb-dwc2-disable-power_down-on-rockchip-devices.patch'
|
||||
'0009-usb-dwc2-disable-power_down-on-rockchip-devices.patch'
|
||||
'config'
|
||||
'kernel.its'
|
||||
'kernel.keyblock'
|
||||
|
@ -39,23 +34,18 @@ source=("http://www.kernel.org/pub/linux/kernel/v4.x/${_srcname}.tar.xz"
|
|||
'linux.preset'
|
||||
'99-linux.hook')
|
||||
md5sums=('bee5fe53ee1c3142b8f0c12c0d3348f9'
|
||||
'8186fbd0e436c775e2dc70148ff2f446'
|
||||
'50c4dde8b3c32c1b2f82d3d44ba1992f'
|
||||
'82059089d9ad1ef5dbb838eda091fcfa'
|
||||
'febcfc46f7911d2523f0aa2aaaa9ca47'
|
||||
'3fe6b37f56aa09c25b1d2401a266b7ca'
|
||||
'03f34822382a4feec407bd7de1ae2ebb'
|
||||
'1a77b60d684676df8b4edd8ad9e25ffa'
|
||||
'b8b4e4e349626a6d2d83c2d44f7099e2'
|
||||
'ddfe27165ecf85ce754514d5bcc12d90'
|
||||
'75f192717be2324c6221d4b378acce7a'
|
||||
'ec405026e7ce1082cb28910e98eb2ff6'
|
||||
'6ea14429f233f7b7dd96a9de95ac33dc'
|
||||
'a10cd1de65af2bb6fadd12e660486143'
|
||||
'6fb53a35c5d36ea06cedae765e59273f'
|
||||
'29f60bdb8f2a7264286a30838a4a07fe'
|
||||
'7c9cd099eadd715c616628c506972c28'
|
||||
'3ccf2beb2c2dbc7e428a5f0f3d192c9a'
|
||||
'66d2396d0abc987979c8b06426e9a1d3'
|
||||
'66d70faf3c34dbd5a446006397f4c49b'
|
||||
'fdfe28eecec7fdb8ef8ab40e1d5ff318'
|
||||
'42d669ef2443593a3e60cafae7a4244e'
|
||||
'2b749e4414375b5e4185d15369491727'
|
||||
'd1d7f81d1fbbcc12deec9d0cae269b96'
|
||||
'5c0cc4fc579a997d16c0463376244a4f'
|
||||
'fb9f7a88ea2c4839be0595f52790470d'
|
||||
'3a081129e684856956aa34d923af4688'
|
||||
'd2210b9d9f6351082aac5a5af7456e9b'
|
||||
'0d793bd695360e3f978a21843d0651cb'
|
||||
'f1a068e6dd3ea2389877d3857ea493f0'
|
||||
'4f2379ed84258050edb858ee8d281678'
|
||||
'61c5ff73c136ed07a7aadbf58db3d96a'
|
||||
'584777ae88bce2c5659960151b64c7d8'
|
||||
|
@ -80,12 +70,7 @@ prepare() {
|
|||
git apply ../0006-set-default-cubietruck-led-triggers.patch
|
||||
git apply ../0007-exynos4412-odroid-set-higher-minimum-buck2-regulator.patch
|
||||
git apply ../0008-ARM-dove-enable-ethernet-on-D3Plug.patch
|
||||
git apply ../0009-power-add-power-sequence-library.patch
|
||||
git apply ../0010-usb-core-add-power-sequence-handling-for-USB-devices.patch
|
||||
git apply ../0011-ARM-dts-imx6qdl-Enable-usb-node-children-with-reg.patch
|
||||
git apply ../0012-ARM-dts-imx6qdl-udoo.dtsi-fix-onboard-USB-HUB-proper.patch
|
||||
git apply ../0013-ARM-dts-imx6q-evi-Fix-onboard-hub-reset-line.patch
|
||||
git apply ../0014-usb-dwc2-disable-power_down-on-rockchip-devices.patch
|
||||
git apply ../0009-usb-dwc2-disable-power_down-on-rockchip-devices.patch
|
||||
|
||||
cat "${srcdir}/config" > ./.config
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#
|
||||
# Automatically generated file; DO NOT EDIT.
|
||||
# Linux/arm 4.18.10-2 Kernel Configuration
|
||||
# Linux/arm 4.18.13-1 Kernel Configuration
|
||||
#
|
||||
|
||||
#
|
||||
|
@ -1367,8 +1367,8 @@ CONFIG_NF_LOG_ARP=m
|
|||
CONFIG_NF_LOG_IPV4=m
|
||||
CONFIG_NF_REJECT_IPV4=m
|
||||
CONFIG_NF_NAT_IPV4=m
|
||||
CONFIG_NFT_CHAIN_NAT_IPV4=m
|
||||
CONFIG_NF_NAT_MASQUERADE_IPV4=y
|
||||
CONFIG_NFT_CHAIN_NAT_IPV4=m
|
||||
CONFIG_NFT_MASQ_IPV4=m
|
||||
CONFIG_NFT_REDIR_IPV4=m
|
||||
CONFIG_NF_NAT_SNMP_BASIC=m
|
||||
|
@ -2198,6 +2198,7 @@ CONFIG_SRAM_EXEC=y
|
|||
CONFIG_VEXPRESS_SYSCFG=y
|
||||
# CONFIG_PCI_ENDPOINT_TEST is not set
|
||||
CONFIG_TIEQEP=m
|
||||
# CONFIG_UDOO_ARD is not set
|
||||
# CONFIG_C2PORT is not set
|
||||
|
||||
#
|
||||
|
|
Loading…
Reference in a new issue