Linux v4.15.2
This commit is contained in:
parent
f0b12d669e
commit
f8e9b44738
@ -0,0 +1,90 @@
|
||||
From 20eeb02a0a489e35de0830b2d61f09d43763c982 Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Mon, 13 Nov 2017 09:23:19 +0100
|
||||
Subject: [PATCH] Bluetooth: btusb: Add a Kconfig option to enable USB
|
||||
autosuspend by default
|
||||
|
||||
On many laptops the btusb device is the only USB device not having USB
|
||||
autosuspend enabled, this causes not only the HCI but also the USB
|
||||
controller to stay awake, together using aprox. 0.4W of power.
|
||||
|
||||
Modern ultrabooks idle around 6W (at 50% screen brightness), 3.5W for
|
||||
Apollo Lake devices. 0.4W is a significant chunk of this (7 / 11%).
|
||||
|
||||
The btusb driver already contains code to allow enabling USB autosuspend,
|
||||
but currently leaves it up to the user / userspace to enable it. This
|
||||
means that for most people it will not be enabled, leading to an
|
||||
unnecessarily high power consumption.
|
||||
|
||||
Since enabling it is not entirely without risk of regressions, this
|
||||
commit adds a Kconfig option so that Linux distributions can choose to
|
||||
enable it by default. This commit also adds a module option so that when
|
||||
distros receive bugs they can easily ask the user to disable it again
|
||||
for easy debugging.
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
Changes in v2:
|
||||
-s/BT_USB_AUTOSUSPEND/BT_HCIBTUSB_AUTOSUSPEND/
|
||||
-s/enable_usb_autosuspend/enable_autosuspend/
|
||||
---
|
||||
drivers/bluetooth/Kconfig | 10 ++++++++++
|
||||
drivers/bluetooth/btusb.c | 7 +++++++
|
||||
2 files changed, 17 insertions(+)
|
||||
|
||||
diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig
|
||||
index 6475f8c0d3b2..20940417d937 100644
|
||||
--- a/drivers/bluetooth/Kconfig
|
||||
+++ b/drivers/bluetooth/Kconfig
|
||||
@@ -30,6 +30,16 @@ config BT_HCIBTUSB
|
||||
Say Y here to compile support for Bluetooth USB devices into the
|
||||
kernel or say M to compile it as module (btusb).
|
||||
|
||||
+config BT_HCIBTUSB_AUTOSUSPEND
|
||||
+ bool "Enable USB autosuspend for Bluetooth USB devices by default"
|
||||
+ depends on BT_HCIBTUSB
|
||||
+ help
|
||||
+ Say Y here to enable USB autosuspend for Bluetooth USB devices by
|
||||
+ default.
|
||||
+
|
||||
+ This can be overridden by passing btusb.enable_autosuspend=[y|n]
|
||||
+ on the kernel commandline.
|
||||
+
|
||||
config BT_HCIBTUSB_BCM
|
||||
bool "Broadcom protocol support"
|
||||
depends on BT_HCIBTUSB
|
||||
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
|
||||
index c054d7bce490..3386034a44aa 100644
|
||||
--- a/drivers/bluetooth/btusb.c
|
||||
+++ b/drivers/bluetooth/btusb.c
|
||||
@@ -40,6 +40,7 @@
|
||||
|
||||
static bool disable_scofix;
|
||||
static bool force_scofix;
|
||||
+static bool enable_autosuspend = IS_ENABLED(CONFIG_BT_HCIBTUSB_AUTOSUSPEND);
|
||||
|
||||
static bool reset = true;
|
||||
|
||||
@@ -3175,6 +3176,9 @@ static int btusb_probe(struct usb_interface *intf,
|
||||
}
|
||||
#endif
|
||||
|
||||
+ if (enable_autosuspend)
|
||||
+ usb_enable_autosuspend(data->udev);
|
||||
+
|
||||
err = hci_register_dev(hdev);
|
||||
if (err < 0)
|
||||
goto out_free_dev;
|
||||
@@ -3387,6 +3391,9 @@ MODULE_PARM_DESC(disable_scofix, "Disable fixup of wrong SCO buffer size");
|
||||
module_param(force_scofix, bool, 0644);
|
||||
MODULE_PARM_DESC(force_scofix, "Force fixup of wrong SCO buffers size");
|
||||
|
||||
+module_param(enable_autosuspend, bool, 0644);
|
||||
+MODULE_PARM_DESC(enable_autosuspend, "Enable USB autosuspend by default");
|
||||
+
|
||||
module_param(reset, bool, 0644);
|
||||
MODULE_PARM_DESC(reset, "Send HCI reset command on initialization");
|
||||
|
||||
--
|
||||
2.14.3
|
||||
|
@ -0,0 +1,47 @@
|
||||
From a5ffa27c07e06900fcfc50b08de6d11e45830168 Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Wed, 3 Jan 2018 12:49:44 +0100
|
||||
Subject: [PATCH v2] Bluetooth: btusb: Disable autosuspend on QCA Rome devices
|
||||
|
||||
Commit fd865802c66b ("Bluetooth: btusb: fix QCA Rome suspend/resume") fixes
|
||||
a suspend/resume problem on QCA devices by doing a full reset on resume,
|
||||
reloading the firmware.
|
||||
|
||||
A similar problem happens when using runtime-pm / autosuspend, when this is
|
||||
enabled by the user the QCA Rome device stops working. Reloading the
|
||||
firmware after a runtime suspend is not really an option since the latency
|
||||
caused by this is unacceptable.
|
||||
|
||||
To fix the runtime-pm issues, this commit disables runtime-pm on QCA Rome
|
||||
HCIs, by getting (and not releasing) an usb autopm reference on the btusb
|
||||
interface.
|
||||
|
||||
BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1514836
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
drivers/bluetooth/btusb.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
|
||||
index 808c249845db..6ed3a0e5b8f6 100644
|
||||
--- a/drivers/bluetooth/btusb.c
|
||||
+++ b/drivers/bluetooth/btusb.c
|
||||
@@ -3122,8 +3122,15 @@ static int btusb_probe(struct usb_interface *intf,
|
||||
/* QCA Rome devices lose their updated firmware over suspend,
|
||||
* but the USB hub doesn't notice any status change.
|
||||
* Explicitly request a device reset on resume.
|
||||
+ * And disable runtime pm by getting a pm reference, the USB
|
||||
+ * core will drop our reference on disconnect.
|
||||
*/
|
||||
set_bit(BTUSB_RESET_RESUME, &data->flags);
|
||||
+ err = usb_autopm_get_interface(data->intf);
|
||||
+ if (err < 0) {
|
||||
+ BT_ERR("failed to get pm reference %d", err);
|
||||
+ goto out_free_dev;
|
||||
+ }
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BT_HCIBTUSB_RTL
|
||||
--
|
||||
2.14.3
|
||||
|
106
0001-HID-multitouch-Properly-deal-with-Win8-PTP-reports-w.patch
Normal file
106
0001-HID-multitouch-Properly-deal-with-Win8-PTP-reports-w.patch
Normal file
@ -0,0 +1,106 @@
|
||||
From f5c1da991de077420fda17a236342de5a0068f5d Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Wed, 22 Nov 2017 12:57:08 +0100
|
||||
Subject: [PATCH v2 1/3] HID: multitouch: Properly deal with Win8 PTP reports
|
||||
with 0 touches
|
||||
|
||||
The Windows Precision Touchpad spec "Figure 4 Button Only Down and Up"
|
||||
and "Table 9 Report Sequence for Button Only Down and Up" indicate
|
||||
that the first packet of a (possibly hybrid mode multi-packet) frame
|
||||
may contain a contact-count of 0 if only a button is pressed and no
|
||||
fingers are detected.
|
||||
|
||||
This means that a value of 0 for contact-count is a valid value and
|
||||
should be used as expected contact count when it is the first packet
|
||||
(num_received == 0), as extra check to make sure that this is the first
|
||||
packet of a buttons only frame, we also check that the timestamp is
|
||||
different.
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
|
||||
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
||||
---
|
||||
drivers/hid/hid-multitouch.c | 32 ++++++++++++++++++++++++++++++--
|
||||
1 file changed, 30 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
|
||||
index 9ef24b518f12..d8b1cad74faf 100644
|
||||
--- a/drivers/hid/hid-multitouch.c
|
||||
+++ b/drivers/hid/hid-multitouch.c
|
||||
@@ -119,6 +119,9 @@ struct mt_device {
|
||||
unsigned long mt_io_flags; /* mt flags (MT_IO_FLAGS_*) */
|
||||
int cc_index; /* contact count field index in the report */
|
||||
int cc_value_index; /* contact count value index in the field */
|
||||
+ int scantime_index; /* scantime field index in the report */
|
||||
+ int scantime_val_index; /* scantime value index in the field */
|
||||
+ int prev_scantime; /* scantime reported in the previous packet */
|
||||
unsigned last_slot_field; /* the last field of a slot */
|
||||
unsigned mt_report_id; /* the report ID of the multitouch device */
|
||||
unsigned long initial_quirks; /* initial quirks state */
|
||||
@@ -599,6 +602,12 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
|
||||
EV_MSC, MSC_TIMESTAMP);
|
||||
input_set_capability(hi->input, EV_MSC, MSC_TIMESTAMP);
|
||||
mt_store_field(usage, td, hi);
|
||||
+ /* Ignore if indexes are out of bounds. */
|
||||
+ if (field->index >= field->report->maxfield ||
|
||||
+ usage->usage_index >= field->report_count)
|
||||
+ return 1;
|
||||
+ td->scantime_index = field->index;
|
||||
+ td->scantime_val_index = usage->usage_index;
|
||||
return 1;
|
||||
case HID_DG_CONTACTCOUNT:
|
||||
/* Ignore if indexes are out of bounds. */
|
||||
@@ -855,9 +864,10 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field,
|
||||
static void mt_touch_report(struct hid_device *hid, struct hid_report *report)
|
||||
{
|
||||
struct mt_device *td = hid_get_drvdata(hid);
|
||||
+ __s32 cls = td->mtclass.name;
|
||||
struct hid_field *field;
|
||||
unsigned count;
|
||||
- int r, n;
|
||||
+ int r, n, scantime = 0;
|
||||
|
||||
/* sticky fingers release in progress, abort */
|
||||
if (test_and_set_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags))
|
||||
@@ -867,12 +877,29 @@ static void mt_touch_report(struct hid_device *hid, struct hid_report *report)
|
||||
* Includes multi-packet support where subsequent
|
||||
* packets are sent with zero contactcount.
|
||||
*/
|
||||
+ if (td->scantime_index >= 0) {
|
||||
+ field = report->field[td->scantime_index];
|
||||
+ scantime = field->value[td->scantime_val_index];
|
||||
+ }
|
||||
if (td->cc_index >= 0) {
|
||||
struct hid_field *field = report->field[td->cc_index];
|
||||
int value = field->value[td->cc_value_index];
|
||||
- if (value)
|
||||
+
|
||||
+ /*
|
||||
+ * For Win8 PTPs the first packet (td->num_received == 0) may
|
||||
+ * have a contactcount of 0 if there only is a button event.
|
||||
+ * We double check that this is not a continuation packet
|
||||
+ * of a possible multi-packet frame be checking that the
|
||||
+ * timestamp has changed.
|
||||
+ */
|
||||
+ if ((cls == MT_CLS_WIN_8 || cls == MT_CLS_WIN_8_DUAL) &&
|
||||
+ td->num_received == 0 && td->prev_scantime != scantime)
|
||||
+ td->num_expected = value;
|
||||
+ /* A non 0 contact count always indicates a first packet */
|
||||
+ else if (value)
|
||||
td->num_expected = value;
|
||||
}
|
||||
+ td->prev_scantime = scantime;
|
||||
|
||||
for (r = 0; r < report->maxfield; r++) {
|
||||
field = report->field[r];
|
||||
@@ -1329,6 +1356,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
td->maxcontact_report_id = -1;
|
||||
td->inputmode_value = MT_INPUTMODE_TOUCHSCREEN;
|
||||
td->cc_index = -1;
|
||||
+ td->scantime_index = -1;
|
||||
td->mt_report_id = -1;
|
||||
hid_set_drvdata(hdev, td);
|
||||
|
||||
--
|
||||
2.14.3
|
||||
|
@ -1,163 +0,0 @@
|
||||
From 25bb14c1e78e641049fd1ee0c404a9ccd2755e44 Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Sat, 22 Jul 2017 13:00:05 +0200
|
||||
Subject: [PATCH 1/2] Input: gpio_keys - Allow suppression of input events for
|
||||
wakeup button presses
|
||||
|
||||
In some cases it is undesirable for a wakeup button to send input events
|
||||
to userspace if pressed to wakeup the system (if pressed during suspend).
|
||||
|
||||
A typical example of this is the power-button on laptops / tablets,
|
||||
sending a KEY_POWER event to userspace when woken up with the power-button
|
||||
will cause userspace to immediately suspend the system again which is
|
||||
undesirable.
|
||||
|
||||
For power-buttons attached to a PMIC, or handled by e.g. ACPI, not sending
|
||||
an input event in this case is take care of by the PMIC / ACPI hardware /
|
||||
code. But in the case of a GPIO button we need to explicitly suppress the
|
||||
sending of the input event.
|
||||
|
||||
This commit adds support for this by adding a no_wakeup_events bool to
|
||||
struct gpio_keys_button, which platform code can set to suppress the
|
||||
input events for presses of wakeup keys during suspend.
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
Changes in v2:
|
||||
-This is a rewrite if my "Input: gpio_keys - Do not report wake button
|
||||
presses as evdev events" patch.
|
||||
-Instead of unconditionally ignoring presses of all wake-up buttons during
|
||||
suspend, this rewrite makes this configurable per button
|
||||
-This version uses a timer to delay clearing the suspended flag for software
|
||||
debouncing, rather then jiffy compare magic
|
||||
---
|
||||
drivers/input/keyboard/gpio_keys.c | 33 +++++++++++++++++++++++++++++++--
|
||||
include/linux/gpio_keys.h | 3 +++
|
||||
2 files changed, 34 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
|
||||
index a047b9af8369..fa3a58620407 100644
|
||||
--- a/drivers/input/keyboard/gpio_keys.c
|
||||
+++ b/drivers/input/keyboard/gpio_keys.c
|
||||
@@ -38,6 +38,7 @@ struct gpio_button_data {
|
||||
|
||||
unsigned short *code;
|
||||
|
||||
+ struct timer_list unsuspend_timer;
|
||||
struct timer_list release_timer;
|
||||
unsigned int release_delay; /* in msecs, for IRQ-only buttons */
|
||||
|
||||
@@ -371,6 +372,9 @@ static void gpio_keys_gpio_report_event(struct gpio_button_data *bdata)
|
||||
return;
|
||||
}
|
||||
|
||||
+ if (state && bdata->button->no_wakeup_events && bdata->suspended)
|
||||
+ return;
|
||||
+
|
||||
if (type == EV_ABS) {
|
||||
if (state)
|
||||
input_event(input, type, button->code, button->value);
|
||||
@@ -400,6 +404,9 @@ static irqreturn_t gpio_keys_gpio_isr(int irq, void *dev_id)
|
||||
if (bdata->button->wakeup) {
|
||||
const struct gpio_keys_button *button = bdata->button;
|
||||
|
||||
+ if (bdata->button->no_wakeup_events && bdata->suspended)
|
||||
+ return IRQ_HANDLED;
|
||||
+
|
||||
pm_stay_awake(bdata->input->dev.parent);
|
||||
if (bdata->suspended &&
|
||||
(button->type == 0 || button->type == EV_KEY)) {
|
||||
@@ -445,9 +452,13 @@ static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id)
|
||||
spin_lock_irqsave(&bdata->lock, flags);
|
||||
|
||||
if (!bdata->key_pressed) {
|
||||
- if (bdata->button->wakeup)
|
||||
+ if (bdata->button->wakeup) {
|
||||
pm_wakeup_event(bdata->input->dev.parent, 0);
|
||||
|
||||
+ if (bdata->button->no_wakeup_events && bdata->suspended)
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
input_event(input, EV_KEY, *bdata->code, 1);
|
||||
input_sync(input);
|
||||
|
||||
@@ -468,6 +479,13 @@ static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
+static void gpio_keys_unsuspend_timer(unsigned long _data)
|
||||
+{
|
||||
+ struct gpio_button_data *bdata = (struct gpio_button_data *)_data;
|
||||
+
|
||||
+ bdata->suspended = false;
|
||||
+}
|
||||
+
|
||||
static void gpio_keys_quiesce_key(void *data)
|
||||
{
|
||||
struct gpio_button_data *bdata = data;
|
||||
@@ -476,6 +494,8 @@ static void gpio_keys_quiesce_key(void *data)
|
||||
cancel_delayed_work_sync(&bdata->work);
|
||||
else
|
||||
del_timer_sync(&bdata->release_timer);
|
||||
+
|
||||
+ del_timer_sync(&bdata->unsuspend_timer);
|
||||
}
|
||||
|
||||
static int gpio_keys_setup_key(struct platform_device *pdev,
|
||||
@@ -496,6 +516,8 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
|
||||
bdata->input = input;
|
||||
bdata->button = button;
|
||||
spin_lock_init(&bdata->lock);
|
||||
+ setup_timer(&bdata->unsuspend_timer, gpio_keys_unsuspend_timer,
|
||||
+ (unsigned long)bdata);
|
||||
|
||||
if (child) {
|
||||
bdata->gpiod = devm_fwnode_get_gpiod_from_child(dev, NULL,
|
||||
@@ -868,6 +890,7 @@ static int __maybe_unused gpio_keys_suspend(struct device *dev)
|
||||
struct gpio_button_data *bdata = &ddata->data[i];
|
||||
if (bdata->button->wakeup)
|
||||
enable_irq_wake(bdata->irq);
|
||||
+ del_timer_sync(&bdata->unsuspend_timer);
|
||||
bdata->suspended = true;
|
||||
}
|
||||
} else {
|
||||
@@ -892,7 +915,13 @@ static int __maybe_unused gpio_keys_resume(struct device *dev)
|
||||
struct gpio_button_data *bdata = &ddata->data[i];
|
||||
if (bdata->button->wakeup)
|
||||
disable_irq_wake(bdata->irq);
|
||||
- bdata->suspended = false;
|
||||
+ if (bdata->button->no_wakeup_events) {
|
||||
+ mod_timer(&bdata->unsuspend_timer, jiffies +
|
||||
+ msecs_to_jiffies(
|
||||
+ bdata->software_debounce));
|
||||
+ } else {
|
||||
+ bdata->suspended = false;
|
||||
+ }
|
||||
}
|
||||
} else {
|
||||
mutex_lock(&input->mutex);
|
||||
diff --git a/include/linux/gpio_keys.h b/include/linux/gpio_keys.h
|
||||
index 0b71024c082c..d8a85e52b6bb 100644
|
||||
--- a/include/linux/gpio_keys.h
|
||||
+++ b/include/linux/gpio_keys.h
|
||||
@@ -15,6 +15,8 @@ struct device;
|
||||
* @debounce_interval: debounce ticks interval in msecs
|
||||
* @can_disable: %true indicates that userspace is allowed to
|
||||
* disable button via sysfs
|
||||
+ * @no_wakeup_events: For wake-up source buttons only, if %true then no input
|
||||
+ * events will be generated if pressed while suspended
|
||||
* @value: axis value for %EV_ABS
|
||||
* @irq: Irq number in case of interrupt keys
|
||||
*/
|
||||
@@ -27,6 +29,7 @@ struct gpio_keys_button {
|
||||
int wakeup;
|
||||
int debounce_interval;
|
||||
bool can_disable;
|
||||
+ bool no_wakeup_events;
|
||||
int value;
|
||||
unsigned int irq;
|
||||
};
|
||||
--
|
||||
2.13.4
|
||||
|
106
0001-ahci-Annotate-PCI-ids-for-mobile-Intel-chipsets-as-s.patch
Normal file
106
0001-ahci-Annotate-PCI-ids-for-mobile-Intel-chipsets-as-s.patch
Normal file
@ -0,0 +1,106 @@
|
||||
From cb1072f66e72eda65a8f7ac37d32c9f4217af6ba Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Tue, 21 Nov 2017 14:44:15 +0100
|
||||
Subject: [PATCH 1/3] ahci: Annotate PCI ids for mobile Intel chipsets as such
|
||||
|
||||
Intel uses different SATA PCI ids for the Desktop and Mobile SKUs of their
|
||||
chipsets. For older models the comment describing which chipset the PCI id
|
||||
is for, aksi indicates when we're dealing with a mobile SKU. Extend the
|
||||
comments for recent chipsets to also indicate mobile SKUs.
|
||||
|
||||
The information this commit adds comes from Intel's chipset datasheets.
|
||||
|
||||
This commit is a preparation patch for allowing a different default
|
||||
sata link powermanagement policy for mobile chipsets.
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
drivers/ata/ahci.c | 32 ++++++++++++++++----------------
|
||||
1 file changed, 16 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
|
||||
index 5443cb71d7ba..9d842ff6ec51 100644
|
||||
--- a/drivers/ata/ahci.c
|
||||
+++ b/drivers/ata/ahci.c
|
||||
@@ -268,9 +268,9 @@ static const struct pci_device_id ahci_pci_tbl[] = {
|
||||
{ PCI_VDEVICE(INTEL, 0x3b23), board_ahci }, /* PCH AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x3b24), board_ahci }, /* PCH RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x3b25), board_ahci }, /* PCH RAID */
|
||||
- { PCI_VDEVICE(INTEL, 0x3b29), board_ahci }, /* PCH AHCI */
|
||||
+ { PCI_VDEVICE(INTEL, 0x3b29), board_ahci }, /* PCH M AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x3b2b), board_ahci }, /* PCH RAID */
|
||||
- { PCI_VDEVICE(INTEL, 0x3b2c), board_ahci }, /* PCH RAID */
|
||||
+ { PCI_VDEVICE(INTEL, 0x3b2c), board_ahci }, /* PCH M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x3b2f), board_ahci }, /* PCH AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19b0), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19b1), board_ahci }, /* DNV AHCI */
|
||||
@@ -293,9 +293,9 @@ static const struct pci_device_id ahci_pci_tbl[] = {
|
||||
{ PCI_VDEVICE(INTEL, 0x19cE), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19cF), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x1c02), board_ahci }, /* CPT AHCI */
|
||||
- { PCI_VDEVICE(INTEL, 0x1c03), board_ahci }, /* CPT AHCI */
|
||||
+ { PCI_VDEVICE(INTEL, 0x1c03), board_ahci }, /* CPT M AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x1c04), board_ahci }, /* CPT RAID */
|
||||
- { PCI_VDEVICE(INTEL, 0x1c05), board_ahci }, /* CPT RAID */
|
||||
+ { PCI_VDEVICE(INTEL, 0x1c05), board_ahci }, /* CPT M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x1c06), board_ahci }, /* CPT RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x1c07), board_ahci }, /* CPT RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x1d02), board_ahci }, /* PBG AHCI */
|
||||
@@ -304,20 +304,20 @@ static const struct pci_device_id ahci_pci_tbl[] = {
|
||||
{ PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* PBG RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x2323), board_ahci }, /* DH89xxCC AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x1e02), board_ahci }, /* Panther Point AHCI */
|
||||
- { PCI_VDEVICE(INTEL, 0x1e03), board_ahci }, /* Panther Point AHCI */
|
||||
+ { PCI_VDEVICE(INTEL, 0x1e03), board_ahci }, /* Panther Point M AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x1e04), board_ahci }, /* Panther Point RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x1e05), board_ahci }, /* Panther Point RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x1e06), board_ahci }, /* Panther Point RAID */
|
||||
- { PCI_VDEVICE(INTEL, 0x1e07), board_ahci }, /* Panther Point RAID */
|
||||
+ { PCI_VDEVICE(INTEL, 0x1e07), board_ahci }, /* Panther Point M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x1e0e), board_ahci }, /* Panther Point RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c02), board_ahci }, /* Lynx Point AHCI */
|
||||
- { PCI_VDEVICE(INTEL, 0x8c03), board_ahci }, /* Lynx Point AHCI */
|
||||
+ { PCI_VDEVICE(INTEL, 0x8c03), board_ahci }, /* Lynx Point M AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c04), board_ahci }, /* Lynx Point RAID */
|
||||
- { PCI_VDEVICE(INTEL, 0x8c05), board_ahci }, /* Lynx Point RAID */
|
||||
+ { PCI_VDEVICE(INTEL, 0x8c05), board_ahci }, /* Lynx Point M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c06), board_ahci }, /* Lynx Point RAID */
|
||||
- { PCI_VDEVICE(INTEL, 0x8c07), board_ahci }, /* Lynx Point RAID */
|
||||
+ { PCI_VDEVICE(INTEL, 0x8c07), board_ahci }, /* Lynx Point M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c0e), board_ahci }, /* Lynx Point RAID */
|
||||
- { PCI_VDEVICE(INTEL, 0x8c0f), board_ahci }, /* Lynx Point RAID */
|
||||
+ { PCI_VDEVICE(INTEL, 0x8c0f), board_ahci }, /* Lynx Point M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x9c02), board_ahci }, /* Lynx Point-LP AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x9c03), board_ahci }, /* Lynx Point-LP AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x9c04), board_ahci }, /* Lynx Point-LP RAID */
|
||||
@@ -358,21 +358,21 @@ static const struct pci_device_id ahci_pci_tbl[] = {
|
||||
{ PCI_VDEVICE(INTEL, 0x9c87), board_ahci }, /* Wildcat Point-LP RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x9c8f), board_ahci }, /* Wildcat Point-LP RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c82), board_ahci }, /* 9 Series AHCI */
|
||||
- { PCI_VDEVICE(INTEL, 0x8c83), board_ahci }, /* 9 Series AHCI */
|
||||
+ { PCI_VDEVICE(INTEL, 0x8c83), board_ahci }, /* 9 Series M AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c84), board_ahci }, /* 9 Series RAID */
|
||||
- { PCI_VDEVICE(INTEL, 0x8c85), board_ahci }, /* 9 Series RAID */
|
||||
+ { PCI_VDEVICE(INTEL, 0x8c85), board_ahci }, /* 9 Series M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c86), board_ahci }, /* 9 Series RAID */
|
||||
- { PCI_VDEVICE(INTEL, 0x8c87), board_ahci }, /* 9 Series RAID */
|
||||
+ { PCI_VDEVICE(INTEL, 0x8c87), board_ahci }, /* 9 Series M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c8e), board_ahci }, /* 9 Series RAID */
|
||||
- { PCI_VDEVICE(INTEL, 0x8c8f), board_ahci }, /* 9 Series RAID */
|
||||
+ { PCI_VDEVICE(INTEL, 0x8c8f), board_ahci }, /* 9 Series M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x9d03), board_ahci }, /* Sunrise Point-LP AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x9d05), board_ahci }, /* Sunrise Point-LP RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x9d07), board_ahci }, /* Sunrise Point-LP RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0xa102), board_ahci }, /* Sunrise Point-H AHCI */
|
||||
- { PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H AHCI */
|
||||
+ { PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H M AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0xa105), board_ahci }, /* Sunrise Point-H RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0xa106), board_ahci }, /* Sunrise Point-H RAID */
|
||||
- { PCI_VDEVICE(INTEL, 0xa107), board_ahci }, /* Sunrise Point-H RAID */
|
||||
+ { PCI_VDEVICE(INTEL, 0xa107), board_ahci }, /* Sunrise Point-H M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0xa10f), board_ahci }, /* Sunrise Point-H RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* Lewisburg RAID*/
|
||||
{ PCI_VDEVICE(INTEL, 0x2823), board_ahci }, /* Lewisburg AHCI*/
|
||||
--
|
||||
2.14.3
|
||||
|
@ -0,0 +1,84 @@
|
||||
From c25d877f4ee97deb92170129eee4777a5d5997d9 Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Wed, 22 Nov 2017 12:57:09 +0100
|
||||
Subject: [PATCH v2 2/3] HID: multitouch: Only look at non touch fields in
|
||||
first packet of a frame
|
||||
|
||||
Devices in "single finger hybrid mode" will send one report per finger,
|
||||
on some devices only the first report of such a multi-packet frame will
|
||||
contain a value for BTN_LEFT, in subsequent reports (if multiple fingers
|
||||
are down) the value is always 0, causing hid-mt to report BTN_LEFT going
|
||||
1 - 0 - 1 - 0 when pressing a clickpad and putting down a second finger.
|
||||
This happens for example on USB 0603:0002 mt touchpads.
|
||||
|
||||
This commit fixes this by only reporting non touch fields for the first
|
||||
packet of a (possibly) multi-packet frame.
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
|
||||
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
||||
---
|
||||
drivers/hid/hid-multitouch.c | 17 +++++++++++++++--
|
||||
1 file changed, 15 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
|
||||
index d8b1cad74faf..760c4a042e6a 100644
|
||||
--- a/drivers/hid/hid-multitouch.c
|
||||
+++ b/drivers/hid/hid-multitouch.c
|
||||
@@ -787,9 +787,11 @@ static int mt_touch_event(struct hid_device *hid, struct hid_field *field,
|
||||
}
|
||||
|
||||
static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field,
|
||||
- struct hid_usage *usage, __s32 value)
|
||||
+ struct hid_usage *usage, __s32 value,
|
||||
+ bool first_packet)
|
||||
{
|
||||
struct mt_device *td = hid_get_drvdata(hid);
|
||||
+ __s32 cls = td->mtclass.name;
|
||||
__s32 quirks = td->mtclass.quirks;
|
||||
struct input_dev *input = field->hidinput->input;
|
||||
|
||||
@@ -846,6 +848,15 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field,
|
||||
break;
|
||||
|
||||
default:
|
||||
+ /*
|
||||
+ * For Win8 PTP touchpads we should only look at
|
||||
+ * non finger/touch events in the first_packet of
|
||||
+ * a (possible) multi-packet frame.
|
||||
+ */
|
||||
+ if ((cls == MT_CLS_WIN_8 || cls == MT_CLS_WIN_8_DUAL) &&
|
||||
+ !first_packet)
|
||||
+ return;
|
||||
+
|
||||
if (usage->type)
|
||||
input_event(input, usage->type, usage->code,
|
||||
value);
|
||||
@@ -866,6 +877,7 @@ static void mt_touch_report(struct hid_device *hid, struct hid_report *report)
|
||||
struct mt_device *td = hid_get_drvdata(hid);
|
||||
__s32 cls = td->mtclass.name;
|
||||
struct hid_field *field;
|
||||
+ bool first_packet;
|
||||
unsigned count;
|
||||
int r, n, scantime = 0;
|
||||
|
||||
@@ -901,6 +913,7 @@ static void mt_touch_report(struct hid_device *hid, struct hid_report *report)
|
||||
}
|
||||
td->prev_scantime = scantime;
|
||||
|
||||
+ first_packet = td->num_received == 0;
|
||||
for (r = 0; r < report->maxfield; r++) {
|
||||
field = report->field[r];
|
||||
count = field->report_count;
|
||||
@@ -910,7 +923,7 @@ static void mt_touch_report(struct hid_device *hid, struct hid_report *report)
|
||||
|
||||
for (n = 0; n < count; n++)
|
||||
mt_process_mt_event(hid, field, &field->usage[n],
|
||||
- field->value[n]);
|
||||
+ field->value[n], first_packet);
|
||||
}
|
||||
|
||||
if (td->num_received >= td->num_expected)
|
||||
--
|
||||
2.14.3
|
||||
|
@ -1,62 +0,0 @@
|
||||
From d561f0543506bc12e7b3355efddb0bfd7ca83c74 Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Sat, 22 Jul 2017 13:17:36 +0200
|
||||
Subject: [PATCH 2/2] Input: soc_button_array - Suppress power button presses
|
||||
during suspend
|
||||
|
||||
If the power-button is pressed to wakeup the laptop/tablet from suspend
|
||||
and we report a KEY_POWER event to userspace when woken up this will cause
|
||||
userspace to immediately suspend the system again which is undesirable.
|
||||
|
||||
This commit sets the new no_wakeup_events flag in the gpio_keys_button
|
||||
struct for the power-button suppressing the undesirable KEY_POWER input
|
||||
events on wake-up.
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
Changes in v2:
|
||||
-New patch in v2 of this patch-set
|
||||
---
|
||||
drivers/input/misc/soc_button_array.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c
|
||||
index f600f3a7a3c6..27b99831cb97 100644
|
||||
--- a/drivers/input/misc/soc_button_array.c
|
||||
+++ b/drivers/input/misc/soc_button_array.c
|
||||
@@ -27,6 +27,7 @@ struct soc_button_info {
|
||||
unsigned int event_code;
|
||||
bool autorepeat;
|
||||
bool wakeup;
|
||||
+ bool no_wakeup_events;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -100,6 +101,7 @@ soc_button_device_create(struct platform_device *pdev,
|
||||
gpio_keys[n_buttons].active_low = 1;
|
||||
gpio_keys[n_buttons].desc = info->name;
|
||||
gpio_keys[n_buttons].wakeup = info->wakeup;
|
||||
+ gpio_keys[n_buttons].no_wakeup_events = info->no_wakeup_events;
|
||||
/* These devices often use cheap buttons, use 50 ms debounce */
|
||||
gpio_keys[n_buttons].debounce_interval = 50;
|
||||
n_buttons++;
|
||||
@@ -185,6 +187,7 @@ static int soc_button_parse_btn_desc(struct device *dev,
|
||||
info->name = "power";
|
||||
info->event_code = KEY_POWER;
|
||||
info->wakeup = true;
|
||||
+ info->no_wakeup_events = true;
|
||||
} else if (upage == 0x07 && usage == 0xe3) {
|
||||
info->name = "home";
|
||||
info->event_code = KEY_LEFTMETA;
|
||||
@@ -369,7 +372,7 @@ static int soc_button_probe(struct platform_device *pdev)
|
||||
* Platforms"
|
||||
*/
|
||||
static struct soc_button_info soc_button_PNP0C40[] = {
|
||||
- { "power", 0, EV_KEY, KEY_POWER, false, true },
|
||||
+ { "power", 0, EV_KEY, KEY_POWER, false, true, true },
|
||||
{ "home", 1, EV_KEY, KEY_LEFTMETA, false, true },
|
||||
{ "volume_up", 2, EV_KEY, KEY_VOLUMEUP, true, false },
|
||||
{ "volume_down", 3, EV_KEY, KEY_VOLUMEDOWN, true, false },
|
||||
--
|
||||
2.13.4
|
||||
|
@ -0,0 +1,33 @@
|
||||
From eab582db4b6c04a20a8bd792faa9ebf7adf1ec17 Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Mon, 27 Nov 2017 12:07:34 +0100
|
||||
Subject: [PATCH 2/3] ahci: Add PCI ids for Intel Bay Trail, Cherry Trail and
|
||||
Apollo Lake AHCI
|
||||
|
||||
Add PCI ids for Intel Bay Trail, Cherry Trail and Apollo Lake AHCI
|
||||
SATA controllers. This commit is a preparation patch for allowing a
|
||||
different default sata link powermanagement policy for mobile chipsets.
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
drivers/ata/ahci.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
|
||||
index 9d842ff6ec51..844f697bedbf 100644
|
||||
--- a/drivers/ata/ahci.c
|
||||
+++ b/drivers/ata/ahci.c
|
||||
@@ -386,6 +386,10 @@ static const struct pci_device_id ahci_pci_tbl[] = {
|
||||
{ PCI_VDEVICE(INTEL, 0xa206), board_ahci }, /* Lewisburg RAID*/
|
||||
{ PCI_VDEVICE(INTEL, 0xa252), board_ahci }, /* Lewisburg RAID*/
|
||||
{ PCI_VDEVICE(INTEL, 0xa256), board_ahci }, /* Lewisburg RAID*/
|
||||
+ { PCI_VDEVICE(INTEL, 0x0f22), board_ahci }, /* Bay Trail AHCI */
|
||||
+ { PCI_VDEVICE(INTEL, 0x0f23), board_ahci }, /* Bay Trail AHCI */
|
||||
+ { PCI_VDEVICE(INTEL, 0x22a3), board_ahci }, /* Cherry Trail AHCI */
|
||||
+ { PCI_VDEVICE(INTEL, 0x5ae3), board_ahci }, /* Apollo Lake AHCI */
|
||||
|
||||
/* JMicron 360/1/3/5/6, match class to avoid IDE function */
|
||||
{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
|
||||
--
|
||||
2.14.3
|
||||
|
@ -0,0 +1,78 @@
|
||||
From 1719566899e5a69b4ba767beb07dab7ceb9ae5a8 Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Wed, 22 Nov 2017 12:57:10 +0100
|
||||
Subject: [PATCH v2 3/3] HID: multitouch: Combine all left-button events in a
|
||||
frame
|
||||
|
||||
According to the Win8 Precision Touchpad spec, inside the HID_UP_BUTTON
|
||||
usage-page usage 1 is for a clickpad getting clicked, 2 for an external
|
||||
left button and 3 for an external right button. Since Linux uses
|
||||
BTN_LEFT for a clickpad being clicked we end up mapping both usage 1
|
||||
and 2 to BTN_LEFT and if a single report contains both then we ended
|
||||
up always reporting the value of both in a single SYN, e.g. :
|
||||
BTN_LEFT 1, BTN_LEFT 0, SYN. This happens for example with Hantick
|
||||
HTT5288 i2c mt touchpads.
|
||||
|
||||
This commit fixes this by not immediately reporting left button when we
|
||||
parse the report, but instead storing or-ing together the values and
|
||||
reporting the result from mt_sync_frame() when we've a complete frame.
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
|
||||
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
||||
---
|
||||
drivers/hid/hid-multitouch.c | 20 ++++++++++++++++++++
|
||||
1 file changed, 20 insertions(+)
|
||||
|
||||
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
|
||||
index 760c4a042e6a..76088f2cf598 100644
|
||||
--- a/drivers/hid/hid-multitouch.c
|
||||
+++ b/drivers/hid/hid-multitouch.c
|
||||
@@ -122,6 +122,7 @@ struct mt_device {
|
||||
int scantime_index; /* scantime field index in the report */
|
||||
int scantime_val_index; /* scantime value index in the field */
|
||||
int prev_scantime; /* scantime reported in the previous packet */
|
||||
+ int left_button_state; /* left button state */
|
||||
unsigned last_slot_field; /* the last field of a slot */
|
||||
unsigned mt_report_id; /* the report ID of the multitouch device */
|
||||
unsigned long initial_quirks; /* initial quirks state */
|
||||
@@ -743,10 +744,16 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input)
|
||||
*/
|
||||
static void mt_sync_frame(struct mt_device *td, struct input_dev *input)
|
||||
{
|
||||
+ __s32 cls = td->mtclass.name;
|
||||
+
|
||||
+ if (cls == MT_CLS_WIN_8 || cls == MT_CLS_WIN_8_DUAL)
|
||||
+ input_event(input, EV_KEY, BTN_LEFT, td->left_button_state);
|
||||
+
|
||||
input_mt_sync_frame(input);
|
||||
input_event(input, EV_MSC, MSC_TIMESTAMP, td->timestamp);
|
||||
input_sync(input);
|
||||
td->num_received = 0;
|
||||
+ td->left_button_state = 0;
|
||||
if (test_bit(MT_IO_FLAGS_ACTIVE_SLOTS, &td->mt_io_flags))
|
||||
set_bit(MT_IO_FLAGS_PENDING_SLOTS, &td->mt_io_flags);
|
||||
else
|
||||
@@ -857,6 +864,19 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field,
|
||||
!first_packet)
|
||||
return;
|
||||
|
||||
+ /*
|
||||
+ * For Win8 PTP touchpads we map both the clickpad click
|
||||
+ * and any "external" left buttons to BTN_LEFT if a
|
||||
+ * device claims to have both we need to report 1 for
|
||||
+ * BTN_LEFT if either is pressed, so we or all values
|
||||
+ * together and report the result in mt_sync_frame().
|
||||
+ */
|
||||
+ if ((cls == MT_CLS_WIN_8 || cls == MT_CLS_WIN_8_DUAL) &&
|
||||
+ usage->type == EV_KEY && usage->code == BTN_LEFT) {
|
||||
+ td->left_button_state |= value;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if (usage->type)
|
||||
input_event(input, usage->type, usage->code,
|
||||
value);
|
||||
--
|
||||
2.14.3
|
||||
|
274
0003-ahci-Allow-setting-a-default-LPM-policy-for-mobile-c.patch
Normal file
274
0003-ahci-Allow-setting-a-default-LPM-policy-for-mobile-c.patch
Normal file
@ -0,0 +1,274 @@
|
||||
From 262135cf058c28d248b997bd11b2c124e27d8d47 Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Mon, 27 Nov 2017 15:32:01 +0100
|
||||
Subject: [PATCH 3/3] ahci: Allow setting a default LPM policy for mobile
|
||||
chipsets
|
||||
|
||||
On many laptops setting a different LPM policy then unknown /
|
||||
max_performance can lead to power-savings of 1.0 - 1.5 Watts (when idle).
|
||||
|
||||
Modern ultrabooks idle around 6W (at 50% screen brightness), 1.0 - 1.5W
|
||||
is a significant chunk of this.
|
||||
|
||||
There are some performance / latency costs to enabling LPM by default,
|
||||
so it is desirable to make it possible to set a different LPM policy
|
||||
for mobile / laptop variants of chipsets / "South Bridges" vs their
|
||||
desktop / server counterparts. Also enabling LPM by default is not
|
||||
entirely without risk of regressions. At least min_power is known to
|
||||
cause issues with some disks, including some reports of data corruption.
|
||||
|
||||
This commits adds a new ahci.mobile_lpm_policy kernel cmdline option,
|
||||
which defaults to a new SATA_MOBILE_LPM_POLICY Kconfig option so that
|
||||
Linux distributions can choose to set a LPM policy for mobile chipsets
|
||||
by default.
|
||||
|
||||
The reason to have both a kernel cmdline option and a Kconfig default
|
||||
value for it, is to allow easy overriding of the default to allow
|
||||
trouble-shooting without needing to rebuild the kernel.
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
Changes in v2:
|
||||
-Remove .config changes from the patch
|
||||
---
|
||||
drivers/ata/Kconfig | 19 +++++++++++
|
||||
drivers/ata/ahci.c | 97 +++++++++++++++++++++++++++++++----------------------
|
||||
drivers/ata/ahci.h | 3 ++
|
||||
3 files changed, 78 insertions(+), 41 deletions(-)
|
||||
|
||||
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
|
||||
index cb5339166563..b3fad5663aeb 100644
|
||||
--- a/drivers/ata/Kconfig
|
||||
+++ b/drivers/ata/Kconfig
|
||||
@@ -92,6 +92,25 @@ config SATA_AHCI
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
+config SATA_MOBILE_LPM_POLICY
|
||||
+ int "Default SATA Link Power Management policy for mobile chipsets"
|
||||
+ range 0 4
|
||||
+ default 0
|
||||
+ depends on SATA_AHCI
|
||||
+ help
|
||||
+ Select the Default SATA Link Power Management (LPM) policy to use
|
||||
+ for mobile / laptop variants of chipsets / "South Bridges".
|
||||
+
|
||||
+ The value set has the following meanings:
|
||||
+ 0 => Keep firmware settings
|
||||
+ 1 => Maximum performance
|
||||
+ 2 => Medium power
|
||||
+ 3 => Medium power with Device Initiated PM enabled
|
||||
+ 4 => Minimum power
|
||||
+
|
||||
+ Note "Minimum power" is known to cause issues, including disk
|
||||
+ corruption, with some disks and should not be used.
|
||||
+
|
||||
config SATA_AHCI_PLATFORM
|
||||
tristate "Platform AHCI SATA support"
|
||||
help
|
||||
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
|
||||
index 844f697bedbf..8e910fae8892 100644
|
||||
--- a/drivers/ata/ahci.c
|
||||
+++ b/drivers/ata/ahci.c
|
||||
@@ -65,6 +65,7 @@ enum board_ids {
|
||||
/* board IDs by feature in alphabetical order */
|
||||
board_ahci,
|
||||
board_ahci_ign_iferr,
|
||||
+ board_ahci_mobile,
|
||||
board_ahci_nomsi,
|
||||
board_ahci_noncq,
|
||||
board_ahci_nosntf,
|
||||
@@ -140,6 +141,13 @@ static const struct ata_port_info ahci_port_info[] = {
|
||||
.udma_mask = ATA_UDMA6,
|
||||
.port_ops = &ahci_ops,
|
||||
},
|
||||
+ [board_ahci_mobile] = {
|
||||
+ AHCI_HFLAGS (AHCI_HFLAG_IS_MOBILE),
|
||||
+ .flags = AHCI_FLAG_COMMON,
|
||||
+ .pio_mask = ATA_PIO4,
|
||||
+ .udma_mask = ATA_UDMA6,
|
||||
+ .port_ops = &ahci_ops,
|
||||
+ },
|
||||
[board_ahci_nomsi] = {
|
||||
AHCI_HFLAGS (AHCI_HFLAG_NO_MSI),
|
||||
.flags = AHCI_FLAG_COMMON,
|
||||
@@ -252,13 +260,13 @@ static const struct pci_device_id ahci_pci_tbl[] = {
|
||||
{ PCI_VDEVICE(INTEL, 0x2924), board_ahci }, /* ICH9 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2925), board_ahci }, /* ICH9 */
|
||||
{ PCI_VDEVICE(INTEL, 0x2927), board_ahci }, /* ICH9 */
|
||||
- { PCI_VDEVICE(INTEL, 0x2929), board_ahci }, /* ICH9M */
|
||||
- { PCI_VDEVICE(INTEL, 0x292a), board_ahci }, /* ICH9M */
|
||||
- { PCI_VDEVICE(INTEL, 0x292b), board_ahci }, /* ICH9M */
|
||||
- { PCI_VDEVICE(INTEL, 0x292c), board_ahci }, /* ICH9M */
|
||||
- { PCI_VDEVICE(INTEL, 0x292f), board_ahci }, /* ICH9M */
|
||||
+ { PCI_VDEVICE(INTEL, 0x2929), board_ahci_mobile }, /* ICH9M */
|
||||
+ { PCI_VDEVICE(INTEL, 0x292a), board_ahci_mobile }, /* ICH9M */
|
||||
+ { PCI_VDEVICE(INTEL, 0x292b), board_ahci_mobile }, /* ICH9M */
|
||||
+ { PCI_VDEVICE(INTEL, 0x292c), board_ahci_mobile }, /* ICH9M */
|
||||
+ { PCI_VDEVICE(INTEL, 0x292f), board_ahci_mobile }, /* ICH9M */
|
||||
{ PCI_VDEVICE(INTEL, 0x294d), board_ahci }, /* ICH9 */
|
||||
- { PCI_VDEVICE(INTEL, 0x294e), board_ahci }, /* ICH9M */
|
||||
+ { PCI_VDEVICE(INTEL, 0x294e), board_ahci_mobile }, /* ICH9M */
|
||||
{ PCI_VDEVICE(INTEL, 0x502a), board_ahci }, /* Tolapai */
|
||||
{ PCI_VDEVICE(INTEL, 0x502b), board_ahci }, /* Tolapai */
|
||||
{ PCI_VDEVICE(INTEL, 0x3a05), board_ahci }, /* ICH10 */
|
||||
@@ -268,9 +276,9 @@ static const struct pci_device_id ahci_pci_tbl[] = {
|
||||
{ PCI_VDEVICE(INTEL, 0x3b23), board_ahci }, /* PCH AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x3b24), board_ahci }, /* PCH RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x3b25), board_ahci }, /* PCH RAID */
|
||||
- { PCI_VDEVICE(INTEL, 0x3b29), board_ahci }, /* PCH M AHCI */
|
||||
+ { PCI_VDEVICE(INTEL, 0x3b29), board_ahci_mobile }, /* PCH M AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x3b2b), board_ahci }, /* PCH RAID */
|
||||
- { PCI_VDEVICE(INTEL, 0x3b2c), board_ahci }, /* PCH M RAID */
|
||||
+ { PCI_VDEVICE(INTEL, 0x3b2c), board_ahci_mobile }, /* PCH M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x3b2f), board_ahci }, /* PCH AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19b0), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19b1), board_ahci }, /* DNV AHCI */
|
||||
@@ -293,9 +301,9 @@ static const struct pci_device_id ahci_pci_tbl[] = {
|
||||
{ PCI_VDEVICE(INTEL, 0x19cE), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x19cF), board_ahci }, /* DNV AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x1c02), board_ahci }, /* CPT AHCI */
|
||||
- { PCI_VDEVICE(INTEL, 0x1c03), board_ahci }, /* CPT M AHCI */
|
||||
+ { PCI_VDEVICE(INTEL, 0x1c03), board_ahci_mobile }, /* CPT M AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x1c04), board_ahci }, /* CPT RAID */
|
||||
- { PCI_VDEVICE(INTEL, 0x1c05), board_ahci }, /* CPT M RAID */
|
||||
+ { PCI_VDEVICE(INTEL, 0x1c05), board_ahci_mobile }, /* CPT M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x1c06), board_ahci }, /* CPT RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x1c07), board_ahci }, /* CPT RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x1d02), board_ahci }, /* PBG AHCI */
|
||||
@@ -304,28 +312,28 @@ static const struct pci_device_id ahci_pci_tbl[] = {
|
||||
{ PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* PBG RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x2323), board_ahci }, /* DH89xxCC AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x1e02), board_ahci }, /* Panther Point AHCI */
|
||||
- { PCI_VDEVICE(INTEL, 0x1e03), board_ahci }, /* Panther Point M AHCI */
|
||||
+ { PCI_VDEVICE(INTEL, 0x1e03), board_ahci_mobile }, /* Panther M AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x1e04), board_ahci }, /* Panther Point RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x1e05), board_ahci }, /* Panther Point RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x1e06), board_ahci }, /* Panther Point RAID */
|
||||
- { PCI_VDEVICE(INTEL, 0x1e07), board_ahci }, /* Panther Point M RAID */
|
||||
+ { PCI_VDEVICE(INTEL, 0x1e07), board_ahci_mobile }, /* Panther M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x1e0e), board_ahci }, /* Panther Point RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c02), board_ahci }, /* Lynx Point AHCI */
|
||||
- { PCI_VDEVICE(INTEL, 0x8c03), board_ahci }, /* Lynx Point M AHCI */
|
||||
+ { PCI_VDEVICE(INTEL, 0x8c03), board_ahci_mobile }, /* Lynx M AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c04), board_ahci }, /* Lynx Point RAID */
|
||||
- { PCI_VDEVICE(INTEL, 0x8c05), board_ahci }, /* Lynx Point M RAID */
|
||||
+ { PCI_VDEVICE(INTEL, 0x8c05), board_ahci_mobile }, /* Lynx M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c06), board_ahci }, /* Lynx Point RAID */
|
||||
- { PCI_VDEVICE(INTEL, 0x8c07), board_ahci }, /* Lynx Point M RAID */
|
||||
+ { PCI_VDEVICE(INTEL, 0x8c07), board_ahci_mobile }, /* Lynx M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c0e), board_ahci }, /* Lynx Point RAID */
|
||||
- { PCI_VDEVICE(INTEL, 0x8c0f), board_ahci }, /* Lynx Point M RAID */
|
||||
- { PCI_VDEVICE(INTEL, 0x9c02), board_ahci }, /* Lynx Point-LP AHCI */
|
||||
- { PCI_VDEVICE(INTEL, 0x9c03), board_ahci }, /* Lynx Point-LP AHCI */
|
||||
- { PCI_VDEVICE(INTEL, 0x9c04), board_ahci }, /* Lynx Point-LP RAID */
|
||||
- { PCI_VDEVICE(INTEL, 0x9c05), board_ahci }, /* Lynx Point-LP RAID */
|
||||
- { PCI_VDEVICE(INTEL, 0x9c06), board_ahci }, /* Lynx Point-LP RAID */
|
||||
- { PCI_VDEVICE(INTEL, 0x9c07), board_ahci }, /* Lynx Point-LP RAID */
|
||||
- { PCI_VDEVICE(INTEL, 0x9c0e), board_ahci }, /* Lynx Point-LP RAID */
|
||||
- { PCI_VDEVICE(INTEL, 0x9c0f), board_ahci }, /* Lynx Point-LP RAID */
|
||||
+ { PCI_VDEVICE(INTEL, 0x8c0f), board_ahci_mobile }, /* Lynx M RAID */
|
||||
+ { PCI_VDEVICE(INTEL, 0x9c02), board_ahci_mobile }, /* Lynx LP AHCI */
|
||||
+ { PCI_VDEVICE(INTEL, 0x9c03), board_ahci_mobile }, /* Lynx LP AHCI */
|
||||
+ { PCI_VDEVICE(INTEL, 0x9c04), board_ahci_mobile }, /* Lynx LP RAID */
|
||||
+ { PCI_VDEVICE(INTEL, 0x9c05), board_ahci_mobile }, /* Lynx LP RAID */
|
||||
+ { PCI_VDEVICE(INTEL, 0x9c06), board_ahci_mobile }, /* Lynx LP RAID */
|
||||
+ { PCI_VDEVICE(INTEL, 0x9c07), board_ahci_mobile }, /* Lynx LP RAID */
|
||||
+ { PCI_VDEVICE(INTEL, 0x9c0e), board_ahci_mobile }, /* Lynx LP RAID */
|
||||
+ { PCI_VDEVICE(INTEL, 0x9c0f), board_ahci_mobile }, /* Lynx LP RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x1f22), board_ahci }, /* Avoton AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x1f23), board_ahci }, /* Avoton AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x1f24), board_ahci }, /* Avoton RAID */
|
||||
@@ -353,26 +361,26 @@ static const struct pci_device_id ahci_pci_tbl[] = {
|
||||
{ PCI_VDEVICE(INTEL, 0x8d66), board_ahci }, /* Wellsburg RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x8d6e), board_ahci }, /* Wellsburg RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x23a3), board_ahci }, /* Coleto Creek AHCI */
|
||||
- { PCI_VDEVICE(INTEL, 0x9c83), board_ahci }, /* Wildcat Point-LP AHCI */
|
||||
- { PCI_VDEVICE(INTEL, 0x9c85), board_ahci }, /* Wildcat Point-LP RAID */
|
||||
- { PCI_VDEVICE(INTEL, 0x9c87), board_ahci }, /* Wildcat Point-LP RAID */
|
||||
- { PCI_VDEVICE(INTEL, 0x9c8f), board_ahci }, /* Wildcat Point-LP RAID */
|
||||
+ { PCI_VDEVICE(INTEL, 0x9c83), board_ahci_mobile }, /* Wildcat LP AHCI */
|
||||
+ { PCI_VDEVICE(INTEL, 0x9c85), board_ahci_mobile }, /* Wildcat LP RAID */
|
||||
+ { PCI_VDEVICE(INTEL, 0x9c87), board_ahci_mobile }, /* Wildcat LP RAID */
|
||||
+ { PCI_VDEVICE(INTEL, 0x9c8f), board_ahci_mobile }, /* Wildcat LP RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c82), board_ahci }, /* 9 Series AHCI */
|
||||
- { PCI_VDEVICE(INTEL, 0x8c83), board_ahci }, /* 9 Series M AHCI */
|
||||
+ { PCI_VDEVICE(INTEL, 0x8c83), board_ahci_mobile }, /* 9 Series M AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c84), board_ahci }, /* 9 Series RAID */
|
||||
- { PCI_VDEVICE(INTEL, 0x8c85), board_ahci }, /* 9 Series M RAID */
|
||||
+ { PCI_VDEVICE(INTEL, 0x8c85), board_ahci_mobile }, /* 9 Series M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c86), board_ahci }, /* 9 Series RAID */
|
||||
- { PCI_VDEVICE(INTEL, 0x8c87), board_ahci }, /* 9 Series M RAID */
|
||||
+ { PCI_VDEVICE(INTEL, 0x8c87), board_ahci_mobile }, /* 9 Series M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x8c8e), board_ahci }, /* 9 Series RAID */
|
||||
- { PCI_VDEVICE(INTEL, 0x8c8f), board_ahci }, /* 9 Series M RAID */
|
||||
- { PCI_VDEVICE(INTEL, 0x9d03), board_ahci }, /* Sunrise Point-LP AHCI */
|
||||
- { PCI_VDEVICE(INTEL, 0x9d05), board_ahci }, /* Sunrise Point-LP RAID */
|
||||
- { PCI_VDEVICE(INTEL, 0x9d07), board_ahci }, /* Sunrise Point-LP RAID */
|
||||
+ { PCI_VDEVICE(INTEL, 0x8c8f), board_ahci_mobile }, /* 9 Series M RAID */
|
||||
+ { PCI_VDEVICE(INTEL, 0x9d03), board_ahci_mobile }, /* Sunrise LP AHCI */
|
||||
+ { PCI_VDEVICE(INTEL, 0x9d05), board_ahci_mobile }, /* Sunrise LP RAID */
|
||||
+ { PCI_VDEVICE(INTEL, 0x9d07), board_ahci_mobile }, /* Sunrise LP RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0xa102), board_ahci }, /* Sunrise Point-H AHCI */
|
||||
- { PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H M AHCI */
|
||||
+ { PCI_VDEVICE(INTEL, 0xa103), board_ahci_mobile }, /* Sunrise M AHCI */
|
||||
{ PCI_VDEVICE(INTEL, 0xa105), board_ahci }, /* Sunrise Point-H RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0xa106), board_ahci }, /* Sunrise Point-H RAID */
|
||||
- { PCI_VDEVICE(INTEL, 0xa107), board_ahci }, /* Sunrise Point-H M RAID */
|
||||
+ { PCI_VDEVICE(INTEL, 0xa107), board_ahci_mobile }, /* Sunrise M RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0xa10f), board_ahci }, /* Sunrise Point-H RAID */
|
||||
{ PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* Lewisburg RAID*/
|
||||
{ PCI_VDEVICE(INTEL, 0x2823), board_ahci }, /* Lewisburg AHCI*/
|
||||
@@ -386,10 +394,10 @@ static const struct pci_device_id ahci_pci_tbl[] = {
|
||||
{ PCI_VDEVICE(INTEL, 0xa206), board_ahci }, /* Lewisburg RAID*/
|
||||
{ PCI_VDEVICE(INTEL, 0xa252), board_ahci }, /* Lewisburg RAID*/
|
||||
{ PCI_VDEVICE(INTEL, 0xa256), board_ahci }, /* Lewisburg RAID*/
|
||||
- { PCI_VDEVICE(INTEL, 0x0f22), board_ahci }, /* Bay Trail AHCI */
|
||||
- { PCI_VDEVICE(INTEL, 0x0f23), board_ahci }, /* Bay Trail AHCI */
|
||||
- { PCI_VDEVICE(INTEL, 0x22a3), board_ahci }, /* Cherry Trail AHCI */
|
||||
- { PCI_VDEVICE(INTEL, 0x5ae3), board_ahci }, /* Apollo Lake AHCI */
|
||||
+ { PCI_VDEVICE(INTEL, 0x0f22), board_ahci_mobile }, /* Bay Trail AHCI */
|
||||
+ { PCI_VDEVICE(INTEL, 0x0f23), board_ahci_mobile }, /* Bay Trail AHCI */
|
||||
+ { PCI_VDEVICE(INTEL, 0x22a3), board_ahci_mobile }, /* Cherry Tr. AHCI */
|
||||
+ { PCI_VDEVICE(INTEL, 0x5ae3), board_ahci_mobile }, /* ApolloLake AHCI */
|
||||
|
||||
/* JMicron 360/1/3/5/6, match class to avoid IDE function */
|
||||
{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
|
||||
@@ -597,6 +605,9 @@ static int marvell_enable = 1;
|
||||
module_param(marvell_enable, int, 0644);
|
||||
MODULE_PARM_DESC(marvell_enable, "Marvell SATA via AHCI (1 = enabled)");
|
||||
|
||||
+static int mobile_lpm_policy = CONFIG_SATA_MOBILE_LPM_POLICY;
|
||||
+module_param(mobile_lpm_policy, int, 0644);
|
||||
+MODULE_PARM_DESC(mobile_lpm_policy, "Default LPM policy for mobile chipsets");
|
||||
|
||||
static void ahci_pci_save_initial_config(struct pci_dev *pdev,
|
||||
struct ahci_host_priv *hpriv)
|
||||
@@ -1732,6 +1743,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
if (ap->flags & ATA_FLAG_EM)
|
||||
ap->em_message_type = hpriv->em_msg_type;
|
||||
|
||||
+ if ((hpriv->flags & AHCI_HFLAG_IS_MOBILE) &&
|
||||
+ mobile_lpm_policy >= ATA_LPM_UNKNOWN &&
|
||||
+ mobile_lpm_policy <= ATA_LPM_MIN_POWER)
|
||||
+ ap->target_lpm_policy = mobile_lpm_policy;
|
||||
|
||||
/* disabled/not-implemented port */
|
||||
if (!(hpriv->port_map & (1 << i)))
|
||||
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
|
||||
index 749fd94441b0..a9d996e17d75 100644
|
||||
--- a/drivers/ata/ahci.h
|
||||
+++ b/drivers/ata/ahci.h
|
||||
@@ -251,6 +251,9 @@ enum {
|
||||
AHCI_HFLAG_YES_ALPM = (1 << 23), /* force ALPM cap on */
|
||||
AHCI_HFLAG_NO_WRITE_TO_RO = (1 << 24), /* don't write to read
|
||||
only registers */
|
||||
+ AHCI_HFLAG_IS_MOBILE = (1 << 25), /* mobile chipset, use
|
||||
+ SATA_MOBILE_LPM_POLICY
|
||||
+ as default lpm_policy */
|
||||
|
||||
/* ap->flags bits */
|
||||
|
||||
--
|
||||
2.14.3
|
||||
|
@ -1,55 +0,0 @@
|
||||
From patchwork Mon Oct 2 14:08:40 2017
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
MIME-Version: 1.0
|
||||
Content-Transfer-Encoding: 7bit
|
||||
Subject: PCI: aspm: deal with missing root ports in link state handling
|
||||
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
|
||||
X-Patchwork-Id: 9980861
|
||||
Message-Id: <20171002140840.7767-1-ard.biesheuvel@linaro.org>
|
||||
To: linux-pci@vger.kernel.org, bhelgaas@google.com
|
||||
Cc: graeme.gregory@linaro.org, leif.lindholm@linaro.org,
|
||||
daniel.thompson@Linaro.org, Ard Biesheuvel <ard.biesheuvel@linaro.org>
|
||||
Date: Mon, 2 Oct 2017 15:08:40 +0100
|
||||
|
||||
Even though it is unconventional, some PCIe host implementations omit
|
||||
the root ports entirely, and simply consist of a host bridge (which
|
||||
is not modeled as a device in the PCI hierarchy) and a link.
|
||||
|
||||
When the downstream device is an endpoint, our current code does not
|
||||
seem to mind this unusual configuration. However, when PCIe switches
|
||||
are involved, the ASPM code assumes that any downstream switch port
|
||||
has a parent, and blindly derefences the bus->parent->self field of
|
||||
the pci_dev struct to chain the downstream link state to the link
|
||||
state of the root port. Given that the root port is missing, the link
|
||||
is not modeled at all, and nor is the link state, and attempting to
|
||||
access it results in a NULL pointer dereference and a crash.
|
||||
|
||||
So let's avoid this by allowing the link state chain to terminate at
|
||||
the downstream port if no root port exists.
|
||||
|
||||
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
|
||||
---
|
||||
drivers/pci/pcie/aspm.c | 8 ++++++--
|
||||
1 file changed, 6 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
|
||||
index 1dfa10cc566b..0bea8498b5a5 100644
|
||||
--- a/drivers/pci/pcie/aspm.c
|
||||
+++ b/drivers/pci/pcie/aspm.c
|
||||
@@ -802,10 +802,14 @@ static struct pcie_link_state *alloc_pcie_link_state(struct pci_dev *pdev)
|
||||
|
||||
/*
|
||||
* Root Ports and PCI/PCI-X to PCIe Bridges are roots of PCIe
|
||||
- * hierarchies.
|
||||
+ * hierarchies. Note that some PCIe host implementations omit
|
||||
+ * the root ports entirely, in which case a downstream port on
|
||||
+ * a switch may become the root of the link state chain for all
|
||||
+ * its subordinate endpoints.
|
||||
*/
|
||||
if (pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT ||
|
||||
- pci_pcie_type(pdev) == PCI_EXP_TYPE_PCIE_BRIDGE) {
|
||||
+ pci_pcie_type(pdev) == PCI_EXP_TYPE_PCIE_BRIDGE ||
|
||||
+ !pdev->bus->parent->self) {
|
||||
link->root = link;
|
||||
} else {
|
||||
struct pcie_link_state *parent;
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,41 @@
|
||||
From patchwork Thu Jan 18 12:34:18 2018
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
MIME-Version: 1.0
|
||||
Content-Transfer-Encoding: 7bit
|
||||
Subject: ARM: dts: imx6qdl-udoo: Disable usbh1 to avoid kernel hang
|
||||
From: Fabio Estevam <fabio.estevam@nxp.com>
|
||||
X-Patchwork-Id: 10173115
|
||||
Message-Id: <1516278858-15464-1-git-send-email-fabio.estevam@nxp.com>
|
||||
To: <shawnguo@kernel.org>
|
||||
Cc: maggu2810@gmail.com, peter.chen@nxp.com, mail@maciej.szmigiero.name,
|
||||
Fabio Estevam <fabio.estevam@nxp.com>, linux-arm-kernel@lists.infradead.org
|
||||
Date: Thu, 18 Jan 2018 10:34:18 -0200
|
||||
|
||||
Currently the kernel hangs when USB Host1 is enabled due to the lack of
|
||||
support for controlling the USB hub clock and GPIO reset line.
|
||||
|
||||
Peter Chen has made several attempts to fix this problem, but his series
|
||||
has not been applied yet, so better disable USB host1 for now to avoid
|
||||
the kernel hang.
|
||||
|
||||
Signed-off-by: Fabio Estevam <fabio.estevam@nxp.com>
|
||||
Acked-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name>
|
||||
Tested-by: Markus Rathgeb <maggu2810@gmail.com>
|
||||
---
|
||||
arch/arm/boot/dts/imx6qdl-udoo.dtsi | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/imx6qdl-udoo.dtsi b/arch/arm/boot/dts/imx6qdl-udoo.dtsi
|
||||
index 4161b7d..1f0b9f6 100644
|
||||
--- a/arch/arm/boot/dts/imx6qdl-udoo.dtsi
|
||||
+++ b/arch/arm/boot/dts/imx6qdl-udoo.dtsi
|
||||
@@ -274,7 +274,8 @@
|
||||
pinctrl-0 = <&pinctrl_usbh>;
|
||||
vbus-supply = <®_usb_h1_vbus>;
|
||||
clocks = <&clks IMX6QDL_CLK_CKO>;
|
||||
- status = "okay";
|
||||
+ /* currently USB support causes a kernel hang. Disable it for now */
|
||||
+ status = "disabled";
|
||||
};
|
||||
|
||||
&usdhc3 {
|
@ -1,411 +0,0 @@
|
||||
From patchwork Mon Oct 9 12:00:50 2017
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
MIME-Version: 1.0
|
||||
Content-Transfer-Encoding: 7bit
|
||||
Subject: [PATCHv4,1/2] drivers: phy: add calibrate method
|
||||
From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
|
||||
X-Patchwork-Id: 9992829
|
||||
Message-Id: <1507550451-21324-2-git-send-email-andrzej.p@samsung.com>
|
||||
To: linux-samsung-soc@vger.kernel.org, linux-usb@vger.kernel.org,
|
||||
linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>, Felipe Balbi <balbi@kernel.org>,
|
||||
Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>,
|
||||
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
|
||||
Russell King <linux@armlinux.org.uk>,
|
||||
Krzysztof Kozlowski <krzk@kernel.org>,
|
||||
Kishon Vijay Abraham I <kishon@ti.com>,
|
||||
Rob Herring <robh+dt@kernel.org>, Kukjin Kim <kgene@kernel.org>,
|
||||
Andrzej Pietrasiewicz <andrzej.p@samsung.com>,
|
||||
Marek Szyprowski <m.szyprowski@samsung.com>
|
||||
Date: Mon, 09 Oct 2017 14:00:50 +0200
|
||||
|
||||
Some quirky UDCs (like dwc3 on Exynos) need to have their phys calibrated e.g.
|
||||
for using super speed. This patch adds a new phy_calibrate() method.
|
||||
When the calibration should be used is dependent on actual chip.
|
||||
|
||||
In case of dwc3 on Exynos the calibration must happen after usb_add_hcd()
|
||||
(while in host mode), because certain phy parameters like Tx LOS levels
|
||||
and boost levels need to be calibrated further post initialization of xHCI
|
||||
controller, to get SuperSpeed operations working. But an hcd must be
|
||||
prepared first in order to pass it to usb_add_hcd(), so, in particular, dwc3
|
||||
registers must be available first, and in order for the latter to happen
|
||||
the phys must be initialized. This poses a chicken and egg problem if
|
||||
the calibration were to be performed in phy_init(). To break the circular
|
||||
dependency a separate method is added which can be called at a desired
|
||||
moment after phy intialization.
|
||||
|
||||
Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
|
||||
---
|
||||
drivers/phy/phy-core.c | 15 +++++++++++++++
|
||||
include/linux/phy/phy.h | 10 ++++++++++
|
||||
2 files changed, 25 insertions(+)
|
||||
|
||||
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
|
||||
index a268f4d..b4964b0 100644
|
||||
--- a/drivers/phy/phy-core.c
|
||||
+++ b/drivers/phy/phy-core.c
|
||||
@@ -372,6 +372,21 @@ int phy_reset(struct phy *phy)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(phy_reset);
|
||||
|
||||
+int phy_calibrate(struct phy *phy)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ if (!phy || !phy->ops->calibrate)
|
||||
+ return 0;
|
||||
+
|
||||
+ mutex_lock(&phy->mutex);
|
||||
+ ret = phy->ops->calibrate(phy);
|
||||
+ mutex_unlock(&phy->mutex);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(phy_calibrate);
|
||||
+
|
||||
/**
|
||||
* _of_phy_get() - lookup and obtain a reference to a phy by phandle
|
||||
* @np: device_node for which to get the phy
|
||||
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
|
||||
index e694d40..87580c8 100644
|
||||
--- a/include/linux/phy/phy.h
|
||||
+++ b/include/linux/phy/phy.h
|
||||
@@ -39,6 +39,7 @@ enum phy_mode {
|
||||
* @power_off: powering off the phy
|
||||
* @set_mode: set the mode of the phy
|
||||
* @reset: resetting the phy
|
||||
+ * @calibrate: calibrate the phy
|
||||
* @owner: the module owner containing the ops
|
||||
*/
|
||||
struct phy_ops {
|
||||
@@ -48,6 +49,7 @@ struct phy_ops {
|
||||
int (*power_off)(struct phy *phy);
|
||||
int (*set_mode)(struct phy *phy, enum phy_mode mode);
|
||||
int (*reset)(struct phy *phy);
|
||||
+ int (*calibrate)(struct phy *phy);
|
||||
struct module *owner;
|
||||
};
|
||||
|
||||
@@ -141,6 +143,7 @@ static inline void *phy_get_drvdata(struct phy *phy)
|
||||
int phy_power_off(struct phy *phy);
|
||||
int phy_set_mode(struct phy *phy, enum phy_mode mode);
|
||||
int phy_reset(struct phy *phy);
|
||||
+int phy_calibrate(struct phy *phy);
|
||||
static inline int phy_get_bus_width(struct phy *phy)
|
||||
{
|
||||
return phy->attrs.bus_width;
|
||||
@@ -262,6 +265,13 @@ static inline int phy_reset(struct phy *phy)
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
+static inline int phy_calibrate(struct phy *phy)
|
||||
+{
|
||||
+ if (!phy)
|
||||
+ return 0;
|
||||
+ return -ENOSYS;
|
||||
+}
|
||||
+
|
||||
static inline int phy_get_bus_width(struct phy *phy)
|
||||
{
|
||||
return -ENOSYS;
|
||||
From patchwork Mon Oct 9 12:00:51 2017
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
MIME-Version: 1.0
|
||||
Content-Transfer-Encoding: 7bit
|
||||
Subject: [PATCHv4,
|
||||
2/2] phy: exynos5-usbdrd: Calibrate LOS levels for exynos5420/5800
|
||||
From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
|
||||
X-Patchwork-Id: 9992809
|
||||
Message-Id: <1507550451-21324-3-git-send-email-andrzej.p@samsung.com>
|
||||
To: linux-samsung-soc@vger.kernel.org, linux-usb@vger.kernel.org,
|
||||
linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>, Felipe Balbi <balbi@kernel.org>,
|
||||
Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>,
|
||||
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
|
||||
Russell King <linux@armlinux.org.uk>,
|
||||
Krzysztof Kozlowski <krzk@kernel.org>,
|
||||
Kishon Vijay Abraham I <kishon@ti.com>,
|
||||
Rob Herring <robh+dt@kernel.org>, Kukjin Kim <kgene@kernel.org>,
|
||||
Andrzej Pietrasiewicz <andrzej.p@samsung.com>,
|
||||
Marek Szyprowski <m.szyprowski@samsung.com>
|
||||
Date: Mon, 09 Oct 2017 14:00:51 +0200
|
||||
|
||||
From: Vivek Gautam <gautam.vivek@samsung.com>
|
||||
|
||||
Adding phy calibration sequence for USB 3.0 DRD PHY present on
|
||||
Exynos5420/5800 systems.
|
||||
This calibration facilitates setting certain PHY parameters viz.
|
||||
the Loss-of-Signal (LOS) Detector Threshold Level, as well as
|
||||
Tx-Vboost-Level for Super-Speed operations.
|
||||
Additionally we also set proper time to wait for RxDetect measurement,
|
||||
for desired PHY reference clock, so as to solve issue with enumeration
|
||||
of few USB 3.0 devices, like Samsung SUM-TSB16S 3.0 USB drive
|
||||
on the controller.
|
||||
|
||||
We are using CR_port for this purpose to send required data
|
||||
to override the LOS values.
|
||||
|
||||
On testing with USB 3.0 devices on USB 3.0 port present on
|
||||
SMDK5420, and peach-pit boards should see following message:
|
||||
usb 2-1: new SuperSpeed USB device number 2 using xhci-hcd
|
||||
|
||||
and without this patch, should see below shown message:
|
||||
usb 1-1: new high-speed USB device number 2 using xhci-hcd
|
||||
|
||||
[Also removed unnecessary extra lines in the register macro definitions]
|
||||
|
||||
Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
|
||||
[adapted to use phy_calibrate as entry point]
|
||||
Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
|
||||
---
|
||||
drivers/phy/samsung/phy-exynos5-usbdrd.c | 183 +++++++++++++++++++++++++++++++
|
||||
drivers/usb/dwc3/core.c | 7 +-
|
||||
2 files changed, 188 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c
|
||||
index 22c68f5..9e83c15 100644
|
||||
--- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
|
||||
+++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
|
||||
@@ -90,7 +90,17 @@
|
||||
#define PHYCLKRST_COMMONONN BIT(0)
|
||||
|
||||
#define EXYNOS5_DRD_PHYREG0 0x14
|
||||
+#define PHYREG0_SSC_REF_CLK_SEL BIT(21)
|
||||
+#define PHYREG0_SSC_RANGE BIT(20)
|
||||
+#define PHYREG0_CR_WRITE BIT(19)
|
||||
+#define PHYREG0_CR_READ BIT(18)
|
||||
+#define PHYREG0_CR_DATA_IN(_x) ((_x) << 2)
|
||||
+#define PHYREG0_CR_CAP_DATA BIT(1)
|
||||
+#define PHYREG0_CR_CAP_ADDR BIT(0)
|
||||
+
|
||||
#define EXYNOS5_DRD_PHYREG1 0x18
|
||||
+#define PHYREG1_CR_DATA_OUT(_x) ((_x) << 1)
|
||||
+#define PHYREG1_CR_ACK BIT(0)
|
||||
|
||||
#define EXYNOS5_DRD_PHYPARAM0 0x1c
|
||||
|
||||
@@ -119,6 +129,25 @@
|
||||
#define EXYNOS5_DRD_PHYRESUME 0x34
|
||||
#define EXYNOS5_DRD_LINKPORT 0x44
|
||||
|
||||
+/* USB 3.0 DRD PHY SS Function Control Reg; accessed by CR_PORT */
|
||||
+#define EXYNOS5_DRD_PHYSS_LOSLEVEL_OVRD_IN (0x15)
|
||||
+#define LOSLEVEL_OVRD_IN_LOS_BIAS_5420 (0x5 << 13)
|
||||
+#define LOSLEVEL_OVRD_IN_LOS_BIAS_DEFAULT (0x0 << 13)
|
||||
+#define LOSLEVEL_OVRD_IN_EN (0x1 << 10)
|
||||
+#define LOSLEVEL_OVRD_IN_LOS_LEVEL_DEFAULT (0x9 << 0)
|
||||
+
|
||||
+#define EXYNOS5_DRD_PHYSS_TX_VBOOSTLEVEL_OVRD_IN (0x12)
|
||||
+#define TX_VBOOSTLEVEL_OVRD_IN_VBOOST_5420 (0x5 << 13)
|
||||
+#define TX_VBOOSTLEVEL_OVRD_IN_VBOOST_DEFAULT (0x4 << 13)
|
||||
+
|
||||
+#define EXYNOS5_DRD_PHYSS_LANE0_TX_DEBUG (0x1010)
|
||||
+#define LANE0_TX_DEBUG_RXDET_MEAS_TIME_19M2_20M (0x4 << 4)
|
||||
+#define LANE0_TX_DEBUG_RXDET_MEAS_TIME_24M (0x8 << 4)
|
||||
+#define LANE0_TX_DEBUG_RXDET_MEAS_TIME_25M_26M (0x8 << 4)
|
||||
+#define LANE0_TX_DEBUG_RXDET_MEAS_TIME_48M_50M_52M (0x20 << 4)
|
||||
+#define LANE0_TX_DEBUG_RXDET_MEAS_TIME_62M5 (0x20 << 4)
|
||||
+#define LANE0_TX_DEBUG_RXDET_MEAS_TIME_96M_100M (0x40 << 4)
|
||||
+
|
||||
#define KHZ 1000
|
||||
#define MHZ (KHZ * KHZ)
|
||||
|
||||
@@ -527,6 +556,151 @@ static int exynos5_usbdrd_phy_power_off(struct phy *phy)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int crport_handshake(struct exynos5_usbdrd_phy *phy_drd,
|
||||
+ u32 val, u32 cmd)
|
||||
+{
|
||||
+ u32 usec = 100;
|
||||
+ unsigned int result;
|
||||
+
|
||||
+ writel(val | cmd, phy_drd->reg_phy + EXYNOS5_DRD_PHYREG0);
|
||||
+
|
||||
+ do {
|
||||
+ result = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYREG1);
|
||||
+ if (result & PHYREG1_CR_ACK)
|
||||
+ break;
|
||||
+
|
||||
+ udelay(1);
|
||||
+ } while (usec-- > 0);
|
||||
+
|
||||
+ if (!usec) {
|
||||
+ dev_err(phy_drd->dev,
|
||||
+ "CRPORT handshake timeout1 (0x%08x)\n", val);
|
||||
+ return -ETIME;
|
||||
+ }
|
||||
+
|
||||
+ usec = 100;
|
||||
+
|
||||
+ writel(val, phy_drd->reg_phy + EXYNOS5_DRD_PHYREG0);
|
||||
+
|
||||
+ do {
|
||||
+ result = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYREG1);
|
||||
+ if (!(result & PHYREG1_CR_ACK))
|
||||
+ break;
|
||||
+
|
||||
+ udelay(1);
|
||||
+ } while (usec-- > 0);
|
||||
+
|
||||
+ if (!usec) {
|
||||
+ dev_err(phy_drd->dev,
|
||||
+ "CRPORT handshake timeout2 (0x%08x)\n", val);
|
||||
+ return -ETIME;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int crport_ctrl_write(struct exynos5_usbdrd_phy *phy_drd,
|
||||
+ u32 addr, u32 data)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ /* Write Address */
|
||||
+ writel(PHYREG0_CR_DATA_IN(addr),
|
||||
+ phy_drd->reg_phy + EXYNOS5_DRD_PHYREG0);
|
||||
+ ret = crport_handshake(phy_drd, PHYREG0_CR_DATA_IN(addr),
|
||||
+ PHYREG0_CR_CAP_ADDR);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Write Data */
|
||||
+ writel(PHYREG0_CR_DATA_IN(data),
|
||||
+ phy_drd->reg_phy + EXYNOS5_DRD_PHYREG0);
|
||||
+ ret = crport_handshake(phy_drd, PHYREG0_CR_DATA_IN(data),
|
||||
+ PHYREG0_CR_CAP_DATA);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = crport_handshake(phy_drd, PHYREG0_CR_DATA_IN(data),
|
||||
+ PHYREG0_CR_WRITE);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Calibrate few PHY parameters using CR_PORT register to meet
|
||||
+ * SuperSpeed requirements on Exynos5420 and Exynos5800 systems,
|
||||
+ * which have 28nm USB 3.0 DRD PHY.
|
||||
+ */
|
||||
+static int exynos5420_usbdrd_phy_calibrate(struct exynos5_usbdrd_phy *phy_drd)
|
||||
+{
|
||||
+ unsigned int temp;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ /*
|
||||
+ * Change los_bias to (0x5) for 28nm PHY from a
|
||||
+ * default value (0x0); los_level is set as default
|
||||
+ * (0x9) as also reflected in los_level[30:26] bits
|
||||
+ * of PHYPARAM0 register.
|
||||
+ */
|
||||
+ temp = LOSLEVEL_OVRD_IN_LOS_BIAS_5420 |
|
||||
+ LOSLEVEL_OVRD_IN_EN |
|
||||
+ LOSLEVEL_OVRD_IN_LOS_LEVEL_DEFAULT;
|
||||
+ ret = crport_ctrl_write(phy_drd,
|
||||
+ EXYNOS5_DRD_PHYSS_LOSLEVEL_OVRD_IN,
|
||||
+ temp);
|
||||
+ if (ret) {
|
||||
+ dev_err(phy_drd->dev,
|
||||
+ "Failed setting Loss-of-Signal level for SuperSpeed\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Set tx_vboost_lvl to (0x5) for 28nm PHY Tuning,
|
||||
+ * to raise Tx signal level from its default value of (0x4)
|
||||
+ */
|
||||
+ temp = TX_VBOOSTLEVEL_OVRD_IN_VBOOST_5420;
|
||||
+ ret = crport_ctrl_write(phy_drd,
|
||||
+ EXYNOS5_DRD_PHYSS_TX_VBOOSTLEVEL_OVRD_IN,
|
||||
+ temp);
|
||||
+ if (ret) {
|
||||
+ dev_err(phy_drd->dev,
|
||||
+ "Failed setting Tx-Vboost-Level for SuperSpeed\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Set proper time to wait for RxDetect measurement, for
|
||||
+ * desired reference clock of PHY, by tuning the CR_PORT
|
||||
+ * register LANE0.TX_DEBUG which is internal to PHY.
|
||||
+ * This fixes issue with few USB 3.0 devices, which are
|
||||
+ * not detected (not even generate interrupts on the bus
|
||||
+ * on insertion) without this change.
|
||||
+ * e.g. Samsung SUM-TSB16S 3.0 USB drive.
|
||||
+ */
|
||||
+ switch (phy_drd->extrefclk) {
|
||||
+ case EXYNOS5_FSEL_50MHZ:
|
||||
+ temp = LANE0_TX_DEBUG_RXDET_MEAS_TIME_48M_50M_52M;
|
||||
+ break;
|
||||
+ case EXYNOS5_FSEL_20MHZ:
|
||||
+ case EXYNOS5_FSEL_19MHZ2:
|
||||
+ temp = LANE0_TX_DEBUG_RXDET_MEAS_TIME_19M2_20M;
|
||||
+ break;
|
||||
+ case EXYNOS5_FSEL_24MHZ:
|
||||
+ default:
|
||||
+ temp = LANE0_TX_DEBUG_RXDET_MEAS_TIME_24M;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ ret = crport_ctrl_write(phy_drd,
|
||||
+ EXYNOS5_DRD_PHYSS_LANE0_TX_DEBUG,
|
||||
+ temp);
|
||||
+ if (ret)
|
||||
+ dev_err(phy_drd->dev,
|
||||
+ "Failed setting RxDetect measurement time for SuperSpeed\n");
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static struct phy *exynos5_usbdrd_phy_xlate(struct device *dev,
|
||||
struct of_phandle_args *args)
|
||||
{
|
||||
@@ -538,11 +712,20 @@ static struct phy *exynos5_usbdrd_phy_xlate(struct device *dev,
|
||||
return phy_drd->phys[args->args[0]].phy;
|
||||
}
|
||||
|
||||
+static int exynos5_usbdrd_phy_calibrate(struct phy *phy)
|
||||
+{
|
||||
+ struct phy_usb_instance *inst = phy_get_drvdata(phy);
|
||||
+ struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst);
|
||||
+
|
||||
+ return exynos5420_usbdrd_phy_calibrate(phy_drd);
|
||||
+}
|
||||
+
|
||||
static const struct phy_ops exynos5_usbdrd_phy_ops = {
|
||||
.init = exynos5_usbdrd_phy_init,
|
||||
.exit = exynos5_usbdrd_phy_exit,
|
||||
.power_on = exynos5_usbdrd_phy_power_on,
|
||||
.power_off = exynos5_usbdrd_phy_power_off,
|
||||
+ .calibrate = exynos5_usbdrd_phy_calibrate,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
|
||||
index 03474d3..224e0dd 100644
|
||||
--- a/drivers/usb/dwc3/core.c
|
||||
+++ b/drivers/usb/dwc3/core.c
|
||||
@@ -156,9 +156,10 @@ static void __dwc3_set_mode(struct work_struct *work)
|
||||
} else {
|
||||
if (dwc->usb2_phy)
|
||||
otg_set_vbus(dwc->usb2_phy->otg, true);
|
||||
- if (dwc->usb2_generic_phy)
|
||||
+ if (dwc->usb2_generic_phy) {
|
||||
phy_set_mode(dwc->usb2_generic_phy, PHY_MODE_USB_HOST);
|
||||
-
|
||||
+ phy_calibrate(dwc->usb2_generic_phy);
|
||||
+ }
|
||||
}
|
||||
break;
|
||||
case DWC3_GCTL_PRTCAP_DEVICE:
|
||||
@@ -955,6 +956,8 @@ static int dwc3_core_init_mode(struct dwc3 *dwc)
|
||||
dev_err(dev, "failed to initialize host\n");
|
||||
return ret;
|
||||
}
|
||||
+ if (dwc->usb2_generic_phy)
|
||||
+ phy_calibrate(dwc->usb2_generic_phy);
|
||||
break;
|
||||
case USB_DR_MODE_OTG:
|
||||
INIT_WORK(&dwc->drd_work, __dwc3_set_mode);
|
146
arm64-mmc-sdhci_f_sdh30-add-ACPI-support.patch
Normal file
146
arm64-mmc-sdhci_f_sdh30-add-ACPI-support.patch
Normal file
@ -0,0 +1,146 @@
|
||||
From patchwork Mon Jan 8 15:44:19 2018
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
MIME-Version: 1.0
|
||||
Content-Transfer-Encoding: 7bit
|
||||
Subject: [v2] mmc: sdhci_f_sdh30: add ACPI support
|
||||
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
|
||||
X-Patchwork-Id: 10149775
|
||||
Message-Id: <20180108154419.2821-1-ard.biesheuvel@linaro.org>
|
||||
To: linux-mmc@vger.kernel.org
|
||||
Cc: adrian.hunter@intel.com, ulf.hansson@linaro.org,
|
||||
Ard Biesheuvel <ard.biesheuvel@linaro.org>
|
||||
Date: Mon, 8 Jan 2018 15:44:19 +0000
|
||||
|
||||
The Fujitsu SDH30 SDHCI controller may be described as a SCX0002 ACPI
|
||||
device on ACPI platforms incorporating the Socionext SynQuacer SoC.
|
||||
|
||||
Given that mmc_of_parse() has already been made ACPI/DT agnostic,
|
||||
making the SDH30 driver ACPI capable is actually rather simple:
|
||||
all we need to do is make the call to sdhci_get_of_property() [which
|
||||
does not set any properties we care about] and the clock handling
|
||||
dependent on whether we are dealing with a DT device, and exposing
|
||||
the ACPI id via the platform_driver struct and the module metadata.
|
||||
|
||||
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
|
||||
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
|
||||
---
|
||||
v2: make OF optional now that ACPI is supported
|
||||
drop dev_of_node() check when disabling the clocks - those routines
|
||||
tolerate NULL pointers so there's no need
|
||||
|
||||
drivers/mmc/host/Kconfig | 2 +-
|
||||
drivers/mmc/host/sdhci_f_sdh30.c | 52 +++++++++++++-------
|
||||
2 files changed, 35 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
|
||||
index 567028c9219a..07ed947ed10b 100644
|
||||
--- a/drivers/mmc/host/Kconfig
|
||||
+++ b/drivers/mmc/host/Kconfig
|
||||
@@ -320,7 +320,7 @@ config MMC_SDHCI_BCM_KONA
|
||||
config MMC_SDHCI_F_SDH30
|
||||
tristate "SDHCI support for Fujitsu Semiconductor F_SDH30"
|
||||
depends on MMC_SDHCI_PLTFM
|
||||
- depends on OF
|
||||
+ depends on OF || ACPI
|
||||
help
|
||||
This selects the Secure Digital Host Controller Interface (SDHCI)
|
||||
Needed by some Fujitsu SoC for MMC / SD / SDIO support.
|
||||
diff --git a/drivers/mmc/host/sdhci_f_sdh30.c b/drivers/mmc/host/sdhci_f_sdh30.c
|
||||
index 04ca0d33a521..485f7591fae4 100644
|
||||
--- a/drivers/mmc/host/sdhci_f_sdh30.c
|
||||
+++ b/drivers/mmc/host/sdhci_f_sdh30.c
|
||||
@@ -10,9 +10,11 @@
|
||||
* the Free Software Foundation, version 2 of the License.
|
||||
*/
|
||||
|
||||
+#include <linux/acpi.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/module.h>
|
||||
+#include <linux/of.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/clk.h>
|
||||
|
||||
@@ -146,7 +148,6 @@ static int sdhci_f_sdh30_probe(struct platform_device *pdev)
|
||||
|
||||
platform_set_drvdata(pdev, host);
|
||||
|
||||
- sdhci_get_of_property(pdev);
|
||||
host->hw_name = "f_sdh30";
|
||||
host->ops = &sdhci_f_sdh30_ops;
|
||||
host->irq = irq;
|
||||
@@ -158,25 +159,29 @@ static int sdhci_f_sdh30_probe(struct platform_device *pdev)
|
||||
goto err;
|
||||
}
|
||||
|
||||
- priv->clk_iface = devm_clk_get(&pdev->dev, "iface");
|
||||
- if (IS_ERR(priv->clk_iface)) {
|
||||
- ret = PTR_ERR(priv->clk_iface);
|
||||
- goto err;
|
||||
- }
|
||||
+ if (dev_of_node(dev)) {
|
||||
+ sdhci_get_of_property(pdev);
|
||||
|
||||
- ret = clk_prepare_enable(priv->clk_iface);
|
||||
- if (ret)
|
||||
- goto err;
|
||||
+ priv->clk_iface = devm_clk_get(&pdev->dev, "iface");
|
||||
+ if (IS_ERR(priv->clk_iface)) {
|
||||
+ ret = PTR_ERR(priv->clk_iface);
|
||||
+ goto err;
|
||||
+ }
|
||||
|
||||
- priv->clk = devm_clk_get(&pdev->dev, "core");
|
||||
- if (IS_ERR(priv->clk)) {
|
||||
- ret = PTR_ERR(priv->clk);
|
||||
- goto err_clk;
|
||||
- }
|
||||
+ ret = clk_prepare_enable(priv->clk_iface);
|
||||
+ if (ret)
|
||||
+ goto err;
|
||||
|
||||
- ret = clk_prepare_enable(priv->clk);
|
||||
- if (ret)
|
||||
- goto err_clk;
|
||||
+ priv->clk = devm_clk_get(&pdev->dev, "core");
|
||||
+ if (IS_ERR(priv->clk)) {
|
||||
+ ret = PTR_ERR(priv->clk);
|
||||
+ goto err_clk;
|
||||
+ }
|
||||
+
|
||||
+ ret = clk_prepare_enable(priv->clk);
|
||||
+ if (ret)
|
||||
+ goto err_clk;
|
||||
+ }
|
||||
|
||||
/* init vendor specific regs */
|
||||
ctrl = sdhci_readw(host, F_SDH30_AHB_CONFIG);
|
||||
@@ -226,16 +231,27 @@ static int sdhci_f_sdh30_remove(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_OF
|
||||
static const struct of_device_id f_sdh30_dt_ids[] = {
|
||||
{ .compatible = "fujitsu,mb86s70-sdhci-3.0" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, f_sdh30_dt_ids);
|
||||
+#endif
|
||||
+
|
||||
+#ifdef CONFIG_ACPI
|
||||
+static const struct acpi_device_id f_sdh30_acpi_ids[] = {
|
||||
+ { "SCX0002" },
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(acpi, f_sdh30_acpi_ids);
|
||||
+#endif
|
||||
|
||||
static struct platform_driver sdhci_f_sdh30_driver = {
|
||||
.driver = {
|
||||
.name = "f_sdh30",
|
||||
- .of_match_table = f_sdh30_dt_ids,
|
||||
+ .of_match_table = of_match_ptr(f_sdh30_dt_ids),
|
||||
+ .acpi_match_table = ACPI_PTR(f_sdh30_acpi_ids),
|
||||
.pm = &sdhci_pltfm_pmops,
|
||||
},
|
||||
.probe = sdhci_f_sdh30_probe,
|
@ -1,313 +1,3 @@
|
||||
From 33d983b5bb2929ae242606925e708092b1dfdd8f Mon Sep 17 00:00:00 2001
|
||||
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
|
||||
Date: Sat, 2 Sep 2017 11:01:22 +0100
|
||||
Subject: drivers/irqchip: gicv3: add workaround for Synquacer pre-ITS
|
||||
|
||||
In their infinite wisdom, the Socionext engineers have decided
|
||||
that ITS device IDs should not be hardwired, but it should be
|
||||
left up to the software to assign them, by allowing it to
|
||||
redirect MSI doorbell writes via a separate hardware block
|
||||
that issues the doorbell write with a device ID that is
|
||||
derived from the memory address. This completely breaks any
|
||||
kind of isolation, or virtualization in general, for that
|
||||
matter, but add support for it nonetheless.
|
||||
|
||||
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
|
||||
---
|
||||
arch/arm64/Kconfig | 8 +++++++
|
||||
drivers/irqchip/irq-gic-v3-its.c | 48 +++++++++++++++++++++++++++++++++++-----
|
||||
2 files changed, 51 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
|
||||
index 0df64a6..c4361df 100644
|
||||
--- a/arch/arm64/Kconfig
|
||||
+++ b/arch/arm64/Kconfig
|
||||
@@ -539,6 +539,14 @@ config QCOM_QDF2400_ERRATUM_0065
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
+config SOCIONEXT_SYNQUACER_PREITS
|
||||
+ bool "Socionext Synquacer: Workaround for GICv3 pre-ITS"
|
||||
+ default y
|
||||
+ help
|
||||
+ Socionext Synquacer SoCs implement a separate h/w block to generate
|
||||
+ MSI doorbell writes with non-zero values for the device ID.
|
||||
+
|
||||
+ If unsure, say Y.
|
||||
endmenu
|
||||
|
||||
|
||||
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
|
||||
index e8d8934..0d372f1 100644
|
||||
--- a/drivers/irqchip/irq-gic-v3-its.c
|
||||
+++ b/drivers/irqchip/irq-gic-v3-its.c
|
||||
@@ -46,6 +46,7 @@
|
||||
#define ITS_FLAGS_CMDQ_NEEDS_FLUSHING (1ULL << 0)
|
||||
#define ITS_FLAGS_WORKAROUND_CAVIUM_22375 (1ULL << 1)
|
||||
#define ITS_FLAGS_WORKAROUND_CAVIUM_23144 (1ULL << 2)
|
||||
+#define ITS_FLAGS_WORKAROUND_SOCIONEXT_PREITS (1ULL << 3)
|
||||
|
||||
#define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0)
|
||||
|
||||
@@ -99,6 +100,10 @@ struct its_node {
|
||||
struct its_collection *collections;
|
||||
struct list_head its_device_list;
|
||||
u64 flags;
|
||||
+#ifdef CONFIG_SOCIONEXT_SYNQUACER_PREITS
|
||||
+ u64 pre_its_base;
|
||||
+ u64 pre_its_size;
|
||||
+#endif
|
||||
u32 ite_size;
|
||||
u32 device_ids;
|
||||
int numa_node;
|
||||
@@ -1102,13 +1107,29 @@ static void its_irq_compose_msi_msg(struct irq_data *d, struct msi_msg *msg)
|
||||
u64 addr;
|
||||
|
||||
its = its_dev->its;
|
||||
- addr = its->phys_base + GITS_TRANSLATER;
|
||||
+
|
||||
+#ifdef CONFIG_SOCIONEXT_SYNQUACER_PREITS
|
||||
+ if (its->flags & ITS_FLAGS_WORKAROUND_SOCIONEXT_PREITS)
|
||||
+
|
||||
+ /*
|
||||
+ * The Socionext Synquacer SoC has a so-called 'pre-ITS',
|
||||
+ * which maps 32-bit writes into a separate window of size
|
||||
+ * '4 << device_id_bits' onto writes to GITS_TRANSLATER with
|
||||
+ * device ID taken from bits [device_id_bits + 1:2] of the
|
||||
+ * window offset.
|
||||
+ */
|
||||
+ addr = its->pre_its_base + (its_dev->device_id << 2);
|
||||
+ else
|
||||
+#endif
|
||||
+ addr = its->phys_base + GITS_TRANSLATER;
|
||||
|
||||
msg->address_lo = lower_32_bits(addr);
|
||||
msg->address_hi = upper_32_bits(addr);
|
||||
msg->data = its_get_event_id(d);
|
||||
|
||||
- iommu_dma_map_msi_msg(d->irq, msg);
|
||||
+ if (!IS_ENABLED(CONFIG_SOCIONEXT_SYNQUACER_PREITS) ||
|
||||
+ !(its->flags & ITS_FLAGS_WORKAROUND_SOCIONEXT_PREITS))
|
||||
+ iommu_dma_map_msi_msg(d->irq, msg);
|
||||
}
|
||||
|
||||
static int its_irq_set_irqchip_state(struct irq_data *d,
|
||||
@@ -1666,6 +1687,11 @@ static int its_alloc_tables(struct its_node *its)
|
||||
ids = 0x14; /* 20 bits, 8MB */
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_SOCIONEXT_SYNQUACER_PREITS
|
||||
+ if (its->flags & ITS_FLAGS_WORKAROUND_SOCIONEXT_PREITS)
|
||||
+ ids = ilog2(its->pre_its_size) - 2;
|
||||
+#endif
|
||||
+
|
||||
its->device_ids = ids;
|
||||
|
||||
for (i = 0; i < GITS_BASER_NR_REGS; i++) {
|
||||
@@ -2788,11 +2814,21 @@ static const struct gic_quirk its_quirks[] = {
|
||||
}
|
||||
};
|
||||
|
||||
-static void its_enable_quirks(struct its_node *its)
|
||||
+static void its_enable_quirks(struct its_node *its,
|
||||
+ struct fwnode_handle *handle)
|
||||
{
|
||||
u32 iidr = readl_relaxed(its->base + GITS_IIDR);
|
||||
|
||||
gic_enable_quirks(iidr, its_quirks, its);
|
||||
+
|
||||
+#ifdef CONFIG_SOCIONEXT_SYNQUACER_PREITS
|
||||
+ if (!fwnode_property_read_u64_array(handle,
|
||||
+ "socionext,synquacer-pre-its",
|
||||
+ &its->pre_its_base, 2)) {
|
||||
+ its->flags |= ITS_FLAGS_WORKAROUND_SOCIONEXT_PREITS;
|
||||
+ pr_info("ITS: enabling workaround for Socionext Synquacer pre-ITS\n");
|
||||
+ }
|
||||
+#endif
|
||||
}
|
||||
|
||||
static int its_init_domain(struct fwnode_handle *handle, struct its_node *its)
|
||||
@@ -2812,7 +2848,9 @@ static int its_init_domain(struct fwnode_handle *handle, struct its_node *its)
|
||||
|
||||
inner_domain->parent = its_parent;
|
||||
irq_domain_update_bus_token(inner_domain, DOMAIN_BUS_NEXUS);
|
||||
- inner_domain->flags |= IRQ_DOMAIN_FLAG_MSI_REMAP;
|
||||
+
|
||||
+ if (!(its->flags & ITS_FLAGS_WORKAROUND_SOCIONEXT_PREITS))
|
||||
+ inner_domain->flags |= IRQ_DOMAIN_FLAG_MSI_REMAP;
|
||||
info->ops = &its_msi_domain_ops;
|
||||
info->data = its;
|
||||
inner_domain->host_data = info;
|
||||
@@ -2966,7 +3004,7 @@ static int __init its_probe_one(struct resource *res,
|
||||
}
|
||||
its->cmd_write = its->cmd_base;
|
||||
|
||||
- its_enable_quirks(its);
|
||||
+ its_enable_quirks(its, handle);
|
||||
|
||||
err = its_alloc_tables(its);
|
||||
if (err)
|
||||
--
|
||||
cgit v1.1
|
||||
|
||||
From 26e7bb47b0fb03a01be1e391a08c7375b45335a2 Mon Sep 17 00:00:00 2001
|
||||
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
|
||||
Date: Mon, 21 Aug 2017 20:29:05 +0100
|
||||
Subject: pci: designware: add driver for DWC controller in ECAM shift mode
|
||||
|
||||
Some implementations of the Synopsys Designware PCIe controller implement
|
||||
a so-called ECAM shift mode, which allows a static memory window to be
|
||||
configured that covers the configuration space of the entire bus range.
|
||||
|
||||
If the firmware performs all the low level configuration that is required
|
||||
to expose this controller in a fully ECAM compatible manner, we can
|
||||
simply describe it as "pci-host-ecam-generic" and be done with it.
|
||||
However, it appears that in some cases (one of which is the Armada 80x0),
|
||||
the IP is synthesized with an ATU window size that does not allow the
|
||||
first bus to be mapped in a way that prevents the device on the
|
||||
downstream port from appearing more than once.
|
||||
|
||||
So implement a driver that relies on the firmware to perform all low
|
||||
level initialization, and drives the controller in ECAM mode, but
|
||||
overrides the config space accessors to take the above quirk into
|
||||
account.
|
||||
|
||||
Note that, unlike most drivers for this IP, this driver does not expose
|
||||
a fake bridge device at B/D/F 00:00.0. There is no point in doing so,
|
||||
given that this is not a true bridge, and does not require any windows
|
||||
to be configured in order for the downstream device to operate correctly.
|
||||
Omitting it also prevents the PCI resource allocation routines from
|
||||
handing out BAR space to it unnecessarily.
|
||||
|
||||
Cc: Bjorn Helgaas <bhelgaas@google.com>
|
||||
Cc: Jingoo Han <jingoohan1@gmail.com>
|
||||
Cc: Joao Pinto <Joao.Pinto@synopsys.com>
|
||||
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
|
||||
---
|
||||
drivers/pci/dwc/Kconfig | 11 +++++
|
||||
drivers/pci/dwc/Makefile | 1 +
|
||||
drivers/pci/dwc/pcie-designware-ecam.c | 77 ++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 89 insertions(+)
|
||||
create mode 100644 drivers/pci/dwc/pcie-designware-ecam.c
|
||||
|
||||
diff --git a/drivers/pci/dwc/Kconfig b/drivers/pci/dwc/Kconfig
|
||||
index 22ec82f..19856b1 100644
|
||||
--- a/drivers/pci/dwc/Kconfig
|
||||
+++ b/drivers/pci/dwc/Kconfig
|
||||
@@ -169,4 +169,15 @@ config PCIE_KIRIN
|
||||
Say Y here if you want PCIe controller support
|
||||
on HiSilicon Kirin series SoCs.
|
||||
|
||||
+config PCIE_DW_HOST_ECAM
|
||||
+ bool "Synopsys DesignWare PCIe controller in ECAM mode"
|
||||
+ depends on OF && PCI
|
||||
+ select PCI_HOST_COMMON
|
||||
+ select IRQ_DOMAIN
|
||||
+ help
|
||||
+ Add support for Synopsys DesignWare PCIe controllers configured
|
||||
+ by the firmware into ECAM shift mode. In some cases, these are
|
||||
+ fully ECAM compliant, in which case the pci-host-generic driver
|
||||
+ may be used instead.
|
||||
+
|
||||
endmenu
|
||||
diff --git a/drivers/pci/dwc/Makefile b/drivers/pci/dwc/Makefile
|
||||
index c61be97..7d5a23e 100644
|
||||
--- a/drivers/pci/dwc/Makefile
|
||||
+++ b/drivers/pci/dwc/Makefile
|
||||
@@ -1,5 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
obj-$(CONFIG_PCIE_DW) += pcie-designware.o
|
||||
obj-$(CONFIG_PCIE_DW_HOST) += pcie-designware-host.o
|
||||
+obj-$(CONFIG_PCIE_DW_HOST_ECAM) += pcie-designware-ecam.o
|
||||
obj-$(CONFIG_PCIE_DW_EP) += pcie-designware-ep.o
|
||||
obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
|
||||
ifneq ($(filter y,$(CONFIG_PCI_DRA7XX_HOST) $(CONFIG_PCI_DRA7XX_EP)),)
|
||||
diff --git a/drivers/pci/dwc/pcie-designware-ecam.c b/drivers/pci/dwc/pcie-designware-ecam.c
|
||||
new file mode 100644
|
||||
index 0000000..ede627d
|
||||
--- /dev/null
|
||||
+++ b/drivers/pci/dwc/pcie-designware-ecam.c
|
||||
@@ -0,0 +1,77 @@
|
||||
+/*
|
||||
+ * Driver for mostly ECAM compatible Synopsys dw PCIe controllers
|
||||
+ * configured by the firmware into RC mode
|
||||
+ *
|
||||
+ * 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.
|
||||
+ *
|
||||
+ * Copyright (C) 2014 ARM Limited
|
||||
+ * Copyright (C) 2017 Linaro Limited
|
||||
+ *
|
||||
+ * Authors: Will Deacon <will.deacon@arm.com>
|
||||
+ * Ard Biesheuvel <ard.biesheuvel@linaro.org>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/of_address.h>
|
||||
+#include <linux/of_pci.h>
|
||||
+#include <linux/pci-ecam.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+
|
||||
+static int pci_dw_ecam_config_read(struct pci_bus *bus, u32 devfn, int where,
|
||||
+ int size, u32 *val)
|
||||
+{
|
||||
+ struct pci_config_window *cfg = bus->sysdata;
|
||||
+
|
||||
+ /*
|
||||
+ * The Synopsys dw PCIe controller in RC mode will not filter type 0
|
||||
+ * config TLPs sent to devices 1 and up on its downstream port,
|
||||
+ * resulting in devices appearing multiple times on bus 0 unless we
|
||||
+ * filter them here.
|
||||
+ */
|
||||
+ if (bus->number == cfg->busr.start && PCI_SLOT(devfn) > 0) {
|
||||
+ *val = 0xffffffff;
|
||||
+ return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
+ }
|
||||
+ return pci_generic_config_read(bus, devfn, where, size, val);
|
||||
+}
|
||||
+
|
||||
+static int pci_dw_ecam_config_write(struct pci_bus *bus, u32 devfn, int where,
|
||||
+ int size, u32 val)
|
||||
+{
|
||||
+ struct pci_config_window *cfg = bus->sysdata;
|
||||
+
|
||||
+ if (bus->number == cfg->busr.start && PCI_SLOT(devfn) > 0)
|
||||
+ return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
+
|
||||
+ return pci_generic_config_write(bus, devfn, where, size, val);
|
||||
+}
|
||||
+
|
||||
+static struct pci_ecam_ops pci_dw_ecam_bus_ops = {
|
||||
+ .pci_ops.map_bus = pci_ecam_map_bus,
|
||||
+ .pci_ops.read = pci_dw_ecam_config_read,
|
||||
+ .pci_ops.write = pci_dw_ecam_config_write,
|
||||
+ .bus_shift = 20,
|
||||
+};
|
||||
+
|
||||
+static const struct of_device_id pci_dw_ecam_of_match[] = {
|
||||
+ { .compatible = "marvell,armada8k-pcie-ecam" },
|
||||
+ { .compatible = "socionext,synquacer-pcie-ecam" },
|
||||
+ { .compatible = "snps,dw-pcie-ecam" },
|
||||
+ { },
|
||||
+};
|
||||
+
|
||||
+static int pci_dw_ecam_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ return pci_host_common_probe(pdev, &pci_dw_ecam_bus_ops);
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver pci_dw_ecam_driver = {
|
||||
+ .driver.name = "pcie-designware-ecam",
|
||||
+ .driver.of_match_table = pci_dw_ecam_of_match,
|
||||
+ .driver.suppress_bind_attrs = true,
|
||||
+ .probe = pci_dw_ecam_probe,
|
||||
+};
|
||||
+builtin_platform_driver(pci_dw_ecam_driver);
|
||||
--
|
||||
cgit v1.1
|
||||
|
||||
From e3dff048a10f16aa0fd32438442ce39558bbdbef Mon Sep 17 00:00:00 2001
|
||||
From: Jassi Brar <jaswinder.singh@linaro.org>
|
||||
Date: Tue, 29 Aug 2017 22:45:59 +0530
|
||||
|
@ -1 +0,0 @@
|
||||
CONFIG_ACT200L_DONGLE=m
|
@ -1 +0,0 @@
|
||||
CONFIG_ACTISYS_DONGLE=m
|
@ -1 +0,0 @@
|
||||
CONFIG_ALI_FIR=m
|
@ -0,0 +1 @@
|
||||
# CONFIG_BOOTPARAM_LOCKDEP_CROSSRELEASE_FULLSTACK is not set
|
1
baseconfig/CONFIG_BPF_JIT_ALWAYS_ON
Normal file
1
baseconfig/CONFIG_BPF_JIT_ALWAYS_ON
Normal file
@ -0,0 +1 @@
|
||||
CONFIG_BPF_JIT_ALWAYS_ON=y
|
1
baseconfig/CONFIG_BTRFS_FS_REF_VERIFY
Normal file
1
baseconfig/CONFIG_BTRFS_FS_REF_VERIFY
Normal file
@ -0,0 +1 @@
|
||||
# CONFIG_BTRFS_FS_REF_VERIFY is not set
|
1
baseconfig/CONFIG_BT_HCIBTUSB_AUTOSUSPEND
Normal file
1
baseconfig/CONFIG_BT_HCIBTUSB_AUTOSUSPEND
Normal file
@ -0,0 +1 @@
|
||||
CONFIG_BT_HCIBTUSB_AUTOSUSPEND=y
|
1
baseconfig/CONFIG_CHASH_SELFTEST
Normal file
1
baseconfig/CONFIG_CHASH_SELFTEST
Normal file
@ -0,0 +1 @@
|
||||
# CONFIG_CHASH_SELFTEST is not set
|
1
baseconfig/CONFIG_CHASH_STATS
Normal file
1
baseconfig/CONFIG_CHASH_STATS
Normal file
@ -0,0 +1 @@
|
||||
# CONFIG_CHASH_STATS is not set
|
1
baseconfig/CONFIG_CHT_DC_TI_PMIC_OPREGION
Normal file
1
baseconfig/CONFIG_CHT_DC_TI_PMIC_OPREGION
Normal file
@ -0,0 +1 @@
|
||||
CONFIG_CHT_DC_TI_PMIC_OPREGION=y
|
1
baseconfig/CONFIG_CPU_ISOLATION
Normal file
1
baseconfig/CONFIG_CPU_ISOLATION
Normal file
@ -0,0 +1 @@
|
||||
# CONFIG_CPU_ISOLATION is not set
|
1
baseconfig/CONFIG_CRAMFS_MTD
Normal file
1
baseconfig/CONFIG_CRAMFS_MTD
Normal file
@ -0,0 +1 @@
|
||||
# CONFIG_CRAMFS_MTD is not set
|
1
baseconfig/CONFIG_CRYPTO_SM3
Normal file
1
baseconfig/CONFIG_CRYPTO_SM3
Normal file
@ -0,0 +1 @@
|
||||
CONFIG_CRYPTO_SM3=m
|
1
baseconfig/CONFIG_DEBUG_KERNEL_DC
Normal file
1
baseconfig/CONFIG_DEBUG_KERNEL_DC
Normal file
@ -0,0 +1 @@
|
||||
# CONFIG_DEBUG_KERNEL_DC is not set
|
@ -1 +0,0 @@
|
||||
# CONFIG_DEBUG_VM_RB is not set # revisit this if performance isn't horrible
|
@ -1 +0,0 @@
|
||||
CONFIG_DONGLE=y
|
1
baseconfig/CONFIG_DP83822_PHY
Normal file
1
baseconfig/CONFIG_DP83822_PHY
Normal file
@ -0,0 +1 @@
|
||||
CONFIG_DP83822_PHY=m
|
1
baseconfig/CONFIG_DRM_AMD_DC
Normal file
1
baseconfig/CONFIG_DRM_AMD_DC
Normal file
@ -0,0 +1 @@
|
||||
CONFIG_DRM_AMD_DC=y
|
1
baseconfig/CONFIG_DRM_AMD_DC_FBC
Normal file
1
baseconfig/CONFIG_DRM_AMD_DC_FBC
Normal file
@ -0,0 +1 @@
|
||||
# CONFIG_DRM_AMD_DC_FBC is not set
|
1
baseconfig/CONFIG_DRM_AMD_DC_PRE_VEGA
Normal file
1
baseconfig/CONFIG_DRM_AMD_DC_PRE_VEGA
Normal file
@ -0,0 +1 @@
|
||||
# CONFIG_DRM_AMD_DC_PRE_VEGA is not set
|
@ -1 +1 @@
|
||||
CONFIG_DRM_I2C_ADV7511=m
|
||||
# CONFIG_DRM_I2C_ADV7511 is not set
|
||||
|
1
baseconfig/CONFIG_DRM_I2C_ADV7511_CEC
Normal file
1
baseconfig/CONFIG_DRM_I2C_ADV7511_CEC
Normal file
@ -0,0 +1 @@
|
||||
# CONFIG_DRM_I2C_ADV7511_CEC is not set
|
1
baseconfig/CONFIG_DRM_PANEL_ORISETECH_OTM8009A
Normal file
1
baseconfig/CONFIG_DRM_PANEL_ORISETECH_OTM8009A
Normal file
@ -0,0 +1 @@
|
||||
CONFIG_DRM_PANEL_ORISETECH_OTM8009A=m
|
1
baseconfig/CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN
Normal file
1
baseconfig/CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN
Normal file
@ -0,0 +1 @@
|
||||
CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=m
|
1
baseconfig/CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03
Normal file
1
baseconfig/CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03
Normal file
@ -0,0 +1 @@
|
||||
CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03=m
|
1
baseconfig/CONFIG_DRM_PANEL_SEIKO_43WVF1G
Normal file
1
baseconfig/CONFIG_DRM_PANEL_SEIKO_43WVF1G
Normal file
@ -0,0 +1 @@
|
||||
CONFIG_DRM_PANEL_SEIKO_43WVF1G=m
|
1
baseconfig/CONFIG_DRM_SII9234
Normal file
1
baseconfig/CONFIG_DRM_SII9234
Normal file
@ -0,0 +1 @@
|
||||
CONFIG_DRM_SII9234=m
|
@ -1 +1 @@
|
||||
CONFIG_DRM_SIL_SII8620=m
|
||||
# CONFIG_DRM_SIL_SII8620 is not set
|
||||
|
1
baseconfig/CONFIG_DS4424
Normal file
1
baseconfig/CONFIG_DS4424
Normal file
@ -0,0 +1 @@
|
||||
# CONFIG_DS4424 is not set
|
@ -1 +0,0 @@
|
||||
CONFIG_ESI_DONGLE=m
|
@ -1 +0,0 @@
|
||||
CONFIG_GIRBIL_DONGLE=m
|
1
baseconfig/CONFIG_GPIO_MAX3191X
Normal file
1
baseconfig/CONFIG_GPIO_MAX3191X
Normal file
@ -0,0 +1 @@
|
||||
# CONFIG_GPIO_MAX3191X is not set
|
1
baseconfig/CONFIG_GPIO_MB86S7X
Normal file
1
baseconfig/CONFIG_GPIO_MB86S7X
Normal file
@ -0,0 +1 @@
|
||||
# CONFIG_GPIO_MB86S7X is not set
|
1
baseconfig/CONFIG_GPIO_TEGRA186
Normal file
1
baseconfig/CONFIG_GPIO_TEGRA186
Normal file
@ -0,0 +1 @@
|
||||
# CONFIG_GPIO_TEGRA186 is not set
|
1
baseconfig/CONFIG_GUP_BENCHMARK
Normal file
1
baseconfig/CONFIG_GUP_BENCHMARK
Normal file
@ -0,0 +1 @@
|
||||
# CONFIG_GUP_BENCHMARK is not set
|
@ -1 +1 @@
|
||||
CONFIG_HWSPINLOCK=m
|
||||
CONFIG_HWSPINLOCK=y
|
||||
|
1
baseconfig/CONFIG_IIO_CROS_EC_ACCEL_LEGACY
Normal file
1
baseconfig/CONFIG_IIO_CROS_EC_ACCEL_LEGACY
Normal file
@ -0,0 +1 @@
|
||||
CONFIG_IIO_CROS_EC_ACCEL_LEGACY=m
|
1
baseconfig/CONFIG_INTEL_SOC_PMIC_CHTDC_TI
Normal file
1
baseconfig/CONFIG_INTEL_SOC_PMIC_CHTDC_TI
Normal file
@ -0,0 +1 @@
|
||||
CONFIG_INTEL_SOC_PMIC_CHTDC_TI=m
|
@ -1 +1 @@
|
||||
# CONFIG_IP6_NF_TARGET_NPT is not set
|
||||
CONFIG_IP6_NF_TARGET_NPT=m
|
||||
|
1
baseconfig/CONFIG_IPMI_PROC_INTERFACE
Normal file
1
baseconfig/CONFIG_IPMI_PROC_INTERFACE
Normal file
@ -0,0 +1 @@
|
||||
# CONFIG_IPMI_PROC_INTERFACE is not set
|
@ -1 +1 @@
|
||||
CONFIG_IPX=m
|
||||
# CONFIG_IPX is not set
|
||||
|
@ -1 +0,0 @@
|
||||
CONFIG_IRCOMM=m
|
@ -1 +1 @@
|
||||
CONFIG_IRDA=m
|
||||
# CONFIG_IRDA is not set
|
||||
|
@ -1 +0,0 @@
|
||||
CONFIG_IRDA_CACHE_LAST_LSAP=y
|
@ -1 +0,0 @@
|
||||
# CONFIG_IRDA_DEBUG is not set
|
@ -1 +0,0 @@
|
||||
CONFIG_IRDA_FAST_RR=y
|
@ -1 +0,0 @@
|
||||
# CONFIG_IRDA_ULTRA is not set
|
@ -1 +0,0 @@
|
||||
CONFIG_IRLAN=m
|
@ -1 +0,0 @@
|
||||
CONFIG_IRNET=m
|
@ -1 +0,0 @@
|
||||
CONFIG_IRTTY_SIR=m
|
@ -1 +1 @@
|
||||
CONFIG_IR_SIR=m
|
||||
# CONFIG_IR_SIR is not set
|
||||
|
@ -1 +0,0 @@
|
||||
CONFIG_KINGSUN_DONGLE=m
|
@ -1 +0,0 @@
|
||||
CONFIG_KS959_DONGLE=m
|
@ -1 +0,0 @@
|
||||
CONFIG_KSDAZZLE_DONGLE=m
|
1
baseconfig/CONFIG_LEDS_TRIGGER_ACTIVITY
Normal file
1
baseconfig/CONFIG_LEDS_TRIGGER_ACTIVITY
Normal file
@ -0,0 +1 @@
|
||||
CONFIG_LEDS_TRIGGER_ACTIVITY=m
|
@ -1 +0,0 @@
|
||||
CONFIG_LIRC_SIR=m
|
@ -1 +0,0 @@
|
||||
CONFIG_LITELINK_DONGLE=m
|
@ -1 +0,0 @@
|
||||
CONFIG_MA600_DONGLE=m
|
1
baseconfig/CONFIG_MANAGER_SBS
Normal file
1
baseconfig/CONFIG_MANAGER_SBS
Normal file
@ -0,0 +1 @@
|
||||
# CONFIG_MANAGER_SBS is not set
|
@ -1 +0,0 @@
|
||||
CONFIG_MCP2120_DONGLE=m
|
@ -1 +0,0 @@
|
||||
CONFIG_MCS_FIR=m
|
1
baseconfig/CONFIG_MESON_GX_PM_DOMAINS
Normal file
1
baseconfig/CONFIG_MESON_GX_PM_DOMAINS
Normal file
@ -0,0 +1 @@
|
||||
# CONFIG_MESON_GX_PM_DOMAINS is not set
|
1
baseconfig/CONFIG_MESON_MX_EFUSE
Normal file
1
baseconfig/CONFIG_MESON_MX_EFUSE
Normal file
@ -0,0 +1 @@
|
||||
# CONFIG_MESON_MX_EFUSE is not set
|
1
baseconfig/CONFIG_MESON_MX_SOCINFO
Normal file
1
baseconfig/CONFIG_MESON_MX_SOCINFO
Normal file
@ -0,0 +1 @@
|
||||
# CONFIG_MESON_MX_SOCINFO is not set
|
1
baseconfig/CONFIG_MLX4_CORE_GEN2
Normal file
1
baseconfig/CONFIG_MLX4_CORE_GEN2
Normal file
@ -0,0 +1 @@
|
||||
CONFIG_MLX4_CORE_GEN2=y
|
1
baseconfig/CONFIG_MMC_SDHCI_OMAP
Normal file
1
baseconfig/CONFIG_MMC_SDHCI_OMAP
Normal file
@ -0,0 +1 @@
|
||||
# CONFIG_MMC_SDHCI_OMAP is not set
|
1
baseconfig/CONFIG_MTD_SHARPSL_PARTS
Normal file
1
baseconfig/CONFIG_MTD_SHARPSL_PARTS
Normal file
@ -0,0 +1 @@
|
||||
# CONFIG_MTD_SHARPSL_PARTS is not set
|
@ -1 +1 @@
|
||||
CONFIG_NCP_FS=m
|
||||
# CONFIG_NCP_FS is not set
|
||||
|
1
baseconfig/CONFIG_NET_SCH_CBS
Normal file
1
baseconfig/CONFIG_NET_SCH_CBS
Normal file
@ -0,0 +1 @@
|
||||
CONFIG_NET_SCH_CBS=m
|
1
baseconfig/CONFIG_NOUVEAU_DEBUG_MMU
Normal file
1
baseconfig/CONFIG_NOUVEAU_DEBUG_MMU
Normal file
@ -0,0 +1 @@
|
||||
# CONFIG_NOUVEAU_DEBUG_MMU is not set
|
@ -1 +0,0 @@
|
||||
CONFIG_NSC_FIR=m
|
1
baseconfig/CONFIG_NTB_SWITCHTEC
Normal file
1
baseconfig/CONFIG_NTB_SWITCHTEC
Normal file
@ -0,0 +1 @@
|
||||
CONFIG_NTB_SWITCHTEC=m
|
1
baseconfig/CONFIG_NVME_MULTIPATH
Normal file
1
baseconfig/CONFIG_NVME_MULTIPATH
Normal file
@ -0,0 +1 @@
|
||||
CONFIG_NVME_MULTIPATH=y
|
@ -1 +0,0 @@
|
||||
CONFIG_OLD_BELKIN_DONGLE=m
|
1
baseconfig/CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW
Normal file
1
baseconfig/CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW
Normal file
@ -0,0 +1 @@
|
||||
CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y
|
1
baseconfig/CONFIG_PINCTRL_CEDARFORK
Normal file
1
baseconfig/CONFIG_PINCTRL_CEDARFORK
Normal file
@ -0,0 +1 @@
|
||||
CONFIG_PINCTRL_CEDARFORK=m
|
1
baseconfig/CONFIG_PINCTRL_MESON_GXBB
Normal file
1
baseconfig/CONFIG_PINCTRL_MESON_GXBB
Normal file
@ -0,0 +1 @@
|
||||
# CONFIG_PINCTRL_MESON_GXBB is not set
|
1
baseconfig/CONFIG_PINCTRL_MESON_GXL
Normal file
1
baseconfig/CONFIG_PINCTRL_MESON_GXL
Normal file
@ -0,0 +1 @@
|
||||
# CONFIG_PINCTRL_MESON_GXL is not set
|
1
baseconfig/CONFIG_PREEMPTIRQ_EVENTS
Normal file
1
baseconfig/CONFIG_PREEMPTIRQ_EVENTS
Normal file
@ -0,0 +1 @@
|
||||
# CONFIG_PREEMPTIRQ_EVENTS is not set
|
1
baseconfig/CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT
Normal file
1
baseconfig/CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT
Normal file
@ -0,0 +1 @@
|
||||
# CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT is not set
|
1
baseconfig/CONFIG_RENESAS_PHY
Normal file
1
baseconfig/CONFIG_RENESAS_PHY
Normal file
@ -0,0 +1 @@
|
||||
CONFIG_RENESAS_PHY=m
|
1
baseconfig/CONFIG_RFD77402
Normal file
1
baseconfig/CONFIG_RFD77402
Normal file
@ -0,0 +1 @@
|
||||
# CONFIG_RFD77402 is not set
|
1
baseconfig/CONFIG_RPMSG_VIRTIO
Normal file
1
baseconfig/CONFIG_RPMSG_VIRTIO
Normal file
@ -0,0 +1 @@
|
||||
CONFIG_RPMSG_VIRTIO=m
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user