Re: [RFC PATCH 3/5] mm/vma: add support for peer to peer to device vma
On Wed, Jan 30, 2019 at 04:18:48AM +, Jason Gunthorpe wrote: > Every attempt to give BAR memory to struct page has run into major > trouble, IMHO, so I like that this approach avoids that. Way less problems than not having struct page for doing anything non-trivial. If you map the BAR to userspace with remap_pfn_range and friends the mapping is indeed very simple. But any operation that expects a page structure, which is at least everything using get_user_pages won't work. So you can't do direct I/O to your remapped BAR, you can't create MRs on it, etc, etc.
Re: [RFC PATCH 3/5] mm/vma: add support for peer to peer to device vma
On Tue, Jan 29, 2019 at 08:58:35PM +, Jason Gunthorpe wrote: > On Tue, Jan 29, 2019 at 01:39:49PM -0700, Logan Gunthorpe wrote: > > > implement the mapping. And I don't think we should have 'special' vma's > > for this (though we may need something to ensure we don't get mapping > > requests mixed with different types of pages...). > > I think Jerome explained the point here is to have a 'special vma' > rather than a 'special struct page' as, really, we don't need a > struct page at all to make this work. > > If I recall your earlier attempts at adding struct page for BAR > memory, it ran aground on issues related to O_DIRECT/sgls, etc, etc. Struct page is what makes O_DIRECT work, using sgls or biovecs, etc on it work. Without struct page none of the above can work at all. That is why we use struct page for backing BARs in the existing P2P code. Not that I'm a particular fan of creating struct page for this device memory, but without major invasive surgery to large parts of the kernel it is the only way to make it work.
Re: [PATCH 05/11] mmc: s3cmci: handle highmem pages
On Wed, Jan 30, 2019 at 08:57:47AM +0100, Ulf Hansson wrote: > On Mon, 14 Jan 2019 at 10:58, Christoph Hellwig wrote: > > > > Instead of setting up a kernel pointer to track the current PIO address, > > track the offset in the current page, and do an atomic kmap for the page > > while doing the actual PIO operations. > > > > Signed-off-by: Christoph Hellwig > > Nitpick: This one have some trailing whitespace errors, which git > complains about when I apply it. > > No need to re-spin due to this, I can fix it up. I'll need to respin to limit the segment size to a page anyway, so I will take this into account as well for v2.
Re: [PATCH] acpi_pm: Reduce PMTMR counter read contention
On Tue, 22 Jan 2019, Zhenzhong Duan wrote: > On a large system with many CPUs, using PMTMR as the clock source can > have a significant impact on the overall system performance because > of the following reasons: > 1) There is a single PMTMR counter shared by all the CPUs. > 2) PMTMR counter reading is a very slow operation. > > Using PMTMR as the default clock source may happen when, for example, > the TSC clock calibration exceeds the allowable tolerance and HPET > disabled by nohpet on kernel command line. Sometimes the performance The question is why would anyone disable HPET on a larger machine when the TSC is wreckaged? I'm not against the change per se, but I really want to understand why we need all the complexity for something which should never be used in a real world deployment. Thanks, tglx
Re: [PATCH v14 01/12] powerpc/32: Fix CONFIG_VIRT_CPU_ACCOUNTING_NATIVE for 40x/booke
Le 24/01/2019 à 17:19, Christophe Leroy a écrit : 40x/booke have another path to reach 3f from transfer_to_handler, so ACCOUNT_CPU_USER_ENTRY() have to be moved there. Signed-off-by: Christophe Leroy Now ACCOUNT_CPU_USER_ENTRY() is also in the non-user entry path. This change is crazy, please ignore it :-S Christophe --- arch/powerpc/kernel/entry_32.S | 13 ++--- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index 0768dfd8a64e..0165edd03b38 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S @@ -185,12 +185,6 @@ transfer_to_handler: addir12,r12,-1 stw r12,4(r11) #endif -#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE - CURRENT_THREAD_INFO(r9, r1) - tophys(r9, r9) - ACCOUNT_CPU_USER_ENTRY(r9, r11, r12) -#endif - b 3f 2: /* if from kernel, check interrupted DOZE/NAP mode and @@ -208,9 +202,14 @@ transfer_to_handler: bt- 31-TLF_NAPPING,4f bt- 31-TLF_SLEEPING,7f #endif /* CONFIG_PPC_BOOK3S_32 || CONFIG_E500 */ +3: +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE + CURRENT_THREAD_INFO(r9, r1) + tophys(r9, r9) + ACCOUNT_CPU_USER_ENTRY(r9, r11, r12) +#endif .globl transfer_to_handler_cont transfer_to_handler_cont: -3: mflrr9 lwz r11,0(r9) /* virtual address of handler */ lwz r9,4(r9)/* where to go when done */
Re: [PATCH v5 1/2] spi: support inter-word delay requirement for devices
Hi Geert, On 30/01/2019 08:35, Geert Uytterhoeven wrote: Hi Jonas, On Tue, Jan 29, 2019 at 9:55 PM Jonas Bonn wrote: Some devices are slow and cannot keep up with the SPI bus and therefore require a short delay between words of the SPI transfer. The example of this that I'm looking at is a SAMA5D2 with a minimum SPI clock of 400kHz talking to an AVR-based SPI slave. The AVR cannot put bytes on the bus fast enough to keep up with the SoC's SPI controller even at the lowest bus speed. This patch introduces the ability to specify a required inter-word delay for SPI devices. It is up to the controller driver to configure itself accordingly in order to introduce the requested delay. Note that, for spi_transfer, there is already a field word_delay that provides similar functionality. This field, however, is specified in clock cycles (and worse, SPI controller cycles, not SCK cycles); that makes this value dependent on the master clock instead of the device clock for which the delay is intended to provide some relief. This patch leaves this old word_delay in place and provides a time-based word_delay_us alongside it; the new field fits in the struct padding so struct size is constant. There is only one in-kernel user of the word_delay field and presumably that driver could be reworked to use the time-based value instead. Thanks for your patch! The time-based delay is limited to 8 bits as these delays are intended to be short. The SAMA5D2 that I've tested this on limits delays to a maximum of ~100us, which is already many word-transfer periods even at the minimum transfer speed supported by the controller. Still, the similar delay_usecs uses a u16. The delays are not comparable. delay_usecs is the "end of transfer" delay and represents the processing time to handle a command or a bundle of data. The inter-word delay is just a stutter to give the slave time to get the next word set up. On the Microchip (Atmel... these name changes take a year or two to sink in!) board that I'm using (SAMA5D2), the inter-word delay is limited to 8192 SPI-controller-clock cycles (not SPI bus clock, input clock). At 83Mhz, that's about 100us, and it only gets shorter as you clock up. The Spreadtrum board has an upper limit of 130 SPI-controller-clock cycles which is just a few microseconds. Aside from that limitation, consider what's reasonable in terms of delay. More than 5x the word-transfer time and things are pretty questionable. A 250us delay with a word transfer time of 50us gives an SPI-bus clock 160kHz. That's already pretty slow in SPI terms and well below what the SAMA5D2 is capable of driving with it's 83MHz input clock (max divider is 255 which gives roughtly 400kHz minimum SPI bus clock). So with that, setting an inter-word delay larger than 255us is barely reasonable. If somebody finds a concrete use for such a setting, then the size of the field can be expanded at that time. Just for info, the inter-word delay that I need to communicate with an Atmega MCU running at 500kHz is ~20us which is on the order of the word transfer time itself. This chip is a poor example of how to design an SPI slave so I suspect it can only get better from here! :) And with that said, if you insist having a u16 for this, I'll change it. Just let me know. --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -803,6 +808,7 @@ struct spi_transfer { #defineSPI_NBITS_DUAL 0x02 /* 2bits transfer */ #defineSPI_NBITS_QUAD 0x04 /* 4bits transfer */ u8 bits_per_word; + u8 word_delay_us; us for µs u16 delay_usecs; usecs for µs Can we please try to be consistent? I can change it to usecs if you want. Is this a serious request to do so? _usecs and _us are used pretty interchangeably across the kernel with a slight advantage to _us. /Jonas Gr{oetje,eeting}s, Geert
Re: INFO: task hung in vhost_init_device_iotlb
On Tue, Jan 29, 2019 at 5:06 PM Michael S. Tsirkin wrote: > > On Tue, Jan 29, 2019 at 01:22:02AM -0800, syzbot wrote: > > Hello, > > > > syzbot found the following crash on: > > > > HEAD commit:983542434e6b Merge tag 'edac_fix_for_5.0' of git://git.ker.. > > git tree: upstream > > console output: https://syzkaller.appspot.com/x/log.txt?x=17476498c0 > > kernel config: https://syzkaller.appspot.com/x/.config?x=505743eba4e4f68 > > dashboard link: https://syzkaller.appspot.com/bug?extid=40e28a8bd59d10ed0c42 > > compiler: gcc (GCC) 9.0.0 20181231 (experimental) > > > > Unfortunately, I don't have any reproducer for this crash yet. > > Hmm nothing obvious below. Generic corruption elsewhere? Hard to say, a silent memory corruption is definitely possible. If there is nothing obvious let's wait, maybe syzbot will come up with a repro or we get more such hangs so that it will be possible to rule out flakes/corruptions. > > IMPORTANT: if you fix the bug, please add the following tag to the commit: > > Reported-by: syzbot+40e28a8bd59d10ed0...@syzkaller.appspotmail.com > > > > protocol 88fb is buggy, dev hsr_slave_1 > > protocol 88fb is buggy, dev hsr_slave_0 > > protocol 88fb is buggy, dev hsr_slave_1 > > protocol 88fb is buggy, dev hsr_slave_0 > > protocol 88fb is buggy, dev hsr_slave_1 > > INFO: task syz-executor5:9417 blocked for more than 140 seconds. > > Not tainted 5.0.0-rc3+ #48 > > "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. > > syz-executor5 D27576 9417 8469 0x0004 > > Call Trace: > > context_switch kernel/sched/core.c:2831 [inline] > > __schedule+0x897/0x1e60 kernel/sched/core.c:3472 > > schedule+0xfe/0x350 kernel/sched/core.c:3516 > > protocol 88fb is buggy, dev hsr_slave_0 > > protocol 88fb is buggy, dev hsr_slave_1 > > schedule_preempt_disabled+0x13/0x20 kernel/sched/core.c:3574 > > __mutex_lock_common kernel/locking/mutex.c:1002 [inline] > > __mutex_lock+0xa3b/0x1670 kernel/locking/mutex.c:1072 > > mutex_lock_nested+0x16/0x20 kernel/locking/mutex.c:1087 > > vhost_init_device_iotlb+0x124/0x280 drivers/vhost/vhost.c:1606 > > vhost_net_set_features drivers/vhost/net.c:1674 [inline] > > vhost_net_ioctl+0x1282/0x1c00 drivers/vhost/net.c:1739 > > vfs_ioctl fs/ioctl.c:46 [inline] > > file_ioctl fs/ioctl.c:509 [inline] > > do_vfs_ioctl+0x107b/0x17d0 fs/ioctl.c:696 > > ksys_ioctl+0xab/0xd0 fs/ioctl.c:713 > > __do_sys_ioctl fs/ioctl.c:720 [inline] > > __se_sys_ioctl fs/ioctl.c:718 [inline] > > __x64_sys_ioctl+0x73/0xb0 fs/ioctl.c:718 > > do_syscall_64+0x1a3/0x800 arch/x86/entry/common.c:290 > > protocol 88fb is buggy, dev hsr_slave_0 > > protocol 88fb is buggy, dev hsr_slave_1 > > entry_SYSCALL_64_after_hwframe+0x49/0xbe > > RIP: 0033:0x458099 > > Code: Bad RIP value. > > RSP: 002b:7efd7ca9bc78 EFLAGS: 0246 ORIG_RAX: 0010 > > RAX: ffda RBX: 0003 RCX: 00458099 > > RDX: 2080 RSI: 4008af00 RDI: 0003 > > RBP: 0073bfa0 R08: R09: > > R10: R11: 0246 R12: 7efd7ca9c6d4 > > R13: 004c295b R14: 004d5280 R15: > > INFO: task syz-executor5:9418 blocked for more than 140 seconds. > > Not tainted 5.0.0-rc3+ #48 > > "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. > > syz-executor5 D27800 9418 8469 0x0004 > > Call Trace: > > context_switch kernel/sched/core.c:2831 [inline] > > __schedule+0x897/0x1e60 kernel/sched/core.c:3472 > > schedule+0xfe/0x350 kernel/sched/core.c:3516 > > schedule_preempt_disabled+0x13/0x20 kernel/sched/core.c:3574 > > __mutex_lock_common kernel/locking/mutex.c:1002 [inline] > > __mutex_lock+0xa3b/0x1670 kernel/locking/mutex.c:1072 > > mutex_lock_nested+0x16/0x20 kernel/locking/mutex.c:1087 > > vhost_net_set_owner drivers/vhost/net.c:1697 [inline] > > vhost_net_ioctl+0x426/0x1c00 drivers/vhost/net.c:1754 > > vfs_ioctl fs/ioctl.c:46 [inline] > > file_ioctl fs/ioctl.c:509 [inline] > > do_vfs_ioctl+0x107b/0x17d0 fs/ioctl.c:696 > > ksys_ioctl+0xab/0xd0 fs/ioctl.c:713 > > __do_sys_ioctl fs/ioctl.c:720 [inline] > > __se_sys_ioctl fs/ioctl.c:718 [inline] > > __x64_sys_ioctl+0x73/0xb0 fs/ioctl.c:718 > > do_syscall_64+0x1a3/0x800 arch/x86/entry/common.c:290 > > entry_SYSCALL_64_after_hwframe+0x49/0xbe > > RIP: 0033:0x458099 > > Code: Bad RIP value. > > RSP: 002b:7efd7ca7ac78 EFLAGS: 0246 ORIG_RAX: 0010 > > RAX: ffda RBX: 0003 RCX: 00458099 > > RDX: RSI: 4001af01 RDI: 0003 > > RBP: 0073c040 R08: R09: > > R10: R11: 0246 R12: 7efd7ca7b6d4 > > R13: 004c33a4 R14: 004d5e80 R15: > > > > Showing all locks held in the system: > > 1 lock held by khungtaskd/1040: > > #0: b7479fbe (rcu_read_lock
Re: [PATCH] can: mark expected switch fall-throughs
On 29/01/2019 at 19:06, Gustavo A. R. Silva wrote: > In preparation to enabling -Wimplicit-fallthrough, mark switch cases > where we are expecting to fall through. > > This patch fixes the following warnings: > > drivers/net/can/peak_canfd/peak_pciefd_main.c:668:3: warning: this statement > may fall through [-Wimplicit-fallthrough=] > drivers/net/can/spi/mcp251x.c:875:7: warning: this statement may fall through > [-Wimplicit-fallthrough=] > drivers/net/can/usb/peak_usb/pcan_usb.c:422:6: warning: this statement may > fall through [-Wimplicit-fallthrough=] > drivers/net/can/at91_can.c:895:6: warning: this statement may fall through > [-Wimplicit-fallthrough=] > drivers/net/can/at91_can.c:953:15: warning: this statement may fall through > [-Wimplicit-fallthrough=] > drivers/net/can/usb/peak_usb/pcan_usb.c: In function ‘pcan_usb_decode_error’: > drivers/net/can/usb/peak_usb/pcan_usb.c:422:6: warning: this statement may > fall through [-Wimplicit-fallthrough=] > if (n & PCAN_USB_ERROR_BUS_LIGHT) { >^ > drivers/net/can/usb/peak_usb/pcan_usb.c:428:2: note: here >case CAN_STATE_ERROR_WARNING: >^~~~ > > Warning level 3 was used: -Wimplicit-fallthrough=3 > > This patch is part of the ongoing efforts to enabling > -Wimplicit-fallthrough. > > Notice that in some cases spelling mistakes were fixed. > In other cases, the /* fall through */ comment is placed > at the bottom of the case statement, which is what GCC > is expecting to find. > > Signed-off-by: Gustavo A. R. Silva > --- > drivers/net/can/at91_can.c| 6 -- For this one: Acked-by: Nicolas Ferre > drivers/net/can/peak_canfd/peak_pciefd_main.c | 2 +- > drivers/net/can/spi/mcp251x.c | 3 ++- > drivers/net/can/usb/peak_usb/pcan_usb.c | 2 +- > 4 files changed, 8 insertions(+), 5 deletions(-) > > diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c > index d98c69045b17..1718c20f9c99 100644 > --- a/drivers/net/can/at91_can.c > +++ b/drivers/net/can/at91_can.c > @@ -902,7 +902,8 @@ static void at91_irq_err_state(struct net_device *dev, > CAN_ERR_CRTL_TX_WARNING : > CAN_ERR_CRTL_RX_WARNING; > } > - case CAN_STATE_ERROR_WARNING: /* fallthrough */ > + /* fall through */ > + case CAN_STATE_ERROR_WARNING: > /* >* from: ERROR_ACTIVE, ERROR_WARNING >* to : ERROR_PASSIVE, BUS_OFF > @@ -951,7 +952,8 @@ static void at91_irq_err_state(struct net_device *dev, > netdev_dbg(dev, "Error Active\n"); > cf->can_id |= CAN_ERR_PROT; > cf->data[2] = CAN_ERR_PROT_ACTIVE; > - case CAN_STATE_ERROR_WARNING: /* fallthrough */ > + /* fall through */ > + case CAN_STATE_ERROR_WARNING: > reg_idr = AT91_IRQ_ERRA | AT91_IRQ_WARN | AT91_IRQ_BOFF; > reg_ier = AT91_IRQ_ERRP; > break; > diff --git a/drivers/net/can/peak_canfd/peak_pciefd_main.c > b/drivers/net/can/peak_canfd/peak_pciefd_main.c > index c458d5fdc8d3..e4f4d65a76b4 100644 > --- a/drivers/net/can/peak_canfd/peak_pciefd_main.c > +++ b/drivers/net/can/peak_canfd/peak_pciefd_main.c > @@ -668,7 +668,7 @@ static int pciefd_can_probe(struct pciefd_board *pciefd) > pciefd_can_writereg(priv, CANFD_CLK_SEL_80MHZ, > PCIEFD_REG_CAN_CLK_SEL); > > - /* fallthough */ > + /* fall through */ > case CANFD_CLK_SEL_80MHZ: > priv->ucan.can.clock.freq = 80 * 1000 * 1000; > break; > diff --git a/drivers/net/can/spi/mcp251x.c b/drivers/net/can/spi/mcp251x.c > index e90817608645..17257c73c302 100644 > --- a/drivers/net/can/spi/mcp251x.c > +++ b/drivers/net/can/spi/mcp251x.c > @@ -875,7 +875,8 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id) > if (new_state >= CAN_STATE_ERROR_WARNING && > new_state <= CAN_STATE_BUS_OFF) > priv->can.can_stats.error_warning++; > - case CAN_STATE_ERROR_WARNING: /* fallthrough */ > + /* fall through */ > + case CAN_STATE_ERROR_WARNING: > if (new_state >= CAN_STATE_ERROR_PASSIVE && > new_state <= CAN_STATE_BUS_OFF) > priv->can.can_stats.error_passive++; > diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c > b/drivers/net/can/usb/peak_usb/pcan_usb.c > index 13238a72a338..eca785532b6b 100644 > --- a/drivers/net/can/usb/peak_usb/pcan_usb.c > +++ b/drivers/net/can/usb/peak_usb/pcan_usb.c > @@ -423,7 +423,7 @@ static int pcan_usb_decode_error(struct > pcan_usb_msg_context *mc, u8 n, > new_state = CAN_STATE_ERROR_WARNING; > break; > } > - /* else: fall through */ > + /* fall through */ > >
Re: [v3 PATCH] mm: ksm: do not block on page lock when searching stable tree
On 29.01.2019 23:29, Yang Shi wrote: > ksmd need search stable tree to look for the suitable KSM page, but the > KSM page might be locked for a while due to i.e. KSM page rmap walk. > Basically it is not a big deal since commit 2c653d0ee2ae > ("ksm: introduce ksm_max_page_sharing per page deduplication limit"), > since max_page_sharing limits the number of shared KSM pages. > > But it still sounds not worth waiting for the lock, the page can be skip, > then try to merge it in the next scan to avoid potential stall if its > content is still intact. > > Introduce trylock mode to get_ksm_page() to not block on page lock, like > what try_to_merge_one_page() does. And, define three possible > operations (nolock, lock and trylock) as enum type to avoid stacking up > bools and make the code more readable. > > Return -EBUSY if trylock fails, since NULL means not find suitable KSM > page, which is a valid case. > > With the default max_page_sharing setting (256), there is almost no > observed change comparing lock vs trylock. > > However, with ksm02 of LTP, the reduced ksmd full scan time can be > observed, which has set max_page_sharing to 786432. With lock version, > ksmd may tak 10s - 11s to run two full scans, with trylock version ksmd > may take 8s - 11s to run two full scans. And, the number of > pages_sharing and pages_to_scan keep same. Basically, this change has > no harm. > > Cc: Hugh Dickins > Cc: Andrea Arcangeli > Suggested-by: John Hubbard > Reviewed-by: Kirill Tkhai Also looks good for me. > Signed-off-by: Yang Shi > --- > Hi folks, > > This patch was with "mm: vmscan: skip KSM page in direct reclaim if priority > is low" in the initial submission. Then Hugh and Andrea pointed out commit > 2c653d0ee2ae ("ksm: introduce ksm_max_page_sharing per page deduplication > limit") is good enough for limiting the number of shared KSM page to prevent > from softlock when walking ksm page rmap. This commit does solve the problem. > So, the series was dropped by Andrew from -mm tree. > > However, I thought the second patch (this one) still sounds useful. So, I did > some test and resubmit it. The first version was reviewed by Krill Tkhai, so > I keep his Reviewed-by tag since there is no change to the patch except the > commit log. > > So, would you please reconsider this patch? > > v3: Use enum to define get_ksm_page operations (nolock, lock and trylock) per > John Hubbard > v2: Updated the commit log to reflect some test result and latest discussion > > mm/ksm.c | 46 -- > 1 file changed, 36 insertions(+), 10 deletions(-) > > diff --git a/mm/ksm.c b/mm/ksm.c > index 6c48ad1..5647bc1 100644 > --- a/mm/ksm.c > +++ b/mm/ksm.c > @@ -667,6 +667,12 @@ static void remove_node_from_stable_tree(struct > stable_node *stable_node) > free_stable_node(stable_node); > } > > +enum get_ksm_page_flags { > + GET_KSM_PAGE_NOLOCK, > + GET_KSM_PAGE_LOCK, > + GET_KSM_PAGE_TRYLOCK > +}; > + > /* > * get_ksm_page: checks if the page indicated by the stable node > * is still its ksm page, despite having held no reference to it. > @@ -686,7 +692,8 @@ static void remove_node_from_stable_tree(struct > stable_node *stable_node) > * a page to put something that might look like our key in page->mapping. > * is on its way to being freed; but it is an anomaly to bear in mind. > */ > -static struct page *get_ksm_page(struct stable_node *stable_node, bool > lock_it) > +static struct page *get_ksm_page(struct stable_node *stable_node, > + enum get_ksm_page_flags flags) > { > struct page *page; > void *expected_mapping; > @@ -728,8 +735,15 @@ static struct page *get_ksm_page(struct stable_node > *stable_node, bool lock_it) > goto stale; > } > > - if (lock_it) { > + if (flags == GET_KSM_PAGE_TRYLOCK) { > + if (!trylock_page(page)) { > + put_page(page); > + return ERR_PTR(-EBUSY); > + } > + } else if (flags == GET_KSM_PAGE_LOCK) > lock_page(page); > + > + if (flags != GET_KSM_PAGE_NOLOCK) { > if (READ_ONCE(page->mapping) != expected_mapping) { > unlock_page(page); > put_page(page); > @@ -763,7 +777,7 @@ static void remove_rmap_item_from_tree(struct rmap_item > *rmap_item) > struct page *page; > > stable_node = rmap_item->head; > - page = get_ksm_page(stable_node, true); > + page = get_ksm_page(stable_node, GET_KSM_PAGE_LOCK); > if (!page) > goto out; > > @@ -863,7 +877,7 @@ static int remove_stable_node(struct stable_node > *stable_node) > struct page *page; > int err; > > - page = get_ksm_page(stable_node, true); > + page = get_ksm_page(stable_node, GET_KSM_PAGE_LOCK); > if (!page) { > /* >
Re: [PATCH v5 1/2] pwm: sifive: Add DT documentation for SiFive PWM Controller
On Tue, Jan 29, 2019 at 05:13:18PM +0530, Yash Shah wrote: > DT documentation for PWM controller added. > > Signed-off-by: Wesley W. Terpstra > [Atish: Compatible string update] > Signed-off-by: Atish Patra > Signed-off-by: Yash Shah > --- > .../devicetree/bindings/pwm/pwm-sifive.txt | 33 > ++ > 1 file changed, 33 insertions(+) > create mode 100644 Documentation/devicetree/bindings/pwm/pwm-sifive.txt > > diff --git a/Documentation/devicetree/bindings/pwm/pwm-sifive.txt > b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt > new file mode 100644 > index 000..8dcb40d > --- /dev/null > +++ b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt > @@ -0,0 +1,33 @@ > +SiFive PWM controller > + > +Unlike most other PWM controllers, the SiFive PWM controller currently only > +supports one period for all channels in the PWM. This is set globally in DTS. You can simply drop this if the first user can set this using the usual interface. Don't you like this suggestion that I already made a few times now? Did you consider to make the driver support only a single output with a more flexible period setting? > +The period also has significant restrictions on the values it can achieve, > +which the driver rounds to the nearest achievable frequency. Rounding a period to a frequency sounds wrong. Best regards Uwe -- Pengutronix e.K. | Uwe Kleine-König| Industrial Linux Solutions | http://www.pengutronix.de/ |
[LSF/MM TOPIC]: userfaultfd (was: [LSF/MM TOPIC] NUMA remote THP vs NUMA local non-THP under MADV_HUGEPAGE)
Hi, (changed the subject and added CRIU folks) On Tue, Jan 29, 2019 at 06:40:58PM -0500, Andrea Arcangeli wrote: > Hello, > > -- > > In addition to the above "NUMA remote THP vs NUMA local non-THP > tradeoff" topic, there are other developments in "userfaultfd" land that > are approaching merge readiness and that would be possible to provide a > short overview about: > > - Peter Xu made significant progress in finalizing the userfaultfd-WP > support over the last few months. That feature was planned from the > start and it will allow userland to do some new things that weren't > possible to achieve before. In addition to synchronously blocking > write faults to be resolved by an userland manager, it has also the > ability to obsolete the softdirty feature, because it can provide > the same information, but with O(1) complexity (as opposed of the > current softdirty O(N) complexity) similarly to what the Page > Modification Logging (PML) does in hardware for EPT write accesses. We (CRIU) have some concerns about obsoleting soft-dirty in favor of uffd-wp. If there are other soft-dirty users these concerns would be relevant to them as well. With soft-dirty we collect the information about the changed memory every pre-dump iteration in the following manner: * freeze the tasks * find entries in /proc/pid/pagemap with SOFT_DIRTY set * unfreeze the tasks * dump the modified pages to disk/remote host While we do need to traverse the /proc/pid/pagemap to identify dirty pages, in between the pre-dump iterations and during the actual memory dump the tasks are running freely. If we are to switch to uffd-wp, every write by the snapshotted/migrated task will incur latency of uffd-wp processing by the monitor. We'd need to see how this affects overall slowdown of the workload under migration before moving forward with obsoleting soft-dirty. > - Blake Caldwell maintained the UFFDIO_REMAP support to atomically > remove memory from a mapping with userfaultfd (which can't be done > with a copy as in UFFDIO_COPY and it requires a slow TLB flush to be > safe) as an alternative to host swapping (which of course also > requires a TLB flush for similar reasons). Notably UFFDIO_REMAP was > rightfully naked early on and quickly replaced by UFFDIO_COPY which > is more optimal to add memory to a mapping is small chunks, but we > can't remove memory with UFFDIO_COPY and UFFDIO_REMAP should be as > efficient as it gets when it comes to removing memory from a > mapping. If we are to discuss userfaultfd, I'd like also to bring the subject of COW mappings. The pages populated with UFFDIO_COPY cannot be COW-shared between related processes which unnecessarily increases memory footprint of a migrated process tree. I've posted a patch [1] a (real) while ago, but nobody reacted and I've put this aside. Maybe it's time to discuss it again :) > Thank you, > Andrea > [1] https://lwn.net/ml/linux-api/20180328101729.GB1743%40rapoport-lnx/ -- Sincerely yours, Mike.
Re: [PATCH v5 1/2] spi: support inter-word delay requirement for devices
Hi Jonas, On Wed, Jan 30, 2019 at 9:10 AM Jonas Bonn wrote: > On 30/01/2019 08:35, Geert Uytterhoeven wrote: > > On Tue, Jan 29, 2019 at 9:55 PM Jonas Bonn wrote: > >> Some devices are slow and cannot keep up with the SPI bus and therefore > >> require a short delay between words of the SPI transfer. > >> > >> The example of this that I'm looking at is a SAMA5D2 with a minimum SPI > >> clock of 400kHz talking to an AVR-based SPI slave. The AVR cannot put > >> bytes on the bus fast enough to keep up with the SoC's SPI controller > >> even at the lowest bus speed. > >> > >> This patch introduces the ability to specify a required inter-word > >> delay for SPI devices. It is up to the controller driver to configure > >> itself accordingly in order to introduce the requested delay. > >> > >> Note that, for spi_transfer, there is already a field word_delay that > >> provides similar functionality. This field, however, is specified in > >> clock cycles (and worse, SPI controller cycles, not SCK cycles); that > >> makes this value dependent on the master clock instead of the device > >> clock for which the delay is intended to provide some relief. This > >> patch leaves this old word_delay in place and provides a time-based > >> word_delay_us alongside it; the new field fits in the struct padding > >> so struct size is constant. There is only one in-kernel user of the > >> word_delay field and presumably that driver could be reworked to use > >> the time-based value instead. > > > > Thanks for your patch! > > > >> The time-based delay is limited to 8 bits as these delays are intended > >> to be short. The SAMA5D2 that I've tested this on limits delays to a > >> maximum of ~100us, which is already many word-transfer periods even at > >> the minimum transfer speed supported by the controller. > > > > Still, the similar delay_usecs uses a u16. > > The delays are not comparable. delay_usecs is the "end of transfer" > delay and represents the processing time to handle a command or a bundle > of data. The inter-word delay is just a stutter to give the slave time > to get the next word set up. > > On the Microchip (Atmel... these name changes take a year or two to sink > in!) board that I'm using (SAMA5D2), the inter-word delay is limited to > 8192 SPI-controller-clock cycles (not SPI bus clock, input clock). At > 83Mhz, that's about 100us, and it only gets shorter as you clock up. > The Spreadtrum board has an upper limit of 130 SPI-controller-clock > cycles which is just a few microseconds. > > Aside from that limitation, consider what's reasonable in terms of > delay. More than 5x the word-transfer time and things are pretty > questionable. A 250us delay with a word transfer time of 50us gives an > SPI-bus clock 160kHz. That's already pretty slow in SPI terms and well > below what the SAMA5D2 is capable of driving with it's 83MHz input clock > (max divider is 255 which gives roughtly 400kHz minimum SPI bus clock). > > So with that, setting an inter-word delay larger than 255us is barely > reasonable. If somebody finds a concrete use for such a setting, then > the size of the field can be expanded at that time. > > Just for info, the inter-word delay that I need to communicate with an > Atmega MCU running at 500kHz is ~20us which is on the order of the word > transfer time itself. This chip is a poor example of how to design an > SPI slave so I suspect it can only get better from here! :) > > And with that said, if you insist having a u16 for this, I'll change it. > Just let me know. I'll defer that to the maintainer (Mark). > >> --- a/include/linux/spi/spi.h > >> +++ b/include/linux/spi/spi.h > > > >> @@ -803,6 +808,7 @@ struct spi_transfer { > >> #defineSPI_NBITS_DUAL 0x02 /* 2bits transfer */ > >> #defineSPI_NBITS_QUAD 0x04 /* 4bits transfer */ > >> u8 bits_per_word; > >> + u8 word_delay_us; > > > > us for µs > > > >> u16 delay_usecs; > > > > usecs for µs > > > > Can we please try to be consistent? > > I can change it to usecs if you want. Is this a serious request to do > so? _usecs and _us are used pretty interchangeably across the kernel > with a slight advantage to _us. Personally, I prefer "us", too. Unfortunately not everyone has been converted to metric, SI, and EURO yet ;-) However, it looks really odd if the next line uses "usecs". Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Re: [PATCH v5 2/2] spi-atmel: support inter-word delay
On 29/01/2019 at 21:55, Jonas Bonn wrote: > If the SPI slave requires an inter-word delay, configure the DLYBCT > register accordingly. > > Tested on a SAMA5D2 board (derived from SAMA5D2-Xplained reference > board). > > Signed-off-by: Jonas Bonn > CC: Nicolas Ferre > CC: Mark Brown > CC: Alexandre Belloni > CC: Ludovic Desroches > CC: linux-...@vger.kernel.org > CC: linux-arm-ker...@lists.infradead.org > --- > drivers/spi/spi-atmel.c | 11 ++- > 1 file changed, 6 insertions(+), 5 deletions(-) > > diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c > index f53f0c5e63da..57cc7110f9e8 100644 > --- a/drivers/spi/spi-atmel.c > +++ b/drivers/spi/spi-atmel.c > @@ -1201,13 +1201,14 @@ static int atmel_spi_setup(struct spi_device *spi) > csr |= SPI_BIT(CSAAT); > > /* DLYBS is mostly irrelevant since we manage chipselect using GPIOs. > - * > - * DLYBCT would add delays between words, slowing down transfers. > - * It could potentially be useful to cope with DMA bottlenecks, but > - * in those cases it's probably best to just use a lower bitrate. >*/ > csr |= SPI_BF(DLYBS, 0); > - csr |= SPI_BF(DLYBCT, 0); > + > + /* DLYBCT adds delays between words. This is useful for slow devices > + * that need a bit of time to setup the next transfer. > + */ > + csr |= SPI_BF(DLYBCT, > + (as->spi_clk / 100 * spi->word_delay_us) >> 5); Looks good to me: Acked-by: Nicolas Ferre > asd = spi->controller_state; > if (!asd) { > -- Nicolas Ferre
[PATCH] PM-runtime: fix deadlock with ktime
A deadlock has been seen when swicthing clocksources which use PM runtime. The call path is: change_clocksource ... write_seqcount_begin ... timekeeping_update ... sh_cmt_clocksource_enable ... rpm_resume pm_runtime_mark_last_busy ktime_get do read_seqcount_begin while read_seqcount_retry write_seqcount_end Although we should be safe because we haven't yet changed the clocksource at that time, we can't because of seqcount protection. Use ktime_get_mono_fast_ns instead which is lock safe for such case Fixes: 8234f6734c5d ("PM-runtime: Switch autosuspend over to using hrtimers") Reported-by: Biju Das Signed-off-by: Vincent Guittot --- drivers/base/power/runtime.c | 10 +- include/linux/pm_runtime.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 457be03..708a13f 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -130,7 +130,7 @@ u64 pm_runtime_autosuspend_expiration(struct device *dev) { int autosuspend_delay; u64 last_busy, expires = 0; - u64 now = ktime_to_ns(ktime_get()); + u64 now = ktime_get_mono_fast_ns(); if (!dev->power.use_autosuspend) goto out; @@ -909,7 +909,7 @@ static enum hrtimer_restart pm_suspend_timer_fn(struct hrtimer *timer) * If 'expires' is after the current time, we've been called * too early. */ - if (expires > 0 && expires < ktime_to_ns(ktime_get())) { + if (expires > 0 && expires < ktime_get_mono_fast_ns()) { dev->power.timer_expires = 0; rpm_suspend(dev, dev->power.timer_autosuspends ? (RPM_ASYNC | RPM_AUTO) : RPM_ASYNC); @@ -928,7 +928,7 @@ static enum hrtimer_restart pm_suspend_timer_fn(struct hrtimer *timer) int pm_schedule_suspend(struct device *dev, unsigned int delay) { unsigned long flags; - ktime_t expires; + u64 expires; int retval; spin_lock_irqsave(&dev->power.lock, flags); @@ -945,8 +945,8 @@ int pm_schedule_suspend(struct device *dev, unsigned int delay) /* Other scheduled or pending requests need to be canceled. */ pm_runtime_cancel_pending(dev); - expires = ktime_add(ktime_get(), ms_to_ktime(delay)); - dev->power.timer_expires = ktime_to_ns(expires); + expires = ktime_get_mono_fast_ns() + (u64)delay * NSEC_PER_MSEC); + dev->power.timer_expires = expires; dev->power.timer_autosuspends = 0; hrtimer_start(&dev->power.suspend_timer, expires, HRTIMER_MODE_ABS); diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h index 54af4ee..fed5be7 100644 --- a/include/linux/pm_runtime.h +++ b/include/linux/pm_runtime.h @@ -105,7 +105,7 @@ static inline bool pm_runtime_callbacks_present(struct device *dev) static inline void pm_runtime_mark_last_busy(struct device *dev) { - WRITE_ONCE(dev->power.last_busy, ktime_to_ns(ktime_get())); + WRITE_ONCE(dev->power.last_busy, ktime_get_mono_fast_ns()); } static inline bool pm_runtime_is_irq_safe(struct device *dev) -- 2.7.4
Re: [PATCH 05/11] mmc: s3cmci: handle highmem pages
On Wed, 30 Jan 2019 at 09:04, Christoph Hellwig wrote: > > On Wed, Jan 30, 2019 at 08:57:47AM +0100, Ulf Hansson wrote: > > On Mon, 14 Jan 2019 at 10:58, Christoph Hellwig wrote: > > > > > > Instead of setting up a kernel pointer to track the current PIO address, > > > track the offset in the current page, and do an atomic kmap for the page > > > while doing the actual PIO operations. > > > > > > Signed-off-by: Christoph Hellwig > > > > Nitpick: This one have some trailing whitespace errors, which git > > complains about when I apply it. > > > > No need to re-spin due to this, I can fix it up. > > I'll need to respin to limit the segment size to a page anyway, so I > will take this into account as well for v2. Okay! FYI, I have no further comment on the series, it looks okay to me! Kind regards Uffe
[PATCH V2] lightnvm: pblk: extend line wp balance check
From: Hans Holmberg pblk stripes writes of minimal write size across all non-offline chunks in a line, which means that the maximum write pointer delta should not exceed the minimal write size. Extend the line write pointer balance check to cover this case, and ignore the offline chunk wps. This will render us a warning during recovery if something unexpected has happened to the chunk write pointers (i.e. powerloss, a spurious chunk reset, ..). Reported-by: Zhoujie Wu Tested-by: Zhoujie Wu Signed-off-by: Hans Holmberg --- Changes since V1: * Squashed with Zhoujie's: "lightnvm: pblk: ignore bad block wp for pblk_line_wp_is_unbalanced" * Clarified commit message based on Javier's comments. drivers/lightnvm/pblk-recovery.c | 56 ++-- 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/drivers/lightnvm/pblk-recovery.c b/drivers/lightnvm/pblk-recovery.c index 6761d2afa4d0..d86f580036d3 100644 --- a/drivers/lightnvm/pblk-recovery.c +++ b/drivers/lightnvm/pblk-recovery.c @@ -302,35 +302,55 @@ static int pblk_pad_distance(struct pblk *pblk, struct pblk_line *line) return (distance > line->left_msecs) ? line->left_msecs : distance; } -static int pblk_line_wp_is_unbalanced(struct pblk *pblk, - struct pblk_line *line) +/* Return a chunk belonging to a line by stripe(write order) index */ +static struct nvm_chk_meta *pblk_get_stripe_chunk(struct pblk *pblk, + struct pblk_line *line, + int index) { struct nvm_tgt_dev *dev = pblk->dev; struct nvm_geo *geo = &dev->geo; - struct pblk_line_meta *lm = &pblk->lm; struct pblk_lun *rlun; - struct nvm_chk_meta *chunk; struct ppa_addr ppa; - u64 line_wp; - int pos, i; + int pos; - rlun = &pblk->luns[0]; + rlun = &pblk->luns[index]; ppa = rlun->bppa; pos = pblk_ppa_to_pos(geo, ppa); - chunk = &line->chks[pos]; - line_wp = chunk->wp; + return &line->chks[pos]; +} - for (i = 1; i < lm->blk_per_line; i++) { - rlun = &pblk->luns[i]; - ppa = rlun->bppa; - pos = pblk_ppa_to_pos(geo, ppa); - chunk = &line->chks[pos]; +static int pblk_line_wps_are_unbalanced(struct pblk *pblk, + struct pblk_line *line) +{ + struct pblk_line_meta *lm = &pblk->lm; + int blk_in_line = lm->blk_per_line; + struct nvm_chk_meta *chunk; + u64 max_wp, min_wp; + int i; + + i = find_first_zero_bit(line->blk_bitmap, blk_in_line); - if (chunk->wp > line_wp) + /* If there is one or zero good chunks in the line, +* the write pointers can't be unbalanced. +*/ + if (i >= (blk_in_line - 1)) + return 0; + + chunk = pblk_get_stripe_chunk(pblk, line, i); + max_wp = chunk->wp; + if (max_wp > pblk->max_write_pgs) + min_wp = max_wp - pblk->max_write_pgs; + else + min_wp = 0; + + i = find_next_zero_bit(line->blk_bitmap, blk_in_line, i + 1); + while (i < blk_in_line) { + chunk = pblk_get_stripe_chunk(pblk, line, i); + if (chunk->wp > max_wp || chunk->wp < min_wp) return 1; - else if (chunk->wp < line_wp) - line_wp = chunk->wp; + + i = find_next_zero_bit(line->blk_bitmap, blk_in_line, i + 1); } return 0; @@ -356,7 +376,7 @@ static int pblk_recov_scan_oob(struct pblk *pblk, struct pblk_line *line, int ret; u64 left_ppas = pblk_sec_in_open_line(pblk, line) - lm->smeta_sec; - if (pblk_line_wp_is_unbalanced(pblk, line)) + if (pblk_line_wps_are_unbalanced(pblk, line)) pblk_warn(pblk, "recovering unbalanced line (%d)\n", line->id); ppa_list = p.ppa_list; -- 2.17.1
Re: [Intel-gfx] linux-next: build failure after merge of the drm-intel-fixes tree
On Tue, 29 Jan 2019, Lucas De Marchi wrote: > On Tue, Jan 29, 2019 at 2:39 PM Stephen Rothwell > wrote: >> >> Hi all, >> >> After merging the drm-intel-fixes tree, today's linux-next build (x86_64 >> allmodconfig) failed like this: >> >> drivers/gpu/drm/i915/intel_display.c: In function 'has_bogus_dpll_config': >> drivers/gpu/drm/i915/intel_display.c:15432:27: error: macro "IS_GEN" >> requires 3 arguments, but only 2 given >> return IS_GEN(dev_priv, 6) && >>^ >> >> Caused by commit >> >> a49a17226feb ("drm/i915: Try to sanitize bogus DPLL state left over by >> broken SNB BIOSen") >> >> It seems this was cherry-picked incorrectly :-( > > while the cherry-pick was correct, the macro is different on > drm-intel-fixes. IS_GEN(dev_priv, 6) needs to be converted to > IS_GEN6(dev_priv). > > Lucas De Marchi > >> >> I have reverted that commit for today. Dropped the commit from drm-intel-fixes. Somehow I had managed to screw up my kernel config in a way that avoided the build failure. BR, Jani. -- Jani Nikula, Intel Open Source Graphics Center
Re: [PATCH] PM-runtime: fix deadlock with ktime
Hi Vincent, On Wed, Jan 30, 2019 at 9:16 AM Vincent Guittot wrote: > A deadlock has been seen when swicthing clocksources which use PM runtime. > The call path is: > change_clocksource > ... > write_seqcount_begin > ... > timekeeping_update > ... > sh_cmt_clocksource_enable > ... > rpm_resume > pm_runtime_mark_last_busy > ktime_get > do > read_seqcount_begin > while read_seqcount_retry > > write_seqcount_end > > Although we should be safe because we haven't yet changed the clocksource > at that time, we can't because of seqcount protection. > > Use ktime_get_mono_fast_ns instead which is lock safe for such case > > Fixes: 8234f6734c5d ("PM-runtime: Switch autosuspend over to using hrtimers") > Reported-by: Biju Das > Signed-off-by: Vincent Guittot Thanks for your patch! /** * ktime_get_mono_fast_ns - Fast NMI safe access to clock monotonic * * This timestamp is not guaranteed to be monotonic across an update. * The timestamp is calculated by: * * now = base_mono + clock_delta * slope * * So if the update lowers the slope, readers who are forced to the * not yet updated second array are still using the old steeper slope. * * tmono * ^ * |o n * | o n * | u * | o * |o * |12345678---> reader order * * o = old slope * u = update * n = new slope * * So reader 6 will observe time going backwards versus reader 5. * * While other CPUs are likely to be able observe that, the only way * for a CPU local observation is when an NMI hits in the middle of * the update. Timestamps taken from that NMI context might be ahead * of the following timestamps. Callers need to be aware of that and * deal with it. */ As this function is not guaranteed to be monotonic, have you checked how the Runtime PM code behaves if time goes backwards? Does it just make a suboptimal decision or does it crash? Thanks! Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Re: [PATCH v2] USB: Disable USB2 LPM at shutdown
On Thu, Jan 24, 2019 at 02:16:43PM +0800, Kai-Heng Feng wrote: > The QCA Rome USB Bluetooth controller has several issues once LPM gets > enabled: > - Fails to get enumerated in coldboot. [1] > - Drains more power (~ 0.2W) when the system is in S5. [2] > - Disappears after a warmboot. [2] > > The issue happens because the device lingers at LPM L1 in S5, so device > can't get enumerated even after a reboot. > > Disable LPM at shutdown to solve the issue. > > [1] https://bugs.launchpad.net/bugs/1757218 > [2] https://patchwork.kernel.org/patch/10607097/ > > Signed-off-by: Kai-Heng Feng > --- > v2: Use new LPM helpers. > > drivers/usb/core/port.c | 9 + > 1 file changed, 9 insertions(+) > > diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c > index 1a06a4b5fbb1..35fa639f 100644 > --- a/drivers/usb/core/port.c > +++ b/drivers/usb/core/port.c > @@ -285,6 +285,14 @@ static int usb_port_runtime_suspend(struct device *dev) > } > #endif > > +static void usb_port_shutdown(struct device *dev) > +{ > + struct usb_port *port_dev = to_usb_port(dev); > + > + if (port_dev->child) > + usb_disable_usb2_hardware_lpm(port_dev->child); > +} > + > static const struct dev_pm_ops usb_port_pm_ops = { > #ifdef CONFIG_PM > .runtime_suspend = usb_port_runtime_suspend, > @@ -301,6 +309,7 @@ struct device_type usb_port_device_type = { > static struct device_driver usb_port_driver = { > .name = "usb", > .owner = THIS_MODULE, > + .shutdown = usb_port_shutdown, > }; So you now do this for all ports in the system, no matter what is plugged in or not. Are you _SURE_ you want to do that? It seems like a big hammer to solve just one single device's problems. thanks, greg k-h
[PATCH v2 1/2] x86: respect memory size limiting via mem= parameter
When limiting memory size via kernel parameter "mem=" this should be respected even in case of memory made accessible via a PCI card. Today this kind of memory won't be made usable in initial memory setup as the memory won't be visible in E820 map, but it might be added when adding PCI devices due to corresponding ACPI table entries. Not respecting "mem=" can be corrected by adding a global max_mem_size variable set by parse_memopt() which will result in rejecting adding memory areas resulting in a memory size above the allowed limit. Signed-off-by: Juergen Gross --- arch/x86/kernel/e820.c | 5 + include/linux/memory_hotplug.h | 2 ++ mm/memory_hotplug.c| 6 ++ 3 files changed, 13 insertions(+) diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 50895c2f937d..e67513e2cbbb 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -881,6 +882,10 @@ static int __init parse_memopt(char *p) e820__range_remove(mem_size, ULLONG_MAX - mem_size, E820_TYPE_RAM, 1); +#ifdef CONFIG_MEMORY_HOTPLUG + max_mem_size = mem_size; +#endif + return 0; } early_param("mem", parse_memopt); diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h index 07da5c6c5ba0..fb6bd0022d41 100644 --- a/include/linux/memory_hotplug.h +++ b/include/linux/memory_hotplug.h @@ -98,6 +98,8 @@ extern void __online_page_free(struct page *page); extern int try_online_node(int nid); +extern u64 max_mem_size; + extern bool memhp_auto_online; /* If movable_node boot option specified */ extern bool movable_node_enabled; diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index b9a667d36c55..94f81c596151 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -96,10 +96,16 @@ void mem_hotplug_done(void) cpus_read_unlock(); } +u64 max_mem_size = U64_MAX; + /* add this memory to iomem resource */ static struct resource *register_memory_resource(u64 start, u64 size) { struct resource *res, *conflict; + + if (start + size > max_mem_size) + return ERR_PTR(-E2BIG); + res = kzalloc(sizeof(struct resource), GFP_KERNEL); if (!res) return ERR_PTR(-ENOMEM); -- 2.16.4
[PATCH v2 0/2] x86: respect memory size limits
On a customer system running Xen a boot problem was observed due to the kernel not respecting the memory size limit imposed by the Xen hypervisor. During analysis I found the same problem should be able to occur on bare metal in case the memory would be limited via the "mem=" boot parameter. The system this problem has been observed on has tons of memory added via PCI. So while in the E820 map the not to be used memory has been wiped out the additional PCI memory is detected during ACPI scan and it is added via __add_memory(). This small series tries to repair the issue by testing the imposed memory limit during the memory hotplug process and refusing to add it in case the limit is being violated. I've chosen to refuse adding the complete memory chunk in case the limit is reached instead of adding only some of the memory, as I thought this would result in less problems (e.g. avoiding to add only parts of a 128MB memory bar which might be difficult to remove later). Changes in V2: - patch 1: set initial allowed size to U64_MAX instead -1 - patch 2: set initial allowed size to end of E820 RAM Juergen Gross (2): x86: respect memory size limiting via mem= parameter x86/xen: dont add memory above max allowed allocation arch/x86/kernel/e820.c | 5 + arch/x86/xen/setup.c | 10 ++ drivers/xen/xen-balloon.c | 6 ++ include/linux/memory_hotplug.h | 2 ++ mm/memory_hotplug.c| 6 ++ 5 files changed, 29 insertions(+) -- 2.16.4
[PATCH v2 2/2] x86/xen: dont add memory above max allowed allocation
Don't allow memory to be added above the allowed maximum allocation limit set by Xen. Trying to do so would result in cases like the following: [ 584.559652] [ cut here ] [ 584.564897] WARNING: CPU: 2 PID: 1 at ../arch/x86/xen/multicalls.c:129 xen_alloc_pte+0x1c7/0x390() [ 584.575151] Modules linked in: [ 584.578643] Supported: Yes [ 584.581750] CPU: 2 PID: 1 Comm: swapper/0 Not tainted 4.4.120-92.70-default #1 [ 584.59] Hardware name: Cisco Systems Inc UCSC-C460-M4/UCSC-C460-M4, BIOS C460M4.4.0.1b.0.0629181419 06/29/2018 [ 584.601862] 813175a0 8184777c [ 584.610200] 8107f4e1 880487eb7000 8801862b79c0 88048608d290 [ 584.618537] 00487eb7 ea000201 81009de7 81068561 [ 584.626876] Call Trace: [ 584.629699] [] dump_trace+0x59/0x340 [ 584.635645] [] show_stack_log_lvl+0xea/0x170 [ 584.642391] [] show_stack+0x21/0x40 [ 584.648238] [] dump_stack+0x5c/0x7c [ 584.654085] [] warn_slowpath_common+0x81/0xb0 [ 584.660932] [] xen_alloc_pte+0x1c7/0x390 [ 584.667289] [] pmd_populate_kernel.constprop.6+0x40/0x80 [ 584.675241] [] phys_pmd_init+0x210/0x255 [ 584.681587] [] phys_pud_init+0x1da/0x247 [ 584.687931] [] kernel_physical_mapping_init+0xf5/0x1d4 [ 584.695682] [] init_memory_mapping+0x18d/0x380 [ 584.702631] [] arch_add_memory+0x59/0xf0 Signed-off-by: Juergen Gross --- arch/x86/xen/setup.c | 10 ++ drivers/xen/xen-balloon.c | 6 ++ 2 files changed, 16 insertions(+) diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index d5f303c0e656..fdb184cadaf5 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -825,6 +826,15 @@ char * __init xen_memory_setup(void) xen_max_p2m_pfn = pfn_s + n_pfns; } else discard = true; +#ifdef CONFIG_MEMORY_HOTPLUG + /* +* Don't allow adding memory not in E820 map while +* booting the system. Once the balloon driver is up +* it will remove that restriction again. +*/ + max_mem_size = xen_e820_table.entries[i].addr + + xen_e820_table.entries[i].size; +#endif } if (!discard) diff --git a/drivers/xen/xen-balloon.c b/drivers/xen/xen-balloon.c index 2acbfe104e46..2a960fcc812e 100644 --- a/drivers/xen/xen-balloon.c +++ b/drivers/xen/xen-balloon.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -63,6 +64,11 @@ static void watch_target(struct xenbus_watch *watch, static bool watch_fired; static long target_diff; +#ifdef CONFIG_MEMORY_HOTPLUG + /* The balloon driver will take care of adding memory now. */ + max_mem_size = U64_MAX; +#endif + err = xenbus_scanf(XBT_NIL, "memory", "target", "%llu", &new_target); if (err != 1) { /* This is ok (for domain0 at least) - so just return */ -- 2.16.4
Re: [PATCH 0/5] RDMA: reg_remote_mr
Steve Wise wrote on 01/29/2019 06:44:48 PM: > > On 1/29/2019 7:26 AM, Joel Nider wrote: > > As discussed at LPC'18, there is a need to be able to register a memory > > region (MR) on behalf of another process. One example is the case of > > post-copy container migration, in which CRIU is responsible for setting > > up the migration, but the contents of the memory are from the migrating > > process. In this case, we want all RDMA READ requests to be served by > > the address space of the migration process directly (not by CRIU). This > > patchset implements a new uverbs command which allows an application to > > register a memory region in the address space of another process. > > Hey Joel, > > Dumb question: > > Doesn't this open a security hole by allowing any process to register > memory in any other process? Not a dumb question - there is a security problem. Jason just suggested I look at how ptrace solves the problem, so that's my best option at the moment. Still, I figured it was a good idea to let everyone take a look at what I have so far, and start to get feedback. > Steve. > >
[PATCH v2 4/7] scsi: libsas: split the replacement of sas disks in two steps
Now if a new device replaced a old device, the sas address will change. We unregister the old device and discover the new device in one revalidation process. But after we deferred the sas_port_delete(), the sas port is not deleted when we registering the new port and device. The sas port cannot be added because the name of the new port is the same as the old. Fix this by doing the replacement in two steps. The first revalidation only delete the old device and trigger a new revalidation. The second revalidation discover the new device. To keep the event processing synchronised to the original event, we wrapped a loop and added a new parameter to see if we should revalidate again. Signed-off-by: Jason Yan CC: chenxiang CC: John Garry CC: Johannes Thumshirn CC: Ewan Milne CC: Christoph Hellwig CC: Tomas Henzl CC: Dan Williams CC: Hannes Reinecke --- drivers/scsi/libsas/sas_discover.c | 20 +++- drivers/scsi/libsas/sas_expander.c | 20 ++-- include/scsi/libsas.h | 2 +- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c index ffc571a12916..c825c89fbddd 100644 --- a/drivers/scsi/libsas/sas_discover.c +++ b/drivers/scsi/libsas/sas_discover.c @@ -498,12 +498,10 @@ static void sas_discover_domain(struct work_struct *work) task_pid_nr(current), error); } -static void sas_revalidate_domain(struct work_struct *work) +static void sas_do_revalidate_domain(struct asd_sas_port *port, bool *retry) { - struct sas_discovery_event *ev = to_sas_discovery_event(work); - struct asd_sas_port *port = ev->port; - struct sas_ha_struct *ha = port->ha; struct domain_device *ddev = port->port_dev; + struct sas_ha_struct *ha = port->ha; /* prevent revalidation from finding sata links in recovery */ mutex_lock(&ha->disco_mutex); @@ -520,7 +518,7 @@ static void sas_revalidate_domain(struct work_struct *work) if (ddev && (ddev->dev_type == SAS_FANOUT_EXPANDER_DEVICE || ddev->dev_type == SAS_EDGE_EXPANDER_DEVICE)) - sas_ex_revalidate_domain(ddev); + sas_ex_revalidate_domain(ddev, retry); pr_debug("done REVALIDATING DOMAIN on port %d, pid:%d\n", port->id, task_pid_nr(current)); @@ -532,6 +530,18 @@ static void sas_revalidate_domain(struct work_struct *work) sas_probe_devices(port); } +static void sas_revalidate_domain(struct work_struct *work) +{ + struct sas_discovery_event *ev = to_sas_discovery_event(work); + struct asd_sas_port *port = ev->port; + bool retry; + + do { + retry = false; + sas_do_revalidate_domain(port, &retry); + } while (retry); +} + /* -- Events -- */ static void sas_chain_work(struct sas_ha_struct *ha, struct sas_work *sw) diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index 5cd720f93f96..cdbf8d8a28bf 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -1994,7 +1994,8 @@ static bool dev_type_flutter(enum sas_device_type new, enum sas_device_type old) return false; } -static int sas_rediscover_dev(struct domain_device *dev, int phy_id, bool last) +static int sas_unregister(struct domain_device *dev, int phy_id, bool last, + bool *retry) { struct expander_device *ex = &dev->ex_dev; struct ex_phy *phy = &ex->ex_phy[phy_id]; @@ -2045,7 +2046,12 @@ static int sas_rediscover_dev(struct domain_device *dev, int phy_id, bool last) SAS_ADDR(phy->attached_sas_addr)); sas_unregister_devs_sas_addr(dev, phy_id, last); - return sas_discover_new(dev, phy_id); + /* force the next revalidation find this phy and bring it up */ + phy->phy_change_count = -1; + ex->ex_change_count = -1; + *retry = true; + + return 0; } /** @@ -2062,7 +2068,8 @@ static int sas_rediscover_dev(struct domain_device *dev, int phy_id, bool last) * first phy,for other phys in this port, we add it to the port to * forming the wide-port. */ -static void sas_rediscover(struct domain_device *dev, const int phy_id) +static void sas_rediscover(struct domain_device *dev, const int phy_id, + bool *retry) { struct expander_device *ex = &dev->ex_dev; struct ex_phy *changed_phy = &ex->ex_phy[phy_id]; @@ -2087,7 +2094,7 @@ static void sas_rediscover(struct domain_device *dev, const int phy_id) break; } } - res = sas_rediscover_dev(dev, phy_id, last); + res = sas_unregister(dev, phy_id, last, retry); } else res = sas_discover_new(dev, phy_id); @@ -2098,13 +2105,14 @@ static void sas_rediscover(struct domain_device *dev,
[PATCH v2 1/7] scsi: libsas: reset the negotiated_linkrate when phy is down
If the device is unplugged or disconnected, the negotiated_linkrate still can be seen from the userspace by sysfs. This makes people confused and leaks information of the device last used. So let's reset the negotiated_linkrate after the phy is down. Signed-off-by: Jason Yan CC: John Garry CC: Johannes Thumshirn CC: Ewan Milne CC: Christoph Hellwig CC: Tomas Henzl CC: Dan Williams CC: Hannes Reinecke --- drivers/scsi/libsas/sas_expander.c | 2 ++ include/scsi/libsas.h | 3 +++ 2 files changed, 5 insertions(+) diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index 17eb4185f29d..7b0e6dcef6e6 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -1904,6 +1904,8 @@ static void sas_unregister_devs_sas_addr(struct domain_device *parent, &parent->port->sas_port_del_list); phy->port = NULL; } + if (phy->phy) + phy->phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN; } static int sas_discover_bfs_by_root_level(struct domain_device *root, diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h index 3de3b10da19a..420156cea3ee 100644 --- a/include/scsi/libsas.h +++ b/include/scsi/libsas.h @@ -448,6 +448,9 @@ static inline void sas_phy_disconnected(struct asd_sas_phy *phy) { phy->oob_mode = OOB_NOT_CONNECTED; phy->linkrate = SAS_LINK_RATE_UNKNOWN; + + if (phy->phy) + phy->phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN; } static inline unsigned int to_sas_gpio_od(int device, int bit) -- 2.14.4
[PATCH v2 6/7] scsi: libsas: reset the phy address if discover failed
When we failed to discover the device, the phy address is still kept in ex_phy. So when the next time we revalidate this phy the address and device type is the same, it will be considered as flutter and will not be discovered again. So the device will not be brought up. Fix this by reset the phy address to the initial value. Then in the next revalidation the device will be discovered agian. Tested-by: Chen Liangfei Signed-off-by: Jason Yan CC: Xiaofei Tan CC: John Garry CC: Johannes Thumshirn CC: Ewan Milne CC: Christoph Hellwig CC: Tomas Henzl CC: Dan Williams CC: Hannes Reinecke --- drivers/scsi/libsas/sas_expander.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index 6e56ebdc2148..e781941a7088 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -1100,6 +1100,13 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id) i, SAS_ADDR(ex->ex_phy[i].attached_sas_addr)); } } + } else { + /* if we failed to discover this device, we have to +* reset the expander phy attached address so that we +* will not treat the phy as flutter in the next +* revalidation +*/ + memset(ex_phy->attached_sas_addr, 0, SAS_ADDR_SIZE); } return res; -- 2.14.4
[PATCH v2 2/7] scsi: libsas: only clear phy->in_shutdown after shutdown event done
When the event queue is full of phy up and down events and reached the threshold, we will queue a shutdown-event, and set phy->in_shutdown so that we will not queue a shutdown-event again. But before the shutdown-event can be executed, every phy-down event will clear phy->in_shutdown and a new shutdown-event will be queued. The queue will be full of these shutdown-events. Fix this by only clear phy->in_shutdown in sas_phye_shutdown(), that is after the first shutdown-event has been executed. Fixes: f12486e06ae8 ("scsi: libsas: shut down the PHY if events reached the threshold") Signed-off-by: Jason Yan CC: John Garry CC: Johannes Thumshirn CC: Ewan Milne CC: Christoph Hellwig CC: Tomas Henzl CC: Dan Williams CC: Hannes Reinecke --- drivers/scsi/libsas/sas_phy.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/libsas/sas_phy.c b/drivers/scsi/libsas/sas_phy.c index 0374243c85d0..762bb13cca74 100644 --- a/drivers/scsi/libsas/sas_phy.c +++ b/drivers/scsi/libsas/sas_phy.c @@ -35,7 +35,6 @@ static void sas_phye_loss_of_signal(struct work_struct *work) struct asd_sas_event *ev = to_asd_sas_event(work); struct asd_sas_phy *phy = ev->phy; - phy->in_shutdown = 0; phy->error = 0; sas_deform_port(phy, 1); } @@ -45,7 +44,6 @@ static void sas_phye_oob_done(struct work_struct *work) struct asd_sas_event *ev = to_asd_sas_event(work); struct asd_sas_phy *phy = ev->phy; - phy->in_shutdown = 0; phy->error = 0; } @@ -127,6 +125,7 @@ static void sas_phye_shutdown(struct work_struct *work) } else pr_notice("phy%02d is not enabled, cannot shutdown\n", phy->id); + phy->in_shutdown = 0; } /* -- Phy class registration -- */ -- 2.14.4
[PATCH v2 0/7] libsas: fix issue of swapping or replacing disks
The work flow of revalidation now is scanning expander phy by the sequence of the phy and check if the phy have changed. This will leads to some issues of swapping disks or replacing a disk with a new one. This patchset addresses the issues above by these main changes: 1. Let the revalidation first scan all phys, mark all changed phys, then revalidate in two steps. First check if we need to unregister some devices. if we need to unregister some devices, tell the upper revalidation that we need to revalidate again. Second, if no devices need to be unregistered, discover new devices. 2. For sata disk, checking the ata devices class and id to ensure the same device after flutter. v1->v2: 1. Do not raise a new bcast but use a loop in sas_revalidate_domain() to retry revalidation if we need to revalidate again. So that we can do the bcast event processing synchronised to the original event 2. Drop some patches splitted from this patchset: https://lkml.org/lkml/2018/9/25/153 3. Drop the SATA PHY connection rate matching patch since John had a better solution for the device discovery phase. https://lkml.org/lkml/2019/1/4/340 4. Re-init negotiated_linkrate when PHY is down. 5. Fix an issue when event in queue reached the limit. Jason Yan (7): scsi: libsas: reset the negotiated_linkrate when phy is down scsi: libsas: only clear phy->in_shutdown after shutdown event done scsi: libsas: optimize the debug print of the revalidate process scsi: libsas: split the replacement of sas disks in two steps scsi: libsas: check if the same device when flutter scsi: libsas: reset the phy address if discover failed scsi: libsas: fix issue of swapping two sas disks drivers/ata/libata-core.c | 3 +- drivers/scsi/libsas/sas_ata.c | 18 +++ drivers/scsi/libsas/sas_discover.c | 25 ++-- drivers/scsi/libsas/sas_expander.c | 239 +++-- drivers/scsi/libsas/sas_phy.c | 3 +- include/linux/libata.h | 2 + include/scsi/libsas.h | 6 +- 7 files changed, 224 insertions(+), 72 deletions(-) -- 2.14.4
[PATCH v2 7/7] scsi: libsas: fix issue of swapping two sas disks
The work flow of revalidation now is scanning expander phy by the sequence of the phy and check if the phy have changed. This will leads to an issue of swapping two sas disks on one expander. Assume we have two sas disks, connected with expander phy10 and phy11: phy10: 5000cca04eb1001d port-0:0:10 phy11: 5000cca04eb043ad port-0:0:11 Swap these two disks, and imaging the following scenario: revalidation 1: -->phy10: 0 --> delete phy10 domain device -->phy11: 5000cca04eb043ad (no change) revalidation done revalidation 2: -->step 1, check phy10: -->phy10: 5000cca04eb043ad --> add to wide port(port-0:0:11) (phy11 address is still 5000cca04eb043ad now) -->step 2, check phy11: -->phy11: 0 --> phy11 address is 0 now, but it's part of wide port(port-0:0:11), the domain device will not be deleted. revalidation done revalidation 3: -->phy10, 5000cca04eb043ad (no change) -->phy11: 5000cca04eb1001d --> try to add port-0:0:11 but failed, port-0:0:11 already exist, trigger a warning as follows revalidation done [14790.189699] sysfs: cannot create duplicate filename '/devices/pci:74/:74:02.0/host0/port-0:0/expander-0:0/port-0:0:11' [14790.201081] CPU: 25 PID: 5031 Comm: kworker/u192:3 Not tainted 4.16.0-rc1-191134-g138f084-dirty #228 [14790.210199] Hardware name: Huawei D06/D06, BIOS Hisilicon D06 EC UEFI Nemo 2.0 RC0 - B303 05/16/2018 [14790.219323] Workqueue: :74:02.0_disco_q sas_revalidate_domain [14790.225404] Call trace: [14790.227842] dump_backtrace+0x0/0x18c [14790.231492] show_stack+0x14/0x1c [14790.234798] dump_stack+0x88/0xac [14790.238101] sysfs_warn_dup+0x64/0x7c [14790.241751] sysfs_create_dir_ns+0x90/0xa0 [14790.245835] kobject_add_internal+0xa0/0x284 [14790.250092] kobject_add+0xb8/0x11c [14790.253570] device_add+0xe8/0x598 [14790.256960] sas_port_add+0x24/0x50 [14790.260436] sas_ex_discover_devices+0xb10/0xc30 [14790.265040] sas_ex_revalidate_domain+0x1d8/0x518 [14790.269731] sas_revalidate_domain+0x12c/0x154 [14790.274163] process_one_work+0x128/0x2b0 [14790.278160] worker_thread+0x14c/0x408 [14790.281897] kthread+0xfc/0x128 [14790.285026] ret_from_fork+0x10/0x18 [14790.288598] [ cut here ] At last, the disk 5000cca04eb1001d is lost. The basic idea of fix this issue is to let the revalidation first scan all phys, and then unregisterring devices. Only when no devices need to be unregisterred, go to the next step to discover new devices. If there are devices need unregister, unregister those devices and tell the revalidation event processor to retry again. The next revalidation will process the discovering of the new devices. Tested-by: Chen Liangfei Signed-off-by: Jason Yan CC: Xiaofei Tan CC: chenxiang CC: John Garry CC: Johannes Thumshirn CC: Ewan Milne CC: Christoph Hellwig CC: Tomas Henzl CC: Dan Williams CC: Hannes Reinecke --- drivers/scsi/libsas/sas_expander.c | 146 + 1 file changed, 100 insertions(+), 46 deletions(-) diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index e781941a7088..073bb5c6e353 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -2056,7 +2056,7 @@ static bool sas_process_flutter(struct domain_device *dev, struct ex_phy *phy, return true; } -static int sas_unregister(struct domain_device *dev, int phy_id, bool last, +static int sas_ex_unregister(struct domain_device *dev, int phy_id, bool last, bool *retry) { struct expander_device *ex = &dev->ex_dev; @@ -2108,21 +2108,8 @@ static int sas_unregister(struct domain_device *dev, int phy_id, bool last, return 0; } -/** - * sas_rediscover - revalidate the domain. - * @dev:domain device to be detect. - * @phy_id: the phy id will be detected. - * - * NOTE: this process _must_ quit (return) as soon as any connection - * errors are encountered. Connection recovery is done elsewhere. - * Discover process only interrogates devices in order to discover the - * domain.For plugging out, we un-register the device only when it is - * the last phy in the port, for other phys in this port, we just delete it - * from the port.For inserting, we do discovery when it is the - * first phy,for other phys in this port, we add it to the port to - * forming the wide-port. - */ -static void sas_rediscover(struct domain_device *dev, const int phy_id, + +static void sas_ex_unregister_device(struct domain_device *dev, const int phy_id, bool *retry) { struct expander_device *ex = &dev->ex_dev; @@ -2131,31 +2118,70 @@ static void sas_rediscover(struct domain_device *dev, const int phy_id, int i; bool last = true; /* is this the last phy of the port */ - pr_debug("ex %016llx phy%d originated BROADCAST(CHANGE)\n", -SAS_ADDR(dev->sas_addr), phy_id); - - if (SAS_ADDR(changed_phy->attach
Re: [PATCH v2] KVM: x86: Sync the pending Posted-Interrupts
On 30/01/19 01:59, Luwei Kang wrote: > Some Posted-Interrupts from passthrough devices may be lost or > overwritten when the vCPU is in runnable state. > > The SN (Suppress Notification) of PID (Posted Interrupt Descriptor) will > be set when the vCPU is preempted (vCPU in KVM_MP_STATE_RUNNABLE state > but not running on physical CPU). If a posted interrupt coming at this > time, the irq remmaping facility will set the bit of PIR (Posted > Interrupt Requests) without ON (Outstanding Notification). > So this interrupt can't be sync to APIC virtualization register and > will not be handled by Guest because ON is zero. > > Signed-off-by: Luwei Kang > --- > arch/x86/kvm/vmx/vmx.c | 2 +- > arch/x86/kvm/x86.c | 2 +- > 2 files changed, 2 insertions(+), 2 deletions(-) > > diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c > index f6915f1..820a03b 100644 > --- a/arch/x86/kvm/vmx/vmx.c > +++ b/arch/x86/kvm/vmx/vmx.c > @@ -6048,7 +6048,7 @@ static int vmx_sync_pir_to_irr(struct kvm_vcpu *vcpu) > bool max_irr_updated; > > WARN_ON(!vcpu->arch.apicv_active); > - if (pi_test_on(&vmx->pi_desc)) { > + if (!bitmap_empty((unsigned long *)vmx->pi_desc.pir, NR_VECTORS)) { > pi_clear_on(&vmx->pi_desc); > /* >* IOMMU can write to PIR.ON, so the barrier matters even on UP. This is not what I asked. You should instead do the check after pi_clear_sn. Paolo > diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c > index 02c8e09..c31b608 100644 > --- a/arch/x86/kvm/x86.c > +++ b/arch/x86/kvm/x86.c > @@ -7793,7 +7793,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) >* 1) We should set ->mode before checking ->requests. Please see >* the comment in kvm_vcpu_exiting_guest_mode(). >* > - * 2) For APICv, we should set ->mode before checking PIR.ON. This > + * 2) For APICv, we should set ->mode before checking PID.PIR. This >* pairs with the memory barrier implicit in pi_test_and_set_on >* (see vmx_deliver_posted_interrupt). >* >
[PATCH v2 5/7] scsi: libsas: check if the same device when flutter
The ata device do not have a real sas address. If a ata device is replaced with another one, the sas address is the same. Now libsas treat this scenario as flutter and do not delete the old one and discover the new one. This will cause the data read from or write to the wrong device. And also when hotplugging a sata device, libsas entered to the flutter case and sometimes found the phy attached address is abnormal. The log is like this: sas: ex 500e004aaa1f phy6 originated BROADCAST(CHANGE) sas: ex 500e004aaa1f phy06:U:0 attached: (no device) sas: ex 500e004aaa1f phy 0x6 broadcast flutter Fix this issue by checking the phy attached address and the ata device's class and id if they are the same as the origin. The ata class and id is readed in ata EH process. When ata EH is scheduled, revalidate will be deferred and a new bcast will be raised. Tested-by: Chen Liangfei Signed-off-by: Jason Yan Reviewed-by: John Garry CC: chenxiang CC: John Garry CC: Johannes Thumshirn CC: Ewan Milne CC: Christoph Hellwig CC: Tomas Henzl CC: Dan Williams CC: Tejun Heo CC: Hannes Reinecke --- drivers/ata/libata-core.c | 3 +- drivers/scsi/libsas/sas_ata.c | 18 ++ drivers/scsi/libsas/sas_expander.c | 67 -- include/linux/libata.h | 2 ++ include/scsi/libsas.h | 1 + 5 files changed, 80 insertions(+), 11 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index b8c3f9e6af89..67e77fa3c63a 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4225,7 +4225,7 @@ void ata_std_postreset(struct ata_link *link, unsigned int *classes) * RETURNS: * 1 if @dev matches @new_class and @new_id, 0 otherwise. */ -static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class, +int ata_dev_same_device(struct ata_device *dev, unsigned int new_class, const u16 *new_id) { const u16 *old_id = dev->id; @@ -7400,6 +7400,7 @@ EXPORT_SYMBOL_GPL(ata_eh_analyze_ncq_error); EXPORT_SYMBOL_GPL(ata_do_eh); EXPORT_SYMBOL_GPL(ata_std_error_handler); +EXPORT_SYMBOL_GPL(ata_dev_same_device); EXPORT_SYMBOL_GPL(ata_cable_40wire); EXPORT_SYMBOL_GPL(ata_cable_80wire); EXPORT_SYMBOL_GPL(ata_cable_unknown); diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index 6f93fee2b21b..a9f5523f0347 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c @@ -625,6 +625,22 @@ static int sas_get_ata_command_set(struct domain_device *dev) return ata_dev_classify(&tf); } +static void sas_ata_store_id(struct domain_device *dev) +{ + struct ata_device *ata_dev = sas_to_ata_dev(dev); + unsigned char model[ATA_ID_PROD_LEN + 1]; + unsigned char serial[ATA_ID_SERNO_LEN + 1]; + + /* store the ata device's class and id */ + memcpy(dev->sata_dev.id, ata_dev->id, ATA_ID_WORDS); + dev->sata_dev.class = ata_dev->class; + + ata_id_c_string(ata_dev->id, model, ATA_ID_PROD, sizeof(model)); + ata_id_c_string(ata_dev->id, serial, ATA_ID_SERNO, sizeof(serial)); + + sas_ata_printk(KERN_INFO, dev, "model:%s serial:%s\n", model, serial); +} + void sas_probe_sata(struct asd_sas_port *port) { struct domain_device *dev, *n; @@ -649,6 +665,8 @@ void sas_probe_sata(struct asd_sas_port *port) */ if (!ata_dev_enabled(sas_to_ata_dev(dev))) sas_fail_probe(dev, __func__, -ENODEV); + else + sas_ata_store_id(dev); } } diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index cdbf8d8a28bf..6e56ebdc2148 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -1994,6 +1994,61 @@ static bool dev_type_flutter(enum sas_device_type new, enum sas_device_type old) return false; } +/* + * we think the device is fluttering so just read the phy state and update + * some information of the device, but if some important things changed + * such as the sas address, or the linkrate, or the ata devices id and class, + * we have to unregister the device and re-probe it. + */ +static bool sas_process_flutter(struct domain_device *dev, struct ex_phy *phy, + int phy_id, u8 *sas_addr) +{ + struct domain_device *ata_dev = sas_ex_to_ata(dev, phy_id); + enum sas_linkrate linkrate = phy->linkrate; + char *action = ""; + + sas_ex_phy_discover(dev, phy_id); + + if (ata_dev && phy->attached_dev_type == SAS_SATA_PENDING) + action = ", needs recovery"; + pr_debug("ex %016llx phy%d broadcast flutter%s\n", +SAS_ADDR(dev->sas_addr), phy_id, action); + + if (linkrate != phy->linkrate) { + pr_debug("ex %016llx phy%d linkrate changed from %d to %d\n", +SAS_AD
[PATCH v2 3/7] scsi: libsas: optimize the debug print of the revalidate process
sas_rediscover() returns error code if discover failed for a expander phy. And sas_ex_revalidate_domain() only returns the last phy's error code. So when sas_revalidate_domain() prints the return value of the discover process, we do not know if the revalidation for every phy is successful or not. We just know the last bcast phy revalidation succeeded or not. No need to return a error code for sas_ex_revalidate_domain() and sas_rediscover(), and just print the debug log for each bcast phy directly in sas_rediscover(). Signed-off-by: Jason Yan CC: John Garry CC: Johannes Thumshirn CC: Ewan Milne CC: Christoph Hellwig CC: Tomas Henzl CC: Dan Williams CC: Hannes Reinecke --- drivers/scsi/libsas/sas_discover.c | 7 +++ drivers/scsi/libsas/sas_expander.c | 11 ++- include/scsi/libsas.h | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c index 726ada9b8c79..ffc571a12916 100644 --- a/drivers/scsi/libsas/sas_discover.c +++ b/drivers/scsi/libsas/sas_discover.c @@ -500,7 +500,6 @@ static void sas_discover_domain(struct work_struct *work) static void sas_revalidate_domain(struct work_struct *work) { - int res = 0; struct sas_discovery_event *ev = to_sas_discovery_event(work); struct asd_sas_port *port = ev->port; struct sas_ha_struct *ha = port->ha; @@ -521,10 +520,10 @@ static void sas_revalidate_domain(struct work_struct *work) if (ddev && (ddev->dev_type == SAS_FANOUT_EXPANDER_DEVICE || ddev->dev_type == SAS_EDGE_EXPANDER_DEVICE)) - res = sas_ex_revalidate_domain(ddev); + sas_ex_revalidate_domain(ddev); - pr_debug("done REVALIDATING DOMAIN on port %d, pid:%d, res 0x%x\n", -port->id, task_pid_nr(current), res); + pr_debug("done REVALIDATING DOMAIN on port %d, pid:%d\n", +port->id, task_pid_nr(current)); out: mutex_unlock(&ha->disco_mutex); diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index 7b0e6dcef6e6..5cd720f93f96 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -2062,7 +2062,7 @@ static int sas_rediscover_dev(struct domain_device *dev, int phy_id, bool last) * first phy,for other phys in this port, we add it to the port to * forming the wide-port. */ -static int sas_rediscover(struct domain_device *dev, const int phy_id) +static void sas_rediscover(struct domain_device *dev, const int phy_id) { struct expander_device *ex = &dev->ex_dev; struct ex_phy *changed_phy = &ex->ex_phy[phy_id]; @@ -2090,7 +2090,9 @@ static int sas_rediscover(struct domain_device *dev, const int phy_id) res = sas_rediscover_dev(dev, phy_id, last); } else res = sas_discover_new(dev, phy_id); - return res; + + pr_debug("ex %016llx phy%d discover returned 0x%x\n", +SAS_ADDR(dev->sas_addr), phy_id, res); } /** @@ -2102,7 +2104,7 @@ static int sas_rediscover(struct domain_device *dev, const int phy_id) * Discover process only interrogates devices in order to discover the * domain. */ -int sas_ex_revalidate_domain(struct domain_device *port_dev) +void sas_ex_revalidate_domain(struct domain_device *port_dev) { int res; struct domain_device *dev = NULL; @@ -2117,11 +2119,10 @@ int sas_ex_revalidate_domain(struct domain_device *port_dev) res = sas_find_bcast_phy(dev, &phy_id, i, true); if (phy_id == -1) break; - res = sas_rediscover(dev, phy_id); + sas_rediscover(dev, phy_id); i = phy_id + 1; } while (i < ex->num_phys); } - return res; } void sas_smp_handler(struct bsg_job *job, struct Scsi_Host *shost, diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h index 420156cea3ee..e557bcb0c266 100644 --- a/include/scsi/libsas.h +++ b/include/scsi/libsas.h @@ -692,7 +692,7 @@ int sas_discover_root_expander(struct domain_device *); void sas_init_ex_attr(void); -int sas_ex_revalidate_domain(struct domain_device *); +void sas_ex_revalidate_domain(struct domain_device *); void sas_unregister_domain_devices(struct asd_sas_port *port, int gone); void sas_init_disc(struct sas_discovery *disc, struct asd_sas_port *); -- 2.14.4
Re: [PATCH] tty: ldisc: add sysctl to prevent autoloading of ldiscs
On Mon, Jan 21, 2019 at 07:01:42PM -0500, Theodore Y. Ts'o wrote: > On Mon, Jan 21, 2019 at 05:26:42PM +0100, Greg Kroah-Hartman wrote: > > By default, the kernel will automatically load the module of any line > > dicipline that is asked for. As this sometimes isn't the safest thing > > to do, provide a sysctl to disable this feature. > > > > By default, we set this to 'y' as that is the historical way that Linux > > has worked, and we do not want to break working systems. But in the > > future, perhaps this can default to 'n' to prevent this functionality. > > > > Signed-off-by: Greg Kroah-Hartman > > Reviewed-by: Theodore Ts'o Thanks for the review!
Re: [PATCH v2 1/7] KVM:VMX: Define CET VMCS fields and bits
On 29/01/19 09:29, Yang Weijiang wrote: > On Tue, Jan 29, 2019 at 04:19:34PM +0100, Paolo Bonzini wrote: >> On 28/01/19 11:33, Yang Weijiang wrote: There is no code in this series to pass these fields to and from userspace, and also to save/restore U_CET, INT_SSP_TAB, PL0_SSP and PL3_SSP across context switches. >>> The kernel consumes these MSRs, please see kernel CET patch: >>> https://lkml.org/lkml/fancy/2018/11/20/225 >> >> Still, even if the kernel saves these fields across context switch in >> XSAVE areas, KVM must support accesses to the MSRs from userspace, for >> example in order to perform live migration. >> >> For example, when reading/writing these in kvm_set_msr or >> kvm_get_msr_common, you would have to do a read/write from the host >> MSRs. You also have to put kvm_load_guest_fpu/kvm_put_guest_fpu calls >> in __msr_io. > Thanks, you're right, if we want to support live migration we need do that. > However, this feature relies on quite a few external > dependencies, e.g., cpu capabilities, kernel version and configuration, we > don't support live migration right now. what's your opinion? Live migration is generally a requirement for a feature to be accepted in KVM. Paolo >> Thanks, >> >> Paolo >> In addition, PL1_SSP and PL2_SSP should be supported even if the guest doesn't use them. It makes sense to avoid intercepting them, but they should still be supported and switched (possibly only if nonzero). Am I missing something, for example a dependency on host CET support? If not, how was this series tested? >>> The guest CET feature is tested with kernel CET patches on internal >>> virtual platform. >>>
Re: [PATCH 5/5] RDMA/uverbs: add UVERBS_METHOD_REG_REMOTE_MR
linux-rdma-ow...@vger.kernel.org wrote on 01/29/2019 07:04:06 PM: > On Tue, Jan 29, 2019 at 03:26:26PM +0200, Joel Nider wrote: > > Add a new handler for new uverb reg_remote_mr. The purpose is to register > > a memory region in a different address space (i.e. process) than the > > caller. > > > > The main use case which motivated this change is post-copy container > > migration. When a migration manager (i.e. CRIU) starts a migration, it > > must have an open connection for handling any page faults that occur > > in the container after restoration on the target machine. Even though > > CRIU establishes and maintains the connection, ultimately the memory > > is copied from the container being migrated (i.e. a remote address > > space). This container must remain passive -- meaning it cannot have > > any knowledge of the RDMA connection; therefore the migration manager > > must have the ability to register a remote memory region. This remote > > memory region will serve as the source for any memory pages that must > > be copied (on-demand or otherwise) during the migration. > > > > Signed-off-by: Joel Nider > > drivers/infiniband/core/uverbs_std_types_mr.c | 129 +- > > include/rdma/ib_verbs.h | 8 ++ > > include/uapi/rdma/ib_user_ioctl_cmds.h| 13 +++ > > 3 files changed, 149 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/infiniband/core/uverbs_std_types_mr.c b/drivers/ > infiniband/core/uverbs_std_types_mr.c > > index 4d4be0c..bf7b4b2 100644 > > +++ b/drivers/infiniband/core/uverbs_std_types_mr.c > > @@ -150,6 +150,99 @@ static int UVERBS_HANDLER(UVERBS_METHOD_DM_MR_REG)( > > return ret; > > } > > > > +static int UVERBS_HANDLER(UVERBS_METHOD_REG_REMOTE_MR)( > > + struct uverbs_attr_bundle *attrs) > > +{ > > I think this should just be REG_MR with an optional remote PID > argument Maybe I missed something. Isn't REG_MR only implemented as a write() command? In our earlier conversation you told me all new commands must be implemented as ioctl() commands. > > DECLARE_UVERBS_NAMED_OBJECT( > > UVERBS_OBJECT_MR, > > UVERBS_TYPE_ALLOC_IDR(uverbs_free_mr), > > &UVERBS_METHOD(UVERBS_METHOD_DM_MR_REG), > > &UVERBS_METHOD(UVERBS_METHOD_MR_DESTROY), > > - &UVERBS_METHOD(UVERBS_METHOD_ADVISE_MR)); > > + &UVERBS_METHOD(UVERBS_METHOD_ADVISE_MR), > > + &UVERBS_METHOD(UVERBS_METHOD_REG_REMOTE_MR), > > +); > > I'm kind of surprised this compiles with the trailing comma? Personally, I think it is nicer with the trailing comma. Of course syntactically it makes no sense, but when adding a new entry, you don't have to touch the previous line, which makes the diff cleaner. If this is against standard practices I will remove the comma.
Re: [Xen-devel] [PATCH v2] drm/xen-front: Make shmem backed display buffer coherent
Dropped in favor of https://lkml.org/lkml/2019/1/29/910 On 1/24/19 5:02 PM, Julien Grall wrote: > > > On 24/01/2019 14:34, Oleksandr Andrushchenko wrote: >> Hello, Julien! > > Hi, > >> On 1/22/19 1:44 PM, Julien Grall wrote: >>> >>> >>> On 1/22/19 10:28 AM, Oleksandr Andrushchenko wrote: Hello, Julien! >>> >>> Hi, >>> On 1/21/19 7:09 PM, Julien Grall wrote: Well, I didn't get the attributes of pages at the backend side, but IMO those do not matter in my use-case (for simplicity I am not using zero-copying at backend side): >>> >>> They are actually important no matter what is your use case. If you >>> access the same physical page with different attributes, then you are >>> asking for trouble. >> So, we have: >> >> DomU: frontend side >> >> !PTE_RDONLY + PTE_PXN + PTE_SHARED + PTE_AF + PTE_UXN + >> PTE_ATTRINDX(MT_NORMAL) > > I still don't understand how you came up with MT_NORMAL when you seem > to confirm... > >> >> DomD: backend side >> >> PTE_USER + !PTE_RDONLY + PTE_PXN + PTE_NG + PTE_CONT + PTE_TABLE_BIT + >> PTE_UXN + PTE_ATTRINDX(MT_NORMAL) >> >> From the above it seems that I don't violate cached/non-cached >> agreement here >>> >>> This is why Xen imposes all the pages shared to have their memory >>> attributes following some rules. Actually, speaking with Mark R., we >>> may want to tight a bit more the attributes. >>> 1. Frontend device allocates display buffer pages which come from shmem and have these attributes: !PTE_RDONLY + PTE_PXN + PTE_SHARED + PTE_AF + PTE_UXN + PTE_ATTRINDX(MT_NORMAL) >>> >>> My knowledge of Xen DRM is inexistent. However, looking at the code in >>> 5.0-rc2, I don't seem to find the same attributes. For instance >>> xen_drm_front_gem_prime_vmap and gem_mmap_obj are using >>> pgprot_writecombine. So it looks like, the mapping will be >>> non-cacheable on Arm64. >>> >>> Can you explain how you came up to these attributes? >> pgprot_writecombine is PTE_ATTRINDX(MT_NORMAL_NC), so it seems to be >> applicable here? [1] > > ... that MT_NORMAL_NC is used for the frontend pages. > > MT_NORMAL_NC is different from MT_NORMAL. The use of the former will > result to non-cacheable memory while the latter will result to > cacheable memory. > > To me, this looks like the exact reason why you see artifact on the > display buffer. As the author of this code, can you explain why you > decided to use pgprot_writecombine here instead of relying on the > default VMA prot? > > [...] > >>> We actually never required to use cache flush in other PV protocol, so >>> I still don't understand why the PV DRM should be different here. >> Well, you are right. But at the same time not flushing the buffer makes >> troubles, >> so this is why I am trying to figure out what is wrong here. > > The cache flush is likely hiding the real problem rather than solving it. > >>> >>> To me, it looks like that you are either missing some barriers >> Barriers for the buffer? Not sure what you mean here. > > If you share information between two entities, you may need some > ordering so the information are seen consistently by the consumer > side. This can be achieved by using barriers. > >> Even more, we have >> a use case >> when the buffer is not touched by CPU in DomD and is solely owned by >> the HW. > > Memory ordering issues are subtle. The fact that one of your use-case > works does not imply that barriers are not necessary. I am not saying > there are a missing barriers, I am only pointed out potential reasons. > > Anyway, I don't think your problem is a missing barriers here. It is > more likely because of mismatch memory attributes (see above). > > Cheers, >
[PATCH v6 0/2] spi: support inter-word delays
Changed in v6: * Changed name of field word_delay_us to word_delay_usecs as per suggestion in patch review * Add Nicolas' ACK to spi-atmel patch Changed in v5: * Rebased on linux-next * Fixed up Atmel patch to simplify register setting Changed in v4: * Rename word_delay to word_delay_us and slot it in _beside_ the existing word_delay parameter in spi_transfer (see commit message for more info). * Add code to __spi_validate to make sure transfer and device align with respect to the word_delay_us parameter Changed in v3: * Drop setting of inter-word delay via device tree Changed in v2: * Fix atmel-spi driver to not unconditionally set minimal delay if no delay is required (erroneous clamping) This short series adds support for SPI inter-word delays and configures the spi-atmel driver to honour the setting. Some SPI slaves are so slow that they are unable to keep up even at the SPI controller's lowest available clock frequency. I have such a configuration where an AVR-based SPI slave is unable to feed the SPI bus fast enough even the SPI master runs at the lowest possible clock speed. Jonas Bonn (2): spi: support inter-word delay requirement for devices spi-atmel: support inter-word delay drivers/spi/spi-atmel.c | 11 ++- drivers/spi/spi.c | 5 + include/linux/spi/spi.h | 6 ++ 3 files changed, 17 insertions(+), 5 deletions(-) -- 2.19.1
[PATCH v6 2/2] spi-atmel: support inter-word delay
If the SPI slave requires an inter-word delay, configure the DLYBCT register accordingly. Tested on a SAMA5D2 board (derived from SAMA5D2-Xplained reference board). Signed-off-by: Jonas Bonn Acked-by: Nicolas Ferre CC: Nicolas Ferre CC: Mark Brown CC: Alexandre Belloni CC: Ludovic Desroches CC: linux-...@vger.kernel.org CC: linux-arm-ker...@lists.infradead.org --- drivers/spi/spi-atmel.c | 11 ++- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index f53f0c5e63da..4954f0ab1606 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -1201,13 +1201,14 @@ static int atmel_spi_setup(struct spi_device *spi) csr |= SPI_BIT(CSAAT); /* DLYBS is mostly irrelevant since we manage chipselect using GPIOs. -* -* DLYBCT would add delays between words, slowing down transfers. -* It could potentially be useful to cope with DMA bottlenecks, but -* in those cases it's probably best to just use a lower bitrate. */ csr |= SPI_BF(DLYBS, 0); - csr |= SPI_BF(DLYBCT, 0); + + /* DLYBCT adds delays between words. This is useful for slow devices +* that need a bit of time to setup the next transfer. +*/ + csr |= SPI_BF(DLYBCT, + (as->spi_clk / 100 * spi->word_delay_usecs) >> 5); asd = spi->controller_state; if (!asd) { -- 2.19.1
[PATCH v6 1/2] spi: support inter-word delay requirement for devices
Some devices are slow and cannot keep up with the SPI bus and therefore require a short delay between words of the SPI transfer. The example of this that I'm looking at is a SAMA5D2 with a minimum SPI clock of 400kHz talking to an AVR-based SPI slave. The AVR cannot put bytes on the bus fast enough to keep up with the SoC's SPI controller even at the lowest bus speed. This patch introduces the ability to specify a required inter-word delay for SPI devices. It is up to the controller driver to configure itself accordingly in order to introduce the requested delay. Note that, for spi_transfer, there is already a field word_delay that provides similar functionality. This field, however, is specified in clock cycles (and worse, SPI controller cycles, not SCK cycles); that makes this value dependent on the master clock instead of the device clock for which the delay is intended to provide some relief. This patch leaves this old word_delay in place and provides a time-based word_delay_us alongside it; the new field fits in the struct padding so struct size is constant. There is only one in-kernel user of the word_delay field and presumably that driver could be reworked to use the time-based value instead. The time-based delay is limited to 8 bits as these delays are intended to be short. The SAMA5D2 that I've tested this on limits delays to a maximum of ~100us, which is already many word-transfer periods even at the minimum transfer speed supported by the controller. Signed-off-by: Jonas Bonn CC: Mark Brown CC: Rob Herring CC: Mark Rutland CC: linux-...@vger.kernel.org CC: devicet...@vger.kernel.org --- drivers/spi/spi.c | 5 + include/linux/spi/spi.h | 6 ++ 2 files changed, 11 insertions(+) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 0e0f2c62973c..2f7176f07591 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -3050,6 +3050,8 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) * it is not set for this transfer. * Set transfer tx_nbits and rx_nbits as single transfer default * (SPI_NBITS_SINGLE) if it is not set for this transfer. +* Ensure transfer word_delay is at least as long as that required by +* device itself. */ message->frame_length = 0; list_for_each_entry(xfer, &message->transfers, transfer_list) { @@ -3120,6 +3122,9 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) !(spi->mode & SPI_RX_QUAD)) return -EINVAL; } + + if (xfer->word_delay_usecs < spi->word_delay_usecs) + xfer->word_delay_usecs = spi->word_delay_usecs; } message->status = -EINPROGRESS; diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 916bba47d156..662b336aa2e4 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -122,6 +122,8 @@ void spi_statistics_add_transfer_stats(struct spi_statistics *stats, * the spi_master. * @cs_gpiod: gpio descriptor of the chipselect line (optional, NULL when * not using a GPIO line) + * @word_delay_usecs: microsecond delay to be inserted between consecutive + * words of a transfer * * @statistics: statistics for the spi_device * @@ -169,6 +171,7 @@ struct spi_device { const char *driver_override; int cs_gpio;/* LEGACY: chip select gpio */ struct gpio_desc*cs_gpiod; /* chip select gpio desc */ + uint8_t word_delay_usecs; /* inter-word delay */ /* the statistics */ struct spi_statistics statistics; @@ -721,6 +724,8 @@ extern void spi_res_release(struct spi_controller *ctlr, * @delay_usecs: microseconds to delay after this transfer before * (optionally) changing the chipselect status, then starting * the next transfer or completing this @spi_message. + * @word_delay_usecs: microseconds to inter word delay after each word size + * (set by bits_per_word) transmission. * @word_delay: clock cycles to inter word delay after each word size * (set by bits_per_word) transmission. * @transfer_list: transfers are sequenced through @spi_message.transfers @@ -803,6 +808,7 @@ struct spi_transfer { #defineSPI_NBITS_DUAL 0x02 /* 2bits transfer */ #defineSPI_NBITS_QUAD 0x04 /* 4bits transfer */ u8 bits_per_word; + u8 word_delay_usecs; u16 delay_usecs; u32 speed_hz; u16 word_delay; -- 2.19.1
Re: [PATCH 02/14] dt-bindings: soc: milbeaut: Add Milbeaut trampoline description
On Tue, Jan 29, 2019 at 05:28:48PM +0900, Sugaya, Taichi wrote: > Hi, > > On 2019/01/22 20:50, Russell King - ARM Linux admin wrote: > > On Tue, Jan 22, 2019 at 08:36:03PM +0900, Sugaya, Taichi wrote: > > > Hi > > > > > > On 2018/12/04 22:32, Rob Herring wrote: > > > > On Tue, Dec 4, 2018 at 5:30 AM Sugaya, Taichi > > > > wrote: > > > > > > > > > > Hi > > > > > > > > > > On 2018/12/04 0:49, Rob Herring wrote: > > > > > > On Mon, Dec 3, 2018 at 1:42 AM Sugaya, Taichi > > > > > > wrote: > > > > > > > > > > > > > > Hi, > > > > > > > > > > > > > > On 2018/11/30 17:16, Stephen Boyd wrote: > > > > > > > > Quoting Sugaya, Taichi (2018-11-29 04:24:51) > > > > > > > > > On 2018/11/28 11:01, Stephen Boyd wrote: > > > > > > > > > > Quoting Sugaya Taichi (2018-11-18 17:01:07) > > > > > > > > > > > create mode 100644 > > > > > > > > > > > Documentation/devicetree/bindings/soc/socionext/socionext,m10v.txt > > > > > > > > > > > > > > > > > > > > > > diff --git > > > > > > > > > > > a/Documentation/devicetree/bindings/soc/socionext/socionext,m10v.txt > > > > > > > > > > > > > > > > > > > > > > b/Documentation/devicetree/bindings/soc/socionext/socionext,m10v.txt > > > > > > > > > > > new file mode 100644 > > > > > > > > > > > index 000..f5d906c > > > > > > > > > > > --- /dev/null > > > > > > > > > > > +++ > > > > > > > > > > > b/Documentation/devicetree/bindings/soc/socionext/socionext,m10v.txt > > > > > > > > > > > @@ -0,0 +1,12 @@ > > > > > > > > > > > +Socionext M10V SMP trampoline driver binding > > > > > > > > > > > + > > > > > > > > > > > +This is a driver to wait for sub-cores while boot > > > > > > > > > > > process. > > > > > > > > > > > + > > > > > > > > > > > +- compatible: should be "socionext,smp-trampoline" > > > > > > > > > > > +- reg: should be <0x4C000100 0x100> > > > > > > > > > > > + > > > > > > > > > > > +EXAMPLE > > > > > > > > > > > + trampoline: trampoline@0x4C000100 { > > > > > > > > > > Drop the 0x part of unit addresses. > > > > > > > > > > > > > > > > > > Okay. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > + compatible = "socionext,smp-trampoline"; > > > > > > > > > > > + reg = <0x4C000100 0x100>; > > > > > > > > > > Looks like a software construct, which we wouldn't want to > > > > > > > > > > put into DT > > > > > > > > > > this way. DT doesn't describe drivers. > > > > > > > > > We would like to use this node only getting the address of the > > > > > > > > > trampoline area > > > > > > > > > in which sub-cores wait. (They have finished to go to this > > > > > > > > > area in previous > > > > > > > > > bootloader process.) > > > > > > > > > > > > > > > > Is this area part of memory, or a special SRAM? If it's part of > > > > > > > > memory, > > > > > > > > I would expect this node to be under the reserved-memory node > > > > > > > > and > > > > > > > > pointed to by some other node that uses this region. Could even > > > > > > > > be the > > > > > > > > CPU nodes. > > > > > > > > > > > > > > Yes, 0x4C000100 is a part of memory under the reserved-memory > > > > > > > node. So > > > > > > > we would like to use the SRAM ( allocated 0x ) area > > > > > > > instead. > > > > > > > BTW, sorry, the trampoline address of this example is simply > > > > > > > wrong. We > > > > > > > were going to use a part of the SRAM from the beginning. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > So should we embed the constant value in source codes instead > > > > > > > > > of getting > > > > > > > > > from > > > > > > > > > DT because the address is constant at the moment? Or is there > > > > > > > > > other > > > > > > > > > approach? > > > > > > > > > > > > > > > > > > > > > > > > > If it's constant then that also works. Why does it need to come > > > > > > > > from DT > > > > > > > > at all then? > > > > > > > > > > > > > > We think it is not good to embed constant value in driver codes > > > > > > > and do > > > > > > > not have another way... > > > > > > > Are there better ways? > > > > > > > > > > > > If this is just memory, can you use the standard spin-table binding > > > > > > in > > > > > > the DT spec? There are some requirements like 64-bit values even on > > > > > > 32-bit machines (though this gets violated). > > > > > > > > > > The spin-table seems to be used on only 64-bit arch. Have it ever > > > > > worked > > > > > on 32-bit machine? > > > > > > > > Yes. > > > > > > > > > And I would like not to use it because avoid violation. > > > > > > > > The issue now that I remember is cpu-release-addr is defined to always > > > > be a 64-bit value while some platforms made it a 32-bit value. > > > > 'cpu-release-addr' is also used for some other enable-methods. > > > > > > I have a question about the spin-table. > > > The code "smp_spin_table.c" is only in "arch/arm64/kernel" directory so > > > can > > > not be compiled in arm-v7 arch. That means the spin-table can not be use
[PATCH 01/10] ARM: dts: sunxi: bananapi-m2-plus-v1.2: Fix CPU supply voltages
The Bananapi M2+ uses a GPIO line to change the effective resistance of the CPU supply regulator's feedback resistor network. The voltages described in the device tree were given directly by the vendor. This turns out to be slightly off compared to the real values. The updated voltages are based on calculations of the feedback resistor network, and verified down to three decimal places with a multi-meter. Fixes: 6eeb4180d4b9 ("ARM: dts: sunxi: h3-h5: Add Bananapi M2+ v1.2 device trees") Signed-off-by: Chen-Yu Tsai --- arch/arm/boot/dts/sunxi-bananapi-m2-plus-v1.2.dtsi | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/sunxi-bananapi-m2-plus-v1.2.dtsi b/arch/arm/boot/dts/sunxi-bananapi-m2-plus-v1.2.dtsi index 53edd1faee99..a567567763f4 100644 --- a/arch/arm/boot/dts/sunxi-bananapi-m2-plus-v1.2.dtsi +++ b/arch/arm/boot/dts/sunxi-bananapi-m2-plus-v1.2.dtsi @@ -16,13 +16,13 @@ regulator-type = "voltage"; regulator-boot-on; regulator-always-on; - regulator-min-microvolt = <110>; - regulator-max-microvolt = <130>; + regulator-min-microvolt = <1108475>; + regulator-max-microvolt = <1308475>; regulator-ramp-delay = <50>; /* 4ms */ gpios = <&r_pio 0 1 GPIO_ACTIVE_HIGH>; /* PL1 */ gpios-states = <0x1>; - states = <110 0x0 - 130 0x1>; + states = <1108475 0x0 + 1308475 0x1>; }; }; -- 2.20.1
[PATCH 00/10] arm64: dts: allwinner: h5: Enable CPU DVFS (cpufreq)
Hi everyone, This series enables DVFS for the CPU cores (aka cpufreq) on the Allwinner H5 SoC. The OPP table was taken from Armbian, with minor tweaks to the maximum voltage to account for slightly increased voltage on some of the boards. This has been tested on the Bananapi M2+ v1.2 and Libre Computer ALL-H3-CC H5 ver.. I do not have the remaining boards so I've CC-ed people who did the original submission or have modified the board specifically later on. Patch 1 fixes the voltages specified for the GPIO-controlled regulator on the Bananapi M2+ v1.2. The voltages are slightly higher than what was originally written. Patch 2 adds a fixed regulator for the CPU on the original Bananapi M2+. This is for the retail version, not the engineering samples that had an even higher voltage setting. Patch 3 hooks up the CPU regulator supply for H5 boards that already define the regulator, but were missing the property to tie it to the CPUs. Patch 4 ~ 8 adds the CPU regulator for boards that don't have it defined. This is based on each vendor's schematics. I need people to test each of these specifically and the whole series. Patch 9 ties the CPU clock to the CPU cores. Patch 10 adds the OPP table, based on the one from Armbian. Please have a look and please help test this. Regards ChenYu Chen-Yu Tsai (10): ARM: dts: sunxi: bananapi-m2-plus-v1.2: Fix CPU supply voltages ARM: dts: bananapi-m2-plus: Add CPU supply regulator arm64: dts: allwinner: h5: Hook up cpu regulator supplies arm64: dts: allwinner: h5: nanopi-neo2: Add CPU regulator supply arm64: dts: allwinner: h5: orange-pi-zero-plus: Add CPU regulator supply arm64: dts: allwinner: h5: orange-pi-zero-plus2: Add CPU regulator supply arm64: dts: allwinner: h5: orange-pi-pc2: Add CPU regulator supply arm64: dts: allwinner: h5: orange-pi-prime: Add CPU regulator supply arm64: dts: allwinner: h5: Add clock to CPU cores arm64: dts: allwinner: h5: Add CPU Operating Performance Points table .../boot/dts/sunxi-bananapi-m2-plus-v1.2.dtsi | 30 +++- arch/arm/boot/dts/sunxi-bananapi-m2-plus.dtsi | 14 .../sun50i-h5-emlid-neutis-n5-devboard.dts| 4 + .../allwinner/sun50i-h5-nanopi-neo-plus2.dts | 4 + .../dts/allwinner/sun50i-h5-nanopi-neo2.dts | 20 + .../dts/allwinner/sun50i-h5-orangepi-pc2.dts | 28 +++ .../allwinner/sun50i-h5-orangepi-prime.dts| 28 +++ .../sun50i-h5-orangepi-zero-plus.dts | 20 + .../sun50i-h5-orangepi-zero-plus2.dts | 20 + arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi | 75 +++ 10 files changed, 224 insertions(+), 19 deletions(-) -- 2.20.1
[PATCH 06/10] arm64: dts: allwinner: h5: orange-pi-zero-plus2: Add CPU regulator supply
The OrangePi Zero Plus 2 uses a fixed regulator to supply the CPU cores. The feedback resistor network can be changed by toggling a GPIO line. This is effectively a GPIO controlled regulator that can change between roughly 1.1V and 1.3V. The actual voltage is slightly higher. The values used in the device tree description are based on calculations using the resistor values from the schematics. Cc: Jagan Teki Cc: Sergey Matyukevich Signed-off-by: Chen-Yu Tsai --- This patch is based on the schematics and has not been tested on an actual board. --- .../sun50i-h5-orangepi-zero-plus2.dts | 20 +++ 1 file changed, 20 insertions(+) diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus2.dts b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus2.dts index 53c8c11620e0..801c681307ef 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus2.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus2.dts @@ -76,6 +76,22 @@ regulator-max-microvolt = <330>; }; + reg_vdd_cpux: vdd-cpux { + compatible = "regulator-gpio"; + regulator-name = "vdd-cpux"; + regulator-type = "voltage"; + regulator-boot-on; + regulator-always-on; + regulator-min-microvolt = <1108475>; + regulator-max-microvolt = <1307810>; + regulator-ramp-delay = <50>; /* 4ms */ + enable-gpios = <&r_pio 0 8 GPIO_ACTIVE_HIGH>; /* PL8 */ + gpios = <&r_pio 0 1 GPIO_ACTIVE_HIGH>; /* PL6 */ + gpios-states = <0x1>; + states = <1108475 0x0 + 1307810 0x1>; + }; + wifi_pwrseq: wifi_pwrseq { compatible = "mmc-pwrseq-simple"; pinctrl-names = "default"; @@ -84,6 +100,10 @@ }; }; +&cpu0 { + cpu-supply = <®_vdd_cpux>; +}; + &de { status = "okay"; }; -- 2.20.1
[PATCH 07/10] arm64: dts: allwinner: h5: orange-pi-pc2: Add CPU regulator supply
The OrangePi PC 2 uses a Silergy SY8106A regulator to supply the CPU cores. The fixed voltage when I2C programmed regulation is not in action is slightly higher than 1.1V. The value in the device tree description is based on calculations of the resistor values from the schematics. Cc: Andre Przywara Cc: Icenowy Zheng Cc: Emmanuel Vadot Signed-off-by: Chen-Yu Tsai --- This patch is based on the schematics and has not been tested on an actual board. --- .../dts/allwinner/sun50i-h5-orangepi-pc2.dts | 28 +++ 1 file changed, 28 insertions(+) diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts index 3e0d5a9c096d..23cfad7c78f4 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts @@ -132,6 +132,10 @@ status = "okay"; }; +&cpu0 { + cpu-supply = <®_vdd_cpux>; +}; + &de { status = "okay"; }; @@ -207,6 +211,30 @@ status = "okay"; }; +&r_i2c { + status = "okay"; + + reg_vdd_cpux: regulator@65 { + compatible = "silergy,sy8106a"; + reg = <0x65>; + regulator-name = "vdd-cpux"; + silergy,fixed-microvolt = <1108474>; + /* +* The datasheet uses 1.1V as the minimum value of VDD-CPUX, +* however both the Armbian DVFS table and the official one +* have operating points with voltage under 1.1V, and both +* DVFS table are known to work properly at the lowest +* operating point. +* +* Use 1.0V as the minimum voltage instead. +*/ + regulator-min-microvolt = <100>; + regulator-max-microvolt = <130>; + regulator-boot-on; + regulator-always-on; + }; +}; + &spi0 { status = "okay"; -- 2.20.1
[PATCH 03/10] arm64: dts: allwinner: h5: Hook up cpu regulator supplies
Some of the device trees for H5 boards already have the CPU supply regulator defined, but they are not referenced in the CPU node. Add the reference, so CPU DVFS mechanisms can see them. Signed-off-by: Chen-Yu Tsai --- .../boot/dts/allwinner/sun50i-h5-emlid-neutis-n5-devboard.dts | 4 arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo-plus2.dts | 4 2 files changed, 8 insertions(+) diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-emlid-neutis-n5-devboard.dts b/arch/arm64/boot/dts/allwinner/sun50i-h5-emlid-neutis-n5-devboard.dts index 85e7993a74e7..0c7b2b3d92f9 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h5-emlid-neutis-n5-devboard.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-emlid-neutis-n5-devboard.dts @@ -71,6 +71,10 @@ status = "okay"; }; +&cpu0 { + cpu-supply = <&vdd_cpux>; +}; + &de { status = "okay"; }; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo-plus2.dts b/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo-plus2.dts index 506e25ba028a..10e52b612892 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo-plus2.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo-plus2.dts @@ -126,6 +126,10 @@ status = "okay"; }; +&cpu0 { + cpu-supply = <&vdd_cpux>; +}; + &ehci0 { status = "okay"; }; -- 2.20.1
[PATCH 05/10] arm64: dts: allwinner: h5: orange-pi-zero-plus: Add CPU regulator supply
The OrangePi Zero Plus uses a fixed regulator to supply the CPU cores. The feedback resistor network can be changed by toggling a GPIO line. This is effectively a GPIO controlled regulator that can change between roughly 1.1V and 1.3V. The actual voltage is slightly higher. The values used in the device tree description are based on calculations using the resistor values from the schematics. Cc: Hauke Mehrtens Signed-off-by: Chen-Yu Tsai --- This patch is based on the schematics and has not been tested on an actual board. --- .../sun50i-h5-orangepi-zero-plus.dts | 20 +++ 1 file changed, 20 insertions(+) diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus.dts b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus.dts index 1238de25a969..3493eea7cf29 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus.dts @@ -57,6 +57,26 @@ enable-active-high; gpio = <&pio 3 6 GPIO_ACTIVE_HIGH>; /* PD6 */ }; + + reg_vdd_cpux: vdd-cpux { + compatible = "regulator-gpio"; + regulator-name = "vdd-cpux"; + regulator-type = "voltage"; + regulator-boot-on; + regulator-always-on; + regulator-min-microvolt = <1108475>; + regulator-max-microvolt = <1307810>; + regulator-ramp-delay = <50>; /* 4ms */ + enable-gpios = <&r_pio 0 8 GPIO_ACTIVE_HIGH>; /* PL8 */ + gpios = <&r_pio 0 1 GPIO_ACTIVE_HIGH>; /* PL6 */ + gpios-states = <0x1>; + states = <1108475 0x0 + 1307810 0x1>; + }; +}; + +&cpu0 { + cpu-supply = <®_vdd_cpux>; }; &ehci0 { -- 2.20.1
[PATCH 10/10] arm64: dts: allwinner: h5: Add CPU Operating Performance Points table
Add an OPP (Operating Performance Points) table for the CPU cores to enable DVFS (Dynamic Voltage & Frequency Scaling) on the H5. The table originates from Armbian, but the maximum voltage is raised slightly to account for boards using slightly higher voltages. This has been tested on the Libre Computer ALL-H3-CC-H5 and the Bananapi M2+ v1.2 H5, both with adequate cooling. The former has a fixed 1.2V regulator, while the latter has a GPIO controlled regulator switchable between 1.1V and 1.3V. Signed-off-by: Chen-Yu Tsai --- arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi | 67 1 file changed, 67 insertions(+) diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi index 25bb8227a6fd..0e83b8a25f9c 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi @@ -54,6 +54,8 @@ enable-method = "psci"; clocks = <&ccu CLK_CPUX>; clock-latency-ns = <244144>; /* 8 32k periods */ + operating-points-v2 = <&cpu_opp_table>; + #cooling-cells = <2>; }; cpu@1 { @@ -63,6 +65,8 @@ enable-method = "psci"; clocks = <&ccu CLK_CPUX>; clock-latency-ns = <244144>; /* 8 32k periods */ + operating-points-v2 = <&cpu_opp_table>; + #cooling-cells = <2>; }; cpu@2 { @@ -72,6 +76,8 @@ enable-method = "psci"; clocks = <&ccu CLK_CPUX>; clock-latency-ns = <244144>; /* 8 32k periods */ + operating-points-v2 = <&cpu_opp_table>; + #cooling-cells = <2>; }; cpu@3 { @@ -81,6 +87,67 @@ enable-method = "psci"; clocks = <&ccu CLK_CPUX>; clock-latency-ns = <244144>; /* 8 32k periods */ + operating-points-v2 = <&cpu_opp_table>; + #cooling-cells = <2>; + }; + }; + + cpu_opp_table: opp_table { + compatible = "operating-points-v2"; + opp-shared; + + opp@40800 { + opp-hz = /bits/ 64 <40800>; + opp-microvolt = <100 100 131>; + clock-latency-ns = <244144>; /* 8 32k periods */ + }; + + opp@64800 { + opp-hz = /bits/ 64 <64800>; + opp-microvolt = <104 104 131>; + clock-latency-ns = <244144>; /* 8 32k periods */ + }; + + opp@81600 { + opp-hz = /bits/ 64 <81600>; + opp-microvolt = <108 108 131>; + clock-latency-ns = <244144>; /* 8 32k periods */ + }; + + opp@91200 { + opp-hz = /bits/ 64 <91200>; + opp-microvolt = <112 112 131>; + clock-latency-ns = <244144>; /* 8 32k periods */ + }; + + opp@96000 { + opp-hz = /bits/ 64 <96000>; + opp-microvolt = <116 116 131>; + clock-latency-ns = <244144>; /* 8 32k periods */ + }; + + opp@100800 { + opp-hz = /bits/ 64 <100800>; + opp-microvolt = <120 120 131>; + clock-latency-ns = <244144>; /* 8 32k periods */ + }; + + opp@105600 { + opp-hz = /bits/ 64 <105600>; + opp-microvolt = <124 124 131>; + clock-latency-ns = <244144>; /* 8 32k periods */ + }; + + opp@110400 { + opp-hz = /bits/ 64 <110400>; + opp-microvolt = <126 126 131>; + clock-latency-ns = <244144>; /* 8 32k periods */ + }; + + opp@115200 { + opp-hz = /bits/ 64 <115200>; + opp-microvolt = <130 130 131>; + clock-latency-ns = <244144>; /* 8 32k periods */ }; }; -- 2.20.1
[PATCH 02/10] ARM: dts: bananapi-m2-plus: Add CPU supply regulator
The original Bananapi M2+ uses a fixed regulator to supply the CPU cores. According to Bananapi, the retail v1.1 version is designed to supply 1.3V. Actual measurements show 1.310V. Earlier engineering samples had it at 1.4V, but this is not covered here. Signed-off-by: Chen-Yu Tsai --- .../boot/dts/sunxi-bananapi-m2-plus-v1.2.dtsi | 30 +++ arch/arm/boot/dts/sunxi-bananapi-m2-plus.dtsi | 14 + 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/arch/arm/boot/dts/sunxi-bananapi-m2-plus-v1.2.dtsi b/arch/arm/boot/dts/sunxi-bananapi-m2-plus-v1.2.dtsi index a567567763f4..39834329b6ae 100644 --- a/arch/arm/boot/dts/sunxi-bananapi-m2-plus-v1.2.dtsi +++ b/arch/arm/boot/dts/sunxi-bananapi-m2-plus-v1.2.dtsi @@ -5,27 +5,19 @@ #include "sunxi-bananapi-m2-plus.dtsi" -/ { +®_vdd_cpux { /* * Bananapi M2+ v1.2 uses a GPIO line to change the effective * resistance on the CPU regulator's feedback pin. */ - reg_vdd_cpux: vdd-cpux { - compatible = "regulator-gpio"; - regulator-name = "vdd-cpux"; - regulator-type = "voltage"; - regulator-boot-on; - regulator-always-on; - regulator-min-microvolt = <1108475>; - regulator-max-microvolt = <1308475>; - regulator-ramp-delay = <50>; /* 4ms */ - gpios = <&r_pio 0 1 GPIO_ACTIVE_HIGH>; /* PL1 */ - gpios-states = <0x1>; - states = <1108475 0x0 - 1308475 0x1>; - }; -}; - -&cpu0 { - cpu-supply = <®_vdd_cpux>; + compatible = "regulator-gpio"; + regulator-type = "voltage"; + regulator-min-microvolt = <1108475>; + regulator-max-microvolt = <1308475>; + regulator-ramp-delay = <50>; /* 4ms */ + enable-gpios = <&r_pio 0 8 GPIO_ACTIVE_HIGH>; /* PL8 */ + gpios = <&r_pio 0 1 GPIO_ACTIVE_HIGH>; /* PL1 */ + gpios-states = <0x1>; + states = <1108475 0x0 + 1308475 0x1>; }; diff --git a/arch/arm/boot/dts/sunxi-bananapi-m2-plus.dtsi b/arch/arm/boot/dts/sunxi-bananapi-m2-plus.dtsi index 3bed375b9c03..eb90f53ae958 100644 --- a/arch/arm/boot/dts/sunxi-bananapi-m2-plus.dtsi +++ b/arch/arm/boot/dts/sunxi-bananapi-m2-plus.dtsi @@ -99,6 +99,16 @@ gpio = <&pio 3 6 GPIO_ACTIVE_HIGH>; }; + reg_vdd_cpux: vdd-cpux { + compatible = "regulator-fixed"; + regulator-name = "vdd-cpux"; + regulator-boot-on; + regulator-always-on; + regulator-min-microvolt = <131>; + regulator-max-microvolt = <131>; + gpios = <&r_pio 0 8 GPIO_ACTIVE_HIGH>; /* PL8 */ + }; + wifi_pwrseq: wifi_pwrseq { compatible = "mmc-pwrseq-simple"; pinctrl-names = "default"; @@ -108,6 +118,10 @@ }; }; +&cpu0 { + cpu-supply = <®_vdd_cpux>; +}; + &de { status = "okay"; }; -- 2.20.1
[PATCH 04/10] arm64: dts: allwinner: h5: nanopi-neo2: Add CPU regulator supply
The Nanopi Neo 2 uses a fixed regulator to supply the CPU cores. The feedback resistor network can be changed by toggling a GPIO line. This is effectively a GPIO controlled regulator that can change between 1.1V and 1.3V. Cc: Icenowy Zheng Signed-off-by: Chen-Yu Tsai --- This patch is based on the schematics and has not been tested on an actual board. --- .../dts/allwinner/sun50i-h5-nanopi-neo2.dts | 20 +++ 1 file changed, 20 insertions(+) diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo2.dts b/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo2.dts index cc268a69786c..08ffdfb78137 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo2.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo2.dts @@ -99,6 +99,26 @@ gpio = <&r_pio 0 2 GPIO_ACTIVE_HIGH>; /* PL2 */ status = "okay"; }; + + reg_vdd_cpux: vdd-cpux { + compatible = "regulator-gpio"; + regulator-name = "vdd-cpux"; + regulator-type = "voltage"; + regulator-boot-on; + regulator-always-on; + regulator-min-microvolt = <110>; + regulator-max-microvolt = <130>; + regulator-ramp-delay = <50>; /* 4ms */ + enable-gpios = <&r_pio 0 8 GPIO_ACTIVE_HIGH>; /* PL8 */ + gpios = <&r_pio 0 1 GPIO_ACTIVE_HIGH>; /* PL6 */ + gpios-states = <0x1>; + states = <110 0x0 + 130 0x1>; + }; +}; + +&cpu0 { + cpu-supply = <®_vdd_cpux>; }; &ehci0 { -- 2.20.1
[PATCH 09/10] arm64: dts: allwinner: h5: Add clock to CPU cores
The ARM CPU cores are fed by the CPU clock from the CCU. Add a reference to the clock for each CPU core, along with the clock transition latency. Signed-off-by: Chen-Yu Tsai --- arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi | 8 1 file changed, 8 insertions(+) diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi index c22621b4b8e9..25bb8227a6fd 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi @@ -52,6 +52,8 @@ device_type = "cpu"; reg = <0>; enable-method = "psci"; + clocks = <&ccu CLK_CPUX>; + clock-latency-ns = <244144>; /* 8 32k periods */ }; cpu@1 { @@ -59,6 +61,8 @@ device_type = "cpu"; reg = <1>; enable-method = "psci"; + clocks = <&ccu CLK_CPUX>; + clock-latency-ns = <244144>; /* 8 32k periods */ }; cpu@2 { @@ -66,6 +70,8 @@ device_type = "cpu"; reg = <2>; enable-method = "psci"; + clocks = <&ccu CLK_CPUX>; + clock-latency-ns = <244144>; /* 8 32k periods */ }; cpu@3 { @@ -73,6 +79,8 @@ device_type = "cpu"; reg = <3>; enable-method = "psci"; + clocks = <&ccu CLK_CPUX>; + clock-latency-ns = <244144>; /* 8 32k periods */ }; }; -- 2.20.1
[PATCH 08/10] arm64: dts: allwinner: h5: orange-pi-prime: Add CPU regulator supply
The OrangePi Prime uses a Silergy SY8106A regulator to supply the CPU cores. The fixed voltage when I2C programmed regulation is not in action is slightly higher than 1.1V. The value in the device tree description is based on calculations of the resistor values from the schematics. Cc: Icenowy Zheng Signed-off-by: Chen-Yu Tsai --- This patch is based on the schematics and has not been tested on an actual board. --- .../allwinner/sun50i-h5-orangepi-prime.dts| 28 +++ 1 file changed, 28 insertions(+) diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-prime.dts b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-prime.dts index b75ca4d7d001..e866a0734bb3 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-prime.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-prime.dts @@ -139,6 +139,10 @@ status = "okay"; }; +&cpu0 { + cpu-supply = <®_vdd_cpux>; +}; + &de { status = "okay"; }; @@ -222,6 +226,30 @@ status = "okay"; }; +&r_i2c { + status = "okay"; + + reg_vdd_cpux: regulator@65 { + compatible = "silergy,sy8106a"; + reg = <0x65>; + regulator-name = "vdd-cpux"; + silergy,fixed-microvolt = <1108474>; + /* +* The datasheet uses 1.1V as the minimum value of VDD-CPUX, +* however both the Armbian DVFS table and the official one +* have operating points with voltage under 1.1V, and both +* DVFS table are known to work properly at the lowest +* operating point. +* +* Use 1.0V as the minimum voltage instead. +*/ + regulator-min-microvolt = <100>; + regulator-max-microvolt = <130>; + regulator-boot-on; + regulator-always-on; + }; +}; + &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_pins_a>; -- 2.20.1
Re: [PATCH 2/4] livepatch: Handle failing allocation of shadow variables in the selftest
On Mon 2019-01-21 13:14:38, Miroslav Benes wrote: > Hi, > > On Wed, 16 Jan 2019, Petr Mladek wrote: > > > Do not dereference pointers to the shadow variables when either > > klp_shadow_alloc() or klp_shadow_get() fail. > > I may misunderstand the patch, so bear with me, please. Is this because of > a possible null pointer dereference? If yes, shouldn't this say rather > "when both klp_shadow_alloc() and klp_shadow_get() fail"? Well, klp_shadow_get() could fail also from other reasons if there is a bug in the implementation. > > There is no need to check the other locations explicitly. The test > > would fail if any allocation fails. And the existing messages, printed > > during the test, provide enough information to debug eventual problems. Heh, this is actually the reason why I did not add the check for shadow_alloc(). Any error would be detected later with klp_shadow_get() calls that should get tested anyway. Hmm, when I think about it. A good practice is to handle klp_shadow_allow() or klp_shadow_get() failures immediately. After all, it is the sample code that people might follow. > > Signed-off-by: Petr Mladek > > --- > > lib/livepatch/test_klp_shadow_vars.c | 8 > > 1 file changed, 4 insertions(+), 4 deletions(-) > > > > diff --git a/lib/livepatch/test_klp_shadow_vars.c > > b/lib/livepatch/test_klp_shadow_vars.c > > index 02f892f941dc..55e6820430dc 100644 > > --- a/lib/livepatch/test_klp_shadow_vars.c > > +++ b/lib/livepatch/test_klp_shadow_vars.c > > @@ -162,15 +162,15 @@ static int test_klp_shadow_vars_init(void) > > * to expected data. > > */ > > ret = shadow_get(obj, id); > > - if (ret == sv1 && *sv1 == &var1) > > + if (ret && ret == sv1 && *sv1 == &var1) > > pr_info(" got expected PTR%d -> PTR%d result\n", > > ptr_id(sv1), ptr_id(*sv1)); > > ret = shadow_get(obj + 1, id); > > - if (ret == sv2 && *sv2 == &var2) > > + if (ret && ret == sv2 && *sv2 == &var2) > > pr_info(" got expected PTR%d -> PTR%d result\n", > > ptr_id(sv2), ptr_id(*sv2)); > > ret = shadow_get(obj, id + 1); > > - if (ret == sv3 && *sv3 == &var3) > > + if (ret && ret == sv3 && *sv3 == &var3) > > pr_info(" got expected PTR%d -> PTR%d result\n", > > ptr_id(sv3), ptr_id(*sv3)); > > There is one more similar site calling shadow_get(obj, id + 1) which is > fixed. Heh, I think that I did not add the check there on purpose. If we are here, shadow_get(obj, id + 1) must have already succeeded above. But it is a bad practice. We should always check the output. I'll do so in v2. Best Regards, Petr
[PATCH v2] arm64: dts: sdm845: Add Q6V5 ADSP node
This patch adds Q6V5 ADSP pil remoteproc node for SDM845 SoC. Signed-off-by: Rohit kumar --- Changes since v1: Addressed comments given by Bjorn. This depends on below upstream patch which defines adsp_mem node: https://lkml.org/lkml/2019/1/29/1392 arch/arm64/boot/dts/qcom/sdm845.dtsi | 89 1 file changed, 89 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi index 33f5f4b..31cb8db 100644 --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi @@ -18,6 +18,7 @@ #include #include #include +#include / { interrupt-parent = <&intc>; @@ -2048,6 +2049,94 @@ status = "disabled"; }; + adsp_pil: remoteproc-adsp-pil@1730 { + compatible = "qcom,sdm845-adsp-pil"; + + reg = <0x1730 0x410>; + interrupts-extended = + <&intc GIC_SPI 162 IRQ_TYPE_EDGE_RISING>, + <&adsp_smp2p_in 0 IRQ_TYPE_EDGE_RISING>, + <&adsp_smp2p_in 1 IRQ_TYPE_EDGE_RISING>, + <&adsp_smp2p_in 2 IRQ_TYPE_EDGE_RISING>, + <&adsp_smp2p_in 3 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "wdog", "fatal", "ready", + "handover", "stop-ack"; + + clocks = <&rpmhcc RPMH_CXO_CLK>, +<&gcc GCC_LPASS_SWAY_CLK>, +<&lpasscc LPASS_Q6SS_AHBS_AON_CLK>, +<&lpasscc LPASS_Q6SS_AHBM_AON_CLK>, +<&lpasscc LPASS_QDSP6SS_XO_CLK>, +<&lpasscc LPASS_QDSP6SS_SLEEP_CLK>, +<&lpasscc LPASS_QDSP6SS_CORE_CLK>; + + clock-names = "xo", "sway_cbcr", "lpass_ahbs_aon_cbcr", + "lpass_ahbm_aon_cbcr", "qdsp6ss_xo", + "qdsp6ss_sleep", "qdsp6ss_core"; + + resets = <&pdc_reset PDC_AUDIO_SYNC_RESET>, +<&aoss_reset AOSS_CC_LPASS_RESTART>; + reset-names = "pdc_sync", "cc_lpass"; + + qcom,halt-regs = <&tcsr_mutex_regs 0x22000>; + + memory-region = <&adsp_mem>; + + qcom,smem-states = <&adsp_smp2p_out 0>; + qcom,smem-state-names = "stop"; + + status = "disabled"; + glink-edge { + interrupts = ; + label = "lpass"; + qcom,remote-pid = <2>; + mboxes = <&apss_shared 8>; + #address-cells = <1>; + #size-cells = <0>; + apr@4 { + compatible = "qcom,apr-v2"; + qcom,glink-channels = "apr_audio_svc"; + reg = ; + #address-cells = <1>; + #size-cells = <0>; + q6core { + compatible = "qcom,q6core"; + reg = ; + }; + + q6afe { + compatible = "qcom,q6afe"; + reg = ; + q6afedai: afedais { + compatible = "qcom,q6afe-dais"; + #sound-dai-cells = <1>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; + + q6asm { + compatible = "qcom,q6asm"; + reg = ; + q6asmdai: asmdai{ + compatible = "qcom,q6asm-dais"; + iommus = <&apps_smmu 0x1821 0x0>; + #sound-dai-cells = <1>; + }; + }; + + q6adm { + compatible = "qcom,q6adm"; +
Re: [RFC v3 02/21] iommu: Introduce cache_invalidate API
Hi Alex, On 1/30/19 12:16 AM, Alex Williamson wrote: > On Fri, 25 Jan 2019 17:49:20 +0100 > Auger Eric wrote: > >> Hi Alex, >> >> On 1/11/19 10:30 PM, Alex Williamson wrote: >>> On Tue, 8 Jan 2019 11:26:14 +0100 >>> Eric Auger wrote: >>> From: "Liu, Yi L" In any virtualization use case, when the first translation stage is "owned" by the guest OS, the host IOMMU driver has no knowledge of caching structure updates unless the guest invalidation activities are trapped by the virtualizer and passed down to the host. Since the invalidation data are obtained from user space and will be written into physical IOMMU, we must allow security check at various layers. Therefore, generic invalidation data format are proposed here, model specific IOMMU drivers need to convert them into their own format. Signed-off-by: Liu, Yi L Signed-off-by: Jean-Philippe Brucker Signed-off-by: Jacob Pan Signed-off-by: Ashok Raj Signed-off-by: Eric Auger --- v1 -> v2: - add arch_id field - renamed tlb_invalidate into cache_invalidate as this API allows to invalidate context caches on top of IOTLBs v1: renamed sva_invalidate into tlb_invalidate and add iommu_ prefix in header. Commit message reworded. --- drivers/iommu/iommu.c | 14 ++ include/linux/iommu.h | 14 ++ include/uapi/linux/iommu.h | 95 ++ 3 files changed, 123 insertions(+) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 0f2b7f1fc7c8..b2e248770508 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -1403,6 +1403,20 @@ int iommu_set_pasid_table(struct iommu_domain *domain, } EXPORT_SYMBOL_GPL(iommu_set_pasid_table); +int iommu_cache_invalidate(struct iommu_domain *domain, struct device *dev, + struct iommu_cache_invalidate_info *inv_info) +{ + int ret = 0; + + if (unlikely(!domain->ops->cache_invalidate)) + return -ENODEV; + + ret = domain->ops->cache_invalidate(domain, dev, inv_info); + + return ret; +} +EXPORT_SYMBOL_GPL(iommu_cache_invalidate); + static void __iommu_detach_device(struct iommu_domain *domain, struct device *dev) { diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 1da2a2357ea4..96d59886f230 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -186,6 +186,7 @@ struct iommu_resv_region { * @of_xlate: add OF master IDs to iommu grouping * @pgsize_bitmap: bitmap of all possible supported page sizes * @set_pasid_table: set pasid table + * @cache_invalidate: invalidate translation caches */ struct iommu_ops { bool (*capable)(enum iommu_cap); @@ -231,6 +232,9 @@ struct iommu_ops { int (*set_pasid_table)(struct iommu_domain *domain, struct iommu_pasid_table_config *cfg); + int (*cache_invalidate)(struct iommu_domain *domain, struct device *dev, + struct iommu_cache_invalidate_info *inv_info); + unsigned long pgsize_bitmap; }; @@ -294,6 +298,9 @@ extern void iommu_detach_device(struct iommu_domain *domain, struct device *dev); extern int iommu_set_pasid_table(struct iommu_domain *domain, struct iommu_pasid_table_config *cfg); +extern int iommu_cache_invalidate(struct iommu_domain *domain, + struct device *dev, + struct iommu_cache_invalidate_info *inv_info); extern struct iommu_domain *iommu_get_domain_for_dev(struct device *dev); extern struct iommu_domain *iommu_get_dma_domain(struct device *dev); extern int iommu_map(struct iommu_domain *domain, unsigned long iova, @@ -709,6 +716,13 @@ int iommu_set_pasid_table(struct iommu_domain *domain, { return -ENODEV; } +static inline int +iommu_cache_invalidate(struct iommu_domain *domain, + struct device *dev, + struct iommu_cache_invalidate_info *inv_info) +{ + return -ENODEV; +} #endif /* CONFIG_IOMMU_API */ diff --git a/include/uapi/linux/iommu.h b/include/uapi/linux/iommu.h index 7a7cf7a3de7c..4605f5cfac84 100644 --- a/include/uapi/linux/iommu.h +++ b/include/uapi/linux/iommu.h @@ -47,4 +47,99 @@ struct iommu_pasid_table_config { }; }; +/** + * enum iommu_inv_granularity - Generic invalidation granularity + * @IOMMU_INV_GRANU_DOMAIN_ALL_PASID: TLB entries or PASID caches of all + *
Re: [PATCH] s390/jump_label: Correct asm contraint
On Tue, Jan 29, 2019 at 08:25:58AM +0100, Laura Abbott wrote: > On 1/23/19 5:24 AM, Heiko Carstens wrote: > >On Wed, Jan 23, 2019 at 01:55:13PM +0100, Laura Abbott wrote: > >>There's a build failure with gcc9: ... > >Hmmm, this works only for the kernel image, but not for modules, which > >we compile with "-fPIC", which again doesn't work as described in the > >referenced bugzilla: > > ^~~ > >./arch/s390/include/asm/jump_label.h:19:2: note: in expansion of macro > >'asm_volatile_goto' > > asm_volatile_goto("0: brcl 0,"__stringify(JUMP_LABEL_NOP_OFFSET)"\n" > > > >Andreas, Ilya, any idea how to fix this? > > I've had to turn off s390 in Fedora until this gets fixed :( I assume this means you only turned off CONFIG_JUMP_LABEL on s390 until we have a fix for this?
Re: [PATCH 2/4] livepatch: Handle failing allocation of shadow variables in the selftest
On Mon 2019-01-21 17:40:12, Joe Lawrence wrote: > On Wed, Jan 16, 2019 at 05:17:18PM +0100, Petr Mladek wrote: > > Do not dereference pointers to the shadow variables when either > > klp_shadow_alloc() or klp_shadow_get() fail. > > > > There is no need to check the other locations explicitly. The test > > would fail if any allocation fails. And the existing messages, printed > > during the test, provide enough information to debug eventual problems. > > > > I didn't run the test under those failing conditions, but at looking at > the code, I think it would simply skip the "expected found" > and the test script would complain about not seeing that msg. Accessing an invalid pointer would crash the kernel. > Would it be easier to just bite the bullet and verify sv[0-4] at their > allocation sites? Then later uses (ie, the sv3 dereference that > Miroslav spotted at the bottom) or new code wouldn't fall through the > cracks. As I wrote in the replay to Miroslav. The best practice is to handle errors everywhere. I am going to do so in v2. People might use it as a sample... Best Regards, Petr
Re: [PATCH v2] [media] v4l: add I / P frame min max QP definitions
Hi Hans, For I frame min QP, if global min QP is set, the QP choose algorithm should meet both of them, hence QP will >= max(V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP, V4L2_CID_MPEG_VIDEO_H264_MIN_QP). And this is also the same to the P frame and max QP. I can add some description to describe this behavior in the document. Thanks, Fish Hans Verkuil 於 2019年1月30日 週三 下午3:57寫道: > > On 1/30/19 8:45 AM, Fish Lin wrote: > > Add following V4L2 QP parameters for H.264: > > * V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP > > * V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MAX_QP > > * V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP > > * V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP > > > > These controls will limit QP range for intra and inter frame, > > provide more manual control to improve video encode quality. > > How will this interact with V4L2_CID_MPEG_VIDEO_H264_MIN/MAX_QP? > > Or are drivers supposed to have either V4L2_CID_MPEG_VIDEO_H264_MIN/MAX_QP > or these new controls? If so, then that should be documented. > > Regards, > > Hans > > > > > Signed-off-by: Fish Lin > > --- > > Changelog since v1: > > - Add description in document. > > > > .../media/uapi/v4l/extended-controls.rst | 16 > > drivers/media/v4l2-core/v4l2-ctrls.c | 4 > > include/uapi/linux/v4l2-controls.h | 6 ++ > > 3 files changed, 26 insertions(+) > > > > diff --git a/Documentation/media/uapi/v4l/extended-controls.rst > > b/Documentation/media/uapi/v4l/extended-controls.rst > > index 286a2dd7ec36..f5989fad34f9 100644 > > --- a/Documentation/media/uapi/v4l/extended-controls.rst > > +++ b/Documentation/media/uapi/v4l/extended-controls.rst > > @@ -1214,6 +1214,22 @@ enum v4l2_mpeg_video_h264_entropy_mode - > > Quantization parameter for an B frame for H264. Valid range: from 0 > > to 51. > > > > +``V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP (integer)`` > > +Minimum quantization parameter for H264 I frame, to limit I frame > > +quality in a range. Valid range: from 0 to 51. > > + > > +``V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MAX_QP (integer)`` > > +Maximum quantization parameter for H264 I frame, to limit I frame > > +quality in a range. Valid range: from 0 to 51. > > + > > +``V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP (integer)`` > > +Minimum quantization parameter for H264 P frame, to limit P frame > > +quality in a range. Valid range: from 0 to 51. > > + > > +``V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP (integer)`` > > +Maximum quantization parameter for H264 P frame, to limit P frame > > +quality in a range. Valid range: from 0 to 51. > > + > > ``V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP (integer)`` > > Quantization parameter for an I frame for MPEG4. Valid range: from 1 > > to 31. > > diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c > > b/drivers/media/v4l2-core/v4l2-ctrls.c > > index 5e3806feb5d7..e2b0af0d2283 100644 > > --- a/drivers/media/v4l2-core/v4l2-ctrls.c > > +++ b/drivers/media/v4l2-core/v4l2-ctrls.c > > @@ -825,6 +825,10 @@ const char *v4l2_ctrl_get_name(u32 id) > > case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER:return "H264 > > Number of HC Layers"; > > case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP: > > return "H264 > > Set QP Value for HC Layers"; > > + case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP: return "H264 > > I-Frame Minimum QP Value"; > > + case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MAX_QP: return "H264 > > I-Frame Maximum QP Value"; > > + case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP: return "H264 > > P-Frame Minimum QP Value"; > > + case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP: return "H264 > > P-Frame Maximum QP Value"; > > case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP: return "MPEG4 > > I-Frame QP Value"; > > case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP: return "MPEG4 > > P-Frame QP Value"; > > case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP: return "MPEG4 > > B-Frame QP Value"; > > diff --git a/include/uapi/linux/v4l2-controls.h > > b/include/uapi/linux/v4l2-controls.h > > index 3dcfc6148f99..9519673e6437 100644 > > --- a/include/uapi/linux/v4l2-controls.h > > +++ b/include/uapi/linux/v4l2-controls.h > > @@ -533,6 +533,12 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type { > > }; > > #define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER > > (V4L2_CID_MPEG_BASE+381) > > #define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP > > (V4L2_CID_MPEG_BASE+382) > > + > > +#define V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP > > (V4L2_CID_MPEG_BASE+390) > > +#define V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MAX_QP > > (V4L2_CID_MPEG_BASE+391) > > +#define V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP > > (V4L2_CID_MPEG_BASE+392) > > +#define V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP > > (V4L2_CID_MPEG_BASE+393) > >
[PATCH] MAINTAINERS: Add the IRC channel to the MTD entry
The #mtd channel (on OFTC servers) is being used to discuss MTD related topics. Add it to the MTD entry. Signed-off-by: Boris Brezillon --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 51029a425dbe..7b39ba46384a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9805,6 +9805,7 @@ M:Richard Weinberger L: linux-...@lists.infradead.org W: http://www.linux-mtd.infradead.org/ Q: http://patchwork.ozlabs.org/project/linux-mtd/list/ +C: irc://irc.oftc.net/mtd T: git git://git.infradead.org/linux-mtd.git master T: git git://git.infradead.org/linux-mtd.git mtd/next S: Maintained -- 2.17.1
Re: [PATCH] media: staging/intel-ipu3: Implement lock for stream on/off operations
Hi Rajmohan, On Tue, Jan 29, 2019 at 02:27:36PM -0800, Rajmohan Mani wrote: > Currently concurrent stream off operations on ImgU nodes are not > synchronized, leading to use-after-free bugs (as reported by KASAN). > > [ 250.090724] BUG: KASAN: use-after-free in ipu3_dmamap_free+0xc5/0x116 > [ipu3_imgu] > [ 250.090726] Read of size 8 at addr 888127b29bc0 by task yavta/18836 > [ 250.090731] Hardware name: HP Soraka/Soraka, BIOS Google_Soraka.10431.17.0 > 03/22/2018 > [ 250.090732] Call Trace: > [ 250.090735] dump_stack+0x6a/0xb1 > [ 250.090739] print_address_description+0x8e/0x279 > [ 250.090743] ? ipu3_dmamap_free+0xc5/0x116 [ipu3_imgu] > [ 250.090746] kasan_report+0x260/0x28a > [ 250.090750] ipu3_dmamap_free+0xc5/0x116 [ipu3_imgu] > [ 250.090754] ipu3_css_pool_cleanup+0x24/0x37 [ipu3_imgu] > [ 250.090759] ipu3_css_pipeline_cleanup+0x61/0xb9 [ipu3_imgu] > [ 250.090763] ipu3_css_stop_streaming+0x1f2/0x321 [ipu3_imgu] > [ 250.090768] imgu_s_stream+0x94/0x443 [ipu3_imgu] > [ 250.090772] ? ipu3_vb2_buf_queue+0x280/0x280 [ipu3_imgu] > [ 250.090775] ? vb2_dma_sg_unmap_dmabuf+0x16/0x6f [videobuf2_dma_sg] > [ 250.090778] ? vb2_buffer_in_use+0x36/0x58 [videobuf2_common] > [ 250.090782] ipu3_vb2_stop_streaming+0xf9/0x135 [ipu3_imgu] > > Implemented a lock to synchronize imgu stream on / off operations and > the modification of streaming flag (in struct imgu_device), to prevent > these issues. > > Reported-by: Laurent Pinchart > Suggested-by: Laurent Pinchart > > Signed-off-by: Rajmohan Mani > --- > drivers/staging/media/ipu3/ipu3-v4l2.c | 6 ++ > drivers/staging/media/ipu3/ipu3.c | 3 +++ > drivers/staging/media/ipu3/ipu3.h | 4 > 3 files changed, 13 insertions(+) > > diff --git a/drivers/staging/media/ipu3/ipu3-v4l2.c > b/drivers/staging/media/ipu3/ipu3-v4l2.c > index c7936032beb9..cf7e917cd0c8 100644 > --- a/drivers/staging/media/ipu3/ipu3-v4l2.c > +++ b/drivers/staging/media/ipu3/ipu3-v4l2.c > @@ -507,12 +507,15 @@ static int ipu3_vb2_start_streaming(struct vb2_queue > *vq, unsigned int count) > goto fail_stop_pipeline; > } > > + mutex_lock(&imgu->streaming_lock); > + You appear to be using imgu_device.lock (while searching buffers to queue to the device) as well as imgu_video_device.lock (qbuf, dqbuf) to serialise access to imgu_video_device.buffers list. The two locks may be acquired at the same time but each by different processes. That needs to be addressed, but probably not in this patch. I wonder if it'd be more simple to use imgu->lock here instead of adding a new one. > /* Start streaming of the whole pipeline now */ > dev_dbg(dev, "IMGU streaming is ready to start"); > r = imgu_s_stream(imgu, true); > if (!r) > imgu->streaming = true; > > + mutex_unlock(&imgu->streaming_lock); > return 0; > > fail_stop_pipeline: > @@ -543,6 +546,8 @@ static void ipu3_vb2_stop_streaming(struct vb2_queue *vq) > dev_err(&imgu->pci_dev->dev, > "failed to stop subdev streaming\n"); > > + mutex_lock(&imgu->streaming_lock); > + > /* Was this the first node with streaming disabled? */ > if (imgu->streaming && ipu3_all_nodes_streaming(imgu, node)) { > /* Yes, really stop streaming now */ > @@ -552,6 +557,7 @@ static void ipu3_vb2_stop_streaming(struct vb2_queue *vq) > imgu->streaming = false; > } > > + mutex_unlock(&imgu->streaming_lock); > ipu3_return_all_buffers(imgu, node, VB2_BUF_STATE_ERROR); > media_pipeline_stop(&node->vdev.entity); > } > diff --git a/drivers/staging/media/ipu3/ipu3.c > b/drivers/staging/media/ipu3/ipu3.c > index d521b3afb8b1..2daee51cd845 100644 > --- a/drivers/staging/media/ipu3/ipu3.c > +++ b/drivers/staging/media/ipu3/ipu3.c > @@ -635,6 +635,7 @@ static int imgu_pci_probe(struct pci_dev *pci_dev, > return r; > > mutex_init(&imgu->lock); > + mutex_init(&imgu->streaming_lock); > atomic_set(&imgu->qbuf_barrier, 0); > init_waitqueue_head(&imgu->buf_drain_wq); > > @@ -699,6 +700,7 @@ static int imgu_pci_probe(struct pci_dev *pci_dev, > ipu3_css_set_powerdown(&pci_dev->dev, imgu->base); > out_mutex_destroy: > mutex_destroy(&imgu->lock); > + mutex_destroy(&imgu->streaming_lock); > > return r; > } > @@ -716,6 +718,7 @@ static void imgu_pci_remove(struct pci_dev *pci_dev) > ipu3_dmamap_exit(imgu); > ipu3_mmu_exit(imgu->mmu); > mutex_destroy(&imgu->lock); > + mutex_destroy(&imgu->streaming_lock); > } > > static int __maybe_unused imgu_suspend(struct device *dev) > diff --git a/drivers/staging/media/ipu3/ipu3.h > b/drivers/staging/media/ipu3/ipu3.h > index 04fc99f47ebb..f732315f0701 100644 > --- a/drivers/staging/media/ipu3/ipu3.h > +++ b/drivers/staging/media/ipu3/ipu3.h > @@ -146,6 +146,10 @@ struct imgu_device { >* vid_buf.list and css->queue
Re: [bug report] Input: add st-keyscan driver
Hi all, I prefer to fix it. I guess people used their own correction. I will send you a fix asap. Best Regards Gabriel On 1/27/19 2:20 AM, Ken Sloat wrote: > On Sat, Jan 26, 2019 at 5:15 PM Dmitry Torokhov > wrote: >> On Sat, Jan 26, 2019 at 1:25 PM Ken Sloat >> wrote: >>> On Tue, Jan 22, 2019 at 1:53 PM Dan Carpenter >>> wrote: Hello Gabriel FERNANDEZ, >>> Hello Dan, >>> >>> I have added CCs for the maintainers as well as Gabriel Fernandez as >>> currently you just have the linux-input mailing list >>> The patch 062589b13991: "Input: add st-keyscan driver" from Apr 12, 2014, leads to the following static checker warning: drivers/input/keyboard/st-keyscan.c:156 keyscan_probe() error: potential zalloc NULL dereference: 'keypad_data->input_dev' drivers/input/keyboard/st-keyscan.c 125 static int keyscan_probe(struct platform_device *pdev) 126 { 127 struct st_keyscan *keypad_data; 128 struct input_dev *input_dev; 129 struct resource *res; 130 int error; 131 132 if (!pdev->dev.of_node) { 133 dev_err(&pdev->dev, "no DT data present\n"); 134 return -EINVAL; 135 } 136 137 keypad_data = devm_kzalloc(&pdev->dev, sizeof(*keypad_data), 138GFP_KERNEL); 139 if (!keypad_data) 140 return -ENOMEM; 141 142 input_dev = devm_input_allocate_device(&pdev->dev); 143 if (!input_dev) { 144 dev_err(&pdev->dev, "failed to allocate the input device\n"); 145 return -ENOMEM; 146 } 147 148 input_dev->name = pdev->name; 149 input_dev->phys = "keyscan-keys/input0"; 150 input_dev->dev.parent = &pdev->dev; 151 input_dev->open = keyscan_open; 152 input_dev->close = keyscan_close; 153 154 input_dev->id.bustype = BUS_HOST; 155 --> 156 error = keypad_matrix_key_parse_dt(keypad_data); ^^^ >>> I agree with you this would be a problem >>> to clarify the NULL derefence would occur here within >>> keypad_matrix_key_parse_dt >>> >>> struct device *dev = keypad_data->input_dev->dev.parent; >>> This assumes we have set "keypad_data->input_dev = input_dev;" but we don't do that until... 157 if (error) 158 return error; 159 160 error = matrix_keypad_build_keymap(NULL, NULL, 161keypad_data->n_rows, 162keypad_data->n_cols, 163NULL, input_dev); 164 if (error) { 165 dev_err(&pdev->dev, "failed to build keymap\n"); 166 return error; 167 } 168 169 input_set_drvdata(input_dev, keypad_data); 170 171 keypad_data->input_dev = input_dev; ^^ this line here. This driver has never worked and it was included almost five years ago. Is it worth fixing? 172 173 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 174 keypad_data->base = devm_ioremap_resource(&pdev->dev, res); 175 if (IS_ERR(keypad_data->base)) 176 return PTR_ERR(keypad_data->base); 177 regards, dan carpenter >>> Here is the interesting thing, I was looking on patchwork, and several >>> of the patches including what appears to be the latest actually set >>> "keypad_data->input_dev = input_dev" before calling >>> "keypad_matrix_key_parse_dt" >>> >>> From v4 on patchwork >>> + if (IS_ERR(keypad_data->clk)) { >>> + dev_err(&pdev->dev, "cannot get clock"); >>> + return PTR_ERR(keypad_data->clk); >>> + } >>> + >>> + keypad_data->input_dev = input_dev; >>> + >>> + input_dev->name = pdev->name; >>> + input_dev->phys = "keyscan-keys/input0"; >>> + input_dev->dev.parent = &pdev->dev; >>> + input_dev->open = keyscan_open; >>> + input_dev->close = keyscan_close; >>> + >>> + input_dev->id.bustype = BUS_HOST; >>> + >>> + error = keypad_matrix_key_parse_dt(keypad_data); >>> >>> According to patchwork, these aren't listed as accepted, so I'm not >>> sure where the exact accepted patch came from. Looking at the commit >>> log, it looks like the issue you showed above was made in the original >>> commit 062589b1399176a9c14bc68e
RE: [PATCH v2] KVM: x86: Sync the pending Posted-Interrupts
> > Some Posted-Interrupts from passthrough devices may be lost or > > overwritten when the vCPU is in runnable state. > > > > The SN (Suppress Notification) of PID (Posted Interrupt Descriptor) > > will be set when the vCPU is preempted (vCPU in KVM_MP_STATE_RUNNABLE > > state but not running on physical CPU). If a posted interrupt coming > > at this time, the irq remmaping facility will set the bit of PIR > > (Posted Interrupt Requests) without ON (Outstanding Notification). > > So this interrupt can't be sync to APIC virtualization register and > > will not be handled by Guest because ON is zero. > > > > Signed-off-by: Luwei Kang > > --- > > arch/x86/kvm/vmx/vmx.c | 2 +- > > arch/x86/kvm/x86.c | 2 +- > > 2 files changed, 2 insertions(+), 2 deletions(-) > > > > diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index > > f6915f1..820a03b 100644 > > --- a/arch/x86/kvm/vmx/vmx.c > > +++ b/arch/x86/kvm/vmx/vmx.c > > @@ -6048,7 +6048,7 @@ static int vmx_sync_pir_to_irr(struct kvm_vcpu *vcpu) > > bool max_irr_updated; > > > > WARN_ON(!vcpu->arch.apicv_active); > > - if (pi_test_on(&vmx->pi_desc)) { > > + if (!bitmap_empty((unsigned long *)vmx->pi_desc.pir, NR_VECTORS)) { > > pi_clear_on(&vmx->pi_desc); > > /* > > * IOMMU can write to PIR.ON, so the barrier matters even on UP. > > This is not what I asked. You should instead do the check after pi_clear_sn. > I think the SN has been cleared here before test the bitmap. The SN will be set when the vCPU is schedule out. ID: 28b835d60fcc2498e717cf5e6f0c3691c24546f7 But SN will be cleared when sched in. Another place is when vCPU run out of the vcpu_run() function: kvm_arch_vcpu_ioctl_run() vcpu_load(vcpu); -> kvm_arch_vcpu_load -> vmx_vcpu_load -> vmx_vcpu_pi_load -> new.sn = 0; vcpu_run(vcpu); for(;;) vcpu_put(vcpu); -> kvm_arch_vcpu_put -> vmx_vcpu_put -> vmx_vcpu_pi_put -> pi_set_sn() But SN will be cleared in vcpu_load() before back to vcpu_run() Thanks, Luwei Kang
Re: [PATCH 1/3] perf: convert perf_event_context.refcount to refcount_t
On Tue, Jan 29, 2019 at 01:55:32PM +, Reshetova, Elena wrote: > > On Mon, Jan 28, 2019 at 02:27:26PM +0200, Elena Reshetova wrote: > > > diff --git a/kernel/events/core.c b/kernel/events/core.c > > > index 3cd13a3..a1e87d2 100644 > > > --- a/kernel/events/core.c > > > +++ b/kernel/events/core.c > > > @@ -1171,7 +1171,7 @@ static void perf_event_ctx_deactivate(struct > > perf_event_context *ctx) > > > > > > static void get_ctx(struct perf_event_context *ctx) > > > { > > > - WARN_ON(!atomic_inc_not_zero(&ctx->refcount)); > > > + WARN_ON(!refcount_inc_not_zero(&ctx->refcount)); > > > > This could be refcount_inc(), remember how that already produces a WARN > > when we try and increment 0. > > But is this true for the x86 arch-specific implementation also? Dunno; but when debugging you should not have those enabled anyway.
Re: [PATCH] arm: dts: gta04: add gps support
On Mon, Jan 28, 2019 at 05:44:29PM +0100, Andreas Kemnade wrote: > On Mon, 28 Jan 2019 08:53:56 +0100 > Johan Hovold wrote: > > > On Fri, Jan 25, 2019 at 08:43:10PM +0100, Andreas Kemnade wrote: > > > The GTA04 has a w2sg0004 or w2sg0084 gps chip. Not detectable > > > which one is mounted so use the compatibility entry for w2sg0004 > > > for all which will work for both. > > > > > > Signed-off-by: Andreas Kemnade > > > --- > > > w2sg0004 bindings (together with the corresponding support is in > > > https://git.kernel.org/pub/scm/linux/kernel/git/johan/gnss gnss-next) > > > arch/arm/boot/dts/omap3-gta04.dtsi | 13 + > > > 1 file changed, 13 insertions(+) > > > + gps: gps { > > > > The node should be named "gnss" as per the binding. > > > > > + compatible = "wi2wi,w2sg0004"; > > > + pinctrl-names = "default"; > > > + pinctrl-0 = <&gps_pins>; > > > + sirf,onoff-gpios = <&gpio5 17 GPIO_ACTIVE_HIGH>; > > > + lna-supply = <&vsim>; > > > > Also, the vcc-supply is a required property. > > > well, it is not require in the driver and it has different behavior > (on even when not opened if on-off is there) than the lna-supply used > here. So maybe fix the binding documentation? The device-tree describes hardware, and how a particular driver happens to implement a binding is not relevant. That said, there is a bit of an on-going, shall we say philosophical, debate about this. The regulator maintainer takes a firm position that all mandatory physical supplies should be represented in firmware https://lore.kernel.org/lkml/20181123133126.gf2...@sirena.org.uk/T/#u https://lore.kernel.org/lkml/20180409102244.gb11...@sirena.org.uk/T/#u while Rob appears to take a slightly different stance on fixed regulators while admitting that this an issue which has not yet been fully resolved: https://lore.kernel.org/lkml/20180425171123.xhyoay3nu463btoq@rob-hp-laptop/T/#u Since this is a new binding, and the hardware requires the vcc supply and this is reflected in the binding, I think you should add a fixed regulator. At least until you hear otherwise. ;) Johan
[PATCH] blk-mq: fix a hung issue when fsync
Florian reported a io hung issue when fsync(). It should be triggered by following race condition. data + post flush a flush blk_flush_complete_seq case REQ_FSEQ_DATA blk_flush_queue_rq issued to driver blk_mq_dispatch_rq_list try to issue a flush req failed due to NON-NCQ command .queue_rq return BLK_STS_DEV_RESOURCE request completion req->end_io // doesn't check RESTART mq_flush_data_end_io case REQ_FSEQ_POSTFLUSH blk_kick_flush do nothing because previous flush has not been completed blk_mq_run_hw_queue insert rq to hctx->dispatch due to RESTART is still set, do nothing To fix this, replace the blk_mq_run_hw_queue in mq_flush_data_end_io with blk_mq_sched_restart to check and clear the RESTART flag. Fixes: bd166ef1 (blk-mq-sched: add framework for MQ capable IO schedulers) Reported-by: Florian Stecker Tested-by: Florian Stecker Signed-off-by: Jianchao Wang --- block/blk-flush.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/blk-flush.c b/block/blk-flush.c index a3fc7191..6e0f2d9 100644 --- a/block/blk-flush.c +++ b/block/blk-flush.c @@ -335,7 +335,7 @@ static void mq_flush_data_end_io(struct request *rq, blk_status_t error) blk_flush_complete_seq(rq, fq, REQ_FSEQ_DATA, error); spin_unlock_irqrestore(&fq->mq_flush_lock, flags); - blk_mq_run_hw_queue(hctx, true); + blk_mq_sched_restart(hctx); } /** -- 2.7.4
Re: [PATCH v2] arm: dts: gta04: add gps support
On Tue, Jan 29, 2019 at 08:38:43AM +0100, Andreas Kemnade wrote: > The GTA04 has a w2sg0004 or w2sg0084 gps chip. Not detectable > which one is mounted so use the compatibility entry for w2sg0004 > for all which will work for both. > > Signed-off-by: Andreas Kemnade > --- > Changes in v2: > - some s/gps/gnss/ > - not added vcc-supply because the regulator is not modelled > in dts at all I strongly suggest not sending revised patches before people have a chance to comment on your previous version and resolve any issues that may have been raised. Also it is customary to CC anyone how bothers to help review your patches. Johan
[RFC PATCH v3 00/10] support ROHM BD70528 PMIC
Patch series introducing support for ROHM BD70528 PMIC Please note that patch 1 breaks compilation without patches 2 and 3 ROHM BD70528 is a programmable Power Management IC for battery powered 'ultra low power' systems like the pre-announced NXP i.MX7 ULP. This patch series introduces support for the PMIC. I send this a RFC now as I would like to receive comments from Lee, Mark and Stephen regarding splitting the existing include/linux/mfd/bd718x7.h into ROHM generic and chip specific portions. Benefit is that for example the clk sub-driver does not need to be aware of chip specific structure(s) (struct bd718x7 and struct bd70528) as it only needs to derefernce the generic struct rohm_regmap_dev. Thus same clk subdriver can support both the bd718x7 and bd70528 as long as MFD driver data has this generic structure in the beginning of allocated data. But knowing the bd718x7 driver is already in upstream, it might be good if this change went through single tree, right? RTC block of the bd70528 can support 'wake' irq which wakes PMIC from standby state. Wake irq's can be armed to wake up system up to 24 hours from arming. bd70528 can also generate alarm interrupts which can be armed to occur years after triggering. The RTC driver does always arm both the waker and alarm irqs and does not utilize longer period of alarm interrupts. All the RTC timers are limited to occur within the next 24 hours. Any suggestions on more elegant timer support are welcome =) GPIO portion of bd70528 driver adds I/O support for driving GPIO pins or reading the state. The interrupt functionality is provided by regmap-irq. Current GPIO driver is not aware of whether the pin(s) are used for I/O or interrupts and it is up-to driver user to ensure there is no misconfiguration or "double use". Currently only MFD core, clk, RTC and regulator portions are somehow tested. The RFC series also include initial gpio, power-supply and watchdog patches in order to provide better overview on chip and to collect initial feedback. Reset and ADC are not supported by this series. Changelog v3: patches 1,2,3,4,5,6,7,8 and 10 are unchanged from v2 RTC fixups suggested by Guenter Roeck: - create bd70528_set_time_locked function in order to simplify error handling and to make mutex lock/unlock path more obvious - don't ignore errors on bd70528_set_time_locked - simplify bd70528_read_alarm enabled condition setting - add __packed to structs where members are mapped to HW registers - remove unnecessary brackets from enable condition in set_wake RTC: fixups suggested by Alessandro Belloni - don't use deprecated devm_rtc_device_register - add alarm_irq_enable callback - add range_min and range_max WDT: - add regmap and mutex pointers to WDT data so that they can be accessed without dereferencing the parent data - remove parent data pointer from WDT data - embed struct watchdog_device into WDT data in order to avoid double allocation. GPIO: - remove unused header as pointed by Linus Walleij POWER: - do not copy the whole MFD data (especially the mutex to avoid all possibilities of accidentally using the copy of a mutex) Changelog v2: Mainly feedback from Guenter Roeck: - patches 1, 2, 3, 4, 5, 9 are unchanged. - mfd: own mutex for each bd70528 instance - embed in struct bd70528 - watchdog: do not copy parent device data - watchdog: fix deadlock caused by double locked mutex - watchdog: set initial timeouts and WDT parent information - watchdog: remove unnecessary ping function from ops - watchdog: and the comment regarding it - watchdog: allocate watchdog struct in order to allow multiple WDG instances - rtc: bd70528 fix the order of mutex unlock and re-enabling RTC based timers - rtc: fix the irq mask register address - power: fix the irq mask register address - regulator/regmap-irq: Drop the patches 1, 8 and 9 from original series as those were already applied by Mark Patch 1: split the bd718x7.h to generic and chip specific portions. (breaks compilation without patch 2 and 3) Patch 2: adapt bd718x7.h changes to bd718x7 regulator driver Patch 3: adapt bd718x7.h changes to bd718x7 clk driver Patch 4: add MFD core support for bd70528 Patch 5: support bd70528 clk using bd718x7 clk driver Patch 6: document DT bindings for BD70528 Patch 7: support BD70528 GPIO block Patch 8: support BD70528 RTC Patch 9: support BD70528 battery charger Patch 10: support BD70528 watchdog This patch series is based on Mark's regulator/for-next branch --- Matti Vaittinen (10): mfd: bd718x7.h split to ROHM common and bd718x7 specific parts regulator: bd718x7 use chip specific and generic data structs clk: bd718x7: use chip specific and generic data structs mfd: bd70528: Support ROHM bd70528 PMIC - core clk: bd718x7: Support ROHM BD70528 clk block devicetree: bindings: Document first ROHM BD70528 bindings gpio: Initial support for ROHM bd70528 GPIO block rt
Re: [PATCH 1/2] regulator: uniphier: Fix probe error handling
Hi Axel, On Wed, 30 Jan 2019 15:11:09 +0800 wrote: > Ensure unwind all resources if probe fails. > > Signed-off-by: Axel Lin > --- > drivers/regulator/uniphier-regulator.c | 6 -- > 1 file changed, 4 insertions(+), 2 deletions(-) > > diff --git a/drivers/regulator/uniphier-regulator.c > b/drivers/regulator/uniphier-regulator.c > index abf22acbd13e..6ba0ae405f2b 100644 > --- a/drivers/regulator/uniphier-regulator.c > +++ b/drivers/regulator/uniphier-regulator.c > @@ -87,8 +87,10 @@ static int uniphier_regulator_probe(struct platform_device > *pdev) > } > > regmap = devm_regmap_init_mmio(dev, base, priv->data->regconf); > - if (IS_ERR(regmap)) > - return PTR_ERR(regmap); > + if (IS_ERR(regmap)) { > + ret = PTR_ERR(regmap); > + goto out_rst_assert; > + } Surely this return without asserting resets is wrong. This looks good to me. Reviewed-by: Kunihiko Hayashi Thank you, --- Best Regards, Kunihiko Hayashi
Re: [PATCH 2/2] regulator: uniphier: Constify uniphier_regulator_ops
On Wed, 30 Jan 2019 15:11:10 +0800 wrote: > Signed-off-by: Axel Lin > --- > drivers/regulator/uniphier-regulator.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/regulator/uniphier-regulator.c > b/drivers/regulator/uniphier-regulator.c > index 6ba0ae405f2b..9026d5a3e964 100644 > --- a/drivers/regulator/uniphier-regulator.c > +++ b/drivers/regulator/uniphier-regulator.c > @@ -32,7 +32,7 @@ struct uniphier_regulator_priv { > const struct uniphier_regulator_soc_data *data; > }; > > -static struct regulator_ops uniphier_regulator_ops = { > +static const struct regulator_ops uniphier_regulator_ops = { > .enable = regulator_enable_regmap, > .disable= regulator_disable_regmap, > .is_enabled = regulator_is_enabled_regmap, Reviewed-by: Kunihiko Hayashi Thank you, --- Best Regards, Kunihiko Hayashi
[RFC PATCH v3 02/10] regulator: bd718x7 use chip specific and generic data structs
Header rohm-bd718x7.h was split to generic and component specific parts. This changed the struct bd718x7. Adapt the regulator driver to these changes. Signed-off-by: Matti Vaittinen Acked-by: Mark Brown --- drivers/regulator/bd718x7-regulator.c | 22 +++--- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/regulator/bd718x7-regulator.c b/drivers/regulator/bd718x7-regulator.c index ccea133778c8..9109920b4a06 100644 --- a/drivers/regulator/bd718x7-regulator.c +++ b/drivers/regulator/bd718x7-regulator.c @@ -1018,11 +1018,11 @@ static int bd718xx_probe(struct platform_device *pdev) struct bd718xx *mfd; struct regulator_config config = { 0 }; struct bd718xx_pmic_inits pmic_regulators[] = { - [BD718XX_TYPE_BD71837] = { + [ROHM_CHIP_TYPE_BD71837] = { .r_datas = bd71837_regulators, .r_amount = ARRAY_SIZE(bd71837_regulators), }, - [BD718XX_TYPE_BD71847] = { + [ROHM_CHIP_TYPE_BD71847] = { .r_datas = bd71847_regulators, .r_amount = ARRAY_SIZE(bd71847_regulators), }, @@ -1037,15 +1037,15 @@ static int bd718xx_probe(struct platform_device *pdev) goto err; } - if (mfd->chip_type >= BD718XX_TYPE_AMOUNT || - !pmic_regulators[mfd->chip_type].r_datas) { + if (mfd->chip.chip_type >= ROHM_CHIP_TYPE_AMOUNT || + !pmic_regulators[mfd->chip.chip_type].r_datas) { dev_err(&pdev->dev, "Unsupported chip type\n"); err = -EINVAL; goto err; } /* Register LOCK release */ - err = regmap_update_bits(mfd->regmap, BD718XX_REG_REGLOCK, + err = regmap_update_bits(mfd->chip.regmap, BD718XX_REG_REGLOCK, (REGLOCK_PWRSEQ | REGLOCK_VREG), 0); if (err) { dev_err(&pdev->dev, "Failed to unlock PMIC (%d)\n", err); @@ -1065,7 +1065,7 @@ static int bd718xx_probe(struct platform_device *pdev) * for all reset types because OTP loading at READY will clear SEL * bit allowing HW defaults for power rails to be used */ - err = regmap_update_bits(mfd->regmap, BD718XX_REG_TRANS_COND1, + err = regmap_update_bits(mfd->chip.regmap, BD718XX_REG_TRANS_COND1, BD718XX_ON_REQ_POWEROFF_MASK | BD718XX_SWRESET_POWEROFF_MASK | BD718XX_WDOG_POWEROFF_MASK | @@ -1078,17 +1078,17 @@ static int bd718xx_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "Changed all resets from SVNS to READY\n"); } - for (i = 0; i < pmic_regulators[mfd->chip_type].r_amount; i++) { + for (i = 0; i < pmic_regulators[mfd->chip.chip_type].r_amount; i++) { const struct regulator_desc *desc; struct regulator_dev *rdev; const struct bd718xx_regulator_data *r; - r = &pmic_regulators[mfd->chip_type].r_datas[i]; + r = &pmic_regulators[mfd->chip.chip_type].r_datas[i]; desc = &r->desc; config.dev = pdev->dev.parent; - config.regmap = mfd->regmap; + config.regmap = mfd->chip.regmap; rdev = devm_regulator_register(&pdev->dev, desc, &config); if (IS_ERR(rdev)) { @@ -1104,7 +1104,7 @@ static int bd718xx_probe(struct platform_device *pdev) * can now switch the control from PMIC state machine to the * register interface */ - err = regmap_update_bits(mfd->regmap, r->init.reg, + err = regmap_update_bits(mfd->chip.regmap, r->init.reg, r->init.mask, r->init.val); if (err) { dev_err(&pdev->dev, @@ -1113,7 +1113,7 @@ static int bd718xx_probe(struct platform_device *pdev) goto err; } for (j = 0; j < r->additional_init_amnt; j++) { - err = regmap_update_bits(mfd->regmap, + err = regmap_update_bits(mfd->chip.regmap, r->additional_inits[j].reg, r->additional_inits[j].mask, r->additional_inits[j].val); -- 2.14.3 -- Matti Vaittinen ROHM Semiconductors Finland SWDC Kiviharjunlenkki 1E 90220 OULU FINLAND ~~~ "I don't think so," said Rene Descartes. Just then, he vanished ~~~
[PATCH 2/2] regulator: max77650: Convert to use regulator_enable/disable/is_enabled_regmap
By setting enable_reg, enable_mask, enable_val and disable_val, we can use the regulator_enable/disable/is_enabled_regmap helpers. With this change, then regB field can be removed from struct max77650_regulator_desc. Signed-off-by: Axel Lin --- Hi Bartosz, I don't have this h/w, please help to review and test it. I think the only difference is the is_enabled checking: Before the patch, it returns en != MAX77650_REGULATOR_DISABLED; After the patch, it returns en == MAX77650_REGULATOR_ENABLED I'm not sure if this difference does matter or not. Thanks, Axel drivers/regulator/max77650-regulator.c | 87 +++--- 1 file changed, 23 insertions(+), 64 deletions(-) diff --git a/drivers/regulator/max77650-regulator.c b/drivers/regulator/max77650-regulator.c index 5afb91400832..90c0f73f3fad 100644 --- a/drivers/regulator/max77650-regulator.c +++ b/drivers/regulator/max77650-regulator.c @@ -13,8 +13,6 @@ #include #define MAX77650_REGULATOR_EN_CTRL_MASKGENMASK(3, 0) -#define MAX77650_REGULATOR_EN_CTRL_BITS(_reg) \ - ((_reg) & MAX77650_REGULATOR_EN_CTRL_MASK) #define MAX77650_REGULATOR_ENABLED GENMASK(2, 1) #define MAX77650_REGULATOR_DISABLEDBIT(2) @@ -41,7 +39,6 @@ enum { struct max77650_regulator_desc { struct regulator_desc desc; unsigned int regA; - unsigned int regB; }; static const u32 max77651_sbb1_regulator_volt_table[] = { @@ -86,50 +83,6 @@ static const int max77650_current_limit_table[] = { 100, 866000, 707000, 50, }; -static int max77650_regulator_is_enabled(struct regulator_dev *rdev) -{ - struct max77650_regulator_desc *rdesc; - struct regmap *map; - int val, rv, en; - - rdesc = rdev_get_drvdata(rdev); - map = rdev_get_regmap(rdev); - - rv = regmap_read(map, rdesc->regB, &val); - if (rv) - return rv; - - en = MAX77650_REGULATOR_EN_CTRL_BITS(val); - - return en != MAX77650_REGULATOR_DISABLED; -} - -static int max77650_regulator_enable(struct regulator_dev *rdev) -{ - struct max77650_regulator_desc *rdesc; - struct regmap *map; - - rdesc = rdev_get_drvdata(rdev); - map = rdev_get_regmap(rdev); - - return regmap_update_bits(map, rdesc->regB, - MAX77650_REGULATOR_EN_CTRL_MASK, - MAX77650_REGULATOR_ENABLED); -} - -static int max77650_regulator_disable(struct regulator_dev *rdev) -{ - struct max77650_regulator_desc *rdesc; - struct regmap *map; - - rdesc = rdev_get_drvdata(rdev); - map = rdev_get_regmap(rdev); - - return regmap_update_bits(map, rdesc->regB, - MAX77650_REGULATOR_EN_CTRL_MASK, - MAX77650_REGULATOR_DISABLED); -} - static int max77650_regulator_set_voltage_sel(struct regulator_dev *rdev, unsigned int sel) { @@ -140,7 +93,7 @@ static int max77650_regulator_set_voltage_sel(struct regulator_dev *rdev, * If the regulator is disabled, we can program the desired * voltage right away. */ - if (!max77650_regulator_is_enabled(rdev)) + if (!regulator_is_enabled_regmap(rdev)) return regulator_set_voltage_sel_regmap(rdev, sel); /* @@ -189,7 +142,7 @@ static int max77651_regulator_sbb1_set_voltage_sel(struct regulator_dev *rdev, * If the regulator is disabled, we can program the desired * voltage right away. */ - if (!max77650_regulator_is_enabled(rdev)) + if (!regulator_is_enabled_regmap(rdev)) return regulator_set_voltage_sel_regmap(rdev, sel); curr = regulator_get_voltage_sel_regmap(rdev); @@ -264,9 +217,9 @@ static int max77650_regulator_set_current_limit(struct regulator_dev *rdev, } static const struct regulator_ops max77650_regulator_LDO_ops = { - .is_enabled = max77650_regulator_is_enabled, - .enable = max77650_regulator_enable, - .disable= max77650_regulator_disable, + .is_enabled = regulator_is_enabled_regmap, + .enable = regulator_enable_regmap, + .disable= regulator_disable_regmap, .list_voltage = regulator_list_voltage_linear, .map_voltage= regulator_map_voltage_linear, .get_voltage_sel= regulator_get_voltage_sel_regmap, @@ -275,9 +228,9 @@ static const struct regulator_ops max77650_regulator_LDO_ops = { }; static const struct regulator_ops max77650_regulator_SBB_ops = { - .is_enabled = max77650_regulator_is_enabled, - .enable = max77650_regulator_enable, - .disable= max77650_regulator_disable, + .is_enabled = regulator_is_enabled_regmap, + .enable = regul
[PATCH 1/2] regulator: max77650: Fix include files
This is a platform driver, no need to include linux/i2c.h. Include linux/of.h for of_match_ptr. Signed-off-by: Axel Lin --- drivers/regulator/max77650-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/max77650-regulator.c b/drivers/regulator/max77650-regulator.c index 474f2c02f2d5..5afb91400832 100644 --- a/drivers/regulator/max77650-regulator.c +++ b/drivers/regulator/max77650-regulator.c @@ -5,7 +5,7 @@ // // Regulator driver for MAXIM 77650/77651 charger/power-supply. -#include +#include #include #include #include -- 2.17.1
[RFC PATCH v3 04/10] mfd: bd70528: Support ROHM bd70528 PMIC - core
ROHM BD70528MWV is an ultra-low quiescent current general purpose single-chip power management IC for battery-powered portable devices. Add MFD core which enables chip access for following subdevices: - regulators/LED drivers - battery-charger - gpios - 32.768kHz clk - RTC - watchdog Signed-off-by: Matti Vaittinen --- drivers/mfd/Kconfig | 17 ++ drivers/mfd/Makefile | 1 + drivers/mfd/rohm-bd70528.c | 410 +++ include/linux/mfd/rohm-bd70528.h | 392 + 4 files changed, 820 insertions(+) create mode 100644 drivers/mfd/rohm-bd70528.c create mode 100644 include/linux/mfd/rohm-bd70528.h diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index f461460a2aeb..f1a0574cebb1 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -1847,6 +1847,23 @@ config MFD_ROHM_BD718XX NXP i.MX8. It contains 8 BUCK outputs and 7 LDOs, voltage monitoring and emergency shut down as well as 32,768KHz clock output. +config MFD_ROHM_BD70528 + tristate "ROHM BD70528 Power Management IC" + depends on I2C=y + depends on OF + select REGMAP_I2C + select REGMAP_IRQ + select MFD_CORE + help + Select this option to get support for the ROHM BD70528 Power + Management IC. BD71837 is general purpose single-chip power + management IC for battery-powered portable devices. It contains + 3 ultra-low current consumption buck converters, 3 LDOs and 2 LED + Drivers. Also included are 4 GPIOs, a real-time clock (RTC), a 32kHz + crystal oscillator, high-accuracy VREF for use with an external ADC, + 10 bits SAR ADC for battery temperature monitor and 1S battery + charger. + config MFD_STM32_LPTIMER tristate "Support for STM32 Low-Power Timer" depends on (ARCH_STM32 && OF) || COMPILE_TEST diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 12980a4ad460..fc9b1408e39b 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -241,4 +241,5 @@ obj-$(CONFIG_MFD_MXS_LRADC) += mxs-lradc.o obj-$(CONFIG_MFD_SC27XX_PMIC) += sprd-sc27xx-spi.o obj-$(CONFIG_RAVE_SP_CORE) += rave-sp.o obj-$(CONFIG_MFD_ROHM_BD718XX) += rohm-bd718x7.o +obj-$(CONFIG_MFD_ROHM_BD70528) += rohm-bd70528.o diff --git a/drivers/mfd/rohm-bd70528.c b/drivers/mfd/rohm-bd70528.c new file mode 100644 index ..580164addeeb --- /dev/null +++ b/drivers/mfd/rohm-bd70528.c @@ -0,0 +1,410 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// +// Copyright (C) 2018 ROHM Semiconductors +// +// ROHM BD70528 PMIC driver + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BD70528_INT_RES(_reg, _name) \ + { \ + .start = (_reg),\ + .end = (_reg), \ + .name = (_name),\ + .flags = IORESOURCE_IRQ,\ + } + +static const struct resource rtc_irqs[] = { + BD70528_INT_RES(BD70528_INT_RTC_ALARM, "bd70528-rtc-alm"), + BD70528_INT_RES(BD70528_INT_ELPS_TIM, "bd70528-elapsed-timer"), +}; + +static const struct resource charger_irqs[] = { + BD70528_INT_RES(BD70528_INT_BAT_OV_RES, "bd70528-bat-ov-res"), + BD70528_INT_RES(BD70528_INT_BAT_OV_DET, "bd70528-bat-ov-det"), + BD70528_INT_RES(BD70528_INT_DBAT_DET, "bd70528-bat-dead"), + BD70528_INT_RES(BD70528_INT_BATTSD_COLD_RES, "bd70528-bat-warmed"), + BD70528_INT_RES(BD70528_INT_BATTSD_COLD_DET, "bd70528-bat-cold"), + BD70528_INT_RES(BD70528_INT_BATTSD_HOT_RES, "bd70528-bat-cooled"), + BD70528_INT_RES(BD70528_INT_BATTSD_HOT_DET, "bd70528-bat-hot"), + BD70528_INT_RES(BD70528_INT_CHG_TSD, "bd70528-chg-tshd"), + BD70528_INT_RES(BD70528_INT_BAT_RMV, "bd70528-bat-removed"), + BD70528_INT_RES(BD70528_INT_BAT_DET, "bd70528-bat-detected"), + BD70528_INT_RES(BD70528_INT_DCIN2_OV_RES, "bd70528-dcin2-ov-res"), + BD70528_INT_RES(BD70528_INT_DCIN2_OV_DET, "bd70528-dcin2-ov-det"), + BD70528_INT_RES(BD70528_INT_DCIN2_RMV, "bd70528-dcin2-removed"), + BD70528_INT_RES(BD70528_INT_DCIN2_DET, "bd70528-dcin2-detected"), + BD70528_INT_RES(BD70528_INT_DCIN1_RMV, "bd70528-dcin1-removed"), + BD70528_INT_RES(BD70528_INT_DCIN1_DET, "bd70528-dcin1-detected"), +}; + +static struct mfd_cell bd70528_mfd_cells[] = { + { .name = "bd70528-pmic", }, + { .name = "bd70528-gpio", }, + /* +* We use BD71837 driver to drive the clk block. Only differences to +* BD70528 clock gate are the register address and mask. +*/ + { .name = "bd718xx-clk", }, + { .name = "bd70528-wdt", }, + { + .name = "bd70528-power", + .resources = &charger_irqs[0], +
Re: [Xen-devel][PATCH] drm/xen-front: Fix mmap attributes for display buffers
On 1/29/19 9:07 PM, Julien Grall wrote: > Hi Oleksandr, > > On 1/29/19 3:04 PM, Oleksandr Andrushchenko wrote: >> From: Oleksandr Andrushchenko >> >> When GEM backing storage is allocated those are normal pages, >> so there is no point using pgprot_writecombine while mmaping. >> This fixes mismatch of buffer pages' memory attributes between >> the frontend and backend which may cause screen artifacts. >> >> Fixes: c575b7eeb89f ("drm/xen-front: Add support for Xen PV display >> frontend") >> >> Signed-off-by: Oleksandr Andrushchenko >> >> Suggested-by: Julien Grall >> --- >> drivers/gpu/drm/xen/xen_drm_front_gem.c | 5 ++--- >> 1 file changed, 2 insertions(+), 3 deletions(-) >> >> diff --git a/drivers/gpu/drm/xen/xen_drm_front_gem.c >> b/drivers/gpu/drm/xen/xen_drm_front_gem.c >> index d303a2e17f5e..9d5c03d7668d 100644 >> --- a/drivers/gpu/drm/xen/xen_drm_front_gem.c >> +++ b/drivers/gpu/drm/xen/xen_drm_front_gem.c >> @@ -235,8 +235,7 @@ static int gem_mmap_obj(struct xen_gem_object >> *xen_obj, >> vma->vm_flags &= ~VM_PFNMAP; >> vma->vm_flags |= VM_MIXEDMAP; >> vma->vm_pgoff = 0; >> - vma->vm_page_prot = >> - pgprot_writecombine(vm_get_page_prot(vma->vm_flags)); >> + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); > > The patch looks good to me. It would be worth expanding the comment a > bit before to explain that we overwrite vm_page_prot to use cacheable > attribute as required by the Xen ABI. > Ok, then I'll put: + /* + * According to Xen on ARM ABI (xen/include/public/arch-arm.h): + * all memory which is shared with other entities in the system + * (including the hypervisor and other guests) must reside in memory + * which is mapped as Normal Inner Write-Back Outer Write-Back + * Inner-Shareable. + */ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); Please let me know if this is not what you want > With the comment updated: > > Acked-by: Julien Grall > > Cheers, > Thank you, Oleksandr
[RFC PATCH v3 06/10] devicetree: bindings: Document first ROHM BD70528 bindings
Document bindings for regulators (3 bucks, 3 LDOs and 2 LED drivers) and 4 GPIO pins which can be configured for I/O or as interrupt sources withe configurable trigger levels. Signed-off-by: Matti Vaittinen --- .../devicetree/bindings/mfd/rohm,bd70528-pmic.txt | 104 + 1 file changed, 104 insertions(+) create mode 100644 Documentation/devicetree/bindings/mfd/rohm,bd70528-pmic.txt diff --git a/Documentation/devicetree/bindings/mfd/rohm,bd70528-pmic.txt b/Documentation/devicetree/bindings/mfd/rohm,bd70528-pmic.txt new file mode 100644 index ..21801440a53a --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/rohm,bd70528-pmic.txt @@ -0,0 +1,104 @@ +* ROHM BD70528 Power Management Integrated Circuit bindings + +BD70528MWV is an ultra-low Iq general purpose single-chip power management IC +for battery-powered portable devices. The IC integrates 3 ultra-low current +consumption buck converters, 3 LDOs and 2 LED Drivers. Also included are 4 +GPIOs, a real-time clock (RTC), a 32kHz clock gate, high-accuracy VREF +for use with an external ADC, flexible dual-input power path, 10 bits SAR ADC +for battery temperature monitor and 1S battery charger with scalable charge +currents. + +Required properties: + - compatible : Should be "rohm,bd70528" + - reg : I2C slave address. + - interrupt-parent: Phandle to the parent interrupt controller. + - interrupts : The interrupt line the device is connected to. + - interrupt-controller: To indicate bd70528 acts as an interrupt controller. + - #interrupt-cells: Should be 2. usage is compliant to the 2 cells + variant of ../interrupt-controller/interrupts.txt + - gpio-controller : To indicate bd70528 acts as a gpio controller. + - #gpio-cells : Should be 2. The first cell is the pin number and + the second cell is used to specify flags. See + ../gpio/gpio.txt for more information. + - clock-frequency : Should be 32768 + - #clock-cells: Should be 0. + - regulators: : List of child nodes that specify the regulators. + Please see ../regulator/rohm,bd70528-regulator.txt + +Optional properties: + - clock-output-names : Should contain name for output clock. + +Example: +/* external oscillator */ +osc: oscillator { + compatible = "fixed-clock"; + #clock-cells = <1>; + clock-frequency = <32768>; + clock-output-names = "osc"; +}; + +pmic: bd70528@4b { + compatible = "rohm,bd70528"; + reg = <0x4b>; + interrupt-parent = <&gpio1>; + interrupts = <29 GPIO_ACTIVE_LOW>; + clocks = <&osc 0>; + #clock-cells = <0>; + clock-output-names = "bd70528-32k-out"; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + + regulators { + buck1: BUCK1 { + regulator-name = "buck1"; + regulator-min-microvolt = <120>; + regulator-max-microvolt = <340>; + regulator-boot-on; + regulator-ramp-delay = <125>; + }; + buck2: BUCK2 { + regulator-name = "buck2"; + regulator-min-microvolt = <120>; + regulator-max-microvolt = <330>; + regulator-boot-on; + regulator-ramp-delay = <125>; + }; + buck3: BUCK3 { + regulator-name = "buck3"; + regulator-min-microvolt = <80>; + regulator-max-microvolt = <180>; + regulator-boot-on; + regulator-ramp-delay = <250>; + }; + ldo1: LDO1 { + regulator-name = "ldo1"; + regulator-min-microvolt = <165>; + regulator-max-microvolt = <330>; + regulator-boot-on; + }; + ldo2: LDO2 { + regulator-name = "ldo2"; + regulator-min-microvolt = <165>; + regulator-max-microvolt = <330>; + regulator-boot-on; + }; + + ldo3: LDO3 { + regulator-name = "ldo3"; + regulator-min-microvolt = <165>; + regulator-max-microvolt = <330>; + }; + led_ldo1: LED_LDO1 { + regulator-name = "led_ldo1"; + regulator-min-microvolt = <20>; + regulator-max-microvolt = <30>; + }; + led_ldo2: LED_LDO2 { + regulator-name = "led_ldo2"; + regulator-
[PATCH v3] [media] v4l: add I / P frame min max QP definitions
Add following V4L2 QP parameters for H.264: * V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP * V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MAX_QP * V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP * V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP These controls will limit QP range for intra and inter frame, provide more manual control to improve video encode quality. Signed-off-by: Fish Lin --- Changelog since v2: - Add interaction with V4L2_CID_MPEG_VIDEO_H264_MIN/MAX_QP description in the document. Changelog since v1: - Add description in document. .../media/uapi/v4l/extended-controls.rst | 24 +++ drivers/media/v4l2-core/v4l2-ctrls.c | 4 include/uapi/linux/v4l2-controls.h| 6 + 3 files changed, 34 insertions(+) diff --git a/Documentation/media/uapi/v4l/extended-controls.rst b/Documentation/media/uapi/v4l/extended-controls.rst index 286a2dd7ec36..402e41eb24ee 100644 --- a/Documentation/media/uapi/v4l/extended-controls.rst +++ b/Documentation/media/uapi/v4l/extended-controls.rst @@ -1214,6 +1214,30 @@ enum v4l2_mpeg_video_h264_entropy_mode - Quantization parameter for an B frame for H264. Valid range: from 0 to 51. +``V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP (integer)`` +Minimum quantization parameter for H264 I frame, to limit I frame +quality in a range. Valid range: from 0 to 51. If +V4L2_CID_MPEG_VIDEO_H264_MIN_QP is set, the quantization parameter +should be chosen to meet both of the requirement. + +``V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MAX_QP (integer)`` +Maximum quantization parameter for H264 I frame, to limit I frame +quality in a range. Valid range: from 0 to 51. If +V4L2_CID_MPEG_VIDEO_H264_MAX_QP is set, the quantization parameter +should be chosen to meet both of the requirement. + +``V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP (integer)`` +Minimum quantization parameter for H264 P frame, to limit P frame +quality in a range. Valid range: from 0 to 51. If +V4L2_CID_MPEG_VIDEO_H264_MIN_QP is set, the quantization parameter +should be chosen to meet both of the requirement. + +``V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP (integer)`` +Maximum quantization parameter for H264 P frame, to limit P frame +quality in a range. Valid range: from 0 to 51. If +V4L2_CID_MPEG_VIDEO_H264_MAX_QP is set, the quantization parameter +should be chosen to meet both of the requirement. + ``V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP (integer)`` Quantization parameter for an I frame for MPEG4. Valid range: from 1 to 31. diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index 5e3806feb5d7..e2b0af0d2283 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c @@ -825,6 +825,10 @@ const char *v4l2_ctrl_get_name(u32 id) case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER:return "H264 Number of HC Layers"; case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP: return "H264 Set QP Value for HC Layers"; + case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP: return "H264 I-Frame Minimum QP Value"; + case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MAX_QP: return "H264 I-Frame Maximum QP Value"; + case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP: return "H264 P-Frame Minimum QP Value"; + case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP: return "H264 P-Frame Maximum QP Value"; case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP: return "MPEG4 I-Frame QP Value"; case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP: return "MPEG4 P-Frame QP Value"; case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP: return "MPEG4 B-Frame QP Value"; diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h index 3dcfc6148f99..9519673e6437 100644 --- a/include/uapi/linux/v4l2-controls.h +++ b/include/uapi/linux/v4l2-controls.h @@ -533,6 +533,12 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type { }; #define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER (V4L2_CID_MPEG_BASE+381) #define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP (V4L2_CID_MPEG_BASE+382) + +#define V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP(V4L2_CID_MPEG_BASE+390) +#define V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MAX_QP(V4L2_CID_MPEG_BASE+391) +#define V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP(V4L2_CID_MPEG_BASE+392) +#define V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP(V4L2_CID_MPEG_BASE+393) + #define V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP (V4L2_CID_MPEG_BASE+400) #define V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP (V4L2_CID_MPEG_BASE+401) #define V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP (V4L2_CID_MPEG_BASE+402) -- 2.20.1.495.gaa96b0ce6b-goog
[RFC PATCH v3 07/10] gpio: Initial support for ROHM bd70528 GPIO block
ROHM BD70528 PMIC has 4 GPIO pins. Allow them to be controlled by GPIO framework. IRQs are handled by regmap-irq and GPIO driver is not aware of the irq usage. Signed-off-by: Matti Vaittinen Reviewed-by: Linus Walleij --- drivers/gpio/Kconfig| 11 +++ drivers/gpio/Makefile | 1 + drivers/gpio/gpio-bd70528.c | 191 3 files changed, 203 insertions(+) create mode 100644 drivers/gpio/gpio-bd70528.c diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index b5a2845347ec..c82187648630 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -962,6 +962,17 @@ config GPIO_ARIZONA help Support for GPIOs on Wolfson Arizona class devices. +config GPIO_BD70528 + tristate "ROHM BD70528 GPIO support" + depends on MFD_ROHM_BD70528 + help + Support for GPIOs on ROHM BD70528 PMIC. There are four GPIOs + available on the ROHM PMIC in total. The GPIOs can also + generate interrupts. + + This driver can also be built as a module. If so, the module + will be called gpio-bd70528. + config GPIO_BD9571MWV tristate "ROHM BD9571 GPIO support" depends on MFD_BD9571MWV diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 37628f8dbf70..6f12c83598fc 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -34,6 +34,7 @@ obj-$(CONFIG_GPIO_ATH79) += gpio-ath79.o obj-$(CONFIG_GPIO_ASPEED) += gpio-aspeed.o obj-$(CONFIG_GPIO_RASPBERRYPI_EXP) += gpio-raspberrypi-exp.o obj-$(CONFIG_GPIO_BCM_KONA)+= gpio-bcm-kona.o +obj-$(CONFIG_GPIO_BD70528) += gpio-bd70528.o obj-$(CONFIG_GPIO_BD9571MWV) += gpio-bd9571mwv.o obj-$(CONFIG_GPIO_BRCMSTB) += gpio-brcmstb.o obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o diff --git a/drivers/gpio/gpio-bd70528.c b/drivers/gpio/gpio-bd70528.c new file mode 100644 index ..6a8149721aaf --- /dev/null +++ b/drivers/gpio/gpio-bd70528.c @@ -0,0 +1,191 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 ROHM Semiconductors +// gpio-bd70528.c ROHM BD70528MWV gpio driver + +#include +#include +#include +#include +#include + +#define GPIO_IN_REG(offset) (BD70528_REG_GPIO1_IN + offset*2) +#define GPIO_OUT_REG(offset) (BD70528_REG_GPIO1_OUT + offset*2) + +struct bd70528_gpio { + struct rohm_regmap_dev chip; + struct gpio_chip gpio; +}; + +static int bd70528_set_debounce(struct bd70528_gpio *bdgpio, + unsigned int offset, unsigned int debounce) +{ + u8 val; + + switch (debounce) { + case 0: + val = BD70528_DEBOUNCE_DISABLE; + break; + case 1 ... 15: + val = BD70528_DEBOUNCE_15MS; + break; + case 16 ... 30: + val = BD70528_DEBOUNCE_30MS; + break; + case 31 ... 50: + val = BD70528_DEBOUNCE_50MS; + break; + default: + dev_err(bdgpio->chip.dev, + "Invalid debouce value %u\n", debounce); + return -EINVAL; + } + return regmap_update_bits(bdgpio->chip.regmap, GPIO_IN_REG(offset), +BD70528_DEBOUNCE_MASK, val); +} + +static int bd70528_get_direction(struct gpio_chip *chip, unsigned int offset) +{ + struct bd70528_gpio *bdgpio = gpiochip_get_data(chip); + int val, ret; + + /* Do we need to do something to IRQs here? */ + ret = regmap_read(bdgpio->chip.regmap, GPIO_OUT_REG(offset), &val); + if (ret) { + dev_err(bdgpio->chip.dev, "Could not read gpio direction\n"); + return ret; + } + + return !(val & BD70528_GPIO_OUT_EN_MASK); +} + +static int bd70528_gpio_set_config(struct gpio_chip *chip, unsigned int offset, + unsigned long config) +{ + struct bd70528_gpio *bdgpio = gpiochip_get_data(chip); + + switch (pinconf_to_config_param(config)) { + case PIN_CONFIG_DRIVE_OPEN_DRAIN: + return regmap_update_bits(bdgpio->chip.regmap, + GPIO_OUT_REG(offset), + BD70528_GPIO_DRIVE_MASK, + BD70528_GPIO_OPEN_DRAIN); + break; + case PIN_CONFIG_DRIVE_PUSH_PULL: + return regmap_update_bits(bdgpio->chip.regmap, + GPIO_OUT_REG(offset), + BD70528_GPIO_DRIVE_MASK, + BD70528_GPIO_PUSH_PULL); + break; + case PIN_CONFIG_INPUT_DEBOUNCE: + return bd70528_set_debounce(bdgpio, offset, + pinconf_to_config_argument(config)); + break; + default: + break; + } + return -ENOTSUPP; +} + +static int bd70528_direction_inp
[PATCH v2 1/2] mm, memory_hotplug: is_mem_section_removable do not pass the end of a zone
From: Michal Hocko Mikhail has reported the following VM_BUG_ON triggered when reading sysfs removable state of a memory block: page:03d08300c000 is uninitialized and poisoned page dumped because: VM_BUG_ON_PAGE(PagePoisoned(p)) Call Trace: ([<0038596c>] is_mem_section_removable+0xb4/0x190) [<008f12fa>] show_mem_removable+0x9a/0xd8 [<008cf9c4>] dev_attr_show+0x34/0x70 [<00463ad0>] sysfs_kf_seq_show+0xc8/0x148 [<003e4194>] seq_read+0x204/0x480 [<003b53ea>] __vfs_read+0x32/0x178 [<003b55b2>] vfs_read+0x82/0x138 [<003b5be2>] ksys_read+0x5a/0xb0 [<00b86ba0>] system_call+0xdc/0x2d8 Last Breaking-Event-Address: [<0038596c>] is_mem_section_removable+0xb4/0x190 Kernel panic - not syncing: Fatal exception: panic_on_oops The reason is that the memory block spans the zone boundary and we are stumbling over an unitialized struct page. Fix this by enforcing zone range in is_mem_section_removable so that we never run away from a zone. Reported-by: Mikhail Zaslonko Debugged-by: Mikhail Zaslonko Tested-by: Gerald Schaefer Tested-by: Mikhail Gavrilov Reviewed-by: Oscar Salvador Signed-off-by: Michal Hocko --- mm/memory_hotplug.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index b9a667d36c55..07872789d778 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -1233,7 +1233,8 @@ static bool is_pageblock_removable_nolock(struct page *page) bool is_mem_section_removable(unsigned long start_pfn, unsigned long nr_pages) { struct page *page = pfn_to_page(start_pfn); - struct page *end_page = page + nr_pages; + unsigned long end_pfn = min(start_pfn + nr_pages, zone_end_pfn(page_zone(page))); + struct page *end_page = pfn_to_page(end_pfn); /* Check the starting page of each pageblock within the range */ for (; page < end_page; page = next_active_pageblock(page)) { -- 2.20.1
[RFC PATCH v3 08/10] rtc: bd70528: Initial support for ROHM bd70528 RTC
Support RTC block in ROHM bd70528 power management IC. Support getting and setting the time and date as well as arming an alarm which can also be used to wake the PMIC from standby state. HW supports wake interrupt only for the next 24 hours (sec, minute and hour information only) so we limit also the alarm interrupt to this 24 hours for the sake of consistency. Signed-off-by: Matti Vaittinen --- drivers/rtc/Kconfig | 8 + drivers/rtc/Makefile | 1 + drivers/rtc/rtc-bd70528.c | 502 ++ 3 files changed, 511 insertions(+) create mode 100644 drivers/rtc/rtc-bd70528.c diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 225b0b8516f3..df6211cbd83f 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -487,6 +487,14 @@ config RTC_DRV_M41T80_WDT help If you say Y here you will get support for the watchdog timer in the ST M41T60 and M41T80 RTC chips series. +config RTC_DRV_BD70528 + tristate "ROHM BD70528 PMIC RTC" + help + If you say Y here you will get support for the RTC + on ROHM BD70528 Power Management IC. + + This driver can also be built as a module. If so, the module + will be called rtc-bd70528. config RTC_DRV_BQ32K tristate "TI BQ32000" diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index df022d820bee..740b13840913 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -36,6 +36,7 @@ obj-$(CONFIG_RTC_DRV_ASM9260) += rtc-asm9260.o obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o obj-$(CONFIG_RTC_DRV_AT91SAM9) += rtc-at91sam9.o obj-$(CONFIG_RTC_DRV_AU1XXX) += rtc-au1xxx.o +obj-$(CONFIG_RTC_DRV_BD70528) += rtc-bd70528.o obj-$(CONFIG_RTC_DRV_BQ32K)+= rtc-bq32k.o obj-$(CONFIG_RTC_DRV_BQ4802) += rtc-bq4802.o obj-$(CONFIG_RTC_DRV_BRCMSTB) += rtc-brcmstb-waketimer.o diff --git a/drivers/rtc/rtc-bd70528.c b/drivers/rtc/rtc-bd70528.c new file mode 100644 index ..081d4c6e7172 --- /dev/null +++ b/drivers/rtc/rtc-bd70528.c @@ -0,0 +1,502 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// +// Copyright (C) 2018 ROHM Semiconductors +// +// RTC driver for ROHM BD70528 PMIC + +#include +#include +#include +#include +#include +#include +#include + +/* + * We read regs RTC_SEC => RTC_YEAR + * this struct is ordered according to chip registers. + * Keep it u8 only to avoid padding issues. + */ +struct bd70528_rtc_day { + u8 sec; + u8 min; + u8 hour; +} __packed; + +struct bd70528_rtc_data { + struct bd70528_rtc_day time; + u8 week; + u8 day; + u8 month; + u8 year; +} __packed; + +struct bd70528_rtc_wake { + struct bd70528_rtc_day time; + u8 ctrl; +} __packed; + +struct bd70528_rtc_alm { + struct bd70528_rtc_data data; + u8 alm_mask; + u8 alm_repeat; +} __packed; + +struct bd70528_rtc { + struct bd70528 *mfd; + struct device *dev; +}; + +static int bd70528_set_wake(struct bd70528 *bd70528, + int enable, int *old_state) +{ + int ret; + unsigned int ctrl_reg; + + ret = regmap_read(bd70528->chip.regmap, BD70528_REG_WAKE_EN, &ctrl_reg); + if (ret) + return ret; + + if (old_state) { + if (ctrl_reg & BD70528_MASK_WAKE_EN) + *old_state |= BD70528_WAKE_STATE_BIT; + else + *old_state &= ~BD70528_WAKE_STATE_BIT; + + if (!enable == !(*old_state & BD70528_WAKE_STATE_BIT)) + return 0; + } + + if (enable) + ctrl_reg |= BD70528_MASK_WAKE_EN; + else + ctrl_reg &= ~BD70528_MASK_WAKE_EN; + + return regmap_write(bd70528->chip.regmap, BD70528_REG_WAKE_EN, + ctrl_reg); +} + +static int bd70528_set_elapsed_tmr(struct bd70528 *bd70528, + int enable, int *old_state) +{ + int ret; + unsigned int ctrl_reg; + + /* +* TBD +* What is the purpose of elapsed timer ? +* Is the timeout registers counting down, or is the disable - re-enable +* going to restart the elapsed-time counting? If counting is restarted +* the timeout should be decreased by the amount of time that has +* elapsed since starting the timer. Maybe we should store the monotonic +* clock value when timer is started so that if RTC is set while timer +* is armed we could do the compensation. This is a hack if RTC/system +* clk are drifting. OTOH, RTC controlled via I2C is in any case +* inaccurate... +*/ + ret = regmap_read(bd70528->chip.regmap, BD70528_REG_ELAPSED_TIMER_EN, + &ctrl_reg); + if (ret) + return ret; + + if (old_state) { + if (ctrl_reg & BD70528_MASK_ELAPSED_TIMER_EN) + *old_state |= BD70528_E
Re: [PATCH 2/2] regulator: max77650: Convert to use regulator_enable/disable/is_enabled_regmap
śr., 30 sty 2019 o 10:07 Axel Lin napisał(a): > > By setting enable_reg, enable_mask, enable_val and disable_val, we can > use the regulator_enable/disable/is_enabled_regmap helpers. With this > change, then regB field can be removed from struct max77650_regulator_desc. > > Signed-off-by: Axel Lin > --- > Hi Bartosz, > I don't have this h/w, please help to review and test it. > > I think the only difference is the is_enabled checking: > Before the patch, it returns en != MAX77650_REGULATOR_DISABLED; > After the patch, it returns en == MAX77650_REGULATOR_ENABLED > I'm not sure if this difference does matter or not. > NACK. I intend to support the FPS feature of the regulator module in the future (see a similar thing in max77620) and I will need to extend these callbacks as there will be more possible values here. Regmap generics will not be enough. Best regards, Bartosz Golaszewski > Thanks, > Axel > drivers/regulator/max77650-regulator.c | 87 +++--- > 1 file changed, 23 insertions(+), 64 deletions(-) > > diff --git a/drivers/regulator/max77650-regulator.c > b/drivers/regulator/max77650-regulator.c > index 5afb91400832..90c0f73f3fad 100644 > --- a/drivers/regulator/max77650-regulator.c > +++ b/drivers/regulator/max77650-regulator.c > @@ -13,8 +13,6 @@ > #include > > #define MAX77650_REGULATOR_EN_CTRL_MASKGENMASK(3, 0) > -#define MAX77650_REGULATOR_EN_CTRL_BITS(_reg) \ > - ((_reg) & MAX77650_REGULATOR_EN_CTRL_MASK) > #define MAX77650_REGULATOR_ENABLED GENMASK(2, 1) > #define MAX77650_REGULATOR_DISABLEDBIT(2) > > @@ -41,7 +39,6 @@ enum { > struct max77650_regulator_desc { > struct regulator_desc desc; > unsigned int regA; > - unsigned int regB; > }; > > static const u32 max77651_sbb1_regulator_volt_table[] = { > @@ -86,50 +83,6 @@ static const int max77650_current_limit_table[] = { > 100, 866000, 707000, 50, > }; > > -static int max77650_regulator_is_enabled(struct regulator_dev *rdev) > -{ > - struct max77650_regulator_desc *rdesc; > - struct regmap *map; > - int val, rv, en; > - > - rdesc = rdev_get_drvdata(rdev); > - map = rdev_get_regmap(rdev); > - > - rv = regmap_read(map, rdesc->regB, &val); > - if (rv) > - return rv; > - > - en = MAX77650_REGULATOR_EN_CTRL_BITS(val); > - > - return en != MAX77650_REGULATOR_DISABLED; > -} > - > -static int max77650_regulator_enable(struct regulator_dev *rdev) > -{ > - struct max77650_regulator_desc *rdesc; > - struct regmap *map; > - > - rdesc = rdev_get_drvdata(rdev); > - map = rdev_get_regmap(rdev); > - > - return regmap_update_bits(map, rdesc->regB, > - MAX77650_REGULATOR_EN_CTRL_MASK, > - MAX77650_REGULATOR_ENABLED); > -} > - > -static int max77650_regulator_disable(struct regulator_dev *rdev) > -{ > - struct max77650_regulator_desc *rdesc; > - struct regmap *map; > - > - rdesc = rdev_get_drvdata(rdev); > - map = rdev_get_regmap(rdev); > - > - return regmap_update_bits(map, rdesc->regB, > - MAX77650_REGULATOR_EN_CTRL_MASK, > - MAX77650_REGULATOR_DISABLED); > -} > - > static int max77650_regulator_set_voltage_sel(struct regulator_dev *rdev, > unsigned int sel) > { > @@ -140,7 +93,7 @@ static int max77650_regulator_set_voltage_sel(struct > regulator_dev *rdev, > * If the regulator is disabled, we can program the desired > * voltage right away. > */ > - if (!max77650_regulator_is_enabled(rdev)) > + if (!regulator_is_enabled_regmap(rdev)) > return regulator_set_voltage_sel_regmap(rdev, sel); > > /* > @@ -189,7 +142,7 @@ static int max77651_regulator_sbb1_set_voltage_sel(struct > regulator_dev *rdev, > * If the regulator is disabled, we can program the desired > * voltage right away. > */ > - if (!max77650_regulator_is_enabled(rdev)) > + if (!regulator_is_enabled_regmap(rdev)) > return regulator_set_voltage_sel_regmap(rdev, sel); > > curr = regulator_get_voltage_sel_regmap(rdev); > @@ -264,9 +217,9 @@ static int max77650_regulator_set_current_limit(struct > regulator_dev *rdev, > } > > static const struct regulator_ops max77650_regulator_LDO_ops = { > - .is_enabled = max77650_regulator_is_enabled, > - .enable = max77650_regulator_enable, > - .disable= max77650_regulator_disable, > + .is_enabled = regulator_is_enabled_regmap, > + .enable = regulator_enable_regmap, > + .disable= regulator_disable_regmap, > .list_voltage = regulator_list_voltage_linear, > .map_voltage
Re: [PATCH] PM-runtime: fix deadlock with ktime
Hi Geert, On Wed, 30 Jan 2019 at 09:21, Geert Uytterhoeven wrote: > > Hi Vincent, > > On Wed, Jan 30, 2019 at 9:16 AM Vincent Guittot > wrote: > > A deadlock has been seen when swicthing clocksources which use PM runtime. > > The call path is: > > change_clocksource > > ... > > write_seqcount_begin > > ... > > timekeeping_update > > ... > > sh_cmt_clocksource_enable > > ... > > rpm_resume > > pm_runtime_mark_last_busy > > ktime_get > > do > > read_seqcount_begin > > while read_seqcount_retry > > > > write_seqcount_end > > > > Although we should be safe because we haven't yet changed the clocksource > > at that time, we can't because of seqcount protection. > > > > Use ktime_get_mono_fast_ns instead which is lock safe for such case > > > > Fixes: 8234f6734c5d ("PM-runtime: Switch autosuspend over to using > > hrtimers") > > Reported-by: Biju Das > > Signed-off-by: Vincent Guittot > > Thanks for your patch! > > /** > * ktime_get_mono_fast_ns - Fast NMI safe access to clock monotonic > * > * This timestamp is not guaranteed to be monotonic across an update. > * The timestamp is calculated by: > * > * now = base_mono + clock_delta * slope > * > * So if the update lowers the slope, readers who are forced to the > * not yet updated second array are still using the old steeper slope. > * > * tmono > * ^ > * |o n > * | o n > * | u > * | o > * |o > * |12345678---> reader order > * > * o = old slope > * u = update > * n = new slope > * > * So reader 6 will observe time going backwards versus reader 5. > * > * While other CPUs are likely to be able observe that, the only way > * for a CPU local observation is when an NMI hits in the middle of > * the update. Timestamps taken from that NMI context might be ahead > * of the following timestamps. Callers need to be aware of that and > * deal with it. > */ > > As this function is not guaranteed to be monotonic, have you checked how > the Runtime PM code behaves if time goes backwards? Does it just make > a suboptimal decision or does it crash? As a worst case this will generate a suboptimal decision around the update Regards, Vincent > > Thanks! > > Gr{oetje,eeting}s, > > Geert > > -- > Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- > ge...@linux-m68k.org > > In personal conversations with technical people, I call myself a hacker. But > when I'm talking to journalists I just say "programmer" or something like > that. > -- Linus Torvalds
[RFC PATCH v3 01/10] mfd: bd718x7.h split to ROHM common and bd718x7 specific parts
Split the bd718x7.h to ROHM common and bd718x7 specific parts so that we do not need to add same things in every new ROHM PMIC header. Please note that this change requires changes also in bd718x7 sub-device drivers for regulators and clk. Signed-off-by: Matti Vaittinen --- drivers/mfd/rohm-bd718x7.c | 23 --- include/linux/mfd/rohm-bd718x7.h | 22 -- include/linux/mfd/rohm-generic.h | 20 3 files changed, 40 insertions(+), 25 deletions(-) create mode 100644 include/linux/mfd/rohm-generic.h diff --git a/drivers/mfd/rohm-bd718x7.c b/drivers/mfd/rohm-bd718x7.c index a29d529a96f4..7beb444a57cb 100644 --- a/drivers/mfd/rohm-bd718x7.c +++ b/drivers/mfd/rohm-bd718x7.c @@ -98,18 +98,19 @@ static int bd718xx_i2c_probe(struct i2c_client *i2c, return -ENOMEM; bd718xx->chip_irq = i2c->irq; - bd718xx->chip_type = (unsigned int)(uintptr_t) + bd718xx->chip.chip_type = (unsigned int)(uintptr_t) of_device_get_match_data(&i2c->dev); - bd718xx->dev = &i2c->dev; + bd718xx->chip.dev = &i2c->dev; dev_set_drvdata(&i2c->dev, bd718xx); - bd718xx->regmap = devm_regmap_init_i2c(i2c, &bd718xx_regmap_config); - if (IS_ERR(bd718xx->regmap)) { + bd718xx->chip.regmap = devm_regmap_init_i2c(i2c, + &bd718xx_regmap_config); + if (IS_ERR(bd718xx->chip.regmap)) { dev_err(&i2c->dev, "regmap initialization failed\n"); - return PTR_ERR(bd718xx->regmap); + return PTR_ERR(bd718xx->chip.regmap); } - ret = devm_regmap_add_irq_chip(&i2c->dev, bd718xx->regmap, + ret = devm_regmap_add_irq_chip(&i2c->dev, bd718xx->chip.regmap, bd718xx->chip_irq, IRQF_ONESHOT, 0, &bd718xx_irq_chip, &bd718xx->irq_data); if (ret) { @@ -118,7 +119,7 @@ static int bd718xx_i2c_probe(struct i2c_client *i2c, } /* Configure short press to 10 milliseconds */ - ret = regmap_update_bits(bd718xx->regmap, + ret = regmap_update_bits(bd718xx->chip.regmap, BD718XX_REG_PWRONCONFIG0, BD718XX_PWRBTN_PRESS_DURATION_MASK, BD718XX_PWRBTN_SHORT_PRESS_10MS); @@ -129,7 +130,7 @@ static int bd718xx_i2c_probe(struct i2c_client *i2c, } /* Configure long press to 10 seconds */ - ret = regmap_update_bits(bd718xx->regmap, + ret = regmap_update_bits(bd718xx->chip.regmap, BD718XX_REG_PWRONCONFIG1, BD718XX_PWRBTN_PRESS_DURATION_MASK, BD718XX_PWRBTN_LONG_PRESS_10S); @@ -149,7 +150,7 @@ static int bd718xx_i2c_probe(struct i2c_client *i2c, button.irq = ret; - ret = devm_mfd_add_devices(bd718xx->dev, PLATFORM_DEVID_AUTO, + ret = devm_mfd_add_devices(bd718xx->chip.dev, PLATFORM_DEVID_AUTO, bd718xx_mfd_cells, ARRAY_SIZE(bd718xx_mfd_cells), NULL, 0, regmap_irq_get_domain(bd718xx->irq_data)); @@ -162,11 +163,11 @@ static int bd718xx_i2c_probe(struct i2c_client *i2c, static const struct of_device_id bd718xx_of_match[] = { { .compatible = "rohm,bd71837", - .data = (void *)BD718XX_TYPE_BD71837, + .data = (void *)ROHM_CHIP_TYPE_BD71837, }, { .compatible = "rohm,bd71847", - .data = (void *)BD718XX_TYPE_BD71847, + .data = (void *)ROHM_CHIP_TYPE_BD71847, }, { } }; diff --git a/include/linux/mfd/rohm-bd718x7.h b/include/linux/mfd/rohm-bd718x7.h index fd194bfc836f..7f2dbde402a1 100644 --- a/include/linux/mfd/rohm-bd718x7.h +++ b/include/linux/mfd/rohm-bd718x7.h @@ -4,14 +4,9 @@ #ifndef __LINUX_MFD_BD718XX_H__ #define __LINUX_MFD_BD718XX_H__ +#include #include -enum { - BD718XX_TYPE_BD71837 = 0, - BD718XX_TYPE_BD71847, - BD718XX_TYPE_AMOUNT -}; - enum { BD718XX_BUCK1 = 0, BD718XX_BUCK2, @@ -321,18 +316,17 @@ enum { BD718XX_PWRBTN_LONG_PRESS_15S }; -struct bd718xx_clk; - struct bd718xx { - unsigned int chip_type; - struct device *dev; - struct regmap *regmap; - unsigned long int id; + /* +* Please keep this as the first member here as some +* drivers (clk) supporting more than one chip may only know this +* generic struct 'struct rohm_regmap_dev' and assume it is +* the first chunk of parent device's private data. +*/ + struct rohm_regmap_dev chip; int chip_irq; struct regmap_irq_chip_data *irq_data; - - struct bd718xx_clk *clk; }; #endif /* __LINUX_MFD_BD718XX_H__ */ diff --
Re: [PATCH v2 10/14] arm64: dts: qcom: qcs404: Add OPP table
On 1/30/19 05:41, Vinod Koul wrote: > On 28-01-19, 19:32, Jorge Ramirez-Ortiz wrote: >> Add a CPU OPP table to qcs404 >> >> Co-developed-by: Niklas Cassel >> Signed-off-by: Niklas Cassel >> Signed-off-by: Jorge Ramirez-Ortiz >> --- >> arch/arm64/boot/dts/qcom/qcs404.dtsi | 15 +++ >> 1 file changed, 15 insertions(+) >> >> diff --git a/arch/arm64/boot/dts/qcom/qcs404.dtsi >> b/arch/arm64/boot/dts/qcom/qcs404.dtsi >> index 9b5c165..4594fea7 100644 >> --- a/arch/arm64/boot/dts/qcom/qcs404.dtsi >> +++ b/arch/arm64/boot/dts/qcom/qcs404.dtsi >> @@ -62,6 +62,21 @@ >> }; >> }; >> >> +cpu_opp_table: cpu_opp_table { > > This should be: > cpu_opp_table: cpu-opp-table yes. um I thought I fixed this ..sorry about it. > > IIRC node names are not supposed to have _ and tags not supposed to have > -, please compile with W=12 to trigger these warnings :) > >> +compatible = "operating-points-v2"; >> +opp-shared; >> + >> +opp-109440 { >> +opp-hz = /bits/ 64 <109440>; >> +}; >> +opp-124800 { >> +opp-hz = /bits/ 64 <124800>; >> +}; also need to remove the frequency below. I might have sent the wrong version of this file >> +opp-140160 { >> +opp-hz = /bits/ 64 <140160>; >> +}; >> +}; >> + >> firmware { >> scm: scm { >> compatible = "qcom,scm-qcs404", "qcom,scm"; >> -- >> 2.7.4 >
Re: [PATCH] mm/mincore: allow for making sys_mincore() privileged
On Wed 30-01-19 00:52:02, Jiri Kosina wrote: > On Mon, 28 Jan 2019, Dominique Martinet wrote: > > > > So, any objections to aproaching it this way? > > > > I'm not sure why I'm the main recipient of that mail but answering > > because I am -- let's get these patches in through the regular -mm tree > > though > > *prod to mm maintainers* (at least for an opinion) Could you repost those patches please? The thread is long and it is not really clear what is the most up-to-date state of patches (at least to me). -- Michal Hocko SUSE Labs
Re: [PATCH v2 3/3] dt-bindings: iio: chemical: pms7003: add device tree support
On Mon, Jan 28, 2019 at 07:43:33PM +0100, Tomasz Duszynski wrote: > On Mon, Jan 28, 2019 at 08:58:19AM +0100, Johan Hovold wrote: > > On Sun, Jan 27, 2019 at 07:19:16PM +0100, Tomasz Duszynski wrote: > > > Add device tree support for Plantower PMS7003 particulate matter sensor. > > > > > > Signed-off-by: Tomasz Duszynski > > > --- > > > .../iio/chemical/plantower,pms7003.txt| 19 +++ > > > 1 file changed, 19 insertions(+) > > > create mode 100644 > > > Documentation/devicetree/bindings/iio/chemical/plantower,pms7003.txt > > > > > > diff --git > > > a/Documentation/devicetree/bindings/iio/chemical/plantower,pms7003.txt > > > b/Documentation/devicetree/bindings/iio/chemical/plantower,pms7003.txt > > > new file mode 100644 > > > index ..e4c7f2fb1e30 > > > --- /dev/null > > > +++ b/Documentation/devicetree/bindings/iio/chemical/plantower,pms7003.txt > > > @@ -0,0 +1,19 @@ > > > +* Plantower PMS7003 particulate matter sensor > > > + > > > +Required properties: > > > +- compatible: must be "plantower,pms7003" > > > + > > > +Optional properties: > > > +- vcc-supply: phandle to the regulator that provides power to the sensor > > > > Shouldn't this one be a required property? > > > > Driver does not use regulator framework hence to me this property fits > here better. The device tree describes hardware, not any particular driver. That said, there is a bit of an on-going debate on whether mandatory supplies (from a hardware perspective) should always be represented in device tree or not. https://lore.kernel.org/lkml/20181123133126.gf2...@sirena.org.uk/T/#u https://lore.kernel.org/lkml/20180409102244.gb11...@sirena.org.uk/T/#u https://lore.kernel.org/lkml/20180425171123.xhyoay3nu463btoq@rob-hp-laptop/T/#u > > > +- set-gpios: phandle to the GPIO connected to the SET line > > > +- reset-gpios: phandle to the GPIO connected to the RESET line > > > + > > > +Refer to serial/slave-device.txt for generic serial attached device > > > bindings. > > > + > > > +Example: > > > + > > > +&uart0 { > > > + pms7003 { > > > > The node name should be generic and reflect the functionality rather > > than model. Perhaps "pms" will do here. > > Agree, ideally we should have a generic dt name for this kind of sensors > (something like air-pollution-sensor perhaps?). But unfortunately there isn't > anything available now so I guess compatible part name should be okay > (besides this is the type of naming commonly used in other iio bindings). What's wrong with particulate matter sensor ("pms")? Seems like a better fix than any particular model name to me at least. > > > + compatible = "plantower,pms7003"; > > > + }; > > > +}; Johan
Re: [PATCH 2/2] regulator: max77650: Convert to use regulator_enable/disable/is_enabled_regmap
Bartosz Golaszewski 於 2019年1月30日 週三 下午5:12寫道: > > śr., 30 sty 2019 o 10:07 Axel Lin napisał(a): > > > > By setting enable_reg, enable_mask, enable_val and disable_val, we can > > use the regulator_enable/disable/is_enabled_regmap helpers. With this > > change, then regB field can be removed from struct max77650_regulator_desc. > > > > Signed-off-by: Axel Lin > > --- > > Hi Bartosz, > > I don't have this h/w, please help to review and test it. > > > > I think the only difference is the is_enabled checking: > > Before the patch, it returns en != MAX77650_REGULATOR_DISABLED; > > After the patch, it returns en == MAX77650_REGULATOR_ENABLED > > I'm not sure if this difference does matter or not. > > > > NACK. I intend to support the FPS feature of the regulator module in > the future (see a similar thing in max77620) and I will need to extend > these callbacks as there will be more possible values here. Regmap > generics will not be enough. Got it, thanks for the quick review.
[GIT PULL] GPIO fixes for the v5.0 series, take two
Hi Linus, here is a bunch of GPIO fixes for the v5.0 series. I was helped out by Bartosz in collecting these fixes, for which I am very grateful, the biggest achievement in GPIO right now is work distribution. There is one serious core fix (timestamping) and a bunch of driver fixes. Please pull it in! Details in the signed tag. Yours, Linus Walleij The following changes since commit 49a57857aeea06ca831043acbb0fa5e0f50602fd: Linux 5.0-rc3 (2019-01-21 13:14:44 +1300) are available in the Git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git tags/gpio-v5.0-3 for you to fetch changes up to 7ae710f9f8b2cf95297e7bbfe1c09789a7dc43d4: gpio: vf610: Mask all GPIO interrupts (2019-01-28 15:28:43 +0100) GPIO fixes for the v5.0 series: - Fix timestamps on nested IRQs - Handle IRQs properly in multiple instances of PCF857x - Use the right data register and IRQ type setting in the Spreadtrum GPIO driver - Let the value argument work properly when setting direction in the Altera GPIO driver - Mask interrupts properly in the vf610 driver Andrew Lunn (1): gpio: vf610: Mask all GPIO interrupts Axel Lin (1): gpio: altera-a10sr: Set proper output level for direction_output Bartosz Golaszewski (1): gpiolib: fix line event timestamps for nested irqs Linus Walleij (1): Merge tag 'gpio-5.0-rc4-fixes-for-linus' of git://git.kernel.org/.../brgl/linux into fixes Neo Hou (2): gpio: sprd: Fix the incorrect data register gpio: sprd: Fix incorrect irq type setting for the async EIC Roger Quadros (1): gpio: pcf857x: Fix interrupts on multiple instances drivers/gpio/gpio-altera-a10sr.c | 4 +++- drivers/gpio/gpio-eic-sprd.c | 14 +- drivers/gpio/gpio-pcf857x.c | 26 -- drivers/gpio/gpio-vf610.c| 5 + drivers/gpio/gpiolib.c | 9 - 5 files changed, 41 insertions(+), 17 deletions(-)
Re: [PATCH 2/7] cpufreq: dt: Register an Energy Model
Hi Viresh, On Wednesday 30 Jan 2019 at 10:48:06 (+0530), Viresh Kumar wrote: > On 29-01-19, 09:15, Quentin Perret wrote: > > On Tuesday 29 Jan 2019 at 10:51:44 (+0530), Viresh Kumar wrote: > > > On 28-01-19, 11:36, Matthias Kaehlcke wrote: > > > > I think this patch will result in error messages at registration on > > > > platforms that use the cpufreq-dt driver and don't specify > > > > 'dynamic-power-coefficient' for the CPUs in the DT. Not sure if that's > > > > a problem as long as the cpufreq initialization succeeds regardless, > > > > it could be seen as a not-so-gentle nudge to add the values. > > > > > > That wouldn't be acceptable. > > > > Fair enough. What I can propose in this case is to have in PM_OPP a > > helper called 'dev_pm_opp_of_register_em()' or something like this. This > > function will check all prerequisites are present (we have the right > > values in DT, and so on) and then call (or not) em_register_perf_domain(). > > Then we can make the CPUFreq drivers use that instead of calling > > em_register_perf_domain() directly. > > That should be fine. > > > That would also make it easy to implement Matthias' suggestion to not > > call em_register_perf_domain() if an EM is already present. > > So you will track registration state within the OPP core for that ? What I had in mind is something as simple as: void of_dev_pm_opp_register_em(struct cpumask *cpus) { /* Bail out if an EM is there */ if (em_cpu_get(cpumask_first(cpus))) return; /* Check prerequisites: dpc coeff in DT, ... */ ... em_register_perf_domain(...); } IIUC, Matthias' point was that if the EM is already registered, there is no good reason to call em_register_perf_domain() again. Now, that should in fact be harmless because em_register_perf_domain() already does that check. It's just cleaner and easier to understand from a conceptual standpoint to not call that function several times for no reason I assume. > Sorry but that doesn't sound right. What's wrong with having an > unregister helper in energy-model to keep proper code flow everywhere > ? For the EM we basically allocate the tables in memory once and for all at boot time and never touch them again. That makes it easy for users (the scheduler as of now, IPA soon) to access them without messing around with RCU or so. So there isn't really a concept or unregistering a pd right now. Thanks, Quentin
[RFC PATCH v3 05/10] clk: bd718x7: Support ROHM BD70528 clk block
ROHM BD70528 is an ultra low power PMIC with similar 32K clk as bd718x7. Only difference (from clk perspective) is register address. Add support for controlling BD70528 clk using bd718x7 driver. Signed-off-by: Matti Vaittinen --- drivers/clk/Kconfig | 6 +++--- drivers/clk/clk-bd718x7.c | 21 + 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index e5b2fe80eab4..992cfb86f2ca 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -285,10 +285,10 @@ config COMMON_CLK_STM32H7 config COMMON_CLK_BD718XX tristate "Clock driver for ROHM BD718x7 PMIC" - depends on MFD_ROHM_BD718XX + depends on MFD_ROHM_BD718XX || MFD_ROHM_BD70528 help - This driver supports ROHM BD71837 and ROHM BD71847 - PMICs clock gates. + This driver supports ROHM BD71837, ROHM BD71847 and + ROHM BD70528 PMICs clock gates. source "drivers/clk/actions/Kconfig" source "drivers/clk/bcm/Kconfig" diff --git a/drivers/clk/clk-bd718x7.c b/drivers/clk/clk-bd718x7.c index 461228ebf703..41c1374f4217 100644 --- a/drivers/clk/clk-bd718x7.c +++ b/drivers/clk/clk-bd718x7.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -86,9 +87,21 @@ static int bd71837_clk_probe(struct platform_device *pdev) dev_err(&pdev->dev, "No parent clk found\n"); return -EINVAL; } - - c->reg = BD718XX_REG_OUT32K; - c->mask = BD718XX_OUT32K_EN; + switch (mfd->chip_type) { + case ROHM_CHIP_TYPE_BD71837: + case ROHM_CHIP_TYPE_BD71847: + + c->reg = BD718XX_REG_OUT32K; + c->mask = BD718XX_OUT32K_EN; + break; + case ROHM_CHIP_TYPE_BD70528: + c->reg = BD70528_REG_CLK_OUT; + c->mask = BD70528_CLK_OUT_EN_MASK; + break; + default: + dev_err(&pdev->dev, "Unknown clk chip\n"); + return -EINVAL; + } c->mfd = mfd; c->pdev = pdev; c->hw.init = &init; @@ -119,5 +132,5 @@ static struct platform_driver bd71837_clk = { module_platform_driver(bd71837_clk); MODULE_AUTHOR("Matti Vaittinen "); -MODULE_DESCRIPTION("BD71837/BD71847 chip clk driver"); +MODULE_DESCRIPTION("BD71837/BD71847/BD70528 chip clk driver"); MODULE_LICENSE("GPL"); -- 2.14.3 -- Matti Vaittinen ROHM Semiconductors Finland SWDC Kiviharjunlenkki 1E 90220 OULU FINLAND ~~~ "I don't think so," said Rene Descartes. Just then, he vanished ~~~
[RFC PATCH v3 03/10] clk: bd718x7: use chip specific and generic data structs
Header rohm-bd718x7.h was split to generic and component specific parts. This changed the struct bd718x7. Adapt the clk driver to these changes. Signed-off-by: Matti Vaittinen --- drivers/clk/clk-bd718x7.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/clk/clk-bd718x7.c b/drivers/clk/clk-bd718x7.c index 60422c72d142..461228ebf703 100644 --- a/drivers/clk/clk-bd718x7.c +++ b/drivers/clk/clk-bd718x7.c @@ -17,7 +17,7 @@ struct bd718xx_clk { u8 reg; u8 mask; struct platform_device *pdev; - struct bd718xx *mfd; + struct rohm_regmap_dev *mfd; }; static int bd71837_clk_set(struct clk_hw *hw, int status) @@ -68,7 +68,7 @@ static int bd71837_clk_probe(struct platform_device *pdev) int rval = -ENOMEM; const char *parent_clk; struct device *parent = pdev->dev.parent; - struct bd718xx *mfd = dev_get_drvdata(parent); + struct rohm_regmap_dev *mfd = dev_get_drvdata(parent); struct clk_init_data init = { .name = "bd718xx-32k-out", .ops = &bd71837_clk_ops, @@ -119,5 +119,5 @@ static struct platform_driver bd71837_clk = { module_platform_driver(bd71837_clk); MODULE_AUTHOR("Matti Vaittinen "); -MODULE_DESCRIPTION("BD71837 chip clk driver"); +MODULE_DESCRIPTION("BD71837/BD71847 chip clk driver"); MODULE_LICENSE("GPL"); -- 2.14.3 -- Matti Vaittinen ROHM Semiconductors Finland SWDC Kiviharjunlenkki 1E 90220 OULU FINLAND ~~~ "I don't think so," said Rene Descartes. Just then, he vanished ~~~
[PATCH v2 0/2] mm, memory_hotplug: fix uninitialized pages fallouts.
Hi, this is the second version of the series. v1 was posted [1]. There are no functional changes since v1. I have just fixed up the changelog of patch 1 which had a wrong trace (c&p mistake). I have also added tested-bys and reviewed-bys. Mikhail has posted fixes for the two bugs quite some time ago [2]. I have pushed back on those fixes because I believed that it is much better to plug the problem at the initialization time rather than play whack-a-mole all over the hotplug code and find all the places which expect the full memory section to be initialized. We have ended up with 2830bf6f05fb ("mm, memory_hotplug: initialize struct pages for the full memory section") merged and cause a regression [3][4]. The reason is that there might be memory layouts when two NUMA nodes share the same memory section so the merged fix is simply incorrect. In order to plug this hole we really have to be zone range aware in those handlers. I have split up the original patch into two. One is unchanged (patch 2) and I took a different approach for `removable' crash. It would be great if Mikhail could test it still works for his memory layout. [1] http://lkml.kernel.org/r/20190128144506.15603-1-mho...@kernel.org [2] http://lkml.kernel.org/r/20181105150401.97287-2-zaslo...@linux.ibm.com [3] https://bugzilla.redhat.com/show_bug.cgi?id=1666948 [4] http://lkml.kernel.org/r/20190125163938.ga20...@dhcp22.suse.cz
Re: [PATCH 1/2] regulator: max77650: Fix include files
śr., 30 sty 2019 o 10:07 Axel Lin napisał(a): > > This is a platform driver, no need to include linux/i2c.h. > Include linux/of.h for of_match_ptr. > > Signed-off-by: Axel Lin > --- > drivers/regulator/max77650-regulator.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/regulator/max77650-regulator.c > b/drivers/regulator/max77650-regulator.c > index 474f2c02f2d5..5afb91400832 100644 > --- a/drivers/regulator/max77650-regulator.c > +++ b/drivers/regulator/max77650-regulator.c > @@ -5,7 +5,7 @@ > // > // Regulator driver for MAXIM 77650/77651 charger/power-supply. > > -#include > +#include > #include > #include > #include > -- > 2.17.1 > Reviewed-by: Bartosz Golaszewski
[PATCH v2 2/2] mm, memory_hotplug: test_pages_in_a_zone do not pass the end of zone
From: Mikhail Zaslonko If memory end is not aligned with the sparse memory section boundary, the mapping of such a section is only partly initialized. This may lead to VM_BUG_ON due to uninitialized struct pages access from test_pages_in_a_zone() function triggered by memory_hotplug sysfs handlers. Here are the the panic examples: CONFIG_DEBUG_VM_PGFLAGS=y kernel parameter mem=2050M -- page:03d082008000 is uninitialized and poisoned page dumped because: VM_BUG_ON_PAGE(PagePoisoned(p)) Call Trace: ([<00385b26>] test_pages_in_a_zone+0xde/0x160) [<008f15c4>] show_valid_zones+0x5c/0x190 [<008cf9c4>] dev_attr_show+0x34/0x70 [<00463ad0>] sysfs_kf_seq_show+0xc8/0x148 [<003e4194>] seq_read+0x204/0x480 [<003b53ea>] __vfs_read+0x32/0x178 [<003b55b2>] vfs_read+0x82/0x138 [<003b5be2>] ksys_read+0x5a/0xb0 [<00b86ba0>] system_call+0xdc/0x2d8 Last Breaking-Event-Address: [<00385b26>] test_pages_in_a_zone+0xde/0x160 Kernel panic - not syncing: Fatal exception: panic_on_oops Fix this by checking whether the pfn to check is within the zone. [mho...@suse.com: separated this change from http://lkml.kernel.org/r/20181105150401.97287-2-zaslo...@linux.ibm.com] Reviewed-by: Oscar Salvador Tested-by: Gerald Schaefer Tested-by: Mikhail Gavrilov Signed-off-by: Mikhail Zaslonko Signed-off-by: Michal Hocko --- mm/memory_hotplug.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 07872789d778..7711d0e327b6 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -1274,6 +1274,9 @@ int test_pages_in_a_zone(unsigned long start_pfn, unsigned long end_pfn, i++; if (i == MAX_ORDER_NR_PAGES || pfn + i >= end_pfn) continue; + /* Check if we got outside of the zone */ + if (zone && !zone_spans_pfn(zone, pfn + i)) + return 0; page = pfn_to_page(pfn + i); if (zone && page_zone(page) != zone) return 0; -- 2.20.1
[RFC PATCH v3 09/10] power: supply: Initial support for ROHM BD70528 PMIC charger block
ROHM BD70528 PMIC includes battery charger block. Support charger staus queries and doing few basic settings like input current limit and charging current. Signed-off-by: Matti Vaittinen --- /* * BD70528 charger HW state machine. Should this be added to the c-file? * * The thermal shutdown state is not drawn. From any other state but * battery error and suspend it is possible to go to TSD/TMP states * if temperature is out of bounds. * * CHG_RST = H * or CHG_EN=L * or (DCIN2_UVLO=L && DCIN1_UVLO=L) * or (DCIN2_OVLO=H & DCIN1_UVKLO=L) * * +--+ +--+ * | | | | * | Any state +---> |Suspend | * | | | | * +--+ +--+---+ * | * CHG_EN = H && BAT_DET = H &&| * No errors (temp, bat_ov, UVLO, | * OVLO...)| * | * BAT_OV or +-v--+ * (DBAT && TTRI)|| * +-+ Trickle Charge | <---+ * | || | * | +---++ | * | | | * | | ^| * |V_BAT > VTRI_TH | | VBAT < VTRI_TH - 50mV | * | | || * | v || * | || * | BAT_OV or +--++ | * | (DBAT && TFST) | | | * | ++ Fast Charge | | * | || | | * v v++--+ | *| | *++ ILIM_DET=L |^ ILIM_DET| *|| & CV_DET=H || or CV_DET=L | *| Battery Error | & VBAT > || or VBAT < VRECHG_TH | *|| VRECHG_TH || or IBAT > IFST/x | *++ & IBAT < || | * IFST/x v| | * ^ | | * | +-+-+ | * | | | | * +---+ Top OFF | | * BAT_OV = H or| | | * (DBAT && TFST) +-+-+ | * | | * Stay top-off for 15s | | * v | * | *++ | *|| | *| Done +-+ *|| *++ VBAT < VRECHG_TH */ drivers/power/supply/Kconfig | 9 + drivers/power/supply/Makefile | 1 + drivers/power/supply/bd70528-charger.c | 676 + 3 files changed, 686 insertions(+) create mode 100644 drivers/power/supply/bd70528-charger.c diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig index e901b9879e7e..903c97a67bf0 100644 --- a/drivers/power/supply/Kconfig +++ b/drivers/power/supply/Kconfig @@ -660,4 +660,13 @@ config FUEL_GAUGE_SC27XX Say Y here to enable support for fuel gauge with SC27XX PMIC chips. +config CHARGER_BD70528 + tristate "ROHM bd70528 charger driver" + depends on MFD_ROHM_BD70528 + default n + help +Say Y here to enable support for getting battery status +information and altering charger configurations from charger +block of the ROHM BD70528 Power Management IC. + endif # POWER_SUPPLY diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile index b731c2a9b695..c60387b04bfa 100644 --- a/drivers/power/supply/Makefile +++ b/drivers/power/supply/Makefile @@ -87,3 +87,4 @@ obj-$(CONFIG_AXP288_CHARGER) += axp288_charger.o obj-$(CONFIG_CHARGER_CROS_USBPD) += cros_usbpd-charger.o obj-$(CONFIG_CHARGER_SC2731) += sc2731_charger.o obj-$(CONFIG_FUEL_GAUGE_SC27XX)+= sc27xx_fuel_gauge.o +obj-$(CONFIG_CHARGER_BD70528) += bd70528-charger.o diff --git a/drivers/power/supply/bd70528-charger.c b/drivers/power/supply/bd70528-charger.c new file mode 1
Re: [PATCH 6/7] MIPS: SGI-IP27: use generic PCI driver
On Tue, Jan 29, 2019 at 04:24:45PM +0100, Thomas Bogendoerfer wrote: > > From an abstraction point of view this doesn't really belong into > > a bridge driver as it is a global exported function. I guess we can > > keep it here with a fixme comment, but we should probably move this > > into a method call instead. > > or put the nodeid into the bus struct ? Doesn't sound to bad to me, you'll just have to update a fair amount of arch implementations. > I'm all for it. I looked at the examples for using dma_pfn_offset and the > only one coming close to usefull for me is arch/sh/drivers/pci/pcie-sh7786.c > It overloads pcibios_bus_add_device() to set dma_pfn_offset, which doesn't > look much nicer. What about having a dma_pfn_offset in struct pci_bus > which all device inherit from ? Or add a add_dev callback, similar to what I did for a previous series that we didn't end up needing after all: http://git.infradead.org/users/hch/misc.git/commitdiff/06d9b4fc7deed336edc1292fe2e661729e98ec39
[PATCH 6/6] arm64: dts: mt6358: add PMIC MT6358 related nodes
add PMIC MT6358 related nodes which is for MT8183 platform Signed-off-by: Hsin-Hsiung Wang --- arch/arm64/boot/dts/mediatek/mt6358.dtsi | 318 +++ 1 file changed, 318 insertions(+) create mode 100644 arch/arm64/boot/dts/mediatek/mt6358.dtsi diff --git a/arch/arm64/boot/dts/mediatek/mt6358.dtsi b/arch/arm64/boot/dts/mediatek/mt6358.dtsi new file mode 100644 index 000..a7c02ab --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt6358.dtsi @@ -0,0 +1,318 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright (c) 2019 MediaTek Inc. + */ + +&pwrap { + pmic: mt6358 { + compatible = "mediatek,mt6358"; + interrupt-controller; + interrupt-parent = <&pio>; + interrupts = <182 IRQ_TYPE_LEVEL_HIGH 190 0>; + #interrupt-cells = <2>; + + mt6358codec: mt6358codec { + compatible = "mediatek,mt6358-sound"; + }; + + mt6358regulator: mt6358regulator { + compatible = "mediatek,mt6358-regulator"; + + mt6358_vdram1_reg: buck_vdram1 { + regulator-compatible = "buck_vdram1"; + regulator-name = "vdram1"; + regulator-min-microvolt = <50>; + regulator-max-microvolt = <2087500>; + regulator-ramp-delay = <12500>; + regulator-enable-ramp-delay = <0>; + regulator-always-on; + regulator-allowed-modes = <0 1>; + }; + mt6358_vcore_reg: buck_vcore { + regulator-name = "vcore"; + regulator-min-microvolt = <50>; + regulator-max-microvolt = <1293750>; + regulator-ramp-delay = <6250>; + regulator-enable-ramp-delay = <200>; + regulator-always-on; + regulator-allowed-modes = <0 1>; + }; + mt6358_vpa_reg: buck_vpa { + regulator-name = "vpa"; + regulator-min-microvolt = <50>; + regulator-max-microvolt = <365>; + regulator-ramp-delay = <5>; + regulator-enable-ramp-delay = <250>; + regulator-allowed-modes = <0 1>; + }; + mt6358_vproc11_reg: buck_vproc11 { + regulator-name = "vproc11"; + regulator-min-microvolt = <50>; + regulator-max-microvolt = <1293750>; + regulator-ramp-delay = <6250>; + regulator-enable-ramp-delay = <200>; + regulator-always-on; + regulator-allowed-modes = <0 1>; + }; + mt6358_vproc12_reg: buck_vproc12 { + regulator-name = "vproc12"; + regulator-min-microvolt = <50>; + regulator-max-microvolt = <1293750>; + regulator-ramp-delay = <6250>; + regulator-enable-ramp-delay = <200>; + regulator-always-on; + regulator-allowed-modes = <0 1>; + }; + mt6358_vgpu_reg: buck_vgpu { + regulator-name = "vgpu"; + regulator-min-microvolt = <50>; + regulator-max-microvolt = <1293750>; + regulator-ramp-delay = <6250>; + regulator-enable-ramp-delay = <200>; + regulator-allowed-modes = <0 1>; + }; + mt6358_vs2_reg: buck_vs2 { + regulator-name = "vs2"; + regulator-min-microvolt = <50>; + regulator-max-microvolt = <2087500>; + regulator-ramp-delay = <12500>; + regulator-enable-ramp-delay = <0>; + regulator-always-on; + }; + mt6358_vmodem_reg: buck_vmodem { + regulator-name = "vmodem"; + regulator-min-microvolt = <50>; + regulator-max-microvolt = <1293750>; + regulator-ramp-delay = <625
[PATCH 3/6] regulator: Add document for MT6358 regulator
add dt-binding document for MediaTek MT6358 PMIC Signed-off-by: Hsin-Hsiung Wang --- .../bindings/regulator/mt6358-regulator.txt| 318 + 1 file changed, 318 insertions(+) create mode 100644 Documentation/devicetree/bindings/regulator/mt6358-regulator.txt diff --git a/Documentation/devicetree/bindings/regulator/mt6358-regulator.txt b/Documentation/devicetree/bindings/regulator/mt6358-regulator.txt new file mode 100644 index 000..3ea8073 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/mt6358-regulator.txt @@ -0,0 +1,318 @@ +Mediatek MT6358 Regulator + +Required properties: +- compatible: "mediatek,mt6358-regulator" +- mt6358regulator: List of regulators provided by this controller. It is named + according to its regulator type, buck_ and ldo_. + The definition for each of these nodes is defined using the standard binding + for regulators at Documentation/devicetree/bindings/regulator/regulator.txt. + +The valid names for regulators are:: +BUCK: + buck_vdram1, buck_vcore, buck_vpa, buck_vproc11, buck_vproc12, buck_vgpu, + buck_vs2, buck_vmodem, buck_vs1 +LDO: + ldo_vdram2, ldo_vsim1, ldo_vibr, ldo_vrf12, ldo_vio18, ldo_vusb, ldo_vcamio, + ldo_vcamd, ldo_vcn18, ldo_vfe28, ldo_vsram_proc11, ldo_vcn28, ldo_vsram_others, + ldo_vsram_gpu, ldo_vxo22, ldo_vefuse, ldo_vaux18, ldo_vmch, ldo_vbif28, + ldo_vsram_proc12, ldo_vcama1, ldo_vemc, ldo_vio28, ldo_va12, ldo_vrf18, + ldo_vcn33_bt, ldo_vcn33_wifi, ldo_vcama2, ldo_vmc, ldo_vldo28, ldo_vaud28, + ldo_vsim2 + +Example: + pmic { + compatible = "mediatek,mt6358"; + + mt6358regulator: mt6358regulator { + compatible = "mediatek,mt6358-regulator"; + + mt6358_vdram1_reg: buck_vdram1 { + regulator-compatible = "buck_vdram1"; + regulator-name = "vdram1"; + regulator-min-microvolt = <50>; + regulator-max-microvolt = <2087500>; + regulator-ramp-delay = <12500>; + regulator-enable-ramp-delay = <0>; + regulator-always-on; + }; + mt6358_vcore_reg: buck_vcore { + regulator-name = "vcore"; + regulator-min-microvolt = <50>; + regulator-max-microvolt = <1293750>; + regulator-ramp-delay = <6250>; + regulator-enable-ramp-delay = <200>; + regulator-always-on; + }; + mt6358_vpa_reg: buck_vpa { + regulator-name = "vpa"; + regulator-min-microvolt = <50>; + regulator-max-microvolt = <365>; + regulator-ramp-delay = <5>; + regulator-enable-ramp-delay = <250>; + }; + mt6358_vproc11_reg: buck_vproc11 { + regulator-name = "vproc11"; + regulator-min-microvolt = <50>; + regulator-max-microvolt = <1293750>; + regulator-ramp-delay = <6250>; + regulator-enable-ramp-delay = <200>; + regulator-always-on; + }; + mt6358_vproc12_reg: buck_vproc12 { + regulator-name = "vproc12"; + regulator-min-microvolt = <50>; + regulator-max-microvolt = <1293750>; + regulator-ramp-delay = <6250>; + regulator-enable-ramp-delay = <200>; + regulator-always-on; + }; + mt6358_vgpu_reg: buck_vgpu { + regulator-name = "vgpu"; + regulator-min-microvolt = <50>; + regulator-max-microvolt = <1293750>; + regulator-ramp-delay = <6250>; + regulator-enable-ramp-delay = <200>; + }; + mt6358_vs2_reg: buck_vs2 { + regulator-name = "vs2"; + regulator-min-microvolt = <50>; + regulator-max-microvolt = <2087500>; + regulator-ramp-delay = <12500>; + regulator-enable-ramp-delay = <0>; + regulator-always-on; + }; + mt6358_vmodem_reg: buck_vmodem { +
[PATCH 2/6] dt-bindings: mfd: Add compatible for the MediaTek MT6358 PMIC
This adds compatible for the MediaTek MT6358 PMIC. Signed-off-by: Hsin-Hsiung Wang --- Documentation/devicetree/bindings/mfd/mt6397.txt | 9 +++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/mfd/mt6397.txt b/Documentation/devicetree/bindings/mfd/mt6397.txt index 0ebd08a..6d20321 100644 --- a/Documentation/devicetree/bindings/mfd/mt6397.txt +++ b/Documentation/devicetree/bindings/mfd/mt6397.txt @@ -17,7 +17,10 @@ Documentation/devicetree/bindings/soc/mediatek/pwrap.txt This document describes the binding for MFD device and its sub module. Required properties: -compatible: "mediatek,mt6397" or "mediatek,mt6323" +compatible: + "mediatek,mt6323" for PMIC MT6323 + "mediatek,mt6358" for PMIC MT6358 + "mediatek,mt6397" for PMIC MT6397 Optional subnodes: @@ -28,11 +31,13 @@ Optional subnodes: Required properties: - compatible: "mediatek,mt6397-regulator" see Documentation/devicetree/bindings/regulator/mt6397-regulator.txt + - compatible: "mediatek,mt6358-regulator" + see Documentation/devicetree/bindings/regulator/mt6358-regulator.txt - compatible: "mediatek,mt6323-regulator" see Documentation/devicetree/bindings/regulator/mt6323-regulator.txt - codec Required properties: - - compatible: "mediatek,mt6397-codec" + - compatible: "mediatek,mt6397-codec" or "mediatek,mt6358-sound" - clk Required properties: - compatible: "mediatek,mt6397-clk" -- 1.9.1
[PATCH 5/6] regulator: mt6358: Add support for MT6358 regulator
The MT6358 is a regulator found on boards based on MediaTek MT8183 and probably other SoCs. It is a so called pmic and connects as a slave to SoC using SPI, wrapped inside the pmic-wrapper. Signed-off-by: Hsin-Hsiung Wang --- drivers/regulator/Kconfig | 9 + drivers/regulator/Makefile | 1 + drivers/regulator/mt6358-regulator.c | 607 + include/linux/regulator/mt6358-regulator.h | 56 +++ 4 files changed, 673 insertions(+) create mode 100644 drivers/regulator/mt6358-regulator.c create mode 100644 include/linux/regulator/mt6358-regulator.h diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index ee60a22..5a6006e 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -596,6 +596,15 @@ config REGULATOR_MT6323 This driver supports the control of different power rails of device through regulator interface. +config REGULATOR_MT6358 + tristate "MediaTek MT6358 PMIC" + depends on MFD_MT6397 + help + Say y here to select this option to enable the power regulator of + MediaTek MT6358 PMIC. + This driver supports the control of different power rails of device + through regulator interface. + config REGULATOR_MT6380 tristate "MediaTek MT6380 PMIC" depends on MTK_PMIC_WRAP diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index b12e1c9..4681425 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -77,6 +77,7 @@ obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o obj-$(CONFIG_REGULATOR_MCP16502) += mcp16502.o obj-$(CONFIG_REGULATOR_MT6311) += mt6311-regulator.o obj-$(CONFIG_REGULATOR_MT6323) += mt6323-regulator.o +obj-$(CONFIG_REGULATOR_MT6358) += mt6358-regulator.o obj-$(CONFIG_REGULATOR_MT6380) += mt6380-regulator.o obj-$(CONFIG_REGULATOR_MT6397) += mt6397-regulator.o obj-$(CONFIG_REGULATOR_QCOM_RPM) += qcom_rpm-regulator.o diff --git a/drivers/regulator/mt6358-regulator.c b/drivers/regulator/mt6358-regulator.c new file mode 100644 index 000..4c86665 --- /dev/null +++ b/drivers/regulator/mt6358-regulator.c @@ -0,0 +1,607 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (c) 2019 MediaTek Inc. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MT6358_BUCK_MODE_AUTO 0 +#define MT6358_BUCK_MODE_FORCE_PWM 1 + +/* + * MT6358 regulators' information + * + * @desc: standard fields of regulator description. + * @qi: Mask for query enable signal status of regulators + */ +struct mt6358_regulator_info { + struct regulator_desc desc; + u32 status_reg; + u32 qi; + const u32 *index_table; + unsigned int n_table; + u32 vsel_shift; + u32 da_vsel_reg; + u32 da_vsel_mask; + u32 da_vsel_shift; + u32 modeset_reg; + u32 modeset_mask; + u32 modeset_shift; +}; + +#define MT6358_BUCK(match, vreg, min, max, step, \ + volt_ranges, vosel_mask, _da_vsel_reg, _da_vsel_mask, \ + _da_vsel_shift, _modeset_reg, _modeset_shift) \ +[MT6358_ID_##vreg] = { \ + .desc = { \ + .name = #vreg, \ + .of_match = of_match_ptr(match),\ + .ops = &mt6358_volt_range_ops, \ + .type = REGULATOR_VOLTAGE, \ + .id = MT6358_ID_##vreg, \ + .owner = THIS_MODULE, \ + .n_voltages = ((max) - (min)) / (step) + 1, \ + .linear_ranges = volt_ranges, \ + .n_linear_ranges = ARRAY_SIZE(volt_ranges), \ + .vsel_reg = MT6358_BUCK_##vreg##_ELR0, \ + .vsel_mask = vosel_mask,\ + .enable_reg = MT6358_BUCK_##vreg##_CON0,\ + .enable_mask = BIT(0), \ + .of_map_mode = mt6358_map_mode, \ + }, \ + .status_reg = MT6358_BUCK_##vreg##_DBG1,\ + .qi = BIT(0), \ + .da_vsel_reg = _da_vsel_reg,\ + .da_vsel_mask = _da_vsel_mask, \ + .da_vsel_shift = _da_vsel_shift,\ + .modeset_reg = _modeset_reg,\ + .modeset_mask = BIT(_modeset_shift),\ + .modeset_shift = _modeset_shift \ +} + +#define MT6358_LDO(match, vreg, ldo_volt_table,\ + ldo_index_table, enreg, enbit, vosel, \ + vosel_mask, vosel_shift)\ +[MT6358_ID_##vreg] = { \ + .desc = { \ + .name = #vreg, \ + .of_match = of_match_ptr(match),\ + .ops = &mt6358_volt_table_ops, \ + .type = REGULATOR_VOLTAGE, \ + .id = MT6358_ID_##vreg, \ + .owner = THIS_MODULE, \ + .n_voltages = ARRAY_SIZE(ldo_volt_table), \ + .volt_table = ldo_volt_table, \ + .vsel_reg = vo
[PATCH 4/6] mfd: Add support for the MediaTek MT6358 PMIC
This adds support for the MediaTek MT6358 PMIC. This is a multifunction device with the following sub modules: - Regulator - RTC - Codec - Interrupt It is interfaced to the host controller using SPI interface by a proprietary hardware called PMIC wrapper or pwrap. MT6358 MFD is a child device of the pwrap. Signed-off-by: Hsin-Hsiung Wang --- drivers/mfd/Makefile |2 +- drivers/mfd/mt6358-irq.c | 236 + drivers/mfd/mt6397-core.c| 62 +- include/linux/mfd/mt6358/core.h | 158 +++ include/linux/mfd/mt6358/registers.h | 1926 ++ include/linux/mfd/mt6397/core.h |3 + 6 files changed, 2385 insertions(+), 2 deletions(-) create mode 100644 drivers/mfd/mt6358-irq.c create mode 100644 include/linux/mfd/mt6358/core.h create mode 100644 include/linux/mfd/mt6358/registers.h diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 088e249..50be021 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -230,7 +230,7 @@ obj-$(CONFIG_INTEL_SOC_PMIC)+= intel-soc-pmic.o obj-$(CONFIG_INTEL_SOC_PMIC_BXTWC) += intel_soc_pmic_bxtwc.o obj-$(CONFIG_INTEL_SOC_PMIC_CHTWC) += intel_soc_pmic_chtwc.o obj-$(CONFIG_INTEL_SOC_PMIC_CHTDC_TI) += intel_soc_pmic_chtdc_ti.o -obj-$(CONFIG_MFD_MT6397) += mt6397-core.o mt6397-irq.o +obj-$(CONFIG_MFD_MT6397) += mt6397-core.o mt6397-irq.o mt6358-irq.o obj-$(CONFIG_MFD_ALTERA_A10SR) += altera-a10sr.o obj-$(CONFIG_MFD_SUN4I_GPADC) += sun4i-gpadc.o diff --git a/drivers/mfd/mt6358-irq.c b/drivers/mfd/mt6358-irq.c new file mode 100644 index 000..b29fdc1 --- /dev/null +++ b/drivers/mfd/mt6358-irq.c @@ -0,0 +1,236 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (c) 2019 MediaTek Inc. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct irq_top_t mt6358_ints[] = { + MT6358_TOP_GEN(BUCK), + MT6358_TOP_GEN(LDO), + MT6358_TOP_GEN(PSC), + MT6358_TOP_GEN(SCK), + MT6358_TOP_GEN(BM), + MT6358_TOP_GEN(HK), + MT6358_TOP_GEN(AUD), + MT6358_TOP_GEN(MISC), +}; + +static int parsing_hwirq_to_top_group(unsigned int hwirq) +{ + int top_group; + + for (top_group = 1; top_group < ARRAY_SIZE(mt6358_ints); top_group++) { + if (mt6358_ints[top_group].hwirq_base > hwirq) { + top_group--; + break; + } + } + return top_group; +} + +static void pmic_irq_enable(struct irq_data *data) +{ + unsigned int hwirq = irqd_to_hwirq(data); + struct mt6397_chip *chip = irq_data_get_irq_chip_data(data); + struct pmic_irq_data *irq_data = chip->irq_data; + + irq_data->enable_hwirq[hwirq] = 1; +} + +static void pmic_irq_disable(struct irq_data *data) +{ + unsigned int hwirq = irqd_to_hwirq(data); + struct mt6397_chip *chip = irq_data_get_irq_chip_data(data); + struct pmic_irq_data *irq_data = chip->irq_data; + + irq_data->enable_hwirq[hwirq] = 0; +} + +static void pmic_irq_lock(struct irq_data *data) +{ + struct mt6397_chip *chip = irq_data_get_irq_chip_data(data); + + mutex_lock(&chip->irqlock); +} + +static void pmic_irq_sync_unlock(struct irq_data *data) +{ + unsigned int i, top_gp, en_reg, int_regs, shift; + struct mt6397_chip *chip = irq_data_get_irq_chip_data(data); + struct pmic_irq_data *irq_data = chip->irq_data; + + for (i = 0; i < irq_data->num_pmic_irqs; i++) { + if (irq_data->enable_hwirq[i] == + irq_data->cache_hwirq[i]) + continue; + + top_gp = parsing_hwirq_to_top_group(i); + int_regs = mt6358_ints[top_gp].num_int_bits / MT6358_REG_WIDTH; + en_reg = mt6358_ints[top_gp].en_reg + + mt6358_ints[top_gp].en_reg_shift * int_regs; + shift = (i - mt6358_ints[top_gp].hwirq_base) % MT6358_REG_WIDTH; + regmap_update_bits(chip->regmap, en_reg, 0x1 << shift, + irq_data->enable_hwirq[i] << shift); + irq_data->cache_hwirq[i] = irq_data->enable_hwirq[i]; + } + mutex_unlock(&chip->irqlock); +} + +static int pmic_irq_set_type(struct irq_data *data, unsigned int type) +{ + return 0; +} + +static struct irq_chip mt6358_irq_chip = { + .name = "mt6358-irq", + .irq_enable = pmic_irq_enable, + .irq_disable = pmic_irq_disable, + .irq_bus_lock = pmic_irq_lock, + .irq_bus_sync_unlock = pmic_irq_sync_unlock, + .irq_set_type = pmic_irq_set_type, +}; + +static void mt6358_irq_sp_handler(struct mt6397_chip *chip, + unsigned int top_gp) +{ + unsigned int sta_reg, int_status = 0; + unsigned int hwirq, virq; + int ret, i, j; + + for (i = 0; i < mt6358_ints[top_gp].num_int_regs; i++) {
[PATCH 0/6] Add Support for MediaTek PMIC MT6358 MFD Core and Regulator
This patchset including refactoring interrupt add support to MT6358 PMIC. MT6358 is the primary PMIC for MT8183 platform. Hsin-Hsiung Wang (6): mfd: mt6397: extract irq related code from core driver dt-bindings: mfd: Add compatible for the MediaTek MT6358 PMIC regulator: Add document for MT6358 regulator mfd: Add support for the MediaTek MT6358 PMIC regulator: mt6358: Add support for MT6358 regulator arm64: dts: mt6358: add PMIC MT6358 related nodes Documentation/devicetree/bindings/mfd/mt6397.txt |9 +- .../bindings/regulator/mt6358-regulator.txt| 318 arch/arm64/boot/dts/mediatek/mt6358.dtsi | 318 drivers/mfd/Makefile |2 +- drivers/mfd/mt6358-irq.c | 236 +++ drivers/mfd/mt6397-core.c | 291 +-- drivers/mfd/mt6397-irq.c | 214 +++ drivers/regulator/Kconfig |9 + drivers/regulator/Makefile |1 + drivers/regulator/mt6358-regulator.c | 607 ++ include/linux/mfd/mt6358/core.h| 158 ++ include/linux/mfd/mt6358/registers.h | 1926 include/linux/mfd/mt6397/core.h| 15 + include/linux/regulator/mt6358-regulator.h | 56 + 14 files changed, 3962 insertions(+), 198 deletions(-) create mode 100644 Documentation/devicetree/bindings/regulator/mt6358-regulator.txt create mode 100644 arch/arm64/boot/dts/mediatek/mt6358.dtsi create mode 100644 drivers/mfd/mt6358-irq.c create mode 100644 drivers/mfd/mt6397-irq.c create mode 100644 drivers/regulator/mt6358-regulator.c create mode 100644 include/linux/mfd/mt6358/core.h create mode 100644 include/linux/mfd/mt6358/registers.h create mode 100644 include/linux/regulator/mt6358-regulator.h -- 1.9.1