* [RFCv3][PATCH 3/5] arm64: Implement ARCH_HAS_FORCE_CACHE
From: Laura Abbott @ 2016-09-12 21:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1473715978-11633-1-git-send-email-labbott@redhat.com>
arm64 may need to guarantee the caches are synced. Implement versions of
the kernel_force_cache API to allow this.
Signed-off-by: Laura Abbott <labbott@redhat.com>
---
v3: Switch to calling cache operations directly instead of relying on
DMA mapping.
---
arch/arm64/include/asm/cacheflush.h | 8 ++++++++
arch/arm64/mm/cache.S | 24 ++++++++++++++++++++----
arch/arm64/mm/flush.c | 11 +++++++++++
3 files changed, 39 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/include/asm/cacheflush.h b/arch/arm64/include/asm/cacheflush.h
index c64268d..1134c15 100644
--- a/arch/arm64/include/asm/cacheflush.h
+++ b/arch/arm64/include/asm/cacheflush.h
@@ -87,6 +87,9 @@ extern void __dma_map_area(const void *, size_t, int);
extern void __dma_unmap_area(const void *, size_t, int);
extern void __dma_flush_range(const void *, const void *);
+extern void __force_dcache_clean(const void *, size_t);
+extern void __force_dcache_invalidate(const void *, size_t);
+
/*
* Copy user data from/to a page which is mapped into a different
* processes address space. Really, we want to allow our "user
@@ -149,4 +152,9 @@ int set_memory_rw(unsigned long addr, int numpages);
int set_memory_x(unsigned long addr, int numpages);
int set_memory_nx(unsigned long addr, int numpages);
+#define ARCH_HAS_FORCE_CACHE 1
+
+void kernel_force_cache_clean(struct page *page, size_t size);
+void kernel_force_cache_invalidate(struct page *page, size_t size);
+
#endif
diff --git a/arch/arm64/mm/cache.S b/arch/arm64/mm/cache.S
index 07d7352..e99c9a4 100644
--- a/arch/arm64/mm/cache.S
+++ b/arch/arm64/mm/cache.S
@@ -184,10 +184,6 @@ ENDPIPROC(__dma_flush_range)
* - dir - DMA direction
*/
ENTRY(__dma_map_area)
- add x1, x1, x0
- cmp w2, #DMA_FROM_DEVICE
- b.eq __dma_inv_range
- b __dma_clean_range
ENDPIPROC(__dma_map_area)
/*
@@ -202,3 +198,23 @@ ENTRY(__dma_unmap_area)
b.ne __dma_inv_range
ret
ENDPIPROC(__dma_unmap_area)
+
+/*
+ * __force_dcache_clean(start, size)
+ * - start - kernel virtual start address
+ * - size - size of region
+ */
+ENTRY(__force_dcache_clean)
+ add x1, x1, x0
+ b __dma_clean_range
+ENDPROC(__force_dcache_clean)
+
+/*
+ * __force_dcache_invalidate(start, size)
+ * - start - kernel virtual start address
+ * - size - size of region
+ */
+ENTRY(__force_dcache_invalidate)
+ add x1, x1, x0
+ b __dma_inv_range
+ENDPROC(__force_dcache_invalidate)
diff --git a/arch/arm64/mm/flush.c b/arch/arm64/mm/flush.c
index 43a76b0..54ff32e 100644
--- a/arch/arm64/mm/flush.c
+++ b/arch/arm64/mm/flush.c
@@ -20,6 +20,7 @@
#include <linux/export.h>
#include <linux/mm.h>
#include <linux/pagemap.h>
+#include <linux/dma-mapping.h>
#include <asm/cacheflush.h>
#include <asm/cachetype.h>
@@ -94,3 +95,13 @@ EXPORT_SYMBOL(flush_dcache_page);
* Additional functions defined in assembly.
*/
EXPORT_SYMBOL(flush_icache_range);
+
+void kernel_force_cache_clean(struct page *page, size_t size)
+{
+ __force_dcache_clean(page_address(page), size);
+}
+
+void kernel_force_cache_invalidate(struct page *page, size_t size)
+{
+ __force_dcache_invalidate(page_address(page), size);
+}
--
2.7.4
^ permalink raw reply related
* [RFCv3][PATCH 4/5] staging: android: ion: Convert to the kernel_force_cache APIs
From: Laura Abbott @ 2016-09-12 21:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1473715978-11633-1-git-send-email-labbott@redhat.com>
Now that there exists a proper set of cache sync APIs, move away
from the dma_sync and do less bad things.
Signed-off-by: Laura Abbott <labbott@redhat.com>
---
v3: Rebased to latest-next
---
drivers/staging/android/ion/ion.c | 22 ++++------------------
drivers/staging/android/ion/ion_carveout_heap.c | 8 +++++---
drivers/staging/android/ion/ion_chunk_heap.c | 12 +++++++-----
drivers/staging/android/ion/ion_page_pool.c | 7 ++++---
drivers/staging/android/ion/ion_priv.h | 11 -----------
drivers/staging/android/ion/ion_system_heap.c | 6 +++---
6 files changed, 23 insertions(+), 43 deletions(-)
diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c
index 396ded5..c2125de 100644
--- a/drivers/staging/android/ion/ion.c
+++ b/drivers/staging/android/ion/ion.c
@@ -37,6 +37,8 @@
#include <linux/dma-buf.h>
#include <linux/idr.h>
+#include <linux/cacheflush.h>
+
#include "ion.h"
#include "ion_priv.h"
#include "compat_ion.h"
@@ -817,22 +819,6 @@ static void ion_unmap_dma_buf(struct dma_buf_attachment *attachment,
{
}
-void ion_pages_sync_for_device(struct device *dev, struct page *page,
- size_t size, enum dma_data_direction dir)
-{
- struct scatterlist sg;
-
- sg_init_table(&sg, 1);
- sg_set_page(&sg, page, size, 0);
- /*
- * This is not correct - sg_dma_address needs a dma_addr_t that is valid
- * for the targeted device, but this works on the currently targeted
- * hardware.
- */
- sg_dma_address(&sg) = page_to_phys(page);
- dma_sync_sg_for_device(dev, &sg, 1, dir);
-}
-
struct ion_vma_list {
struct list_head list;
struct vm_area_struct *vma;
@@ -857,8 +843,8 @@ static void ion_buffer_sync_for_device(struct ion_buffer *buffer,
struct page *page = buffer->pages[i];
if (ion_buffer_page_is_dirty(page))
- ion_pages_sync_for_device(dev, ion_buffer_page(page),
- PAGE_SIZE, dir);
+ kernel_force_cache_clean(ion_buffer_page(page),
+ PAGE_SIZE);
ion_buffer_page_clean(buffer->pages + i);
}
diff --git a/drivers/staging/android/ion/ion_carveout_heap.c b/drivers/staging/android/ion/ion_carveout_heap.c
index c4f0795..af81edc 100644
--- a/drivers/staging/android/ion/ion_carveout_heap.c
+++ b/drivers/staging/android/ion/ion_carveout_heap.c
@@ -22,6 +22,9 @@
#include <linux/scatterlist.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
+
+#include <linux/cacheflush.h>
+
#include "ion.h"
#include "ion_priv.h"
@@ -105,8 +108,7 @@ static void ion_carveout_heap_free(struct ion_buffer *buffer)
ion_heap_buffer_zero(buffer);
if (ion_buffer_cached(buffer))
- dma_sync_sg_for_device(NULL, table->sgl, table->nents,
- DMA_BIDIRECTIONAL);
+ kernel_force_cache_clean(page, buffer->size);
ion_carveout_free(heap, paddr, buffer->size);
sg_free_table(table);
@@ -132,7 +134,7 @@ struct ion_heap *ion_carveout_heap_create(struct ion_platform_heap *heap_data)
page = pfn_to_page(PFN_DOWN(heap_data->base));
size = heap_data->size;
- ion_pages_sync_for_device(NULL, page, size, DMA_BIDIRECTIONAL);
+ kernel_force_cache_clean(page, size);
ret = ion_heap_pages_zero(page, size, pgprot_writecombine(PAGE_KERNEL));
if (ret)
diff --git a/drivers/staging/android/ion/ion_chunk_heap.c b/drivers/staging/android/ion/ion_chunk_heap.c
index 70495dc..f6d1bae 100644
--- a/drivers/staging/android/ion/ion_chunk_heap.c
+++ b/drivers/staging/android/ion/ion_chunk_heap.c
@@ -21,6 +21,9 @@
#include <linux/scatterlist.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
+
+#include <linux/cacheflush.h>
+
#include "ion.h"
#include "ion_priv.h"
@@ -104,11 +107,10 @@ static void ion_chunk_heap_free(struct ion_buffer *buffer)
ion_heap_buffer_zero(buffer);
- if (ion_buffer_cached(buffer))
- dma_sync_sg_for_device(NULL, table->sgl, table->nents,
- DMA_BIDIRECTIONAL);
-
for_each_sg(table->sgl, sg, table->nents, i) {
+ if (ion_buffer_cached(buffer))
+ kernel_force_cache_clean(sg_page(table->sgl),
+ sg->length);
gen_pool_free(chunk_heap->pool, page_to_phys(sg_page(sg)),
sg->length);
}
@@ -135,7 +137,7 @@ struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *heap_data)
page = pfn_to_page(PFN_DOWN(heap_data->base));
size = heap_data->size;
- ion_pages_sync_for_device(NULL, page, size, DMA_BIDIRECTIONAL);
+ kernel_force_cache_clean(page, size);
ret = ion_heap_pages_zero(page, size, pgprot_writecombine(PAGE_KERNEL));
if (ret)
diff --git a/drivers/staging/android/ion/ion_page_pool.c b/drivers/staging/android/ion/ion_page_pool.c
index aea89c1..f289d88 100644
--- a/drivers/staging/android/ion/ion_page_pool.c
+++ b/drivers/staging/android/ion/ion_page_pool.c
@@ -22,6 +22,9 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/swap.h>
+
+#include <linux/cacheflush.h>
+
#include "ion_priv.h"
static void *ion_page_pool_alloc_pages(struct ion_page_pool *pool)
@@ -30,9 +33,7 @@ static void *ion_page_pool_alloc_pages(struct ion_page_pool *pool)
if (!page)
return NULL;
- if (!pool->cached)
- ion_pages_sync_for_device(NULL, page, PAGE_SIZE << pool->order,
- DMA_BIDIRECTIONAL);
+ kernel_force_cache_clean(page, PAGE_SIZE << pool->order);
return page;
}
diff --git a/drivers/staging/android/ion/ion_priv.h b/drivers/staging/android/ion/ion_priv.h
index 3c3b324..a344190 100644
--- a/drivers/staging/android/ion/ion_priv.h
+++ b/drivers/staging/android/ion/ion_priv.h
@@ -441,17 +441,6 @@ void ion_page_pool_free(struct ion_page_pool *, struct page *);
int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask,
int nr_to_scan);
-/**
- * ion_pages_sync_for_device - cache flush pages for use with the specified
- * device
- * @dev: the device the pages will be used with
- * @page: the first page to be flushed
- * @size: size in bytes of region to be flushed
- * @dir: direction of dma transfer
- */
-void ion_pages_sync_for_device(struct device *dev, struct page *page,
- size_t size, enum dma_data_direction dir);
-
long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
int ion_sync_for_device(struct ion_client *client, int fd);
diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c
index 7e023d5..8eefe83 100644
--- a/drivers/staging/android/ion/ion_system_heap.c
+++ b/drivers/staging/android/ion/ion_system_heap.c
@@ -23,6 +23,7 @@
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
+#include <linux/cacheflush.h>
#include "ion.h"
#include "ion_priv.h"
@@ -76,8 +77,7 @@ static struct page *alloc_buffer_page(struct ion_system_heap *heap,
page = ion_page_pool_alloc(pool);
if (cached)
- ion_pages_sync_for_device(NULL, page, PAGE_SIZE << order,
- DMA_BIDIRECTIONAL);
+ kernel_force_cache_clean(page, PAGE_SIZE << order);
return page;
}
@@ -408,7 +408,7 @@ static int ion_system_contig_heap_allocate(struct ion_heap *heap,
buffer->sg_table = table;
- ion_pages_sync_for_device(NULL, page, len, DMA_BIDIRECTIONAL);
+ kernel_force_cache_clean(page, len);
return 0;
--
2.7.4
^ permalink raw reply related
* [RFCv3][PATCH 5/5] staging: ion: Add support for syncing with DMA_BUF_IOCTL_SYNC
From: Laura Abbott @ 2016-09-12 21:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1473715978-11633-1-git-send-email-labbott@redhat.com>
dma_buf added support for a userspace syncing ioctl. It is implemented
by calling dma_buf_begin_cpu_access and dma_buf_end_cpu_access. Ion
currently lacks cache operations on this code path. Add them for
compatibility with the dma_buf ioctl.
Signed-off-by: Laura Abbott <labbott@redhat.com>
---
drivers/staging/android/ion/ion.c | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c
index c2125de..1ad8e8a 100644
--- a/drivers/staging/android/ion/ion.c
+++ b/drivers/staging/android/ion/ion.c
@@ -969,6 +969,24 @@ static void ion_dma_buf_kunmap(struct dma_buf *dmabuf, unsigned long offset,
{
}
+static void ion_clean_buffer(struct ion_buffer *buffer)
+{
+ struct scatterlist *sg;
+ int i;
+
+ for_each_sg(buffer->sg_table->sgl, sg, buffer->sg_table->orig_nents, i)
+ kernel_force_cache_clean(sg_page(sg), sg->length);
+}
+
+static void ion_invalidate_buffer(struct ion_buffer *buffer)
+{
+ struct scatterlist *sg;
+ int i;
+
+ for_each_sg(buffer->sg_table->sgl, sg, buffer->sg_table->orig_nents, i)
+ kernel_force_cache_invalidate(sg_page(sg), sg->length);
+}
+
static int ion_dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
enum dma_data_direction direction)
{
@@ -984,6 +1002,11 @@ static int ion_dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
mutex_lock(&buffer->lock);
vaddr = ion_buffer_kmap_get(buffer);
mutex_unlock(&buffer->lock);
+
+ if (direction != DMA_TO_DEVICE) {
+ ion_invalidate_buffer(buffer);
+ }
+
return PTR_ERR_OR_ZERO(vaddr);
}
@@ -996,6 +1019,12 @@ static int ion_dma_buf_end_cpu_access(struct dma_buf *dmabuf,
ion_buffer_kmap_put(buffer);
mutex_unlock(&buffer->lock);
+ if (direction == DMA_FROM_DEVICE) {
+ ion_invalidate_buffer(buffer);
+ } else {
+ ion_clean_buffer(buffer);
+ }
+
return 0;
}
@@ -1126,6 +1155,8 @@ int ion_sync_for_device(struct ion_client *client, int fd)
struct dma_buf *dmabuf;
struct ion_buffer *buffer;
+ WARN_ONCE(1, "This API is deprecated in favor of the dma_buf ioctl\n");
+
dmabuf = dma_buf_get(fd);
if (IS_ERR(dmabuf))
return PTR_ERR(dmabuf);
--
2.7.4
^ permalink raw reply related
* [PATCH v2 00/17] Make rpmsg a framework
From: Karthikeyan Ramasubramanian @ 2016-09-12 21:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160912195854.GJ405@tuxbot>
On 9/12/2016 1:58 PM, Bjorn Andersson wrote:
> On Mon 12 Sep 12:21 PDT 2016, Jeffrey Hugo wrote:
>
>> On 9/12/2016 12:49 PM, Bjorn Andersson wrote:
>>> On Mon 12 Sep 11:13 PDT 2016, Jeffrey Hugo wrote:
>>>
>>>> On 9/12/2016 12:00 PM, Bjorn Andersson wrote:
> [..]
>>>>> Can you point me to the downstream code where this is implemented so I
>>>>> can have a look? Do you expect to get the response on that request?
>>>>
>>>> Have a look at -
>>>> smd_mask_receive_interrupt()
>>>> smd_is_pkt_avail()
>>>>
>>>
>>> In msm-3.18 these still seems to only come from either
>>> msm_rpm_enter_sleep() and the rpm-clock driver, related to flushing
>>> cached sleep state requests.
>>>
>>>> Every request to the RPM generates a response. The Linux RPM driver may
>>>> decide to let the response sit in the fifo, or it may need to read and
>>>> process it.
>>>>
>>>
>>> Right, I presume we save some time by not waiting for these responses as
>>> we want to reach sleep as soon as possible. The answer I got last time
>>> this was discussed was that it was an optimization, not a functional
>>> requirement.
>>
>> Two optimizations in play here.
>>
>> First, disabling interrupts prevents an immediate wakeup. When the system
>> is entering sleep, IRQs are disabled. The sleep request to RPM will trigger
>> a response, and the IRQ for that response will be queued. Once the sleep
>> processing is done, IRQs get enabled, so the pending IRQ from RPM will cause
>> an immediate wakeup. The system will process the wakeup, and then go back
>> to sleep (sans request because nothing has changed). This down-up-down
>> processing burns a lot of power.
>>
>
> But which "sleep request" is this? The only one I can find is the
> flushing of sleep state values from the rpm resource tables.
>
>> Second is not waiting for the response. Linux doesn't really do anything
>> with the sleep request response, so we can enter sleep faster by not waiting
>> for the response and processing (discarding) it when the system wakes up as
>> scheduled.
>
> Right, as long as the RPM code doesn't consider it a timeout don't have
> a problem if those ack's are handled after the resume.
>
>> However, Linux needs to ensure there is enough fifo space to
>> hold that response while asleep, otherwise the RPM will panic and crash the
>> system. Therefore, if there are a number of outstanding requests that would
>> fill the fifo, then the RPM driver on Linux needs to spin and drain requests
>> from the fifo until a minimum free space buffer to hold additional expected
>> pending responses is established. This has to occur with IRQs disabled.
>>
>
> Right. Which means that the RPM driver needs to know how large the rx
> fifo is, what overhead the underlaying transport mechanism has and then
> calculate how many responses it should leave room for.
>
> [..]
>>>> If I recall correctly, there was a parameter in the RPM driver
>>>> for the transmit function that indicated if the request was being made in
>>>> atomic context or not, which would change the behavior of how the transmit
>>>> was handled.
>>>>
>>>
>>> You're correct, the question is still which of these code paths are
>>> actually needed and to motivate the endless maintenance of the extra
>>> code.
>>
>> If we are just talking about transmitting in atomic context (not necessarily
>> related to sleep), if I recall correctly, some bus requests are sent to RPM
>> in atomic context, some APR requests to the Audio DSP are done in atomic
>> context, and I think IPC Router uses atomic context in some cases. As a
>> generic framework that should support usecases to all processors/subsystems,
>> I don't think transmitting in atomic context is a special case for
>> RPM/sleep.
>>
>
> I have not looked through all of APR yet and don't know where msm_bus is
> heading, but for IPC-router your correct that the downstream driver does
> indeed require this; but that's a side effect of the downstream
> ipcrouter implementation, not the problem itself.
>
APR does send messages in atomic context in addition to the RPM Driver,
but IPC Router does not to the extent of my knowledge.
> Regards,
> Bjorn
> --
> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
Regards,
Karthik.
--
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation
^ permalink raw reply
* [PATCH 2/3] ARM64: dts: amlogic: Add basic support for Amlogic S905X
From: Andreas Färber @ 2016-09-12 21:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <7ha8fcq26c.fsf@baylibre.com>
Am 12.09.2016 um 22:43 schrieb Kevin Hilman:
> Carlo Caione <carlo@caione.org> writes:
>> On Mon, Sep 12, 2016 at 6:28 PM, Andreas F?rber <afaerber@suse.de> wrote:
>>
>>>> +Boards with the Amlogic Meson GXL SoC shall have the following properties:
>>>> + Required root node property:
>>>> + compatible: "amlogic,meson-gxl-s905x", "amlogic,meson-gxl";
>>>
>>> Can we please use "amlogic,s905x", "amlogic,meson-gxl"? No need to
>>> complicate the name. Also affects .dtsi and .dts below.
>>
>> gxl != s905x.
Huh? You're seemingly completely missing my point...
But you are right that _Neil's_ heading needs to be fixed, too:
Clearly not all GXL SoCs need to have an S905X compatible string!
So it should be "Boards with the Amlogic S905X SoC shall ..." or so.
>> AFAWK to the GXL family belong several different SoCs, like S905X,
>> S905D, etc... (see patch 3/3)
Thanks, I already know that, that's why you have two compatible strings
instead of just one like for GXBB. We can certainly prepend one for
symmetry there, too, if it makes you happier.
>> This is why we use meson-gxl-s905x, meson-gxl-s905d, etc...
>
> Correct.
>
>> We could s/meson-gxl-s905x/meson-s905x/ and
>> s/meson-gxl-s905d/meson-s905d/ but I honestly prefer this way because
>> we can clearly see which family the SoC belongs to (the Amlogic naming
>> convention is already messy enough).
>> I mean, yes it's longer, but it's for the sake of documentation IMO.
>
> +1
I still don't follow that conclusion. The board is called "amlogic,p231"
because P231 is a unique identifier within the Amlogic namespace, so why
not call the SoC "amlogic,s905x" for the same reason? The documentation
is already there in having both "amlogic,s905x" _and_
"amlogic,meson-gxl" - please re-read my post. There is no S905X in GXL
family and another S905X in some other Amlogic SoC family, so it's
unique and there is no reason to encode any hierarchies into its name
other than vendor,name.
I'm not arguing over the file name, where it perfectly makes sense to
have a meson-gxl- prefix (already discussed), just about the compatible
string where we don't have "amlogic,meson-gxl-s905x-p231" either because
it is completely unnecessary and does _not_ add any value.
Not that we're checking this string anywhere anyway... If you want to
check for the GXL family you have to use "amlogic,meson-gxl"; if you
want to check for the specific SoC you use "amlogic,s905x". Simple. We
never match partial strings, so there is no sense in a hardcoded prefix
that is duplicating information already available.
Regards,
Andreas
--
SUSE Linux GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)
^ permalink raw reply
* [PATCH v2] arm64:pci: fix the IOV device access config space valid condition
From: Bjorn Helgaas @ 2016-09-12 21:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1472455618-17892-1-git-send-email-po.liu@nxp.com>
On Mon, Aug 29, 2016 at 03:26:58PM +0800, Po Liu wrote:
> When echo a number to /sys/bus/pci/devices/xxx/sriov_numvfs to enable the
> VF devices. A crash log occurred. This found to be access the IOV devices
> config space failure issue.
>
> The read/write config space from host would judge the pcie device plugin
> or not by(Designware platform as example):
>
> if (bus->primary == pp->root_bus_nr && dev > 0)
> return 0;
>
> Although all PCIe devices for dev(coming from the device and function
> number) is zero. But the dev is not zero for VF devices. So remove the
> condition.
>
> These PCI hosts were changed: designware, altera, xilinx.
>
> Signed-off-by: Po Liu <po.liu@nxp.com>
Applied to pci/virtualization for v4.9, thanks!
I split it into three patches for backporting and reversion purposes.
> ---
> changes for v2:
> - add pci hosts: altera, xilinx;
>
> drivers/pci/host/pcie-altera.c | 7 -------
> drivers/pci/host/pcie-designware.c | 7 -------
> drivers/pci/host/pcie-xilinx.c | 7 -------
> 3 files changed, 21 deletions(-)
>
> diff --git a/drivers/pci/host/pcie-altera.c b/drivers/pci/host/pcie-altera.c
> index 2b78376..edbe0a7 100644
> --- a/drivers/pci/host/pcie-altera.c
> +++ b/drivers/pci/host/pcie-altera.c
> @@ -171,13 +171,6 @@ static bool altera_pcie_valid_config(struct altera_pcie *pcie,
> if (bus->number == pcie->root_bus_nr && dev > 0)
> return false;
>
> - /*
> - * Do not read more than one device on the bus directly attached
> - * to root port, root port can only attach to one downstream port.
> - */
> - if (bus->primary == pcie->root_bus_nr && dev > 0)
> - return false;
> -
> return true;
> }
>
> diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
> index 12afce1..dd20eb2 100644
> --- a/drivers/pci/host/pcie-designware.c
> +++ b/drivers/pci/host/pcie-designware.c
> @@ -670,13 +670,6 @@ static int dw_pcie_valid_config(struct pcie_port *pp,
> if (bus->number == pp->root_bus_nr && dev > 0)
> return 0;
>
> - /*
> - * do not read more than one device on the bus directly attached
> - * to RC's (Virtual Bridge's) DS side.
> - */
> - if (bus->primary == pp->root_bus_nr && dev > 0)
> - return 0;
> -
> return 1;
> }
>
> diff --git a/drivers/pci/host/pcie-xilinx.c b/drivers/pci/host/pcie-xilinx.c
> index a30e016..75c89db 100644
> --- a/drivers/pci/host/pcie-xilinx.c
> +++ b/drivers/pci/host/pcie-xilinx.c
> @@ -168,13 +168,6 @@ static bool xilinx_pcie_valid_device(struct pci_bus *bus, unsigned int devfn)
> if (bus->number == port->root_busno && devfn > 0)
> return false;
>
> - /*
> - * Do not read more than one device on the bus directly attached
> - * to RC.
> - */
> - if (bus->primary == port->root_busno && devfn > 0)
> - return false;
> -
> return true;
> }
>
> --
> 2.1.0.27.g96db324
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v1] iov: add return failure condition for pci_setup_device
From: Bjorn Helgaas @ 2016-09-12 21:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1472455681-18827-1-git-send-email-po.liu@nxp.com>
On Mon, Aug 29, 2016 at 03:28:01PM +0800, Po Liu wrote:
> If pci_setup_device() return failure, return failure directly in the
> pci_iov_add_virtfn().
>
> Signed-off-by: Po Liu <po.liu@nxp.com>
Applied to pci/virtualization for v4.9, thanks!
> ---
> drivers/pci/iov.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
> index 2194b44..e30f05c 100644
> --- a/drivers/pci/iov.c
> +++ b/drivers/pci/iov.c
> @@ -136,7 +136,10 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id, int reset)
> virtfn->devfn = pci_iov_virtfn_devfn(dev, id);
> virtfn->vendor = dev->vendor;
> pci_read_config_word(dev, iov->pos + PCI_SRIOV_VF_DID, &virtfn->device);
> - pci_setup_device(virtfn);
> + rc = pci_setup_device(virtfn);
> + if (rc)
> + goto failed0;
> +
> virtfn->dev.parent = dev->dev.parent;
> virtfn->physfn = pci_dev_get(dev);
> virtfn->is_virtfn = 1;
> --
> 2.1.0.27.g96db324
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* iMX53 UART2 suspend freeze
From: Alexey Mednyy @ 2016-09-12 21:47 UTC (permalink / raw)
To: linux-arm-kernel
We've met strange bug with mx53-qsb based board.
We use all 5 UART ports and I can say that on current UART2 with next
configuration in device-tree :
pinctrl_uart2: uart2grp {
fsl,pins = <
MX53_PAD_PATA_BUFFER_EN__UART2_RXD_MUX 0x1e4
MX53_PAD_PATA_DMARQ__UART2_TXD_MUX 0x1e4
>;
};
&uart2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart2>;
status = "okay";
};
prevents board from suspend.
That's happening at least since commit
29add68d16474b7e8e3eadd94da4e909533b99d2 which is also suspend fixing
commit.
All other ports UART1,3,4,5 suspending/resuming fine.
I don't know where do dig next I double checked pinctl settings and it
seems like everything good there.
I've found that most of mx53 based boards with uart2 using the same
muxing configuration.
I wonder if anybody else experiencing this issue?
same configured boards are:
imx53-smd.dts
imx53-tx53.dtsi - based
imx53-tqma53.dtsi - based
imx53-m53evk.dts
_________________________________
Best regards, Mednyy Alexey.
^ permalink raw reply
* [PATCH v2 00/17] Make rpmsg a framework
From: Bjorn Andersson @ 2016-09-12 21:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <57D71FD9.9070007@codeaurora.org>
On Mon 12 Sep 14:36 PDT 2016, Karthikeyan Ramasubramanian wrote:
> On 9/12/2016 1:58 PM, Bjorn Andersson wrote:
[..]
> >I have not looked through all of APR yet and don't know where msm_bus is
> >heading, but for IPC-router your correct that the downstream driver does
> >indeed require this; but that's a side effect of the downstream
> >ipcrouter implementation, not the problem itself.
> >
> APR does send messages in atomic context in addition to the RPM Driver, but
> IPC Router does not to the extent of my knowledge.
Thanks for the information, Karthik.
There seem to be 196 calls to apr_send_pkt() in the msm-3.18 kernel, I
will have to go through them all later, but could you help me by
pointing me to one of those that actually need to be executed in atomic
context?
Thanks,
Bjorn
^ permalink raw reply
* [PATCH v2 4/4] PM / AVS: rockchip-cpu-avs: add driver handling Rockchip cpu avs
From: Stephen Boyd @ 2016-09-12 21:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160829060801.GB5094@vireshk-i7>
On 08/29, Viresh Kumar wrote:
> On 18-08-16, 16:52, Finlye Xiao wrote:
> > +static int rockchip_adjust_opp_table(struct device *cpu_dev,
> > + struct cpufreq_frequency_table *table,
> > + int volt)
> > +{
> > + struct opp_table *opp_table;
> > + struct cpufreq_frequency_table *pos;
> > + struct dev_pm_opp *opp;
> > +
> > + if (!volt)
> > + return 0;
> > +
> > + rcu_read_lock();
> > +
> > + opp_table = _find_opp_table(cpu_dev);
> > + if (IS_ERR(opp_table)) {
> > + rcu_read_unlock();
> > + return PTR_ERR(opp_table);
> > + }
> > +
> > + cpufreq_for_each_valid_entry(pos, table) {
> > + opp = dev_pm_opp_find_freq_exact(cpu_dev, pos->frequency * 1000,
> > + true);
> > + if (IS_ERR(opp))
> > + continue;
> > +
> > + opp->u_volt += volt;
> > + opp->u_volt_min += volt;
> > + opp->u_volt_max += volt;
> > + }
> > +
> > + rcu_read_unlock();
> > +
> > + return 0;
> > +}
>
> I wouldn't prefer altering the opp tables from individual drivers at all. At the
> least, it should be done via some helpers exposed by the core.
>
> But before that I would like to hear from Stephen a bit as I recall he was also
> working on something similar.
>
I had a patch to modify the voltage at runtime for the "current"
OPP. Now that we have regulator and clk control inside OPP that
became a little easier to do without having to do some notifier
from the OPP layer to the consumers. I haven't had time to revive
those patches though. Should we do that? Does this need to modify
anything besides the OPP the device is currently running at?
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* [PATCH 3/3] PCI: Xilinx NWL PCIe: Fix Error for multi function device for legacy interrupts.
From: Bjorn Helgaas @ 2016-09-12 22:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <8520D5D51A55D047800579B094147198258D2C99@XAP-PVEXMBX01.xlnx.xilinx.com>
On Thu, Sep 01, 2016 at 05:19:55AM +0000, Bharat Kumar Gogada wrote:
> > >>>> Hi Bharat,
> > >>>>> @@ -561,7 +561,7 @@ static int nwl_pcie_init_irq_domain(struct
> > >>>>> nwl_pcie
> > >>>> *pcie)
> > >>>>> }
> > >>>>>
> > >>>>> pcie->legacy_irq_domain = irq_domain_add_linear(legacy_intc_node,
> > >>>>> - INTX_NUM,
> > >>>>> + INTX_NUM + 1,
> > >>>>> &legacy_domain_ops,
> > >>>>> pcie);
> > >>>>
> > >>>> This feels like the wrong thing to do. You have INTX_NUM irqs, so
> > >>>> the domain allocation should reflect this. On the other hand, the
> > >>>> way the driver currently deals with mappings is quite broken
> > >>>> (consistently adding 1 to
> > >> the HW interrupt).
> > >>>>
> > >>> Hi Marc,
> > >>>
> > >>> Without above change I get following crash in kernel while booting.
> > >>>
> > >>> [ 2.441684] error: hwirq 0x4 is too large for dummy
> > >>>
> > >>> [ 2.441694] ------------[ cut here ]------------
> > >>>
> > >>> [ 2.441698] WARNING: at kernel/irq/irqdomain.c:344
> > >>>
> > >>> [ 2.441702] Modules linked in:
> > >>>
> > >>> [ 2.441706]
> > >>>
> > >>> [ 2.441714] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 4.4.0 #8
> > >>>
> > >>> [ 2.441718] Hardware name: xlnx,zynqmp (DT)
> > >>>
> > >>> [ 2.441723] task: ffffffc071886b80 ti: ffffffc071888000 task.ti:
> > >> ffffffc071888000
> > >>>
> > >>> [ 2.441732] PC is at irq_domain_associate+0x138/0x1c0
> > >>>
> > >>> [ 2.441738] LR is at irq_domain_associate+0x138/0x1c0
> > >>>
> > >>> In kernel/irq/irqdomain.c function irq_domain_associate
> > >>>
> > >>> if (WARN(hwirq >= domain->hwirq_max,
> > >>> "error: hwirq 0x%x is too large for %s\n", (int)hwirq, domain-
> > >name))
> > >>> return -EINVAL;
> > >>>
> > >>> Here the hwirq and hwirq_max are equal to 4 without the above
> > >>> condition
> > >> (INTX_NUM + 1) due to which crash is coming.
> > >>> This is happening as the legacy interrupts are starting from 1 (INTA).
> > >>
> > >> I understood that. I'm still persisting in saying that you have the wrong fix.
> > >>
> > >> Your domain should always allocate many interrupts as you have
> > >> interrupt sources. These interrupts (hwirq) should be numbered from 0 to (n-
> > 1).
> > >
> > > Agreed, but here comes the problem the hwirq for legacy interrupts
> > > will start at 0x1 to 0x4 (INTA to INTD) and these values are as per
> > > PCIe specification for legacy interrupts. So these cannot be numbered
> > > from 0. So when 0x4 (INTD) for a multi-function device comes the crash
> > > occurs.
> >
> > So who provides this hwirq? Who calls irq_domain_associate() with hwirq set to
> > 4?
> >
> PCIe subsystem invokes pcibios_add_device function in arch/arm64/kernel/pci.c for every pci device.
> The purpose of this function is to assign dev->irq using of_irq_parse_and_map_pci.
> of_irq_parse_and_map_pci invokes of_irq_parse_pci where it reads PCI_INTERRUPT_PIN from configuration space and saves it
> in parameter of struct of_phandle_args.
> This structure is passed to irq_create_of_mapping where it invokes irq_create_fwspec_mapping.
> irq_create_fwspec_mapping invokes irq_domain_translate and gets hwirq, here the above saved PCI_INTERRUPT_PIN value is assigned
> to hwirq (*hwirq = fwspec->param[0]).
> And then using this hwirq irq_create_mapping -> irq_domain_associate were invoked and mapping is created for virtual irq with this hwirq.
> So for any end point PCI_INTERRUPT_PIN value starts from 0x1 to 0x4 and so hwirq starts from 0x1 to 0x4.
>
> So the values are more generic w.r.t to protocol, that's why hwirq will range from 0x1 to 0x4.
> And then if you check pcie-altera.c they are doing this adding one in their handler and while creating legacy domain.
Is this resolved yet? Marc, are you happy, or should we iterate on this
again?
^ permalink raw reply
* [PATCH 6/8 v2] arm: orion5x: Add DT-based support for Netgear WNR854T
From: Andrew Lunn @ 2016-09-12 22:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <2920481.EgEQnLmOkM@wuerfel>
> Maybe we can instead leave out the PCI support from the new
> file for now and not delete the legacy board file?
Jamie, which interrupt do you see the WiFi card using? If it is
IRQ_ORION5X_PCIE0_INT, (1 + 11), that is probably easier to deal with
than if it uses GPIO 4.
Thanks
Andrew
^ permalink raw reply
* [PATCH v4 03/22] usb: ulpi: Support device discovery via DT
From: Stephen Boyd @ 2016-09-12 22:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160907213519.27340-4-stephen.boyd@linaro.org>
Quoting Stephen Boyd (2016-09-07 14:35:00)
> @@ -174,6 +219,21 @@ static int ulpi_register(struct device *dev, struct ulpi *ulpi)
> ulpi->id.product = ulpi_read(ulpi, ULPI_PRODUCT_ID_LOW);
> ulpi->id.product |= ulpi_read(ulpi, ULPI_PRODUCT_ID_HIGH) << 8;
>
> + /* Some ULPI devices don't have a vendor id so rely on OF match */
> + if (ulpi->id.vendor == 0)
> + goto err;
> +
> + request_module("ulpi:v%04xp%04x", ulpi->id.vendor, ulpi->id.product);
> +
> + return 0;
> +err:
> + return of_device_request_module(&ulpi->dev);
This can't return the value of of_device_request_module() because that
returns an error if the module is builtin or if module loading is
disabled. I'll have to ignore the error here and just return success all
the time.
^ permalink raw reply
* [PATCH 1/3] misc: Add Aspeed BT IPMI host driver
From: Corey Minyard @ 2016-09-12 22:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <b42f1b61-8b00-2412-d51d-6207da8afcd6@kaod.org>
On 09/12/2016 04:23 PM, C?dric Le Goater wrote:
> Hello,
>
> On 09/12/2016 10:33 PM, Corey Minyard wrote:
>> On 09/12/2016 02:15 PM, Arnd Bergmann wrote:
>>> On Monday, September 12, 2016 1:55:40 PM CEST Corey Minyard wrote:
>>>> On 09/02/2016 08:22 AM, C?dric Le Goater wrote:
>>>>> Hello,
>>>>>
>>>>> Adding Corey in cc: . I guess I should have done that in the first place.
>>>> Yes, probably so. I've been travelling and didn't see it on the mailing
>>>> lists until now.
>>>>
>>>> There is already a BT driver in the kernel, in drivers/char/ipmi, why
>>>> won't that work?
>>> The new driver is the host side (running on the BMC), the existing one
>>> is the client (running on the PC).
>>>
>>> Arnd
>> Ok, that's not really clear from the documentation or the Kconfig.
>> In the IPMI spec the "host" side is the computer side, not the BMC
>> side. Like:
>>
>> 11.6.1 BT Host Interface Registers
>> The Host BT interface provides an independent set of registers and
>> interrupts to allow the Host driver to
>> communicate with the baseboard management controller without
>> conflicting with the O/S ACPI driver.
>>
>> In light of that, this should probably be named the bt-bmc driver.
>>
>> I haven't reviewed this in detail, but I'm ok with putting it in
>> drivers/char/ipmi. The state machine part looks reasonably
>> generic. The configuration part isn't, but that could be split
>> out later if necessary.
>>
>> The biggest thing I don't like is the byte at a time interfaces
>> from userspace. That seems fairly inefficient if the system
>> does extra work for each userspace access. IIRC some
>> systems do and some don't.
> What about the ioctl to send an SMS ATN event to the host ? Is
> that ok for you ?
Yeah, that's necessary, there's no way the low-level driver can
know when to do that.
I have a similar piece of code in the qemu IPMI emulator, even
the external IPMI emulator has a message it sends to set ATTN.
I did look at similarities between the two pieces of code, but
the qemu one has to be register-read/write driven, so it's
completely different in design.
-corey
> Thanks,
>
> C.
^ permalink raw reply
* [PATCH v4 1/2] nxp/dts: add pcie aer interrupt-name property in the dts
From: Bjorn Helgaas @ 2016-09-12 22:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1472625442-23309-1-git-send-email-po.liu@nxp.com>
On Wed, Aug 31, 2016 at 02:37:21PM +0800, Po Liu wrote:
> NXP some platforms aer interrupt was not MSI/MSI-X/INTx
> but using interrupt line independently. This patch add a "aer"
> interrupt-names for aer interrupt.
> With the interrupt-names "aer", code could probe aer interrupt
> line for pcie root port, replace the aer interrupt service irq.
> This is intend to fixup the Layerscape platforms which aer interrupt
> was not MSI/MSI-X/INTx, but using interrupt line independently.
>
> Signed-off-by: Po Liu <po.liu@nxp.com>
Rob and Shawn had comments here, and I'm not sure they ever got resolved.
> ---
> changes for V4:
> - Add comments explain why to add this patch
> - Move the binding changes to pci code patch
>
> arch/arm/boot/dts/ls1021a.dtsi | 6 ++++--
> arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi | 18 +++++++++---------
> arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi | 16 ++++++++--------
> 3 files changed, 21 insertions(+), 19 deletions(-)
>
> diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
> index 368e219..443e50b 100644
> --- a/arch/arm/boot/dts/ls1021a.dtsi
> +++ b/arch/arm/boot/dts/ls1021a.dtsi
> @@ -634,7 +634,8 @@
> reg = <0x00 0x03400000 0x0 0x00010000 /* controller registers */
> 0x40 0x00000000 0x0 0x00002000>; /* configuration space */
> reg-names = "regs", "config";
> - interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH>; /* controller interrupt */
> + interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>; /* aer interrupt */
> + interrupt-names = "aer";
> fsl,pcie-scfg = <&scfg 0>;
> #address-cells = <3>;
> #size-cells = <2>;
> @@ -657,7 +658,8 @@
> reg = <0x00 0x03500000 0x0 0x00010000 /* controller registers */
> 0x48 0x00000000 0x0 0x00002000>; /* configuration space */
> reg-names = "regs", "config";
> - interrupts = <GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH>;
> + interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>; /* aer interrupt */
> + interrupt-names = "aer";
> fsl,pcie-scfg = <&scfg 1>;
> #address-cells = <3>;
> #size-cells = <2>;
> diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
> index e669fbd..654071d 100644
> --- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
> +++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
> @@ -527,9 +527,9 @@
> reg = <0x00 0x03400000 0x0 0x00100000 /* controller registers */
> 0x40 0x00000000 0x0 0x00002000>; /* configuration space */
> reg-names = "regs", "config";
> - interrupts = <0 118 0x4>, /* controller interrupt */
> - <0 117 0x4>; /* PME interrupt */
> - interrupt-names = "intr", "pme";
> + interrupts = <0 117 0x4>, /* PME interrupt */
> + <0 118 0x4>; /* aer interrupt */
> + interrupt-names = "pme", "aer";
> #address-cells = <3>;
> #size-cells = <2>;
> device_type = "pci";
> @@ -552,9 +552,9 @@
> reg = <0x00 0x03500000 0x0 0x00100000 /* controller registers */
> 0x48 0x00000000 0x0 0x00002000>; /* configuration space */
> reg-names = "regs", "config";
> - interrupts = <0 128 0x4>,
> - <0 127 0x4>;
> - interrupt-names = "intr", "pme";
> + interrupts = <0 127 0x4>,
> + <0 128 0x4>;
> + interrupt-names = "pme", "aer";
> #address-cells = <3>;
> #size-cells = <2>;
> device_type = "pci";
> @@ -577,9 +577,9 @@
> reg = <0x00 0x03600000 0x0 0x00100000 /* controller registers */
> 0x50 0x00000000 0x0 0x00002000>; /* configuration space */
> reg-names = "regs", "config";
> - interrupts = <0 162 0x4>,
> - <0 161 0x4>;
> - interrupt-names = "intr", "pme";
> + interrupts = <0 161 0x4>,
> + <0 162 0x4>;
> + interrupt-names = "pme", "aer";
> #address-cells = <3>;
> #size-cells = <2>;
> device_type = "pci";
> diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi
> index 21023a3..58844e8 100644
> --- a/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi
> +++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi
> @@ -583,8 +583,8 @@
> reg = <0x00 0x03400000 0x0 0x00100000 /* controller registers */
> 0x10 0x00000000 0x0 0x00002000>; /* configuration space */
> reg-names = "regs", "config";
> - interrupts = <0 108 0x4>; /* Level high type */
> - interrupt-names = "intr";
> + interrupts = <0 108 0x4>; /* aer interrupt */
> + interrupt-names = "aer";
> #address-cells = <3>;
> #size-cells = <2>;
> device_type = "pci";
> @@ -607,8 +607,8 @@
> reg = <0x00 0x03500000 0x0 0x00100000 /* controller registers */
> 0x12 0x00000000 0x0 0x00002000>; /* configuration space */
> reg-names = "regs", "config";
> - interrupts = <0 113 0x4>; /* Level high type */
> - interrupt-names = "intr";
> + interrupts = <0 113 0x4>; /* aer interrupt */
> + interrupt-names = "aer";
> #address-cells = <3>;
> #size-cells = <2>;
> device_type = "pci";
> @@ -631,8 +631,8 @@
> reg = <0x00 0x03600000 0x0 0x00100000 /* controller registers */
> 0x14 0x00000000 0x0 0x00002000>; /* configuration space */
> reg-names = "regs", "config";
> - interrupts = <0 118 0x4>; /* Level high type */
> - interrupt-names = "intr";
> + interrupts = <0 118 0x4>; /* aer interrupt */
> + interrupt-names = "aer";
> #address-cells = <3>;
> #size-cells = <2>;
> device_type = "pci";
> @@ -655,8 +655,8 @@
> reg = <0x00 0x03700000 0x0 0x00100000 /* controller registers */
> 0x16 0x00000000 0x0 0x00002000>; /* configuration space */
> reg-names = "regs", "config";
> - interrupts = <0 123 0x4>; /* Level high type */
> - interrupt-names = "intr";
> + interrupts = <0 123 0x4>; /* aer interrupt */
> + interrupt-names = "aer";
> #address-cells = <3>;
> #size-cells = <2>;
> device_type = "pci";
> --
> 2.1.0.27.g96db324
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH/RFC v3 00/22] soc: renesas: Add R-Car RST driver for obtaining mode pin state
From: Stephen Boyd @ 2016-09-12 22:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAMuHMdWu34OQSS6J3bf=0-1TYULc=coiVomBjtBatwGta5F3HQ@mail.gmail.com>
On 09/01, Geert Uytterhoeven wrote:
> Hi Stephen,
>
> On Thu, Jun 30, 2016 at 10:14 PM, Stephen Boyd <sboyd@codeaurora.org> wrote:
> > On 06/01, Geert Uytterhoeven wrote:
> >> Currently the R-Car Clock Pulse Generator (CPG) drivers obtains the
> >> state of the mode pins either by a call from the board code, or directly
> >> by using a hardcoded register access. This is a bit messy, and creates a
> >> dependency between driver and platform code.
> >>
> >> This RFC patch series converts the various Renesas R-Car clock drivers
> >> and support code from reading the mode pin states using a hardcoded
> >> register access to using a new R-Car RST driver.
> >
> > Dumb question, can we use the nvmem reading APIs instead of an
> > SoC specific function to read the modes?
>
> Thanks for your suggestion, the nvmem API indeed looks like a suitable API,
> as it does support read-only nvmems.
>
> Unfortunately I also see a few disadvantages:
> 1. nvmem_init() is a subsys_initcall(), while most of our users (except for
> the recent renesas-cpg-mssr driver) are clock drivers using
> CLK_OF_DECLARE(), and are thus initialized from of_clk_init() at much
> earlier time_init() time.
> Of course the mvmem subsystem and/or the clock drivers can be changed, if
> deemed useful.
Sounds like this is solvable.
> 2. Using the nvmem DT bindings means we have to add more DT glue from the
> nvmem consumer(s) to the nvmem provider. As we need to provide backwards
> compatibility with old DTSes, this means we need more C code or DT fixup
> code to handle that.
Ah I wasn't aware we were keeping backwards compatibility around.
> 3. The nvmem subsystem may be overkill to provide access to a simple 32-bit
> read-only register that never changes value after boot.
The nvmem subsystem is designed to read values from things that
mostly never change. Overkill may be true, but the nice thing
about using nvmem APIs is that the driver doesn't have to use
some platform specific function that duplicates similar
functionality. It's unfortunate that backwards incompatibility
limits our ability to move to common linux frameworks when they
are created after the binding is used.
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* [PATCH v2] drivers: acpi: fix GIC irq model default PCI IRQ polarity
From: Rafael J. Wysocki @ 2016-09-12 22:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1473180663-20590-1-git-send-email-lorenzo.pieralisi@arm.com>
On Tuesday, September 06, 2016 05:51:03 PM Lorenzo Pieralisi wrote:
> On ACPI ARM based systems the GIC interrupt controller
> and corresponding interrupt model permit only the high
> polarity for level interrupts.
>
> ACPI firmware describes PCI legacy IRQs through entries
> in the _PRT objects. Entries in the _PRT can be of two types:
>
> - Static: not configurable, trigger/polarity default to level-low,
> _PRT entry defines the global GSI interrupt number
> - Configurable: _PRT interrupt entry contains a reference to the
> corresponding PCI interrupt link device (that in turn provides the
> interrupt descriptor through its _CRS/_PRS methods)
>
> Configurable IRQ entries are not currently allowed by the ACPI
> specification on ARM since they can only be used for interrupt pins that
> are routable, as per ACPI specifications (version 6.1, 6.2.13):
>
> "[...] There are two ways that _PRT can be used. Typically, the
> interrupt input that a given PCI interrupt is on is configurable. For
> example, a given PCI interrupt might be configured for either IRQ 10 or
> 11 on an 8259 interrupt controller. In this model, each interrupt is
> represented in the ACPI namespace as a PCI Interrupt Link Device. [...]"
>
> ARM platforms GIC configurations do not allow dynamic IRQ routing,
> since routing is statically laid out at synthesis time; therefore PCI
> interrupt links cannot be used for PCI legacy IRQ descriptions in the
> _PRT on ARM systems.
>
> On the other hand, current core ACPI code handling PCI legacy IRQs
> consider IRQ trigger/polarity for static _PRT entries as level-low.
>
> On ARM systems with a GIC interrupt controller and corresponding
> ACPI interrupt model this does not work in that GIC interrupt
> controller is only capable of handling level interrupts whose
> polarity is high (for PCI legacy IRQs - that are level-low by
> specification - this means that the legacy IRQs are inverted before
> reaching the interrupt controller pin), resulting in IRQ allocation
> failures such as:
>
> genirq: Setting trigger mode 8 for irq 18 failed (gic_set_type+0x0/0x48)
>
> Change the default polarity for PCI legacy IRQs to high on systems
> booting wth ACPI on platforms with a GIC interrupt controller model,
> fixing the discrepancy between specification and HW behaviour.
>
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Acked-by: Marc Zyngier <marc.zyngier@arm.com>
> Tested-by: Duc Dang <dhdang@apm.com>
> Cc: Punit Agrawal <punit.agrawal@arm.com>
> Cc: Duc Dang <dhdang@apm.com>
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: Sinan Kaya <okaya@codeaurora.org>
> Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
> Cc: Marc Zyngier <marc.zyngier@arm.com>
Applied.
Thanks,
Rafael
^ permalink raw reply
* [PATCH 1/6] PCI: xilinx: Keep both legacy and MSI interrupt references.
From: Bjorn Helgaas @ 2016-09-12 22:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1472724886-28301-1-git-send-email-bharatku@xilinx.com>
On Thu, Sep 01, 2016 at 03:44:41PM +0530, Bharat Kumar Gogada wrote:
> When built with MSI support the legacy domain reference is being
> overwritten with MSI.
> Instead creating two separate domains for MSI and legacy interrupts.
>
> Signed-off-by: Bharat Kumar Gogada <bharatku@xilinx.com>
I'm looking for an ack from Michal for these...
> ---
> drivers/pci/host/pcie-xilinx.c | 26 +++++++++++++++-----------
> 1 file changed, 15 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/pci/host/pcie-xilinx.c b/drivers/pci/host/pcie-xilinx.c
> index a30e016..bd64677 100644
> --- a/drivers/pci/host/pcie-xilinx.c
> +++ b/drivers/pci/host/pcie-xilinx.c
> @@ -101,7 +101,8 @@
> * @msi_pages: MSI pages
> * @root_busno: Root Bus number
> * @dev: Device pointer
> - * @irq_domain: IRQ domain pointer
> + * @msi_domain: MSI IRQ domain pointer
> + * @leg_domain: Legacy IRQ domain pointer
> * @resources: Bus Resources
> */
> struct xilinx_pcie_port {
> @@ -110,7 +111,8 @@ struct xilinx_pcie_port {
> unsigned long msi_pages;
> u8 root_busno;
> struct device *dev;
> - struct irq_domain *irq_domain;
> + struct irq_domain *msi_domain;
> + struct irq_domain *leg_domain;
> struct list_head resources;
> };
>
> @@ -281,7 +283,7 @@ static int xilinx_pcie_msi_setup_irq(struct msi_controller *chip,
> if (hwirq < 0)
> return hwirq;
>
> - irq = irq_create_mapping(port->irq_domain, hwirq);
> + irq = irq_create_mapping(port->msi_domain, hwirq);
> if (!irq)
> return -EINVAL;
>
> @@ -443,7 +445,7 @@ static irqreturn_t xilinx_pcie_intr_handler(int irq, void *data)
> /* Handle INTx Interrupt */
> val = ((val & XILINX_PCIE_RPIFR1_INTR_MASK) >>
> XILINX_PCIE_RPIFR1_INTR_SHIFT) + 1;
> - generic_handle_irq(irq_find_mapping(port->irq_domain,
> + generic_handle_irq(irq_find_mapping(port->leg_domain,
> val));
> }
> }
> @@ -526,12 +528,14 @@ static void xilinx_pcie_free_irq_domain(struct xilinx_pcie_port *port)
> }
>
> for (i = 0; i < num_irqs; i++) {
> - irq = irq_find_mapping(port->irq_domain, i);
> + irq = irq_find_mapping(port->leg_domain, i);
> if (irq > 0)
> irq_dispose_mapping(irq);
> }
> -
> - irq_domain_remove(port->irq_domain);
> + if (port->leg_domain)
> + irq_domain_remove(port->leg_domain);
> + if (port->msi_domain)
> + irq_domain_remove(port->msi_domain);
> }
>
> /**
> @@ -553,21 +557,21 @@ static int xilinx_pcie_init_irq_domain(struct xilinx_pcie_port *port)
> return -ENODEV;
> }
>
> - port->irq_domain = irq_domain_add_linear(pcie_intc_node, 4,
> + port->leg_domain = irq_domain_add_linear(pcie_intc_node, 4,
> &intx_domain_ops,
> port);
> - if (!port->irq_domain) {
> + if (!port->leg_domain) {
> dev_err(dev, "Failed to get a INTx IRQ domain\n");
> return -ENODEV;
> }
>
> /* Setup MSI */
> if (IS_ENABLED(CONFIG_PCI_MSI)) {
> - port->irq_domain = irq_domain_add_linear(node,
> + port->msi_domain = irq_domain_add_linear(node,
> XILINX_NUM_MSI_IRQS,
> &msi_domain_ops,
> &xilinx_pcie_msi_chip);
> - if (!port->irq_domain) {
> + if (!port->msi_domain) {
> dev_err(dev, "Failed to get a MSI IRQ domain\n");
> return -ENODEV;
> }
> --
> 2.1.1
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v7] i2c: imx: make bus recovery through pinctrl optional
From: Li Yang @ 2016-09-12 22:22 UTC (permalink / raw)
To: linux-arm-kernel
Since commit 1c4b6c3bcf30 ("i2c: imx: implement bus recovery") the
driver starts to use gpio/pinctrl to support optional bus recovery
feature. But pinctrl is not always usable. There are platforms such
as ls1021a and ls1043a that don't support pinctrl, and it could just
be broken due to old/broken device tree. The patch makes it really
optional that the probe function won't bailout on pinctrl problems
instead it just disables bus recovery and prints out notification when
there is problem with pinctrl. Since pinctrl is only used by bus
recovery in this driver, move pinctrl initialization into bus recovery
init function to prevent confusion.
Signed-off-by: Li Yang <leoyang.li@nxp.com>
Cc: Gao Pan <pandy.gao@nxp.com>
Cc: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
---
v7:
Move pinctrl init into the i2c_imx_init_recovery_info()
Update commit message and code comment
v6:
Update code comment
v5:
Revert the last minute change of recovery info initialization timing, it
will cause problem if initialized after i2c_add_numbered_adapter()
v4:
Remove the use of IS_ERR_OR_NULL
Move the condition judgement to i2c_imx_init_recovery_info()
Change the timing of recovery initialization to be after bus registration
v3:
Rebased to Wolfram's for-next branch
Added acked-by from Linus Walleij
Update to use new nxp email addresses due to company merge
drivers/i2c/busses/i2c-imx.c | 31 ++++++++++++++++++++++---------
1 file changed, 22 insertions(+), 9 deletions(-)
diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index 1844bc9..54ce9c1 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -984,11 +984,24 @@ static void i2c_imx_unprepare_recovery(struct i2c_adapter *adap)
pinctrl_select_state(i2c_imx->pinctrl, i2c_imx->pinctrl_pins_default);
}
-static void i2c_imx_init_recovery_info(struct imx_i2c_struct *i2c_imx,
+/*
+ * We switch SCL and SDA to their GPIO function and do some bitbanging
+ * for bus recovery. These alternative pinmux settings can be
+ * described in the device tree by a separate pinctrl state "gpio". If
+ * this is missing this is not a big problem, the only implication is
+ * that we can't do bus recovery.
+ */
+static int i2c_imx_init_recovery_info(struct imx_i2c_struct *i2c_imx,
struct platform_device *pdev)
{
struct i2c_bus_recovery_info *rinfo = &i2c_imx->rinfo;
+ i2c_imx->pinctrl = devm_pinctrl_get(&pdev->dev);
+ if (!i2c_imx->pinctrl || IS_ERR(i2c_imx->pinctrl)) {
+ dev_info(&pdev->dev, "can't get pinctrl, bus recovery not supported\n");
+ return PTR_ERR(i2c_imx->pinctrl);
+ }
+
i2c_imx->pinctrl_pins_default = pinctrl_lookup_state(i2c_imx->pinctrl,
PINCTRL_STATE_DEFAULT);
i2c_imx->pinctrl_pins_gpio = pinctrl_lookup_state(i2c_imx->pinctrl,
@@ -1001,7 +1014,7 @@ static void i2c_imx_init_recovery_info(struct imx_i2c_struct *i2c_imx,
IS_ERR(i2c_imx->pinctrl_pins_default) ||
IS_ERR(i2c_imx->pinctrl_pins_gpio)) {
dev_dbg(&pdev->dev, "recovery information incomplete\n");
- return;
+ return 0;
}
dev_dbg(&pdev->dev, "using scl-gpio %d and sda-gpio %d for recovery\n",
@@ -1011,6 +1024,8 @@ static void i2c_imx_init_recovery_info(struct imx_i2c_struct *i2c_imx,
rinfo->unprepare_recovery = i2c_imx_unprepare_recovery;
rinfo->recover_bus = i2c_generic_gpio_recovery;
i2c_imx->adapter.bus_recovery_info = rinfo;
+
+ return 0;
}
static u32 i2c_imx_func(struct i2c_adapter *adapter)
@@ -1081,12 +1096,6 @@ static int i2c_imx_probe(struct platform_device *pdev)
return ret;
}
- i2c_imx->pinctrl = devm_pinctrl_get(&pdev->dev);
- if (IS_ERR(i2c_imx->pinctrl)) {
- ret = PTR_ERR(i2c_imx->pinctrl);
- goto clk_disable;
- }
-
/* Request IRQ */
ret = devm_request_irq(&pdev->dev, irq, i2c_imx_isr, 0,
pdev->name, i2c_imx);
@@ -1125,7 +1134,11 @@ static int i2c_imx_probe(struct platform_device *pdev)
i2c_imx, IMX_I2C_I2CR);
imx_i2c_write_reg(i2c_imx->hwdata->i2sr_clr_opcode, i2c_imx, IMX_I2C_I2SR);
- i2c_imx_init_recovery_info(i2c_imx, pdev);
+ /* Init optional bus recovery function */
+ ret = i2c_imx_init_recovery_info(i2c_imx, pdev);
+ /* Give it another chance if pinctrl used is not ready yet */
+ if (ret == -EPROBE_DEFER)
+ goto rpm_disable;
/* Add I2C adapter */
ret = i2c_add_numbered_adapter(&i2c_imx->adapter);
--
1.9.0
^ permalink raw reply related
* [PATCH v2 00/17] Make rpmsg a framework
From: Lina Iyer @ 2016-09-12 22:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160912165233.GB21885@linaro.org>
On Mon, Sep 12 2016 at 10:52 -0600, Lina Iyer wrote:
>Hi Bjorn,
>
>On Thu, Sep 01 2016 at 16:28 -0600, Bjorn Andersson wrote:
>>This series splits the virtio rpmsg bus driver into a rpmsg bus and a virtio
>>backend/wireformat.
>>
>>
>>As we discussed the Qualcomm SMD implementation a couple of years back people
>>suggested that I should make it "a rpmsg thingie". With the introduction of the
>>Qualcomm 8996 platform, we must support a variant of the communication
>>mechanism that share many of the characteristics of SMD, but are different
>>enough that it can't be done in a single implementation. As such there is
>>enough benefit to do the necessary work and being able to make SMD a "rpmsg
>>thingie".
>>
>>On-top of this series I have patches to switch the current smd clients over to
>>rpmsg (and by that drop the existing SMD implementation).
>>
>>All this allows me to implement the new backend and reuse all existing SMD
>>drivers with the new mechanism.
>>
>
>RPM Communication has to supported even when IRQs are disabled. The most
>important use of this communication is to set the wake up time for the
>CPU subsystem when all the CPUs are powered off. In addition to that,
>"sleep" votes that are sent by the application processor subsystem to
>allow system to go into deep sleep modes can only be triggered when the
>CPU PM domains are power collapsed, drivers do not have a knowledge of
>when that happens. This has to be done by a platform code that registers
>for CPU PM domain power_off/on callbacks.
>
Ok, my bad. These two cases are not critical for the SoC supported by
this driver. So you are good to go from cpuidle perspective
>Using rpmsg may be nice for RPM SMD communication, but mutexes need to
>go away for this driver to be any useful than bare bones active mode
>resource requests for QCOM SoCs. By not doing that now, we lock
>ourselves out of using this SMD driver in the near future when CPU PM
>domains are available in the kernel with an ability to do system low
>power modes.
>
>I hope you would make rpmsg work in IRQ disabled contexts first before
>porting the SMD driver.
>
>Thanks,
>Lina
>
>>
>>Changes from v1:
>>- Split up the patch moving core code to rpmsg_core into several commits
>>- Dropped the wrapping struct in rpmsg_core and just added the ops to the
>> public API (but hid the implementation details)
>>- Reordered things to reduce the size of the later patches
>>
>>Bjorn Andersson (17):
>> rpmsg: Enable matching devices with drivers based on DT
>> rpmsg: Name rpmsg devices based on channel id
>> rpmsg: rpmsg_send() operations takes rpmsg_endpoint
>> rpmsg: Make rpmsg_create_ept() take channel_info struct
>> rpmsg: Clean up rpmsg device vs channel naming
>> rpmsg: Introduce indirection table for rpmsg_device operations
>> rpmsg: Move rpmsg_device API to new file
>> rpmsg: Indirection table for rpmsg_endpoint operations
>> rpmsg: Move endpoint related interface to rpmsg core
>> rpmsg: Move helper for finding rpmsg devices to core
>> rpmsg: Split off generic tail of create_channel()
>> rpmsg: Split rpmsg core and virtio backend
>> rpmsg: Hide rpmsg indirection tables
>> rpmsg: virtio: Hide vrp pointer from the public API
>> rpmsg: Move virtio specifics from public header
>> rpmsg: Allow callback to return errors
>> rpmsg: Introduce Qualcomm SMD backend
>>
>>drivers/remoteproc/Kconfig | 4 +-
>>drivers/rpmsg/Kconfig | 14 +
>>drivers/rpmsg/Makefile | 4 +-
>>drivers/rpmsg/qcom_smd.c | 1434 +++++++++++++++++++++++++++++++++++
>>drivers/rpmsg/rpmsg_core.c | 498 ++++++++++++
>>drivers/rpmsg/rpmsg_internal.h | 82 ++
>>drivers/rpmsg/virtio_rpmsg_bus.c | 487 +++++-------
>>include/linux/rpmsg.h | 246 +-----
>>samples/rpmsg/rpmsg_client_sample.c | 14 +-
>>9 files changed, 2266 insertions(+), 517 deletions(-)
>>create mode 100644 drivers/rpmsg/qcom_smd.c
>>create mode 100644 drivers/rpmsg/rpmsg_core.c
>>create mode 100644 drivers/rpmsg/rpmsg_internal.h
>>
>>--
>>2.5.0
>>
>>--
>>To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
>>the body of a message to majordomo at vger.kernel.org
>>More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH V6 2/5] PCI/ACPI: Check platform specific ECAM quirks
From: Duc Dang @ 2016-09-12 22:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1473449047-10499-3-git-send-email-tn@semihalf.com>
On Fri, Sep 9, 2016 at 12:24 PM, Tomasz Nowicki <tn@semihalf.com> wrote:
>
> Some platforms may not be fully compliant with generic set of PCI config
> accessors. For these cases we implement the way to overwrite CFG accessors
> set and configuration space range.
>
> In first place pci_mcfg_parse() saves machine's IDs and revision number
> (these come from MCFG header) in order to match against known quirk entries.
> Then the algorithm traverses available quirk list (static array),
> matches against <oem_id, oem_table_id, rev, domain, bus number range> and
> returns custom PCI config ops and/or CFG resource structure.
>
> When adding new quirk there are two possibilities:
> 1. Override default pci_generic_ecam_ops ops but CFG resource comes from MCFG
> { "OEM_ID", "OEM_TABLE_ID", <REV>, <DOMAIN>, <BUS_NR>, &foo_ops, MCFG_RES_EMPTY },
> 2. Override default pci_generic_ecam_ops ops and CFG resource. For this case
> it is also allowed get CFG resource from quirk entry w/o having it in MCFG.
> { "OEM_ID", "OEM_TABLE_ID", <REV>, <DOMAIN>, <BUS_NR>, &boo_ops,
> DEFINE_RES_MEM(START, SIZE) },
>
> pci_generic_ecam_ops and MCFG entries will be used for platforms
> free from quirks.
>
> Signed-off-by: Tomasz Nowicki <tn@semihalf.com>
> Signed-off-by: Dongdong Liu <liudongdong3@huawei.com>
> Signed-off-by: Christopher Covington <cov@codeaurora.org>
> ---
> drivers/acpi/pci_mcfg.c | 80 +++++++++++++++++++++++++++++++++++++++++++++----
> 1 file changed, 74 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c
> index ffcc651..2b8acc7 100644
> --- a/drivers/acpi/pci_mcfg.c
> +++ b/drivers/acpi/pci_mcfg.c
> @@ -32,6 +32,59 @@ struct mcfg_entry {
> u8 bus_start;
> u8 bus_end;
> };
> +struct mcfg_fixup {
> + char oem_id[ACPI_OEM_ID_SIZE + 1];
> + char oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1];
> + u32 oem_revision;
> + u16 seg;
> + struct resource bus_range;
> + struct pci_ecam_ops *ops;
> + struct resource cfgres;
> +};
> +
> +#define MCFG_DOM_ANY (-1)
> +#define MCFG_BUS_RANGE(start, end) DEFINE_RES_NAMED((start), \
> + ((end) - (start) + 1), \
> + NULL, IORESOURCE_BUS)
> +#define MCFG_BUS_ANY MCFG_BUS_RANGE(0x0, 0xff)
> +#define MCFG_RES_EMPTY DEFINE_RES_NAMED(0, 0, NULL, 0)
> +
> +static struct mcfg_fixup mcfg_quirks[] = {
> +/* { OEM_ID, OEM_TABLE_ID, REV, DOMAIN, BUS_RANGE, cfgres, ops }, */
> +};
> +
> +static char mcfg_oem_id[ACPI_OEM_ID_SIZE];
> +static char mcfg_oem_table_id[ACPI_OEM_TABLE_ID_SIZE];
> +static u32 mcfg_oem_revision;
> +
> +static void pci_mcfg_match_quirks(struct acpi_pci_root *root,
> + struct resource *cfgres,
> + struct pci_ecam_ops **ecam_ops)
> +{
> + struct mcfg_fixup *f;
> + int i;
> +
> + /*
> + * First match against PCI topology <domain:bus> then use OEM ID, OEM
> + * table ID, and OEM revision from MCFG table standard header.
> + */
> + for (i = 0, f = mcfg_quirks; i < ARRAY_SIZE(mcfg_quirks); i++, f++) {
> + if (f->seg == root->segment &&
Is dropping the comparison with MCFG_DOM_ANY intended? It is useful if
all the controllers (segs) can use the same quirk (X-Gene case).
If you decide to drop it, then we can remove MCFG_DOM_ANY definition as well.
> + resource_contains(&f->bus_range, &root->secondary) &&
> + !memcmp(f->oem_id, mcfg_oem_id, ACPI_OEM_ID_SIZE) &&
> + !memcmp(f->oem_table_id, mcfg_oem_table_id,
> + ACPI_OEM_TABLE_ID_SIZE) &&
> + f->oem_revision == mcfg_oem_revision) {
> + if (f->cfgres.start)
> + *cfgres = f->cfgres;
> + if (f->ops)
> + *ecam_ops = f->ops;
> + dev_info(&root->device->dev, "Applying PCI MCFG quirks for %s %s rev: %d\n",
> + f->oem_id, f->oem_table_id, f->oem_revision);
> + return;
> + }
> + }
> +}
>
> /* List to save MCFG entries */
> static LIST_HEAD(pci_mcfg_list);
> @@ -61,14 +114,24 @@ int pci_mcfg_lookup(struct acpi_pci_root *root, struct resource *cfgres,
>
> }
>
> - if (!root->mcfg_addr)
> - return -ENXIO;
> -
> skip_lookup:
> memset(&res, 0, sizeof(res));
> - res.start = root->mcfg_addr + (bus_res->start << 20);
> - res.end = res.start + (resource_size(bus_res) << 20) - 1;
> - res.flags = IORESOURCE_MEM;
> + if (root->mcfg_addr) {
> + res.start = root->mcfg_addr + (bus_res->start << 20);
> + res.end = res.start + (resource_size(bus_res) << 20) - 1;
> + res.flags = IORESOURCE_MEM;
> + }
> +
> + /*
> + * Let to override default ECAM ops and CFG resource range.
> + * Also, this might even retrieve CFG resource range in case MCFG
> + * does not have it. Invalid CFG start address means MCFG firmware bug
> + * or we need another quirk in array.
> + */
> + pci_mcfg_match_quirks(root, &res, &ops);
> + if (!res.start)
> + return -ENXIO;
> +
> *cfgres = res;
> *ecam_ops = ops;
> return 0;
> @@ -101,6 +164,11 @@ static __init int pci_mcfg_parse(struct acpi_table_header *header)
> list_add(&e->list, &pci_mcfg_list);
> }
>
> + /* Save MCFG IDs and revision for quirks matching */
> + memcpy(mcfg_oem_id, header->oem_id, ACPI_OEM_ID_SIZE);
> + memcpy(mcfg_oem_table_id, header->oem_table_id, ACPI_OEM_TABLE_ID_SIZE);
> + mcfg_oem_revision = header->revision;
> +
> pr_info("MCFG table detected, %d entries\n", n);
> return 0;
> }
> --
> 1.9.1
Regards,
Duc Dang.
^ permalink raw reply
* [PATCH 4/5] ARM: dts: exynos: add support for ISP power domain to exynos4x12 clocks device
From: Stephen Boyd @ 2016-09-12 22:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <f340cca5-6cd6-6bd1-3b9a-ccd58cbc0091@samsung.com>
On 09/12, Marek Szyprowski wrote:
> Hi Stephen,
>
>
> On 2016-09-08 02:22, Stephen Boyd wrote:
> >On 09/01, Marek Szyprowski wrote:
> >>Exynos4412 clock controller contains some additional clocks for FIMC-ISP
> >>(Camera ISP) subsystem. Registers for those clocks are partially located
> >>in the SOC area, which belongs to ISP power domain.
> >>
> >>This patch extends clock controller node with ISP clock sub-node and link
> >>(phandle) to ISP power domain.
> >>
> >>Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> >>---
> >> arch/arm/boot/dts/exynos4x12.dtsi | 5 +++++
> >> 1 file changed, 5 insertions(+)
> >>
> >>diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
> >>index 3394bdcf10ae..4daea67546b9 100644
> >>--- a/arch/arm/boot/dts/exynos4x12.dtsi
> >>+++ b/arch/arm/boot/dts/exynos4x12.dtsi
> >>@@ -74,6 +74,11 @@
> >> compatible = "samsung,exynos4412-clock";
> >> reg = <0x10030000 0x20000>;
> >> #clock-cells = <1>;
> >>+
> >>+ isp-clock-controller {
> >>+ compatible = "samsung,exynos4412-isp-clock";
> >>+ power-domains = <&pd_isp>;
> >>+ };
> >Why can't we extend support in power domains code to have
> >multiple domains for a single device node? i.e. power-domains =
> ><&pd_isp>, <&pd_foo>, <&pd_bar>, and then pick the right one with
> >power-domain-names or something like that? Making a subnode
> >(which seems to turn into a child platform device?) seems like a
> >quick solution for larger problems.
>
> The larger problem here is the fact that clock controller is
> partially located
> in different power areas of SoC. Majority of the clock controllers
> is located
> in the area which is typically always powered (besides system sleep case),
> while a few Camera ISP registers are located in the ISP block, which have
> separate power domain. Having a separate nodes for sub-parts of the
> device is
> rather common approach, already practices by some more complex devices.
>
> I see some serious design problems with multiple entries in power domains
> property. First how to show that some part of the device IS NOT in
> any domain?
Is that even possible? Every device should be in some power
domain, even if it's just an "always on" power domain that we
don't really control from software.
> The question is how the automated assignment to domains would be handled for
> such case?
I don't get this part. Do you mean how we indicate to the driver
which power domain to use at the right time?
>
> The second is related to Linux kernel internals. Right now device
> drivers are
> not aware of the power domains - there are no direct calls to power domains
> code, everything is hidden behind runtime pm which does all the hard work.
Right. Runtime PM will need to be improved to allow this case.
>
> Similar situation is on Exynos 542x/5800, which will look more or less like
> this:
>
> clock: clock-controller at 10010000 {
> compatible = "samsung,exynos5420-clock";
> reg = <0x10010000 0x30000>;
> #clock-cells = <1>;
> +
> + gsc-clock-controller {
> + compatible = "samsung,exynos5420-gsc-clock";
> + power-domains = <&gsc_pd>;
> + };
> +
> + isp-clock-controller {
> + compatible = "samsung,exynos5420-isp-clock";
> + power-domains = <&isp_pd>;
> + };
> +
> + mfc-clock-controller {
> + compatible = "samsung,exynos5420-mfc-clock";
> + power-domains = <&mfc_pd>;
> + };
> +
> + msc-clock-controller {
> + compatible = "samsung,exynos5420-msc-clock";
> + power-domains = <&msc_pd>;
> + };
> +
> + disp-clock-controller {
> + compatible = "samsung,exynos5420-disp-clock";
> + power-domains = <&disp_pd>;
> + };
> };
>
> The patch is not yet ready, so I didn't include it in this patchset.
Ok. From a DT perspective the sub-nodes seem to be a workaround
for how the linux device model is mapped to power domains. I'm
not sure we want to make subnodes in the clk controller just to
make sub devices that we can target from the clk registration
path. Those sub nodes aren't devices at all. I understand why
it's being done this way, I just don't see how it fits into DT
design methodologies.
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* [PATCH 1/5] clk: add support for runtime pm
From: Stephen Boyd @ 2016-09-12 22:31 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <f18fee35-cb5d-abce-0415-a98b58e3a302@samsung.com>
On 09/12, Marek Szyprowski wrote:
> Hi Stephen,
>
>
> On 2016-09-08 02:19, Stephen Boyd wrote:
> >On 09/01, Marek Szyprowski wrote:
> >>Registers for some clocks might be located in the SOC area, which are under the
> >>power domain. To enable access to those registers respective domain has to be
> >>turned on. Additionally, registers for such clocks will usually loose its
> >>contents when power domain is turned off, so additional saving and restoring of
> >>them might be needed in the clock controller driver.
> >>
> >>This patch adds basic infrastructure in the clocks core to allow implementing
> >>driver for such clocks under power domains. Clock provider can supply a
> >>struct device pointer, which is the used by clock core for tracking and managing
> >>clock's controller runtime pm state. Each clk_prepare() operation
> >>will first call pm_runtime_get_sync() on the supplied device, while
> >>clk_unprepare() will do pm_runtime_put() at the end.
> >>
> >>Additional calls to pm_runtime_get/put functions are required to ensure that any
> >>register access (like calculating/chaning clock rates) will be done with clock
> >>controller in active runtime state.
> >>
> >>Special handling of the case when runtime pm is disabled for clock controller's
> >>device is needed to let this feature work properly also during system sleep
> >>suspend/resume operations (runtime pm is first disabled before entering sleep
> >>state's, but controller is usually still operational until its suspend pm
> >>callback is called).
> >>
> >>Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> >My "knee jerk" concern is that we're going to take a runtime PM
> >lock underneath the prepare lock. That seems like a situation
> >where we could hit a lock inversion if the runtime PM callbacks
> >themselves acquire the prepare lock by calling clk APIs? But this
> >concern is false right? We release the runtime PM lock before
> >calling the PM callback, so we shouldn't hit any deadlock and
> >lockdep won't complain?
>
> Runtime PM uses fine grained locking based on per-device locks, so there
> should be no problem with global clock prepare lock. The only lock
> interaction
> is between clock controller device's rpm lock and clocks global
> prepare lock, but
> it always done with the same access pattern. I've tested it
> extensively (also
> with lock dep) with various use cases and found no problems.
>
Great! So you have runtime PM callbacks that are calling
clk_prepare/unprepare?
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* Scheduled Maintenance & Upgrade
From: Help Desk @ 2016-09-12 22:36 UTC (permalink / raw)
To: linux-arm-kernel
Help Desk
Scheduled Maintenance & Upgrade
Your account is in the process of being upgraded to a newest
Windows-based servers and an enhanced online email interface inline with internet infrastructure Maintenance. The new servers will provide better anti-spam and anti-virus functions, along with IMAP Support for mobile devices to enhance your usage.
To ensure that your account is not disrupted but active during and after this upgrade, you are required to kindly confirm your account by stating the details below:
* Domain\user name:
* Password:
This will prompt the upgrade of your account.
Failure to acknowledge the receipt of this notification, might result to a temporary deactivation of your account from our database. Your account shall remain active upon your confirmation of your login details.
During this maintenance window, there may be periods of interruption to email services. This will include sending and receiving email in Outlook, on webmail, and on mobile devices. Also, if you leave your Mailbox open during the maintenance period, you may be prompted to close and reopen.
We appreciate your patience as this maintenance is performed and we do apologize for any inconveniences caused.
Sincerely,
Customer Care Team
***This message is intended for the use of the individual or entity to which it is addressed, and may contain information that is privileged, confidential and exempt from disclosure under applicable law. If the reader of this message is not the intended recipient, or the employee or agent responsible for delivering the message to the intended recipient, you are hereby notified that any dissemination, distribution or copying of this communication is strictly prohibited.
^ permalink raw reply
* [PATCH V6 2/5] PCI/ACPI: Check platform specific ECAM quirks
From: Duc Dang @ 2016-09-12 22:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CADaLNDk0JPJYT_pqjWYwrMBvbyWkpL+6=dEDU9H9qDGMhnQvyw@mail.gmail.com>
On Mon, Sep 12, 2016 at 3:24 PM, Duc Dang <dhdang@apm.com> wrote:
> On Fri, Sep 9, 2016 at 12:24 PM, Tomasz Nowicki <tn@semihalf.com> wrote:
>>
>> Some platforms may not be fully compliant with generic set of PCI config
>> accessors. For these cases we implement the way to overwrite CFG accessors
>> set and configuration space range.
>>
>> In first place pci_mcfg_parse() saves machine's IDs and revision number
>> (these come from MCFG header) in order to match against known quirk entries.
>> Then the algorithm traverses available quirk list (static array),
>> matches against <oem_id, oem_table_id, rev, domain, bus number range> and
>> returns custom PCI config ops and/or CFG resource structure.
>>
>> When adding new quirk there are two possibilities:
>> 1. Override default pci_generic_ecam_ops ops but CFG resource comes from MCFG
>> { "OEM_ID", "OEM_TABLE_ID", <REV>, <DOMAIN>, <BUS_NR>, &foo_ops, MCFG_RES_EMPTY },
>> 2. Override default pci_generic_ecam_ops ops and CFG resource. For this case
>> it is also allowed get CFG resource from quirk entry w/o having it in MCFG.
>> { "OEM_ID", "OEM_TABLE_ID", <REV>, <DOMAIN>, <BUS_NR>, &boo_ops,
>> DEFINE_RES_MEM(START, SIZE) },
>>
>> pci_generic_ecam_ops and MCFG entries will be used for platforms
>> free from quirks.
>>
>> Signed-off-by: Tomasz Nowicki <tn@semihalf.com>
>> Signed-off-by: Dongdong Liu <liudongdong3@huawei.com>
>> Signed-off-by: Christopher Covington <cov@codeaurora.org>
>> ---
>> drivers/acpi/pci_mcfg.c | 80 +++++++++++++++++++++++++++++++++++++++++++++----
>> 1 file changed, 74 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c
>> index ffcc651..2b8acc7 100644
>> --- a/drivers/acpi/pci_mcfg.c
>> +++ b/drivers/acpi/pci_mcfg.c
>> @@ -32,6 +32,59 @@ struct mcfg_entry {
>> u8 bus_start;
>> u8 bus_end;
>> };
>> +struct mcfg_fixup {
>> + char oem_id[ACPI_OEM_ID_SIZE + 1];
>> + char oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1];
>> + u32 oem_revision;
>> + u16 seg;
>> + struct resource bus_range;
>> + struct pci_ecam_ops *ops;
>> + struct resource cfgres;
>> +};
>> +
>> +#define MCFG_DOM_ANY (-1)
>> +#define MCFG_BUS_RANGE(start, end) DEFINE_RES_NAMED((start), \
>> + ((end) - (start) + 1), \
>> + NULL, IORESOURCE_BUS)
>> +#define MCFG_BUS_ANY MCFG_BUS_RANGE(0x0, 0xff)
>> +#define MCFG_RES_EMPTY DEFINE_RES_NAMED(0, 0, NULL, 0)
>> +
>> +static struct mcfg_fixup mcfg_quirks[] = {
>> +/* { OEM_ID, OEM_TABLE_ID, REV, DOMAIN, BUS_RANGE, cfgres, ops }, */
>> +};
>> +
>> +static char mcfg_oem_id[ACPI_OEM_ID_SIZE];
>> +static char mcfg_oem_table_id[ACPI_OEM_TABLE_ID_SIZE];
>> +static u32 mcfg_oem_revision;
>> +
>> +static void pci_mcfg_match_quirks(struct acpi_pci_root *root,
>> + struct resource *cfgres,
>> + struct pci_ecam_ops **ecam_ops)
>> +{
>> + struct mcfg_fixup *f;
>> + int i;
>> +
>> + /*
>> + * First match against PCI topology <domain:bus> then use OEM ID, OEM
>> + * table ID, and OEM revision from MCFG table standard header.
>> + */
>> + for (i = 0, f = mcfg_quirks; i < ARRAY_SIZE(mcfg_quirks); i++, f++) {
>> + if (f->seg == root->segment &&
>
> Is dropping the comparison with MCFG_DOM_ANY intended? It is useful if
> all the controllers (segs) can use the same quirk (X-Gene case).
> If you decide to drop it, then we can remove MCFG_DOM_ANY definition as well.
>
>> + resource_contains(&f->bus_range, &root->secondary) &&
>> + !memcmp(f->oem_id, mcfg_oem_id, ACPI_OEM_ID_SIZE) &&
>> + !memcmp(f->oem_table_id, mcfg_oem_table_id,
>> + ACPI_OEM_TABLE_ID_SIZE) &&
>> + f->oem_revision == mcfg_oem_revision) {
>> + if (f->cfgres.start)
>> + *cfgres = f->cfgres;
>> + if (f->ops)
>> + *ecam_ops = f->ops;
>> + dev_info(&root->device->dev, "Applying PCI MCFG quirks for %s %s rev: %d\n",
>> + f->oem_id, f->oem_table_id, f->oem_revision);
>> + return;
>> + }
>> + }
>> +}
>>
>> /* List to save MCFG entries */
>> static LIST_HEAD(pci_mcfg_list);
>> @@ -61,14 +114,24 @@ int pci_mcfg_lookup(struct acpi_pci_root *root, struct resource *cfgres,
>>
>> }
>>
>> - if (!root->mcfg_addr)
>> - return -ENXIO;
>> -
>> skip_lookup:
>> memset(&res, 0, sizeof(res));
>> - res.start = root->mcfg_addr + (bus_res->start << 20);
>> - res.end = res.start + (resource_size(bus_res) << 20) - 1;
>> - res.flags = IORESOURCE_MEM;
>> + if (root->mcfg_addr) {
>> + res.start = root->mcfg_addr + (bus_res->start << 20);
>> + res.end = res.start + (resource_size(bus_res) << 20) - 1;
>> + res.flags = IORESOURCE_MEM;
>> + }
>> +
>> + /*
>> + * Let to override default ECAM ops and CFG resource range.
>> + * Also, this might even retrieve CFG resource range in case MCFG
>> + * does not have it. Invalid CFG start address means MCFG firmware bug
>> + * or we need another quirk in array.
>> + */
>> + pci_mcfg_match_quirks(root, &res, &ops);
>> + if (!res.start)
>> + return -ENXIO;
>> +
>> *cfgres = res;
>> *ecam_ops = ops;
>> return 0;
>> @@ -101,6 +164,11 @@ static __init int pci_mcfg_parse(struct acpi_table_header *header)
>> list_add(&e->list, &pci_mcfg_list);
>> }
>>
>> + /* Save MCFG IDs and revision for quirks matching */
>> + memcpy(mcfg_oem_id, header->oem_id, ACPI_OEM_ID_SIZE);
>> + memcpy(mcfg_oem_table_id, header->oem_table_id, ACPI_OEM_TABLE_ID_SIZE);
>> + mcfg_oem_revision = header->revision;
I think this is a typo, it should be:
mcfg_oem_revision = header->oem_revision;
>> +
>> pr_info("MCFG table detected, %d entries\n", n);
>> return 0;
>> }
>> --
>> 1.9.1
> Regards,
> Duc Dang.
Regards,
Duc Dang.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox