[PATCH] ACPI / property: restore _DSD data subnodes GUID comment

2019-04-01 Thread Shunyong Yang
Patch "5f5e4890d57a" removes the comment of _DSD data subnodes GUID. This
patch restores it.

Fixes: 5f5e4890d57a ("ACPI / property: Allow multiple property
compatible _DSD entries")

Cc: Joey Zheng 
Signed-off-by: Shunyong Yang 
---
 drivers/acpi/property.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c
index 77abe0ec4043..8832d0e13a72 100644
--- a/drivers/acpi/property.c
+++ b/drivers/acpi/property.c
@@ -44,6 +44,7 @@ static int acpi_data_get_property_array(const struct 
acpi_device_data *data,
  0xbf, 0xf0, 0x76, 0x14, 0x38, 0x07, 0xc3, 0x89),
 };
 
+/* ACPI _DSD data subnodes GUID: dbb8e3e6-5886-4ba6-8795-1319f52a966b */
 static const guid_t ads_guid =
GUID_INIT(0xdbb8e3e6, 0x5886, 0x4ba6,
  0x87, 0x95, 0x13, 0x19, 0xf5, 0x2a, 0x96, 0x6b);
-- 
1.8.3.1



[PATCH v2 2/2] dmaengine: qcom_hidma: assign channel cookie correctly

2019-01-06 Thread Shunyong Yang
When dma_cookie_complete() is called in hidma_process_completed(),
dma_cookie_status() will return DMA_COMPLETE in hidma_tx_status(). Then,
hidma_txn_is_success() will be called to use channel cookie
mchan->last_success to do additional DMA status check. Current code
assigns mchan->last_success after dma_cookie_complete(). This causes
a race condition of dma_cookie_status() returns DMA_COMPLETE before
mchan->last_success is assigned correctly. The race will cause
hidma_tx_status() return DMA_ERROR but the transaction is actually a
success. Moreover, in async_tx case, it will cause a timeout panic
in async_tx_quiesce().

 Kernel panic - not syncing: async_tx_quiesce: DMA error waiting for
 transaction
 ...
 Call trace:
 [] dump_backtrace+0x0/0x1f4
 [] show_stack+0x24/0x2c
 [] dump_stack+0x84/0xa8
 [] panic+0x12c/0x29c
 [] async_tx_quiesce+0xa4/0xc8 [async_tx]
 [] async_trigger_callback+0x70/0x1c0 [async_tx]
 [] raid_run_ops+0x86c/0x1540 [raid456]
 [] handle_stripe+0x5e8/0x1c7c [raid456]
 [] handle_active_stripes.isra.45+0x2d4/0x550 [raid456]
 [] raid5d+0x38c/0x5d0 [raid456]
 [] md_thread+0x108/0x168
 [] kthread+0x10c/0x138
 [] ret_from_fork+0x10/0x18

Cc: Joey Zheng 
Reviewed-by: Sinan Kaya 
Signed-off-by: Shunyong Yang 
---
v2:
  fix missing brace according to Vinod's feedback.
  add Reviewed-by: Sinan Kaya .
---
 drivers/dma/qcom/hidma.c | 17 +
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/dma/qcom/hidma.c b/drivers/dma/qcom/hidma.c
index 9d639ed1955a..411f91fde734 100644
--- a/drivers/dma/qcom/hidma.c
+++ b/drivers/dma/qcom/hidma.c
@@ -138,24 +138,25 @@ static void hidma_process_completed(struct hidma_chan 
*mchan)
desc = &mdesc->desc;
last_cookie = desc->cookie;
 
+   llstat = hidma_ll_status(mdma->lldev, mdesc->tre_ch);
+
spin_lock_irqsave(&mchan->lock, irqflags);
+   if (llstat == DMA_COMPLETE) {
+   mchan->last_success = last_cookie;
+   result.result = DMA_TRANS_NOERROR;
+   } else {
+   result.result = DMA_TRANS_ABORTED;
+   }
+
dma_cookie_complete(desc);
spin_unlock_irqrestore(&mchan->lock, irqflags);
 
-   llstat = hidma_ll_status(mdma->lldev, mdesc->tre_ch);
dmaengine_desc_get_callback(desc, &cb);
 
dma_run_dependencies(desc);
 
spin_lock_irqsave(&mchan->lock, irqflags);
list_move(&mdesc->node, &mchan->free);
-
-   if (llstat == DMA_COMPLETE) {
-   mchan->last_success = last_cookie;
-   result.result = DMA_TRANS_NOERROR;
-   } else
-   result.result = DMA_TRANS_ABORTED;
-
spin_unlock_irqrestore(&mchan->lock, irqflags);
 
dmaengine_desc_callback_invoke(&cb, &result);
-- 
1.8.3.1



[PATCH v2 1/2] dmaengine: qcom_hidma: initialize tx flags in hidma_prep_dma_*

2019-01-06 Thread Shunyong Yang
In async_tx_test_ack(), it uses flags in struct dma_async_tx_descriptor
to check the ACK status. As hidma reuses the descriptor in a free list
when hidma_prep_dma_*(memcpy/memset) is called, the flag will keep ACKed
if the descriptor has been used before. This will cause a BUG_ON in
async_tx_quiesce().

  kernel BUG at crypto/async_tx/async_tx.c:282!
  Internal error: Oops - BUG: 0 1 SMP
  ...
  task: 8017dd3ec000 task.stack: 8017dd3e8000
  PC is at async_tx_quiesce+0x54/0x78 [async_tx]
  LR is at async_trigger_callback+0x98/0x110 [async_tx]

This patch initializes flags in dma_async_tx_descriptor by the flags
passed from the caller when hidma_prep_dma_*(memcpy/memset) is called.

Cc: Joey Zheng 
Reviewed-by: Sinan Kaya 
Signed-off-by: Shunyong Yang 
---

v2: add Reviewed-by: Sinan Kaya 

---
 drivers/dma/qcom/hidma.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/dma/qcom/hidma.c b/drivers/dma/qcom/hidma.c
index 43d4b00b8138..9d639ed1955a 100644
--- a/drivers/dma/qcom/hidma.c
+++ b/drivers/dma/qcom/hidma.c
@@ -415,6 +415,7 @@ static int hidma_alloc_chan_resources(struct dma_chan 
*dmach)
if (!mdesc)
return NULL;
 
+   mdesc->desc.flags = flags;
hidma_ll_set_transfer_params(mdma->lldev, mdesc->tre_ch,
 src, dest, len, flags,
 HIDMA_TRE_MEMCPY);
@@ -447,6 +448,7 @@ static int hidma_alloc_chan_resources(struct dma_chan 
*dmach)
if (!mdesc)
return NULL;
 
+   mdesc->desc.flags = flags;
hidma_ll_set_transfer_params(mdma->lldev, mdesc->tre_ch,
 value, dest, len, flags,
 HIDMA_TRE_MEMSET);
-- 
1.8.3.1



[PATCH v2] ACPI / tables: table override from built-in initrd

2018-12-17 Thread Shunyong Yang
In some scenario, we need to build initrd with kernel in a single image.
This can simplify system deployment process by downloading the whole system
once, such as in IC verification.

This patch adds support to override ACPI tables from built-in initrd.

