Linux v4.15.2

This commit is contained in:
Laura Abbott 2018-02-05 11:20:04 -08:00
parent f0b12d669e
commit f8e9b44738
676 changed files with 3230 additions and 4938 deletions

View File

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

View File

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

View 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

View File

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

View 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

View File

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

View File

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

View File

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

View File

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

View 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

View File

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

View File

@ -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 = <&reg_usb_h1_vbus>;
clocks = <&clks IMX6QDL_CLK_CKO>;
- status = "okay";
+ /* currently USB support causes a kernel hang. Disable it for now */
+ status = "disabled";
};
&usdhc3 {

View File

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

View 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,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1 +0,0 @@
# CONFIG_DEBUG_VM_RB is not set # revisit this if performance isn't horrible

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

1
baseconfig/CONFIG_DS4424 Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1 +1 @@
CONFIG_HWSPINLOCK=m
CONFIG_HWSPINLOCK=y

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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