Re: [PATCH v3 09/24] wfx: add hwio.c/hwio.h
On Tuesday 22 December 2020 16:27:01 CET Greg Kroah-Hartman wrote: > On Tue, Dec 22, 2020 at 05:10:11PM +0200, Kalle Valo wrote: > > Jerome Pouiller writes: > > > > > +/* > > > + * Internal helpers. > > > + * > > > + * About CONFIG_VMAP_STACK: > > > + * When CONFIG_VMAP_STACK is enabled, it is not possible to run DMA on > > > stack > > > + * allocated data. Functions below that work with registers (aka > > > functions > > > + * ending with "32") automatically reallocate buffers with kmalloc. > > > However, > > > + * functions that work with arbitrary length buffers let's caller to > > > handle > > > + * memory location. In doubt, enable CONFIG_DEBUG_SG to detect badly > > > located > > > + * buffer. > > > + */ > > > > This sounds very hacky to me, I have understood that you should never > > use stack with DMA. > > You should never do that because some platforms do not support it, so no > driver should ever try to do that as they do not know what platform they > are running on. Just to be curious, why these platforms don't support DMA in a stack allocated area? If the memory is contiguous (= not vmalloced), correctly aligned and in the first 4GB of physical memory, it should be sufficient, shouldn't? -- Jérôme Pouiller
[PATCH] drm/amdgpu: kref_put() may not require a lock.
kref_put() can be outside of mutex_lock(),and use amdgpu_ctx_put() instead of kref_put(). Signed-off-by: Yejune Deng --- drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 23 +++ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index 0350205..af26ec2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c @@ -282,6 +282,15 @@ static void amdgpu_ctx_do_release(struct kref *ref) amdgpu_ctx_fini(ref); } +int amdgpu_ctx_put(struct amdgpu_ctx *ctx) +{ + if (ctx == NULL) + return -EINVAL; + + kref_put(&ctx->refcount, amdgpu_ctx_do_release); + return 0; +} + static int amdgpu_ctx_free(struct amdgpu_fpriv *fpriv, uint32_t id) { struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr; @@ -289,10 +298,9 @@ static int amdgpu_ctx_free(struct amdgpu_fpriv *fpriv, uint32_t id) mutex_lock(&mgr->lock); ctx = idr_remove(&mgr->ctx_handles, id); - if (ctx) - kref_put(&ctx->refcount, amdgpu_ctx_do_release); mutex_unlock(&mgr->lock); - return ctx ? 0 : -EINVAL; + + return amdgpu_ctx_put(ctx); } static int amdgpu_ctx_query(struct amdgpu_device *adev, @@ -439,15 +447,6 @@ struct amdgpu_ctx *amdgpu_ctx_get(struct amdgpu_fpriv *fpriv, uint32_t id) return ctx; } -int amdgpu_ctx_put(struct amdgpu_ctx *ctx) -{ - if (ctx == NULL) - return -EINVAL; - - kref_put(&ctx->refcount, amdgpu_ctx_do_release); - return 0; -} - void amdgpu_ctx_add_fence(struct amdgpu_ctx *ctx, struct drm_sched_entity *entity, struct dma_fence *fence, uint64_t *handle) -- 1.9.1
Re: [PATCH v5 09/12] media: uvcvideo: Implement UVC_QUIRK_PRIVACY_DURING_STREAM
Hi Ricardo, On Tue, Dec 22, 2020 at 09:04:19PM +0100, Ricardo Ribalda wrote: > On Tue, Dec 22, 2020 at 11:30 AM Laurent Pinchart wrote: > > On Mon, Dec 21, 2020 at 05:48:16PM +0100, Ricardo Ribalda wrote: > > > Some devices, can only read the privacy_pin if the device is > > > > s/devices,/devices/ > > > > > streaming. > > > > > > This patch implement a quirk for such devices, in order to avoid invalid > > > reads and/or spurious events. > > > > > > Signed-off-by: Ricardo Ribalda > > > --- > > > drivers/media/usb/uvc/uvc_driver.c | 57 -- > > > drivers/media/usb/uvc/uvc_queue.c | 3 ++ > > > drivers/media/usb/uvc/uvcvideo.h | 4 +++ > > > 3 files changed, 61 insertions(+), 3 deletions(-) > > > > > > diff --git a/drivers/media/usb/uvc/uvc_driver.c > > > b/drivers/media/usb/uvc/uvc_driver.c > > > index 72516101fdd0..7af37d4bd60a 100644 > > > --- a/drivers/media/usb/uvc/uvc_driver.c > > > +++ b/drivers/media/usb/uvc/uvc_driver.c > > > @@ -7,6 +7,7 @@ > > > */ > > > > > > #include > > > +#include > > > #include > > > #include > > > #include > > > @@ -1472,6 +1473,17 @@ static int uvc_parse_control(struct uvc_device > > > *dev) > > > /* > > > - > > > * Privacy GPIO > > > */ > > > > There should be a blank line here. > > > > > +static bool uvc_gpio_is_streaming(struct uvc_device *dev) > > > +{ > > > + struct uvc_streaming *streaming; > > > + > > > + list_for_each_entry(streaming, &dev->streams, list) { > > > + if (uvc_queue_streaming(&streaming->queue)) > > > + return true; > > > + } > > > + > > > + return false; > > > +} > > > > > > > > > > But not too blank lines here. > > > > > static u8 uvc_gpio_update_value(struct uvc_device *dev, > > > @@ -1499,7 +1511,12 @@ static int uvc_gpio_get_cur(struct uvc_device > > > *dev, struct uvc_entity *entity, > > > if (cs != UVC_CT_PRIVACY_CONTROL || size < 1) > > > return -EINVAL; > > > > > > + if ((dev->quirks & UVC_QUIRK_PRIVACY_DURING_STREAM) && > > > + !uvc_gpio_is_streaming(dev)) > > > + return -EBUSY; > > > + > > > *(uint8_t *)data = uvc_gpio_update_value(dev, entity); > > > + > > > return 0; > > > } > > > > > > @@ -1528,19 +1545,50 @@ static struct uvc_entity > > > *uvc_gpio_find_entity(struct uvc_device *dev) > > > return NULL; > > > } > > > > > > -static irqreturn_t uvc_gpio_irq(int irq, void *data) > > > +void uvc_privacy_gpio_event(struct uvc_device *dev) > > > { > > > - struct uvc_device *dev = data; > > > struct uvc_entity *unit; > > > > > > + > > > unit = uvc_gpio_find_entity(dev); > > > if (!unit) > > > - return IRQ_HANDLED; > > > + return; > > > > > > uvc_gpio_update_value(dev, unit); > > > +} > > > + > > > +static irqreturn_t uvc_gpio_irq(int irq, void *data) > > > +{ > > > + struct uvc_device *dev = data; > > > + > > > + /* Ignore privacy events during streamoff */ > > > + if (dev->quirks & UVC_QUIRK_PRIVACY_DURING_STREAM) > > > + if (!uvc_gpio_is_streaming(dev)) > > > + return IRQ_HANDLED; > > > > I'm still a bit concerned of race conditions. When stopping the stream, > > vb2_queue.streaming is set to 0 after calling the driver's .stop_stream() > > handler. This means that the device will cut power before > > uvc_gpio_is_streaming() can detect that streaming has stopped, and the > > GPIO could thus trigger an IRQ. > > On the affected devices I have not seen this. I guess it takes some > time to discharge. Anyway I am implementing a workaround. Tell me if > it is too ugly. > > > You mentioned that devices have a pull-up or pull-down on the GPIO line. > > As there are only two devices affected, do you know if it's a pull-up or > > pull-down ? Would it be worse to expose that state to userspace than to > > return -EBUSY when reading the control ? > > The module has a 100K pull up. This is, it will return "Privacy = 0". > > We cannot return the default value, as it would make the user believe > that the privacy is in a different state that currently is. > In other words, userspace needs to know at all times if the privacy is > in : unknow_state, on, off. This seems to be the core of the issue: we're trying to shove 3 states into a boolean. Would this call for turning the V4L2_CID_PRIVACY control into a menu ? Or maybe setting V4L2_CTRL_FLAG_INACTIVE ? Returning -EBUSY when the control is read while not streaming, and not generating an event that tells the control value becomes unknown, seems like a hack designed to work with a single userspace implementation. As the rest of the series is getting ready, I'd propose merging it without this patch until we figure out what should be done to support these lovely devices. Would that work for you ? > > > + > > > + uvc_privacy_gpio_event(dev); > > > + > > > return
Re: [dm-devel] DM's filesystem lookup in dm_get_dev_t() [was: Re: linux-next: manual merge of the device-mapper tree with Linus' tree]
On Tue, Dec 22, 2020 at 09:06:04PM +, Alasdair G Kergon wrote: > I have not read the background about whatever the new problem is - I'm > jumping in cold seeing this message - but from the very beginning of > device-mapper we have strongly recommended that userspace supplies the > block device in the form MAJOR:MINOR and all our own tools do that. We > guarantee not to deadlock in these places when this is done. > > We also accept the device in the form of a path name as we know there > are times when this is safe and convenient, but then we offer no > guarantees - we place the responsibility upon userspace only to do this > when it knows it is safe to do so i.e. no race and no deadlock. 644bda6f346038bce7ad3ed48f7044c10dde6d47 changes that by accepting all kinds of weirdo formats :(
Re: DM's filesystem lookup in dm_get_dev_t() [was: Re: linux-next: manual merge of the device-mapper tree with Linus' tree]
On Tue, Dec 22, 2020 at 06:24:09PM +0100, Hannes Reinecke wrote: > Ok. The problem from my perspective is that device-mapper needs to > a) ensure that the arbitrary string passed in with the table definition > refers to a valid block device > and > b) the block device can be opened with O_EXCL, so that device-mapper can > then use it. > > Originally (ie prior to commit 644bda6f3460) dm_get_device() just converted > the string to a 'dev_t' representation, and then the block device itself > was checked and opened in dm_get_table_device(). > 'lookup_bdev' was just being used to convert the path if the string was not > in the canonical major:minor format, as then it was assumed that it > referred to a block device node, and then lookup_bdev kinda makes sense. Yes, 644bda6f3460 is the cause of all evil, as it uses an API in a place where it should not be used. It and the prep patch (e6e20a7a5f3f49bfee518d5c6849107398d83912) which did the grave mistake of making name_to_dev_t available outside of the early init code really need to be reverted. > However, lookup_bdev() now always recurses into the filesystem, causing > multipath to stall in an all-paths-down scenario. lookup_bdev always did a file system lookup, and always only accepted a valid name in the file system. > Alternatively, if Mike says that only major:minor is the valid format for a > table definition we can kill that code completely. But clearly _I_ cannot > make the call here. Before 644bda6f3460 the table definitions only accepted a valid name in the file system. Which is the proper interface.
Re: [PATCH] staging: comedi: correct spelling mistakes of I/O port base address
On Wed, Dec 23, 2020 at 10:26:23AM +0800, chensong wrote: > "base" was double input in comment line "I/O port base > address", remove one of them. > > Signed-off-by: chensong > --- > drivers/staging/comedi/drivers/dt2815.c | 2 +- > drivers/staging/comedi/drivers/dt2817.c | 2 +- > 2 files changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/staging/comedi/drivers/dt2815.c > b/drivers/staging/comedi/drivers/dt2815.c > index 5906f32..2be2406 100644 > --- a/drivers/staging/comedi/drivers/dt2815.c > +++ b/drivers/staging/comedi/drivers/dt2815.c > @@ -17,7 +17,7 @@ > * contrary, please update. > * > * Configuration options: > - * [0] - I/O port base base address > + * [0] - I/O port base address > * [1] - IRQ (unused) > * [2] - Voltage unipolar/bipolar configuration > * 0 == unipolar 5V (0V -- +5V) > diff --git a/drivers/staging/comedi/drivers/dt2817.c > b/drivers/staging/comedi/drivers/dt2817.c > index 7c1463e..a173394 100644 > --- a/drivers/staging/comedi/drivers/dt2817.c > +++ b/drivers/staging/comedi/drivers/dt2817.c > @@ -21,7 +21,7 @@ > * with 32 channels, configurable in groups of 8. > * > * Configuration options: > - * [0] - I/O port base base address > + * [0] - I/O port base address I think the original is correct here. thanks, greg k-h
Re: [PATCH] staging: comedi: remove warnings of comedi_lrange
On Wed, Dec 23, 2020 at 10:24:23AM +0800, chensong wrote: > Checkpatch.pl reports "warning: struct comedi_lrange should > normally be const" in some places, which are supposed to > be removed. > > Signed-off-by: chensong > --- > drivers/staging/comedi/drivers/das16.c | 4 ++-- > drivers/staging/comedi/drivers/jr3_pci.c | 4 ++-- > drivers/staging/comedi/drivers/ni_670x.c | 2 +- > 3 files changed, 5 insertions(+), 5 deletions(-) > > diff --git a/drivers/staging/comedi/drivers/das16.c > b/drivers/staging/comedi/drivers/das16.c > index 4ac2622..40bfd84 100644 > --- a/drivers/staging/comedi/drivers/das16.c > +++ b/drivers/staging/comedi/drivers/das16.c > @@ -958,7 +958,7 @@ static const struct comedi_lrange *das16_ai_range(struct > comedi_device *dev, > > /* get any user-defined input range */ > if (pg_type == das16_pg_none && (min || max)) { > - struct comedi_lrange *lrange; > + const struct comedi_lrange *lrange; > struct comedi_krange *krange; > > /* allocate single-range range table */ > @@ -992,7 +992,7 @@ static const struct comedi_lrange *das16_ao_range(struct > comedi_device *dev, > > /* get any user-defined output range */ > if (min || max) { > - struct comedi_lrange *lrange; > + const struct comedi_lrange *lrange; > struct comedi_krange *krange; > > /* allocate single-range range table */ > diff --git a/drivers/staging/comedi/drivers/jr3_pci.c > b/drivers/staging/comedi/drivers/jr3_pci.c > index 7a02c4f..c35db0b 100644 > --- a/drivers/staging/comedi/drivers/jr3_pci.c > +++ b/drivers/staging/comedi/drivers/jr3_pci.c > @@ -91,8 +91,8 @@ struct jr3_pci_dev_private { > }; > > union jr3_pci_single_range { > - struct comedi_lrange l; > - char _reserved[offsetof(struct comedi_lrange, range[1])]; > + const struct comedi_lrange l; > + char _reserved[offsetof(const struct comedi_lrange, range[1])]; > }; > > enum jr3_pci_poll_state { > diff --git a/drivers/staging/comedi/drivers/ni_670x.c > b/drivers/staging/comedi/drivers/ni_670x.c > index c197e47..66485ec 100644 > --- a/drivers/staging/comedi/drivers/ni_670x.c > +++ b/drivers/staging/comedi/drivers/ni_670x.c > @@ -200,7 +200,7 @@ static int ni_670x_auto_attach(struct comedi_device *dev, > const struct comedi_lrange **range_table_list; > > range_table_list = kmalloc_array(32, > - sizeof(struct comedi_lrange *), > + sizeof(const struct > comedi_lrange *), >GFP_KERNEL); > if (!range_table_list) > return -ENOMEM; > -- > 2.7.4 > Hi, This is the friendly patch-bot of Greg Kroah-Hartman. You have sent him a patch that has triggered this response. He used to manually respond to these common problems, but in order to save his sanity (he kept writing the same thing over and over, yet to different people), I was created. Hopefully you will not take offence and will fix the problem in your patch and resubmit it so that it can be accepted into the Linux kernel tree. You are receiving this message because of the following common error(s) as indicated below: - It looks like you did not use your "real" name for the patch on either the Signed-off-by: line, or the From: line (both of which have to match). Please read the kernel file, Documentation/SubmittingPatches for how to do this correctly. If you wish to discuss this problem further, or you have questions about how to resolve this issue, please feel free to respond to this email and Greg will reply once he has dug out from the pending patches received from other developers. thanks, greg k-h's patch email bot
[PATCH v3 0/1] mm: memmap defer init dosn't work as expected
Post the regression fix in a standalone patch as Andrew suggested for -stable branch better back porting. This is rebased on the latest master branch of mainline kenrel, surely there's almost no change comparing with v2. https://lore.kernel.org/linux-mm/20201220082754.6900-1-...@redhat.com/ Tested on a system with 24G ram as below, adding 'memmap=128M!0x5' to split the one ram region into two regions in numa node1 to simulate the scenario of VMware. [ +0.00] BIOS-provided physical RAM map: [ +0.00] BIOS-e820: [mem 0x-0x0009bfff] usable [ +0.00] BIOS-e820: [mem 0x0009c000-0x0009] reserved [ +0.00] BIOS-e820: [mem 0x000e-0x000f] reserved [ +0.00] BIOS-e820: [mem 0x0010-0x6cdcefff] usable [ +0.00] BIOS-e820: [mem 0x6cdcf000-0x6efcefff] reserved [ +0.00] BIOS-e820: [mem 0x6efcf000-0x6fdfefff] ACPI NVS [ +0.00] BIOS-e820: [mem 0x6fdff000-0x6fffefff] ACPI data [ +0.00] BIOS-e820: [mem 0x6000-0x6fff] usable [ +0.00] BIOS-e820: [mem 0x7000-0x8fff] reserved [ +0.00] BIOS-e820: [mem 0xe000-0x] reserved [ +0.00] BIOS-e820: [mem 0x0001-0x00067f1f] usable [ +0.00] BIOS-e820: [mem 0x00067f20-0x00067fff] reserved Test passed as below. As you can see, with patch applied, memmap init will cost much less time on numa node 1: Without the patch: [0.065029] Early memory node ranges [0.065030] node 0: [mem 0x1000-0x0009bfff] [0.065032] node 0: [mem 0x0010-0x6cdcefff] [0.065034] node 0: [mem 0x6000-0x6fff] [0.065036] node 0: [mem 0x0001-0x00027fff] [0.065038] node 1: [mem 0x00028000-0x0004] [0.065040] node 1: [mem 0x00050800-0x00067f1f] [0.065185] Zeroed struct page in unavailable ranges: 16533 pages [0.065187] Initmem setup node 0 [mem 0x1000-0x00027fff] [0.069616] Initmem setup node 1 [mem 0x00028000-0x00067f1f] [0.096298] ACPI: PM-Timer IO Port: 0x408 With the patch applied: [0.065029] Early memory node ranges [0.065030] node 0: [mem 0x1000-0x0009bfff] [0.065032] node 0: [mem 0x0010-0x6cdcefff] [0.065034] node 0: [mem 0x6000-0x6fff] [0.065036] node 0: [mem 0x0001-0x00027fff] [0.065038] node 1: [mem 0x00028000-0x0004] [0.065041] node 1: [mem 0x00050800-0x00067f1f] [0.065187] Zeroed struct page in unavailable ranges: 16533 pages [0.065189] Initmem setup node 0 [mem 0x1000-0x00027fff] [0.069572] Initmem setup node 1 [mem 0x00028000-0x00067f1f] [0.070161] ACPI: PM-Timer IO Port: 0x408 Baoquan He (1): mm: memmap defer init dosn't work as expected arch/ia64/mm/init.c | 4 ++-- include/linux/mm.h | 5 +++-- mm/memory_hotplug.c | 2 +- mm/page_alloc.c | 8 +--- 4 files changed, 11 insertions(+), 8 deletions(-) -- 2.17.2
[PATCH v3 1/1] mm: memmap defer init dosn't work as expected
VMware observed a performance regression during memmap init on their platform, and bisected to commit 73a6e474cb376 ("mm: memmap_init: iterate over memblock regions rather that check each PFN") causing it. Before the commit: [0.033176] Normal zone: 1445888 pages used for memmap [0.033176] Normal zone: 89391104 pages, LIFO batch:63 [0.035851] ACPI: PM-Timer IO Port: 0x448 With commit [0.026874] Normal zone: 1445888 pages used for memmap [0.026875] Normal zone: 89391104 pages, LIFO batch:63 [2.028450] ACPI: PM-Timer IO Port: 0x448 The root cause is the current memmap defer init doesn't work as expected. Before, memmap_init_zone() was used to do memmap init of one whole zone, to initialize all low zones of one numa node, but defer memmap init of the last zone in that numa node. However, since commit 73a6e474cb376, function memmap_init() is adapted to iterater over memblock regions inside one zone, then call memmap_init_zone() to do memmap init for each region. E.g, on VMware's system, the memory layout is as below, there are two memory regions in node 2. The current code will mistakenly initialize the whole 1st region [mem 0xab-0xfc], then do memmap defer to iniatialize only one memmory section on the 2nd region [mem 0x100-0x1033fff]. In fact, we only expect to see that there's only one memory section's memmap initialized. That's why more time is costed at the time. [0.008842] ACPI: SRAT: Node 0 PXM 0 [mem 0x-0x0009] [0.008842] ACPI: SRAT: Node 0 PXM 0 [mem 0x0010-0xbfff] [0.008843] ACPI: SRAT: Node 0 PXM 0 [mem 0x1-0x55] [0.008844] ACPI: SRAT: Node 1 PXM 1 [mem 0x56-0xaa] [0.008844] ACPI: SRAT: Node 2 PXM 2 [mem 0xab-0xfc] [0.008845] ACPI: SRAT: Node 2 PXM 2 [mem 0x100-0x1033fff] Now, let's add a parameter 'zone_end_pfn' to memmap_init_zone() to pass down the real zone end pfn so that defer_init() can use it to judge whether defer need be taken in zone wide. Fixes: commit 73a6e474cb376 ("mm: memmap_init: iterate over memblock regions rather that check each PFN") Reported-by: Rahul Gopakumar Signed-off-by: Baoquan He Reviewed-by: Mike Rapoport Cc: sta...@vger.kernel.org --- arch/ia64/mm/init.c | 4 ++-- include/linux/mm.h | 5 +++-- mm/memory_hotplug.c | 2 +- mm/page_alloc.c | 8 +--- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index 9b5acf8fb092..e76386a3479e 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c @@ -536,7 +536,7 @@ virtual_memmap_init(u64 start, u64 end, void *arg) if (map_start < map_end) memmap_init_zone((unsigned long)(map_end - map_start), -args->nid, args->zone, page_to_pfn(map_start), +args->nid, args->zone, page_to_pfn(map_start), page_to_pfn(map_end), MEMINIT_EARLY, NULL, MIGRATE_MOVABLE); return 0; } @@ -546,7 +546,7 @@ memmap_init (unsigned long size, int nid, unsigned long zone, unsigned long start_pfn) { if (!vmem_map) { - memmap_init_zone(size, nid, zone, start_pfn, + memmap_init_zone(size, nid, zone, start_pfn, start_pfn + size, MEMINIT_EARLY, NULL, MIGRATE_MOVABLE); } else { struct page *start; diff --git a/include/linux/mm.h b/include/linux/mm.h index 5299b90a6c40..af0d3a8d77f7 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2432,8 +2432,9 @@ extern int __meminit early_pfn_to_nid(unsigned long pfn); #endif extern void set_dma_reserve(unsigned long new_dma_reserve); -extern void memmap_init_zone(unsigned long, int, unsigned long, unsigned long, - enum meminit_context, struct vmem_altmap *, int migratetype); +extern void memmap_init_zone(unsigned long, int, unsigned long, + unsigned long, unsigned long, enum meminit_context, + struct vmem_altmap *, int migratetype); extern void setup_per_zone_wmarks(void); extern int __meminit init_per_zone_wmark_min(void); extern void mem_init(void); diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index c01604224299..789fceb4f2d5 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -713,7 +713,7 @@ void __ref move_pfn_range_to_zone(struct zone *zone, unsigned long start_pfn, * expects the zone spans the pfn range. All the pages in the range * are reserved so nobody should be touching them so we should be safe */ - memmap_init_zone(nr_pages, nid, zone_idx(zone), start_pfn, + memmap_init_zone(nr_pages, nid, zone_idx(zone), start_pfn, 0, MEMINIT_HOTPLUG, altmap, migratetype); set_zone_contiguous(zone); diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 7a2c89b21115..bdbec4c98173 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.
Re: [PATCH v3 09/24] wfx: add hwio.c/hwio.h
On Wed, Dec 23, 2020 at 09:01:33AM +0100, Jérôme Pouiller wrote: > On Tuesday 22 December 2020 16:27:01 CET Greg Kroah-Hartman wrote: > > On Tue, Dec 22, 2020 at 05:10:11PM +0200, Kalle Valo wrote: > > > Jerome Pouiller writes: > > > > > > > +/* > > > > + * Internal helpers. > > > > + * > > > > + * About CONFIG_VMAP_STACK: > > > > + * When CONFIG_VMAP_STACK is enabled, it is not possible to run DMA on > > > > stack > > > > + * allocated data. Functions below that work with registers (aka > > > > functions > > > > + * ending with "32") automatically reallocate buffers with kmalloc. > > > > However, > > > > + * functions that work with arbitrary length buffers let's caller to > > > > handle > > > > + * memory location. In doubt, enable CONFIG_DEBUG_SG to detect badly > > > > located > > > > + * buffer. > > > > + */ > > > > > > This sounds very hacky to me, I have understood that you should never > > > use stack with DMA. > > > > You should never do that because some platforms do not support it, so no > > driver should ever try to do that as they do not know what platform they > > are running on. > > Just to be curious, why these platforms don't support DMA in a stack > allocated area? Hardware is odd :( > If the memory is contiguous (= not vmalloced), correctly > aligned and in the first 4GB of physical memory, it should be sufficient, > shouldn't? Nope, sorry, this just does not work at all on many platforms. thanks, greg k-h
Re: [PATCH v3 4/7] power: supply: max8997_charger: Set CHARGER current limit
On Tue, 22 Dec 2020 09:40:04 +0100, Krzysztof Kozlowski wrote: > On Tue, Dec 22, 2020 at 07:31:40AM +, Timon Baetz wrote: > > Register for extcon notification and set charging current depending on > > the detected cable type. Current values are taken from vendor kernel, > > where most charger types end up setting 650mA [0]. > > > > Also enable and disable the CHARGER regulator based on extcon events. > > > > [0] > > https://github.com/krzk/linux-vendor-backup/blob/samsung/galaxy-s2-epic-4g-touch-sph-d710-exynos4210-dump/drivers/misc/max8997-muic.c#L1675-L1678 > > > > Signed-off-by: Timon Baetz > > --- > > drivers/power/supply/max8997_charger.c | 94 ++ > > 1 file changed, 94 insertions(+) > > > > diff --git a/drivers/power/supply/max8997_charger.c > > b/drivers/power/supply/max8997_charger.c > > index 1947af25879a..67314ae0 100644 > > --- a/drivers/power/supply/max8997_charger.c > > +++ b/drivers/power/supply/max8997_charger.c > > @@ -6,12 +6,14 @@ > > // MyungJoo Ham > > > > #include > > +#include > > #include > > #include > > #include > > #include > > #include > > #include > > +#include > > > > /* MAX8997_REG_STATUS4 */ > > #define DCINOK_SHIFT 1 > > @@ -31,6 +33,10 @@ struct charger_data { > > struct device *dev; > > struct max8997_dev *iodev; > > struct power_supply *battery; > > + struct regulator *reg; > > + struct extcon_dev *edev; > > + struct notifier_block extcon_nb; > > + struct work_struct extcon_work; > > }; > > > > static enum power_supply_property max8997_battery_props[] = { > > @@ -88,6 +94,67 @@ static int max8997_battery_get_property(struct > > power_supply *psy, > > return 0; > > } > > > > +static void max8997_battery_extcon_evt_stop_work(void *data) > > +{ > > + struct charger_data *charger = data; > > + > > + cancel_work_sync(&charger->extcon_work); > > +} > > + > > +static void max8997_battery_extcon_evt_worker(struct work_struct *work) > > +{ > > + struct charger_data *charger = > > + container_of(work, struct charger_data, extcon_work); > > + struct extcon_dev *edev = charger->edev; > > + int current_limit; > > + > > + if (extcon_get_state(edev, EXTCON_CHG_USB_SDP) > 0) { > > + dev_dbg(charger->dev, "USB SDP charger is connected\n"); > > + current_limit = 45; > > + } else if (extcon_get_state(edev, EXTCON_CHG_USB_DCP) > 0) { > > + dev_dbg(charger->dev, "USB DCP charger is connected\n"); > > + current_limit = 65; > > + } else if (extcon_get_state(edev, EXTCON_CHG_USB_FAST) > 0) { > > + dev_dbg(charger->dev, "USB FAST charger is connected\n"); > > + current_limit = 65; > > + } else if (extcon_get_state(edev, EXTCON_CHG_USB_SLOW) > 0) { > > + dev_dbg(charger->dev, "USB SLOW charger is connected\n"); > > + current_limit = 65; > > + } else if (extcon_get_state(edev, EXTCON_CHG_USB_CDP) > 0) { > > + dev_dbg(charger->dev, "USB CDP charger is connected\n"); > > + current_limit = 65; > > + } else { > > + dev_dbg(charger->dev, "USB charger is diconnected\n"); > > + current_limit = -1; > > + } > > + > > + if (current_limit > 0) { > > + int ret = regulator_set_current_limit(charger->reg, > > current_limit, current_limit); > > + > > + if (ret) { > > + dev_err(charger->dev, "failed to set current limit: > > %d\n", ret); > > + return; > > + } > > + ret = regulator_enable(charger->reg); > > + if (ret) > > + dev_err(charger->dev, "failed to enable regulator: > > %d\n", ret); > > + } else { > > + int ret = regulator_disable(charger->reg); > > + > > + if (ret) > > + dev_err(charger->dev, "failed to disable regulator: > > %d\n", ret); > > + } > > +} > > + > > +static int max8997_battery_extcon_evt(struct notifier_block *nb, > > + unsigned long event, void *param) > > +{ > > + struct charger_data *charger = > > + container_of(nb, struct charger_data, extcon_nb); > > + schedule_work(&charger->extcon_work); > > + return NOTIFY_OK; > > +} > > + > > static const struct power_supply_desc max8997_battery_desc = { > > .name = "max8997_pmic", > > .type = POWER_SUPPLY_TYPE_BATTERY, > > @@ -170,6 +237,33 @@ static int max8997_battery_probe(struct > > platform_device *pdev) > > return PTR_ERR(charger->battery); > > } > > > > + charger->reg = devm_regulator_get(&pdev->dev, "charger"); > > The code looks good but isn't it breaking all existing platforms? So there is 2 other DTS in the kernel sources that are using MAX8997 pmic: - Insignal Origen evaluation board - Samsung Trats Non of them have charging regulators. Also probing of the charger has been failing for long time because of https://lore.kernel.org
Re: [PATCH] staging: comedi: clean up debugging code in #if 0 or 1
On Wed, Dec 23, 2020 at 10:20:44AM +0800, chensong wrote: > There are a log of "#if 0" or "#if 1" in comedi driver which > cause warning when running checkpatch.pl, they are supposed to > be cleaned up before release. > > Signed-off-by: chensong Hi, This is the friendly patch-bot of Greg Kroah-Hartman. You have sent him a patch that has triggered this response. He used to manually respond to these common problems, but in order to save his sanity (he kept writing the same thing over and over, yet to different people), I was created. Hopefully you will not take offence and will fix the problem in your patch and resubmit it so that it can be accepted into the Linux kernel tree. You are receiving this message because of the following common error(s) as indicated below: - It looks like you did not use your "real" name for the patch on either the Signed-off-by: line, or the From: line (both of which have to match). Please read the kernel file, Documentation/SubmittingPatches for how to do this correctly. If you wish to discuss this problem further, or you have questions about how to resolve this issue, please feel free to respond to this email and Greg will reply once he has dug out from the pending patches received from other developers. thanks, greg k-h's patch email bot
Re: [RESEND] usb: dwc3: meson-g12a: disable clk on error handling path in probe
On Wed, Dec 23, 2020 at 10:13:03AM +0800, Zheng Zengkai wrote: > Hi everyone, > > Friendly ping: > > Just want to know why this patch was ignored, Right now it is the merge window and we can't do anything with any patches until 5.11-rc1 is out. After that happens, I'll work on catching up on older patches like this. thanks, greg k-h
Re: [PATCH v2 0/5] Fix the incorrect memmep defer init handling and do some cleanup
On 12/23/20 at 10:05am, Baoquan He wrote: > On 12/22/20 at 05:46pm, Andrew Morton wrote: > > On Sun, 20 Dec 2020 16:27:49 +0800 Baoquan He wrote: > > > > > VMware reported the performance regression during memmap_init() > > > invocation. > > > And they bisected to commit 73a6e474cb376 ("mm: memmap_init: iterate over > > > memblock regions rather that check each PFN") causing it. > > > > > > https://lore.kernel.org/linux-mm/dm6pr05mb52921ff90fa01cc337dd23a1a4...@dm6pr05mb5292.namprd05.prod.outlook.com/ > > > > > > After investigation, it's caused by incorrect memmap init defer handling > > > in memmap_init_zone() after commit 73a6e474cb376. The current > > > memmap_init_zone() only handle one memory region of one zone, while > > > memmap_init() iterates over all its memory regions and pass them one by > > > one into memmap_init_zone() to handle. > > > > > > So in this patchset, patch 1/5 fixes the bug observed by VMware. Patch > > > 2~5/5 clean up codes. > > > accordingly. > > > > This series doesn't apply well to current mainline (plus, perhaps, > > material which I sent to Linus today). > > > > So please check all that against mainline in a day or so, refresh, > > retest and resend. > > > > Please separate the fix for the performance regression (1/5) into a > > single standalone patch, ready for -stable backporting. And then a > > separate 4-patch series with the cleanups for a 5.11 merge. Have sent the 1/5 as a standalone patch. Will send the rest 4 patches as a patchset once the patch 1/5 is merged into linux-next. Thanks, Andrew. > > Sure, doing now. > > By the way, when sending patches to linux-mm ML, which branch should I > rebase them on? I usually take your akpm/master as base, thought this > will make your patch picking easier. Seems my understanding is not true, > akpm/master is changed very soon, we should always base patch on linus's > master branch, whether patch is sending to linux-mm or not, right?
Re: [PATCH] blokc/blk-merge: remove the next_bvec label in __blk_bios_map_sg()linux-bl...@vger.kernel.org (open list:BLOCK LAYER)
Hi, all: Please ignore this change, i will resend a patch V2 later.
Re: [PATCH v5 04/27] dt-bindings: memory: mediatek: Add domain definition
Hi Yong, On Wed, Dec 09, 2020 at 04:00:39PM +0800, Yong Wu wrote: > In the latest SoC, there are several HW IP require a sepecial iova > range, mainly CCU and VPU has this requirement. Take CCU as a example, > CCU require its iova locate in the range(0x4000_ ~ 0x43ff_). Is this really a domain? Does the address range come from the design of the IOMMU? Best regards, Tomasz > > In this patch we add a domain definition for the special port. In the > example of CCU, If we preassign CCU port in domain1, then iommu driver > will prepare a independent iommu domain of the special iova range for it, > then the iova got from dma_alloc_attrs(ccu-dev) will locate in its special > range. > > This is a preparing patch for multi-domain support. > > Signed-off-by: Yong Wu > Acked-by: Krzysztof Kozlowski > Acked-by: Rob Herring > --- > include/dt-bindings/memory/mtk-smi-larb-port.h | 9 - > 1 file changed, 8 insertions(+), 1 deletion(-) > > diff --git a/include/dt-bindings/memory/mtk-smi-larb-port.h > b/include/dt-bindings/memory/mtk-smi-larb-port.h > index 7d64103209af..2d4c973c174f 100644 > --- a/include/dt-bindings/memory/mtk-smi-larb-port.h > +++ b/include/dt-bindings/memory/mtk-smi-larb-port.h > @@ -7,9 +7,16 @@ > #define __DT_BINDINGS_MEMORY_MTK_MEMORY_PORT_H_ > > #define MTK_LARB_NR_MAX 32 > +#define MTK_M4U_DOM_NR_MAX 8 > + > +#define MTK_M4U_DOM_ID(domid, larb, port)\ > + (((domid) & 0x7) << 16 | (((larb) & 0x1f) << 5) | ((port) & 0x1f)) > + > +/* The default dom id is 0. */ > +#define MTK_M4U_ID(larb, port) MTK_M4U_DOM_ID(0, larb, port) > > -#define MTK_M4U_ID(larb, port) (((larb) << 5) | (port)) > #define MTK_M4U_TO_LARB(id) (((id) >> 5) & 0x1f) > #define MTK_M4U_TO_PORT(id) ((id) & 0x1f) > +#define MTK_M4U_TO_DOM(id) (((id) >> 16) & 0x7) > > #endif > -- > 2.18.0 > > ___ > iommu mailing list > io...@lists.linux-foundation.org > https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v5 06/27] dt-bindings: mediatek: Add binding for mt8192 IOMMU
On Wed, Dec 09, 2020 at 04:00:41PM +0800, Yong Wu wrote: > This patch adds decriptions for mt8192 IOMMU and SMI. > > mt8192 also is MTK IOMMU gen2 which uses ARM Short-Descriptor translation > table format. The M4U-SMI HW diagram is as below: > > EMI >| > M4U >| > >SMI Common > >| > +---+--+--+--+---+ > | | | | .. | | > | | | | | | > larb0 larb1 larb2 larb4 .. larb19 larb20 > disp0 disp1 mdpvdec IPE IPE > > All the connections are HW fixed, SW can NOT adjust it. > > mt8192 M4U support 0~16GB iova range. we preassign different engines > into different iova ranges: > > domain-id module iova-range larbs >0 disp0 ~ 4G larb0/1 >1 vcodec 4G ~ 8G larb4/5/7 >2 cam/mdp 8G ~ 12G larb2/9/11/13/14/16/17/18/19/20 Why do we preassign these addresses in DT? Shouldn't it be a user's or integrator's decision to split the 16 GB address range into sub-ranges and define which larbs those sub-ranges are shared with? Best regards, Tomasz >3 CCU00x4000_ ~ 0x43ff_ larb13: port 9/10 >4 CCU10x4400_ ~ 0x47ff_ larb14: port 4/5 > > The iova range for CCU0/1(camera control unit) is HW requirement. > > Signed-off-by: Yong Wu > Reviewed-by: Rob Herring > --- > .../bindings/iommu/mediatek,iommu.yaml| 18 +- > include/dt-bindings/memory/mt8192-larb-port.h | 240 ++ > 2 files changed, 257 insertions(+), 1 deletion(-) > create mode 100644 include/dt-bindings/memory/mt8192-larb-port.h > > diff --git a/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml > b/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml > index ba6626347381..0f26fe14c8e2 100644 > --- a/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml > +++ b/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml > @@ -76,6 +76,7 @@ properties: >- mediatek,mt8167-m4u # generation two >- mediatek,mt8173-m4u # generation two >- mediatek,mt8183-m4u # generation two > + - mediatek,mt8192-m4u # generation two > >- description: mt7623 generation one > items: > @@ -115,7 +116,11 @@ properties: >dt-binding/memory/mt6779-larb-port.h for mt6779, >dt-binding/memory/mt8167-larb-port.h for mt8167, >dt-binding/memory/mt8173-larb-port.h for mt8173, > - dt-binding/memory/mt8183-larb-port.h for mt8183. > + dt-binding/memory/mt8183-larb-port.h for mt8183, > + dt-binding/memory/mt8192-larb-port.h for mt8192. > + > + power-domains: > +maxItems: 1 > > required: >- compatible > @@ -133,11 +138,22 @@ allOf: >- mediatek,mt2701-m4u >- mediatek,mt2712-m4u >- mediatek,mt8173-m4u > + - mediatek,mt8192-m4u > > then: >required: > - clocks > > + - if: > + properties: > +compatible: > + enum: > +- mediatek,mt8192-m4u > + > +then: > + required: > +- power-domains > + > additionalProperties: false > > examples: > diff --git a/include/dt-bindings/memory/mt8192-larb-port.h > b/include/dt-bindings/memory/mt8192-larb-port.h > new file mode 100644 > index ..ec1ac2ba7094 > --- /dev/null > +++ b/include/dt-bindings/memory/mt8192-larb-port.h > @@ -0,0 +1,240 @@ > +/* SPDX-License-Identifier: GPL-2.0-only */ > +/* > + * Copyright (c) 2020 MediaTek Inc. > + * > + * Author: Chao Hao > + * Author: Yong Wu > + */ > +#ifndef _DT_BINDINGS_MEMORY_MT8192_LARB_PORT_H_ > +#define _DT_BINDINGS_MEMORY_MT8192_LARB_PORT_H_ > + > +#include > + > +/* > + * MM IOMMU: > + * domain 0: display: larb0, larb1. > + * domain 1: vcodec: larb4, larb5, larb7. > + * domain 2: CAM/MDP: larb2, larb9, larb11, larb13, larb14, larb16, > + * larb17, larb18, larb19, larb20, > + * domain 3: CCU0: larb13 - port9/10. > + * domain 4: CCU1: larb14 - port4/5. > + * > + * larb3/6/8/10/12/15 is null. > + */ > + > +/* larb0 */ > +#define M4U_PORT_L0_DISP_POSTMASK0 MTK_M4U_DOM_ID(0, 0, 0) > +#define M4U_PORT_L0_OVL_RDMA0_HDRMTK_M4U_DOM_ID(0, 0, 1) > +#define M4U_PORT_L0_OVL_RDMA0MTK_M4U_DOM_ID(0, 0, 2) > +#define M4U_PORT_L0_DISP_RDMA0 MTK_M4U_DOM_ID(0, 0, 3) > +#define M4U_PORT_L0_DISP_WDMA0 MTK_M4U_DOM_ID(0, 0, 4) > +#define M4U_PORT_L0_DISP_FAKE0 MTK_M4U_DOM_ID(0, 0, 5) > + > +/* larb1 */ > +#define M4U_PORT_L1_OVL_2L_RDMA0_HDR MTK_M
Re: [PATCH v5 09/27] iommu/io-pgtable-arm-v7s: Extend PA34 for MediaTek
On Wed, Dec 09, 2020 at 04:00:44PM +0800, Yong Wu wrote: > MediaTek extend the bit5 in lvl1 and lvl2 descriptor as PA34. > > Signed-off-by: Yong Wu > Acked-by: Will Deacon > Reviewed-by: Robin Murphy > --- > drivers/iommu/io-pgtable-arm-v7s.c | 9 +++-- > drivers/iommu/mtk_iommu.c | 2 +- > include/linux/io-pgtable.h | 4 ++-- > 3 files changed, 10 insertions(+), 5 deletions(-) > > diff --git a/drivers/iommu/io-pgtable-arm-v7s.c > b/drivers/iommu/io-pgtable-arm-v7s.c > index e880745ab1e8..4d0aa079470f 100644 > --- a/drivers/iommu/io-pgtable-arm-v7s.c > +++ b/drivers/iommu/io-pgtable-arm-v7s.c > @@ -112,9 +112,10 @@ > #define ARM_V7S_TEX_MASK 0x7 > #define ARM_V7S_ATTR_TEX(val)(((val) & ARM_V7S_TEX_MASK) << > ARM_V7S_TEX_SHIFT) > > -/* MediaTek extend the two bits for PA 32bit/33bit */ > +/* MediaTek extend the bits below for PA 32bit/33bit/34bit */ > #define ARM_V7S_ATTR_MTK_PA_BIT32BIT(9) > #define ARM_V7S_ATTR_MTK_PA_BIT33BIT(4) > +#define ARM_V7S_ATTR_MTK_PA_BIT34BIT(5) > > /* *well, except for TEX on level 2 large pages, of course :( */ > #define ARM_V7S_CONT_PAGE_TEX_SHIFT 6 > @@ -194,6 +195,8 @@ static arm_v7s_iopte paddr_to_iopte(phys_addr_t paddr, > int lvl, > pte |= ARM_V7S_ATTR_MTK_PA_BIT32; > if (paddr & BIT_ULL(33)) > pte |= ARM_V7S_ATTR_MTK_PA_BIT33; > + if (paddr & BIT_ULL(34)) > + pte |= ARM_V7S_ATTR_MTK_PA_BIT34; > return pte; > } > > @@ -218,6 +221,8 @@ static phys_addr_t iopte_to_paddr(arm_v7s_iopte pte, int > lvl, > paddr |= BIT_ULL(32); > if (pte & ARM_V7S_ATTR_MTK_PA_BIT33) > paddr |= BIT_ULL(33); > + if (pte & ARM_V7S_ATTR_MTK_PA_BIT34) > + paddr |= BIT_ULL(34); > return paddr; > } > > @@ -754,7 +759,7 @@ static struct io_pgtable *arm_v7s_alloc_pgtable(struct > io_pgtable_cfg *cfg, > if (cfg->ias > ARM_V7S_ADDR_BITS) > return NULL; > > - if (cfg->oas > (arm_v7s_is_mtk_enabled(cfg) ? 34 : ARM_V7S_ADDR_BITS)) > + if (cfg->oas > (arm_v7s_is_mtk_enabled(cfg) ? 35 : ARM_V7S_ADDR_BITS)) > return NULL; > > if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_NS | > diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c > index 6451d83753e1..ec3c87d4b172 100644 > --- a/drivers/iommu/mtk_iommu.c > +++ b/drivers/iommu/mtk_iommu.c > @@ -320,7 +320,7 @@ static int mtk_iommu_domain_finalise(struct > mtk_iommu_domain *dom) > IO_PGTABLE_QUIRK_ARM_MTK_EXT, > .pgsize_bitmap = mtk_iommu_ops.pgsize_bitmap, > .ias = 32, > - .oas = 34, > + .oas = 35, Shouldn't this be set according to the real hardware capabilities, instead of always setting it to 35? Best regards, Tomasz > .tlb = &mtk_iommu_flush_ops, > .iommu_dev = data->dev, > }; > diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h > index 4cde111e425b..1ae0757f4f94 100644 > --- a/include/linux/io-pgtable.h > +++ b/include/linux/io-pgtable.h > @@ -77,8 +77,8 @@ struct io_pgtable_cfg { >* TLB maintenance when mapping as well as when unmapping. >* >* IO_PGTABLE_QUIRK_ARM_MTK_EXT: (ARM v7s format) MediaTek IOMMUs extend > - * to support up to 34 bits PA where the bit32 and bit33 are > - * encoded in the bit9 and bit4 of the PTE respectively. > + * to support up to 35 bits PA where the bit32, bit33 and bit34 are > + * encoded in the bit9, bit4 and bit5 of the PTE respectively. >* >* IO_PGTABLE_QUIRK_NON_STRICT: Skip issuing synchronous leaf TLBIs >* on unmap, for DMA domains using the flush queue mechanism for > -- > 2.18.0 > > ___ > iommu mailing list > io...@lists.linux-foundation.org > https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH] clocksource: clint: Avoid remove __iomem in get_cycles_hi()
On Mon, Dec 21, 2020 at 09:32:30PM -0800, Palmer Dabbelt wrote: > From: Palmer Dabbelt > > This cast loses the __iomem qualifier from clint_timer_val, which > triggers an sparse warning. I'm not a native speaker, but the subject line sounds strange to me. Shouldn't this be: "don't cast away the __iommu annotation" or something similar? Also this adds an overly long line. Otherwise it looks fine.
Re: [PATCH] riscv: return -ENOSYS for syscall -1
On Tue, Dec 22, 2020 at 09:22:19AM -0700, Tycho Andersen wrote: > On Mon, Dec 21, 2020 at 11:52:00PM +0100, Andreas Schwab wrote: > > Properly return -ENOSYS for syscall -1 instead of leaving the return value > > uninitialized. This fixes the strace teststuite. > > > > Fixes: 5340627e3fe0 ("riscv: add support for SECCOMP and SECCOMP_FILTER") > > Signed-off-by: Andreas Schwab > > --- > > arch/riscv/kernel/entry.S | 9 + > > 1 file changed, 1 insertion(+), 8 deletions(-) > > > > diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S > > index 524d918f3601..d07763001eb0 100644 > > --- a/arch/riscv/kernel/entry.S > > +++ b/arch/riscv/kernel/entry.S > > @@ -186,14 +186,7 @@ check_syscall_nr: > > * Syscall number held in a7. > > * If syscall number is above allowed value, redirect to ni_syscall. > > */ > > - bge a7, t0, 1f > > - /* > > -* Check if syscall is rejected by tracer, i.e., a7 == -1. > > -* If yes, we pretend it was executed. > > -*/ > > - li t1, -1 > > - beq a7, t1, ret_from_syscall_rejected > > - blt a7, t1, 1f > > + bgeu a7, t0, 1f > > IIUC, this is all dead code anyway for the path where seccomp actually > rejects the syscall, since it should do the rejection directly in > handle_syscall_trace_enter(), which is called above this hunk. So it > seems good to me. That change really needs to be documented in the commit log, or even better split into a separate patch (still documented of course!).
Re: [PATCH v5 15/27] iommu/mediatek: Add fail handle for sysfs_add and device_register
On Wed, Dec 09, 2020 at 04:00:50PM +0800, Yong Wu wrote: > Add fail handle for iommu_device_sysfs_add and iommu_device_register. > > Fixes: b16c0170b53c ("iommu/mediatek: Make use of iommu_device_register > interface") > Signed-off-by: Yong Wu > --- > drivers/iommu/mtk_iommu.c | 13 +++-- > 1 file changed, 11 insertions(+), 2 deletions(-) > > diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c > index 39478cfbe0f1..09c8c58feb78 100644 > --- a/drivers/iommu/mtk_iommu.c > +++ b/drivers/iommu/mtk_iommu.c > @@ -746,7 +746,7 @@ static int mtk_iommu_probe(struct platform_device *pdev) > > ret = iommu_device_register(&data->iommu); > if (ret) > - return ret; > + goto out_sysfs_remove; > > spin_lock_init(&data->tlb_lock); > list_add_tail(&data->list, &m4ulist); > @@ -754,7 +754,16 @@ static int mtk_iommu_probe(struct platform_device *pdev) > if (!iommu_present(&platform_bus_type)) > bus_set_iommu(&platform_bus_type, &mtk_iommu_ops); > > - return component_master_add_with_match(dev, &mtk_iommu_com_ops, match); > + ret = component_master_add_with_match(dev, &mtk_iommu_com_ops, match); > + if (ret) > + goto out_dev_unreg; > + return ret; > + > +out_dev_unreg: Shouldn't other operations be undone as well? I can see that above bus_set_iommu() is set and an entry is added to m4ulist. > + iommu_device_unregister(&data->iommu); > +out_sysfs_remove: > + iommu_device_sysfs_remove(&data->iommu); > + return ret; > } > > static int mtk_iommu_remove(struct platform_device *pdev) > -- > 2.18.0 > > ___ > iommu mailing list > io...@lists.linux-foundation.org > https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v3 4/7] power: supply: max8997_charger: Set CHARGER current limit
On Wed, Dec 23, 2020 at 08:09:55AM +, Timon Baetz wrote: > On Tue, 22 Dec 2020 09:40:04 +0100, Krzysztof Kozlowski wrote: (...) > > > .name = "max8997_pmic", > > > .type = POWER_SUPPLY_TYPE_BATTERY, > > > @@ -170,6 +237,33 @@ static int max8997_battery_probe(struct > > > platform_device *pdev) > > > return PTR_ERR(charger->battery); > > > } > > > > > > + charger->reg = devm_regulator_get(&pdev->dev, "charger"); > > > > The code looks good but isn't it breaking all existing platforms? > > So there is 2 other DTS in the kernel sources that are using MAX8997 > pmic: > - Insignal Origen evaluation board > - Samsung Trats > Non of them have charging regulators. But still the power supply was probing on them (if not the error you mentioned). Now, the charger will fail. > Also probing of the charger has been failing for long time because of > https://lore.kernel.org/lkml/20201109194251.562203-2-timon.ba...@protonmail.com/ > but that seems to land in 5.11. That's a good argument supporting introduced breakage. Use it in commit message. Don't hide such information. > That being said, I guess I could make extcon and charger-supply > optional if you prefer. Since at least two boards will loose now power supply, I don't think you have a choice. Best regards, Krzysztof
Re: [PATCH] checkpatch: make the line length warnings match the coding style document
On Tue, Dec 22, 2020 at 08:22:06AM -0800, Joe Perches wrote: > Having checkpatch complain about > 80 column lines didn't stop > patches before, likely it wouldn't stop patches now. > > Emitting yet more messages for trivial lines > 80 columns is also > against the intent of the commit that changed the line length maximum. It certainly helped. Since that checkpatch change I waste a lot more of my time on finding all this crap, and people are confused because they only rely on checkpatch. Other maintainers are similarly annoyed or just silently fix things up. Right now this is making things much worse.
Re: [PATCH v5 1/7] scsi: ufs: Add "wb_on" sysfs node to control WB on/off
On Wed, 2020-12-23 at 09:31 +0800, Can Guo wrote: > I don't see why removing the sysfs nodes during ufshcd_shutdown() is > a > concern to customer - we should do whatever is needed to protect LLD > contexts from user space intervene. What do you think? The sysfs nodes can be removed only when the device is remvoed. Bean
Re: [PATCH v5 16/27] iommu/mediatek: Add device link for smi-common and m4u
On Wed, Dec 09, 2020 at 04:00:51PM +0800, Yong Wu wrote: > In the lastest SoC, M4U has its special power domain. thus, If the engine > begin to work, it should help enable the power for M4U firstly. > Currently if the engine work, it always enable the power/clocks for > smi-larbs/smi-common. This patch adds device_link for smi-common and M4U. > then, if smi-common power is enabled, the M4U power also is powered on > automatically. > > Normally M4U connect with several smi-larbs and their smi-common always > are the same, In this patch it get smi-common dev from the first smi-larb > device(i==0), then add the device_link only while m4u has power-domain. > > Signed-off-by: Yong Wu > --- > drivers/iommu/mtk_iommu.c | 30 -- > drivers/iommu/mtk_iommu.h | 1 + > 2 files changed, 29 insertions(+), 2 deletions(-) > > diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c > index 09c8c58feb78..5614015e5b96 100644 > --- a/drivers/iommu/mtk_iommu.c > +++ b/drivers/iommu/mtk_iommu.c > @@ -20,6 +20,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -706,7 +707,7 @@ static int mtk_iommu_probe(struct platform_device *pdev) > return larb_nr; > > for (i = 0; i < larb_nr; i++) { > - struct device_node *larbnode; > + struct device_node *larbnode, *smicomm_node; > struct platform_device *plarbdev; > u32 id; > > @@ -732,6 +733,26 @@ static int mtk_iommu_probe(struct platform_device *pdev) > > component_match_add_release(dev, &match, release_of, > compare_of, larbnode); > + if (i != 0) > + continue; How about using the last larb instead and moving the code below outside of the loop? > + smicomm_node = of_parse_phandle(larbnode, "mediatek,smi", 0); > + if (!smicomm_node) > + return -EINVAL; > + > + plarbdev = of_find_device_by_node(smicomm_node); > + of_node_put(smicomm_node); > + data->smicomm_dev = &plarbdev->dev; > + } > + > + if (dev->pm_domain) { > + struct device_link *link; > + > + link = device_link_add(data->smicomm_dev, dev, > +DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME); > + if (!link) { > + dev_err(dev, "Unable link %s.\n", > dev_name(data->smicomm_dev)); > + return -EINVAL; > + } > } > > platform_set_drvdata(pdev, data); > @@ -739,7 +760,7 @@ static int mtk_iommu_probe(struct platform_device *pdev) > ret = iommu_device_sysfs_add(&data->iommu, dev, NULL, >"mtk-iommu.%pa", &ioaddr); > if (ret) > - return ret; > + goto out_link_remove; > > iommu_device_set_ops(&data->iommu, &mtk_iommu_ops); > iommu_device_set_fwnode(&data->iommu, &pdev->dev.of_node->fwnode); > @@ -763,6 +784,9 @@ static int mtk_iommu_probe(struct platform_device *pdev) > iommu_device_unregister(&data->iommu); > out_sysfs_remove: > iommu_device_sysfs_remove(&data->iommu); > +out_link_remove: > + if (dev->pm_domain) > + device_link_remove(data->smicomm_dev, dev); > return ret; > } > > @@ -777,6 +801,8 @@ static int mtk_iommu_remove(struct platform_device *pdev) > bus_set_iommu(&platform_bus_type, NULL); > > clk_disable_unprepare(data->bclk); > + if (pdev->dev.pm_domain) > + device_link_remove(data->smicomm_dev, &pdev->dev); > devm_free_irq(&pdev->dev, data->irq, data); > component_master_del(&pdev->dev, &mtk_iommu_com_ops); > return 0; > diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h > index d0c93652bdbe..5e03a029c4dc 100644 > --- a/drivers/iommu/mtk_iommu.h > +++ b/drivers/iommu/mtk_iommu.h > @@ -68,6 +68,7 @@ struct mtk_iommu_data { > > struct iommu_device iommu; > const struct mtk_iommu_plat_data *plat_data; > + struct device *smicomm_dev; > > struct dma_iommu_mapping*mapping; /* For mtk_iommu_v1.c */ > > -- > 2.18.0 > > ___ > iommu mailing list > io...@lists.linux-foundation.org > https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v5 1/7] scsi: ufs: Add "wb_on" sysfs node to control WB on/off
On Wed, 2020-12-23 at 09:31 +0800, Can Guo wrote: > First of all, this check is not helping at all, during > ufshcd_shutdown(), > both the link and dev can be active for a moment, so this check is > not > helping the race condition. yes, This checkup doesn't fix race, it is to address your remove of sysfs nodes in the ufshcd_shutdown(). Bean
[GIT PULL] sound fixes for 5.11-rc1
Linus, please pull sound fixes for v5.11-rc1 from: git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git tags/sound-fix-5.11-rc1 The topmost commit is 13be30f156fda725b168ac89fc91f78651575307 sound fixes for 5.11-rc1 A collection of small fixes that came up recently for 5.11. Majority of fixes are usual HD-audio and USB-audio quirks, while a few PCM core fixes for addressing the information leak and yet more UBSAN fixes in the core side. Amadej Kastelic (1): ALSA: usb-audio: Add VID to support native DSD reproduction on FiiO devices Chris Chiu (3): ALSA: hda/realtek: Remove dummy lineout on Acer TravelMate P648/P658 ALSA: hda/realtek: Apply jack fixup for Quanta NL3 ALSA/hda: apply jack fixup for the Acer Veriton N4640G/N6640G/N2510G Kailang Yang (1): ALSA: hda/realtek - Supported Dell fixed type headset Lars-Peter Clausen (1): ALSA: pcm: Remove snd_pcm_lib_preallocate_dma_free() Mike Oliphant (1): ALSA: usb-audio: Add implicit feeback support for the BOSS GT-1 Robin Gong (1): ALSA: core: memalloc: add page alignment for iram Takashi Iwai (6): ALSA: usb-audio: Disable sample read check if firmware doesn't give back ALSA: memalloc: Align buffer allocations in page size ALSA: pcm: Clear the full allocated memory at hw_params ALSA: pcm: oss: Fix a few more UBSAN fixes ALSA: hda/realtek: Add quirk for MSI-GP73 ALSA: usb-audio: Add alias entry for ASUS PRIME TRX40 PRO-S YangHui (1): ALSA: core: Remove redundant comments --- sound/core/init.c | 2 -- sound/core/memalloc.c | 4 +++- sound/core/oss/pcm_oss.c | 22 ++ sound/core/pcm_memory.c | 10 +- sound/core/pcm_native.c | 9 +++-- sound/pci/hda/patch_realtek.c | 33 + sound/usb/card.c | 3 +++ sound/usb/clock.c | 6 ++ sound/usb/implicit.c | 2 ++ sound/usb/quirks.c| 1 + 10 files changed, 70 insertions(+), 22 deletions(-)
Re: [PATCH v5 09/12] media: uvcvideo: Implement UVC_QUIRK_PRIVACY_DURING_STREAM
Hi Laurent On Wed, Dec 23, 2020 at 9:05 AM Laurent Pinchart wrote: > > Hi Ricardo, > > On Tue, Dec 22, 2020 at 09:04:19PM +0100, Ricardo Ribalda wrote: > > On Tue, Dec 22, 2020 at 11:30 AM Laurent Pinchart wrote: > > > On Mon, Dec 21, 2020 at 05:48:16PM +0100, Ricardo Ribalda wrote: > > > > Some devices, can only read the privacy_pin if the device is > > > > > > s/devices,/devices/ > > > > > > > streaming. > > > > > > > > This patch implement a quirk for such devices, in order to avoid invalid > > > > reads and/or spurious events. > > > > > > > > Signed-off-by: Ricardo Ribalda > > > > --- > > > > drivers/media/usb/uvc/uvc_driver.c | 57 -- > > > > drivers/media/usb/uvc/uvc_queue.c | 3 ++ > > > > drivers/media/usb/uvc/uvcvideo.h | 4 +++ > > > > 3 files changed, 61 insertions(+), 3 deletions(-) > > > > > > > > diff --git a/drivers/media/usb/uvc/uvc_driver.c > > > > b/drivers/media/usb/uvc/uvc_driver.c > > > > index 72516101fdd0..7af37d4bd60a 100644 > > > > --- a/drivers/media/usb/uvc/uvc_driver.c > > > > +++ b/drivers/media/usb/uvc/uvc_driver.c > > > > @@ -7,6 +7,7 @@ > > > > */ > > > > > > > > #include > > > > +#include > > > > #include > > > > #include > > > > #include > > > > @@ -1472,6 +1473,17 @@ static int uvc_parse_control(struct uvc_device > > > > *dev) > > > > /* > > > > - > > > > * Privacy GPIO > > > > */ > > > > > > There should be a blank line here. > > > > > > > +static bool uvc_gpio_is_streaming(struct uvc_device *dev) > > > > +{ > > > > + struct uvc_streaming *streaming; > > > > + > > > > + list_for_each_entry(streaming, &dev->streams, list) { > > > > + if (uvc_queue_streaming(&streaming->queue)) > > > > + return true; > > > > + } > > > > + > > > > + return false; > > > > +} > > > > > > > > > > > > > > But not too blank lines here. > > > > > > > static u8 uvc_gpio_update_value(struct uvc_device *dev, > > > > @@ -1499,7 +1511,12 @@ static int uvc_gpio_get_cur(struct uvc_device > > > > *dev, struct uvc_entity *entity, > > > > if (cs != UVC_CT_PRIVACY_CONTROL || size < 1) > > > > return -EINVAL; > > > > > > > > + if ((dev->quirks & UVC_QUIRK_PRIVACY_DURING_STREAM) && > > > > + !uvc_gpio_is_streaming(dev)) > > > > + return -EBUSY; > > > > + > > > > *(uint8_t *)data = uvc_gpio_update_value(dev, entity); > > > > + > > > > return 0; > > > > } > > > > > > > > @@ -1528,19 +1545,50 @@ static struct uvc_entity > > > > *uvc_gpio_find_entity(struct uvc_device *dev) > > > > return NULL; > > > > } > > > > > > > > -static irqreturn_t uvc_gpio_irq(int irq, void *data) > > > > +void uvc_privacy_gpio_event(struct uvc_device *dev) > > > > { > > > > - struct uvc_device *dev = data; > > > > struct uvc_entity *unit; > > > > > > > > + > > > > unit = uvc_gpio_find_entity(dev); > > > > if (!unit) > > > > - return IRQ_HANDLED; > > > > + return; > > > > > > > > uvc_gpio_update_value(dev, unit); > > > > +} > > > > + > > > > +static irqreturn_t uvc_gpio_irq(int irq, void *data) > > > > +{ > > > > + struct uvc_device *dev = data; > > > > + > > > > + /* Ignore privacy events during streamoff */ > > > > + if (dev->quirks & UVC_QUIRK_PRIVACY_DURING_STREAM) > > > > + if (!uvc_gpio_is_streaming(dev)) > > > > + return IRQ_HANDLED; > > > > > > I'm still a bit concerned of race conditions. When stopping the stream, > > > vb2_queue.streaming is set to 0 after calling the driver's .stop_stream() > > > handler. This means that the device will cut power before > > > uvc_gpio_is_streaming() can detect that streaming has stopped, and the > > > GPIO could thus trigger an IRQ. > > > > On the affected devices I have not seen this. I guess it takes some > > time to discharge. Anyway I am implementing a workaround. Tell me if > > it is too ugly. > > > > > You mentioned that devices have a pull-up or pull-down on the GPIO line. > > > As there are only two devices affected, do you know if it's a pull-up or > > > pull-down ? Would it be worse to expose that state to userspace than to > > > return -EBUSY when reading the control ? > > > > The module has a 100K pull up. This is, it will return "Privacy = 0". > > > > We cannot return the default value, as it would make the user believe > > that the privacy is in a different state that currently is. > > In other words, userspace needs to know at all times if the privacy is > > in : unknow_state, on, off. > > This seems to be the core of the issue: we're trying to shove 3 states > into a boolean. Would this call for turning the V4L2_CID_PRIVACY control > into a menu ? Or maybe setting V4L2_CTRL_FLAG_INACTIVE ? Returning > -EBUSY when the control is read while not streaming, and not generating > an event that tells the control value becomes unknown, seems like a
Re: [PATCH] mm: add prototype for __add_to_page_cache_locked()
Can we please make the eBPF code stop referencing this function instead of papering over this crap? It has no business poking into page cache internals.
Re: [PATCH v5 17/27] iommu/mediatek: Add pm runtime callback
On Wed, Dec 09, 2020 at 04:00:52PM +0800, Yong Wu wrote: > This patch adds pm runtime callback. > > In pm runtime case, all the registers backup/restore and bclk are > controlled in the pm_runtime callback, then pm_suspend is not needed in > this case. > > runtime PM is disabled when suspend, thus we call > pm_runtime_status_suspended instead of pm_runtime_suspended. > > And, m4u doesn't have its special pm runtime domain in previous SoC, in > this case dev->power.runtime_status is RPM_SUSPENDED defaultly, This sounds wrong and could lead to hard to debug errors when the driver is changed in the future. Would it be possible to make the behavior consistent across the SoCs instead, so that runtime PM status is ACTIVE when needed, even on SoCs without an IOMMU PM domain? > thus add > a "dev->pm_domain" checking for the SoC that has pm runtime domain. > > Signed-off-by: Yong Wu > --- > drivers/iommu/mtk_iommu.c | 22 -- > 1 file changed, 20 insertions(+), 2 deletions(-) > > diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c > index 5614015e5b96..6fe3ee2b2bf5 100644 > --- a/drivers/iommu/mtk_iommu.c > +++ b/drivers/iommu/mtk_iommu.c > @@ -808,7 +808,7 @@ static int mtk_iommu_remove(struct platform_device *pdev) > return 0; > } > > -static int __maybe_unused mtk_iommu_suspend(struct device *dev) > +static int __maybe_unused mtk_iommu_runtime_suspend(struct device *dev) > { > struct mtk_iommu_data *data = dev_get_drvdata(dev); > struct mtk_iommu_suspend_reg *reg = &data->reg; > @@ -826,7 +826,7 @@ static int __maybe_unused mtk_iommu_suspend(struct device > *dev) > return 0; > } > > -static int __maybe_unused mtk_iommu_resume(struct device *dev) > +static int __maybe_unused mtk_iommu_runtime_resume(struct device *dev) > { > struct mtk_iommu_data *data = dev_get_drvdata(dev); > struct mtk_iommu_suspend_reg *reg = &data->reg; > @@ -853,7 +853,25 @@ static int __maybe_unused mtk_iommu_resume(struct device > *dev) > return 0; > } > > +static int __maybe_unused mtk_iommu_suspend(struct device *dev) > +{ > + /* runtime PM is disabled when suspend in pm_runtime case. */ > + if (dev->pm_domain && pm_runtime_status_suspended(dev)) > + return 0; > + > + return mtk_iommu_runtime_suspend(dev); > +} > + > +static int __maybe_unused mtk_iommu_resume(struct device *dev) > +{ > + if (dev->pm_domain && pm_runtime_status_suspended(dev)) > + return 0; > + > + return mtk_iommu_runtime_resume(dev); > +} Wouldn't it be enough to just use pm_runtime_force_suspend() and pm_runtime_force_resume() as system sleep ops? > + > static const struct dev_pm_ops mtk_iommu_pm_ops = { > + SET_RUNTIME_PM_OPS(mtk_iommu_runtime_suspend, mtk_iommu_runtime_resume, > NULL) > SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(mtk_iommu_suspend, mtk_iommu_resume) > }; > > -- > 2.18.0 > > ___ > iommu mailing list > io...@lists.linux-foundation.org > https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH] blokc/blk-merge: remove the next_bvec label in __blk_bios_map_sg()linux-bl...@vger.kernel.org (open list:BLOCK LAYER)
On Wed, Dec 23, 2020 at 12:31:58PM +0800, sh wrote: > remove the next_bvec label in __blk_bios_map_sg(), simplify the logic > of traversal bvec. What makes you believe that this simplifies anything?
soc: mediatek: cmdq: add address shift in jump
Change since v1: -move out from mt8192 seri series Yongqiang Niu (1): soc: mediatek: cmdq: add address shift in jump drivers/mailbox/mtk-cmdq-mailbox.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) -- 1.8.1.1.dirty
[PATCH v2] soc: mediatek: cmdq: add address shift in jump
Add address shift when compose jump instruction to compatible with 35bit format. Fixes: 0858fde496f8 ("mailbox: cmdq: variablize address shift in platform") Signed-off-by: Yongqiang Niu Reviewed-by: Nicolas Boichat --- drivers/mailbox/mtk-cmdq-mailbox.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c index 5665b6e..75378e3 100644 --- a/drivers/mailbox/mtk-cmdq-mailbox.c +++ b/drivers/mailbox/mtk-cmdq-mailbox.c @@ -168,7 +168,8 @@ static void cmdq_task_insert_into_thread(struct cmdq_task *task) dma_sync_single_for_cpu(dev, prev_task->pa_base, prev_task->pkt->cmd_buf_size, DMA_TO_DEVICE); prev_task_base[CMDQ_NUM_CMD(prev_task->pkt) - 1] = - (u64)CMDQ_JUMP_BY_PA << 32 | task->pa_base; + (u64)CMDQ_JUMP_BY_PA << 32 | + (task->pa_base >> task->cmdq->shift_pa); dma_sync_single_for_device(dev, prev_task->pa_base, prev_task->pkt->cmd_buf_size, DMA_TO_DEVICE); -- 1.8.1.1.dirty
Re: [PATCH v1] scsi: ufs-mediatek: Enable UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL
On Wed, 2020-12-23 at 07:47 +, Avri Altman wrote: > > > could change the way it does: Keep manual flush disabled by > > > default and > > > remove this quirk. > > Ack on that. > I never understood why it was needed in the first place. > Maybe just remove it, and allow to perform explicit flush from sysfs. > > Thanks, > Avr Avri I agree with you. I don't understand why setting that at the begginnning, also assign this feature the contrller to make desicion. Bean
Re: [PATCH v5 18/27] iommu/mediatek: Add power-domain operation
On Wed, Dec 09, 2020 at 04:00:53PM +0800, Yong Wu wrote: > In the previous SoC, the M4U HW is in the EMI power domain which is > always on. the latest M4U is in the display power domain which may be > turned on/off, thus we have to add pm_runtime interface for it. > > When the engine work, the engine always enable the power and clocks for > smi-larb/smi-common, then the M4U's power will always be powered on > automatically via the device link with smi-common. > > Note: we don't enable the M4U power in iommu_map/unmap for tlb flush. > If its power already is on, of course it is ok. if the power is off, > the main tlb will be reset while M4U power on, thus the tlb flush while > m4u power off is unnecessary, just skip it. > > There will be one case that pm runctime status is not expected when tlb > flush. After boot, the display may call dma_alloc_attrs before it call > pm_runtime_get(disp-dev), then the m4u's pm status is not active inside > the dma_alloc_attrs. Since it only happens after boot, the tlb is clean > at that time, I also think this is ok. > > Signed-off-by: Yong Wu > --- > drivers/iommu/mtk_iommu.c | 41 +-- > 1 file changed, 35 insertions(+), 6 deletions(-) > > diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c > index 6fe3ee2b2bf5..0e9c03cbab32 100644 > --- a/drivers/iommu/mtk_iommu.c > +++ b/drivers/iommu/mtk_iommu.c > @@ -184,6 +184,8 @@ static void mtk_iommu_tlb_flush_all(void *cookie) > struct mtk_iommu_data *data = cookie; > > for_each_m4u(data) { > + if (!pm_runtime_active(data->dev)) > + continue; Is it guaranteed that the status is active in the check above, but then the process is preempted and it goes down here? Shouldn't we do something like below? ret = pm_runtime_get_if_active(); if (!ret) continue; if (ret < 0) // handle error // Flush pm_runtime_put(); Similar comment to the other places being changed by this patch. > writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0, > data->base + data->plat_data->inv_sel_reg); > writel_relaxed(F_ALL_INVLD, data->base + REG_MMU_INVALIDATE); > @@ -200,6 +202,10 @@ static void mtk_iommu_tlb_flush_range_sync(unsigned long > iova, size_t size, > u32 tmp; > > for_each_m4u(data) { > + /* skip tlb flush when pm is not active. */ > + if (!pm_runtime_active(data->dev)) > + continue; > + > spin_lock_irqsave(&data->tlb_lock, flags); > writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0, > data->base + data->plat_data->inv_sel_reg); > @@ -384,6 +390,8 @@ static int mtk_iommu_attach_device(struct iommu_domain > *domain, > { > struct mtk_iommu_data *data = dev_iommu_priv_get(dev); > struct mtk_iommu_domain *dom = to_mtk_domain(domain); > + struct device *m4udev = data->dev; > + bool pm_enabled = pm_runtime_enabled(m4udev); > int ret; > > if (!data) > @@ -391,12 +399,25 @@ static int mtk_iommu_attach_device(struct iommu_domain > *domain, > > /* Update the pgtable base address register of the M4U HW */ > if (!data->m4u_dom) { > + if (pm_enabled) { > + ret = pm_runtime_get_sync(m4udev); > + if (ret < 0) { > + pm_runtime_put_noidle(m4udev); > + return ret; > + } > + } > ret = mtk_iommu_hw_init(data); > - if (ret) > + if (ret) { > + if (pm_enabled) > + pm_runtime_put(m4udev); > return ret; > + } > data->m4u_dom = dom; > writel(dom->cfg.arm_v7s_cfg.ttbr & MMU_PT_ADDR_MASK, > data->base + REG_MMU_PT_BASE_ADDR); > + > + if (pm_enabled) > + pm_runtime_put(m4udev); > } > > mtk_iommu_config(data, dev, true); > @@ -747,10 +768,13 @@ static int mtk_iommu_probe(struct platform_device *pdev) > if (dev->pm_domain) { > struct device_link *link; > > + pm_runtime_enable(dev); > + > link = device_link_add(data->smicomm_dev, dev, > DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME); > if (!link) { > dev_err(dev, "Unable link %s.\n", > dev_name(data->smicomm_dev)); > + pm_runtime_disable(dev); > return -EINVAL; > } > } > @@ -785,8 +809,10 @@ static int mtk_iommu_probe(struct platform_device *pdev) > out_sysfs_remove: > iommu_device_sysfs_remove(&data->iommu); > out_link_remove: > - if (dev->pm_domain) > + if (dev->pm_domain) { > devic
[PATCH] rcu: Fix dynticks_nmi_nesting underflow check in rcu_is_cpu_rrupt_from_idle
For the smp_call_function() optimization, where callbacks can run from idle context, in commit 806f04e9fd2c ("rcu: Allow for smp_call_function() running callbacks from idle"), an additional check is added in rcu_is_cpu_rrupt_from_idle(), for dynticks_nmi_nesting value being 0, for these smp_call_function() callbacks running from idle loop. However, this commit missed updating a preexisting underflow check of dynticks_nmi_nesting, which checks for a non zero positive value. Fix this warning and while at it, read the counter only once. Signed-off-by: Neeraj Upadhyay --- Hi, I was not able to get this warning, with scftorture. RCU_LOCKDEP_WARN(__this_cpu_read(rcu_data.dynticks_nmi_nesting) <= 0, "RCU dynticks_nmi_nesting counter underflow/zero!"); Not sure if idle loop smp_call_function() optimization is already present in mainline? Another thing, which I am not sure of is, maybe lockdep gets disabled in the idle loop contexts, where rcu_is_cpu_rrupt_from_idle() is called? Was this the original intention, to keep the lockdep based RCU_LOCKDEP_WARN(__this_cpu_read(rcu_data.dynticks_nmi_nesting) <= 0 check separate from idle task context nesting value WARN_ON_ONCE(!nesting && !is_idle_task(current)) check? Thanks Neeraj kernel/rcu/tree.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index bc8b489..c3037cf 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -457,11 +457,10 @@ static int rcu_is_cpu_rrupt_from_idle(void) /* Check for counter underflows */ RCU_LOCKDEP_WARN(__this_cpu_read(rcu_data.dynticks_nesting) < 0, "RCU dynticks_nesting counter underflow!"); - RCU_LOCKDEP_WARN(__this_cpu_read(rcu_data.dynticks_nmi_nesting) <= 0, -"RCU dynticks_nmi_nesting counter underflow/zero!"); + nesting = __this_cpu_read(rcu_data.dynticks_nmi_nesting); + RCU_LOCKDEP_WARN(nesting < 0, "RCU dynticks_nmi_nesting counter underflow!"); /* Are we at first interrupt nesting level? */ - nesting = __this_cpu_read(rcu_data.dynticks_nmi_nesting); if (nesting > 1) return false; -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
Re: [RFC v2 PATCH 0/4] speed up page allocation for __GFP_ZERO
[...] >> I was rather saying that for security it's of little use IMHO. >> Application/VM start up time might be improved by using huge pages (and >> pre-zeroing these). Free page reporting might be improved by using >> MADV_FREE instead of MADV_DONTNEED in the hypervisor. >> >>> this feature, above all of them, which one is likely to become the >>> most strong one? From the implementation, you will find it is >>> configurable, users don't want to use it can turn it off. This is not >>> an option? >> >> Well, we have to maintain the feature and sacrifice a page flag. For >> example, do we expect someone explicitly enabling the feature just to >> speed up startup time of an app that consumes a lot of memory? I highly >> doubt it. > > In our production environment, there are three main applications have such > requirement, one is QEMU [creating a VM with SR-IOV passthrough device], > anther other two are DPDK related applications, DPDK OVS and SPDK vhost, > for best performance, they populate memory when starting up. For SPDK vhost, > we make use of the VHOST_USER_GET/SET_INFLIGHT_FD feature for > vhost 'live' upgrade, which is done by killing the old process and > starting a new > one with the new binary. In this case, we want the new process started as > quick > as possible to shorten the service downtime. We really enable this feature > to speed up startup time for them :) Thanks for info on the use case! All of these use cases either already use, or could use, huge pages IMHO. It's not your ordinary proprietary gaming app :) This is where pre-zeroing of huge pages could already help. Just wondering, wouldn't it be possible to use tmpfs/hugetlbfs ... creating a file and pre-zeroing it from another process, or am I missing something important? At least for QEMU this should work AFAIK, where you can just pass the file to be use using memory-backend-file. > >> I'd love to hear opinions of other people. (a lot of people are offline >> until beginning of January, including, well, actually me :) ) > > OK. I will wait some time for others' feedback. Happy holidays! To you too, cheers! -- Thanks, David / dhildenb
[PATCH v1 2/2] arm64: configs: Support DEVAPC on MediaTek platforms
Support DEVAPC on MediaTek platforms by enabling CONFIG_MTK_DEVAPC. Signed-off-by: Neal Liu --- arch/arm64/configs/defconfig |1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 17a2df6..a373776 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -257,6 +257,7 @@ CONFIG_MTD_NAND_MARVELL=y CONFIG_MTD_NAND_FSL_IFC=y CONFIG_MTD_NAND_QCOM=y CONFIG_MTD_SPI_NOR=y +CONFIG_MTK_DEVAPC=m CONFIG_SPI_CADENCE_QUADSPI=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_NBD=m -- 1.7.9.5
[PATCH v1 0/2] arm64: Support devapc on MediaTek MT6779 platform
This series adds DEVAPC (Device Access Permission Control) support on MediaTek MT6779 SoC platform. *** BLURB HERE *** Neal Liu (2): arm64: dts: mt6779: Support devapc arm64: configs: Support DEVAPC on MediaTek platforms arch/arm64/boot/dts/mediatek/mt6779.dtsi | 8 arch/arm64/configs/defconfig | 1 + 2 files changed, 9 insertions(+) -- 2.18.0
[PATCH v1 1/2] arm64: dts: mt6779: Support devapc
Signed-off-by: Neal Liu --- arch/arm64/boot/dts/mediatek/mt6779.dtsi |8 1 file changed, 8 insertions(+) diff --git a/arch/arm64/boot/dts/mediatek/mt6779.dtsi b/arch/arm64/boot/dts/mediatek/mt6779.dtsi index 370f309..52ecfc7 100644 --- a/arch/arm64/boot/dts/mediatek/mt6779.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt6779.dtsi @@ -189,6 +189,14 @@ #clock-cells = <1>; }; + devapc: devapc@10207000 { + compatible = "mediatek,mt6779-devapc"; + reg = <0 0x10207000 0 0x1000>; + interrupts = ; + clocks = <&infracfg_ao CLK_INFRA_DEVICE_APC>; + clock-names = "devapc-infra-clock"; + }; + uart0: serial@11002000 { compatible = "mediatek,mt6779-uart", "mediatek,mt6577-uart"; -- 1.7.9.5
Re: [PATCH] erofs: support direct IO for uncompressed file
Hi Christoph, The reason we use dio is because we need to deploy the patch on some early kernel versions, and we don't pay much attention to the change of iomap. Anyway, I will study the problem mentioned by Gao Xiang and try to convert the current patch to iomap. Thanks, Jianan On Wed, Dec 23, 2020 at 03:39:01AM +0800, Gao Xiang wrote: Hi Christoph, On Tue, Dec 22, 2020 at 02:22:34PM +, Christoph Hellwig wrote: Please do not add new callers of __blockdev_direct_IO and use the modern iomap variant instead. We've talked about this topic before. The current status is that iomap doesn't support tail-packing inline data yet (Chao once sent out a version), and erofs only cares about read intrastructure for now (So we don't think more about how to deal with tail-packing inline write path). Plus, the original patch was once lack of inline data regression test from gfs2 folks. So resend Chaos prep patch as part of the series switching parts of erofs to iomap. We need to move things off the old infrastructure instead of adding more users and everyone needs to help a little.
Re: [PATCH v3 1/7] iommu: Move iotlb_sync_map out from __iommu_map
On Wed, Dec 16, 2020 at 06:36:01PM +0800, Yong Wu wrote: > In the end of __iommu_map, It alway call iotlb_sync_map. > This patch moves iotlb_sync_map out from __iommu_map since it is > unnecessary to call this for each sg segment especially iotlb_sync_map > is flush tlb all currently. > > Signed-off-by: Yong Wu > Reviewed-by: Robin Murphy What about adding a little helper that does the NULL check and method call instead of duplicating it all over?
Re: [RFC PATCH v2 2/8] net: sparx5: add the basic sparx5 driver
On 22.12.2020 16:01, Andrew Lunn wrote: EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe > > +static void sparx5_board_init(struct sparx5 *sparx5) > > +{ > > + int idx; > > + > > + if (!sparx5->sd_sgpio_remapping) > > + return; > > + > > + /* Enable SGPIO Signal Detect remapping */ > > + spx5_rmw(GCB_HW_SGPIO_SD_CFG_SD_MAP_SEL, > > + GCB_HW_SGPIO_SD_CFG_SD_MAP_SEL, > > + sparx5, > > + GCB_HW_SGPIO_SD_CFG); > > + > > + /* Refer to LOS SGPIO */ > > + for (idx = 0; idx < SPX5_PORTS; idx++) { > > + if (sparx5->ports[idx]) { > > + if (sparx5->ports[idx]->conf.sd_sgpio != ~0) > > { > > + spx5_wr(sparx5->ports[idx]- > > >conf.sd_sgpio, > > + sparx5, > > + > > GCB_HW_SGPIO_TO_SD_MAP_CFG(idx)); > > + } > > + } > > + } > > +} > > I've not looked at how you do SFP integration yet. Is this the LOS > from the SFP socket? Is there a Linux GPIO controller exported by > this > driver, so the SFP driver can use the GPIOs? Yes the SFP driver (used by the Sparx5 SerDes driver) will use the SGPIO LOS, Module Detect etc, and the Port Modules are aware of the location of the LOS, and use this by default without any driver configuration. But on the PCB134 the SGPIOs are shifted one bit by a mistake, and they are not located in the expected position, so we have this board remapping function to handle that aspect. Is it possible to turn this off in the hardware? It might be less confusing if LOS it determined by phylink, not phylink and the switch itself. Especially when we get into race conditions between PHYLINK polling the GPIO and the hardware taking the short cut? OK - I get you point, but I think the message I got when investigating this, was that it was not possible to turn it off. I will check that again. On the other hand this is also used by our bare-metal API (MESA) so in that context it simpifies the setup, since the port modules are aware of the SFP state. > > +static int mchp_sparx5_probe(struct platform_device *pdev) > > +{ > > + struct device_node *np = pdev->dev.of_node; > > + struct sparx5 *sparx5; > > + struct device_node *ports, *portnp; > > + const u8 *mac_addr; > > + int err = 0; > > + > > + if (!np && !pdev->dev.platform_data) > > + return -ENODEV; > > + > > + sparx5 = devm_kzalloc(&pdev->dev, sizeof(*sparx5), > > GFP_KERNEL); > > + if (!sparx5) > > + return -ENOMEM; > > + > > + platform_set_drvdata(pdev, sparx5); > > + sparx5->pdev = pdev; > > + sparx5->dev = &pdev->dev; > > + > > + /* Default values, some from DT */ > > + sparx5->coreclock = SPX5_CORE_CLOCK_DEFAULT; > > + > > + mac_addr = of_get_mac_address(np); > > + if (IS_ERR_OR_NULL(mac_addr)) { > > + dev_info(sparx5->dev, "MAC addr was not set, use > > random MAC\n"); > > + eth_random_addr(sparx5->base_mac); > > + sparx5->base_mac[5] = 0; > > + } else { > > + ether_addr_copy(sparx5->base_mac, mac_addr); > > + } > > The binding document does not say anything about a MAC address at the > top level. What is this used for? This the base MAC address used for generating the the switch NI's MAC addresses. Yes, that is obvious from the code. But all DT properties must be in the binding Documentation. The DT verifier is going to complain when it finds a mac-address property which is not described in the yaml file. I will add a description for the MAC address to the bindings. > > + config.media_type = ETH_MEDIA_DAC; > > + config.serdes_reset = true; > > + config.portmode = config.phy_mode; > > + err = sparx5_probe_port(sparx5, portnp, serdes, > > portno, &config); > > + if (err) { > > + dev_err(sparx5->dev, "port probe error\n"); > > + goto cleanup_ports; > > + } > > + } > > + sparx5_board_init(sparx5); > > + > > +cleanup_ports: > > + return err; > > Seems missed named, no cleanup. Ah - this comes later (as the driver was split in functional groups for reviewing). I hope this is OK, as it is only temporary - I could add a comment to that effect. Yes, this is fine. Here, and in other places, a comment like: /* More code to be added in later patches */ would of been nice, just as a heads up. That is the problem with linear patch review. Will do > > +static int __init sparx5_switch_reset(void) > > +{ > > + const char *syscon_cpu = "microchip,sparx5-cpu-syscon", > > + *syscon_gcb = "microchip,sparx5-gcb-syscon"; > > + struct regmap *cpu_ctrl, *gcb_ctrl; > > + u32 val; > > + > > + cpu_ctrl = syscon_regmap_lookup_by_compatible(syscon_cpu); > > + if (IS_ERR(cpu_ctrl)) { > > + pr_err("No '%
Re: [PATCH] erofs: support direct IO for uncompressed file
On Wed, Dec 23, 2020 at 04:48:20PM +0800, Huang Jianan wrote: > Hi Christoph, > > The reason we use dio is because we need to deploy the patch on some early > kernel versions, and we don't pay much attention to the change of iomap. No, that is never an excuse for upstream development.
Re: [PATCH v6 04/11] media: uvcvideo: Add uvc_ctrl_status_event_direct
Hi Ricardo, Thank you for the patch. On Wed, Dec 23, 2020 at 12:04:39AM +0100, Ricardo Ribalda wrote: > Provide a code path for events that can be sent without a work-queue, > this is, that do not belong to an URB and are not handled in the top > half on an irq-handled. > > Signed-off-by: Ricardo Ribalda > --- > drivers/media/usb/uvc/uvc_ctrl.c | 35 +++- > drivers/media/usb/uvc/uvcvideo.h | 2 ++ > 2 files changed, 32 insertions(+), 5 deletions(-) > > diff --git a/drivers/media/usb/uvc/uvc_ctrl.c > b/drivers/media/usb/uvc/uvc_ctrl.c > index 9f6174a10e73..5fe228a3213b 100644 > --- a/drivers/media/usb/uvc/uvc_ctrl.c > +++ b/drivers/media/usb/uvc/uvc_ctrl.c > @@ -1254,17 +1254,14 @@ static void uvc_ctrl_send_slave_event(struct > uvc_video_chain *chain, > uvc_ctrl_send_event(chain, handle, ctrl, mapping, val, changes); > } > > -static void uvc_ctrl_status_event_work(struct work_struct *work) > +static void __uvc_ctrl_status_event(struct uvc_device *dev, > + struct uvc_ctrl_work *w) As this function doesn't deal with the work queue, should it receive the members of uvc_ctrl_work as direct arguments ? You could then drop the separate uvc_ctrl_status_event_direct(), or rather rename this function to uvc_ctrl_status_event_direct(). Speaking of names, maybe uvc_ctrl_status_event() should be renamed to uvc_ctrl_status_event_async(), and this function become uvc_ctrl_status_event() ? > { > - struct uvc_device *dev = container_of(work, struct uvc_device, > - async_ctrl.work); > - struct uvc_ctrl_work *w = &dev->async_ctrl; > struct uvc_video_chain *chain = w->chain; > struct uvc_control_mapping *mapping; > struct uvc_control *ctrl = w->ctrl; > struct uvc_fh *handle; > unsigned int i; > - int ret; > > mutex_lock(&chain->ctrl_mutex); > > @@ -1291,6 +1288,16 @@ static void uvc_ctrl_status_event_work(struct > work_struct *work) > } > > mutex_unlock(&chain->ctrl_mutex); > +} > + > +static void uvc_ctrl_status_event_work(struct work_struct *work) > +{ > + struct uvc_device *dev = container_of(work, struct uvc_device, > + async_ctrl.work); > + struct uvc_ctrl_work *w = &dev->async_ctrl; > + int ret; > + > + __uvc_ctrl_status_event(dev, w); > > /* Resubmit the URB. */ > w->urb->interval = dev->int_ep->desc.bInterval; > @@ -1321,6 +1328,24 @@ bool uvc_ctrl_status_event(struct urb *urb, struct > uvc_video_chain *chain, > return true; > } > > +void uvc_ctrl_status_event_direct(struct uvc_video_chain *chain, > + struct uvc_control *ctrl, const u8 *data) > +{ > + struct uvc_device *dev = chain->dev; > + struct uvc_ctrl_work w; > + > + if (list_empty(&ctrl->info.mappings)) { > + ctrl->handle = NULL; > + return; > + } > + > + w.data = data; > + w.chain = chain; > + w.ctrl = ctrl; > + > + __uvc_ctrl_status_event(dev, &w); > +} > + > static bool uvc_ctrl_xctrls_has_control(const struct v4l2_ext_control > *xctrls, > unsigned int xctrls_count, u32 id) > { > diff --git a/drivers/media/usb/uvc/uvcvideo.h > b/drivers/media/usb/uvc/uvcvideo.h > index c50b0546901f..d7954dcc2b60 100644 > --- a/drivers/media/usb/uvc/uvcvideo.h > +++ b/drivers/media/usb/uvc/uvcvideo.h > @@ -845,6 +845,8 @@ void uvc_ctrl_cleanup_device(struct uvc_device *dev); > int uvc_ctrl_restore_values(struct uvc_device *dev); > bool uvc_ctrl_status_event(struct urb *urb, struct uvc_video_chain *chain, > struct uvc_control *ctrl, const u8 *data); > +void uvc_ctrl_status_event_direct(struct uvc_video_chain *chain, > + struct uvc_control *ctrl, const u8 *data); > > int uvc_ctrl_begin(struct uvc_video_chain *chain); > int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback, -- Regards, Laurent Pinchart
[PATCH bpf-next] xsk: build skb by page
This patch is used to construct skb based on page to save memory copy overhead. Taking into account the problem of addr unaligned, and the possibility of frame size greater than page in the future. Signed-off-by: Xuan Zhuo --- net/xdp/xsk.c | 68 --- 1 file changed, 51 insertions(+), 17 deletions(-) diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c index ac4a317..7cab40f 100644 --- a/net/xdp/xsk.c +++ b/net/xdp/xsk.c @@ -430,6 +430,55 @@ static void xsk_destruct_skb(struct sk_buff *skb) sock_wfree(skb); } +static struct sk_buff *xsk_build_skb_bypage(struct xdp_sock *xs, struct xdp_desc *desc) +{ + char *buffer; + u64 addr; + u32 len, offset, copy, copied; + int err, i; + struct page *page; + struct sk_buff *skb; + + skb = sock_alloc_send_skb(&xs->sk, 0, 1, &err); + if (unlikely(!skb)) + return NULL; + + addr = desc->addr; + len = desc->len; + + buffer = xsk_buff_raw_get_data(xs->pool, addr); + offset = offset_in_page(buffer); + addr = buffer - (char *)xs->pool->addrs; + + for (copied = 0, i = 0; copied < len; ++i) { + page = xs->pool->umem->pgs[addr >> PAGE_SHIFT]; + + get_page(page); + + copy = min((u32)(PAGE_SIZE - offset), len - copied); + + skb_fill_page_desc(skb, i, page, offset, copy); + + copied += copy; + addr += copy; + offset = 0; + } + + skb->len += len; + skb->data_len += len; + skb->truesize += len; + + refcount_add(len, &xs->sk.sk_wmem_alloc); + + skb->dev = xs->dev; + skb->priority = xs->sk.sk_priority; + skb->mark = xs->sk.sk_mark; + skb_shinfo(skb)->destructor_arg = (void *)(long)addr; + skb->destructor = xsk_destruct_skb; + + return skb; +} + static int xsk_generic_xmit(struct sock *sk) { struct xdp_sock *xs = xdp_sk(sk); @@ -445,40 +494,25 @@ static int xsk_generic_xmit(struct sock *sk) goto out; while (xskq_cons_peek_desc(xs->tx, &desc, xs->pool)) { - char *buffer; - u64 addr; - u32 len; - if (max_batch-- == 0) { err = -EAGAIN; goto out; } - len = desc.len; - skb = sock_alloc_send_skb(sk, len, 1, &err); + skb = xsk_build_skb_bypage(xs, &desc); if (unlikely(!skb)) goto out; - skb_put(skb, len); - addr = desc.addr; - buffer = xsk_buff_raw_get_data(xs->pool, addr); - err = skb_store_bits(skb, 0, buffer, len); /* This is the backpressure mechanism for the Tx path. * Reserve space in the completion queue and only proceed * if there is space in it. This avoids having to implement * any buffering in the Tx path. */ - if (unlikely(err) || xskq_prod_reserve(xs->pool->cq)) { + if (xskq_prod_reserve(xs->pool->cq)) { kfree_skb(skb); goto out; } - skb->dev = xs->dev; - skb->priority = sk->sk_priority; - skb->mark = sk->sk_mark; - skb_shinfo(skb)->destructor_arg = (void *)(long)desc.addr; - skb->destructor = xsk_destruct_skb; - err = __dev_direct_xmit(skb, xs->queue_id); if (err == NETDEV_TX_BUSY) { /* Tell user-space to retry the send */ -- 1.8.3.1
Re: [PATCH v4] bcache:remove a superfluous check in register_bcache
Looks good, Reviewed-by: Christoph Hellwig
Re: [PATCH v3 6/7] iommu/mediatek: Gather iova in iommu_unmap to achieve tlb sync once
On Wed, Dec 16, 2020 at 06:36:06PM +0800, Yong Wu wrote: > In current iommu_unmap, this code is: > > iommu_iotlb_gather_init(&iotlb_gather); > ret = __iommu_unmap(domain, iova, size, &iotlb_gather); > iommu_iotlb_sync(domain, &iotlb_gather); > > We could gather the whole iova range in __iommu_unmap, and then do tlb > synchronization in the iommu_iotlb_sync. > > This patch implement this, Gather the range in mtk_iommu_unmap. > then iommu_iotlb_sync call tlb synchronization for the gathered iova range. > we don't call iommu_iotlb_gather_add_page since our tlb synchronization > could be regardless of granule size. > > In this way, gather->start is impossible ULONG_MAX, remove the checking. > > This patch aims to do tlb synchronization *once* in the iommu_unmap. > > Signed-off-by: Yong Wu > --- > drivers/iommu/mtk_iommu.c | 8 +--- > 1 file changed, 5 insertions(+), 3 deletions(-) > > diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c > index db7d43adb06b..89cec51405cd 100644 > --- a/drivers/iommu/mtk_iommu.c > +++ b/drivers/iommu/mtk_iommu.c > @@ -506,7 +506,12 @@ static size_t mtk_iommu_unmap(struct iommu_domain > *domain, > struct iommu_iotlb_gather *gather) > { > struct mtk_iommu_domain *dom = to_mtk_domain(domain); > + unsigned long long end = iova + size; > > + if (gather->start > iova) > + gather->start = iova; > + if (gather->end < end) > + gather->end = end; I don't know how common the case is, but what happens if gather->start...gather->end is a disjoint range from iova...end? E.g. | gather | ..XXX... | iova | | | | | gather->start | iova | gather->end end We would also end up invalidating the TLB for the XXX area, which could affect the performance. Also, why is the existing code in __arm_v7s_unmap() not enough? It seems to call io_pgtable_tlb_add_page() already, so it should be batching the flushes. > return dom->iop->unmap(dom->iop, iova, size, gather); > } > > @@ -523,9 +528,6 @@ static void mtk_iommu_iotlb_sync(struct iommu_domain > *domain, > struct mtk_iommu_domain *dom = to_mtk_domain(domain); > size_t length = gather->end - gather->start; > > - if (gather->start == ULONG_MAX) > - return; > - > mtk_iommu_tlb_flush_range_sync(gather->start, length, gather->pgsize, > dom->data); > } > -- > 2.18.0 > > ___ > iommu mailing list > io...@lists.linux-foundation.org > https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH AUTOSEL 4.14 40/66] hv_netvsc: Validate number of allocated sub-channels
On Wed, Dec 23, 2020 at 02:47:56AM +, Michael Kelley wrote: > From: Sasha Levin Sent: Tuesday, December 22, 2020 6:22 PM > > > > From: "Andrea Parri (Microsoft)" > > > > [ Upstream commit 206ad34d52a2f1205c84d08c12fc116aad0eb407 ] > > > > Lack of validation could lead to out-of-bound reads and information > > leaks (cf. usage of nvdev->chan_table[]). Check that the number of > > allocated sub-channels fits into the expected range. > > > > Suggested-by: Saruhan Karademir > > Signed-off-by: Andrea Parri (Microsoft) > > Reviewed-by: Haiyang Zhang > > Acked-by: Jakub Kicinski > > Cc: "David S. Miller" > > Cc: Jakub Kicinski > > Cc: net...@vger.kernel.org > > Link: > > https://lore.kernel.org/linux-hyperv/20201118153310.112404-1-parri.and...@gmail.com/ > > Signed-off-by: Wei Liu > > Signed-off-by: Sasha Levin > > --- > > drivers/net/hyperv/rndis_filter.c | 5 + > > 1 file changed, 5 insertions(+) > > > > Sasha -- This patch is one of an ongoing group of patches where a Linux > guest running on Hyper-V will start assuming that hypervisor behavior might > be malicious, and guards against such behavior. Because this is a new > assumption, these patches are more properly treated as new functionality > rather than as bug fixes. So I would propose that we *not* bring such patches > back to stable branches. Thank you, Michael. Just to confirm, I agree with Michael's assessment above and I join his proposal to *not* backport such patches to stable. Thanks, Andrea
Re: Re: [PATCH] ide: pci: Fix memleak in ide_pci_init_two
> On Sun, Dec 20, 2020 at 03:05:40PM +0800, Dinghao Liu wrote: > > When do_ide_setup_pci_device() fails, host allocated > > by ide_host_alloc() may not have been freed, which > > leads to memleak. > > > > Signed-off-by: Dinghao Liu > > --- > > drivers/ide/setup-pci.c | 8 > > 1 file changed, 4 insertions(+), 4 deletions(-) > > > > diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c > > index fdc8e813170c..c7da5368fcd4 100644 > > --- a/drivers/ide/setup-pci.c > > +++ b/drivers/ide/setup-pci.c > > @@ -586,7 +586,7 @@ int ide_pci_init_two(struct pci_dev *dev1, struct > > pci_dev *dev2, > > * do_ide_setup_pci_device() on the first device! > > */ > > if (ret < 0) > > - goto out_free_bars; > > + goto out_free_host; > > > > /* fixup IRQ */ > > if (ide_pci_is_in_compatibility_mode(pdev[i])) { > > @@ -597,11 +597,11 @@ int ide_pci_init_two(struct pci_dev *dev1, struct > > pci_dev *dev2, > > } > > > > ret = ide_host_register(host, d, hws); > > - if (ret) > > - ide_host_free(host); > > - else > > + if (!ret) > > goto out; > > Maybe > if (ret) > goto out_free_host; > > return 0; > > would be more clear here. But this is just small nit. > > > > > +out_free_host: > > + ide_host_free(host); > > out_free_bars: > > i = n_ports / 2; > > while (i--) Thank you for your advice and I will send a new patch soon. Regards, Dinghao
NASA scientists achieve long-distance 'quantum teleportation' over 27 miles for the first time – paving the way for unhackable networks that transfer data faster than the speed of light
Subject: NASA scientists achieve long-distance 'quantum teleportation' over 27 miles for the first time – paving the way for unhackable networks that transfer data faster than the speed of light Good day from Singapore, I am sharing the below news article: News Article: NASA scientists achieve long-distance 'quantum teleportation' over 27 miles for the first time – paving the way for unhackable networks that transfer data faster than the speed of light Author: JOE PINKSTONE FOR MAILONLINE Date Published: 22 December 2020 Link: https://www.dailymail.co.uk/sciencetech/article-9078855/NASA-scientists-achieve-long-distance-quantum-teleportation-time.html Publisher: MailOnline UK Synopis: - Scientists built a 27-mile long prototype quantum internet in the US - They successfully used quantum entanglement to teleport signals instantly - The phenomenon sees qubits, the quantum equivalent of computer bits, pair up and respond instantly Scientists have demonstrated long-distance 'quantum teleportation' – the instant transfer of units of quantum information known as qubits – for the first time. The qubits were transferred faster than the speed of light over a distance of 27 miles, laying the foundations for a quantum internet service, which could one day revolutionise computing. Quantum communication systems are faster and more secure than regular networks because they use photons rather than computer code, which can be hacked. But their development relies on cutting-edge scientific theory which transforms our understanding of how computers work. In a quantum internet, information stored in qubits (the quantum equivalent of computer bits) is shuttled, or 'teleported', over long distances through entanglement. Entanglement is a phenomenon whereby two particles are linked in such a way that information shared with one is shared with the other at exactly the same time. This means that the quantum state of each particle is dependent on the state of the other – even when they are separated by a large distance. Quantum teleportation, therefore, is the transfer of quantum states from one location to the other. However, it is highly sensitive to environmental interference that can easily disrupt the quality or 'fidelity' of teleportation, so proving the theory in practice has been technologically challenging. In their latest experiment, researchers from Caltech, NASA, and Fermilab (Fermi National Accelerator Laboratory) built a unique system between two labs separated by 27 miles (44km). The system comprises three nodes which interact with one another to trigger a sequence of qubits, which pass a signal from one place to the other instantly. The 'teleportation' is instant, occurring faster than the speed of light, and the researchers reported a fidelity of more than 90 percent, according to the new study, published in PRX Quantum. Fidelity is used to measure how close the resulting qubit signal is to the original message that was sent. 'This high fidelity is important especially in the case of quantum networks designed to connect advanced quantum devices, including quantum sensors,' explains Professor Maria Spiropulu from Caltech. The findings of the project are crucial to hopes of a future quantum internet as well as pushing the boundaries of what scientists known about the quantum realm. Although the technology is yet to reach the point of being rolled out beyond sophisticated tests such as this, there are already plans for how policy makers will employ the technology. For example, the US Department of Energy hopes to erect a quantum network between its laboratories across the states. The power of a quantum computer running on quantum internet will likely exceed the speeds of the world's current most sophisticated supercomputers by around 100 trillion times. 'People on social media are asking if they should sign up for a quantum internet provider (jokingly of course),' Professor Spiropulu told Motherboard. 'We need (a lot) more R&D work.' WHAT IS QUANTUM ENTANGLEMENT? In quantum physics, entangled particles remain connected so that actions performed by one affects the behaviour of the other, even if they are separated by huge distances. This means if you measure, 'up' for the spin of one photon from an entangled pair, the spin of the other, measured an instant later, will be 'down' - even if the two are on opposite sides of the world. Entanglement takes place when a part of particles interact physically. For instance, a laser beam fired through a certain type of crystal can cause individual light particles to be split into pairs of entangled photons. The theory that so riled Einstein is also referred to as 'spooky action at a distance'. Einstein wasn't happy with theory, because it suggested that information could travel faster than light. Mr. Turritopsis Dohrnii Teo En Ming, 42 years old as of 23rd December 20
[PATCH 1/2] mmc: jz4740: remove unused struct component card_detect_irq
I have not found any user for this struct component. Signed-off-by: H. Nikolaus Schaller --- drivers/mmc/host/jz4740_mmc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/mmc/host/jz4740_mmc.c b/drivers/mmc/host/jz4740_mmc.c index a1f92fed2a55b7..b3c636edbb4610 100644 --- a/drivers/mmc/host/jz4740_mmc.c +++ b/drivers/mmc/host/jz4740_mmc.c @@ -152,7 +152,6 @@ struct jz4740_mmc_host { enum jz4740_mmc_version version; int irq; - int card_detect_irq; void __iomem *base; struct resource *mem_res; -- 2.26.2
[PATCH 2/2] mmc: omap: remove unused struct component card_detect_irq
I have not found any user for this struct component. Signed-off-by: H. Nikolaus Schaller --- include/linux/platform_data/mmc-omap.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/linux/platform_data/mmc-omap.h b/include/linux/platform_data/mmc-omap.h index f0b8947e6b07d8..91051e9907f34e 100644 --- a/include/linux/platform_data/mmc-omap.h +++ b/include/linux/platform_data/mmc-omap.h @@ -108,8 +108,7 @@ struct omap_mmc_platform_data { const char *name; u32 ocr_mask; - /* Card detection IRQs */ - int card_detect_irq; + /* Card detection */ int (*card_detect)(struct device *dev, int slot); unsigned int ban_openended:1; -- 2.26.2
[PATCH 0/2] mmc: remove unused struct component card_detect_irq
card_detect_irq is not used anymore since v4.1. Remove it. H. Nikolaus Schaller (2): mmc: jz4740: remove unused struct component card_detect_irq mmc: omap: remove unused struct component card_detect_irq drivers/mmc/host/jz4740_mmc.c | 1 - include/linux/platform_data/mmc-omap.h | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) -- 2.26.2
Re: [PATCH] erofs: support direct IO for uncompressed file
On Wed, Dec 23, 2020 at 08:54:01AM +, Christoph Hellwig wrote: > On Wed, Dec 23, 2020 at 04:48:20PM +0800, Huang Jianan wrote: > > Hi Christoph, > > > > The reason we use dio is because we need to deploy the patch on some early > > kernel versions, and we don't pay much attention to the change of iomap. > > No, that is never an excuse for upstream development. Ok, personally I also agree this, let's go further in this way. Thanks, Gao Xiang >
Re: [RFC PATCH v2 2/8] net: sparx5: add the basic sparx5 driver
Alexandre Belloni writes: > On 22/12/2020 16:01:22+0100, Andrew Lunn wrote: >> > The problem is that the switch core reset also affects (reset) the >> > SGPIO controller. >> > >> > We tried to put this in the reset driver, but it was rejected. If the >> > reset is done at probe time, the SGPIO driver may already have >> > initialized state. >> > >> > The switch core reset will then reset all SGPIO registers. >> >> Ah, O.K. Dumb question. Why is the SGPIO driver a separate driver? It >> sounds like it should be embedded inside this driver if it is sharing >> hardware. >> >> Another option would be to look at the reset subsystem, and have this >> driver export a reset controller, which the SGPIO driver can bind to. >> Given that the GPIO driver has been merged, if this will work, it is >> probably a better solution. >> > > That was my suggestion. Then you can ensure from the reset controller > driver that this is done exactly once, either from the sgpio driver or > from the switchdev driver. IIRC, the sgpio from the other SoCs are not > affected by the reset. I will take a look to see if we can change the implementation to use a reset controller. ---Lars -- Lars Povlsen, Microchip
[PATCH v2] vdpa_sim: use iova module to allocate IOVA addresses
The identical mapping used until now created issues when mapping different virtual pages with the same physical address. To solve this issue, we can use the iova module, to handle the IOVA allocation. For simplicity we use an IOVA allocator with byte granularity. We add two new functions, vdpasim_map_range() and vdpasim_unmap_range(), to handle the IOVA allocation and the registration into the IOMMU/IOTLB. These functions are used by dma_map_ops callbacks. Acked-by: Jason Wang Signed-off-by: Stefano Garzarella --- v2: - used ULONG_MAX instead of ~0UL [Jason] - fixed typos in comment and patch description [Jason] --- drivers/vdpa/vdpa_sim/vdpa_sim.h | 2 + drivers/vdpa/vdpa_sim/vdpa_sim.c | 108 +++ drivers/vdpa/Kconfig | 1 + 3 files changed, 69 insertions(+), 42 deletions(-) diff --git a/drivers/vdpa/vdpa_sim/vdpa_sim.h b/drivers/vdpa/vdpa_sim/vdpa_sim.h index b02142293d5b..6efe205e583e 100644 --- a/drivers/vdpa/vdpa_sim/vdpa_sim.h +++ b/drivers/vdpa/vdpa_sim/vdpa_sim.h @@ -6,6 +6,7 @@ #ifndef _VDPA_SIM_H #define _VDPA_SIM_H +#include #include #include #include @@ -55,6 +56,7 @@ struct vdpasim { /* virtio config according to device type */ void *config; struct vhost_iotlb *iommu; + struct iova_domain iova; void *buffer; u32 status; u32 generation; diff --git a/drivers/vdpa/vdpa_sim/vdpa_sim.c b/drivers/vdpa/vdpa_sim/vdpa_sim.c index b3fcc67bfdf0..edc930719fb8 100644 --- a/drivers/vdpa/vdpa_sim/vdpa_sim.c +++ b/drivers/vdpa/vdpa_sim/vdpa_sim.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "vdpa_sim.h" @@ -128,30 +129,57 @@ static int dir_to_perm(enum dma_data_direction dir) return perm; } +static dma_addr_t vdpasim_map_range(struct vdpasim *vdpasim, phys_addr_t paddr, + size_t size, unsigned int perm) +{ + struct iova *iova; + dma_addr_t dma_addr; + int ret; + + /* We set the limit_pfn to the maximum (ULONG_MAX - 1) */ + iova = alloc_iova(&vdpasim->iova, size, ULONG_MAX - 1, true); + if (!iova) + return DMA_MAPPING_ERROR; + + dma_addr = iova_dma_addr(&vdpasim->iova, iova); + + spin_lock(&vdpasim->iommu_lock); + ret = vhost_iotlb_add_range(vdpasim->iommu, (u64)dma_addr, + (u64)dma_addr + size - 1, (u64)paddr, perm); + spin_unlock(&vdpasim->iommu_lock); + + if (ret) { + __free_iova(&vdpasim->iova, iova); + return DMA_MAPPING_ERROR; + } + + return dma_addr; +} + +static void vdpasim_unmap_range(struct vdpasim *vdpasim, dma_addr_t dma_addr, + size_t size) +{ + spin_lock(&vdpasim->iommu_lock); + vhost_iotlb_del_range(vdpasim->iommu, (u64)dma_addr, + (u64)dma_addr + size - 1); + spin_unlock(&vdpasim->iommu_lock); + + free_iova(&vdpasim->iova, iova_pfn(&vdpasim->iova, dma_addr)); +} + static dma_addr_t vdpasim_map_page(struct device *dev, struct page *page, unsigned long offset, size_t size, enum dma_data_direction dir, unsigned long attrs) { struct vdpasim *vdpasim = dev_to_sim(dev); - struct vhost_iotlb *iommu = vdpasim->iommu; - u64 pa = (page_to_pfn(page) << PAGE_SHIFT) + offset; - int ret, perm = dir_to_perm(dir); + phys_addr_t paddr = page_to_phys(page) + offset; + int perm = dir_to_perm(dir); if (perm < 0) return DMA_MAPPING_ERROR; - /* For simplicity, use identical mapping to avoid e.g iova -* allocator. -*/ - spin_lock(&vdpasim->iommu_lock); - ret = vhost_iotlb_add_range(iommu, pa, pa + size - 1, - pa, dir_to_perm(dir)); - spin_unlock(&vdpasim->iommu_lock); - if (ret) - return DMA_MAPPING_ERROR; - - return (dma_addr_t)(pa); + return vdpasim_map_range(vdpasim, paddr, size, perm); } static void vdpasim_unmap_page(struct device *dev, dma_addr_t dma_addr, @@ -159,12 +187,8 @@ static void vdpasim_unmap_page(struct device *dev, dma_addr_t dma_addr, unsigned long attrs) { struct vdpasim *vdpasim = dev_to_sim(dev); - struct vhost_iotlb *iommu = vdpasim->iommu; - spin_lock(&vdpasim->iommu_lock); - vhost_iotlb_del_range(iommu, (u64)dma_addr, - (u64)dma_addr + size - 1); - spin_unlock(&vdpasim->iommu_lock); + vdpasim_unmap_range(vdpasim, dma_addr, size); } static void *vdpasim_alloc_coherent(struct device *dev, size_t size, @@ -172,27 +196,22 @@ static void *vdpasim_alloc_coherent(struct device *dev, size_t size, unsigned long attrs) { struct vdpasim *vdpasim = dev_to_sim
Re: [PATCH v5 1/7] scsi: ufs: Add "wb_on" sysfs node to control WB on/off
On Wed, 2020-12-23 at 09:31 +0800, Can Guo wrote: > And assume you come up with a better check, > you want to add the check everywhere? You must have noticed the fix > to > the func ufshcd_clk_gate_enable_store() from Jaegeuk Kim. Do you mean lock spin_lock_irqsave(hba->host->host_lock, flags)? It can completely fix race issue, but it is different with here. ufshcd_clkgate_enable_store() doesn't call ufshcd_hold(). If you want using this lock, we should change ufshcd_hold() and ufshcd_query_*(). Bean
Re: [PATCH v5 08/12] gpio: bd9571mwv: Add BD9574MWF support
Hello! On 22.12.2020 14:22, Yoshihiro Shimoda wrote: Add support for BD9574MWF which is silimar chip with BD9571MWV. Similar? :-) Note that BD9574MWF has additional features "RECOV_GPOUT", "FREQSEL" and "RTC_IN", but supports GPIO function only. Signed-off-by: Yoshihiro Shimoda Reviewed-by: Matti Vaittinen [...] MBR, Sergei
Re: [PATCH v5 05/12] regulator: bd9571mwv: Add BD9574MWF support
On 22.12.2020 14:22, Yoshihiro Shimoda wrote: Add support for BD9574MWF which is silimar chip with BD9571MWV. Similar (again)? :-) Note that we don't support voltage rails VD{09,18,25,33} by this driver on BD9574. The VD09 voltage could be read from PMIC but that is not supported by this commit. Signed-off-by: Yoshihiro Shimoda Reviewed-by: Matti Vaittinen [...] MBR, Sergei
RE: [PATCH v5 05/12] regulator: bd9571mwv: Add BD9574MWF support
Hi Sergei, > From: Sergei Shtylyov, Sent: Wednesday, December 23, 2020 6:15 PM > > On 22.12.2020 14:22, Yoshihiro Shimoda wrote: > > > Add support for BD9574MWF which is silimar chip with BD9571MWV. > > Similar (again)? :-) Thank you for pointed it out! I'll fix this and patch 8/12. Best regards, Yoshihiro Shimoda
[PATCH v8] dmaengine: mediatek-cqdma: add dt-bindings and remove redundant queue
This patch set adds document the devicetree bindings for MediaTek Command-Queue DMA controller, and remove redundant queue structure. hanges since v6: - fix dt binding format hanges since v5: - fix full name hanges since v4: - fix yaml & dma-mask code flow hanges since v3: - fix dt_binding_check errors Changes since v2: - add devicetree bindings for MediaTek Command-Queue DMA controller Changes since v1: - remove redundant queue structure - fix wrong description and tags in the earlier patch - add dma-channel-mask for DMA capability - fix compatible for common
[PATCH v8 4/4] dmaengine: mediatek-cqdma: fix compatible
This patch adds common compatible & platform compatiable. Signed-off-by: EastL Lee Reviewed-by: Matthias Brugger --- drivers/dma/mediatek/mtk-cqdma.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/dma/mediatek/mtk-cqdma.c b/drivers/dma/mediatek/mtk-cqdma.c index 1610632..17b3ab9 100644 --- a/drivers/dma/mediatek/mtk-cqdma.c +++ b/drivers/dma/mediatek/mtk-cqdma.c @@ -547,6 +547,7 @@ static void mtk_cqdma_hw_deinit(struct mtk_cqdma_device *cqdma) static const struct of_device_id mtk_cqdma_match[] = { { .compatible = "mediatek,mt6765-cqdma" }, + { .compatible = "mediatek,mt6779-cqdma" }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, mtk_cqdma_match); -- 1.9.1
[PATCH v8 2/4] dmaengine: mediatek-cqdma: remove redundant queue structure
This patch introduces active_vdec to indicate the virtual descriptor under processing by the CQDMA dmaengine, and simplify the control logic by removing redundant queue structure, tasklets, and completion management. Signed-off-by: EastL Lee --- drivers/dma/mediatek/mtk-cqdma.c | 382 ++- 1 file changed, 93 insertions(+), 289 deletions(-) diff --git a/drivers/dma/mediatek/mtk-cqdma.c b/drivers/dma/mediatek/mtk-cqdma.c index 41ef9f1..905bbcb 100644 --- a/drivers/dma/mediatek/mtk-cqdma.c +++ b/drivers/dma/mediatek/mtk-cqdma.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -47,7 +48,6 @@ #define MTK_CQDMA_SRC 0x1c #define MTK_CQDMA_DST 0x20 #define MTK_CQDMA_LEN1 0x24 -#define MTK_CQDMA_LEN2 0x28 #define MTK_CQDMA_SRC2 0x60 #define MTK_CQDMA_DST2 0x64 @@ -69,45 +69,32 @@ * descriptor (CVD) * @vd:An instance for struct virt_dma_desc * @len: The total data size device wants to move - * @residue: The remaining data size device will move * @dest: The destination address device wants to move to * @src: The source address device wants to move from * @ch:The pointer to the corresponding dma channel - * @node: The lise_head struct to build link-list for VDs - * @parent:The pointer to the parent CVD */ struct mtk_cqdma_vdesc { struct virt_dma_desc vd; size_t len; - size_t residue; dma_addr_t dest; dma_addr_t src; struct dma_chan *ch; - - struct list_head node; - struct mtk_cqdma_vdesc *parent; }; /** * struct mtk_cqdma_pchan - The struct holding info describing physical * channel (PC) - * @queue: Queue for the PDs issued to this PC + * @active_vdesc: The pointer to the CVD which is under processing * @base: The mapped register I/O base of this PC * @irq: The IRQ that this PC are using * @refcnt:Track how many VCs are using this PC - * @tasklet: Tasklet for this PC * @lock: Lock protect agaisting multiple VCs access PC */ struct mtk_cqdma_pchan { - struct list_head queue; + struct mtk_cqdma_vdesc *active_vdesc; void __iomem *base; u32 irq; - refcount_t refcnt; - - struct tasklet_struct tasklet; - - /* lock to protect PC */ spinlock_t lock; }; @@ -116,14 +103,11 @@ struct mtk_cqdma_pchan { * channel (VC) * @vc:An instance for struct virt_dma_chan * @pc:The pointer to the underlying PC - * @issue_completion: The wait for all issued descriptors completited - * @issue_synchronize:Bool indicating channel synchronization starts */ struct mtk_cqdma_vchan { struct virt_dma_chan vc; struct mtk_cqdma_pchan *pc; - struct completion issue_completion; - bool issue_synchronize; + struct completion cmp; }; /** @@ -202,22 +186,22 @@ static void mtk_cqdma_vdesc_free(struct virt_dma_desc *vd) kfree(to_cqdma_vdesc(vd)); } -static int mtk_cqdma_poll_engine_done(struct mtk_cqdma_pchan *pc, bool atomic) +static int mtk_cqdma_poll_engine_done(struct mtk_cqdma_pchan *pc) { u32 status = 0; - if (!atomic) + if (in_task()) + return readl_poll_timeout_atomic(pc->base + MTK_CQDMA_EN, +status, +!(status & MTK_CQDMA_EN_BIT), +MTK_CQDMA_USEC_POLL, +MTK_CQDMA_TIMEOUT_POLL); + else return readl_poll_timeout(pc->base + MTK_CQDMA_EN, status, !(status & MTK_CQDMA_EN_BIT), MTK_CQDMA_USEC_POLL, MTK_CQDMA_TIMEOUT_POLL); - - return readl_poll_timeout_atomic(pc->base + MTK_CQDMA_EN, -status, -!(status & MTK_CQDMA_EN_BIT), -MTK_CQDMA_USEC_POLL, -MTK_CQDMA_TIMEOUT_POLL); } static int mtk_cqdma_hard_reset(struct mtk_cqdma_pchan *pc) @@ -225,20 +209,17 @@ static int mtk_cqdma_hard_reset(struct mtk_cqdma_pchan *pc) mtk_dma_set(pc, MTK_CQDMA_RESET, MTK_CQDMA_HARD_RST_BIT); mtk_dma_clr(pc, MTK_CQDMA_RESET, MTK_CQDMA_HARD_RST_BIT); - return mtk_cqdma_poll_engine_done(pc, true); + return mtk_cqdma_poll_engine_don
[PATCH v8 3/4] dmaengine: mediatek-cqdma: add dma mask for capability
This patch add dma mask for capability. Signed-off-by: EastL Lee Reviewed-by: Matthias Brugger --- drivers/dma/mediatek/mtk-cqdma.c | 17 + 1 file changed, 17 insertions(+) diff --git a/drivers/dma/mediatek/mtk-cqdma.c b/drivers/dma/mediatek/mtk-cqdma.c index 905bbcb..1610632 100644 --- a/drivers/dma/mediatek/mtk-cqdma.c +++ b/drivers/dma/mediatek/mtk-cqdma.c @@ -117,6 +117,7 @@ struct mtk_cqdma_vchan { * @clk:The clock that device internal is using * @dma_requests: The number of VCs the device supports to * @dma_channels: The number of PCs the device supports to + * @dma_mask: A mask for DMA capability * @vc: The pointer to all available VCs * @pc: The pointer to all the underlying PCs */ @@ -126,6 +127,7 @@ struct mtk_cqdma_device { u32 dma_requests; u32 dma_channels; + u32 dma_mask; struct mtk_cqdma_vchan *vc; struct mtk_cqdma_pchan **pc; }; @@ -607,6 +609,21 @@ static int mtk_cqdma_probe(struct platform_device *pdev) cqdma->dma_channels = MTK_CQDMA_NR_PCHANS; } + if (pdev->dev.of_node) + err = of_property_read_u32(pdev->dev.of_node, + "dma-channel-mask", + &cqdma->dma_mask); + if (err) { + dev_warn(&pdev->dev, +"Using 0 as missing dma-channel-mask property\n"); + cqdma->dma_mask = 0; + } + + if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(cqdma->dma_mask))) { + dev_warn(&pdev->dev, "DMA set mask failed\n"); + return -EINVAL; + } + cqdma->pc = devm_kcalloc(&pdev->dev, cqdma->dma_channels, sizeof(*cqdma->pc), GFP_KERNEL); if (!cqdma->pc) -- 1.9.1
Re: [PATCH RFC v4 1/1] scsi: ufs: Fix ufs power down/on specs violation
On Tue, 2020-12-22 at 21:49 +0800, Ziqi Chen wrote: > As per specs, e.g, JESD220E chapter 7.2, while powering > off/on the ufs device, RST_N signal and REF_CLK signal > should be between VSS(Ground) and VCCQ/VCCQ2. > > To flexibly control device reset line, refactor the function > ufschd_vops_device_reset(sturct ufs_hba *hba) to ufshcd_ > vops_device_reset(sturct ufs_hba *hba, bool asserted). The > new parameter "bool asserted" is used to separate device reset > line pulling down from pulling up. > > Cc: Kiwoong Kim > Cc: Stanley Chu > Signed-off-by: Ziqi Chen Thanks for this fix including ufs-mediatek change as well. Reviewed-by: Stanley Chu Tested-by: Stanley Chu
[PATCH v8 1/4] dt-bindings: dmaengine: Add MediaTek Command-Queue DMA controller bindings
Document the devicetree bindings for MediaTek Command-Queue DMA controller which could be found on MT6779 SoC or other similar Mediatek SoCs. Signed-off-by: EastL Lee --- .../devicetree/bindings/dma/mtk-cqdma.yaml | 104 + 1 file changed, 104 insertions(+) create mode 100644 Documentation/devicetree/bindings/dma/mtk-cqdma.yaml diff --git a/Documentation/devicetree/bindings/dma/mtk-cqdma.yaml b/Documentation/devicetree/bindings/dma/mtk-cqdma.yaml new file mode 100644 index 000..a76a263 --- /dev/null +++ b/Documentation/devicetree/bindings/dma/mtk-cqdma.yaml @@ -0,0 +1,104 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/dma/mtk-cqdma.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek Command-Queue DMA controller Device Tree Binding + +maintainers: + - EastL Lee + +description: + MediaTek Command-Queue DMA controller (CQDMA) on Mediatek SoC + is dedicated to memory-to-memory transfer through queue based + descriptor management. + +allOf: + - $ref: "dma-controller.yaml#" + +properties: + compatible: +items: + - enum: + - mediatek,mt6765-cqdma + - mediatek,mt6779-cqdma + - const: mediatek,cqdma + + reg: +minItems: 1 +maxItems: 5 +description: +A base address of MediaTek Command-Queue DMA controller, +a channel will have a set of base address. + + interrupts: +minItems: 1 +maxItems: 5 +description: +A interrupt number of MediaTek Command-Queue DMA controller, +one interrupt number per dma-channels. + + clocks: +maxItems: 1 + + clock-names: +const: cqdma + + dma-channel-mask: +description: + For DMA capability, We will know the addressing capability of + MediaTek Command-Queue DMA controller through dma-channel-mask. + minimum: 1 + maximum: 63 + + dma-channels: +description: + Number of DMA channels supported by MediaTek Command-Queue DMA + controller, support up to five. + minimum: 1 + maximum: 5 + + dma-requests: +description: + Number of DMA request (virtual channel) supported by MediaTek + Command-Queue DMA controller, support up to 32. + minimum: 1 + maximum: 32 + +required: + - "#dma-cells" + - compatible + - reg + - interrupts + - clocks + - clock-names + - dma-channel-mask + - dma-channels + - dma-requests + +additionalProperties: false + +examples: + - | +#include +#include +#include +cqdma: dma-controller@10212000 { +compatible = "mediatek,mt6779-cqdma"; +reg = <0x10212000 0x80>, +<0x10212080 0x80>, +<0x10212100 0x80>; +interrupts = , +, +; +clocks = <&infracfg_ao CLK_INFRA_CQ_DMA>; +clock-names = "cqdma"; +dma-channel-mask = <63>; +dma-channels = <3>; +dma-requests = <32>; +#dma-cells = <1>; +}; + +... -- 1.9.1
[PATCH] tty: serial: cpm_uart: Add udbg support for enabling xmon
In order to use xmon with powerpc 8xx, the serial driver must provide udbg_putc() and udpb_getc(). Provide them via cpm_put_poll_char() and cpm_get_poll_char(). This requires CONFIG_CONSOLE_POLL. Signed-off-by: Christophe Leroy --- drivers/tty/serial/cpm_uart/cpm_uart_core.c | 40 - 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c index ba14ec5b9bc4..2920b9b602b3 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c @@ -1145,6 +1145,32 @@ static void cpm_put_poll_char(struct uart_port *port, ch[0] = (char)c; cpm_uart_early_write(pinfo, ch, 1, false); } + +static struct uart_port *udbg_port; + +static void udbg_cpm_putc(char c) +{ + if (c == '\n') + cpm_put_poll_char(udbg_port, '\r'); + cpm_put_poll_char(udbg_port, c); +} + +static int udbg_cpm_getc_poll(void) +{ + int c = cpm_get_poll_char(udbg_port); + + return c == NO_POLL_CHAR ? -1 : c; +} + +static int udbg_cpm_getc(void) +{ + int c; + + while ((c = udbg_cpm_getc_poll()) == -1) + cpu_relax(); + return c; +} + #endif /* CONFIG_CONSOLE_POLL */ static const struct uart_ops cpm_uart_pops = { @@ -1251,7 +1277,10 @@ static int cpm_uart_init_port(struct device_node *np, pinfo->gpios[i] = NULL; #ifdef CONFIG_PPC_EARLY_DEBUG_CPM - udbg_putc = NULL; +#ifdef CONFIG_CONSOLE_POLL + if (!udbg_port) +#endif + udbg_putc = NULL; #endif return cpm_uart_request_port(&pinfo->port); @@ -1370,6 +1399,15 @@ static int __init cpm_uart_console_setup(struct console *co, char *options) uart_set_options(port, co, baud, parity, bits, flow); cpm_line_cr_cmd(pinfo, CPM_CR_RESTART_TX); +#ifdef CONFIG_CONSOLE_POLL + if (!udbg_port) { + udbg_port = &pinfo->port; + udbg_putc = udbg_cpm_putc; + udbg_getc = udbg_cpm_getc; + udbg_getc_poll = udbg_cpm_getc_poll; + } +#endif + return 0; } -- 2.25.0
[PATCH] powerpc/xmon: Select CONSOLE_POLL for the 8xx
Powerpc 8xx requires CONSOLE_POLL to get udbg_putc() and udbg_getc() in CPM uart driver. Signed-off-by: Christophe Leroy --- arch/powerpc/Kconfig.debug | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug index b88900f4832f..ae084357994e 100644 --- a/arch/powerpc/Kconfig.debug +++ b/arch/powerpc/Kconfig.debug @@ -88,6 +88,7 @@ config PPC_IRQ_SOFT_MASK_DEBUG config XMON bool "Include xmon kernel debugger" depends on DEBUG_KERNEL + select CONSOLE_POLL if SERIAL_CPM_CONSOLE help Include in-kernel hooks for the xmon kernel monitor/debugger. Unless you are intending to debug the kernel, say N here. -- 2.25.0
[PATCH] powerpc/xmon: Enable breakpoints on 8xx
Since commit 4ad8622dc548 ("powerpc/8xx: Implement hw_breakpoint"), 8xx has breakpoints so there is no reason to opt breakpoint logic out of xmon for the 8xx. Signed-off-by: Christophe Leroy Fixes: 4ad8622dc548 ("powerpc/8xx: Implement hw_breakpoint") --- arch/powerpc/xmon/xmon.c | 4 1 file changed, 4 deletions(-) diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index dcd817ca2edf..cec432eb9189 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -1383,7 +1383,6 @@ static long check_bp_loc(unsigned long addr) return 1; } -#ifndef CONFIG_PPC_8xx static int find_free_data_bpt(void) { int i; @@ -1395,7 +1394,6 @@ static int find_free_data_bpt(void) printf("Couldn't find free breakpoint register\n"); return -1; } -#endif static void print_data_bpts(void) { @@ -1435,7 +1433,6 @@ bpt_cmds(void) cmd = inchar(); switch (cmd) { -#ifndef CONFIG_PPC_8xx static const char badaddr[] = "Only kernel addresses are permitted for breakpoints\n"; int mode; case 'd': /* bd - hardware data breakpoint */ @@ -1497,7 +1494,6 @@ bpt_cmds(void) force_enable_xmon(); } break; -#endif case 'c': if (!scanhex(&a)) { -- 2.25.0
Re: [PATCH] mm/userfaultfd: fix memory corruption due to writeprotect
On Tue, Dec 22, 2020 at 4:01 PM Linus Torvalds wrote: > > The more I look at the mprotect code, the less I like it. We seem to > be much better about the TLB flushes in other places (looking at > mremap, for example). The mprotect code seems to be very laissez-faire > about the TLB flushing. No, this doesn't help. > Does adding a TLB flush to before that > > pte_unmap_unlock(pte - 1, ptl); > > fix things for you? It really doesn't fix it. Exactly because - as pointed out earlier - the actual page *copy* happens outside the pte lock. So what can happen is: - CPU 1 holds the page table lock, while doing the write protect. It has cleared the writable bit, but hasn't flushed the TLB's yet - CPU 2 did *not* have the TLB entry, sees the new read-only state, takes a COW page fault, and reads the PTE from memory (into vmf->orig_pte) - CPU 2 correctly decides it needs to be a COW, and copies the page contents - CPU 3 *does* have a stale TLB (because TLB invalidation hasn't happened yet), and writes to that page in users apce - CPU 1 now does the TLB invalidate, and releases the page table lock - CPU 2 gets the page table lock, sees that its PTE matches vmf->orig_pte, and switches it to be that writable copy of the page. where the copy happened before CPU 3 had stopped writing to the page. So the pte lock doesn't actually matter, unless we actually do the page copy inside of it (on CPU2), in addition to doing the TLB flush inside of it (on CPU1). mprotect() is actually safe for two independent reasons: (a) it does the mmap_sem for writing (so mprotect can't race with the COW logic at all), and (b) it changes the vma permissions so turning something read-only actually disables COW anyway, since it won't be a COW, it will be a SIGSEGV. So mprotect() is irrelevant, other than the fact that it shares some code with that "turn it read-only in the page tables". fork() is a much closer operation, in that it actually triggers that COW behavior, but fork() takes the mmap_sem for writing, so it avoids this too. So it's really just userfaultfd and that kind of ilk that is relevant here, I think. But that "you need to flush the TLB before releasing the page table lock" was not true (well, it's true in other circumstances - just not *here*), and is not part of the solution. Or rather, if it's part of the solution here, it would have to be matched with that "page copy needs to be done under the page table lock too". Linus
Re: [PATCH] proc/wchan: Use printk format instead of lookup_symbol_name()
On 12/23/20 3:18 AM, Andrew Morton wrote: > On Thu, 17 Dec 2020 17:54:13 +0100 Helge Deller wrote: > >> To resolve the symbol fuction name for wchan, use the printk format >> specifier %ps instead of manually looking up the symbol function name >> via lookup_symbol_name(). >> >> Signed-off-by: Helge Deller >> > > Please don't forget the "^---$" to separate the changelog from the > diff. Ok. > >> #include >> @@ -386,19 +385,17 @@ static int proc_pid_wchan(struct seq_file *m, struct >> pid_namespace *ns, >>struct pid *pid, struct task_struct *task) >> { >> unsigned long wchan; >> -char symname[KSYM_NAME_LEN]; >> >> -if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) >> -goto print0; >> +if (ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) >> +wchan = get_wchan(task); >> +else >> +wchan = 0; >> >> -wchan = get_wchan(task); >> -if (wchan && !lookup_symbol_name(wchan, symname)) { >> -seq_puts(m, symname); >> -return 0; >> -} >> +if (wchan) >> +seq_printf(m, "%ps", (void *) wchan); >> +else >> +seq_putc(m, '0'); >> >> -print0: >> -seq_putc(m, '0'); >> return 0; >> } > > We can simplify this further? > > static int proc_pid_wchan(struct seq_file *m, struct pid_namespace *ns, > struct pid *pid, struct task_struct *task) > { > if (ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) > seq_printf(m, "%ps", (void *)get_wchan(task)); > else > seq_putc(m, '0'); > > return 0; > } > > > --- > a/fs/proc/base.c~proc-wchan-use-printk-format-instead-of-lookup_symbol_name-fix > +++ a/fs/proc/base.c > @@ -384,15 +384,8 @@ static const struct file_operations proc > static int proc_pid_wchan(struct seq_file *m, struct pid_namespace *ns, > struct pid *pid, struct task_struct *task) > { > - unsigned long wchan; > - > if (ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) > - wchan = get_wchan(task); > - else > - wchan = 0; > - > - if (wchan) > - seq_printf(m, "%ps", (void *) wchan); > + seq_printf(m, "%ps", (void *)get_wchan(task)); > else > seq_putc(m, '0'); get_wchan() does return NULL sometimes, in which case with your change now "0x0" instead of "0" gets printed. If that's acceptable, then your patch is Ok. Helge
[PATCH] sched: pull tasks when CPU is about to run SCHED_IDLE tasks
From: Chen Xiaoguang Before a CPU switches from running SCHED_NORMAL task to SCHED_IDLE task, trying to pull SCHED_NORMAL tasks from other CPU by doing load_balance first. Signed-off-by: Chen Xiaoguang Signed-off-by: Chen He --- kernel/sched/fair.c | 5 + 1 file changed, 5 insertions(+) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index ae7ceba..0a26132 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -7004,6 +7004,11 @@ struct task_struct * struct task_struct *p; int new_tasks; + if (prev && + fair_policy(prev->policy) && + sched_idle_cpu(rq->cpu)) + goto idle; + again: if (!sched_fair_runnable(rq)) goto idle; -- 1.8.3.1
Re: [PATCH v1 1/2] arm64: dts: mt6779: Support devapc
+add comments & reviewed-by Hanks On Wed, 2020-12-23 at 16:44 +0800, Neal Liu wrote: Support DEVAPC on MT6779 platforms by adding device node. Reviewed-by: Hanks Chen > Signed-off-by: Neal Liu > --- > arch/arm64/boot/dts/mediatek/mt6779.dtsi |8 > 1 file changed, 8 insertions(+) > > diff --git a/arch/arm64/boot/dts/mediatek/mt6779.dtsi > b/arch/arm64/boot/dts/mediatek/mt6779.dtsi > index 370f309..52ecfc7 100644 > --- a/arch/arm64/boot/dts/mediatek/mt6779.dtsi > +++ b/arch/arm64/boot/dts/mediatek/mt6779.dtsi > @@ -189,6 +189,14 @@ > #clock-cells = <1>; > }; > > + devapc: devapc@10207000 { > + compatible = "mediatek,mt6779-devapc"; > + reg = <0 0x10207000 0 0x1000>; > + interrupts = ; > + clocks = <&infracfg_ao CLK_INFRA_DEVICE_APC>; > + clock-names = "devapc-infra-clock"; > + }; > + > uart0: serial@11002000 { > compatible = "mediatek,mt6779-uart", >"mediatek,mt6577-uart";
[PATCH] staging: comedi: clean up debugging code in #if 0 or 1
There are a log of "#if 0" or "#if 1" in driver which cause warning when running checkpatch.pl, they are supposed to be cleaned up before release. Signed-off-by: Song Chen --- drivers/staging/comedi/drivers/cb_pcidas64.c | 95 -- drivers/staging/comedi/drivers/dt2801.c| 29 drivers/staging/comedi/drivers/ni_atmio16d.c | 9 --- drivers/staging/comedi/drivers/ni_mio_common.c | 37 +- drivers/staging/comedi/drivers/ni_mio_cs.c | 10 --- drivers/staging/comedi/drivers/ni_pcidio.c | 5 -- drivers/staging/comedi/drivers/ni_pcimio.c | 48 - drivers/staging/comedi/drivers/s526.c | 49 - drivers/staging/comedi/drivers/s626.c | 45 9 files changed, 1 insertion(+), 326 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index fa987bb..2d74ec9 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -998,101 +998,6 @@ static const struct pcidas64_board pcidas64_boards[] = { .ai_fifo= &ai_fifo_4020, .has_8255 = 1, }, -#if 0 - /* The device id for these boards is unknown */ - - [BOARD_PCIDAS6402_16_JR] = { - .name = "pci-das6402/16/jr", - .ai_se_chans= 64, - .ai_bits= 16, - .ai_speed = 5000, - .ao_nchan = 0, - .ao_scan_speed = 1, - .layout = LAYOUT_64XX, - .ai_range_table = &ai_ranges_64xx, - .ai_range_code = ai_range_code_64xx, - .ai_fifo= ai_fifo_64xx, - .has_8255 = 1, - }, - [BOARD_PCIDAS64_M1_16_JR] = { - .name = "pci-das64/m1/16/jr", - .ai_se_chans= 64, - .ai_bits= 16, - .ai_speed = 1000, - .ao_nchan = 0, - .ao_scan_speed = 1, - .layout = LAYOUT_64XX, - .ai_range_table = &ai_ranges_64_mx, - .ai_range_code = ai_range_code_64_mx, - .ai_fifo= ai_fifo_64xx, - .has_8255 = 1, - }, - [BOARD_PCIDAS64_M2_16_JR] = { - .name = "pci-das64/m2/16/jr", - .ai_se_chans= 64, - .ai_bits= 16, - .ai_speed = 500, - .ao_nchan = 0, - .ao_scan_speed = 1, - .layout = LAYOUT_64XX, - .ai_range_table = &ai_ranges_64_mx, - .ai_range_code = ai_range_code_64_mx, - .ai_fifo= ai_fifo_64xx, - .has_8255 = 1, - }, - [BOARD_PCIDAS64_M3_16_JR] = { - .name = "pci-das64/m3/16/jr", - .ai_se_chans= 64, - .ai_bits= 16, - .ai_speed = 333, - .ao_nchan = 0, - .ao_scan_speed = 1, - .layout = LAYOUT_64XX, - .ai_range_table = &ai_ranges_64_mx, - .ai_range_code = ai_range_code_64_mx, - .ai_fifo= ai_fifo_64xx, - .has_8255 = 1, - }, - [BOARD_PCIDAS64_M1_14] = { - .name = "pci-das64/m1/14", - .ai_se_chans= 64, - .ai_bits= 14, - .ai_speed = 1000, - .ao_nchan = 2, - .ao_scan_speed = 1, - .layout = LAYOUT_64XX, - .ai_range_table = &ai_ranges_64_mx, - .ai_range_code = ai_range_code_64_mx, - .ai_fifo= ai_fifo_64xx, - .has_8255 = 1, - }, - [BOARD_PCIDAS64_M2_14] = { - .name = "pci-das64/m2/14", - .ai_se_chans= 64, - .ai_bits= 14, - .ai_speed = 500, - .ao_nchan = 2, - .ao_scan_speed = 1, - .layout = LAYOUT_64XX, - .ai_range_table = &ai_ranges_64_mx, - .ai_range_code = ai_range_code_64_mx, - .ai_fifo= ai_fifo_64xx, - .has_8255 = 1, - }, - [BOARD_PCIDAS64_M3_14] = { - .name = "pci-das64/m3/14", - .ai_se_chans= 64, - .ai_bits= 14, - .ai_speed = 333, - .ao_nchan = 2, - .ao_scan_speed = 1, - .layout = LAYOUT_64XX, - .ai_range_table = &ai_ranges_64_mx, - .ai_range_code = ai_range_code_64_mx, - .ai_fifo= ai_fifo_64xx, - .has_8255
Re: [PATCH v2 2/4] arm64: dts: imx8mq-librem5: add pinctrl for the touchscreen description
On Tue, Dec 22, 2020 at 04:13:45PM +0100, Martin Kepplinger wrote: > In order for the touchscreen interrupt line to work, describe it properly. > Otherwise it can work if defaults are ok, but we cannot be sure. > > Fixes: 8f0216b006e5 ("arm64: dts: Add a device tree for the Librem 5 phone") > Signed-off-by: Martin Kepplinger > --- > arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi | 9 + > 1 file changed, 9 insertions(+) > Reviewed-by: Krzysztof Kozlowski Best regards, Krzysztof
Re: [PATCH] ubifs: Fix read out-of-bounds in ubifs_jnl_write_inode()
Chengsong Ke, - Ursprüngliche Mail - > The memory area allocated in ubifs_jnl_write_inode() is not aligned with 8 > bytes: > ino_start = ino = kmalloc(write_len, GFP_NOFS); > > When ino_start passed into write_head -> ubifs_wbuf_write_nolock: >n = aligned_len >> c->max_write_shift; >if (n) { > n <<= c->max_write_shift; > err = ubifs_leb_write(c, wbuf->lnum, buf + written, wbuf->offs, n); > // Read oob occurs here, read n bytes from buf, and buf is passed from > @ino_start which is > // not 8 bytes aligned(write_len < n). Program read (n - write_len) more > bytes. >} > > Reproducer: > 0. config KASAN && apply print.patch > 1. mount ubifs on /root/temp > 2. run test.sh > 3. cd /root/temp && ls // change atime for link_file > 4. wait 1~2 minutes > > Cc: > Fixes: 1e51764a3c2ac0 ("UBIFS: add new flash file system") > Link: https://bugzilla.kernel.org/show_bug.cgi?id=210865 > > Signed-off-by: Chengsong Ke > --- > fs/ubifs/io.c | 11 +-- > 1 file changed, 9 insertions(+), 2 deletions(-) Good catch! Please address the problem in ubifs_jnl_write_inode(). The length there needs to be properly aligned like all other journal functions do. I think you managed to trigger the issue because ui->data_len is not aligned. Thanks, //richard
Re: [PATCH v2 3/4] arm64: dts: imx8mq-librem5: Move usdhc clocks assignment to board DT
On Tue, Dec 22, 2020 at 04:13:46PM +0100, Martin Kepplinger wrote: > According to commit e045f044e84e ("arm64: dts: imx8mq: Move usdhc clocks > assignment to board DT") add the clocks assignment to imx8mq-librem5.dtsi > too. > > Fixes: e045f044e84e ("arm64: dts: imx8mq: Move usdhc clocks assignment to > board DT") > Signed-off-by: Martin Kepplinger > --- > arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi | 4 > 1 file changed, 4 insertions(+) Reviewed-by: Krzysztof Kozlowski Best regards, Krzysztof
[PATCH 02/11] coresight: Do not scan for graph if none is present
From: Suzuki K Poulose If a graph node is not found for a given node, of_get_next_endpoint() will emit the following error message : OF: graph: no port node found in / If the given component doesn't have any explicit connections (e.g, ETE) we could simply ignore the graph parsing. Cc: Mathieu Poirier Cc: Mike Leach Signed-off-by: Suzuki K Poulose Signed-off-by: Anshuman Khandual --- drivers/hwtracing/coresight/coresight-platform.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c index 3629b78..c594f45 100644 --- a/drivers/hwtracing/coresight/coresight-platform.c +++ b/drivers/hwtracing/coresight/coresight-platform.c @@ -90,6 +90,12 @@ static void of_coresight_get_ports_legacy(const struct device_node *node, struct of_endpoint endpoint; int in = 0, out = 0; + /* +* Avoid warnings in of_graph_get_next_endpoint() +* if the device doesn't have any graph connections +*/ + if (!of_graph_is_present(node)) + return; do { ep = of_graph_get_next_endpoint(node, ep); if (!ep) -- 2.7.4
[PATCH 00/11] arm64: coresight: Enable ETE and TRBE
This series enables future IP trace features Embedded Trace Extension (ETE) and Trace Buffer Extension (TRBE). This series depends on the ETM system register instruction support series [0] which is available here [1]. This series which applies on [1] is avaialble here [2] for quick access. ETE is the PE (CPU) trace unit for CPUs, implementing future architecture extensions. ETE overlaps with the ETMv4 architecture, with additions to support the newer architecture features and some restrictions on the supported features w.r.t ETMv4. The ETE support is added by extending the ETMv4 driver to recognise the ETE and handle the features as exposed by the TRCIDRx registers. ETE only supports system instructions access from the host CPU. The ETE could be integrated with a TRBE (see below), or with the legacy CoreSight trace bus (e.g, ETRs). Thus the ETE follows same firmware description as the ETMs and requires a node per instance. Trace Buffer Extensions (TRBE) implements a per CPU trace buffer, which is accessible via the system registers and can be combined with the ETE to provide a 1x1 configuration of source & sink. TRBE is being represented here as a CoreSight sink. Primary reason is that the ETE source could work with other traditional CoreSight sink devices. As TRBE captures the trace data which is produced by ETE, it cannot work alone. TRBE representation here have some distinct deviations from a traditional CoreSight sink device. Coresight path between ETE and TRBE are not built during boot looking at respective DT or ACPI entries. Unlike traditional sinks, TRBE can generate interrupts to signal including many other things, buffer got filled. The interrupt is a PPI and should be communicated from the platform. DT or ACPI entry representing TRBE should have the PPI number for a given platform. During perf session, the TRBE IRQ handler should capture trace for perf auxiliary buffer before restarting it back. System registers being used here to configure ETE and TRBE could be referred in the link below. https://developer.arm.com/docs/ddi0601/g/aarch64-system-registers. Things todo: - Improve TRBE IRQ handling for all possible corner cases - Implement sysfs based trace sessions [0] https://lore.kernel.org/linux-arm-kernel/20201214173731.302520-1-suzuki.poul...@arm.com/ [1] https://gitlab.arm.com/linux-arm/linux-skp/-/tree/coresight/etm/sysreg-v5 [2] https://gitlab.arm.com/linux-arm/linux-anshuman/-/tree/coresight/ete_trbe_v1 Changes in V1: - There are not much ETE changes from Suzuki apart from splitting of the ETE DTS patch - TRBE changes have been captured in the respective patches Changes in RFC: https://lore.kernel.org/linux-arm-kernel/1605012309-24812-1-git-send-email-anshuman.khand...@arm.com/ Cc: Mathieu Poirier Cc: Suzuki K Poulose Cc: Mike Leach Cc: Linu Cherian Cc: coresi...@lists.linaro.org Cc: linux-arm-ker...@lists.infradead.org Cc: linux-kernel@vger.kernel.org Anshuman Khandual (5): arm64: Add TRBE definitions coresight: core: Add support for dedicated percpu sinks coresight: etm-perf: Truncate the perf record if handle has no space coresight: sink: Add TRBE driver dts: bindings: Document device tree binding for Arm TRBE Suzuki K Poulose (6): coresight: etm-perf: Allow an event to use different sinks coresight: Do not scan for graph if none is present coresight: etm4x: Add support for PE OS lock coresight: ete: Add support for ETE sysreg access coresight: ete: Add support for ETE tracing dts: bindings: Document device tree bindings for ETE Documentation/devicetree/bindings/arm/ete.txt | 41 + Documentation/devicetree/bindings/arm/trbe.txt | 20 + Documentation/trace/coresight/coresight-trbe.rst | 39 + arch/arm64/include/asm/sysreg.h| 51 ++ drivers/hwtracing/coresight/Kconfig| 11 + drivers/hwtracing/coresight/Makefile | 1 + drivers/hwtracing/coresight/coresight-core.c | 14 + drivers/hwtracing/coresight/coresight-etm-perf.c | 51 +- drivers/hwtracing/coresight/coresight-etm4x-core.c | 138 ++- drivers/hwtracing/coresight/coresight-etm4x.h | 64 +- drivers/hwtracing/coresight/coresight-platform.c | 6 + drivers/hwtracing/coresight/coresight-trbe.c | 925 + drivers/hwtracing/coresight/coresight-trbe.h | 248 ++ include/linux/coresight.h | 12 + 14 files changed, 1580 insertions(+), 41 deletions(-) create mode 100644 Documentation/devicetree/bindings/arm/ete.txt create mode 100644 Documentation/devicetree/bindings/arm/trbe.txt create mode 100644 Documentation/trace/coresight/coresight-trbe.rst create mode 100644 drivers/hwtracing/coresight/coresight-trbe.c create mode 100644 drivers/hwtracing/coresight/coresight-trbe.h -- 2.7.4
[PATCH 03/11] coresight: etm4x: Add support for PE OS lock
From: Suzuki K Poulose ETE may not implement the OS lock and instead could rely on the PE OS Lock for the trace unit access. This is indicated by the TRCOLSR.OSM == 0b100. Add support for handling the PE OS lock Cc: Mathieu Poirier Cc: Mike Leach Signed-off-by: Suzuki K Poulose Signed-off-by: Anshuman Khandual --- drivers/hwtracing/coresight/coresight-etm4x-core.c | 50 ++ drivers/hwtracing/coresight/coresight-etm4x.h | 15 +++ 2 files changed, 56 insertions(+), 9 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c index 3d62acb..31d65f3 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c @@ -110,30 +110,59 @@ void etm4x_sysreg_write(u64 val, u32 offset, bool _relaxed, bool _64bit) } } -static void etm4_os_unlock_csa(struct etmv4_drvdata *drvdata, struct csdev_access *csa) +static void etm_detect_os_lock(struct etmv4_drvdata *drvdata, + struct csdev_access *csa) { - /* Writing 0 to TRCOSLAR unlocks the trace registers */ - etm4x_relaxed_write32(csa, 0x0, TRCOSLAR); - drvdata->os_unlock = true; + u32 oslsr = etm4x_relaxed_read32(csa, TRCOSLSR); + + drvdata->os_lock_model = ETM_OSLSR_OSLM(oslsr); +} + +static void etm_write_os_lock(struct etmv4_drvdata *drvdata, + struct csdev_access *csa, u32 val) +{ + val = !!val; + + switch (drvdata->os_lock_model) { + case ETM_OSLOCK_PRESENT: + etm4x_relaxed_write32(csa, val, TRCOSLAR); + break; + case ETM_OSLOCK_PE: + write_sysreg_s(val, SYS_OSLAR_EL1); + break; + default: + pr_warn_once("CPU%d: Unsupported Trace OSLock model: %x\n", +smp_processor_id(), drvdata->os_lock_model); + fallthrough; + case ETM_OSLOCK_NI: + return; + } isb(); } +static inline void etm4_os_unlock_csa(struct etmv4_drvdata *drvdata, + struct csdev_access *csa) +{ + WARN_ON(drvdata->cpu != smp_processor_id()); + + /* Writing 0 to OS Lock unlocks the trace unit registers */ + etm_write_os_lock(drvdata, csa, 0x0); + drvdata->os_unlock = true; +} + static void etm4_os_unlock(struct etmv4_drvdata *drvdata) { if (!WARN_ON(!drvdata->csdev)) etm4_os_unlock_csa(drvdata, &drvdata->csdev->access); - } static void etm4_os_lock(struct etmv4_drvdata *drvdata) { if (WARN_ON(!drvdata->csdev)) return; - - /* Writing 0x1 to TRCOSLAR locks the trace registers */ - etm4x_relaxed_write32(&drvdata->csdev->access, 0x1, TRCOSLAR); + /* Writing 0x1 to OS Lock locks the trace registers */ + etm_write_os_lock(drvdata, &drvdata->csdev->access, 0x1); drvdata->os_unlock = false; - isb(); } static void etm4_cs_lock(struct etmv4_drvdata *drvdata, @@ -807,6 +836,9 @@ static void etm4_init_arch_data(void *info) if (!etm4_init_csdev_access(drvdata, csa)) return; + /* Detect the support for OS Lock before we actuall use it */ + etm_detect_os_lock(drvdata, csa); + /* Make sure all registers are accessible */ etm4_os_unlock_csa(drvdata, csa); etm4_cs_unlock(drvdata, csa); diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h index 7a6e3cd..69af577 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.h +++ b/drivers/hwtracing/coresight/coresight-etm4x.h @@ -498,6 +498,20 @@ ETM_MODE_EXCL_USER) /* + * TRCOSLSR.OSLM advertises the OS Lock model. + * OSLM[2:0] = TRCOSLSR[4:3,0] + * + * 0b000 - Trace OS Lock is not implemented. + * 0b010 - Trace OS Lock is implemented. + * 0b100 - Trace OS Lock is not implemented, unit is controlled by PE OS Lock. + */ +#define ETM_OSLOCK_NI 0b000 +#define ETM_OSLOCK_PRESENT 0b010 +#define ETM_OSLOCK_PE 0b100 + +#define ETM_OSLSR_OSLM(oslsr) oslsr) & GENMASK(4, 3)) >> 2) | (oslsr & 0x1)) + +/* * TRCDEVARCH Bit field definitions * Bits[31:21] - ARCHITECT = Always Arm Ltd. ** Bits[31:28] = 0x4 @@ -883,6 +897,7 @@ struct etmv4_drvdata { u8 s_ex_level; u8 ns_ex_level; u8 q_support; + u8 os_lock_model; boolsticky_enable; boolboot_enable; boolos_unlock; -- 2.7.4
[PATCH 04/11] coresight: ete: Add support for ETE sysreg access
From: Suzuki K Poulose Add support for handling the system registers for Embedded Trace Extensions (ETE). ETE shares most of the registers with ETMv4 except for some and also adds some new registers. Re-arrange the ETMv4x list to share the common definitions and add the ETE sysreg support. Cc: Mike Leach Cc: Mathieu Poirier Signed-off-by: Suzuki K Poulose Signed-off-by: Anshuman Khandual --- drivers/hwtracing/coresight/coresight-etm4x-core.c | 32 + drivers/hwtracing/coresight/coresight-etm4x.h | 42 +- 2 files changed, 65 insertions(+), 9 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c index 31d65f3..dff502f 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c @@ -110,6 +110,38 @@ void etm4x_sysreg_write(u64 val, u32 offset, bool _relaxed, bool _64bit) } } +u64 ete_sysreg_read(u32 offset, bool _relaxed, bool _64bit) +{ + u64 res = 0; + + switch (offset) { + ETE_READ_CASES(res) + default : + WARN_ONCE(1, "ete: trying to read unsupported register @%x\n", +offset); + } + + if (!_relaxed) + __iormb(res); /* Imitate the !relaxed I/O helpers */ + + return res; +} + +void ete_sysreg_write(u64 val, u32 offset, bool _relaxed, bool _64bit) +{ + if (!_relaxed) + __iowmb(); /* Imitate the !relaxed I/O helpers */ + if (!_64bit) + val &= GENMASK(31, 0); + + switch (offset) { + ETE_WRITE_CASES(val) + default : + WARN_ONCE(1, "ete: trying to write to unsupported register @%x\n", + offset); + } +} + static void etm_detect_os_lock(struct etmv4_drvdata *drvdata, struct csdev_access *csa) { diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h index 69af577..6f64f08 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.h +++ b/drivers/hwtracing/coresight/coresight-etm4x.h @@ -28,6 +28,7 @@ #define TRCAUXCTLR 0x018 #define TRCEVENTCTL0R 0x020 #define TRCEVENTCTL1R 0x024 +#define TRCRSR 0x028 #define TRCSTALLCTLR 0x02C #define TRCTSCTLR 0x030 #define TRCSYNCPR 0x034 @@ -48,6 +49,7 @@ #define TRCSEQRSTEVR 0x118 #define TRCSEQSTR 0x11C #define TRCEXTINSELR 0x120 +#define TRCEXTINSELRn(n) (0x120 + (n * 4)) /* n = 0-3 */ #define TRCCNTRLDVRn(n)(0x140 + (n * 4)) /* n = 0-3 */ #define TRCCNTCTLRn(n) (0x150 + (n * 4)) /* n = 0-3 */ #define TRCCNTVRn(n) (0x160 + (n * 4)) /* n = 0-3 */ @@ -156,9 +158,22 @@ #define CASE_WRITE(val, x) \ case (x): { write_etm4x_sysreg_const_offset((val), (x)); break; } -#define CASE_LIST(op, val) \ - CASE_##op((val), TRCPRGCTLR)\ +#define ETE_ONLY_LIST(op, val) \ + CASE_##op((val), TRCRSR)\ + CASE_##op((val), TRCEXTINSELRn(1)) \ + CASE_##op((val), TRCEXTINSELRn(2)) \ + CASE_##op((val), TRCEXTINSELRn(3)) + +#define ETM_ONLY_LIST(op, val) \ CASE_##op((val), TRCPROCSELR) \ + CASE_##op((val), TRCVDCTLR) \ + CASE_##op((val), TRCVDSACCTLR) \ + CASE_##op((val), TRCVDARCCTLR) \ + CASE_##op((val), TRCITCTRL) \ + CASE_##op((val), TRCOSLAR) + +#define COMMON_LIST(op, val) \ + CASE_##op((val), TRCPRGCTLR)\ CASE_##op((val), TRCSTATR) \ CASE_##op((val), TRCCONFIGR)\ CASE_##op((val), TRCAUXCTLR)\ @@ -175,9 +190,6 @@ CASE_##op((val), TRCVIIECTLR) \ CASE_##op((val), TRCVISSCTLR) \ CASE_##op((val), TRCVIPCSSCTLR) \ - CASE_##op((val), TRCVDCTLR) \ - CASE_##op((val), TRCVDSACCTLR) \ - CASE_##op((val), TRCVDARCCTLR) \ CASE_##op((val), TRCSEQEVRn(0)) \ CASE_##op((val), TRCSEQEVRn(1)) \ CASE_##op((val), TRCSEQEVRn(2)) \ @@ -272,7 +284,6 @@ CASE_##op((val), TRCSSPCICRn(5))\ CASE_##op((val), TRCSSPCICRn(6))\ CASE_##op((val), TRCSSPCICRn(7))\ - CASE_##op((val), TRCOSLAR) \ CASE_##op((val), TRCOSLSR) \ CASE_##op((val), TRCPDCR) \ CASE_##op((val), TRCPDSR) \ @@ -344,7 +355,6 @@ CASE_##op((val), TRCCIDCCTLR1) \ CASE_##op((val)
Re: [PATCH bpf-next] xsk: build skb by page
On Wed, Dec 23, 2020 at 9:57 AM Xuan Zhuo wrote: > > This patch is used to construct skb based on page to save memory copy > overhead. > > Taking into account the problem of addr unaligned, and the > possibility of frame size greater than page in the future. Thanks Xuan for the patch set. Could you please share performance numbers so we know how much this buys us? Would be good if you could produce them for 64 bytes, 1500 bytes and something in the middle so we can judge the benefits of this. Please note that responses will be delayed this week and next due to the Christmas and New Years holidays over here. > Signed-off-by: Xuan Zhuo > --- > net/xdp/xsk.c | 68 > --- > 1 file changed, 51 insertions(+), 17 deletions(-) > > diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c > index ac4a317..7cab40f 100644 > --- a/net/xdp/xsk.c > +++ b/net/xdp/xsk.c > @@ -430,6 +430,55 @@ static void xsk_destruct_skb(struct sk_buff *skb) > sock_wfree(skb); > } > > +static struct sk_buff *xsk_build_skb_bypage(struct xdp_sock *xs, struct > xdp_desc *desc) > +{ > + char *buffer; > + u64 addr; > + u32 len, offset, copy, copied; > + int err, i; > + struct page *page; > + struct sk_buff *skb; > + > + skb = sock_alloc_send_skb(&xs->sk, 0, 1, &err); > + if (unlikely(!skb)) > + return NULL; > + > + addr = desc->addr; > + len = desc->len; > + > + buffer = xsk_buff_raw_get_data(xs->pool, addr); > + offset = offset_in_page(buffer); > + addr = buffer - (char *)xs->pool->addrs; > + > + for (copied = 0, i = 0; copied < len; ++i) { > + page = xs->pool->umem->pgs[addr >> PAGE_SHIFT]; > + > + get_page(page); > + > + copy = min((u32)(PAGE_SIZE - offset), len - copied); > + > + skb_fill_page_desc(skb, i, page, offset, copy); > + > + copied += copy; > + addr += copy; > + offset = 0; > + } > + > + skb->len += len; > + skb->data_len += len; > + skb->truesize += len; > + > + refcount_add(len, &xs->sk.sk_wmem_alloc); > + > + skb->dev = xs->dev; > + skb->priority = xs->sk.sk_priority; > + skb->mark = xs->sk.sk_mark; > + skb_shinfo(skb)->destructor_arg = (void *)(long)addr; > + skb->destructor = xsk_destruct_skb; > + > + return skb; > +} > + > static int xsk_generic_xmit(struct sock *sk) > { > struct xdp_sock *xs = xdp_sk(sk); > @@ -445,40 +494,25 @@ static int xsk_generic_xmit(struct sock *sk) > goto out; > > while (xskq_cons_peek_desc(xs->tx, &desc, xs->pool)) { > - char *buffer; > - u64 addr; > - u32 len; > - > if (max_batch-- == 0) { > err = -EAGAIN; > goto out; > } > > - len = desc.len; > - skb = sock_alloc_send_skb(sk, len, 1, &err); > + skb = xsk_build_skb_bypage(xs, &desc); > if (unlikely(!skb)) > goto out; > > - skb_put(skb, len); > - addr = desc.addr; > - buffer = xsk_buff_raw_get_data(xs->pool, addr); > - err = skb_store_bits(skb, 0, buffer, len); > /* This is the backpressure mechanism for the Tx path. > * Reserve space in the completion queue and only proceed > * if there is space in it. This avoids having to implement > * any buffering in the Tx path. > */ > - if (unlikely(err) || xskq_prod_reserve(xs->pool->cq)) { > + if (xskq_prod_reserve(xs->pool->cq)) { > kfree_skb(skb); > goto out; > } > > - skb->dev = xs->dev; > - skb->priority = sk->sk_priority; > - skb->mark = sk->sk_mark; > - skb_shinfo(skb)->destructor_arg = (void *)(long)desc.addr; > - skb->destructor = xsk_destruct_skb; > - > err = __dev_direct_xmit(skb, xs->queue_id); > if (err == NETDEV_TX_BUSY) { > /* Tell user-space to retry the send */ > -- > 1.8.3.1 >
[PATCH 01/11] coresight: etm-perf: Allow an event to use different sinks
From: Suzuki K Poulose When there are multiple sinks on the system, in the absence of a specified sink, it is quite possible that a default sink for an ETM could be different from that of another ETM. However we do not support having multiple sinks for an event yet. This patch allows the event to use the default sinks on the ETMs where they are scheduled as long as the sinks are of the same type. e.g, if we have 1x1 topology with per-CPU ETRs, the event can use the per-CPU ETR for the session. However, if the sinks are of different type, e.g TMC-ETR on one and a custom sink on another, the event will only trace on the first detected sink. Cc: Mathieu Poirier Cc: Mike Leach Tested-by: Linu Cherian Signed-off-by: Suzuki K Poulose Signed-off-by: Anshuman Khandual --- drivers/hwtracing/coresight/coresight-etm-perf.c | 48 +++- 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c index bdc34ca..eb9e7e9 100644 --- a/drivers/hwtracing/coresight/coresight-etm-perf.c +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c @@ -204,6 +204,13 @@ static void etm_free_aux(void *data) schedule_work(&event_data->work); } +static bool sinks_match(struct coresight_device *a, struct coresight_device *b) +{ + if (!a || !b) + return false; + return (sink_ops(a) == sink_ops(b)); +} + static void *etm_setup_aux(struct perf_event *event, void **pages, int nr_pages, bool overwrite) { @@ -212,6 +219,7 @@ static void *etm_setup_aux(struct perf_event *event, void **pages, cpumask_t *mask; struct coresight_device *sink = NULL; struct etm_event_data *event_data = NULL; + bool sink_forced = false; event_data = alloc_event_data(cpu); if (!event_data) @@ -222,6 +230,7 @@ static void *etm_setup_aux(struct perf_event *event, void **pages, if (event->attr.config2) { id = (u32)event->attr.config2; sink = coresight_get_sink_by_id(id); + sink_forced = true; } mask = &event_data->mask; @@ -235,7 +244,7 @@ static void *etm_setup_aux(struct perf_event *event, void **pages, */ for_each_cpu(cpu, mask) { struct list_head *path; - struct coresight_device *csdev; + struct coresight_device *csdev, *new_sink; csdev = per_cpu(csdev_src, cpu); /* @@ -249,21 +258,35 @@ static void *etm_setup_aux(struct perf_event *event, void **pages, } /* -* No sink provided - look for a default sink for one of the -* devices. At present we only support topology where all CPUs -* use the same sink [N:1], so only need to find one sink. The -* coresight_build_path later will remove any CPU that does not -* attach to the sink, or if we have not found a sink. +* No sink provided - look for a default sink for all the devices. +* We only support multiple sinks, only if all the default sinks +* are of the same type, so that the sink buffer can be shared +* as the event moves around. We don't trace on a CPU if it can't +* */ - if (!sink) - sink = coresight_find_default_sink(csdev); + if (!sink_forced) { + new_sink = coresight_find_default_sink(csdev); + if (!new_sink) { + cpumask_clear_cpu(cpu, mask); + continue; + } + /* Skip checks for the first sink */ + if (!sink) { + sink = new_sink; + } else if (!sinks_match(new_sink, sink)) { + cpumask_clear_cpu(cpu, mask); + continue; + } + } else { + new_sink = sink; + } /* * Building a path doesn't enable it, it simply builds a * list of devices from source to sink that can be * referenced later when the path is actually needed. */ - path = coresight_build_path(csdev, sink); + path = coresight_build_path(csdev, new_sink); if (IS_ERR(path)) { cpumask_clear_cpu(cpu, mask); continue; @@ -284,7 +307,12 @@ static void *etm_setup_aux(struct perf_event *event, void **pages, if (!sink_ops(sink)->alloc_buffer || !sink_ops(sink)->free_buffer) goto err; - /* Allocate the sink buffer for this session */ + /* +
[PATCH 05/11] coresight: ete: Add support for ETE tracing
From: Suzuki K Poulose Add ETE as one of the supported device types we support with ETM4x driver. The devices are named following the existing convention as ete. ETE mandates that the trace resource status register is programmed before the tracing is turned on. For the moment simply write to it indicating TraceActive. Cc: Mathieu Poirier Cc: Mike Leach Signed-off-by: Suzuki K Poulose Signed-off-by: Anshuman Khandual --- drivers/hwtracing/coresight/coresight-etm4x-core.c | 56 +- drivers/hwtracing/coresight/coresight-etm4x.h | 7 +++ 2 files changed, 50 insertions(+), 13 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c index dff502f..1af6ae0 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c @@ -333,6 +333,13 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata) etm4x_relaxed_write32(csa, trcpdcr | TRCPDCR_PU, TRCPDCR); } + /* +* ETE mandates that the TRCRSR is written to before +* enabling it. +*/ + if (drvdata->arch >= ETM_ARCH_ETE) + etm4x_relaxed_write32(csa, TRCRSR_TA, TRCRSR); + /* Enable the trace unit */ etm4x_relaxed_write32(csa, 1, TRCPRGCTLR); @@ -765,13 +772,24 @@ static bool etm4_init_sysreg_access(struct etmv4_drvdata *drvdata, * ETMs implementing sysreg access must implement TRCDEVARCH. */ devarch = read_etm4x_sysreg_const_offset(TRCDEVARCH); - if ((devarch & ETM_DEVARCH_ID_MASK) != ETM_DEVARCH_ETMv4x_ARCH) + switch (devarch & ETM_DEVARCH_ID_MASK) { + case ETM_DEVARCH_ETMv4x_ARCH: + *csa = (struct csdev_access) { + .io_mem = false, + .read = etm4x_sysreg_read, + .write = etm4x_sysreg_write, + }; + break; + case ETM_DEVARCH_ETE_ARCH: + *csa = (struct csdev_access) { + .io_mem = false, + .read = ete_sysreg_read, + .write = ete_sysreg_write, + }; + break; + default: return false; - *csa = (struct csdev_access) { - .io_mem = false, - .read = etm4x_sysreg_read, - .write = etm4x_sysreg_write, - }; + } drvdata->arch = etm_devarch_to_arch(devarch); return true; @@ -1707,6 +1725,8 @@ static int etm4_probe(struct device *dev, void __iomem *base) struct etmv4_drvdata *drvdata; struct coresight_desc desc = { 0 }; struct etm4_init_arg init_arg = { 0 }; + u8 major, minor; + char *type_name; drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) @@ -1733,10 +1753,6 @@ static int etm4_probe(struct device *dev, void __iomem *base) if (drvdata->cpu < 0) return drvdata->cpu; - desc.name = devm_kasprintf(dev, GFP_KERNEL, "etm%d", drvdata->cpu); - if (!desc.name) - return -ENOMEM; - init_arg.drvdata = drvdata; init_arg.csa = &desc.access; @@ -1751,6 +1767,20 @@ static int etm4_probe(struct device *dev, void __iomem *base) if (!desc.access.io_mem || fwnode_property_present(dev_fwnode(dev), "qcom,skip-power-up")) drvdata->skip_power_up = true; + major = ETM_ARCH_MAJOR_VERSION(drvdata->arch); + minor = ETM_ARCH_MINOR_VERSION(drvdata->arch); + if (drvdata->arch >= ETM_ARCH_ETE) { + type_name = "ete"; + /* ETE v1 has major version == 5. Adjust this for logging.*/ + major -= 4; + } else { + type_name = "etm"; + } + + desc.name = devm_kasprintf(dev, GFP_KERNEL, + "%s%d", type_name, drvdata->cpu); + if (!desc.name) + return -ENOMEM; etm4_init_trace_id(drvdata); etm4_set_default(&drvdata->config); @@ -1779,9 +1809,8 @@ static int etm4_probe(struct device *dev, void __iomem *base) etmdrvdata[drvdata->cpu] = drvdata; - dev_info(&drvdata->csdev->dev, "CPU%d: ETM v%d.%d initialized\n", -drvdata->cpu, ETM_ARCH_MAJOR_VERSION(drvdata->arch), -ETM_ARCH_MINOR_VERSION(drvdata->arch)); + dev_info(&drvdata->csdev->dev, "CPU%d: %s v%d.%d initialized\n", +drvdata->cpu, type_name, major, minor); if (boot_enable) { coresight_enable(drvdata->csdev); @@ -1918,6 +1947,7 @@ static struct amba_driver etm4x_amba_driver = { static const struct of_device_id etm4_sysreg_match[] = { { .compatible = "arm,coresight-etm4x-sysreg" }, + { .compatible = "arm,embedded-trace-extension" }, {} }; diff --git a/drivers/hwtracing/coresight/cor
[PATCH 06/11] dts: bindings: Document device tree bindings for ETE
From: Suzuki K Poulose Document the device tree bindings for Embedded Trace Extensions. ETE can be connected to legacy coresight components and thus could optionally contain a connection graph as described by the CoreSight bindings. Cc: devicet...@vger.kernel.org Cc: Mathieu Poirier Cc: Mike Leach Cc: Rob Herring Signed-off-by: Suzuki K Poulose Signed-off-by: Anshuman Khandual --- Documentation/devicetree/bindings/arm/ete.txt | 41 +++ 1 file changed, 41 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/ete.txt diff --git a/Documentation/devicetree/bindings/arm/ete.txt b/Documentation/devicetree/bindings/arm/ete.txt new file mode 100644 index 000..b52b507 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/ete.txt @@ -0,0 +1,41 @@ +Arm Embedded Trace Extensions + +Arm Embedded Trace Extensions (ETE) is a per CPU trace component that +allows tracing the CPU execution. It overlaps with the CoreSight ETMv4 +architecture and has extended support for future architecture changes. +The trace generated by the ETE could be stored via legacy CoreSight +components (e.g, TMC-ETR) or other means (e.g, using a per CPU buffer +Arm Trace Buffer Extension (TRBE)). Since the ETE can be connected to +legacy CoreSight components, a node must be listed per instance, along +with any optional connection graph as per the coresight bindings. +See bindings/arm/coresight.txt. + +** ETE Required properties: + +- compatible : should be one of: + "arm,embedded-trace-extensions" + +- cpu : the CPU phandle this ETE belongs to. + +** Optional properties: +- CoreSight connection graph, see bindings/arm/coresight.txt. + +** Example: + +ete_0 { + compatible = "arm,embedded-trace-extension"; + cpu = <&cpu_0>; +}; + +ete_1 { + compatible = "arm,embedded-trace-extension"; + cpu = <&cpu_1>; + + out-ports { /* legacy CoreSight connection */ + port { + ete1_out_port: endpoint@0 { + remote-endpoint = <&funnel_in_port0>; + }; + }; + }; +}; -- 2.7.4
[PATCH 09/11] coresight: etm-perf: Truncate the perf record if handle has no space
While starting off the etm event, just abort and truncate the perf record if the perf handle as no space left. This avoids configuring both source and sink devices in case the data cannot be consumed in perf. Cc: Mathieu Poirier Cc: Mike Leach Cc: Suzuki K Poulose Signed-off-by: Anshuman Khandual --- drivers/hwtracing/coresight/coresight-etm-perf.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c index eb9e7e9..e776a07 100644 --- a/drivers/hwtracing/coresight/coresight-etm-perf.c +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c @@ -347,6 +347,9 @@ static void etm_event_start(struct perf_event *event, int flags) if (!event_data) goto fail; + if (!handle->size) + goto fail_end_stop; + /* * Check if this ETM is allowed to trace, as decided * at etm_setup_aux(). This could be due to an unreachable -- 2.7.4
[PATCH 08/11] coresight: core: Add support for dedicated percpu sinks
Add support for dedicated sinks that are bound to individual CPUs. (e.g, TRBE). To allow quicker access to the sink for a given CPU bound source, keep a percpu array of the sink devices. Also, add support for building a path to the CPU local sink from the ETM. This adds a new percpu sink type CORESIGHT_DEV_SUBTYPE_SINK_PERCPU_SYSMEM. This new sink type is exclusively available and can only work with percpu source type device CORESIGHT_DEV_SUBTYPE_SOURCE_PERCPU_PROC. This defines a percpu structure that accommodates a single coresight_device which can be used to store an initialized instance from a sink driver. As these sinks are exclusively linked and dependent on corresponding percpu sources devices, they should also be the default sink device during a perf session. Outwards device connections are scanned while establishing paths between a source and a sink device. But such connections are not present for certain percpu source and sink devices which are exclusively linked and dependent. Build the path directly and skip connection scanning for such devices. Cc: Mathieu Poirier Cc: Mike Leach Cc: Suzuki K Poulose Signed-off-by: Anshuman Khandual --- Changes in V1: - Replaced post init ETE-TRBE link configuration with dynamic path creation drivers/hwtracing/coresight/coresight-core.c | 14 ++ include/linux/coresight.h| 12 2 files changed, 26 insertions(+) diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c index 0062c89..b300606 100644 --- a/drivers/hwtracing/coresight/coresight-core.c +++ b/drivers/hwtracing/coresight/coresight-core.c @@ -23,6 +23,7 @@ #include "coresight-priv.h" static DEFINE_MUTEX(coresight_mutex); +DEFINE_PER_CPU(struct coresight_device *, csdev_sink); /** * struct coresight_node - elements of a path, from source to sink @@ -784,6 +785,13 @@ static int _coresight_build_path(struct coresight_device *csdev, if (csdev == sink) goto out; + if (coresight_is_percpu_source(csdev) && coresight_is_percpu_sink(sink) && + sink == per_cpu(csdev_sink, source_ops(csdev)->cpu_id(csdev))) { + _coresight_build_path(sink, sink, path); + found = true; + goto out; + } + /* Not a sink - recursively explore each port found on this element */ for (i = 0; i < csdev->pdata->nr_outport; i++) { struct coresight_device *child_dev; @@ -998,6 +1006,12 @@ coresight_find_default_sink(struct coresight_device *csdev) { int depth = 0; + if (coresight_is_percpu_source(csdev)) { + csdev->def_sink = per_cpu(csdev_sink, source_ops(csdev)->cpu_id(csdev)); + if (csdev->def_sink) + return csdev->def_sink; + } + /* look for a default sink if we have not found for this device */ if (!csdev->def_sink) csdev->def_sink = coresight_find_sink(csdev, &depth); diff --git a/include/linux/coresight.h b/include/linux/coresight.h index 951ba88..2aee12e 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -50,6 +50,7 @@ enum coresight_dev_subtype_sink { CORESIGHT_DEV_SUBTYPE_SINK_PORT, CORESIGHT_DEV_SUBTYPE_SINK_BUFFER, CORESIGHT_DEV_SUBTYPE_SINK_SYSMEM, + CORESIGHT_DEV_SUBTYPE_SINK_PERCPU_SYSMEM, }; enum coresight_dev_subtype_link { @@ -432,6 +433,17 @@ static inline void csdev_access_write64(struct csdev_access *csa, u64 val, u32 o csa->write(val, offset, false, true); } +static inline bool coresight_is_percpu_source(struct coresight_device *csdev) +{ + return csdev && (csdev->type == CORESIGHT_DEV_TYPE_SOURCE) && + csdev->subtype.source_subtype == CORESIGHT_DEV_SUBTYPE_SOURCE_PROC; +} + +static inline bool coresight_is_percpu_sink(struct coresight_device *csdev) +{ + return csdev && (csdev->type == CORESIGHT_DEV_TYPE_SINK) && + csdev->subtype.sink_subtype == CORESIGHT_DEV_SUBTYPE_SINK_PERCPU_SYSMEM; +} #else /* !CONFIG_64BIT */ static inline u64 csdev_access_relaxed_read64(struct csdev_access *csa, -- 2.7.4
[PATCH 07/11] arm64: Add TRBE definitions
This adds TRBE related registers and corresponding feature macros. Cc: Mathieu Poirier Cc: Mike Leach Cc: Suzuki K Poulose Signed-off-by: Anshuman Khandual --- Changes in V1: - Re-arranged TRBE register definitions per existing sorted registers - Replaced some instances with BIT() and GENMASK_ULL() when applicable arch/arm64/include/asm/sysreg.h | 49 + 1 file changed, 49 insertions(+) diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index eeaab55..e6962b1 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -325,6 +325,55 @@ /*** End of Statistical Profiling Extension ***/ +/* + * TRBE Registers + */ +#define SYS_TRBLIMITR_EL1 sys_reg(3, 0, 9, 11, 0) +#define SYS_TRBPTR_EL1 sys_reg(3, 0, 9, 11, 1) +#define SYS_TRBBASER_EL1 sys_reg(3, 0, 9, 11, 2) +#define SYS_TRBSR_EL1 sys_reg(3, 0, 9, 11, 3) +#define SYS_TRBMAR_EL1 sys_reg(3, 0, 9, 11, 4) +#define SYS_TRBTRG_EL1 sys_reg(3, 0, 9, 11, 6) +#define SYS_TRBIDR_EL1 sys_reg(3, 0, 9, 11, 7) + +#define TRBLIMITR_LIMIT_MASK GENMASK_ULL(51, 0) +#define TRBLIMITR_LIMIT_SHIFT 12 +#define TRBLIMITR_NVM BIT(5) +#define TRBLIMITR_TRIG_MODE_MASK GENMASK(1, 0) +#define TRBLIMITR_TRIG_MODE_SHIFT 2 +#define TRBLIMITR_FILL_MODE_MASK GENMASK(1, 0) +#define TRBLIMITR_FILL_MODE_SHIFT 1 +#define TRBLIMITR_ENABLE BIT(0) +#define TRBPTR_PTR_MASKGENMASK_ULL(63, 0) +#define TRBPTR_PTR_SHIFT 0 +#define TRBBASER_BASE_MASK GENMASK_ULL(51, 0) +#define TRBBASER_BASE_SHIFT12 +#define TRBSR_EC_MASK GENMASK(5, 0) +#define TRBSR_EC_SHIFT 26 +#define TRBSR_IRQ BIT(22) +#define TRBSR_TRG BIT(21) +#define TRBSR_WRAP BIT(20) +#define TRBSR_ABORTBIT(18) +#define TRBSR_STOP BIT(17) +#define TRBSR_MSS_MASK GENMASK(15, 0) +#define TRBSR_MSS_SHIFT0 +#define TRBSR_BSC_MASK GENMASK(5, 0) +#define TRBSR_BSC_SHIFT0 +#define TRBSR_FSC_MASK GENMASK(5, 0) +#define TRBSR_FSC_SHIFT0 +#define TRBMAR_SHARE_MASK GENMASK(1, 0) +#define TRBMAR_SHARE_SHIFT 8 +#define TRBMAR_OUTER_MASK GENMASK(3, 0) +#define TRBMAR_OUTER_SHIFT 4 +#define TRBMAR_INNER_MASK GENMASK(3, 0) +#define TRBMAR_INNER_SHIFT 0 +#define TRBTRG_TRG_MASKGENMASK(31, 0) +#define TRBTRG_TRG_SHIFT 0 +#define TRBIDR_FLAGBIT(5) +#define TRBIDR_PROGBIT(4) +#define TRBIDR_ALIGN_MASK GENMASK(3, 0) +#define TRBIDR_ALIGN_SHIFT 0 + #define SYS_PMINTENSET_EL1 sys_reg(3, 0, 9, 14, 1) #define SYS_PMINTENCLR_EL1 sys_reg(3, 0, 9, 14, 2) -- 2.7.4
[PATCH 10/11] coresight: sink: Add TRBE driver
Trace Buffer Extension (TRBE) implements a trace buffer per CPU which is accessible via the system registers. The TRBE supports different addressing modes including CPU virtual address and buffer modes including the circular buffer mode. The TRBE buffer is addressed by a base pointer (TRBBASER_EL1), an write pointer (TRBPTR_EL1) and a limit pointer (TRBLIMITR_EL1). But the access to the trace buffer could be prohibited by a higher exception level (EL3 or EL2), indicated by TRBIDR_EL1.P. The TRBE can also generate a CPU private interrupt (PPI) on address translation errors and when the buffer is full. Overall implementation here is inspired from the Arm SPE driver. Cc: Mathieu Poirier Cc: Mike Leach Cc: Suzuki K Poulose Signed-off-by: Anshuman Khandual --- Changes in V1: - Replaced direct alignment tests with IS_ALIGNED() - Dropped trbe_perf->pid as its not really required - Dropped trbe_drvdata->atclk is its not really required - Changed trbe_cpudata->trbe_align sysfs entry as hex - Dropped trbe_cpudata->irq sysfs entry completely and updated the documentation - Dropped ACPI based TRBE detection support - Dropped trbe_address_mode and string enum - Added CORESIGHT_DEV_SUBTYPE_SINK_PERCPU_SYSMEM enumeration - Make TRBE driver modular - Premature exit when mode != CS_MODE_PERF - Dropped CONFIG_PM suspend and resume support - Dropped unused helpers and enumerations - Truncate the perf record when perf_aux_output_begin() fails - Dropped assert_trbe_address_[mode|align]() - Introduce clear_trbe_state() which clear TRBSR in single pass - Introduce set_trbe_state() which configures TRBE for perf session - Changed percpu trbe_drvdata->handle to hold a pointer instead - Dropped TSB_CSYNC, dsb(), isb() from trbe_get_fault_act() - Dropped two redundant isb() from trbe_reset_local() - Dropped flush_tlb_all() from trbe_enable_hw() - Moved dsb() after TSB_CSYNC in trbe_enable_hw() and trbe_disable_and_drain_local() - Changed dsb() argument to ish for all instances - Introduce set_trbe_flush() - Reorganized arm_trbe_[probe|remove]_coresight_cpu() - Dropped smp_call_function_single() from cpu online path i.e arm_trbe_cpu_startup() - Replaced smp_call_function_single() with smp_call_function_many() - Added some documentation on TRBE buffer management for perf - Added comment for padding packet ETE_IGNORE_PACKET - Dropped trbe_name[], instead used DRVNAME - Changed TRBE DT node from arm-trbe to trace-buffer-extension - Renamed trbe_perf structure as trbe_buf - Changed all TRBE enum classification into just simple int defines - Reworked TRBE module init/exit and CPU start-up/tear-down sequences Documentation/trace/coresight/coresight-trbe.rst | 39 + arch/arm64/include/asm/sysreg.h | 2 + drivers/hwtracing/coresight/Kconfig | 11 + drivers/hwtracing/coresight/Makefile | 1 + drivers/hwtracing/coresight/coresight-trbe.c | 925 +++ drivers/hwtracing/coresight/coresight-trbe.h | 248 ++ 6 files changed, 1226 insertions(+) create mode 100644 Documentation/trace/coresight/coresight-trbe.rst create mode 100644 drivers/hwtracing/coresight/coresight-trbe.c create mode 100644 drivers/hwtracing/coresight/coresight-trbe.h diff --git a/Documentation/trace/coresight/coresight-trbe.rst b/Documentation/trace/coresight/coresight-trbe.rst new file mode 100644 index 000..8b79850 --- /dev/null +++ b/Documentation/trace/coresight/coresight-trbe.rst @@ -0,0 +1,39 @@ +.. SPDX-License-Identifier: GPL-2.0 + +== +Trace Buffer Extension (TRBE). +== + +:Author: Anshuman Khandual +:Date: November 2020 + +Hardware Description + + +Trace Buffer Extension (TRBE) is a percpu hardware which captures in system +memory, CPU traces generated from a corresponding percpu tracing unit. This +gets plugged in as a coresight sink device because the corresponding trace +genarators (ETE), are plugged in as source device. + +The TRBE is not compliant to CoreSight architecture specifications, but is +driven via the CoreSight driver framework to support the ETE (which is +CoreSight compliant) integration. + +Sysfs files and directories +--- + +The TRBE devices appear on the existing coresight bus alongside the other +coresight devices:: + + >$ ls /sys/bus/coresight/devices + trbe0 trbe1 trbe2 trbe3 + +The ``trbe`` named TRBEs are associated with a CPU.:: + + >$ ls /sys/bus/coresight/devices/trbe0/ + irq align dbm + +*Key file items are:-* + * ``align``: TRBE write pointer alignment + * ``dbm``: TRBE updates memory with access and dirty flags + diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index e6962b1..2a9bfb7 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -97,6 +97,7 @@ #define SET_PSTATE_UAO(x) __emit_inst(0xd500401f | PSTATE_UAO | ((!!x) <<
[PATCH 11/11] dts: bindings: Document device tree binding for Arm TRBE
This patch documents the device tree binding in use for Arm TRBE. Cc: devicet...@vger.kernel.org Cc: Mathieu Poirier Cc: Mike Leach Cc: Suzuki K Poulose Signed-off-by: Anshuman Khandual --- Changes in V1: - TRBE DT entry has been renamed as 'arm, trace-buffer-extension' Documentation/devicetree/bindings/arm/trbe.txt | 20 1 file changed, 20 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/trbe.txt diff --git a/Documentation/devicetree/bindings/arm/trbe.txt b/Documentation/devicetree/bindings/arm/trbe.txt new file mode 100644 index 000..001945d --- /dev/null +++ b/Documentation/devicetree/bindings/arm/trbe.txt @@ -0,0 +1,20 @@ +* Trace Buffer Extension (TRBE) + +Trace Buffer Extension (TRBE) is used for collecting trace data generated +from a corresponding trace unit (ETE) using an in memory trace buffer. + +** TRBE Required properties: + +- compatible : should be one of: + "arm,trace-buffer-extension" + +- interrupts : Exactly 1 PPI must be listed. For heterogeneous systems where + TRBE is only supported on a subset of the CPUs, please consult + the arm,gic-v3 binding for details on describing a PPI partition. + +** Example: + +trbe { + compatible = "arm,trace-buffer-extension"; + interrupts = ; +}; -- 2.7.4
Re: [PATCH] mm/userfaultfd: fix memory corruption due to writeprotect
On Wed, Dec 23, 2020 at 01:44:42AM -0800, Linus Torvalds wrote: > On Tue, Dec 22, 2020 at 4:01 PM Linus Torvalds > wrote: > > > > The more I look at the mprotect code, the less I like it. We seem to > > be much better about the TLB flushes in other places (looking at > > mremap, for example). The mprotect code seems to be very laissez-faire > > about the TLB flushing. > > No, this doesn't help. > > > Does adding a TLB flush to before that > > > > pte_unmap_unlock(pte - 1, ptl); > > > > fix things for you? > > It really doesn't fix it. Exactly because - as pointed out earlier - > the actual page *copy* happens outside the pte lock. I appreciate all the pointers. It seems to me it does. > So what can happen is: > > - CPU 1 holds the page table lock, while doing the write protect. It > has cleared the writable bit, but hasn't flushed the TLB's yet > > - CPU 2 did *not* have the TLB entry, sees the new read-only state, > takes a COW page fault, and reads the PTE from memory (into > vmf->orig_pte) In handle_pte_fault(), we lock page table and check pte_write(), so we either see a RW pte before CPU 1 runs or a RO one with no stale tlb entries after CPU 1 runs, assume CPU 1 flushes tlb while holding the same page table lock (not mmap_lock). > - CPU 2 correctly decides it needs to be a COW, and copies the page contents > > - CPU 3 *does* have a stale TLB (because TLB invalidation hasn't > happened yet), and writes to that page in users apce > > - CPU 1 now does the TLB invalidate, and releases the page table lock > > - CPU 2 gets the page table lock, sees that its PTE matches > vmf->orig_pte, and switches it to be that writable copy of the page. > > where the copy happened before CPU 3 had stopped writing to the page. > > So the pte lock doesn't actually matter, unless we actually do the > page copy inside of it (on CPU2), in addition to doing the TLB flush > inside of it (on CPU1). > > mprotect() is actually safe for two independent reasons: (a) it does > the mmap_sem for writing (so mprotect can't race with the COW logic at > all), and (b) it changes the vma permissions so turning something > read-only actually disables COW anyway, since it won't be a COW, it > will be a SIGSEGV. > > So mprotect() is irrelevant, other than the fact that it shares some > code with that "turn it read-only in the page tables". > > fork() is a much closer operation, in that it actually triggers that > COW behavior, but fork() takes the mmap_sem for writing, so it avoids > this too. > > So it's really just userfaultfd and that kind of ilk that is relevant > here, I think. But that "you need to flush the TLB before releasing > the page table lock" was not true (well, it's true in other > circumstances - just not *here*), and is not part of the solution. > > Or rather, if it's part of the solution here, it would have to be > matched with that "page copy needs to be done under the page table > lock too". > > Linus >
Re: [PATCH v2 3/3] iommu/vt-d: Fix ineffective devTLB invalidation for subdevices
Hi Yi, On 2020/12/23 14:27, Liu Yi L wrote: iommu_flush_dev_iotlb() is called to invalidate caches on device. It only loops the devices which are full-attached to the domain. For sub-devices, this is ineffective. This results in invalid caching entries left on the device. Fix it by adding loop for subdevices as well. Also, the domain-> has_iotlb_device needs to be updated when attaching to subdevices. Fixes: 67b8e02b5e761 ("iommu/vt-d: Aux-domain specific domain attach/detach") Signed-off-by: Liu Yi L --- drivers/iommu/intel/iommu.c | 63 +++-- 1 file changed, 47 insertions(+), 16 deletions(-) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index acfe0a5b955e..e97c5ac1d7fc 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -726,6 +726,8 @@ static int domain_update_device_node(struct dmar_domain *domain) return nid; } +static void domain_update_iotlb(struct dmar_domain *domain); + /* Some capabilities may be different across iommus */ static void domain_update_iommu_cap(struct dmar_domain *domain) { @@ -739,6 +741,8 @@ static void domain_update_iommu_cap(struct dmar_domain *domain) */ if (domain->nid == NUMA_NO_NODE) domain->nid = domain_update_device_node(domain); + + domain_update_iotlb(domain); } struct context_entry *iommu_context_addr(struct intel_iommu *iommu, u8 bus, @@ -1459,6 +1463,18 @@ iommu_support_dev_iotlb (struct dmar_domain *domain, struct intel_iommu *iommu, return NULL; } +static bool dev_iotlb_enabled(struct device_domain_info *info) +{ + struct pci_dev *pdev; + + if (!info->dev || !dev_is_pci(info->dev)) + return false; + + pdev = to_pci_dev(info->dev); + + return !!pdev->ats_enabled; +} I know this is just separated from below function. But isn't "(info && info->ats_enabled)" is enough? + static void domain_update_iotlb(struct dmar_domain *domain) { struct device_domain_info *info; @@ -1466,17 +1482,20 @@ static void domain_update_iotlb(struct dmar_domain *domain) assert_spin_locked(&device_domain_lock); - list_for_each_entry(info, &domain->devices, link) { - struct pci_dev *pdev; - - if (!info->dev || !dev_is_pci(info->dev)) - continue; - - pdev = to_pci_dev(info->dev); - if (pdev->ats_enabled) { + list_for_each_entry(info, &domain->devices, link) + if (dev_iotlb_enabled(info)) { has_iotlb_device = true; break; } + + if (!has_iotlb_device) { + struct subdev_domain_info *sinfo; + + list_for_each_entry(sinfo, &domain->subdevices, link_domain) + if (dev_iotlb_enabled(get_domain_info(sinfo->pdev))) { Please make the code easier for reading by: info = get_domain_info(sinfo->pdev); if (dev_iotlb_enabled(info)) Best regards, baolu + has_iotlb_device = true; + break; + } } domain->has_iotlb_device = has_iotlb_device; @@ -1557,25 +1576,37 @@ static void iommu_disable_dev_iotlb(struct device_domain_info *info) #endif } +static void __iommu_flush_dev_iotlb(struct device_domain_info *info, + u64 addr, unsigned int mask) +{ + u16 sid, qdep; + + if (!info || !info->ats_enabled) + return; + + sid = info->bus << 8 | info->devfn; + qdep = info->ats_qdep; + qi_flush_dev_iotlb(info->iommu, sid, info->pfsid, + qdep, addr, mask); +} + static void iommu_flush_dev_iotlb(struct dmar_domain *domain, u64 addr, unsigned mask) { - u16 sid, qdep; unsigned long flags; struct device_domain_info *info; + struct subdev_domain_info *sinfo; if (!domain->has_iotlb_device) return; spin_lock_irqsave(&device_domain_lock, flags); - list_for_each_entry(info, &domain->devices, link) { - if (!info->ats_enabled) - continue; + list_for_each_entry(info, &domain->devices, link) + __iommu_flush_dev_iotlb(info, addr, mask); - sid = info->bus << 8 | info->devfn; - qdep = info->ats_qdep; - qi_flush_dev_iotlb(info->iommu, sid, info->pfsid, - qdep, addr, mask); + list_for_each_entry(sinfo, &domain->subdevices, link_domain) { + __iommu_flush_dev_iotlb(get_domain_info(sinfo->pdev), + addr, mask); } spin_unlock_irqrestore(&device_domain_lock, flags); }
Re: Does uaccess_kernel() work for detecting kernel thread?
On 2020/12/23 16:53, Christoph Hellwig wrote: > On Tue, Dec 22, 2020 at 11:39:08PM +0900, Tetsuo Handa wrote: >> For example, if uaccess_kernel() is "false" due to CONFIG_SET_FS=n, >> isn't sg_check_file_access() failing to detect kernel context? > > sg_check_file_access does exactly the right thing - fail for all kernel > threads as those can't support the magic it does. My question is, in Linux 5.10, sg_check_file_access() for x86 became static int sg_check_file_access(struct file *filp, const char *caller) { if (filp->f_cred != current_real_cred()) { pr_err_once("%s: process %d (%s) changed security contexts after opening file descriptor, this is not allowed.\n", caller, task_tgid_vnr(current), current->comm); return -EPERM; } if (0) { pr_err_once("%s: process %d (%s) called from kernel context, this is not allowed.\n", caller, task_tgid_vnr(current), current->comm); return -EACCES; } return 0; } due to commit 5e6e9852d6f76e01 ("uaccess: add infrastructure for kernel builds with set_fs()") and follow up changes. Don't we need to change this "uaccess_kernel()" with "(current->flags & PF_KTHREAD)" ? > >> For another example, if uaccess_kernel() is "false" due to CONFIG_SET_FS=n, >> isn't TOMOYO unexpectedly checking permissions for socket operations? > > Can someone explain WTF TOMOYO is even doing there? A security module > has absolutely no business checking what context it is called from, but > must check the process credentials instead. > TOMOYO distinguishes userspace processes and kernel threads, and grants kernel threads implicit permissions to perform socket operations. Since "uaccess_kernel()" became "0" for x86, TOMOYO is no longer able to grant kernel threads implicit permissions to perform socket operations. Since Eric says "For PF_IO_WORKER kernel threads which are running code on behalf of a user we want to perform the ordinary permission checks.", I think that TOMOYO wants to use "(current->flags & (PF_KTHREAD | PF_IO_WORKER)) == PF_KTHREAD" instead.
Re: [PATCH -next] ubi: eba: Delete useless kfree code
On Wed, Dec 16, 2020 at 2:13 PM Zheng Yongjun wrote: > > The parameter of kfree function is NULL, so kfree code is useless, delete it. > > Signed-off-by: Zheng Yongjun > --- > drivers/mtd/ubi/eba.c | 1 - > 1 file changed, 1 deletion(-) > > diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c > index 0edecfdbd01f..9c2840ffd2e9 100644 > --- a/drivers/mtd/ubi/eba.c > +++ b/drivers/mtd/ubi/eba.c > @@ -142,7 +142,6 @@ struct ubi_eba_table *ubi_eba_create_table(struct > ubi_volume *vol, > return tbl; > > err: > - kfree(tbl->entries); > kfree(tbl); > > return ERR_PTR(err); On Sat, Dec 19, 2020 at 1:52 PM Jubin Zhong wrote: > > data_size is already checked against zero when vol_type matches > UBI_VID_STATIC. Remove the following dead code. > > Signed-off-by: Jubin Zhong > --- > drivers/mtd/ubi/io.c | 7 +-- > 1 file changed, 1 insertion(+), 6 deletions(-) > > diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c > index 2f3312c..8a7306c 100644 > --- a/drivers/mtd/ubi/io.c > +++ b/drivers/mtd/ubi/io.c > @@ -913,12 +913,7 @@ static int validate_vid_hdr(const struct ubi_device *ubi, > ubi_err(ubi, "bad data_size"); > goto bad; > } > - } else if (lnum == used_ebs - 1) { > - if (data_size == 0) { > - ubi_err(ubi, "bad data_size at last LEB"); > - goto bad; > - } > - } else { > + } else if (lnum > used_ebs - 1) { > ubi_err(ubi, "too high lnum"); > goto bad; > } > -- Looks good, applied to my 5.12 queue! -- Thanks, //richard
[PATCH v6 01/12] mfd: bd9571mwv: Use devm_mfd_add_devices()
To remove mfd devices when unload this driver, should use devm_mfd_add_devices() instead. Fixes: d3ea21272094 ("mfd: Add ROHM BD9571MWV-M MFD PMIC driver") Signed-off-by: Yoshihiro Shimoda Acked-for-MFD-by: Lee Jones Reviewed-by: Geert Uytterhoeven Reviewed-by: Matti Vaittinen --- drivers/mfd/bd9571mwv.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/mfd/bd9571mwv.c b/drivers/mfd/bd9571mwv.c index fab3cdc..19d57a4 100644 --- a/drivers/mfd/bd9571mwv.c +++ b/drivers/mfd/bd9571mwv.c @@ -185,9 +185,9 @@ static int bd9571mwv_probe(struct i2c_client *client, return ret; } - ret = mfd_add_devices(bd->dev, PLATFORM_DEVID_AUTO, bd9571mwv_cells, - ARRAY_SIZE(bd9571mwv_cells), NULL, 0, - regmap_irq_get_domain(bd->irq_data)); + ret = devm_mfd_add_devices(bd->dev, PLATFORM_DEVID_AUTO, + bd9571mwv_cells, ARRAY_SIZE(bd9571mwv_cells), + NULL, 0, regmap_irq_get_domain(bd->irq_data)); if (ret) { regmap_del_irq_chip(bd->irq, bd->irq_data); return ret; -- 2.7.4
[PATCH v6 04/12] regulator: bd9571mwv: rid of using struct bd9571mwv
To simplify this driver, use dev_get_regmap() and rid of using struct bd9571mwv. Signed-off-by: Yoshihiro Shimoda Reviewed-by: Matti Vaittinen --- drivers/regulator/bd9571mwv-regulator.c | 49 + 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/drivers/regulator/bd9571mwv-regulator.c b/drivers/regulator/bd9571mwv-regulator.c index e690c2c..42b6a70 100644 --- a/drivers/regulator/bd9571mwv-regulator.c +++ b/drivers/regulator/bd9571mwv-regulator.c @@ -17,7 +17,7 @@ #include struct bd9571mwv_reg { - struct bd9571mwv *bd; + struct regmap *regmap; /* DDR Backup Power */ u8 bkup_mode_cnt_keepon;/* from "rohm,ddr-backup-power" */ @@ -137,26 +137,30 @@ static const struct regulator_desc regulators[] = { }; #ifdef CONFIG_PM_SLEEP -static int bd9571mwv_bkup_mode_read(struct bd9571mwv *bd, unsigned int *mode) +static int bd9571mwv_bkup_mode_read(struct bd9571mwv_reg *bdreg, + unsigned int *mode) { int ret; - ret = regmap_read(bd->regmap, BD9571MWV_BKUP_MODE_CNT, mode); + ret = regmap_read(bdreg->regmap, BD9571MWV_BKUP_MODE_CNT, mode); if (ret) { - dev_err(bd->dev, "failed to read backup mode (%d)\n", ret); + dev_err(regmap_get_device(bdreg->regmap), + "failed to read backup mode (%d)\n", ret); return ret; } return 0; } -static int bd9571mwv_bkup_mode_write(struct bd9571mwv *bd, unsigned int mode) +static int bd9571mwv_bkup_mode_write(struct bd9571mwv_reg *bdreg, +unsigned int mode) { int ret; - ret = regmap_write(bd->regmap, BD9571MWV_BKUP_MODE_CNT, mode); + ret = regmap_write(bdreg->regmap, BD9571MWV_BKUP_MODE_CNT, mode); if (ret) { - dev_err(bd->dev, "failed to configure backup mode 0x%x (%d)\n", + dev_err(regmap_get_device(bdreg->regmap), + "failed to configure backup mode 0x%x (%d)\n", mode, ret); return ret; } @@ -194,7 +198,7 @@ static ssize_t backup_mode_store(struct device *dev, * Configure DDR Backup Mode, to change the role of the accessory power * switch from a power switch to a wake-up switch, or vice versa */ - ret = bd9571mwv_bkup_mode_read(bdreg->bd, &mode); + ret = bd9571mwv_bkup_mode_read(bdreg, &mode); if (ret) return ret; @@ -202,7 +206,7 @@ static ssize_t backup_mode_store(struct device *dev, if (bdreg->bkup_mode_enabled) mode |= bdreg->bkup_mode_cnt_keepon; - ret = bd9571mwv_bkup_mode_write(bdreg->bd, mode); + ret = bd9571mwv_bkup_mode_write(bdreg, mode); if (ret) return ret; @@ -221,7 +225,7 @@ static int bd9571mwv_suspend(struct device *dev) return 0; /* Save DDR Backup Mode */ - ret = bd9571mwv_bkup_mode_read(bdreg->bd, &mode); + ret = bd9571mwv_bkup_mode_read(bdreg, &mode); if (ret) return ret; @@ -235,7 +239,7 @@ static int bd9571mwv_suspend(struct device *dev) mode |= bdreg->bkup_mode_cnt_keepon; if (mode != bdreg->bkup_mode_cnt_saved) - return bd9571mwv_bkup_mode_write(bdreg->bd, mode); + return bd9571mwv_bkup_mode_write(bdreg, mode); return 0; } @@ -248,7 +252,7 @@ static int bd9571mwv_resume(struct device *dev) return 0; /* Restore DDR Backup Mode */ - return bd9571mwv_bkup_mode_write(bdreg->bd, bdreg->bkup_mode_cnt_saved); + return bd9571mwv_bkup_mode_write(bdreg, bdreg->bkup_mode_cnt_saved); } static const struct dev_pm_ops bd9571mwv_pm = { @@ -268,7 +272,6 @@ static int bd9571mwv_regulator_remove(struct platform_device *pdev) static int bd9571mwv_regulator_probe(struct platform_device *pdev) { - struct bd9571mwv *bd = dev_get_drvdata(pdev->dev.parent); struct regulator_config config = { }; struct bd9571mwv_reg *bdreg; struct regulator_dev *rdev; @@ -279,40 +282,40 @@ static int bd9571mwv_regulator_probe(struct platform_device *pdev) if (!bdreg) return -ENOMEM; - bdreg->bd = bd; + bdreg->regmap = dev_get_regmap(pdev->dev.parent, NULL); platform_set_drvdata(pdev, bdreg); config.dev = &pdev->dev; - config.dev->of_node = bd->dev->of_node; - config.driver_data = bd; - config.regmap = bd->regmap; + config.dev->of_node = pdev->dev.parent->of_node; + config.driver_data = bdreg; + config.regmap = bdreg->regmap; for (i = 0; i < ARRAY_SIZE(regulators); i++) { rdev = devm_regulator_register(&pdev->dev, ®ulators[i], &config); if (IS_ERR(rdev)) { - dev_err(bd->dev, "fa
[PATCH v6 12/12] mfd: bd9571mwv: Add support for BD9574MWF
From: Khiem Nguyen The new PMIC BD9574MWF inherits features from BD9571MWV. Add the support of new PMIC to existing bd9571mwv driver. Signed-off-by: Khiem Nguyen Co-developed-by: Yoshihiro Shimoda Signed-off-by: Yoshihiro Shimoda Reviewed-by: Matti Vaittinen --- drivers/mfd/bd9571mwv.c | 80 ++- include/linux/mfd/bd9571mwv.h | 17 +++-- 2 files changed, 93 insertions(+), 4 deletions(-) diff --git a/drivers/mfd/bd9571mwv.c b/drivers/mfd/bd9571mwv.c index c905ab4..b1e7ae9 100644 --- a/drivers/mfd/bd9571mwv.c +++ b/drivers/mfd/bd9571mwv.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * ROHM BD9571MWV-M MFD driver + * ROHM BD9571MWV-M and BD9574MVF-M core driver * * Copyright (C) 2017 Marek Vasut * Copyright (C) 2020 Renesas Electronics Corporation @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -118,6 +119,79 @@ static const struct bd957x_ddata bd9571mwv_ddata = { .num_cells = ARRAY_SIZE(bd9571mwv_cells), }; +static const struct mfd_cell bd9574mwf_cells[] = { + { .name = "bd9574mwf-regulator", }, + { .name = "bd9574mwf-gpio", }, +}; + +static const struct regmap_range bd9574mwf_readable_yes_ranges[] = { + regmap_reg_range(BD9571MWV_VENDOR_CODE, BD9571MWV_PRODUCT_REVISION), + regmap_reg_range(BD9571MWV_BKUP_MODE_CNT, BD9571MWV_BKUP_MODE_CNT), + regmap_reg_range(BD9571MWV_DVFS_VINIT, BD9571MWV_DVFS_SETVMAX), + regmap_reg_range(BD9571MWV_DVFS_SETVID, BD9571MWV_DVFS_MONIVDAC), + regmap_reg_range(BD9571MWV_GPIO_IN, BD9571MWV_GPIO_IN), + regmap_reg_range(BD9571MWV_GPIO_INT, BD9571MWV_GPIO_INTMASK), + regmap_reg_range(BD9571MWV_INT_INTREQ, BD9571MWV_INT_INTMASK), +}; + +static const struct regmap_access_table bd9574mwf_readable_table = { + .yes_ranges = bd9574mwf_readable_yes_ranges, + .n_yes_ranges = ARRAY_SIZE(bd9574mwf_readable_yes_ranges), +}; + +static const struct regmap_range bd9574mwf_writable_yes_ranges[] = { + regmap_reg_range(BD9571MWV_BKUP_MODE_CNT, BD9571MWV_BKUP_MODE_CNT), + regmap_reg_range(BD9571MWV_DVFS_SETVID, BD9571MWV_DVFS_SETVID), + regmap_reg_range(BD9571MWV_GPIO_DIR, BD9571MWV_GPIO_OUT), + regmap_reg_range(BD9571MWV_GPIO_INT_SET, BD9571MWV_GPIO_INTMASK), + regmap_reg_range(BD9571MWV_INT_INTREQ, BD9571MWV_INT_INTMASK), +}; + +static const struct regmap_access_table bd9574mwf_writable_table = { + .yes_ranges = bd9574mwf_writable_yes_ranges, + .n_yes_ranges = ARRAY_SIZE(bd9574mwf_writable_yes_ranges), +}; + +static const struct regmap_range bd9574mwf_volatile_yes_ranges[] = { + regmap_reg_range(BD9571MWV_DVFS_MONIVDAC, BD9571MWV_DVFS_MONIVDAC), + regmap_reg_range(BD9571MWV_GPIO_IN, BD9571MWV_GPIO_IN), + regmap_reg_range(BD9571MWV_GPIO_INT, BD9571MWV_GPIO_INT), + regmap_reg_range(BD9571MWV_INT_INTREQ, BD9571MWV_INT_INTREQ), +}; + +static const struct regmap_access_table bd9574mwf_volatile_table = { + .yes_ranges = bd9574mwf_volatile_yes_ranges, + .n_yes_ranges = ARRAY_SIZE(bd9574mwf_volatile_yes_ranges), +}; + +static const struct regmap_config bd9574mwf_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .cache_type = REGCACHE_RBTREE, + .rd_table = &bd9574mwf_readable_table, + .wr_table = &bd9574mwf_writable_table, + .volatile_table = &bd9574mwf_volatile_table, + .max_register = 0xff, +}; + +static struct regmap_irq_chip bd9574mwf_irq_chip = { + .name = "bd9574mwf", + .status_base= BD9571MWV_INT_INTREQ, + .mask_base = BD9571MWV_INT_INTMASK, + .ack_base = BD9571MWV_INT_INTREQ, + .init_ack_masked = true, + .num_regs = 1, + .irqs = bd9571mwv_irqs, + .num_irqs = ARRAY_SIZE(bd9571mwv_irqs), +}; + +static const struct bd957x_ddata bd9574mwf_ddata = { + .regmap_config = &bd9574mwf_regmap_config, + .irq_chip = &bd9574mwf_irq_chip, + .cells = bd9574mwf_cells, + .num_cells = ARRAY_SIZE(bd9574mwf_cells), +}; + static int bd957x_identify(struct device *dev, struct regmap *regmap) { unsigned int value; @@ -171,6 +245,9 @@ static int bd9571mwv_probe(struct i2c_client *client, case BD9571MWV_PRODUCT_CODE_BD9571MWV: ddata = &bd9571mwv_ddata; break; + case BD9571MWV_PRODUCT_CODE_BD9574MWF: + ddata = &bd9574mwf_ddata; + break; default: dev_err(dev, "Unsupported device 0x%x\n", ret); return -ENODEV; @@ -200,6 +277,7 @@ static int bd9571mwv_probe(struct i2c_client *client, static const struct of_device_id bd9571mwv_of_match_table[] = { { .compatible = "rohm,bd9571mwv", }, + { .compatible = "rohm,bd9574mwf", }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, bd9571mwv_of_match_table); diff
[PATCH v6 07/12] gpio: bd9571mwv: rid of using struct bd9571mwv
To simplify this driver, use dev_get_regmap() and rid of using struct bd9571mwv. Signed-off-by: Yoshihiro Shimoda Reviewed-by: Matti Vaittinen --- drivers/gpio/gpio-bd9571mwv.c | 19 +-- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/gpio/gpio-bd9571mwv.c b/drivers/gpio/gpio-bd9571mwv.c index abb622c..0e5395f 100644 --- a/drivers/gpio/gpio-bd9571mwv.c +++ b/drivers/gpio/gpio-bd9571mwv.c @@ -16,8 +16,8 @@ #include struct bd9571mwv_gpio { + struct regmap *regmap; struct gpio_chip chip; - struct bd9571mwv *bd; }; static int bd9571mwv_gpio_get_direction(struct gpio_chip *chip, @@ -26,7 +26,7 @@ static int bd9571mwv_gpio_get_direction(struct gpio_chip *chip, struct bd9571mwv_gpio *gpio = gpiochip_get_data(chip); int ret, val; - ret = regmap_read(gpio->bd->regmap, BD9571MWV_GPIO_DIR, &val); + ret = regmap_read(gpio->regmap, BD9571MWV_GPIO_DIR, &val); if (ret < 0) return ret; if (val & BIT(offset)) @@ -40,8 +40,7 @@ static int bd9571mwv_gpio_direction_input(struct gpio_chip *chip, { struct bd9571mwv_gpio *gpio = gpiochip_get_data(chip); - regmap_update_bits(gpio->bd->regmap, BD9571MWV_GPIO_DIR, - BIT(offset), 0); + regmap_update_bits(gpio->regmap, BD9571MWV_GPIO_DIR, BIT(offset), 0); return 0; } @@ -52,9 +51,9 @@ static int bd9571mwv_gpio_direction_output(struct gpio_chip *chip, struct bd9571mwv_gpio *gpio = gpiochip_get_data(chip); /* Set the initial value */ - regmap_update_bits(gpio->bd->regmap, BD9571MWV_GPIO_OUT, + regmap_update_bits(gpio->regmap, BD9571MWV_GPIO_OUT, BIT(offset), value ? BIT(offset) : 0); - regmap_update_bits(gpio->bd->regmap, BD9571MWV_GPIO_DIR, + regmap_update_bits(gpio->regmap, BD9571MWV_GPIO_DIR, BIT(offset), BIT(offset)); return 0; @@ -65,7 +64,7 @@ static int bd9571mwv_gpio_get(struct gpio_chip *chip, unsigned int offset) struct bd9571mwv_gpio *gpio = gpiochip_get_data(chip); int ret, val; - ret = regmap_read(gpio->bd->regmap, BD9571MWV_GPIO_IN, &val); + ret = regmap_read(gpio->regmap, BD9571MWV_GPIO_IN, &val); if (ret < 0) return ret; @@ -77,7 +76,7 @@ static void bd9571mwv_gpio_set(struct gpio_chip *chip, unsigned int offset, { struct bd9571mwv_gpio *gpio = gpiochip_get_data(chip); - regmap_update_bits(gpio->bd->regmap, BD9571MWV_GPIO_OUT, + regmap_update_bits(gpio->regmap, BD9571MWV_GPIO_OUT, BIT(offset), value ? BIT(offset) : 0); } @@ -105,9 +104,9 @@ static int bd9571mwv_gpio_probe(struct platform_device *pdev) platform_set_drvdata(pdev, gpio); - gpio->bd = dev_get_drvdata(pdev->dev.parent); + gpio->regmap = dev_get_regmap(pdev->dev.parent, NULL); gpio->chip = template_chip; - gpio->chip.parent = gpio->bd->dev; + gpio->chip.parent = pdev->dev.parent; ret = devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio); if (ret < 0) { -- 2.7.4
[PATCH v6 08/12] gpio: bd9571mwv: Add BD9574MWF support
Add support for BD9574MWF which is similar chip with BD9571MWV. Note that BD9574MWF has additional features "RECOV_GPOUT", "FREQSEL" and "RTC_IN", but supports GPIO function only. Signed-off-by: Yoshihiro Shimoda Reviewed-by: Matti Vaittinen --- drivers/gpio/gpio-bd9571mwv.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpio-bd9571mwv.c b/drivers/gpio/gpio-bd9571mwv.c index 0e5395f..df6102b 100644 --- a/drivers/gpio/gpio-bd9571mwv.c +++ b/drivers/gpio/gpio-bd9571mwv.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * ROHM BD9571MWV-M GPIO driver + * ROHM BD9571MWV-M and BD9574MWF-M GPIO driver * * Copyright (C) 2017 Marek Vasut * @@ -10,6 +10,7 @@ */ #include +#include #include #include @@ -118,7 +119,8 @@ static int bd9571mwv_gpio_probe(struct platform_device *pdev) } static const struct platform_device_id bd9571mwv_gpio_id_table[] = { - { "bd9571mwv-gpio", }, + { "bd9571mwv-gpio", ROHM_CHIP_TYPE_BD9571 }, + { "bd9574mwf-gpio", ROHM_CHIP_TYPE_BD9574 }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(platform, bd9571mwv_gpio_id_table); -- 2.7.4