Cc: Joey Zheng 
Signed-off-by: Shunyong Yang 
---
v2: change "upgrade" to "override" as it's more accurate
---
 Documentation/acpi/initrd_table_override.txt |  4 
 drivers/acpi/Kconfig | 10 ++
 drivers/acpi/tables.c| 12 ++--
 include/linux/initrd.h   |  3 +++
 4 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/Documentation/acpi/initrd_table_override.txt 
b/Documentation/acpi/initrd_table_override.txt
index eb651a6aa285..324d5fb90a22 100644
--- a/Documentation/acpi/initrd_table_override.txt
+++ b/Documentation/acpi/initrd_table_override.txt
@@ -14,6 +14,10 @@ upgrade the ACPI execution environment that is defined by 
the ACPI tables
 via upgrading the ACPI tables provided by the BIOS with an instrumented,
 modified, more recent version one, or installing brand new ACPI tables.
 
+When building initrd with kernel in a single image, option
+ACPI_TABLE_OVERRIDE_VIA_BUILTIN_INITRD should also be true for this
+purpose.
+
 For a full list of ACPI tables that can be upgraded/installed, take a look
 at the char *table_sigs[MAX_ACPI_SIGNATURE]; definition in
 drivers/acpi/tables.c.
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 7cea769c37df..3b362a1c7685 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -357,6 +357,16 @@ config ACPI_TABLE_UPGRADE
  initrd, therefore it's safe to say Y.
  See Documentation/acpi/initrd_table_override.txt for details
 
+config ACPI_TABLE_OVERRIDE_VIA_BUILTIN_INITRD
+   bool "Override ACPI tables from built-in initrd"
+   depends on ACPI_TABLE_UPGRADE
+   depends on INITRAMFS_SOURCE!="" && INITRAMFS_COMPRESSION=""
+   def_bool n
+   help
+ This option provides functionality to override arbitrary ACPI tables
+ from built-in uncompressed initrd.
+ See Documentation/acpi/initrd_table_override.txt for details
+
 config ACPI_DEBUG
bool "Debug Statements"
help
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index 61203eebf3a1..f6a2c5ebabcd 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -473,14 +473,22 @@ static u8 __init acpi_table_checksum(u8 *buffer, u32 
length)
 
 void __init acpi_table_upgrade(void)
 {
-   void *data = (void *)initrd_start;
-   size_t size = initrd_end - initrd_start;
+   void *data;
+   size_t size;
int sig, no, table_nr = 0, total_offset = 0;
long offset = 0;
struct acpi_table_header *table;
char cpio_path[32] = "kernel/firmware/acpi/";
struct cpio_data file;
 
+   if (IS_ENABLED(CONFIG_ACPI_TABLE_OVERRIDE_VIA_BUILTIN_INITRD)) {
+   data = __initramfs_start;
+   size = __initramfs_size;
+   } else {
+   data = (void *)initrd_start;
+   size = initrd_end - initrd_start;
+   }
+
if (data == NULL || size == 0)
return;
 
diff --git a/include/linux/initrd.h b/include/linux/initrd.h
index 84b423044088..02d94aae54c7 100644
--- a/include/linux/initrd.h
+++ b/include/linux/initrd.h
@@ -22,3 +22,6 @@
 extern void free_initrd_mem(unsigned long, unsigned long);
 
 extern unsigned int real_root_dev;
+
+extern char __initramfs_start[];
+extern unsigned long __initramfs_size;
-- 
1.8.3.1



[PATCH] ACPI / tables: table upgrade from built-in initrd

2018-12-16 Thread Shunyong Yang
In some scenario, we need to build initrd with kernel in a single image.
This can simplify system deployment process by downloading the whole system
once, such as in IC verification.

This patch adds support to upgrade ACPI tables from built-in initrd.

Cc: Joey Zheng 
Signed-off-by: Shunyong Yang 
---
 drivers/acpi/Kconfig   |  9 +
 drivers/acpi/tables.c  | 12 ++--
 include/linux/initrd.h |  3 +++
 3 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 7cea769c37df..30976496fe77 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -357,6 +357,15 @@ config ACPI_TABLE_UPGRADE
  initrd, therefore it's safe to say Y.
  See Documentation/acpi/initrd_table_override.txt for details
 
+config ACPI_TABLE_UPGRADE_VIA_BUILTIN_INITRD
+   bool "Upgrade ACPI tables from built-in initrd"
+   depends on ACPI_TABLE_UPGRADE
+   depends on INITRAMFS_SOURCE!="" && INITRAMFS_COMPRESSION=""
+   def_bool n
+   help
+ This option provides functionality to upgrade arbitrary ACPI tables
+ from built-in uncompressed initrd.
+
 config ACPI_DEBUG
bool "Debug Statements"
help
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index 61203eebf3a1..88e3a34443da 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -473,14 +473,22 @@ static u8 __init acpi_table_checksum(u8 *buffer, u32 
length)
 
 void __init acpi_table_upgrade(void)
 {
-   void *data = (void *)initrd_start;
-   size_t size = initrd_end - initrd_start;
+   void *data;
+   size_t size;
int sig, no, table_nr = 0, total_offset = 0;
long offset = 0;
struct acpi_table_header *table;
char cpio_path[32] = "kernel/firmware/acpi/";
struct cpio_data file;
 
+   if (IS_ENABLED(CONFIG_ACPI_TABLE_UPGRADE_VIA_BUILTIN_INITRD)) {
+   data = __initramfs_start;
+   size = __initramfs_size;
+   } else {
+   data = (void *)initrd_start;
+   size = initrd_end - initrd_start;
+   }
+
if (data == NULL || size == 0)
return;
 
diff --git a/include/linux/initrd.h b/include/linux/initrd.h
index 84b423044088..02d94aae54c7 100644
--- a/include/linux/initrd.h
+++ b/include/linux/initrd.h
@@ -22,3 +22,6 @@
 extern void free_initrd_mem(unsigned long, unsigned long);
 
 extern unsigned int real_root_dev;
+
+extern char __initramfs_start[];
+extern unsigned long __initramfs_size;
-- 
1.8.3.1



[PATCH 2/2] dmaengine: qcom_hidma: assign channel cookie correctly

2018-12-06 Thread Shunyong Yang
When dma_cookie_complete() is called in hidma_process_completed(),
dma_cookie_status() will return DMA_COMPLETE in hidma_tx_status(). Then,
hidma_txn_is_success() will be called to use channel cookie
mchan->last_success to do additional DMA status check. Current code
assigns mchan->last_success after dma_cookie_complete(). This causes
a race condition of dma_cookie_status() returns DMA_COMPLETE before
mchan->last_success is assigned correctly. The race will cause
hidma_tx_status() return DMA_ERROR but the transaction is actually a
success. Moreover, in async_tx case, it will cause a timeout panic
in async_tx_quiesce().

 Kernel panic - not syncing: async_tx_quiesce: DMA error waiting for
 transaction
 ...
 Call trace:
 [] dump_backtrace+0x0/0x1f4
 [] show_stack+0x24/0x2c
 [] dump_stack+0x84/0xa8
 [] panic+0x12c/0x29c
 [] async_tx_quiesce+0xa4/0xc8 [async_tx]
 [] async_trigger_callback+0x70/0x1c0 [async_tx]
 [] raid_run_ops+0x86c/0x1540 [raid456]
 [] handle_stripe+0x5e8/0x1c7c [raid456]
 [] handle_active_stripes.isra.45+0x2d4/0x550 [raid456]
 [] raid5d+0x38c/0x5d0 [raid456]
 [] md_thread+0x108/0x168
 [] kthread+0x10c/0x138
 [] ret_from_fork+0x10/0x18

Cc: Joey Zheng 
Signed-off-by: Shunyong Yang 
---
 drivers/dma/qcom/hidma.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/dma/qcom/hidma.c b/drivers/dma/qcom/hidma.c
index 9d639ed1955a..aa88bcceda20 100644
--- a/drivers/dma/qcom/hidma.c
+++ b/drivers/dma/qcom/hidma.c
@@ -138,24 +138,24 @@ static void hidma_process_completed(struct hidma_chan 
*mchan)
desc = &mdesc->desc;
last_cookie = desc->cookie;
 
+   llstat = hidma_ll_status(mdma->lldev, mdesc->tre_ch);
+
spin_lock_irqsave(&mchan->lock, irqflags);
+   if (llstat == DMA_COMPLETE) {
+   mchan->last_success = last_cookie;
+   result.result = DMA_TRANS_NOERROR;
+   } else
+   result.result = DMA_TRANS_ABORTED;
+
dma_cookie_complete(desc);
spin_unlock_irqrestore(&mchan->lock, irqflags);
 
-   llstat = hidma_ll_status(mdma->lldev, mdesc->tre_ch);
dmaengine_desc_get_callback(desc, &cb);
 
dma_run_dependencies(desc);
 
spin_lock_irqsave(&mchan->lock, irqflags);
list_move(&mdesc->node, &mchan->free);
-
-   if (llstat == DMA_COMPLETE) {
-   mchan->last_success = last_cookie;
-   result.result = DMA_TRANS_NOERROR;
-   } else
-   result.result = DMA_TRANS_ABORTED;
-
spin_unlock_irqrestore(&mchan->lock, irqflags);
 
dmaengine_desc_callback_invoke(&cb, &result);
-- 
1.8.3.1



[PATCH 1/2] dmaengine: qcom_hidma: initialize tx flags in hidma_prep_dma_*

2018-12-06 Thread Shunyong Yang
In async_tx_test_ack(), it uses flags in struct dma_async_tx_descriptor
to check the ACK status. As hidma reuses the descriptor in a free list
when hidma_prep_dma_*(memcpy/memset) is called, the flag will keep ACKed
if the descriptor has been used before. This will cause a BUG_ON in
async_tx_quiesce().

  kernel BUG at crypto/async_tx/async_tx.c:282!
  Internal error: Oops - BUG: 0 1 SMP
  ...
  task: 8017dd3ec000 task.stack: 8017dd3e8000
  PC is at async_tx_quiesce+0x54/0x78 [async_tx]
  LR is at async_trigger_callback+0x98/0x110 [async_tx]

This patch initializes flags in dma_async_tx_descriptor by the flags
passed from the caller when hidma_prep_dma_*(memcpy/memset) is called.

Cc: Joey Zheng 
Signed-off-by: Shunyong Yang 
---
 drivers/dma/qcom/hidma.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/dma/qcom/hidma.c b/drivers/dma/qcom/hidma.c
index 43d4b00b8138..9d639ed1955a 100644
--- a/drivers/dma/qcom/hidma.c
+++ b/drivers/dma/qcom/hidma.c
@@ -415,6 +415,7 @@ static int hidma_alloc_chan_resources(struct dma_chan 
*dmach)
if (!mdesc)
return NULL;
 
+   mdesc->desc.flags = flags;
hidma_ll_set_transfer_params(mdma->lldev, mdesc->tre_ch,
 src, dest, len, flags,
 HIDMA_TRE_MEMCPY);
@@ -447,6 +448,7 @@ static int hidma_alloc_chan_resources(struct dma_chan 
*dmach)
if (!mdesc)
return NULL;
 
+   mdesc->desc.flags = flags;
hidma_ll_set_transfer_params(mdma->lldev, mdesc->tre_ch,
 value, dest, len, flags,
 HIDMA_TRE_MEMSET);
-- 
1.8.3.1



[PATCH v2 1/2] PCI: Add HXT vendor ID and ACS quirk

2018-11-06 Thread Shunyong Yang
Add the HXT vendor ID to pci_ids.h and use it in quirks. As the
design of HXT SD4800 ACS feature is the same as QCOM QDF2xxx,
pci_quirk_qcom_rp_acs() is reused for SD4800 quirk.

cc: Joey Zheng 
Reviewed-by: Sinan Kaya 
Signed-off-by: Shunyong Yang 

---
v2:
  Add Reviewed-by: Sinan Kaya.

v1:
  Initial version.
---

diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 4700d24e5d55..1e00ef6a88f4 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -4495,6 +4495,8 @@ static int pci_quirk_mf_endpoint_acs(struct pci_dev *dev, 
u16 acs_flags)
/* QCOM QDF2xxx root ports */
{ PCI_VENDOR_ID_QCOM, 0x0400, pci_quirk_qcom_rp_acs },
{ PCI_VENDOR_ID_QCOM, 0x0401, pci_quirk_qcom_rp_acs },
+   /* HXT SD4800 root ports. The ACS design is same as QCOM QDF2xxx */
+   { PCI_VENDOR_ID_HXT, 0x0401, pci_quirk_qcom_rp_acs },
/* Intel PCH root ports */
{ PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_pch_acs },
{ PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_spt_pch_acs },
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 69f0abe1ba1a..e60a6bc38298 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2565,6 +2565,8 @@
 
 #define PCI_VENDOR_ID_HYGON0x1d94
 
+#define PCI_VENDOR_ID_HXT  0x1dbf
+
 #define PCI_VENDOR_ID_TEKRAM   0x1de1
 #define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29
 
-- 
1.8.3.1



[PATCH v2 2/2] PCI: pciehp: Add HXT quirk for Command Completed errata

2018-11-06 Thread Shunyong Yang
The HXT SD4800 PCI controller does not set the Command Completed
bit unless writes to the Slot Command register change "Control"
bits.

This patch adds SD4800 to the quirk.

Cc: Joey Zheng 
Signed-off-by: Shunyong Yang 

diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 7dd443aea5a5..91db67963aea 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -920,3 +920,5 @@ static void quirk_cmd_compl(struct pci_dev *pdev)
  PCI_CLASS_BRIDGE_PCI, 8, quirk_cmd_compl);
 DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_QCOM, 0x0401,
  PCI_CLASS_BRIDGE_PCI, 8, quirk_cmd_compl);
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_HXT, 0x0401,
+ PCI_CLASS_BRIDGE_PCI, 8, quirk_cmd_compl);
-- 
1.8.3.1



[PATCH] PCI: Add HXT vendor ID and ACS quirk

2018-11-04 Thread Shunyong Yang
Add the HXT vendor ID to pci_ids.h and use it in quirks. As the
design of HXT SD4800 ACS feature is the same as QCOM QDF2xxx,
pci_quirk_qcom_rp_acs() is reused for SD4800 quirk.

Cc: Joey Zheng 
Signed-off-by: Shunyong Yang 
---
 drivers/pci/quirks.c| 2 ++
 include/linux/pci_ids.h | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 4700d24e5d55..1e00ef6a88f4 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -4495,6 +4495,8 @@ static int pci_quirk_mf_endpoint_acs(struct pci_dev *dev, 
u16 acs_flags)
/* QCOM QDF2xxx root ports */
{ PCI_VENDOR_ID_QCOM, 0x0400, pci_quirk_qcom_rp_acs },
{ PCI_VENDOR_ID_QCOM, 0x0401, pci_quirk_qcom_rp_acs },
+   /* HXT SD4800 root ports. The ACS design is same as QCOM QDF2xxx */
+   { PCI_VENDOR_ID_HXT, 0x0401, pci_quirk_qcom_rp_acs },
/* Intel PCH root ports */
{ PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_pch_acs },
{ PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_spt_pch_acs },
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index f4e278493f5b..e3d7efb1442f 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2559,6 +2559,8 @@
 
 #define PCI_VENDOR_ID_AMAZON   0x1d0f
 
+#define PCI_VENDOR_ID_HXT  0x1dbf
+
 #define PCI_VENDOR_ID_TEKRAM   0x1de1
 #define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29
 
-- 
1.8.3.1



[PATCH v2] PCI: Unify pci and normal dma direction definition

2018-07-17 Thread Shunyong Yang
Current DMA direction definitions in pci-dma-compat.h and dma-direction.h
are mirrored in value. Unifying them to enhance readability and avoid
possible inconsistency.

Cc: Joey Zheng 
Signed-off-by: Shunyong Yang 
---

v2:
  Remove unnecessary comments and  braces according to Christoph's
  comments.

---
 include/linux/dma-direction.h  | 6 ++
 include/linux/pci-dma-compat.h | 8 
 2 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/include/linux/dma-direction.h b/include/linux/dma-direction.h
index 3649a031893a..9c96e30e6a0b 100644
--- a/include/linux/dma-direction.h
+++ b/include/linux/dma-direction.h
@@ -1,14 +1,12 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 #ifndef _LINUX_DMA_DIRECTION_H
 #define _LINUX_DMA_DIRECTION_H
-/*
- * These definitions mirror those in pci.h, so they can be used
- * interchangeably with their PCI_ counterparts.
- */
+
 enum dma_data_direction {
DMA_BIDIRECTIONAL = 0,
DMA_TO_DEVICE = 1,
DMA_FROM_DEVICE = 2,
DMA_NONE = 3,
 };
+
 #endif
diff --git a/include/linux/pci-dma-compat.h b/include/linux/pci-dma-compat.h
index 0dd1a3f7b309..c3f1b44ade29 100644
--- a/include/linux/pci-dma-compat.h
+++ b/include/linux/pci-dma-compat.h
@@ -8,10 +8,10 @@
 #include 
 
 /* This defines the direction arg to the DMA mapping routines. */
-#define PCI_DMA_BIDIRECTIONAL  0
-#define PCI_DMA_TODEVICE   1
-#define PCI_DMA_FROMDEVICE 2
-#define PCI_DMA_NONE   3
+#define PCI_DMA_BIDIRECTIONAL  DMA_BIDIRECTIONAL
+#define PCI_DMA_TODEVICE   DMA_TO_DEVICE
+#define PCI_DMA_FROMDEVICE DMA_FROM_DEVICE
+#define PCI_DMA_NONE   DMA_NONE
 
 static inline void *
 pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
-- 
1.8.3.1



[PATCH] PCI: Unify pci and normal dma direction definition

2018-07-12 Thread Shunyong Yang
Current DMA direction definitions in pci-dma-compat.h and dma-direction.h
are mirrored in value. Unify them to enhance readability and avoid
possible inconsistency.

Cc: Joey Zheng 
Signed-off-by: Shunyong Yang 
---
 include/linux/dma-direction.h  | 2 +-
 include/linux/pci-dma-compat.h | 8 
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/include/linux/dma-direction.h b/include/linux/dma-direction.h
index 3649a031893a..9d52716e9218 100644
--- a/include/linux/dma-direction.h
+++ b/include/linux/dma-direction.h
@@ -2,7 +2,7 @@
 #ifndef _LINUX_DMA_DIRECTION_H
 #define _LINUX_DMA_DIRECTION_H
 /*
- * These definitions mirror those in pci.h, so they can be used
+ * These definitions mirror those in pci-dma-compat.h, so they can be used
  * interchangeably with their PCI_ counterparts.
  */
 enum dma_data_direction {
diff --git a/include/linux/pci-dma-compat.h b/include/linux/pci-dma-compat.h
index 0dd1a3f7b309..c1c8d49b6072 100644
--- a/include/linux/pci-dma-compat.h
+++ b/include/linux/pci-dma-compat.h
@@ -8,10 +8,10 @@
 #include 
 
 /* This defines the direction arg to the DMA mapping routines. */
-#define PCI_DMA_BIDIRECTIONAL  0
-#define PCI_DMA_TODEVICE   1
-#define PCI_DMA_FROMDEVICE 2
-#define PCI_DMA_NONE   3
+#define PCI_DMA_BIDIRECTIONAL  (DMA_BIDIRECTIONAL)
+#define PCI_DMA_TODEVICE   (DMA_TO_DEVICE)
+#define PCI_DMA_FROMDEVICE (DMA_FROM_DEVICE)
+#define PCI_DMA_NONE   (DMA_NONE)
 
 static inline void *
 pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
-- 
1.8.3.1



[RFC PATCH] arm64: topology: Map PPTT node offset to logic physical package id

2018-06-28 Thread Shunyong Yang
As PPTT spec doesn't define the physical package id,
find_acpi_cpu_topology_package() will return offset of the node with
Physical package field set when querying physical package id. So, it
returns 162(0xA2) in following example.

[0A2h 0162   1]Subtable Type : 00 [Processor Hierarchy
Node]
[0A3h 0163   1]   Length : 1C
[0A4h 0164   2] Reserved : 
[0A6h 0166   4]Flags (decoded below) : 0003
Physical package : 1
 ACPI Processor ID valid : 1
[0AAh 0170   4]   Parent : 
[0AEh 0174   4]ACPI Processor ID : 1000
[0B2h 0178   4]  Private Resource Number : 0002
[0B6h 0182   4] Private Resource : 006C
[0BAh 0186   4] Private Resource : 0084

So, when "cat physical_package" in /sys/devices/system/cpu/cpu0/topology/,
it will output 162(0xA2). And if some items are added before the node
above, the output will change to other value.

This patch maps the node offset to a logic package id. It maps the first
node offset to 0, the second to 1, and so on.

Then, it will not output a big value, such as 162 above. And it will
not change when some nodes(Physical package not set) are added.

And as long as the nodes with Physical package field set in PPTT keeps
the real hardware order, the logic id can map to hardware package id to
some extent.

Hope to get feedback from you.

Cc: Joey Zheng 
Signed-off-by: Shunyong Yang 
---
 arch/arm64/kernel/topology.c | 53 +++-
 1 file changed, 52 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
index f845a8617812..c219224b36e8 100644
--- a/arch/arm64/kernel/topology.c
+++ b/arch/arm64/kernel/topology.c
@@ -320,11 +320,59 @@ static void __init reset_cpu_topology(void)
  * Propagate the topology information of the processor_topology_node tree to 
the
  * cpu_topology array.
  */
+
+struct package_id_map {
+   int topology_id;
+   int package_id;
+   struct list_head list;
+};
+
+static int map_package_id(int topology_id, int *max_package_id,
+ struct list_head *head)
+{
+   struct list_head *pos;
+   struct package_id_map *entry;
+
+   list_for_each(pos, head) {
+   entry = container_of(pos, struct package_id_map, list);
+   if (entry->topology_id == topology_id)
+   goto done;
+   }
+
+   /* topology_id not found in the list */
+   entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+   if (!entry)
+   return topology_id;
+
+   entry->topology_id = topology_id;
+   entry->package_id = *max_package_id;
+   list_add(&entry->list, head);
+   *max_package_id = *max_package_id + 1;
+
+done:
+   return entry->package_id;
+}
+
+static void destroy_map(struct list_head *head)
+{
+   struct package_id_map *entry;
+   struct list_head *pos, *q;
+
+   list_for_each_safe(pos, q, head) {
+   entry = container_of(pos, struct package_id_map, list);
+   list_del(pos);
+   kfree(entry);
+   }
+}
+
 static int __init parse_acpi_topology(void)
 {
bool is_threaded;
int cpu, topology_id;
+   struct list_head package_id_list;
+   int max_package_id = 0;
 
+   INIT_LIST_HEAD(&package_id_list);
is_threaded = read_cpuid_mpidr() & MPIDR_MT_BITMASK;
 
for_each_possible_cpu(cpu) {
@@ -343,7 +391,9 @@ static int __init parse_acpi_topology(void)
cpu_topology[cpu].core_id= topology_id;
}
topology_id = find_acpi_cpu_topology_package(cpu);
-   cpu_topology[cpu].package_id = topology_id;
+   cpu_topology[cpu].package_id = map_package_id(topology_id,
+   &max_package_id,
+   &package_id_list);
 
i = acpi_find_last_cache_level(cpu);
 
@@ -358,6 +408,7 @@ static int __init parse_acpi_topology(void)
}
}
 
+   destroy_map(&package_id_list);
return 0;
 }
 
-- 
1.8.3.1



[tip:efi/core] efi/capsule-loader: Don't output reset log when reset flags are not set

2018-05-14 Thread tip-bot for Shunyong Yang
Commit-ID:  83f0a7c7b265a56d757f7e3a80622e5b0b7ebc46
Gitweb: https://git.kernel.org/tip/83f0a7c7b265a56d757f7e3a80622e5b0b7ebc46
Author: Shunyong Yang 
AuthorDate: Fri, 4 May 2018 08:00:02 +0200
Committer:  Ingo Molnar 
CommitDate: Mon, 14 May 2018 08:57:49 +0200

efi/capsule-loader: Don't output reset log when reset flags are not set

When reset flags in capsule header are not set, it means firmware
attempts to immediately process or launch the capsule. Moreover, reset
is not needed in this case. The current code will output log to indicate
reset.

This patch adds a branch to avoid reset log output when the flags are not
set.

[ardb: use braces in multi-line 'if', clarify comment and commit log]
Signed-off-by: Shunyong Yang 
Signed-off-by: Ard Biesheuvel 
Cc: Joey Zheng 
Cc: Linus Torvalds 
Cc: Matt Fleming 
Cc: Peter Zijlstra 
Cc: Thomas Gleixner 
Cc: linux-...@vger.kernel.org
Link: http://lkml.kernel.org/r/20180504060003.19618-17-ard.biesheu...@linaro.org
Signed-off-by: Ingo Molnar 
---
 drivers/firmware/efi/capsule-loader.c | 14 ++
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/firmware/efi/capsule-loader.c 
b/drivers/firmware/efi/capsule-loader.c
index e456f4602df1..96688986da56 100644
--- a/drivers/firmware/efi/capsule-loader.c
+++ b/drivers/firmware/efi/capsule-loader.c
@@ -134,10 +134,16 @@ static ssize_t efi_capsule_submit_update(struct 
capsule_info *cap_info)
 
/* Indicate capsule binary uploading is done */
cap_info->index = NO_FURTHER_WRITE_ACTION;
-   pr_info("Successfully upload capsule file with reboot type '%s'\n",
-   !cap_info->reset_type ? "RESET_COLD" :
-   cap_info->reset_type == 1 ? "RESET_WARM" :
-   "RESET_SHUTDOWN");
+
+   if (cap_info->header.flags & EFI_CAPSULE_PERSIST_ACROSS_RESET) {
+   pr_info("Successfully uploaded capsule file with reboot type 
'%s'\n",
+   !cap_info->reset_type ? "RESET_COLD" :
+   cap_info->reset_type == 1 ? "RESET_WARM" :
+   "RESET_SHUTDOWN");
+   } else {
+   pr_info("Successfully processed capsule file\n");
+   }
+
return 0;
 }
 


[PATCH v2] efi/capsule-loader: Don't output reset log when reset flags are not set

2018-05-02 Thread Shunyong Yang
It means firmware attempts to immediately process or launch the capsule
when reset flags in capsule header are not set. Moreover, reset is not
needed in this case. The current code will output log to indicate reset.

This patch adds a branch to avoid reset log output when the flags are not
set.

Cc: Joey Zheng 
Signed-off-by: Shunyong Yang 
---

Changes in v2:
  *Add EFI_CAPSULE_PERSIST_ACROSS_RESET check according to Ard's
   suggestion.
  
---
 drivers/firmware/efi/capsule-loader.c | 13 +
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/firmware/efi/capsule-loader.c 
b/drivers/firmware/efi/capsule-loader.c
index e456f4602df1..344785ef8539 100644
--- a/drivers/firmware/efi/capsule-loader.c
+++ b/drivers/firmware/efi/capsule-loader.c
@@ -134,10 +134,15 @@ static ssize_t efi_capsule_submit_update(struct 
capsule_info *cap_info)
 
/* Indicate capsule binary uploading is done */
cap_info->index = NO_FURTHER_WRITE_ACTION;
-   pr_info("Successfully upload capsule file with reboot type '%s'\n",
-   !cap_info->reset_type ? "RESET_COLD" :
-   cap_info->reset_type == 1 ? "RESET_WARM" :
-   "RESET_SHUTDOWN");
+
+   if (cap_info->header.flags & EFI_CAPSULE_PERSIST_ACROSS_RESET)
+   pr_info("Successfully upload capsule file with reboot type 
'%s'\n",
+   !cap_info->reset_type ? "RESET_COLD" :
+   cap_info->reset_type == 1 ? "RESET_WARM" :
+   "RESET_SHUTDOWN");
+   else
+   pr_info("Successfully upload, process and launch capsule 
file\n");
+
return 0;
 }
 
-- 
1.8.3.1



[PATCH] efi/capsule-loader: Don't output reset log when header flags is not set

2018-04-24 Thread Shunyong Yang
It means firmware attempts to immediately process or launch the capsule
when flags in capsule header is not set. Moreover, reset is not needed
in this case. Current code will output log to indicate reset.

This patch adds a branch to avoid reset log output when the flags is not
set.

Cc: Joey Zheng 
Signed-off-by: Shunyong Yang 
---
 drivers/firmware/efi/capsule-loader.c | 13 +
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/firmware/efi/capsule-loader.c 
b/drivers/firmware/efi/capsule-loader.c
index e456f4602df1..a63b8e5bde23 100644
--- a/drivers/firmware/efi/capsule-loader.c
+++ b/drivers/firmware/efi/capsule-loader.c
@@ -134,10 +134,15 @@ static ssize_t efi_capsule_submit_update(struct 
capsule_info *cap_info)
 
/* Indicate capsule binary uploading is done */
cap_info->index = NO_FURTHER_WRITE_ACTION;
-   pr_info("Successfully upload capsule file with reboot type '%s'\n",
-   !cap_info->reset_type ? "RESET_COLD" :
-   cap_info->reset_type == 1 ? "RESET_WARM" :
-   "RESET_SHUTDOWN");
+
+   if (cap_info->header.flags)
+   pr_info("Successfully upload capsule file with reboot type 
'%s'\n",
+   !cap_info->reset_type ? "RESET_COLD" :
+   cap_info->reset_type == 1 ? "RESET_WARM" :
+   "RESET_SHUTDOWN");
+   else
+   pr_info("Successfully upload, process and launch capsule 
file\n");
+
return 0;
 }
 
-- 
1.8.3.1



[PATCH v3] cpufreq: cppc_cpufreq: Initialize shared cpu's perf capabilities

2018-04-05 Thread Shunyong Yang
When multiple cpus are related in one cpufreq policy, the first online
cpu will be chosen by default to handle cpufreq operations. Let's take
cpu0 and cpu1 as an example.

When cpu0 is offline, policy->cpu will be shifted to cpu1. Cpu1's perf
capabilities should be initialized. Otherwise, perf capabilities are 0s
and speed change can not take effect.

This patch copies perf capabilities of the first online cpu to other
shared cpus when policy shared type is CPUFREQ_SHARED_TYPE_ANY.

Cc: Joey Zheng 
Acked-by: Viresh Kumar 
Signed-off-by: Shunyong Yang 
---

Changes in v3:
  -Remove unnecessary wrap per Kumar's comments.

Changes in v2:
  -Add unlikely in cpu comparison per Kumar's comments.
  -Fix coding style per Kumar's comments.

Changes in v1:
  -Drop RFC tag,
 The original RFC link,
 https://patchwork.kernel.org/patch/10299055/.

 This patch solves same issue as RFC above.

 Patch name is changed as code is too much different with RFC above.

  -Remove extra init() per Viresh Kumar's comments and only handle
   CPPC CPUFREQ_SHARED_TYPE_ANY case.

---
 drivers/cpufreq/cppc_cpufreq.c | 14 --
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c
index 8300a9fcb80c..8b432d6e846d 100644
--- a/drivers/cpufreq/cppc_cpufreq.c
+++ b/drivers/cpufreq/cppc_cpufreq.c
@@ -167,9 +167,19 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy 
*policy)
NSEC_PER_USEC;
policy->shared_type = cpu->shared_type;
 
-   if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY)
+   if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) {
+   int i;
+
cpumask_copy(policy->cpus, cpu->shared_cpu_map);
-   else if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL) {
+
+   for_each_cpu(i, policy->cpus) {
+   if (unlikely(i == policy->cpu))
+   continue;
+
+   memcpy(&all_cpu_data[i]->perf_caps, &cpu->perf_caps,
+  sizeof(cpu->perf_caps));
+   }
+   } else if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL) {
/* Support only SW_ANY for now. */
pr_debug("Unsupported CPU co-ord type\n");
return -EFAULT;
-- 
1.8.3.1



[PATCH v2] cpufreq: cppc_cpufreq: Initialize shared cpu's perf capabilities

2018-04-04 Thread Shunyong Yang
When multiple cpus are related in one cpufreq policy, the first online
cpu will be chosen by default to handle cpufreq operations. Let's take
cpu0 and cpu1 as an example.

When cpu0 is offline, policy->cpu will be shifted to cpu1. Cpu1's perf
capabilities should be initialized. Otherwise, perf capabilities are 0s
and speed change can not take effect.

This patch copies perf capabilities of the first online cpu to other
shared cpus when policy shared type is CPUFREQ_SHARED_TYPE_ANY.

Cc: Joey Zheng 
Signed-off-by: Shunyong Yang 
---

Changes in v2:
  -Add unlikely in cpu comparison per Kumar's comments.
  -Fix coding style per Kumar's comments.

Changes in v1:
  -Drop RFC tag,
 The original RFC link,
 https://patchwork.kernel.org/patch/10299055/.

 This patch solves same issue as RFC above.

 Patch name is changed as code is too much different with RFC above.

  -Remove extra init() per Viresh Kumar's comments and only handle
   CPPC CPUFREQ_SHARED_TYPE_ANY case.

---
 drivers/cpufreq/cppc_cpufreq.c | 15 +--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c
index 8f7b21a4d537..679e43b9c980 100644
--- a/drivers/cpufreq/cppc_cpufreq.c
+++ b/drivers/cpufreq/cppc_cpufreq.c
@@ -164,9 +164,20 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy 
*policy)
policy->cpuinfo.transition_latency = 
cppc_get_transition_latency(cpu_num);
policy->shared_type = cpu->shared_type;
 
-   if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY)
+   if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) {
+   int i;
+
cpumask_copy(policy->cpus, cpu->shared_cpu_map);
-   else if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL) {
+
+   for_each_cpu(i, policy->cpus) {
+   if (unlikely(i == policy->cpu))
+   continue;
+
+   memcpy(&all_cpu_data[i]->perf_caps,
+  &cpu->perf_caps,
+  sizeof(cpu->perf_caps));
+   }
+   } else if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL) {
/* Support only SW_ANY for now. */
pr_debug("Unsupported CPU co-ord type\n");
return -EFAULT;
-- 
1.8.3.1



[PATCH] cpufreq: cppc_cpufreq: Initialize shared cpu's perf capabilities

2018-03-28 Thread Shunyong Yang
When multiple cpus are related in one cpufreq policy, the first online
cpu will be chosen by default to handle cpufreq operations. Let's take
cpu0 and cpu1 as an example.

When cpu0 is offline, policy->cpu will be shifted to cpu1. Cpu1's should
be initialized. Otherwise, perf capabilities are 0s and speed change can
not take effect.

This patch copies perf capabilities of the first online cpu to other
shared cpus when policy shared type is CPUFREQ_SHARED_TYPE_ANY.

Cc: Joey Zheng 
Signed-off-by: Shunyong Yang 
---

The original RFC link,
  https://patchwork.kernel.org/patch/10299055/.

This patch solves same issue as RFC above.

Patch name is changed as code is too much different with RFC above.

Remove extra init() per Viresh Kumar's comments and only handle
CPPC CPUFREQ_SHARED_TYPE_ANY case.

---
 drivers/cpufreq/cppc_cpufreq.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c
index 8f7b21a4d537..dc625a93a58e 100644
--- a/drivers/cpufreq/cppc_cpufreq.c
+++ b/drivers/cpufreq/cppc_cpufreq.c
@@ -164,8 +164,18 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy 
*policy)
policy->cpuinfo.transition_latency = 
cppc_get_transition_latency(cpu_num);
policy->shared_type = cpu->shared_type;
 
-   if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY)
+   if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) {
+   int i;
+
cpumask_copy(policy->cpus, cpu->shared_cpu_map);
+
+   for_each_cpu(i, policy->cpus) {
+   if (i != policy->cpu)
+   memcpy(&all_cpu_data[i]->perf_caps,
+  &cpu->perf_caps,
+  sizeof(cpu->perf_caps));
+   }
+   }
else if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL) {
/* Support only SW_ANY for now. */
pr_debug("Unsupported CPU co-ord type\n");
-- 
1.8.3.1



[RFC PATCH] cpufreq: Calling init() of cpufreq_driver when policy inactive cpu online

2018-03-21 Thread Shunyong Yang
When multiple cpus are related in one cpufreq policy, the first online cpu
will be chosen by default to handle cpufreq operations. In a CPPC case,
let's take two related cpus, cpu0 and cpu1 as an example.

After system start, cpu0 is the first online cpu. Cpufreq policy will be
allocated and init() in cpufreq_driver will be called to initialize cpu0's
perf capabilities and policy parameters. When cpu1 is online, current code
will not call init() in cpufreq_driver as policy has been allocated and
activated by cpu0. So, cpu1's perf capabilities are not initialized
(all 0s).

When cpu0 is offline, policy->cpu will be shifted to cpu1. As cpu1's perf
capabilities are 0s, speed change will not take effect when setting
speed.

This patch adds calling init() of cpufreq_driver when policy inactive cpu
comes to online. Moreover, perf capabilities of all online cpus are
initialized when init() is called.

This patch is tested on CPPC enabled system. I am not sure it's influnce
on other cpufreq_driver. So, this RFC is sent for comments.

Cc: Wang Dongsheng 
Cc: Joey Zheng 
Signed-off-by: Shunyong Yang 
---
 drivers/cpufreq/cppc_cpufreq.c | 45 ++
 drivers/cpufreq/cpufreq.c  | 18 -
 2 files changed, 49 insertions(+), 14 deletions(-)

diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c
index a1c3025f9df7..f23a2007dd66 100644
--- a/drivers/cpufreq/cppc_cpufreq.c
+++ b/drivers/cpufreq/cppc_cpufreq.c
@@ -125,23 +125,12 @@ static void cppc_cpufreq_stop_cpu(struct cpufreq_policy 
*policy)
cpu->perf_caps.lowest_perf, cpu_num, ret);
 }
 
-static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
+static int cppc_cpufreq_update_policy(struct cpufreq_policy *policy,
+ struct cppc_cpudata *cpu)
 {
-   struct cppc_cpudata *cpu;
unsigned int cpu_num = policy->cpu;
int ret = 0;
 
-   cpu = all_cpu_data[policy->cpu];
-
-   cpu->cpu = cpu_num;
-   ret = cppc_get_perf_caps(policy->cpu, &cpu->perf_caps);
-
-   if (ret) {
-   pr_debug("Err reading CPU%d perf capabilities. ret:%d\n",
-   cpu_num, ret);
-   return ret;
-   }
-
cppc_dmi_max_khz = cppc_get_dmi_max_khz();
 
/*
@@ -186,6 +175,36 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy 
*policy)
return ret;
 }
 
+static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
+{
+   struct cppc_cpudata *cpu;
+   unsigned int cpu_num;
+   int ret = 0;
+
+   for_each_cpu(cpu_num, policy->cpus) {
+   cpu = all_cpu_data[cpu_num];
+
+   cpu->cpu = cpu_num;
+   ret = cppc_get_perf_caps(cpu_num, &cpu->perf_caps);
+   if (ret) {
+   pr_debug("Err reading CPU%d perf capabilities. 
ret:%d\n",
+   cpu_num, ret);
+   return ret;
+   }
+
+   if (policy->cpu == cpu_num) {
+   ret = cppc_cpufreq_update_policy(policy, cpu);
+   if (ret) {
+   pr_debug("Err update CPU%d perf capabilities. 
ret:%d\n",
+   cpu_num, ret);
+   return ret;
+   }
+   }
+   }
+
+   return ret;
+}
+
 static struct cpufreq_driver cppc_cpufreq_driver = {
.flags = CPUFREQ_CONST_LOOPS,
.verify = cppc_verify_policy,
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 239063fb6afc..3317c5e55e7f 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1192,8 +1192,24 @@ static int cpufreq_online(unsigned int cpu)
policy = per_cpu(cpufreq_cpu_data, cpu);
if (policy) {
WARN_ON(!cpumask_test_cpu(cpu, policy->related_cpus));
-   if (!policy_is_inactive(policy))
+   if (!policy_is_inactive(policy)) {
+   /*
+* Parameters of policy inactive CPU should be
+* initialized here to make cpufreq work correctly
+* when policy active CPU is switched to offline.
+* When initialization failed, goto out_destroy_policy
+* to destroy.
+*/
+   if (cpu != policy->cpu) {
+   ret = cpufreq_driver->init(policy);
+   if (ret) {
+   pr_debug("inactive cpu initialization 
failed\n");
+   goto out_destroy_policy;
+   }
+   }
+
return cpufreq_add_poli

[PATCH] vfio-mdev/samples: change RDI interrupt condition

2018-03-07 Thread Shunyong Yang
When FIFO mode is enabled, the receive data available interrupt
(UART_IIR_RDI in code) should be triggered when the number of data
in FIFO is equal or larger than interrupt trigger level.

This patch changes the trigger level check to ensure multiple bytes
received from upper layer can trigger RDI interrupt correctly.

Cc: Joey Zheng 
Signed-off-by: Shunyong Yang 
---
 samples/vfio-mdev/mtty.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/samples/vfio-mdev/mtty.c b/samples/vfio-mdev/mtty.c
index 09f255bdf3ac..7abb79d8313d 100644
--- a/samples/vfio-mdev/mtty.c
+++ b/samples/vfio-mdev/mtty.c
@@ -534,7 +534,7 @@ static void handle_bar_read(unsigned int index, struct 
mdev_state *mdev_state,
 
/* Interrupt priority 2: Fifo trigger level reached */
if ((ier & UART_IER_RDI) &&
-   (mdev_state->s[index].rxtx.count ==
+   (mdev_state->s[index].rxtx.count >=
  mdev_state->s[index].intr_trigger_level))
*buf |= UART_IIR_RDI;
 
-- 
1.8.3.1



[RFC PATCH] KVM: arm/arm64: vgic: change condition for level interrupt resampling

2018-03-07 Thread Shunyong Yang
When resampling irqfds is enabled, level interrupt should be
de-asserted when resampling happens. On page 4-47 of GIC v3
specification IHI0069D, it said,
"When the PE acknowledges an SGI, a PPI, or an SPI at the CPU
interface, the IRI changes the status of the interrupt to active
and pending if:
• It is an edge-triggered interrupt, and another edge has been
detected since the interrupt was acknowledged.
• It is a level-sensitive interrupt, and the level has not been
deasserted since the interrupt was acknowledged."

GIC v2 specification IHI0048B.b has similar description on page
3-42 for state machine transition.

When some VFIO device, like mtty(8250 VFIO mdev emulation driver
in samples/vfio-mdev) triggers a level interrupt, the status
transition in LR is pending-->active-->active and pending.
Then it will wait resampling to de-assert the interrupt.

Current design of lr_signals_eoi_mi() will return false if state
in LR is not invalid(Inactive). It causes resampling will not happen
in mtty case.

This will cause interrupt fired continuously to guest even 8250 IIR
has no interrupt. When 8250's interrupt is configured in shared mode,
it will pass interrupt to other drivers to handle. However, there
is no other driver involved. Then, a "nobody cared" kernel complaint
occurs.

/ # cat /dev/ttyS0
[4.826836] random: crng init done
[6.373620] irq 41: nobody cared (try booting with the "irqpoll"
option)
[6.376414] CPU: 0 PID: 1307 Comm: cat Not tainted 4.16.0-rc4 #4
[6.378927] Hardware name: linux,dummy-virt (DT)
[6.380876] Call trace:
[6.381937]  dump_backtrace+0x0/0x180
[6.383495]  show_stack+0x14/0x1c
[6.384902]  dump_stack+0x90/0xb4
[6.386312]  __report_bad_irq+0x38/0xe0
[6.387944]  note_interrupt+0x1f4/0x2b8
[6.389568]  handle_irq_event_percpu+0x54/0x7c
[6.391433]  handle_irq_event+0x44/0x74
[6.393056]  handle_fasteoi_irq+0x9c/0x154
[6.394784]  generic_handle_irq+0x24/0x38
[6.396483]  __handle_domain_irq+0x60/0xb4
[6.398207]  gic_handle_irq+0x98/0x1b0
[6.399796]  el1_irq+0xb0/0x128
[6.401138]  _raw_spin_unlock_irqrestore+0x18/0x40
[6.403149]  __setup_irq+0x41c/0x678
[6.404669]  request_threaded_irq+0xe0/0x190
[6.406474]  univ8250_setup_irq+0x208/0x234
[6.408250]  serial8250_do_startup+0x1b4/0x754
[6.410123]  serial8250_startup+0x20/0x28
[6.411826]  uart_startup.part.21+0x78/0x144
[6.413633]  uart_port_activate+0x50/0x68
[6.415328]  tty_port_open+0x84/0xd4
[6.416851]  uart_open+0x34/0x44
[6.418229]  tty_open+0xec/0x3c8
[6.419610]  chrdev_open+0xb0/0x198
[6.421093]  do_dentry_open+0x200/0x310
[6.422714]  vfs_open+0x54/0x84
[6.424054]  path_openat+0x2dc/0xf04
[6.425569]  do_filp_open+0x68/0xd8
[6.427044]  do_sys_open+0x16c/0x224
[6.428563]  SyS_openat+0x10/0x18
[6.429972]  el0_svc_naked+0x30/0x34
[6.431494] handlers:
[6.432479] [<0e9fb4bb>] serial8250_interrupt
[6.434597] Disabling IRQ #41

This patch changes the lr state condition in lr_signals_eoi_mi() from
invalid(Inactive) to active and pending to avoid this.

I am not sure about the original design of the condition of
invalid(active). So, This RFC is sent out for comments.

Cc: Joey Zheng 
Signed-off-by: Shunyong Yang 
---
 virt/kvm/arm/vgic/vgic-v2.c | 4 ++--
 virt/kvm/arm/vgic/vgic-v3.c | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/virt/kvm/arm/vgic/vgic-v2.c b/virt/kvm/arm/vgic/vgic-v2.c
index e9d840a75e7b..740ee9a5f551 100644
--- a/virt/kvm/arm/vgic/vgic-v2.c
+++ b/virt/kvm/arm/vgic/vgic-v2.c
@@ -46,8 +46,8 @@ void vgic_v2_set_underflow(struct kvm_vcpu *vcpu)
 
 static bool lr_signals_eoi_mi(u32 lr_val)
 {
-   return !(lr_val & GICH_LR_STATE) && (lr_val & GICH_LR_EOI) &&
-  !(lr_val & GICH_LR_HW);
+   return !((lr_val & GICH_LR_STATE) ^ GICH_LR_STATE) &&
+  (lr_val & GICH_LR_EOI) && !(lr_val & GICH_LR_HW);
 }
 
 /*
diff --git a/virt/kvm/arm/vgic/vgic-v3.c b/virt/kvm/arm/vgic/vgic-v3.c
index 6b329414e57a..43111bba7af9 100644
--- a/virt/kvm/arm/vgic/vgic-v3.c
+++ b/virt/kvm/arm/vgic/vgic-v3.c
@@ -35,8 +35,8 @@ void vgic_v3_set_underflow(struct kvm_vcpu *vcpu)
 
 static bool lr_signals_eoi_mi(u64 lr_val)
 {
-   return !(lr_val & ICH_LR_STATE) && (lr_val & ICH_LR_EOI) &&
-  !(lr_val & ICH_LR_HW);
+   return !((lr_val & ICH_LR_STATE) ^ ICH_LR_STATE) &&
+  (lr_val & ICH_LR_EOI) && !(lr_val & ICH_LR_HW);
 }
 
 void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu)
-- 
1.8.3.1



[PATCH] vsprintf: replace space with readable '=' before crng is ready

2018-02-12 Thread Shunyong Yang
Before crng is ready, output of "%p" composes of "(ptrval)" and
left padding spaces for alignment as no random address can be
generated. This seems a little strange when default string width
is larger than strlen("(ptrval)").

For example, when irq domain names are built with "%p", the nodes
under /sys/kernel/debug/irq/domains like this on AArch64 system,

[root@y irq]# ls domains/
default   irqchip@(ptrval)-2
irqchip@(ptrval)-4  \_SB_.TCS0.QIC1  \_SB_.TCS0.QIC3
irqchip@(ptrval)  irqchip@(ptrval)-3
\_SB_.TCS0.QIC0 \_SB_.TCS0.QIC2

The name "irqchip@(ptrval)-2" is not so readable in console
output.

This patch replaces space with readable "=" when output needs padding.
Following is the output after applying the patch,

[root@y domains]# ls
default   irqchip@(ptrval)-2
irqchip@(ptrval)-4  \_SB_.TCS0.QIC1  \_SB_.TCS0.QIC3
irqchip@(ptrval)  irqchip@(ptrval)-3  \_SB_.TCS0.QIC0
\_SB_.TCS0.QIC2

There is same problem in some subsystem's dmesg output. Moreover,
someone may call "%p" in a similar case. In addition, the timing of
crng initialization done may vary on different system. So, the change
is made in vsprintf.c.

Link: https://patchwork.kernel.org/patch/10185199/

Cc: Andy Shevchenko 
Cc: Joey Zheng 
Suggested-by: Rasmus Villemoes 
Signed-off-by: Shunyong Yang 
---
 lib/vsprintf.c | 18 +-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 77ee6ced11b1..9fdc8376752a 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -1700,9 +1700,25 @@ static char *ptr_to_id(char *buf, char *end, void *ptr, 
struct printf_spec spec)
const int default_width = 2 * sizeof(ptr);
 
if (unlikely(!have_filled_random_ptr_key)) {
+   char *ptrval_str = "(ptrval)";
+   char str[default_width + 1];
+   int len = strlen(ptrval_str);
+
+   if (default_width > len) {
+   int pos;
+
+   pos = (default_width - len) / 2;
+   memset(str, '=', default_width);
+   memcpy(str + pos + 1, ptrval_str + 1, len - 2);
+   str[0] = '(';
+   str[default_width - 1] = ')';
+   str[default_width] = 0;
+   ptrval_str = str;
+   }
+
spec.field_width = default_width;
/* string length must be less than default_width */
-   return string(buf, end, "(ptrval)", spec);
+   return string(buf, end, ptrval_str, spec);
}
 
 #ifdef CONFIG_64BIT
-- 
1.8.3.1