Re: [PATCH v4 5/5] misc: pci_endpoint_test: Handle 64-bit BARs properly
On Thursday 08 March 2018 07:03 PM, Niklas Cassel wrote: > A 64-bit BAR consists of a BAR pair, where the second BAR has the > upper bits, so we cannot simply call pci_ioremap_bar() on every single > BAR index. > > The second BAR in a BAR pair will not have the IORESOURCE_MEM resource > flag set. Only call ioremap on BARs that have the IORESOURCE_MEM > resource flag set. > > pci :01:00.0: BAR 4: assigned [mem 0xc030-0xc031 64bit] > pci :01:00.0: BAR 2: assigned [mem 0xc032-0xc03203ff 64bit] > pci :01:00.0: BAR 0: assigned [mem 0xc0320400-0xc03204ff 64bit] > pci-endpoint-test :01:00.0: can't ioremap BAR 1: [??? 0x flags > 0x0] > pci-endpoint-test :01:00.0: failed to read BAR1 > pci-endpoint-test :01:00.0: can't ioremap BAR 3: [??? 0x flags > 0x0] > pci-endpoint-test :01:00.0: failed to read BAR3 > pci-endpoint-test :01:00.0: can't ioremap BAR 5: [??? 0x flags > 0x0] > pci-endpoint-test :01:00.0: failed to read BAR5 > > Signed-off-by: Niklas CasselAcked-by: Kishon Vijay Abraham I > --- > drivers/misc/pci_endpoint_test.c | 12 +++- > 1 file changed, 7 insertions(+), 5 deletions(-) > > diff --git a/drivers/misc/pci_endpoint_test.c > b/drivers/misc/pci_endpoint_test.c > index 320276f42653..fe8897e64635 100644 > --- a/drivers/misc/pci_endpoint_test.c > +++ b/drivers/misc/pci_endpoint_test.c > @@ -534,12 +534,14 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev, > } > > for (bar = BAR_0; bar <= BAR_5; bar++) { > - base = pci_ioremap_bar(pdev, bar); > - if (!base) { > - dev_err(dev, "failed to read BAR%d\n", bar); > - WARN_ON(bar == test_reg_bar); > + if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM) { > + base = pci_ioremap_bar(pdev, bar); > + if (!base) { > + dev_err(dev, "failed to read BAR%d\n", bar); > + WARN_ON(bar == test_reg_bar); > + } > + test->bar[bar] = base; > } > - test->bar[bar] = base; > } > > test->base = test->bar[test_reg_bar]; >
Re: [PATCH v4 5/5] misc: pci_endpoint_test: Handle 64-bit BARs properly
On Thursday 08 March 2018 07:03 PM, Niklas Cassel wrote: > A 64-bit BAR consists of a BAR pair, where the second BAR has the > upper bits, so we cannot simply call pci_ioremap_bar() on every single > BAR index. > > The second BAR in a BAR pair will not have the IORESOURCE_MEM resource > flag set. Only call ioremap on BARs that have the IORESOURCE_MEM > resource flag set. > > pci :01:00.0: BAR 4: assigned [mem 0xc030-0xc031 64bit] > pci :01:00.0: BAR 2: assigned [mem 0xc032-0xc03203ff 64bit] > pci :01:00.0: BAR 0: assigned [mem 0xc0320400-0xc03204ff 64bit] > pci-endpoint-test :01:00.0: can't ioremap BAR 1: [??? 0x flags > 0x0] > pci-endpoint-test :01:00.0: failed to read BAR1 > pci-endpoint-test :01:00.0: can't ioremap BAR 3: [??? 0x flags > 0x0] > pci-endpoint-test :01:00.0: failed to read BAR3 > pci-endpoint-test :01:00.0: can't ioremap BAR 5: [??? 0x flags > 0x0] > pci-endpoint-test :01:00.0: failed to read BAR5 > > Signed-off-by: Niklas Cassel Acked-by: Kishon Vijay Abraham I > --- > drivers/misc/pci_endpoint_test.c | 12 +++- > 1 file changed, 7 insertions(+), 5 deletions(-) > > diff --git a/drivers/misc/pci_endpoint_test.c > b/drivers/misc/pci_endpoint_test.c > index 320276f42653..fe8897e64635 100644 > --- a/drivers/misc/pci_endpoint_test.c > +++ b/drivers/misc/pci_endpoint_test.c > @@ -534,12 +534,14 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev, > } > > for (bar = BAR_0; bar <= BAR_5; bar++) { > - base = pci_ioremap_bar(pdev, bar); > - if (!base) { > - dev_err(dev, "failed to read BAR%d\n", bar); > - WARN_ON(bar == test_reg_bar); > + if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM) { > + base = pci_ioremap_bar(pdev, bar); > + if (!base) { > + dev_err(dev, "failed to read BAR%d\n", bar); > + WARN_ON(bar == test_reg_bar); > + } > + test->bar[bar] = base; > } > - test->bar[bar] = base; > } > > test->base = test->bar[test_reg_bar]; >
Re: [PATCH v4 3/5] PCI: designware-ep: Make dw_pcie_ep_reset_bar() handle 64-bit BARs properly
Hi Niklas, On Thursday 08 March 2018 07:03 PM, Niklas Cassel wrote: > Since a 64-bit BAR consists of a BAR pair, we need to write to both > BARs in the BAR pair to clear the BAR properly. > > Signed-off-by: Niklas Cassel> --- > drivers/pci/dwc/pcie-designware-ep.c | 7 +++ > 1 file changed, 7 insertions(+) > > diff --git a/drivers/pci/dwc/pcie-designware-ep.c > b/drivers/pci/dwc/pcie-designware-ep.c > index 946bbdf53c4d..b20b2651caf9 100644 > --- a/drivers/pci/dwc/pcie-designware-ep.c > +++ b/drivers/pci/dwc/pcie-designware-ep.c > @@ -22,11 +22,18 @@ void dw_pcie_ep_linkup(struct dw_pcie_ep *ep) > void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar) > { > u32 reg; > + u32 val; > > reg = PCI_BASE_ADDRESS_0 + (4 * bar); > + val = dw_pcie_readl_dbi(pci, reg); > dw_pcie_dbi_ro_wr_en(pci); > dw_pcie_writel_dbi2(pci, reg, 0x0); > dw_pcie_writel_dbi(pci, reg, 0x0); > + if (!(val & PCI_BASE_ADDRESS_SPACE_IO) && > + (val & PCI_BASE_ADDRESS_MEM_TYPE_64)) { > + dw_pcie_writel_dbi2(pci, reg + 4, 0x0); > + dw_pcie_writel_dbi(pci, reg + 4, 0x0); > + } same comment as previous patch apply here too. Thanks Kishon
Re: [PATCH v4 3/5] PCI: designware-ep: Make dw_pcie_ep_reset_bar() handle 64-bit BARs properly
Hi Niklas, On Thursday 08 March 2018 07:03 PM, Niklas Cassel wrote: > Since a 64-bit BAR consists of a BAR pair, we need to write to both > BARs in the BAR pair to clear the BAR properly. > > Signed-off-by: Niklas Cassel > --- > drivers/pci/dwc/pcie-designware-ep.c | 7 +++ > 1 file changed, 7 insertions(+) > > diff --git a/drivers/pci/dwc/pcie-designware-ep.c > b/drivers/pci/dwc/pcie-designware-ep.c > index 946bbdf53c4d..b20b2651caf9 100644 > --- a/drivers/pci/dwc/pcie-designware-ep.c > +++ b/drivers/pci/dwc/pcie-designware-ep.c > @@ -22,11 +22,18 @@ void dw_pcie_ep_linkup(struct dw_pcie_ep *ep) > void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar) > { > u32 reg; > + u32 val; > > reg = PCI_BASE_ADDRESS_0 + (4 * bar); > + val = dw_pcie_readl_dbi(pci, reg); > dw_pcie_dbi_ro_wr_en(pci); > dw_pcie_writel_dbi2(pci, reg, 0x0); > dw_pcie_writel_dbi(pci, reg, 0x0); > + if (!(val & PCI_BASE_ADDRESS_SPACE_IO) && > + (val & PCI_BASE_ADDRESS_MEM_TYPE_64)) { > + dw_pcie_writel_dbi2(pci, reg + 4, 0x0); > + dw_pcie_writel_dbi(pci, reg + 4, 0x0); > + } same comment as previous patch apply here too. Thanks Kishon
Re: [PATCH 2/3] i2c: mux: pca9541: namespace cleanup
On 2018-03-21 00:24, Vladimir Zapolskiy wrote: > Hi Peter, > > On 03/20/2018 11:31 AM, Peter Rosin wrote: >> In preparation for PCA9641 support, convert the mybus and busoff macros >> to functions, and in the process prefix them with pca9541_. Also prefix >> remaining chip specific macros with PCA9541_. >> >> Signed-off-by: Peter Rosin>> --- >> drivers/i2c/muxes/i2c-mux-pca9541.c | 26 +++--- >> 1 file changed, 19 insertions(+), 7 deletions(-) >> >> diff --git a/drivers/i2c/muxes/i2c-mux-pca9541.c >> b/drivers/i2c/muxes/i2c-mux-pca9541.c >> index ad168125d23d..47685eb4e0e9 100644 >> --- a/drivers/i2c/muxes/i2c-mux-pca9541.c >> +++ b/drivers/i2c/muxes/i2c-mux-pca9541.c >> @@ -59,10 +59,8 @@ >> #define PCA9541_ISTAT_MYTESTBIT(6) >> #define PCA9541_ISTAT_NMYTEST BIT(7) >> >> -#define BUSON (PCA9541_CTL_BUSON | PCA9541_CTL_NBUSON) >> -#define MYBUS (PCA9541_CTL_MYBUS | PCA9541_CTL_NMYBUS) >> -#define mybus(x)(!((x) & MYBUS) || ((x) & MYBUS) == MYBUS) >> -#define busoff(x) (!((x) & BUSON) || ((x) & BUSON) == BUSON) >> +#define PCA9541_BUSON (PCA9541_CTL_BUSON | PCA9541_CTL_NBUSON) >> +#define PCA9541_MYBUS (PCA9541_CTL_MYBUS | PCA9541_CTL_NMYBUS) >> >> /* arbitration timeouts, in jiffies */ >> #define ARB_TIMEOUT (HZ / 8)/* 125 ms until forcing bus ownership */ >> @@ -93,6 +91,20 @@ static const struct of_device_id pca9541_of_match[] = { >> MODULE_DEVICE_TABLE(of, pca9541_of_match); >> #endif >> >> +static int pca9541_mybus(int ctl) > > static inline? No, "inline" is only used in header files in the kernel. The compiler is free to inline whatever function it likes anyway, and in this case we do not know better than the compiler. We don't care either. At least, that is my understanding of the situation regarding the "inline" keyword. > >> +{ >> +if (!(ctl & PCA9541_MYBUS)) >> +return 1; >> +return (ctl & PCA9541_MYBUS) == PCA9541_MYBUS; >> +} >> + >> +static int pca9541_busoff(int ctl) > > static inline? > >> +{ >> +if (!(ctl & PCA9541_BUSON)) >> +return 1; >> +return (ctl & PCA9541_BUSON) == PCA9541_BUSON; >> +} > > Reviewed-by: Vladimir Zapolskiy Thanks! Cheers, Peter > > -- > With best wishes, > Vladimir >
Re: [PATCH 2/3] i2c: mux: pca9541: namespace cleanup
On 2018-03-21 00:24, Vladimir Zapolskiy wrote: > Hi Peter, > > On 03/20/2018 11:31 AM, Peter Rosin wrote: >> In preparation for PCA9641 support, convert the mybus and busoff macros >> to functions, and in the process prefix them with pca9541_. Also prefix >> remaining chip specific macros with PCA9541_. >> >> Signed-off-by: Peter Rosin >> --- >> drivers/i2c/muxes/i2c-mux-pca9541.c | 26 +++--- >> 1 file changed, 19 insertions(+), 7 deletions(-) >> >> diff --git a/drivers/i2c/muxes/i2c-mux-pca9541.c >> b/drivers/i2c/muxes/i2c-mux-pca9541.c >> index ad168125d23d..47685eb4e0e9 100644 >> --- a/drivers/i2c/muxes/i2c-mux-pca9541.c >> +++ b/drivers/i2c/muxes/i2c-mux-pca9541.c >> @@ -59,10 +59,8 @@ >> #define PCA9541_ISTAT_MYTESTBIT(6) >> #define PCA9541_ISTAT_NMYTEST BIT(7) >> >> -#define BUSON (PCA9541_CTL_BUSON | PCA9541_CTL_NBUSON) >> -#define MYBUS (PCA9541_CTL_MYBUS | PCA9541_CTL_NMYBUS) >> -#define mybus(x)(!((x) & MYBUS) || ((x) & MYBUS) == MYBUS) >> -#define busoff(x) (!((x) & BUSON) || ((x) & BUSON) == BUSON) >> +#define PCA9541_BUSON (PCA9541_CTL_BUSON | PCA9541_CTL_NBUSON) >> +#define PCA9541_MYBUS (PCA9541_CTL_MYBUS | PCA9541_CTL_NMYBUS) >> >> /* arbitration timeouts, in jiffies */ >> #define ARB_TIMEOUT (HZ / 8)/* 125 ms until forcing bus ownership */ >> @@ -93,6 +91,20 @@ static const struct of_device_id pca9541_of_match[] = { >> MODULE_DEVICE_TABLE(of, pca9541_of_match); >> #endif >> >> +static int pca9541_mybus(int ctl) > > static inline? No, "inline" is only used in header files in the kernel. The compiler is free to inline whatever function it likes anyway, and in this case we do not know better than the compiler. We don't care either. At least, that is my understanding of the situation regarding the "inline" keyword. > >> +{ >> +if (!(ctl & PCA9541_MYBUS)) >> +return 1; >> +return (ctl & PCA9541_MYBUS) == PCA9541_MYBUS; >> +} >> + >> +static int pca9541_busoff(int ctl) > > static inline? > >> +{ >> +if (!(ctl & PCA9541_BUSON)) >> +return 1; >> +return (ctl & PCA9541_BUSON) == PCA9541_BUSON; >> +} > > Reviewed-by: Vladimir Zapolskiy Thanks! Cheers, Peter > > -- > With best wishes, > Vladimir >
Re: update vruntime incorrectly When use rt_mutex
hi, Thanks for your feedback. On Fri, 2018-03-16 at 10:51 +0100, Peter Zijlstra wrote: > On Thu, Mar 15, 2018 at 03:36:10PM +0800, Kathleen Chang wrote: > > hi, > > > > We found the vruntime might update incorrectly when use rt_mutex. > > That's nice, on what kernel? > > Also, your email is very hard to make sense of. > > > <> > > When the Task is waking, update vruntime incorrectly. > > 1. When there is a CFS task (A) hold rt_mutex_lock and the state is > > TASK_WAKING (on_rq=0), a RT task (B) want to hold this rt_mutex_lock. > > Update vruntime incorrectly. > > > > RT task (B) > > rt_mutex_setprio (cfs->RT) -> Task is waking , and update > > vruntime > > > >queued = task_on_rq_queued(p); // task is waking, queued=0 > >running = task_current(rq, p); > >if (queued) /* don't update vruntime here! */ > > dequeue_task(rq, p, queue_flag); > >if (running) > > put_prev_task(rq, p); > > > >check_class_changed(rq, p, prev_class, oldprio); -> > > switched_from_fair -> > > detach_task_cfs_rq > > ( due to task is waking, and bypass > > vruntime-=cfs_rq.min_vruntime) > > > > static void detach_task_cfs_rq(struct task_struct *p) > > { > > struct sched_entity *se = >se; > > struct cfs_rq *cfs_rq = cfs_rq_of(se); > > > > if (!vruntime_normalized(p)) { // return 1, then p->state is > > TASK_WAKING > > /* > > * Fix up our vruntime so that the current sleep doesn't > > * cause 'unlimited' sleep bonus. > > */ > > place_entity(cfs_rq, se, 0); > > check_vruntime(8, se, cfs_rq->min_vruntime); > > se->vruntime -= cfs_rq->min_vruntime; > > So here we subtract min_vruntime, When the p->state is TASK_WAKING, vruntime_normlized will return 1 and if(!vruntime_normalized(p)) will be 0 in this case, don't subtract min_vruntime. > > > se->normalized = true; > > this doesn't exist.. which makes me wonder what you're looking at, > > > } > > > > detach_entity_cfs_rq(se); > > } > > > > // when p->state is TASK_WAKING, the task's vruntime is normalized > > static inline bool vruntime_normalized(struct task_struct *p) > > { > > . > > if (!se->sum_exec_runtime || p->state == TASK_WAKING) > > return true; > > > > } > > > > 2. When the task (A) which holds the rt_muex_lock unlock the > > rt_mutex_lock. > > Task (A) must be on_rq=1 > > > > rt_mutex_setprio (RT->CFS) > >if (queued) > > enqueue_task(rq, p, queue_flag);); > > /* vruntime += cfs_rq.min_vruntime */ > > And here we're adding min_vruntime. > > >if (running) > > set_curr_task(rq, p); > > > > that result in vruntime accumulates > > So what exactly is the problem? > >
Re: update vruntime incorrectly When use rt_mutex
hi, Thanks for your feedback. On Fri, 2018-03-16 at 10:51 +0100, Peter Zijlstra wrote: > On Thu, Mar 15, 2018 at 03:36:10PM +0800, Kathleen Chang wrote: > > hi, > > > > We found the vruntime might update incorrectly when use rt_mutex. > > That's nice, on what kernel? > > Also, your email is very hard to make sense of. > > > <> > > When the Task is waking, update vruntime incorrectly. > > 1. When there is a CFS task (A) hold rt_mutex_lock and the state is > > TASK_WAKING (on_rq=0), a RT task (B) want to hold this rt_mutex_lock. > > Update vruntime incorrectly. > > > > RT task (B) > > rt_mutex_setprio (cfs->RT) -> Task is waking , and update > > vruntime > > > >queued = task_on_rq_queued(p); // task is waking, queued=0 > >running = task_current(rq, p); > >if (queued) /* don't update vruntime here! */ > > dequeue_task(rq, p, queue_flag); > >if (running) > > put_prev_task(rq, p); > > > >check_class_changed(rq, p, prev_class, oldprio); -> > > switched_from_fair -> > > detach_task_cfs_rq > > ( due to task is waking, and bypass > > vruntime-=cfs_rq.min_vruntime) > > > > static void detach_task_cfs_rq(struct task_struct *p) > > { > > struct sched_entity *se = >se; > > struct cfs_rq *cfs_rq = cfs_rq_of(se); > > > > if (!vruntime_normalized(p)) { // return 1, then p->state is > > TASK_WAKING > > /* > > * Fix up our vruntime so that the current sleep doesn't > > * cause 'unlimited' sleep bonus. > > */ > > place_entity(cfs_rq, se, 0); > > check_vruntime(8, se, cfs_rq->min_vruntime); > > se->vruntime -= cfs_rq->min_vruntime; > > So here we subtract min_vruntime, When the p->state is TASK_WAKING, vruntime_normlized will return 1 and if(!vruntime_normalized(p)) will be 0 in this case, don't subtract min_vruntime. > > > se->normalized = true; > > this doesn't exist.. which makes me wonder what you're looking at, > > > } > > > > detach_entity_cfs_rq(se); > > } > > > > // when p->state is TASK_WAKING, the task's vruntime is normalized > > static inline bool vruntime_normalized(struct task_struct *p) > > { > > . > > if (!se->sum_exec_runtime || p->state == TASK_WAKING) > > return true; > > > > } > > > > 2. When the task (A) which holds the rt_muex_lock unlock the > > rt_mutex_lock. > > Task (A) must be on_rq=1 > > > > rt_mutex_setprio (RT->CFS) > >if (queued) > > enqueue_task(rq, p, queue_flag);); > > /* vruntime += cfs_rq.min_vruntime */ > > And here we're adding min_vruntime. > > >if (running) > > set_curr_task(rq, p); > > > > that result in vruntime accumulates > > So what exactly is the problem? > >
Re: [PATCH v4 2/5] PCI: designware-ep: Make dw_pcie_ep_set_bar() handle 64-bit BARs properly
Hi Niklas, On Thursday 08 March 2018 07:03 PM, Niklas Cassel wrote: > Since a 64-bit BAR consists of a BAR pair, we need to write to both > BARs in the BAR pair to setup the BAR properly. > > Signed-off-by: Niklas Cassel> --- > drivers/pci/dwc/pcie-designware-ep.c | 11 +-- > 1 file changed, 9 insertions(+), 2 deletions(-) > > diff --git a/drivers/pci/dwc/pcie-designware-ep.c > b/drivers/pci/dwc/pcie-designware-ep.c > index 9236b998327f..946bbdf53c4d 100644 > --- a/drivers/pci/dwc/pcie-designware-ep.c > +++ b/drivers/pci/dwc/pcie-designware-ep.c > @@ -136,8 +136,15 @@ static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 > func_no, > return ret; > > dw_pcie_dbi_ro_wr_en(pci); > - dw_pcie_writel_dbi2(pci, reg, size - 1); > - dw_pcie_writel_dbi(pci, reg, flags); > + if (flags & PCI_BASE_ADDRESS_MEM_TYPE_64) { > + dw_pcie_writel_dbi2(pci, reg, lower_32_bits(size - 1)); > + dw_pcie_writel_dbi(pci, reg, flags); > + dw_pcie_writel_dbi2(pci, reg + 4, upper_32_bits(size - 1)); > + dw_pcie_writel_dbi(pci, reg + 4, 0); I think we should check in pci_epc_set_bar to make sure BAR_5 cannot have PCI_BASE_ADDRESS_MEM_TYPE_64 flag set as this might lead undesired result. Thanks Kishon
Re: [PATCH v4 2/5] PCI: designware-ep: Make dw_pcie_ep_set_bar() handle 64-bit BARs properly
Hi Niklas, On Thursday 08 March 2018 07:03 PM, Niklas Cassel wrote: > Since a 64-bit BAR consists of a BAR pair, we need to write to both > BARs in the BAR pair to setup the BAR properly. > > Signed-off-by: Niklas Cassel > --- > drivers/pci/dwc/pcie-designware-ep.c | 11 +-- > 1 file changed, 9 insertions(+), 2 deletions(-) > > diff --git a/drivers/pci/dwc/pcie-designware-ep.c > b/drivers/pci/dwc/pcie-designware-ep.c > index 9236b998327f..946bbdf53c4d 100644 > --- a/drivers/pci/dwc/pcie-designware-ep.c > +++ b/drivers/pci/dwc/pcie-designware-ep.c > @@ -136,8 +136,15 @@ static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 > func_no, > return ret; > > dw_pcie_dbi_ro_wr_en(pci); > - dw_pcie_writel_dbi2(pci, reg, size - 1); > - dw_pcie_writel_dbi(pci, reg, flags); > + if (flags & PCI_BASE_ADDRESS_MEM_TYPE_64) { > + dw_pcie_writel_dbi2(pci, reg, lower_32_bits(size - 1)); > + dw_pcie_writel_dbi(pci, reg, flags); > + dw_pcie_writel_dbi2(pci, reg + 4, upper_32_bits(size - 1)); > + dw_pcie_writel_dbi(pci, reg + 4, 0); I think we should check in pci_epc_set_bar to make sure BAR_5 cannot have PCI_BASE_ADDRESS_MEM_TYPE_64 flag set as this might lead undesired result. Thanks Kishon
Re: linux-next: build failure after merge of the sound-asoc tree
On Wednesday 21 March 2018 08:15 AM, Mark Brown wrote: On Wed, Mar 21, 2018 at 01:30:40PM +1100, Stephen Rothwell wrote: Caused by commit 363fe37948e2 ("ASoC: amd: dma driver changes for BT I2S controller instance") I have used the sound-asoc tree from next-20180320 for today. Dropped. There is a patch dependency . Below patch not merged yet. We submitted for upstream review. [PATCH V2] ASoC: dwc: I2S Controller instance param added
Re: linux-next: build failure after merge of the sound-asoc tree
On Wednesday 21 March 2018 08:15 AM, Mark Brown wrote: On Wed, Mar 21, 2018 at 01:30:40PM +1100, Stephen Rothwell wrote: Caused by commit 363fe37948e2 ("ASoC: amd: dma driver changes for BT I2S controller instance") I have used the sound-asoc tree from next-20180320 for today. Dropped. There is a patch dependency . Below patch not merged yet. We submitted for upstream review. [PATCH V2] ASoC: dwc: I2S Controller instance param added
Re: [PATCH 3/5] x86/smpboot: Make the check code more clear in prefill_possible_map()
Hi Peter, At 03/20/2018 08:39 PM, Peter Zijlstra wrote: On Tue, Mar 20, 2018 at 07:04:30PM +0800, Dou Liyang wrote: case 1: no | no | no | --> min (setup_possible_cpus, nr_cpu_ids, setup_max_cpus) case 2: no | no | yes| --> min (setup_possible_cpus, nr_cpu_ids) case 3: no | yes | no | --> 1 case 4: no | yes | yes| --> 1 case 5: yes | no | no | --> min (num_processors, nr_cpu_ids, setup_max_cpus) case 6: yes | no | yes| --> min (num_processors + disabled_cpus, nr_cpu_ids) case 7: yes | yes | no | --> 1 case 8: yes | yes | yes| --> 1 The case number is off by one ;-) I got it! ;-) Thanks dou
Re: [PATCH 3/5] x86/smpboot: Make the check code more clear in prefill_possible_map()
Hi Peter, At 03/20/2018 08:39 PM, Peter Zijlstra wrote: On Tue, Mar 20, 2018 at 07:04:30PM +0800, Dou Liyang wrote: case 1: no | no | no | --> min (setup_possible_cpus, nr_cpu_ids, setup_max_cpus) case 2: no | no | yes| --> min (setup_possible_cpus, nr_cpu_ids) case 3: no | yes | no | --> 1 case 4: no | yes | yes| --> 1 case 5: yes | no | no | --> min (num_processors, nr_cpu_ids, setup_max_cpus) case 6: yes | no | yes| --> min (num_processors + disabled_cpus, nr_cpu_ids) case 7: yes | yes | no | --> 1 case 8: yes | yes | yes| --> 1 The case number is off by one ;-) I got it! ;-) Thanks dou
[PATCH v2 2/2] dt-bindings: phy-qcom-qmp: Add UFS phy compitable string for sdm845
Update the compatible string for UFS QMP PHY on SDM845. Signed-off-by: Can Guo--- Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt index cef8765..6e68a6d 100644 --- a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt +++ b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt @@ -11,7 +11,8 @@ Required properties: "qcom,msm8996-qmp-usb3-phy" for 14nm USB3 phy on msm8996, "qcom,qmp-v3-usb3-phy" for USB3 QMP V3 phy, "qcom,sdm845-qmp-usb3-phy" for USB3 QMP V3 phy on sdm845, - "qcom,sdm845-qmp-usb3-uni-phy" for USB3 QMP V3 UNI phy on sdm845. + "qcom,sdm845-qmp-usb3-uni-phy" for USB3 QMP V3 UNI phy on sdm845, + "qcom,sdm845-qmp-ufs-phy" for UFS QMP phy on sdm845. - reg: offset and length of register set for PHY's common serdes block. -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[PATCH v2 2/2] dt-bindings: phy-qcom-qmp: Add UFS phy compitable string for sdm845
Update the compatible string for UFS QMP PHY on SDM845. Signed-off-by: Can Guo --- Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt index cef8765..6e68a6d 100644 --- a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt +++ b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt @@ -11,7 +11,8 @@ Required properties: "qcom,msm8996-qmp-usb3-phy" for 14nm USB3 phy on msm8996, "qcom,qmp-v3-usb3-phy" for USB3 QMP V3 phy, "qcom,sdm845-qmp-usb3-phy" for USB3 QMP V3 phy on sdm845, - "qcom,sdm845-qmp-usb3-uni-phy" for USB3 QMP V3 UNI phy on sdm845. + "qcom,sdm845-qmp-usb3-uni-phy" for USB3 QMP V3 UNI phy on sdm845, + "qcom,sdm845-qmp-ufs-phy" for UFS QMP phy on sdm845. - reg: offset and length of register set for PHY's common serdes block. -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[PATCH v2 0/2] Support for Qualcomm UFS QMP PHY on SDM845
This patch series adds support for UFS QMP PHY on SDM845 and the compitable string for it. This patch series depends on the current proposed QMP V3 USB3 UNI PHY support for sdm845 driver [1] and also based on the DT bindings for the QMP V3 USB3 PHYs based dirver [2]. This series can only be merged once the dependent patches do. [1] http://lists-archives.com/linux-kernel/29071659-dt-bindings-phy-qcom-qmp-update-bindings-for-sdm845.html [2] http://lists-archives.com/linux-kernel/29071660-phy-qcom-qmp-add-qmp-v3-usb3-uni-phy-support-for-sdm845.html Changes since v1: - Incorporated review comments from Vivek and Manu. - Update the commit title of patch 2. Can Guo (2): phy: Add QMP phy based UFS phy support for sdm845 dt-bindings: phy-qcom-qmp: Add UFS phy compitable string for sdm845 .../devicetree/bindings/phy/qcom-qmp-phy.txt | 3 +- drivers/phy/qualcomm/phy-qcom-qmp.c| 122 - drivers/phy/qualcomm/phy-qcom-qmp.h| 8 ++ 3 files changed, 129 insertions(+), 4 deletions(-) -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[PATCH v2 0/2] Support for Qualcomm UFS QMP PHY on SDM845
This patch series adds support for UFS QMP PHY on SDM845 and the compitable string for it. This patch series depends on the current proposed QMP V3 USB3 UNI PHY support for sdm845 driver [1] and also based on the DT bindings for the QMP V3 USB3 PHYs based dirver [2]. This series can only be merged once the dependent patches do. [1] http://lists-archives.com/linux-kernel/29071659-dt-bindings-phy-qcom-qmp-update-bindings-for-sdm845.html [2] http://lists-archives.com/linux-kernel/29071660-phy-qcom-qmp-add-qmp-v3-usb3-uni-phy-support-for-sdm845.html Changes since v1: - Incorporated review comments from Vivek and Manu. - Update the commit title of patch 2. Can Guo (2): phy: Add QMP phy based UFS phy support for sdm845 dt-bindings: phy-qcom-qmp: Add UFS phy compitable string for sdm845 .../devicetree/bindings/phy/qcom-qmp-phy.txt | 3 +- drivers/phy/qualcomm/phy-qcom-qmp.c| 122 - drivers/phy/qualcomm/phy-qcom-qmp.h| 8 ++ 3 files changed, 129 insertions(+), 4 deletions(-) -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[PATCH v2 1/2] phy: Add QMP phy based UFS phy support for sdm845
Add UFS PHY support to make SDM845 UFS work with common PHY framework. Signed-off-by: Can Guo--- drivers/phy/qualcomm/phy-qcom-qmp.c | 122 +++- drivers/phy/qualcomm/phy-qcom-qmp.h | 8 +++ 2 files changed, 127 insertions(+), 3 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c index 5cf2c3c..85d40d4 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp.c @@ -156,6 +156,11 @@ enum qphy_reg_layout { [QPHY_PCS_LFPS_RXTERM_IRQ_STATUS] = 0x170, }; +static const unsigned int sdm845_ufsphy_regs_layout[] = { + [QPHY_START_CTRL] = 0x00, + [QPHY_PCS_READY_STATUS] = 0x168, +}; + static const struct qmp_phy_init_tbl msm8996_pcie_serdes_tbl[] = { QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x1c), QMP_PHY_INIT_CFG(QSERDES_COM_CLK_ENABLE1, 0x10), @@ -601,6 +606,73 @@ enum qphy_reg_layout { QMP_PHY_INIT_CFG(QPHY_V3_PCS_REFGEN_REQ_CONFIG2, 0x60), }; +static const struct qmp_phy_init_tbl sdm845_ufsphy_serdes_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0xd5), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL, 0x20), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_CTRL, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_INITVAL1, 0xff), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_INITVAL2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xda), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0xff), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x0c), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE1, 0x98), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE1, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE1, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE1, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE1, 0x3f), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE1, 0xc1), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE1, 0x32), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE1, 0x0f), + + /* Rate B */ + QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x44), +}; + +static const struct qmp_phy_init_tbl sdm845_ufsphy_tx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x06), +}; + +static const struct qmp_phy_init_tbl sdm845_ufsphy_rx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_LVL, 0x24), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1e), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_INTERFACE_MODE, 0x40), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_TERM_BW, 0x5b), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1d), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_HALF, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x81), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80), +}; + +static const struct qmp_phy_init_tbl sdm845_ufsphy_pcs_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_DOWN_CONTROL, 0x01), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_MULTI_LANE_CTRL1, 0x02), +}; /* struct qmp_phy_cfg - per-PHY initialization config */ struct qmp_phy_cfg { @@ -652,6 +724,9 @@ struct qmp_phy_cfg { /* Register offset of
[PATCH] mtd: devices: check mtd_device_register() return code
stfsm_probe() misses error handling of mtd_device_register(). Signed-off-by: Arushi Singhal--- drivers/mtd/devices/st_spi_fsm.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c index 7bc29d7..e1aa4f8 100644 --- a/drivers/mtd/devices/st_spi_fsm.c +++ b/drivers/mtd/devices/st_spi_fsm.c @@ -2125,7 +2125,13 @@ static int stfsm_probe(struct platform_device *pdev) (long long)fsm->mtd.size, (long long)(fsm->mtd.size >> 20), fsm->mtd.erasesize, (fsm->mtd.erasesize >> 10)); - return mtd_device_register(>mtd, NULL, 0); + ret = mtd_device_register(>mtd, NULL, 0); + if (ret) { + pr_err("Failed to register device\n"); + return ret; + } + + return 0; err_clk_unprepare: clk_disable_unprepare(fsm->clk); -- 2.7.4
[PATCH v2 1/2] phy: Add QMP phy based UFS phy support for sdm845
Add UFS PHY support to make SDM845 UFS work with common PHY framework. Signed-off-by: Can Guo --- drivers/phy/qualcomm/phy-qcom-qmp.c | 122 +++- drivers/phy/qualcomm/phy-qcom-qmp.h | 8 +++ 2 files changed, 127 insertions(+), 3 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c index 5cf2c3c..85d40d4 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp.c @@ -156,6 +156,11 @@ enum qphy_reg_layout { [QPHY_PCS_LFPS_RXTERM_IRQ_STATUS] = 0x170, }; +static const unsigned int sdm845_ufsphy_regs_layout[] = { + [QPHY_START_CTRL] = 0x00, + [QPHY_PCS_READY_STATUS] = 0x168, +}; + static const struct qmp_phy_init_tbl msm8996_pcie_serdes_tbl[] = { QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x1c), QMP_PHY_INIT_CFG(QSERDES_COM_CLK_ENABLE1, 0x10), @@ -601,6 +606,73 @@ enum qphy_reg_layout { QMP_PHY_INIT_CFG(QPHY_V3_PCS_REFGEN_REQ_CONFIG2, 0x60), }; +static const struct qmp_phy_init_tbl sdm845_ufsphy_serdes_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0xd5), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL, 0x20), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_CTRL, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_INITVAL1, 0xff), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_INITVAL2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xda), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0xff), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x0c), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE1, 0x98), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE1, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE1, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE1, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE1, 0x3f), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE1, 0xc1), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE1, 0x32), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE1, 0x0f), + + /* Rate B */ + QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x44), +}; + +static const struct qmp_phy_init_tbl sdm845_ufsphy_tx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x06), +}; + +static const struct qmp_phy_init_tbl sdm845_ufsphy_rx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_LVL, 0x24), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1e), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_INTERFACE_MODE, 0x40), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_TERM_BW, 0x5b), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1d), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_HALF, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x81), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80), +}; + +static const struct qmp_phy_init_tbl sdm845_ufsphy_pcs_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_DOWN_CONTROL, 0x01), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_MULTI_LANE_CTRL1, 0x02), +}; /* struct qmp_phy_cfg - per-PHY initialization config */ struct qmp_phy_cfg { @@ -652,6 +724,9 @@ struct qmp_phy_cfg { /* Register offset of secondary tx/rx lanes
[PATCH] mtd: devices: check mtd_device_register() return code
stfsm_probe() misses error handling of mtd_device_register(). Signed-off-by: Arushi Singhal --- drivers/mtd/devices/st_spi_fsm.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c index 7bc29d7..e1aa4f8 100644 --- a/drivers/mtd/devices/st_spi_fsm.c +++ b/drivers/mtd/devices/st_spi_fsm.c @@ -2125,7 +2125,13 @@ static int stfsm_probe(struct platform_device *pdev) (long long)fsm->mtd.size, (long long)(fsm->mtd.size >> 20), fsm->mtd.erasesize, (fsm->mtd.erasesize >> 10)); - return mtd_device_register(>mtd, NULL, 0); + ret = mtd_device_register(>mtd, NULL, 0); + if (ret) { + pr_err("Failed to register device\n"); + return ret; + } + + return 0; err_clk_unprepare: clk_disable_unprepare(fsm->clk); -- 2.7.4
[PATCH] eeprom: at25: sizeof t should be sizeof(t)
Resolved checkpatch warning "sizeof t should be sizeof(t)" issue found by checkpatch. Signed-off-by: Devang Panchal--- drivers/misc/eeprom/at25.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c index 9282ffd..6a7d4a2 100644 --- a/drivers/misc/eeprom/at25.c +++ b/drivers/misc/eeprom/at25.c @@ -102,7 +102,7 @@ static int at25_ee_read(void *priv, unsigned int offset, } spi_message_init(); - memset(t, 0, sizeof t); + memset(t, 0, sizeof(t)); t[0].tx_buf = command; t[0].len = at25->addrlen + 1; -- 1.9.1
[PATCH] eeprom: at25: sizeof t should be sizeof(t)
Resolved checkpatch warning "sizeof t should be sizeof(t)" issue found by checkpatch. Signed-off-by: Devang Panchal --- drivers/misc/eeprom/at25.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c index 9282ffd..6a7d4a2 100644 --- a/drivers/misc/eeprom/at25.c +++ b/drivers/misc/eeprom/at25.c @@ -102,7 +102,7 @@ static int at25_ee_read(void *priv, unsigned int offset, } spi_message_init(); - memset(t, 0, sizeof t); + memset(t, 0, sizeof(t)); t[0].tx_buf = command; t[0].len = at25->addrlen + 1; -- 1.9.1
Re: [PATCH 1/5] x86/smpboot: Add the missing description of possible_cpus
Hi Peter, At 03/20/2018 08:37 PM, Peter Zijlstra wrote: On Tue, Mar 20, 2018 at 07:04:28PM +0800, Dou Liyang wrote: + possible_cpus= [s390,x86_64] Use this to set hotpluggable cpus. + This option sets possible_cpus bits in cpu_possible_map. + Thus keeping the numbers of bits set constant even if + the machine gets rebooted. That description, esp. the last sentence, doesn't make any kind of sense to me. What? Ah, sure enough, I can't be lazy. :-) I stole that from the commit 3b11ce7f542e ("x86: use possible_cpus=NUM to extend the possible cpus allowed") How about: possible_cpus= [s390,x86_64] Set the number of possible CPUs which are determined by the ACPI tables MADT or mptables by default. possible_cpus=n : n >= 1 enforces the possible number to be 'n'. While nr_cpus is also be set: nr_cpus=m, choice the minimum one for the number of possible CPUs. Thank, dou
Re: [PATCH 1/5] x86/smpboot: Add the missing description of possible_cpus
Hi Peter, At 03/20/2018 08:37 PM, Peter Zijlstra wrote: On Tue, Mar 20, 2018 at 07:04:28PM +0800, Dou Liyang wrote: + possible_cpus= [s390,x86_64] Use this to set hotpluggable cpus. + This option sets possible_cpus bits in cpu_possible_map. + Thus keeping the numbers of bits set constant even if + the machine gets rebooted. That description, esp. the last sentence, doesn't make any kind of sense to me. What? Ah, sure enough, I can't be lazy. :-) I stole that from the commit 3b11ce7f542e ("x86: use possible_cpus=NUM to extend the possible cpus allowed") How about: possible_cpus= [s390,x86_64] Set the number of possible CPUs which are determined by the ACPI tables MADT or mptables by default. possible_cpus=n : n >= 1 enforces the possible number to be 'n'. While nr_cpus is also be set: nr_cpus=m, choice the minimum one for the number of possible CPUs. Thank, dou
Re: [PATCH v4 1/5] PCI: endpoint: BAR width should not depend on sizeof dma_addr_t
On Thursday 08 March 2018 07:03 PM, Niklas Cassel wrote: > If a BAR supports 64-bit width or not depends on the hardware, > and should thus not depend on sizeof(dma_addr_t). > > Since this driver is generic, default to always using BAR width > of 32-bits. 64-bit BARs can easily be tested by replacing > PCI_BASE_ADDRESS_MEM_TYPE_32 with PCI_BASE_ADDRESS_MEM_TYPE_64 > in bar_flags. > > Signed-off-by: Niklas CasselAcked-by: Kishon Vijay Abraham I > --- > Note to Lorenzo/Bjorn: > It is not trivial to convert the bar_size + bar_flags + > struct pci_epf->bar member array to an array of struct resources, > since we need to be able to store the addresses returned > by dma_alloc_coherent(), which is of type dma_addr_t. > struct resource uses resource_size_t, which is defined as phys_addr_t. > E.g. ARTPEC-7 uses 64-bit dma_addr_t, but only 32-bit phys_addr_t. > > drivers/pci/endpoint/functions/pci-epf-test.c | 15 +-- > 1 file changed, 9 insertions(+), 6 deletions(-) > > diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c > b/drivers/pci/endpoint/functions/pci-epf-test.c > index 800da09d9005..7c70433b11a7 100644 > --- a/drivers/pci/endpoint/functions/pci-epf-test.c > +++ b/drivers/pci/endpoint/functions/pci-epf-test.c > @@ -71,6 +71,14 @@ struct pci_epf_test_data { > }; > > static int bar_size[] = { 512, 512, 1024, 16384, 131072, 1048576 }; > +static int bar_flags[] = { > + PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_32, > + PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_32, > + PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_32, > + PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_32, > + PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_32, > + PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_32 > +}; > > static int pci_epf_test_copy(struct pci_epf_test *epf_test) > { > @@ -358,7 +366,6 @@ static void pci_epf_test_unbind(struct pci_epf *epf) > > static int pci_epf_test_set_bar(struct pci_epf *epf) > { > - int flags; > int bar; > int ret; > struct pci_epf_bar *epf_bar; > @@ -367,15 +374,11 @@ static int pci_epf_test_set_bar(struct pci_epf *epf) > struct pci_epf_test *epf_test = epf_get_drvdata(epf); > enum pci_barno test_reg_bar = epf_test->test_reg_bar; > > - flags = PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_32; > - if (sizeof(dma_addr_t) == 0x8) > - flags |= PCI_BASE_ADDRESS_MEM_TYPE_64; > - > for (bar = BAR_0; bar <= BAR_5; bar++) { > epf_bar = >bar[bar]; > ret = pci_epc_set_bar(epc, epf->func_no, bar, > epf_bar->phys_addr, > - epf_bar->size, flags); > + epf_bar->size, bar_flags[bar]); > if (ret) { > pci_epf_free_space(epf, epf_test->reg[bar], bar); > dev_err(dev, "failed to set BAR%d\n", bar); >
Re: [PATCH v4 1/5] PCI: endpoint: BAR width should not depend on sizeof dma_addr_t
On Thursday 08 March 2018 07:03 PM, Niklas Cassel wrote: > If a BAR supports 64-bit width or not depends on the hardware, > and should thus not depend on sizeof(dma_addr_t). > > Since this driver is generic, default to always using BAR width > of 32-bits. 64-bit BARs can easily be tested by replacing > PCI_BASE_ADDRESS_MEM_TYPE_32 with PCI_BASE_ADDRESS_MEM_TYPE_64 > in bar_flags. > > Signed-off-by: Niklas Cassel Acked-by: Kishon Vijay Abraham I > --- > Note to Lorenzo/Bjorn: > It is not trivial to convert the bar_size + bar_flags + > struct pci_epf->bar member array to an array of struct resources, > since we need to be able to store the addresses returned > by dma_alloc_coherent(), which is of type dma_addr_t. > struct resource uses resource_size_t, which is defined as phys_addr_t. > E.g. ARTPEC-7 uses 64-bit dma_addr_t, but only 32-bit phys_addr_t. > > drivers/pci/endpoint/functions/pci-epf-test.c | 15 +-- > 1 file changed, 9 insertions(+), 6 deletions(-) > > diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c > b/drivers/pci/endpoint/functions/pci-epf-test.c > index 800da09d9005..7c70433b11a7 100644 > --- a/drivers/pci/endpoint/functions/pci-epf-test.c > +++ b/drivers/pci/endpoint/functions/pci-epf-test.c > @@ -71,6 +71,14 @@ struct pci_epf_test_data { > }; > > static int bar_size[] = { 512, 512, 1024, 16384, 131072, 1048576 }; > +static int bar_flags[] = { > + PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_32, > + PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_32, > + PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_32, > + PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_32, > + PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_32, > + PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_32 > +}; > > static int pci_epf_test_copy(struct pci_epf_test *epf_test) > { > @@ -358,7 +366,6 @@ static void pci_epf_test_unbind(struct pci_epf *epf) > > static int pci_epf_test_set_bar(struct pci_epf *epf) > { > - int flags; > int bar; > int ret; > struct pci_epf_bar *epf_bar; > @@ -367,15 +374,11 @@ static int pci_epf_test_set_bar(struct pci_epf *epf) > struct pci_epf_test *epf_test = epf_get_drvdata(epf); > enum pci_barno test_reg_bar = epf_test->test_reg_bar; > > - flags = PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_32; > - if (sizeof(dma_addr_t) == 0x8) > - flags |= PCI_BASE_ADDRESS_MEM_TYPE_64; > - > for (bar = BAR_0; bar <= BAR_5; bar++) { > epf_bar = >bar[bar]; > ret = pci_epc_set_bar(epc, epf->func_no, bar, > epf_bar->phys_addr, > - epf_bar->size, flags); > + epf_bar->size, bar_flags[bar]); > if (ret) { > pci_epf_free_space(epf, epf_test->reg[bar], bar); > dev_err(dev, "failed to set BAR%d\n", bar); >
Re: [PATCH 4.4 000/134] 4.4.123-stable review
On Tue, Mar 20, 2018 at 06:32:00AM -0700, Guenter Roeck wrote: > On 03/19/2018 11:04 AM, Greg Kroah-Hartman wrote: > > This is the start of the stable review cycle for the 4.4.123 release. > > There are 134 patches in this series, all will be posted as a response > > to this one. If anyone has any issues with these being applied, please > > let me know. > > > > Responses should be made by Wed Mar 21 17:18:04 UTC 2018. > > Anything received after that time might be too late. > > > > For v4.4.122-134-gb4e03b4: > > Build results: > total: 145 pass: 140 fail: 5 > Failed builds: > arm:allmodconfig > powerpc:defconfig > powerpc:allmodconfig > powerpc:cell_defconfig > powerpc:maple_defconfig > > arm:allmodconfig: > > drivers/net/ethernet/marvell/mvpp2.c: In function 'mvpp2_probe': > drivers/net/ethernet/marvell/mvpp2.c:6451:10: error: 'struct mvpp2' has no > member named 'hw_version' > if (priv->hw_version == MVPP22) { > ^ > drivers/net/ethernet/marvell/mvpp2.c:6451:26: error: 'MVPP22' undeclared > (first use in this function) > if (priv->hw_version == MVPP22) { > Caused by commit 6349601ed3e1 ("net: mvpp2: set dma mask and coherent dma mask on PPv2.2"), which seems irrelevant for 4.4 since PPv2.2 support was added in 4.12 per upstream commit fc5e1550e5c3 ("net: mvpp2: finally add the PPv2.2 compatible string"). > powerpc: > > arch/powerpc/mm/hugetlbpage.c: In function 'add_huge_page_size': > arch/powerpc/mm/hugetlbpage.c:840:2: error: implicit declaration of function > 'radix_enabled' > Caused by commit 17cd5e81ded7 ("powerpc/mm/hugetlb: Filter out hugepage size not supported by page table layout"). It is introduced in 4.7 in upstream commit 566ca99af026 ("powerpc/mm/radix: Add dummy radix_enabled()") and not properly turned on until upstream commit a8ed87c92adf ("powerpc/mm/radix: Add MMU_FTR_RADIX"). I am going to assume from the fact there is a lot of MMU work after this and the wording of the Kconfig entry that this is probably not suitable fo a stable backport. > Guenter Cheers, Nathan
Re: [PATCH 4.4 000/134] 4.4.123-stable review
On Tue, Mar 20, 2018 at 06:32:00AM -0700, Guenter Roeck wrote: > On 03/19/2018 11:04 AM, Greg Kroah-Hartman wrote: > > This is the start of the stable review cycle for the 4.4.123 release. > > There are 134 patches in this series, all will be posted as a response > > to this one. If anyone has any issues with these being applied, please > > let me know. > > > > Responses should be made by Wed Mar 21 17:18:04 UTC 2018. > > Anything received after that time might be too late. > > > > For v4.4.122-134-gb4e03b4: > > Build results: > total: 145 pass: 140 fail: 5 > Failed builds: > arm:allmodconfig > powerpc:defconfig > powerpc:allmodconfig > powerpc:cell_defconfig > powerpc:maple_defconfig > > arm:allmodconfig: > > drivers/net/ethernet/marvell/mvpp2.c: In function 'mvpp2_probe': > drivers/net/ethernet/marvell/mvpp2.c:6451:10: error: 'struct mvpp2' has no > member named 'hw_version' > if (priv->hw_version == MVPP22) { > ^ > drivers/net/ethernet/marvell/mvpp2.c:6451:26: error: 'MVPP22' undeclared > (first use in this function) > if (priv->hw_version == MVPP22) { > Caused by commit 6349601ed3e1 ("net: mvpp2: set dma mask and coherent dma mask on PPv2.2"), which seems irrelevant for 4.4 since PPv2.2 support was added in 4.12 per upstream commit fc5e1550e5c3 ("net: mvpp2: finally add the PPv2.2 compatible string"). > powerpc: > > arch/powerpc/mm/hugetlbpage.c: In function 'add_huge_page_size': > arch/powerpc/mm/hugetlbpage.c:840:2: error: implicit declaration of function > 'radix_enabled' > Caused by commit 17cd5e81ded7 ("powerpc/mm/hugetlb: Filter out hugepage size not supported by page table layout"). It is introduced in 4.7 in upstream commit 566ca99af026 ("powerpc/mm/radix: Add dummy radix_enabled()") and not properly turned on until upstream commit a8ed87c92adf ("powerpc/mm/radix: Add MMU_FTR_RADIX"). I am going to assume from the fact there is a lot of MMU work after this and the wording of the Kconfig entry that this is probably not suitable fo a stable backport. > Guenter Cheers, Nathan
[PATCH] USB:fix USB3 devices behind USB3 hubs not resuming at hibernate thaw
USB3 hubs don't support global suspend. USB3 specification 10.10, Enhanced SuperSpeed hubs only support selective suspend and resume, they do not support global suspend/resume where the hub downstream facing ports states are not affected. When system enters hibernation it first enters freeze process where only the root hub enters suspend, usb_port_suspend() is not called for other devices, and suspend status flags are not set for them. Other devices are expected to suspend globally. Some external USB3 hubs will suspend the downstream facing port at global suspend. These devices won't be resumed at thaw as the suspend status flag is not set. A USB3 removable hard disk connected through a USB3 hub that won't resume at thaw will fail to synchronize SCSI cache, return “cmd cmplt err -71” error, and needs a 60 seconds timeout which causing system hang for 60s before the USB host reset the port for the USB3 removable hard disk to recover. Fix this by always calling usb_port_suspend() during freeze for USB3 devices. Signed-off-by: Zhengjun Xing--- drivers/usb/core/generic.c | 9 +++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c index 83c14dda6300..bc8242bc4564 100644 --- a/drivers/usb/core/generic.c +++ b/drivers/usb/core/generic.c @@ -210,8 +210,13 @@ static int generic_suspend(struct usb_device *udev, pm_message_t msg) if (!udev->parent) rc = hcd_bus_suspend(udev, msg); - /* Non-root devices don't need to do anything for FREEZE or PRETHAW */ - else if (msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_PRETHAW) + /* +* Non-root USB2 devices don't need to do anything for FREEZE +* or PRETHAW. USB3 devices don't support global suspend and +* needs to be selectively suspended. +*/ + else if ((msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_PRETHAW) +&& (udev->speed < USB_SPEED_SUPER)) rc = 0; else rc = usb_port_suspend(udev, msg); -- 2.11.0
[PATCH] USB:fix USB3 devices behind USB3 hubs not resuming at hibernate thaw
USB3 hubs don't support global suspend. USB3 specification 10.10, Enhanced SuperSpeed hubs only support selective suspend and resume, they do not support global suspend/resume where the hub downstream facing ports states are not affected. When system enters hibernation it first enters freeze process where only the root hub enters suspend, usb_port_suspend() is not called for other devices, and suspend status flags are not set for them. Other devices are expected to suspend globally. Some external USB3 hubs will suspend the downstream facing port at global suspend. These devices won't be resumed at thaw as the suspend status flag is not set. A USB3 removable hard disk connected through a USB3 hub that won't resume at thaw will fail to synchronize SCSI cache, return “cmd cmplt err -71” error, and needs a 60 seconds timeout which causing system hang for 60s before the USB host reset the port for the USB3 removable hard disk to recover. Fix this by always calling usb_port_suspend() during freeze for USB3 devices. Signed-off-by: Zhengjun Xing --- drivers/usb/core/generic.c | 9 +++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c index 83c14dda6300..bc8242bc4564 100644 --- a/drivers/usb/core/generic.c +++ b/drivers/usb/core/generic.c @@ -210,8 +210,13 @@ static int generic_suspend(struct usb_device *udev, pm_message_t msg) if (!udev->parent) rc = hcd_bus_suspend(udev, msg); - /* Non-root devices don't need to do anything for FREEZE or PRETHAW */ - else if (msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_PRETHAW) + /* +* Non-root USB2 devices don't need to do anything for FREEZE +* or PRETHAW. USB3 devices don't support global suspend and +* needs to be selectively suspended. +*/ + else if ((msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_PRETHAW) +&& (udev->speed < USB_SPEED_SUPER)) rc = 0; else rc = usb_port_suspend(udev, msg); -- 2.11.0
Re: [PATCH] ARM: dts: db600c: add support to pcie refclk
Thanks Bjorn for the review comments, On 21/03/18 11:35, Bjorn Andersson wrote: On Tue 20 Mar 17:28 HKT 2018, Srinivas Kandagatla wrote: From: Srinivas KandagatlaThis patch adds support to external pcie refclk. Signed-off-by: Srinivas Kandagatla --- arch/arm/boot/dts/qcom-apq8064-db600c.dts | 27 +++ 1 file changed, 27 insertions(+) diff --git a/arch/arm/boot/dts/qcom-apq8064-db600c.dts b/arch/arm/boot/dts/qcom-apq8064-db600c.dts index 50151ef6e912..7587088c122f 100644 --- a/arch/arm/boot/dts/qcom-apq8064-db600c.dts +++ b/arch/arm/boot/dts/qcom-apq8064-db600c.dts @@ -45,6 +45,18 @@ }; + clocks { + compatible = "simple-bus"; + pcie_refclk: pcie-refclk { As the si53154 is used to acquire 3 different clocks (2 pcie and 1 sata) it would be nice to accurately represent this in the DT. That said, exposing this as a clock allow us to change the representation here later. (Both pcie_core_clk and pcie_eth_clk use the same gpio pin as enable pin, so I don't know how to represent this...) This is a refclk, which should be always same for both PCIe Controllers and connected PCIe endpoints. For sata we should have one more refclk entry of its own. So for now, please name this "pcie_core_clk", per the schematics. This is pcie refclk, if you follow the line in the schematics should see that it terminates to pcie refclk. + pinctrl-0 = <_pins>; + pinctrl-names = "default"; + compatible = "gpio-gate-clock"; + clocks = < 27>; + #clock-cells = <0>; + enable-gpios = <_gpio 22 GPIO_ACTIVE_HIGH>; + }; + }; + hdmi-out { compatible = "hdmi-connector"; type = "a"; @@ -140,6 +152,16 @@ qcom,ssbi@50 { pmic@0 { + gpio@150 { + pcie_pins: pcie_pins { Please label this "pcie_clk_en_pin" and don't use '_' in the name of the node. I agree, Will fix it. + pios { You can omit this level and just put the properties in directly in the pcie-clk-en node. Okay. thanks, srini + pins = "gpio22"; + function = "normal"; + power-source = ; + }; + }; + }; + Regards, Bjorn
Re: [PATCH] ARM: dts: db600c: add support to pcie refclk
Thanks Bjorn for the review comments, On 21/03/18 11:35, Bjorn Andersson wrote: On Tue 20 Mar 17:28 HKT 2018, Srinivas Kandagatla wrote: From: Srinivas Kandagatla This patch adds support to external pcie refclk. Signed-off-by: Srinivas Kandagatla --- arch/arm/boot/dts/qcom-apq8064-db600c.dts | 27 +++ 1 file changed, 27 insertions(+) diff --git a/arch/arm/boot/dts/qcom-apq8064-db600c.dts b/arch/arm/boot/dts/qcom-apq8064-db600c.dts index 50151ef6e912..7587088c122f 100644 --- a/arch/arm/boot/dts/qcom-apq8064-db600c.dts +++ b/arch/arm/boot/dts/qcom-apq8064-db600c.dts @@ -45,6 +45,18 @@ }; + clocks { + compatible = "simple-bus"; + pcie_refclk: pcie-refclk { As the si53154 is used to acquire 3 different clocks (2 pcie and 1 sata) it would be nice to accurately represent this in the DT. That said, exposing this as a clock allow us to change the representation here later. (Both pcie_core_clk and pcie_eth_clk use the same gpio pin as enable pin, so I don't know how to represent this...) This is a refclk, which should be always same for both PCIe Controllers and connected PCIe endpoints. For sata we should have one more refclk entry of its own. So for now, please name this "pcie_core_clk", per the schematics. This is pcie refclk, if you follow the line in the schematics should see that it terminates to pcie refclk. + pinctrl-0 = <_pins>; + pinctrl-names = "default"; + compatible = "gpio-gate-clock"; + clocks = < 27>; + #clock-cells = <0>; + enable-gpios = <_gpio 22 GPIO_ACTIVE_HIGH>; + }; + }; + hdmi-out { compatible = "hdmi-connector"; type = "a"; @@ -140,6 +152,16 @@ qcom,ssbi@50 { pmic@0 { + gpio@150 { + pcie_pins: pcie_pins { Please label this "pcie_clk_en_pin" and don't use '_' in the name of the node. I agree, Will fix it. + pios { You can omit this level and just put the properties in directly in the pcie-clk-en node. Okay. thanks, srini + pins = "gpio22"; + function = "normal"; + power-source = ; + }; + }; + }; + Regards, Bjorn
Re: [PATCH 10/15] mm/hmm: do not differentiate between empty entry or missing directory v2
On 03/19/2018 07:00 PM, jgli...@redhat.com wrote: > From: Jérôme Glisse> > There is no point in differentiating between a range for which there > is not even a directory (and thus entries) and empty entry (pte_none() > or pmd_none() returns true). > > Simply drop the distinction ie remove HMM_PFN_EMPTY flag and merge now > duplicate hmm_vma_walk_hole() and hmm_vma_walk_clear() functions. > > Changed since v1: > - Improved comments > > Signed-off-by: Jérôme Glisse > Cc: Evgeny Baskakov > Cc: Ralph Campbell > Cc: Mark Hairgrove > Cc: John Hubbard > --- > include/linux/hmm.h | 8 +++- > mm/hmm.c| 45 +++-- > 2 files changed, 18 insertions(+), 35 deletions(-) > > diff --git a/include/linux/hmm.h b/include/linux/hmm.h > index 54d684fe3b90..cf283db22106 100644 > --- a/include/linux/hmm.h > +++ b/include/linux/hmm.h > @@ -84,7 +84,6 @@ struct hmm; > * HMM_PFN_VALID: pfn is valid. It has, at least, read permission. > * HMM_PFN_WRITE: CPU page table has write permission set > * HMM_PFN_ERROR: corresponding CPU page table entry points to poisoned > memory > - * HMM_PFN_EMPTY: corresponding CPU page table entry is pte_none() > * HMM_PFN_SPECIAL: corresponding CPU page table entry is special; i.e., the > * result of vm_insert_pfn() or vm_insert_page(). Therefore, it should > not > * be mirrored by a device, because the entry will never have > HMM_PFN_VALID > @@ -94,10 +93,9 @@ struct hmm; > #define HMM_PFN_VALID (1 << 0) > #define HMM_PFN_WRITE (1 << 1) > #define HMM_PFN_ERROR (1 << 2) > -#define HMM_PFN_EMPTY (1 << 3) Hi Jerome, Nearly done with this one...see below for a bit more detail, but I think if we did this: #define HMM_PFN_EMPTY (0) ...it would work out nicely. > -#define HMM_PFN_SPECIAL (1 << 4) > -#define HMM_PFN_DEVICE_UNADDRESSABLE (1 << 5) > -#define HMM_PFN_SHIFT 6 > +#define HMM_PFN_SPECIAL (1 << 3) > +#define HMM_PFN_DEVICE_UNADDRESSABLE (1 << 4) > +#define HMM_PFN_SHIFT 5 > > @@ -438,7 +423,7 @@ static int hmm_vma_walk_pmd(pmd_t *pmdp, > pfns[i] = 0; > > if (pte_none(pte)) { > - pfns[i] = HMM_PFN_EMPTY; > + pfns[i] = 0; This works, but why not keep HMM_PFN_EMPTY, and just define it as zero? Symbols are better than raw numbers here. > if (hmm_vma_walk->fault) > goto fault; > continue; > @@ -489,8 +474,8 @@ static int hmm_vma_walk_pmd(pmd_t *pmdp, > > fault: > pte_unmap(ptep); > - /* Fault all pages in range */ > - return hmm_vma_walk_clear(start, end, walk); > + /* Fault any virtual address we were ask to fault */ asked to fault thanks, -- John Hubbard NVIDIA
Re: [PATCH 10/15] mm/hmm: do not differentiate between empty entry or missing directory v2
On 03/19/2018 07:00 PM, jgli...@redhat.com wrote: > From: Jérôme Glisse > > There is no point in differentiating between a range for which there > is not even a directory (and thus entries) and empty entry (pte_none() > or pmd_none() returns true). > > Simply drop the distinction ie remove HMM_PFN_EMPTY flag and merge now > duplicate hmm_vma_walk_hole() and hmm_vma_walk_clear() functions. > > Changed since v1: > - Improved comments > > Signed-off-by: Jérôme Glisse > Cc: Evgeny Baskakov > Cc: Ralph Campbell > Cc: Mark Hairgrove > Cc: John Hubbard > --- > include/linux/hmm.h | 8 +++- > mm/hmm.c| 45 +++-- > 2 files changed, 18 insertions(+), 35 deletions(-) > > diff --git a/include/linux/hmm.h b/include/linux/hmm.h > index 54d684fe3b90..cf283db22106 100644 > --- a/include/linux/hmm.h > +++ b/include/linux/hmm.h > @@ -84,7 +84,6 @@ struct hmm; > * HMM_PFN_VALID: pfn is valid. It has, at least, read permission. > * HMM_PFN_WRITE: CPU page table has write permission set > * HMM_PFN_ERROR: corresponding CPU page table entry points to poisoned > memory > - * HMM_PFN_EMPTY: corresponding CPU page table entry is pte_none() > * HMM_PFN_SPECIAL: corresponding CPU page table entry is special; i.e., the > * result of vm_insert_pfn() or vm_insert_page(). Therefore, it should > not > * be mirrored by a device, because the entry will never have > HMM_PFN_VALID > @@ -94,10 +93,9 @@ struct hmm; > #define HMM_PFN_VALID (1 << 0) > #define HMM_PFN_WRITE (1 << 1) > #define HMM_PFN_ERROR (1 << 2) > -#define HMM_PFN_EMPTY (1 << 3) Hi Jerome, Nearly done with this one...see below for a bit more detail, but I think if we did this: #define HMM_PFN_EMPTY (0) ...it would work out nicely. > -#define HMM_PFN_SPECIAL (1 << 4) > -#define HMM_PFN_DEVICE_UNADDRESSABLE (1 << 5) > -#define HMM_PFN_SHIFT 6 > +#define HMM_PFN_SPECIAL (1 << 3) > +#define HMM_PFN_DEVICE_UNADDRESSABLE (1 << 4) > +#define HMM_PFN_SHIFT 5 > > @@ -438,7 +423,7 @@ static int hmm_vma_walk_pmd(pmd_t *pmdp, > pfns[i] = 0; > > if (pte_none(pte)) { > - pfns[i] = HMM_PFN_EMPTY; > + pfns[i] = 0; This works, but why not keep HMM_PFN_EMPTY, and just define it as zero? Symbols are better than raw numbers here. > if (hmm_vma_walk->fault) > goto fault; > continue; > @@ -489,8 +474,8 @@ static int hmm_vma_walk_pmd(pmd_t *pmdp, > > fault: > pte_unmap(ptep); > - /* Fault all pages in range */ > - return hmm_vma_walk_clear(start, end, walk); > + /* Fault any virtual address we were ask to fault */ asked to fault thanks, -- John Hubbard NVIDIA
Re: [PATCH] iommu/mediatek: Fix protect memory setting
Hi Joerg, On Tue, 2018-03-20 at 13:57 -0500, Joerg Roedel wrote: > On Sun, Mar 18, 2018 at 09:52:54AM +0800, Yong Wu wrote: > > To avoid adding this complex macro or a new function, I put > > it in the code and backup its value in the suspend registers. > > Missing Signed-off-by. Signed-off-by and Reported-by have been added above. Reported-by: Honghui ZhangSigned-off-by: Yong Wu > > > --- > > drivers/iommu/mtk_iommu.c | 15 ++- > > drivers/iommu/mtk_iommu.h | 1 + > > 2 files changed, 11 insertions(+), 5 deletions(-) > > > Joerg
Re: [PATCH] iommu/mediatek: Fix protect memory setting
Hi Joerg, On Tue, 2018-03-20 at 13:57 -0500, Joerg Roedel wrote: > On Sun, Mar 18, 2018 at 09:52:54AM +0800, Yong Wu wrote: > > To avoid adding this complex macro or a new function, I put > > it in the code and backup its value in the suspend registers. > > Missing Signed-off-by. Signed-off-by and Reported-by have been added above. Reported-by: Honghui Zhang Signed-off-by: Yong Wu > > > --- > > drivers/iommu/mtk_iommu.c | 15 ++- > > drivers/iommu/mtk_iommu.h | 1 + > > 2 files changed, 11 insertions(+), 5 deletions(-) > > > Joerg
[PATCH] builddeb: Fix header package regarding dtc source links
Since d5d332d3f7e8, a couple of links in scripts/dtc/include-prefixes are additionally required in order to build device trees with the header package. Signed-off-by: Jan Kiszka--- scripts/package/builddeb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/package/builddeb b/scripts/package/builddeb index b4f0f2b3f8d2..13fabb1f81db 100755 --- a/scripts/package/builddeb +++ b/scripts/package/builddeb @@ -313,7 +313,7 @@ fi # Build kernel header package (cd $srctree; find . -name Makefile\* -o -name Kconfig\* -o -name \*.pl) > "$objtree/debian/hdrsrcfiles" -(cd $srctree; find arch/*/include include scripts -type f) >> "$objtree/debian/hdrsrcfiles" +(cd $srctree; find arch/*/include include scripts -type f -o -type l) >> "$objtree/debian/hdrsrcfiles" (cd $srctree; find arch/$SRCARCH -name module.lds -o -name Kbuild.platforms -o -name Platform) >> "$objtree/debian/hdrsrcfiles" (cd $srctree; find $(find arch/$SRCARCH -name include -o -name scripts -type d) -type f) >> "$objtree/debian/hdrsrcfiles" if grep -q '^CONFIG_STACK_VALIDATION=y' $KCONFIG_CONFIG ; then -- 2.13.6
[PATCH] builddeb: Fix header package regarding dtc source links
Since d5d332d3f7e8, a couple of links in scripts/dtc/include-prefixes are additionally required in order to build device trees with the header package. Signed-off-by: Jan Kiszka --- scripts/package/builddeb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/package/builddeb b/scripts/package/builddeb index b4f0f2b3f8d2..13fabb1f81db 100755 --- a/scripts/package/builddeb +++ b/scripts/package/builddeb @@ -313,7 +313,7 @@ fi # Build kernel header package (cd $srctree; find . -name Makefile\* -o -name Kconfig\* -o -name \*.pl) > "$objtree/debian/hdrsrcfiles" -(cd $srctree; find arch/*/include include scripts -type f) >> "$objtree/debian/hdrsrcfiles" +(cd $srctree; find arch/*/include include scripts -type f -o -type l) >> "$objtree/debian/hdrsrcfiles" (cd $srctree; find arch/$SRCARCH -name module.lds -o -name Kbuild.platforms -o -name Platform) >> "$objtree/debian/hdrsrcfiles" (cd $srctree; find $(find arch/$SRCARCH -name include -o -name scripts -type d) -type f) >> "$objtree/debian/hdrsrcfiles" if grep -q '^CONFIG_STACK_VALIDATION=y' $KCONFIG_CONFIG ; then -- 2.13.6
[GIT PULL] extcon next for v4.17
Dear Greg, This is extcon-next pull request for v4.17. I add detailed description of this pull request on below. Please pull extcon with following updates. Best Regards, Chanwoo Choi The following changes since commit 4a3928c6f8a53fa1aed28ccba227742486e8ddcb: Linux 4.16-rc3 (2018-02-25 18:50:41 -0800) are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/extcon.git tags/extcon-next-for-4.17 for you to fetch changes up to eb7768e774d12eac1189984a62925bc3bb386e13: Merge branch 'ib-extcon-drm-dt-v4.17' into extcon-next (2018-03-21 13:58:23 +0900) Update extcon for 4.17 Detailed description for this pull request: 1. Add exported extcon function in order to support OF graph binding - The extcon consumer driver used the "extcon = <'s phandle" property in device-tree in order to bind between extcon provider and consumer driver. But, OF graph method is better than 'extcon' property. So, extcon subsystem adds the following function to support OF graph binding. : extcon_find_edev_by_node(struct device_node *node) - Create the immutable branch ("ib-extcon-drm-dt-v4.17") for both drm-misc and device-tree subsystem. This immutable branch contains the use-case of OF graph binding for EXTCON_HDMI connector between MHL device driver and extcon provider driver. 2. Fix minor issues of extcon device drivers - Remove platform_data and covert to fully use GPIO descriptor for extcon-gpio.c - Remove workaround code for id pin direction from extcon-inte-int3496.c because GPIO ACPI library does support it with generic way. - Set direction and drv flags for V5 boost GPIO because of fixing the firmware bug. Andrzej Hajda (3): dt-bindings: add bindings for USB physical connector dt-bindings: add bindings for Samsung micro-USB 11-pin connector extcon: add possibility to get extcon device by OF node Andy Shevchenko (1): extcon: int3496: Ignore incorrect IoRestriction for ID pin Chanwoo Choi (1): Merge branch 'ib-extcon-drm-dt-v4.17' into extcon-next Hans de Goede (1): extcon: intel-cht-wc: Set direction and drv flags for V5 boost GPIO Linus Walleij (3): extcon: gpio: Localize platform data extcon: gpio: Move platform data into state container extcon: gpio: Convert to fully use GPIO descriptor Maciej Purski (1): drm/bridge/sii8620: use micro-USB cable detection logic to detect MHL .../connector/samsung,usb-connector-11pin.txt | 49 ++ .../bindings/connector/usb-connector.txt | 75 +++ drivers/extcon/extcon-gpio.c | 103 + drivers/extcon/extcon-intel-cht-wc.c | 11 ++- drivers/extcon/extcon-intel-int3496.c | 9 +- drivers/extcon/extcon.c| 44 +++-- drivers/gpu/drm/bridge/sil-sii8620.c | 97 ++- include/linux/extcon.h | 6 ++ include/linux/extcon/extcon-gpio.h | 47 -- 9 files changed, 315 insertions(+), 126 deletions(-) create mode 100644 Documentation/devicetree/bindings/connector/samsung,usb-connector-11pin.txt create mode 100644 Documentation/devicetree/bindings/connector/usb-connector.txt delete mode 100644 include/linux/extcon/extcon-gpio.h
[GIT PULL] extcon next for v4.17
Dear Greg, This is extcon-next pull request for v4.17. I add detailed description of this pull request on below. Please pull extcon with following updates. Best Regards, Chanwoo Choi The following changes since commit 4a3928c6f8a53fa1aed28ccba227742486e8ddcb: Linux 4.16-rc3 (2018-02-25 18:50:41 -0800) are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/extcon.git tags/extcon-next-for-4.17 for you to fetch changes up to eb7768e774d12eac1189984a62925bc3bb386e13: Merge branch 'ib-extcon-drm-dt-v4.17' into extcon-next (2018-03-21 13:58:23 +0900) Update extcon for 4.17 Detailed description for this pull request: 1. Add exported extcon function in order to support OF graph binding - The extcon consumer driver used the "extcon = <'s phandle" property in device-tree in order to bind between extcon provider and consumer driver. But, OF graph method is better than 'extcon' property. So, extcon subsystem adds the following function to support OF graph binding. : extcon_find_edev_by_node(struct device_node *node) - Create the immutable branch ("ib-extcon-drm-dt-v4.17") for both drm-misc and device-tree subsystem. This immutable branch contains the use-case of OF graph binding for EXTCON_HDMI connector between MHL device driver and extcon provider driver. 2. Fix minor issues of extcon device drivers - Remove platform_data and covert to fully use GPIO descriptor for extcon-gpio.c - Remove workaround code for id pin direction from extcon-inte-int3496.c because GPIO ACPI library does support it with generic way. - Set direction and drv flags for V5 boost GPIO because of fixing the firmware bug. Andrzej Hajda (3): dt-bindings: add bindings for USB physical connector dt-bindings: add bindings for Samsung micro-USB 11-pin connector extcon: add possibility to get extcon device by OF node Andy Shevchenko (1): extcon: int3496: Ignore incorrect IoRestriction for ID pin Chanwoo Choi (1): Merge branch 'ib-extcon-drm-dt-v4.17' into extcon-next Hans de Goede (1): extcon: intel-cht-wc: Set direction and drv flags for V5 boost GPIO Linus Walleij (3): extcon: gpio: Localize platform data extcon: gpio: Move platform data into state container extcon: gpio: Convert to fully use GPIO descriptor Maciej Purski (1): drm/bridge/sii8620: use micro-USB cable detection logic to detect MHL .../connector/samsung,usb-connector-11pin.txt | 49 ++ .../bindings/connector/usb-connector.txt | 75 +++ drivers/extcon/extcon-gpio.c | 103 + drivers/extcon/extcon-intel-cht-wc.c | 11 ++- drivers/extcon/extcon-intel-int3496.c | 9 +- drivers/extcon/extcon.c| 44 +++-- drivers/gpu/drm/bridge/sil-sii8620.c | 97 ++- include/linux/extcon.h | 6 ++ include/linux/extcon/extcon-gpio.h | 47 -- 9 files changed, 315 insertions(+), 126 deletions(-) create mode 100644 Documentation/devicetree/bindings/connector/samsung,usb-connector-11pin.txt create mode 100644 Documentation/devicetree/bindings/connector/usb-connector.txt delete mode 100644 include/linux/extcon/extcon-gpio.h
Re: [PATCH 13/15] mm/hmm: factor out pte and pmd handling to simplify hmm_vma_walk_pmd()
On 03/19/2018 07:00 PM, jgli...@redhat.com wrote: > From: Jérôme Glisse> > No functional change, just create one function to handle pmd and one > to handle pte (hmm_vma_handle_pmd() and hmm_vma_handle_pte()). > > Signed-off-by: Jérôme Glisse > Cc: Evgeny Baskakov > Cc: Ralph Campbell > Cc: Mark Hairgrove > Cc: John Hubbard > --- > mm/hmm.c | 174 > +-- > 1 file changed, 102 insertions(+), 72 deletions(-) > > diff --git a/mm/hmm.c b/mm/hmm.c > index 52cdceb35733..dc703e9c3a95 100644 > --- a/mm/hmm.c > +++ b/mm/hmm.c > @@ -351,6 +351,99 @@ static int hmm_vma_walk_hole(unsigned long addr, > return hmm_vma_walk->fault ? -EAGAIN : 0; > } > > +static int hmm_vma_handle_pmd(struct mm_walk *walk, > + unsigned long addr, > + unsigned long end, > + uint64_t *pfns, Hi Jerome, Nice cleanup, it makes it much easier to follow the code now. Let's please rename the pfns argument above to "pfn", because in this helper (and the _pte helper too), there is only one pfn involved, rather than an array of them. > + pmd_t pmd) > +{ > + struct hmm_vma_walk *hmm_vma_walk = walk->private; > + unsigned long pfn, i; > + uint64_t flag = 0; > + > + if (pmd_protnone(pmd)) > + return hmm_vma_walk_hole(addr, end, walk); > + > + if ((hmm_vma_walk->fault & hmm_vma_walk->write) && !pmd_write(pmd)) > + return hmm_vma_walk_hole(addr, end, walk); > + > + pfn = pmd_pfn(pmd) + pte_index(addr); > + flag |= pmd_write(pmd) ? HMM_PFN_WRITE : 0; > + for (i = 0; addr < end; addr += PAGE_SIZE, i++, pfn++) > + pfns[i] = hmm_pfn_from_pfn(pfn) | flag; > + hmm_vma_walk->last = end; > + return 0; > +} > + > +static int hmm_vma_handle_pte(struct mm_walk *walk, unsigned long addr, > + unsigned long end, pmd_t *pmdp, pte_t *ptep, > + uint64_t *pfns) Same thing here: rename pfns --> pfn. I moved diffs around to attempt to confirm that this is just a refactoring, and it does look the same. It's easy to overlook things here, but: Reviewed-by: John Hubbard thanks, -- John Hubbard NVIDIA > +{ > + struct hmm_vma_walk *hmm_vma_walk = walk->private; > + struct vm_area_struct *vma = walk->vma; > + pte_t pte = *ptep; > + > + *pfns = 0; > + > + if (pte_none(pte)) { > + *pfns = 0; > + if (hmm_vma_walk->fault) > + goto fault; > + return 0; > + } > + > + if (!pte_present(pte)) { > + swp_entry_t entry = pte_to_swp_entry(pte); > + > + if (!non_swap_entry(entry)) { > + if (hmm_vma_walk->fault) > + goto fault; > + return 0; > + } > + > + /* > + * This is a special swap entry, ignore migration, use > + * device and report anything else as error. > + */ > + if (is_device_private_entry(entry)) { > + *pfns = hmm_pfn_from_pfn(swp_offset(entry)); > + if (is_write_device_private_entry(entry)) { > + *pfns |= HMM_PFN_WRITE; > + } else if ((hmm_vma_walk->fault & hmm_vma_walk->write)) > + goto fault; > + *pfns |= HMM_PFN_DEVICE_PRIVATE; > + return 0; > + } > + > + if (is_migration_entry(entry)) { > + if (hmm_vma_walk->fault) { > + pte_unmap(ptep); > + hmm_vma_walk->last = addr; > + migration_entry_wait(vma->vm_mm, > + pmdp, addr); > + return -EAGAIN; > + } > + return 0; > + } > + > + /* Report error for everything else */ > + *pfns = HMM_PFN_ERROR; > + return -EFAULT; > + } > + > + if ((hmm_vma_walk->fault & hmm_vma_walk->write) && !pte_write(pte)) > + goto fault; > + > + *pfns = hmm_pfn_from_pfn(pte_pfn(pte)); > + *pfns |= pte_write(pte) ? HMM_PFN_WRITE : 0; > + return 0; > + > +fault: > + pte_unmap(ptep); > + /* Fault any virtual address we were ask to fault */ > + return hmm_vma_walk_hole(addr, end, walk); > +} > + > static int hmm_vma_walk_pmd(pmd_t *pmdp, > unsigned long start, > unsigned long end, > @@ -358,25 +451,20 @@ static int hmm_vma_walk_pmd(pmd_t *pmdp, > { > struct hmm_vma_walk *hmm_vma_walk = walk->private; > struct
Re: [PATCH 13/15] mm/hmm: factor out pte and pmd handling to simplify hmm_vma_walk_pmd()
On 03/19/2018 07:00 PM, jgli...@redhat.com wrote: > From: Jérôme Glisse > > No functional change, just create one function to handle pmd and one > to handle pte (hmm_vma_handle_pmd() and hmm_vma_handle_pte()). > > Signed-off-by: Jérôme Glisse > Cc: Evgeny Baskakov > Cc: Ralph Campbell > Cc: Mark Hairgrove > Cc: John Hubbard > --- > mm/hmm.c | 174 > +-- > 1 file changed, 102 insertions(+), 72 deletions(-) > > diff --git a/mm/hmm.c b/mm/hmm.c > index 52cdceb35733..dc703e9c3a95 100644 > --- a/mm/hmm.c > +++ b/mm/hmm.c > @@ -351,6 +351,99 @@ static int hmm_vma_walk_hole(unsigned long addr, > return hmm_vma_walk->fault ? -EAGAIN : 0; > } > > +static int hmm_vma_handle_pmd(struct mm_walk *walk, > + unsigned long addr, > + unsigned long end, > + uint64_t *pfns, Hi Jerome, Nice cleanup, it makes it much easier to follow the code now. Let's please rename the pfns argument above to "pfn", because in this helper (and the _pte helper too), there is only one pfn involved, rather than an array of them. > + pmd_t pmd) > +{ > + struct hmm_vma_walk *hmm_vma_walk = walk->private; > + unsigned long pfn, i; > + uint64_t flag = 0; > + > + if (pmd_protnone(pmd)) > + return hmm_vma_walk_hole(addr, end, walk); > + > + if ((hmm_vma_walk->fault & hmm_vma_walk->write) && !pmd_write(pmd)) > + return hmm_vma_walk_hole(addr, end, walk); > + > + pfn = pmd_pfn(pmd) + pte_index(addr); > + flag |= pmd_write(pmd) ? HMM_PFN_WRITE : 0; > + for (i = 0; addr < end; addr += PAGE_SIZE, i++, pfn++) > + pfns[i] = hmm_pfn_from_pfn(pfn) | flag; > + hmm_vma_walk->last = end; > + return 0; > +} > + > +static int hmm_vma_handle_pte(struct mm_walk *walk, unsigned long addr, > + unsigned long end, pmd_t *pmdp, pte_t *ptep, > + uint64_t *pfns) Same thing here: rename pfns --> pfn. I moved diffs around to attempt to confirm that this is just a refactoring, and it does look the same. It's easy to overlook things here, but: Reviewed-by: John Hubbard thanks, -- John Hubbard NVIDIA > +{ > + struct hmm_vma_walk *hmm_vma_walk = walk->private; > + struct vm_area_struct *vma = walk->vma; > + pte_t pte = *ptep; > + > + *pfns = 0; > + > + if (pte_none(pte)) { > + *pfns = 0; > + if (hmm_vma_walk->fault) > + goto fault; > + return 0; > + } > + > + if (!pte_present(pte)) { > + swp_entry_t entry = pte_to_swp_entry(pte); > + > + if (!non_swap_entry(entry)) { > + if (hmm_vma_walk->fault) > + goto fault; > + return 0; > + } > + > + /* > + * This is a special swap entry, ignore migration, use > + * device and report anything else as error. > + */ > + if (is_device_private_entry(entry)) { > + *pfns = hmm_pfn_from_pfn(swp_offset(entry)); > + if (is_write_device_private_entry(entry)) { > + *pfns |= HMM_PFN_WRITE; > + } else if ((hmm_vma_walk->fault & hmm_vma_walk->write)) > + goto fault; > + *pfns |= HMM_PFN_DEVICE_PRIVATE; > + return 0; > + } > + > + if (is_migration_entry(entry)) { > + if (hmm_vma_walk->fault) { > + pte_unmap(ptep); > + hmm_vma_walk->last = addr; > + migration_entry_wait(vma->vm_mm, > + pmdp, addr); > + return -EAGAIN; > + } > + return 0; > + } > + > + /* Report error for everything else */ > + *pfns = HMM_PFN_ERROR; > + return -EFAULT; > + } > + > + if ((hmm_vma_walk->fault & hmm_vma_walk->write) && !pte_write(pte)) > + goto fault; > + > + *pfns = hmm_pfn_from_pfn(pte_pfn(pte)); > + *pfns |= pte_write(pte) ? HMM_PFN_WRITE : 0; > + return 0; > + > +fault: > + pte_unmap(ptep); > + /* Fault any virtual address we were ask to fault */ > + return hmm_vma_walk_hole(addr, end, walk); > +} > + > static int hmm_vma_walk_pmd(pmd_t *pmdp, > unsigned long start, > unsigned long end, > @@ -358,25 +451,20 @@ static int hmm_vma_walk_pmd(pmd_t *pmdp, > { > struct hmm_vma_walk *hmm_vma_walk = walk->private; > struct hmm_range *range = hmm_vma_walk->range; > - struct vm_area_struct *vma = walk->vma; > uint64_t *pfns = range->pfns; > unsigned long addr
Re: [RFC PATCH v2 2/4] mm/__free_one_page: skip merge for order-0 page unless compaction failed
On Tue, Mar 20, 2018 at 09:21:33PM -0700, Figo.zhang wrote: > suppose that in free_one_page() will try to merge to high order anytime , > but now in your patch, > those merge has postponed when system in low memory status, it is very easy > let system trigger > low memory state and get poor performance. Merge or not merge, the size of free memory is not affected.
Re: [RFC PATCH v2 2/4] mm/__free_one_page: skip merge for order-0 page unless compaction failed
On Tue, Mar 20, 2018 at 09:21:33PM -0700, Figo.zhang wrote: > suppose that in free_one_page() will try to merge to high order anytime , > but now in your patch, > those merge has postponed when system in low memory status, it is very easy > let system trigger > low memory state and get poor performance. Merge or not merge, the size of free memory is not affected.
[PATCH V2 6/9] arm64: tegra: Add pwm based fan support on Tegra186
Add pwm fan driver support on Tegra186 SoC. Signed-off-by: Rajkumar Rampelli--- V2: Removed generic-pwm-tachometer driver dt node and using pwm-fan driver for reading fan speed. arch/arm64/boot/dts/nvidia/tegra186.dtsi | 6 ++ 1 file changed, 6 insertions(+) diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi index 19e1afc..27ae73e 100644 --- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi @@ -1053,4 +1053,10 @@ reset-names = "tachometer"; status = "disabled"; }; + + pwm_fan { + compatible = "pwm-fan"; + pwms = <_tachometer 0 100>; + status = "disabled"; + }; }; -- 2.1.4
[PATCH V2 6/9] arm64: tegra: Add pwm based fan support on Tegra186
Add pwm fan driver support on Tegra186 SoC. Signed-off-by: Rajkumar Rampelli --- V2: Removed generic-pwm-tachometer driver dt node and using pwm-fan driver for reading fan speed. arch/arm64/boot/dts/nvidia/tegra186.dtsi | 6 ++ 1 file changed, 6 insertions(+) diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi index 19e1afc..27ae73e 100644 --- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi @@ -1053,4 +1053,10 @@ reset-names = "tachometer"; status = "disabled"; }; + + pwm_fan { + compatible = "pwm-fan"; + pwms = <_tachometer 0 100>; + status = "disabled"; + }; }; -- 2.1.4
[PATCH V2 0/9] Implementation of Tegra Tachometer driver
The following patches adds support for PWM based Tegra Tachometer driver which implements PWM capture interface to analyze the PWM signal of a electronic fan and reports it in periods and duty cycles. Added fan device attribute fan1_input in pwm-fan driver to monitor the speed of fan in rotations per minute using PWM interface. RPM of Fan will be exposed to user interface through HWMON sysfs interface avialable at location: /sys/class/hwmon/hwmon0/fan1_input Steps to validate Tachometer on Tegra186 SoC: A. push modules pwm-tegra.ko, pwm-tegra-tachometer.ko and pwm-fan.ko to linux device using scp command. scp build/tegra186/drivers/pwm/pwm-tegra.ko ubuntu@10.19.65.176:/tmp/ scp build/tegra186/drivers/pwm/pwm-tegra-tachometer.ko ubuntu@10.19.65.176:/tmp/ scp build/tegra186/drivers/hwmon/pwm-fan.ko ubuntu@10.19.65.176:/tmp/ B. On Linux device console, insert these modules using insmod command. insmod /tmp/pwm-tegra.ko insmod /tmp/pwm-tegra-tachometer.ko insmod /tmp/pwm-fan.ko C. Read RPM value at below sysfs node cat /sys/calss/hwmon/hwmon0/fan1_input D. Change the FAN speed using PWM sysfs interface. Follow below steps for the same: a. cd /sys/class/pwm/pwmchip0 b. ls -la (make sure pwm controller is c34.pwm) Output should be: device -> ../../../c34.pwm c. echo 0 > export d. cd pwmchip0:0 e. echo 8000 > period f. echo 1 > enable g. echo 8000 > duty_cycle # change duty_cycles from 0 to 8000 for FAN speed variation h. cat /sys/calss/hwmon/hwmon0/fan1_input i. echo 4000 > duty_cycle h. cat /sys/calss/hwmon/hwmon0/fan1_input i. echo 2000 > duty_cycle h. cat /sys/calss/hwmon/hwmon0/fan1_input i. echo 0 > duty_cycle h. cat /sys/calss/hwmon/hwmon0/fan1_input Rajkumar Rampelli (9): pwm: core: Add support for PWM HW driver with pwm capture only arm64: tegra: Add PWM controller on Tegra186 soc dt-bindings: Tegra186 tachometer device tree bindings arm64: tegra: Add Tachometer Controller on Tegra186 pwm: tegra: Add PWM based Tachometer driver arm64: tegra: Add pwm based fan support on Tegra186 hwmon: pwm-fan: add sysfs node to read rpm of fan arm64: defconfig: enable Nvidia Tegra Tachometer as a module arm64: defconfig: enable pwm-fan as a loadable module .../bindings/pwm/pwm-tegra-tachometer.txt | 31 +++ arch/arm64/boot/dts/nvidia/tegra186-p2771-.dts | 5 + arch/arm64/boot/dts/nvidia/tegra186.dtsi | 28 ++ arch/arm64/configs/defconfig | 2 + drivers/hwmon/pwm-fan.c| 23 ++ drivers/pwm/Kconfig| 10 + drivers/pwm/Makefile | 1 + drivers/pwm/core.c | 21 +- drivers/pwm/pwm-tegra-tachometer.c | 303 + 9 files changed, 418 insertions(+), 6 deletions(-) create mode 100644 Documentation/devicetree/bindings/pwm/pwm-tegra-tachometer.txt create mode 100644 drivers/pwm/pwm-tegra-tachometer.c -- 2.1.4
[PATCH V2 0/9] Implementation of Tegra Tachometer driver
The following patches adds support for PWM based Tegra Tachometer driver which implements PWM capture interface to analyze the PWM signal of a electronic fan and reports it in periods and duty cycles. Added fan device attribute fan1_input in pwm-fan driver to monitor the speed of fan in rotations per minute using PWM interface. RPM of Fan will be exposed to user interface through HWMON sysfs interface avialable at location: /sys/class/hwmon/hwmon0/fan1_input Steps to validate Tachometer on Tegra186 SoC: A. push modules pwm-tegra.ko, pwm-tegra-tachometer.ko and pwm-fan.ko to linux device using scp command. scp build/tegra186/drivers/pwm/pwm-tegra.ko ubuntu@10.19.65.176:/tmp/ scp build/tegra186/drivers/pwm/pwm-tegra-tachometer.ko ubuntu@10.19.65.176:/tmp/ scp build/tegra186/drivers/hwmon/pwm-fan.ko ubuntu@10.19.65.176:/tmp/ B. On Linux device console, insert these modules using insmod command. insmod /tmp/pwm-tegra.ko insmod /tmp/pwm-tegra-tachometer.ko insmod /tmp/pwm-fan.ko C. Read RPM value at below sysfs node cat /sys/calss/hwmon/hwmon0/fan1_input D. Change the FAN speed using PWM sysfs interface. Follow below steps for the same: a. cd /sys/class/pwm/pwmchip0 b. ls -la (make sure pwm controller is c34.pwm) Output should be: device -> ../../../c34.pwm c. echo 0 > export d. cd pwmchip0:0 e. echo 8000 > period f. echo 1 > enable g. echo 8000 > duty_cycle # change duty_cycles from 0 to 8000 for FAN speed variation h. cat /sys/calss/hwmon/hwmon0/fan1_input i. echo 4000 > duty_cycle h. cat /sys/calss/hwmon/hwmon0/fan1_input i. echo 2000 > duty_cycle h. cat /sys/calss/hwmon/hwmon0/fan1_input i. echo 0 > duty_cycle h. cat /sys/calss/hwmon/hwmon0/fan1_input Rajkumar Rampelli (9): pwm: core: Add support for PWM HW driver with pwm capture only arm64: tegra: Add PWM controller on Tegra186 soc dt-bindings: Tegra186 tachometer device tree bindings arm64: tegra: Add Tachometer Controller on Tegra186 pwm: tegra: Add PWM based Tachometer driver arm64: tegra: Add pwm based fan support on Tegra186 hwmon: pwm-fan: add sysfs node to read rpm of fan arm64: defconfig: enable Nvidia Tegra Tachometer as a module arm64: defconfig: enable pwm-fan as a loadable module .../bindings/pwm/pwm-tegra-tachometer.txt | 31 +++ arch/arm64/boot/dts/nvidia/tegra186-p2771-.dts | 5 + arch/arm64/boot/dts/nvidia/tegra186.dtsi | 28 ++ arch/arm64/configs/defconfig | 2 + drivers/hwmon/pwm-fan.c| 23 ++ drivers/pwm/Kconfig| 10 + drivers/pwm/Makefile | 1 + drivers/pwm/core.c | 21 +- drivers/pwm/pwm-tegra-tachometer.c | 303 + 9 files changed, 418 insertions(+), 6 deletions(-) create mode 100644 Documentation/devicetree/bindings/pwm/pwm-tegra-tachometer.txt create mode 100644 drivers/pwm/pwm-tegra-tachometer.c -- 2.1.4
[PATCH 0/1] cover-letter/lz4: Implement lz4 with dynamic offset length.
(Added cover letter to avoid much text in patch description) LZ4 specification defines 2 byte offset length for 64 KB data. But in case of ZRAM we compress data per page and in most of architecture PAGE_SIZE is 4KB. So we can decide offset length based on actual offset value. For this we can reserve 1 bit to decide offset length (1 byte or 2 byte). 2 byte required only if ofsset is greater than 127, else 1 byte is enough. With this new implementation new offset value can be at MAX 32 KB. Thus we can save more memory for compressed data. results checked with new implementation:- comression size for same input source (LZ4_DYN < LZO < LZ4) LZO === orig_data_size: 78917632 compr_data_size: 15894668 mem_used_total: 17117184 LZ4 orig_data_size: 78917632 compr_data_size: 16310717 mem_used_total: 17592320 LZ4_DYN === orig_data_size: 78917632 compr_data_size: 15520506 mem_used_total: 16748544 checked performance with below tool:- https://github.com/sergey-senozhatsky/zram-perf-test # ./fio-perf-o-meter.sh /tmp/test-fio-zram-lz4 /tmp/test-fio-zram-lz4_dyn Processing /tmp/test-fio-zram-lz4 Processing /tmp/test-fio-zram-lz4_dyn #jobs1 WRITE: 1101.7MB/s 1197.7MB/s WRITE: 799829KB/s 900838KB/s READ: 2670.2MB/s 2649.5MB/s READ: 2027.8MB/s 2039.9MB/s READ: 603703KB/s 597855KB/s WRITE: 602943KB/s 597103KB/s READ: 680438KB/s 707986KB/s WRITE: 679582KB/s 707095KB/s #jobs2 WRITE: 1993.2MB/s 2121.2MB/s WRITE: 1654.1MB/s 1700.2MB/s READ: 5038.2MB/s 4970.9MB/s READ: 3930.1MB/s 3908.5MB/s READ: 1113.2MB/s 1117.4MB/s WRITE: .8MB/s 1115.2MB/s READ: 1255.8MB/s 1286.5MB/s WRITE: 1254.2MB/s 1284.9MB/s #jobs3 WRITE: 2875.6MB/s 3010.3MB/s WRITE: 2394.4MB/s 2363.2MB/s READ: 7384.7MB/s 7314.3MB/s READ: 5389.5MB/s 5427.6MB/s READ: 1570.8MB/s 1557.3MB/s WRITE: 1568.8MB/s 1555.3MB/s READ: 1848.5MB/s 1854.0MB/s WRITE: 1846.2MB/s 1851.7MB/s #jobs4 WRITE: 3720.3MB/s 3077.4MB/s WRITE: 3027.4MB/s 3072.8MB/s READ: 9694.7MB/s 9822.6MB/s READ: 6606.5MB/s 6617.2MB/s READ: 1941.6MB/s 1966.8MB/s WRITE: 1939.1MB/s 1964.3MB/s READ: 2405.3MB/s 2347.5MB/s WRITE: 2402.3MB/s 2344.5MB/s #jobs5 WRITE: 3335.6MB/s 3360.7MB/s WRITE: 2670.2MB/s 2677.9MB/s READ: 9455.3MB/s 8782.2MB/s READ: 6534.8MB/s 6501.7MB/s READ: 1848.9MB/s 1858.3MB/s WRITE: 1846.6MB/s 1855.1MB/s READ: 2232.4MB/s 2223.7MB/s WRITE: 2229.6MB/s 2220.9MB/s #jobs6 WRITE: 3896.5MB/s 3772.9MB/s WRITE: 3171.1MB/s 3109.4MB/s READ: 11060MB/s11120MB/s READ: 7375.8MB/s 7384.7MB/s READ: 2132.5MB/s 2133.1MB/s WRITE: 2129.8MB/s 2131.3MB/s READ: 2608.4MB/s 2627.3MB/s WRITE: 2605.7MB/s 2623.2MB/s #jobs7 WRITE: 4129.4MB/s 4083.2MB/s WRITE: 3364.5MB/s 3384.4MB/s READ: 12088MB/s11062MB/s READ: 7868.3MB/s 7851.5MB/s READ: 2277.8MB/s 2291.6MB/s WRITE: 2274.9MB/s 2288.7MB/s READ: 2798.5MB/s 2890.1MB/s WRITE: 2794.1MB/s 2887.4MB/s #jobs8 WRITE: 4623.3MB/s 4794.9MB/s WRITE: 3749.3MB/s 3676.9MB/s READ: 12337MB/s14076MB/s READ: 8320.1MB/s 8229.4MB/s READ: 2496.9MB/s 2486.3MB/s WRITE: 2493.8MB/s 2483.2MB/s READ: 3340.4MB/s 3370.6MB/s WRITE: 3336.2MB/s 3366.4MB/s #jobs9 WRITE: 4427.6MB/s 4341.3MB/s WRITE: 3542.6MB/s 3597.2MB/s READ: 10094MB/s9888.5MB/s READ: 7863.5MB/s 8119.9MB/s READ: 2357.1MB/s 2382.1MB/s WRITE: 2354.1MB/s 2379.1MB/s READ: 2828.8MB/s 2826.2MB/s WRITE: 2825.3MB/s 2822.7MB/s #jobs10 WRITE: 4463.9MB/s 4327.7MB/s WRITE: 3637.7MB/s 3592.4MB/s READ: 10020MB/s8MB/s READ: 7837.8MB/s 8098.7MB/s READ: 2459.6MB/s 2406.5MB/s WRITE: 2456.5MB/s 2403.4MB/s READ: 2804.2MB/s 2829.8MB/s WRITE: 2800.7MB/s 2826.2MB/s jobs1 perfstat stalled-cycles-frontend 20,23,52,25,317 ( 54.32%)19,29,10,49,608 ( 54.50%) instructions44,62,30,88,401 (1.20)42,50,67,71,907 ( 1.20) branches
[PATCH 0/1] cover-letter/lz4: Implement lz4 with dynamic offset length.
(Added cover letter to avoid much text in patch description) LZ4 specification defines 2 byte offset length for 64 KB data. But in case of ZRAM we compress data per page and in most of architecture PAGE_SIZE is 4KB. So we can decide offset length based on actual offset value. For this we can reserve 1 bit to decide offset length (1 byte or 2 byte). 2 byte required only if ofsset is greater than 127, else 1 byte is enough. With this new implementation new offset value can be at MAX 32 KB. Thus we can save more memory for compressed data. results checked with new implementation:- comression size for same input source (LZ4_DYN < LZO < LZ4) LZO === orig_data_size: 78917632 compr_data_size: 15894668 mem_used_total: 17117184 LZ4 orig_data_size: 78917632 compr_data_size: 16310717 mem_used_total: 17592320 LZ4_DYN === orig_data_size: 78917632 compr_data_size: 15520506 mem_used_total: 16748544 checked performance with below tool:- https://github.com/sergey-senozhatsky/zram-perf-test # ./fio-perf-o-meter.sh /tmp/test-fio-zram-lz4 /tmp/test-fio-zram-lz4_dyn Processing /tmp/test-fio-zram-lz4 Processing /tmp/test-fio-zram-lz4_dyn #jobs1 WRITE: 1101.7MB/s 1197.7MB/s WRITE: 799829KB/s 900838KB/s READ: 2670.2MB/s 2649.5MB/s READ: 2027.8MB/s 2039.9MB/s READ: 603703KB/s 597855KB/s WRITE: 602943KB/s 597103KB/s READ: 680438KB/s 707986KB/s WRITE: 679582KB/s 707095KB/s #jobs2 WRITE: 1993.2MB/s 2121.2MB/s WRITE: 1654.1MB/s 1700.2MB/s READ: 5038.2MB/s 4970.9MB/s READ: 3930.1MB/s 3908.5MB/s READ: 1113.2MB/s 1117.4MB/s WRITE: .8MB/s 1115.2MB/s READ: 1255.8MB/s 1286.5MB/s WRITE: 1254.2MB/s 1284.9MB/s #jobs3 WRITE: 2875.6MB/s 3010.3MB/s WRITE: 2394.4MB/s 2363.2MB/s READ: 7384.7MB/s 7314.3MB/s READ: 5389.5MB/s 5427.6MB/s READ: 1570.8MB/s 1557.3MB/s WRITE: 1568.8MB/s 1555.3MB/s READ: 1848.5MB/s 1854.0MB/s WRITE: 1846.2MB/s 1851.7MB/s #jobs4 WRITE: 3720.3MB/s 3077.4MB/s WRITE: 3027.4MB/s 3072.8MB/s READ: 9694.7MB/s 9822.6MB/s READ: 6606.5MB/s 6617.2MB/s READ: 1941.6MB/s 1966.8MB/s WRITE: 1939.1MB/s 1964.3MB/s READ: 2405.3MB/s 2347.5MB/s WRITE: 2402.3MB/s 2344.5MB/s #jobs5 WRITE: 3335.6MB/s 3360.7MB/s WRITE: 2670.2MB/s 2677.9MB/s READ: 9455.3MB/s 8782.2MB/s READ: 6534.8MB/s 6501.7MB/s READ: 1848.9MB/s 1858.3MB/s WRITE: 1846.6MB/s 1855.1MB/s READ: 2232.4MB/s 2223.7MB/s WRITE: 2229.6MB/s 2220.9MB/s #jobs6 WRITE: 3896.5MB/s 3772.9MB/s WRITE: 3171.1MB/s 3109.4MB/s READ: 11060MB/s11120MB/s READ: 7375.8MB/s 7384.7MB/s READ: 2132.5MB/s 2133.1MB/s WRITE: 2129.8MB/s 2131.3MB/s READ: 2608.4MB/s 2627.3MB/s WRITE: 2605.7MB/s 2623.2MB/s #jobs7 WRITE: 4129.4MB/s 4083.2MB/s WRITE: 3364.5MB/s 3384.4MB/s READ: 12088MB/s11062MB/s READ: 7868.3MB/s 7851.5MB/s READ: 2277.8MB/s 2291.6MB/s WRITE: 2274.9MB/s 2288.7MB/s READ: 2798.5MB/s 2890.1MB/s WRITE: 2794.1MB/s 2887.4MB/s #jobs8 WRITE: 4623.3MB/s 4794.9MB/s WRITE: 3749.3MB/s 3676.9MB/s READ: 12337MB/s14076MB/s READ: 8320.1MB/s 8229.4MB/s READ: 2496.9MB/s 2486.3MB/s WRITE: 2493.8MB/s 2483.2MB/s READ: 3340.4MB/s 3370.6MB/s WRITE: 3336.2MB/s 3366.4MB/s #jobs9 WRITE: 4427.6MB/s 4341.3MB/s WRITE: 3542.6MB/s 3597.2MB/s READ: 10094MB/s9888.5MB/s READ: 7863.5MB/s 8119.9MB/s READ: 2357.1MB/s 2382.1MB/s WRITE: 2354.1MB/s 2379.1MB/s READ: 2828.8MB/s 2826.2MB/s WRITE: 2825.3MB/s 2822.7MB/s #jobs10 WRITE: 4463.9MB/s 4327.7MB/s WRITE: 3637.7MB/s 3592.4MB/s READ: 10020MB/s8MB/s READ: 7837.8MB/s 8098.7MB/s READ: 2459.6MB/s 2406.5MB/s WRITE: 2456.5MB/s 2403.4MB/s READ: 2804.2MB/s 2829.8MB/s WRITE: 2800.7MB/s 2826.2MB/s jobs1 perfstat stalled-cycles-frontend 20,23,52,25,317 ( 54.32%)19,29,10,49,608 ( 54.50%) instructions44,62,30,88,401 (1.20)42,50,67,71,907 ( 1.20) branches
[PATCH V2 8/9] arm64: defconfig: enable Nvidia Tegra Tachometer as a module
Tegra Tachometer driver implements PWM capture to measure period. Enable this driver as a module in the ARM64 defconfig. Signed-off-by: Rajkumar Rampelli--- V2: No changes in this patch arch/arm64/configs/defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 634b373..8b2bda7 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -550,6 +550,7 @@ CONFIG_PWM_MESON=m CONFIG_PWM_ROCKCHIP=y CONFIG_PWM_SAMSUNG=y CONFIG_PWM_TEGRA=m +CONFIG_PWM_TEGRA_TACHOMETER=m CONFIG_PHY_RCAR_GEN3_USB2=y CONFIG_PHY_HI6220_USB=y CONFIG_PHY_QCOM_USB_HS=y -- 2.1.4
[PATCH V2 9/9] arm64: defconfig: enable pwm-fan as a loadable module
Enable pwm-fan driver to make use of a PWM interface to read speed of a fan in rotations per minute. Signed-off-by: Rajkumar Rampelli--- V2: Added pwm-fan driver support as a loadable module. Removed generic-pwm-tachometer driver support which was added as part of v1 arch/arm64/configs/defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 8b2bda7..50aa3bce 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -320,6 +320,7 @@ CONFIG_SYSCON_REBOOT_MODE=y CONFIG_BATTERY_BQ27XXX=y CONFIG_SENSORS_ARM_SCPI=y CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_PWM_FAN=m CONFIG_SENSORS_INA2XX=m CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y CONFIG_CPU_THERMAL=y -- 2.1.4
[PATCH V2 8/9] arm64: defconfig: enable Nvidia Tegra Tachometer as a module
Tegra Tachometer driver implements PWM capture to measure period. Enable this driver as a module in the ARM64 defconfig. Signed-off-by: Rajkumar Rampelli --- V2: No changes in this patch arch/arm64/configs/defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 634b373..8b2bda7 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -550,6 +550,7 @@ CONFIG_PWM_MESON=m CONFIG_PWM_ROCKCHIP=y CONFIG_PWM_SAMSUNG=y CONFIG_PWM_TEGRA=m +CONFIG_PWM_TEGRA_TACHOMETER=m CONFIG_PHY_RCAR_GEN3_USB2=y CONFIG_PHY_HI6220_USB=y CONFIG_PHY_QCOM_USB_HS=y -- 2.1.4
[PATCH V2 9/9] arm64: defconfig: enable pwm-fan as a loadable module
Enable pwm-fan driver to make use of a PWM interface to read speed of a fan in rotations per minute. Signed-off-by: Rajkumar Rampelli --- V2: Added pwm-fan driver support as a loadable module. Removed generic-pwm-tachometer driver support which was added as part of v1 arch/arm64/configs/defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 8b2bda7..50aa3bce 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -320,6 +320,7 @@ CONFIG_SYSCON_REBOOT_MODE=y CONFIG_BATTERY_BQ27XXX=y CONFIG_SENSORS_ARM_SCPI=y CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_PWM_FAN=m CONFIG_SENSORS_INA2XX=m CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y CONFIG_CPU_THERMAL=y -- 2.1.4
[PATCH 1/1] lz4: Implement lz4 with dynamic offset length.
LZ4 specification defines 2 byte offset length for 64 KB data. But in case of ZRAM we compress data per page and in most of architecture PAGE_SIZE is 4KB. So we can decide offset length based on actual offset value. For this we can reserve 1 bit to decide offset length (1 byte or 2 byte). 2 byte required only if ofsset is greater than 127, else 1 byte is enough. With this new implementation new offset value can be at MAX 32 KB. Thus we can save more memory for compressed data. results checked with new implementation:- LZO === orig_data_size: 78917632 compr_data_size: 15894668 mem_used_total: 17117184 LZ4 orig_data_size: 78917632 compr_data_size: 16310717 mem_used_total: 17592320 LZ4_DYN === orig_data_size: 78917632 compr_data_size: 15520506 mem_used_total: 16748544 Signed-off-by: Maninder SinghSigned-off-by: Vaneet Narang --- crypto/lz4.c | 64 - drivers/block/zram/zcomp.c |4 ++ fs/pstore/platform.c |2 +- include/linux/lz4.h| 15 ++-- lib/decompress_unlz4.c |2 +- lib/lz4/lz4_compress.c | 84 +++ lib/lz4/lz4_decompress.c | 56 - lib/lz4/lz4defs.h | 11 ++ 8 files changed, 197 insertions(+), 41 deletions(-) diff --git a/crypto/lz4.c b/crypto/lz4.c index 2ce2660..f1a8a20 100644 --- a/crypto/lz4.c +++ b/crypto/lz4.c @@ -67,7 +67,20 @@ static int __lz4_compress_crypto(const u8 *src, unsigned int slen, u8 *dst, unsigned int *dlen, void *ctx) { int out_len = LZ4_compress_default(src, dst, - slen, *dlen, ctx); + slen, *dlen, ctx, false); + + if (!out_len) + return -EINVAL; + + *dlen = out_len; + return 0; +} + +static int __lz4_compress_crypto_dynamic(const u8 *src, unsigned int slen, +u8 *dst, unsigned int *dlen, void *ctx) +{ + int out_len = LZ4_compress_default(src, dst, + slen, *dlen, ctx, true); if (!out_len) return -EINVAL; @@ -91,10 +104,30 @@ static int lz4_compress_crypto(struct crypto_tfm *tfm, const u8 *src, return __lz4_compress_crypto(src, slen, dst, dlen, ctx->lz4_comp_mem); } +static int lz4_compress_crypto_dynamic(struct crypto_tfm *tfm, const u8 *src, + unsigned int slen, u8 *dst, unsigned int *dlen) +{ + struct lz4_ctx *ctx = crypto_tfm_ctx(tfm); + + return __lz4_compress_crypto_dynamic(src, slen, dst, dlen, ctx->lz4_comp_mem); +} + static int __lz4_decompress_crypto(const u8 *src, unsigned int slen, u8 *dst, unsigned int *dlen, void *ctx) { - int out_len = LZ4_decompress_safe(src, dst, slen, *dlen); + int out_len = LZ4_decompress_safe(src, dst, slen, *dlen, false); + + if (out_len < 0) + return -EINVAL; + + *dlen = out_len; + return 0; +} + +static int __lz4_decompress_crypto_dynamic(const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen, void *ctx) +{ + int out_len = LZ4_decompress_safe(src, dst, slen, *dlen, true); if (out_len < 0) return -EINVAL; @@ -117,6 +150,13 @@ static int lz4_decompress_crypto(struct crypto_tfm *tfm, const u8 *src, return __lz4_decompress_crypto(src, slen, dst, dlen, NULL); } +static int lz4_decompress_crypto_dynamic(struct crypto_tfm *tfm, const u8 *src, +unsigned int slen, u8 *dst, +unsigned int *dlen) +{ + return __lz4_decompress_crypto_dynamic(src, slen, dst, dlen, NULL); +} + static struct crypto_alg alg_lz4 = { .cra_name = "lz4", .cra_flags = CRYPTO_ALG_TYPE_COMPRESS, @@ -130,6 +170,19 @@ static int lz4_decompress_crypto(struct crypto_tfm *tfm, const u8 *src, .coa_decompress = lz4_decompress_crypto } } }; +static struct crypto_alg alg_lz4_dyn = { + .cra_name = "lz4_dyn", + .cra_flags = CRYPTO_ALG_TYPE_COMPRESS, + .cra_ctxsize= sizeof(struct lz4_ctx), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(alg_lz4_dyn.cra_list), + .cra_init = lz4_init, + .cra_exit = lz4_exit, + .cra_u = { .compress = { + .coa_compress = lz4_compress_crypto_dynamic, + .coa_decompress = lz4_decompress_crypto_dynamic } } +}; + static struct scomp_alg scomp = { .alloc_ctx = lz4_alloc_ctx, .free_ctx = lz4_free_ctx, @@ -150,9 +203,16 @@ static int __init lz4_mod_init(void) if (ret) return ret; + ret = crypto_register_alg(_lz4_dyn); + if (ret) {
[PATCH V2 7/9] hwmon: pwm-fan: add sysfs node to read rpm of fan
Add fan device attribute fan1_input in pwm-fan driver to read speed of fan in rotations per minute. Signed-off-by: Rajkumar Rampelli--- V2: Removed generic-pwm-tachometer driver and using pwm-fan driver as per suggestions to read fan speed. Added fan device attribute to report speed of fan in rpms through hwmon sysfs. drivers/hwmon/pwm-fan.c | 23 +++ 1 file changed, 23 insertions(+) diff --git a/drivers/hwmon/pwm-fan.c b/drivers/hwmon/pwm-fan.c index 70cc0d1..8dda209 100644 --- a/drivers/hwmon/pwm-fan.c +++ b/drivers/hwmon/pwm-fan.c @@ -98,11 +98,34 @@ static ssize_t show_pwm(struct device *dev, return sprintf(buf, "%u\n", ctx->pwm_value); } +static ssize_t show_rpm(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct pwm_fan_ctx *ptt = dev_get_drvdata(dev); + struct pwm_device *pwm = ptt->pwm; + struct pwm_capture result; + unsigned int rpm = 0; + int ret; + + ret = pwm_capture(pwm, , 0); + if (ret < 0) { + pr_err("Failed to capture PWM: %d\n", ret); + return ret; + } + + if (result.period) + rpm = DIV_ROUND_CLOSEST_ULL(60ULL * NSEC_PER_SEC, + result.period); + + return sprintf(buf, "%u\n", rpm); +} static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 0); +static SENSOR_DEVICE_ATTR(fan1_input, 0444, show_rpm, NULL, 0); static struct attribute *pwm_fan_attrs[] = { _dev_attr_pwm1.dev_attr.attr, + _dev_attr_fan1_input.dev_attr.attr, NULL, }; -- 2.1.4
[PATCH V2 7/9] hwmon: pwm-fan: add sysfs node to read rpm of fan
Add fan device attribute fan1_input in pwm-fan driver to read speed of fan in rotations per minute. Signed-off-by: Rajkumar Rampelli --- V2: Removed generic-pwm-tachometer driver and using pwm-fan driver as per suggestions to read fan speed. Added fan device attribute to report speed of fan in rpms through hwmon sysfs. drivers/hwmon/pwm-fan.c | 23 +++ 1 file changed, 23 insertions(+) diff --git a/drivers/hwmon/pwm-fan.c b/drivers/hwmon/pwm-fan.c index 70cc0d1..8dda209 100644 --- a/drivers/hwmon/pwm-fan.c +++ b/drivers/hwmon/pwm-fan.c @@ -98,11 +98,34 @@ static ssize_t show_pwm(struct device *dev, return sprintf(buf, "%u\n", ctx->pwm_value); } +static ssize_t show_rpm(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct pwm_fan_ctx *ptt = dev_get_drvdata(dev); + struct pwm_device *pwm = ptt->pwm; + struct pwm_capture result; + unsigned int rpm = 0; + int ret; + + ret = pwm_capture(pwm, , 0); + if (ret < 0) { + pr_err("Failed to capture PWM: %d\n", ret); + return ret; + } + + if (result.period) + rpm = DIV_ROUND_CLOSEST_ULL(60ULL * NSEC_PER_SEC, + result.period); + + return sprintf(buf, "%u\n", rpm); +} static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 0); +static SENSOR_DEVICE_ATTR(fan1_input, 0444, show_rpm, NULL, 0); static struct attribute *pwm_fan_attrs[] = { _dev_attr_pwm1.dev_attr.attr, + _dev_attr_fan1_input.dev_attr.attr, NULL, }; -- 2.1.4
[PATCH 1/1] lz4: Implement lz4 with dynamic offset length.
LZ4 specification defines 2 byte offset length for 64 KB data. But in case of ZRAM we compress data per page and in most of architecture PAGE_SIZE is 4KB. So we can decide offset length based on actual offset value. For this we can reserve 1 bit to decide offset length (1 byte or 2 byte). 2 byte required only if ofsset is greater than 127, else 1 byte is enough. With this new implementation new offset value can be at MAX 32 KB. Thus we can save more memory for compressed data. results checked with new implementation:- LZO === orig_data_size: 78917632 compr_data_size: 15894668 mem_used_total: 17117184 LZ4 orig_data_size: 78917632 compr_data_size: 16310717 mem_used_total: 17592320 LZ4_DYN === orig_data_size: 78917632 compr_data_size: 15520506 mem_used_total: 16748544 Signed-off-by: Maninder Singh Signed-off-by: Vaneet Narang --- crypto/lz4.c | 64 - drivers/block/zram/zcomp.c |4 ++ fs/pstore/platform.c |2 +- include/linux/lz4.h| 15 ++-- lib/decompress_unlz4.c |2 +- lib/lz4/lz4_compress.c | 84 +++ lib/lz4/lz4_decompress.c | 56 - lib/lz4/lz4defs.h | 11 ++ 8 files changed, 197 insertions(+), 41 deletions(-) diff --git a/crypto/lz4.c b/crypto/lz4.c index 2ce2660..f1a8a20 100644 --- a/crypto/lz4.c +++ b/crypto/lz4.c @@ -67,7 +67,20 @@ static int __lz4_compress_crypto(const u8 *src, unsigned int slen, u8 *dst, unsigned int *dlen, void *ctx) { int out_len = LZ4_compress_default(src, dst, - slen, *dlen, ctx); + slen, *dlen, ctx, false); + + if (!out_len) + return -EINVAL; + + *dlen = out_len; + return 0; +} + +static int __lz4_compress_crypto_dynamic(const u8 *src, unsigned int slen, +u8 *dst, unsigned int *dlen, void *ctx) +{ + int out_len = LZ4_compress_default(src, dst, + slen, *dlen, ctx, true); if (!out_len) return -EINVAL; @@ -91,10 +104,30 @@ static int lz4_compress_crypto(struct crypto_tfm *tfm, const u8 *src, return __lz4_compress_crypto(src, slen, dst, dlen, ctx->lz4_comp_mem); } +static int lz4_compress_crypto_dynamic(struct crypto_tfm *tfm, const u8 *src, + unsigned int slen, u8 *dst, unsigned int *dlen) +{ + struct lz4_ctx *ctx = crypto_tfm_ctx(tfm); + + return __lz4_compress_crypto_dynamic(src, slen, dst, dlen, ctx->lz4_comp_mem); +} + static int __lz4_decompress_crypto(const u8 *src, unsigned int slen, u8 *dst, unsigned int *dlen, void *ctx) { - int out_len = LZ4_decompress_safe(src, dst, slen, *dlen); + int out_len = LZ4_decompress_safe(src, dst, slen, *dlen, false); + + if (out_len < 0) + return -EINVAL; + + *dlen = out_len; + return 0; +} + +static int __lz4_decompress_crypto_dynamic(const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen, void *ctx) +{ + int out_len = LZ4_decompress_safe(src, dst, slen, *dlen, true); if (out_len < 0) return -EINVAL; @@ -117,6 +150,13 @@ static int lz4_decompress_crypto(struct crypto_tfm *tfm, const u8 *src, return __lz4_decompress_crypto(src, slen, dst, dlen, NULL); } +static int lz4_decompress_crypto_dynamic(struct crypto_tfm *tfm, const u8 *src, +unsigned int slen, u8 *dst, +unsigned int *dlen) +{ + return __lz4_decompress_crypto_dynamic(src, slen, dst, dlen, NULL); +} + static struct crypto_alg alg_lz4 = { .cra_name = "lz4", .cra_flags = CRYPTO_ALG_TYPE_COMPRESS, @@ -130,6 +170,19 @@ static int lz4_decompress_crypto(struct crypto_tfm *tfm, const u8 *src, .coa_decompress = lz4_decompress_crypto } } }; +static struct crypto_alg alg_lz4_dyn = { + .cra_name = "lz4_dyn", + .cra_flags = CRYPTO_ALG_TYPE_COMPRESS, + .cra_ctxsize= sizeof(struct lz4_ctx), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(alg_lz4_dyn.cra_list), + .cra_init = lz4_init, + .cra_exit = lz4_exit, + .cra_u = { .compress = { + .coa_compress = lz4_compress_crypto_dynamic, + .coa_decompress = lz4_decompress_crypto_dynamic } } +}; + static struct scomp_alg scomp = { .alloc_ctx = lz4_alloc_ctx, .free_ctx = lz4_free_ctx, @@ -150,9 +203,16 @@ static int __init lz4_mod_init(void) if (ret) return ret; + ret = crypto_register_alg(_lz4_dyn); + if (ret) { + crypto_unregister_alg(_lz4); +
[PATCH V2 5/9] pwm: tegra: Add PWM based Tachometer driver
PWM Tachometer driver capture the PWM signal which is output of FAN in general and provide the period of PWM signal which is converted to RPM by SW. Add Tegra Tachometer driver which implements the pwm-capture to measure period. Signed-off-by: Rajkumar RampelliSigned-off-by: Laxman Dewangan --- V2: Renamed compatible string to "nvidia-tegra186-pwm-tachometer" Renamed arguments of reset and clk apis to "tachometer" from "tach" drivers/pwm/Kconfig| 10 ++ drivers/pwm/Makefile | 1 + drivers/pwm/pwm-tegra-tachometer.c | 303 + 3 files changed, 314 insertions(+) create mode 100644 drivers/pwm/pwm-tegra-tachometer.c diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index 763ee50..29aeeeb 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -454,6 +454,16 @@ config PWM_TEGRA To compile this driver as a module, choose M here: the module will be called pwm-tegra. +config PWM_TEGRA_TACHOMETER + tristate "NVIDIA Tegra Tachometer PWM driver" + depends on ARCH_TEGRA + help + NVIDIA Tegra Tachometer reads the PWM signal and reports the PWM + signal periods. This helps in measuring the fan speed where Fan + output for speed is PWM signal. + + This driver support the Tachometer driver in PWM framework. + config PWM_TIECAP tristate "ECAP PWM support" depends on ARCH_OMAP2PLUS || ARCH_DAVINCI_DA8XX || ARCH_KEYSTONE diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile index 0258a74..14c183e 100644 --- a/drivers/pwm/Makefile +++ b/drivers/pwm/Makefile @@ -45,6 +45,7 @@ obj-$(CONFIG_PWM_STM32_LP)+= pwm-stm32-lp.o obj-$(CONFIG_PWM_STMPE)+= pwm-stmpe.o obj-$(CONFIG_PWM_SUN4I)+= pwm-sun4i.o obj-$(CONFIG_PWM_TEGRA)+= pwm-tegra.o +obj-$(CONFIG_PWM_TEGRA_TACHOMETER) += pwm-tegra-tachometer.o obj-$(CONFIG_PWM_TIECAP) += pwm-tiecap.o obj-$(CONFIG_PWM_TIEHRPWM) += pwm-tiehrpwm.o obj-$(CONFIG_PWM_TIPWMSS) += pwm-tipwmss.o diff --git a/drivers/pwm/pwm-tegra-tachometer.c b/drivers/pwm/pwm-tegra-tachometer.c new file mode 100644 index 000..bcc44ce --- /dev/null +++ b/drivers/pwm/pwm-tegra-tachometer.c @@ -0,0 +1,303 @@ +/* + * Tegra Tachometer Pulse-Width-Modulation driver + * + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Since oscillator clock (38.4MHz) serves as a clock source for + * the tach input controller, 1.0105263MHz (i.e. 38.4/38) has to be + * used as a clock value in the RPM calculations + */ +#define TACH_COUNTER_CLK 1010526 + +#define TACH_FAN_TACH0 0x0 +#define TACH_FAN_TACH0_PERIOD_MASK 0x7 +#define TACH_FAN_TACH0_PERIOD_MAX 0x7 +#define TACH_FAN_TACH0_PERIOD_MIN 0x0 +#define TACH_FAN_TACH0_WIN_LENGTH_SHIFT25 +#define TACH_FAN_TACH0_WIN_LENGTH_MASK 0x3 +#define TACH_FAN_TACH0_OVERFLOW_MASK BIT(24) + +#define TACH_FAN_TACH1 0x4 +#define TACH_FAN_TACH1_HI_MASK 0x7 +/* + * struct pwm_tegra_tach - Tegra tachometer object + * @dev: device providing the Tachometer + * @pulse_per_rev: Pulses per revolution of a Fan + * @capture_window_len: Defines the window of the FAN TACH monitor + * @regs: physical base addresses of the controller + * @clk: phandle list of tachometer clocks + * @rst: phandle to reset the controller + * @chip: PWM chip providing this PWM device + */ +struct pwm_tegra_tach { + struct device *dev; + void __iomem*regs; + struct clk *clk; + struct reset_control*rst; + u32 pulse_per_rev; + u32 capture_window_len; + struct pwm_chip chip; +}; + +static struct pwm_tegra_tach *to_tegra_pwm_chip(struct pwm_chip *chip) +{ + return container_of(chip, struct pwm_tegra_tach, chip); +} + +static u32 tachometer_readl(struct pwm_tegra_tach *ptt, unsigned long reg) +{ + return readl(ptt->regs + reg); +} + +static inline void tachometer_writel(struct pwm_tegra_tach *ptt, u32 val, +unsigned long reg) +{ + writel(val, ptt->regs + reg); +} + +static int
[PATCH V2 5/9] pwm: tegra: Add PWM based Tachometer driver
PWM Tachometer driver capture the PWM signal which is output of FAN in general and provide the period of PWM signal which is converted to RPM by SW. Add Tegra Tachometer driver which implements the pwm-capture to measure period. Signed-off-by: Rajkumar Rampelli Signed-off-by: Laxman Dewangan --- V2: Renamed compatible string to "nvidia-tegra186-pwm-tachometer" Renamed arguments of reset and clk apis to "tachometer" from "tach" drivers/pwm/Kconfig| 10 ++ drivers/pwm/Makefile | 1 + drivers/pwm/pwm-tegra-tachometer.c | 303 + 3 files changed, 314 insertions(+) create mode 100644 drivers/pwm/pwm-tegra-tachometer.c diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index 763ee50..29aeeeb 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -454,6 +454,16 @@ config PWM_TEGRA To compile this driver as a module, choose M here: the module will be called pwm-tegra. +config PWM_TEGRA_TACHOMETER + tristate "NVIDIA Tegra Tachometer PWM driver" + depends on ARCH_TEGRA + help + NVIDIA Tegra Tachometer reads the PWM signal and reports the PWM + signal periods. This helps in measuring the fan speed where Fan + output for speed is PWM signal. + + This driver support the Tachometer driver in PWM framework. + config PWM_TIECAP tristate "ECAP PWM support" depends on ARCH_OMAP2PLUS || ARCH_DAVINCI_DA8XX || ARCH_KEYSTONE diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile index 0258a74..14c183e 100644 --- a/drivers/pwm/Makefile +++ b/drivers/pwm/Makefile @@ -45,6 +45,7 @@ obj-$(CONFIG_PWM_STM32_LP)+= pwm-stm32-lp.o obj-$(CONFIG_PWM_STMPE)+= pwm-stmpe.o obj-$(CONFIG_PWM_SUN4I)+= pwm-sun4i.o obj-$(CONFIG_PWM_TEGRA)+= pwm-tegra.o +obj-$(CONFIG_PWM_TEGRA_TACHOMETER) += pwm-tegra-tachometer.o obj-$(CONFIG_PWM_TIECAP) += pwm-tiecap.o obj-$(CONFIG_PWM_TIEHRPWM) += pwm-tiehrpwm.o obj-$(CONFIG_PWM_TIPWMSS) += pwm-tipwmss.o diff --git a/drivers/pwm/pwm-tegra-tachometer.c b/drivers/pwm/pwm-tegra-tachometer.c new file mode 100644 index 000..bcc44ce --- /dev/null +++ b/drivers/pwm/pwm-tegra-tachometer.c @@ -0,0 +1,303 @@ +/* + * Tegra Tachometer Pulse-Width-Modulation driver + * + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Since oscillator clock (38.4MHz) serves as a clock source for + * the tach input controller, 1.0105263MHz (i.e. 38.4/38) has to be + * used as a clock value in the RPM calculations + */ +#define TACH_COUNTER_CLK 1010526 + +#define TACH_FAN_TACH0 0x0 +#define TACH_FAN_TACH0_PERIOD_MASK 0x7 +#define TACH_FAN_TACH0_PERIOD_MAX 0x7 +#define TACH_FAN_TACH0_PERIOD_MIN 0x0 +#define TACH_FAN_TACH0_WIN_LENGTH_SHIFT25 +#define TACH_FAN_TACH0_WIN_LENGTH_MASK 0x3 +#define TACH_FAN_TACH0_OVERFLOW_MASK BIT(24) + +#define TACH_FAN_TACH1 0x4 +#define TACH_FAN_TACH1_HI_MASK 0x7 +/* + * struct pwm_tegra_tach - Tegra tachometer object + * @dev: device providing the Tachometer + * @pulse_per_rev: Pulses per revolution of a Fan + * @capture_window_len: Defines the window of the FAN TACH monitor + * @regs: physical base addresses of the controller + * @clk: phandle list of tachometer clocks + * @rst: phandle to reset the controller + * @chip: PWM chip providing this PWM device + */ +struct pwm_tegra_tach { + struct device *dev; + void __iomem*regs; + struct clk *clk; + struct reset_control*rst; + u32 pulse_per_rev; + u32 capture_window_len; + struct pwm_chip chip; +}; + +static struct pwm_tegra_tach *to_tegra_pwm_chip(struct pwm_chip *chip) +{ + return container_of(chip, struct pwm_tegra_tach, chip); +} + +static u32 tachometer_readl(struct pwm_tegra_tach *ptt, unsigned long reg) +{ + return readl(ptt->regs + reg); +} + +static inline void tachometer_writel(struct pwm_tegra_tach *ptt, u32 val, +unsigned long reg) +{ + writel(val, ptt->regs + reg); +} + +static int pwm_tegra_tach_set_wlen(struct pwm_tegra_tach *ptt, +
[PATCH V2 1/9] pwm: core: Add support for PWM HW driver with pwm capture only
Add support for pwm HW driver which has only capture functionality. This helps to implement the PWM based Tachometer driver which reads the PWM output signals from electronic fans. PWM Tachometer captures the period and duty cycle of the PWM signal Add conditional checks for callabacks enable(), disable(), config() to check if they are supported by the client driver or not. Skip these callbacks if they are not supported. Signed-off-by: Rajkumar Rampelli--- V2: Added if conditional checks for pwm callbacks since drivers may implements only pwm capture functionality. drivers/pwm/core.c | 21 +++-- 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index 1581f6a..f70fe68 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c @@ -246,6 +246,10 @@ static bool pwm_ops_check(const struct pwm_ops *ops) if (ops->apply) return true; + /* driver supports capture operation */ + if (ops->capture) + return true; + return false; } @@ -495,7 +499,8 @@ int pwm_apply_state(struct pwm_device *pwm, struct pwm_state *state) * ->apply(). */ if (pwm->state.enabled) { - pwm->chip->ops->disable(pwm->chip, pwm); + if (pwm->chip->ops->disable) + pwm->chip->ops->disable(pwm->chip, pwm); pwm->state.enabled = false; } @@ -509,22 +514,26 @@ int pwm_apply_state(struct pwm_device *pwm, struct pwm_state *state) if (state->period != pwm->state.period || state->duty_cycle != pwm->state.duty_cycle) { - err = pwm->chip->ops->config(pwm->chip, pwm, + if (pwm->chip->ops->config) { + err = pwm->chip->ops->config(pwm->chip, pwm, state->duty_cycle, state->period); - if (err) - return err; + if (err) + return err; + } pwm->state.duty_cycle = state->duty_cycle; pwm->state.period = state->period; } if (state->enabled != pwm->state.enabled) { - if (state->enabled) { + if (state->enabled && pwm->chip->ops->enable) { err = pwm->chip->ops->enable(pwm->chip, pwm); if (err) return err; - } else { + } + + if (!state->enabled && pwm->chip->ops->disable) { pwm->chip->ops->disable(pwm->chip, pwm); } -- 2.1.4
[PATCH V2 1/9] pwm: core: Add support for PWM HW driver with pwm capture only
Add support for pwm HW driver which has only capture functionality. This helps to implement the PWM based Tachometer driver which reads the PWM output signals from electronic fans. PWM Tachometer captures the period and duty cycle of the PWM signal Add conditional checks for callabacks enable(), disable(), config() to check if they are supported by the client driver or not. Skip these callbacks if they are not supported. Signed-off-by: Rajkumar Rampelli --- V2: Added if conditional checks for pwm callbacks since drivers may implements only pwm capture functionality. drivers/pwm/core.c | 21 +++-- 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index 1581f6a..f70fe68 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c @@ -246,6 +246,10 @@ static bool pwm_ops_check(const struct pwm_ops *ops) if (ops->apply) return true; + /* driver supports capture operation */ + if (ops->capture) + return true; + return false; } @@ -495,7 +499,8 @@ int pwm_apply_state(struct pwm_device *pwm, struct pwm_state *state) * ->apply(). */ if (pwm->state.enabled) { - pwm->chip->ops->disable(pwm->chip, pwm); + if (pwm->chip->ops->disable) + pwm->chip->ops->disable(pwm->chip, pwm); pwm->state.enabled = false; } @@ -509,22 +514,26 @@ int pwm_apply_state(struct pwm_device *pwm, struct pwm_state *state) if (state->period != pwm->state.period || state->duty_cycle != pwm->state.duty_cycle) { - err = pwm->chip->ops->config(pwm->chip, pwm, + if (pwm->chip->ops->config) { + err = pwm->chip->ops->config(pwm->chip, pwm, state->duty_cycle, state->period); - if (err) - return err; + if (err) + return err; + } pwm->state.duty_cycle = state->duty_cycle; pwm->state.period = state->period; } if (state->enabled != pwm->state.enabled) { - if (state->enabled) { + if (state->enabled && pwm->chip->ops->enable) { err = pwm->chip->ops->enable(pwm->chip, pwm); if (err) return err; - } else { + } + + if (!state->enabled && pwm->chip->ops->disable) { pwm->chip->ops->disable(pwm->chip, pwm); } -- 2.1.4
[PATCH V2 4/9] arm64: tegra: Add Tachometer Controller on Tegra186
The NVIDIA Tegra186 SoC has a Tachometer Controller that analyzes the PWM signal of a Fan and reports the period value through pwm interface. Signed-off-by: Rajkumar Rampelli--- V2: Renamed clock-names/reset-names dt properties values to "tachometer" Renamed compatible property value to "nvidia-tegra186-pwm-tachometer" arch/arm64/boot/dts/nvidia/tegra186-p2771-.dts | 5 + arch/arm64/boot/dts/nvidia/tegra186.dtsi | 11 +++ 2 files changed, 16 insertions(+) diff --git a/arch/arm64/boot/dts/nvidia/tegra186-p2771-.dts b/arch/arm64/boot/dts/nvidia/tegra186-p2771-.dts index bd5305a..13c3e59 100644 --- a/arch/arm64/boot/dts/nvidia/tegra186-p2771-.dts +++ b/arch/arm64/boot/dts/nvidia/tegra186-p2771-.dts @@ -172,4 +172,9 @@ vin-supply = <_5v0_sys>; }; }; + + tachometer@39c { + nvidia,pulse-per-rev = <2>; + nvidia,capture-window-len = <2>; + }; }; diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi index 731cd01..19e1afc 100644 --- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi @@ -1042,4 +1042,15 @@ reset-names = "pwm"; status = "disabled"; }; + + tegra_tachometer: tachometer@39c { + compatible = "nvidia,tegra186-pwm-tachometer"; + reg = <0x0 0x039c 0x0 0x10>; + #pwm-cells = <2>; + clocks = < TEGRA186_CLK_TACH>; + clock-names = "tachometer"; + resets = < TEGRA186_RESET_TACH>; + reset-names = "tachometer"; + status = "disabled"; + }; }; -- 2.1.4
[PATCH V2 4/9] arm64: tegra: Add Tachometer Controller on Tegra186
The NVIDIA Tegra186 SoC has a Tachometer Controller that analyzes the PWM signal of a Fan and reports the period value through pwm interface. Signed-off-by: Rajkumar Rampelli --- V2: Renamed clock-names/reset-names dt properties values to "tachometer" Renamed compatible property value to "nvidia-tegra186-pwm-tachometer" arch/arm64/boot/dts/nvidia/tegra186-p2771-.dts | 5 + arch/arm64/boot/dts/nvidia/tegra186.dtsi | 11 +++ 2 files changed, 16 insertions(+) diff --git a/arch/arm64/boot/dts/nvidia/tegra186-p2771-.dts b/arch/arm64/boot/dts/nvidia/tegra186-p2771-.dts index bd5305a..13c3e59 100644 --- a/arch/arm64/boot/dts/nvidia/tegra186-p2771-.dts +++ b/arch/arm64/boot/dts/nvidia/tegra186-p2771-.dts @@ -172,4 +172,9 @@ vin-supply = <_5v0_sys>; }; }; + + tachometer@39c { + nvidia,pulse-per-rev = <2>; + nvidia,capture-window-len = <2>; + }; }; diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi index 731cd01..19e1afc 100644 --- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi @@ -1042,4 +1042,15 @@ reset-names = "pwm"; status = "disabled"; }; + + tegra_tachometer: tachometer@39c { + compatible = "nvidia,tegra186-pwm-tachometer"; + reg = <0x0 0x039c 0x0 0x10>; + #pwm-cells = <2>; + clocks = < TEGRA186_CLK_TACH>; + clock-names = "tachometer"; + resets = < TEGRA186_RESET_TACH>; + reset-names = "tachometer"; + status = "disabled"; + }; }; -- 2.1.4
[PATCH V2 2/9] arm64: tegra: Add PWM controller on Tegra186 soc
The NVIDIA Tegra186 SoC has a PWM controller which is used in FAN control use case. Signed-off-by: Rajkumar Rampelli--- V2: no changes in this patch arch/arm64/boot/dts/nvidia/tegra186.dtsi | 11 +++ 1 file changed, 11 insertions(+) diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi index b762227..731cd01 100644 --- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi @@ -1031,4 +1031,15 @@ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>; interrupt-parent = <>; }; + + pwm@c34 { + compatible = "nvidia,tegra186-pwm"; + reg = <0x0 0xc34 0x0 0x1>; + clocks = < TEGRA186_CLK_PWM4>; + clock-names = "pwm"; + #pwm-cells = <2>; + resets = < TEGRA186_RESET_PWM4>; + reset-names = "pwm"; + status = "disabled"; + }; }; -- 2.1.4
[PATCH V2 3/9] dt-bindings: Tegra186 tachometer device tree bindings
Supply Device tree binding documentation for the NVIDIA Tegra186 SoC's Tachometer Controller Signed-off-by: Rajkumar Rampelli--- V2: Renamed compatible string to "nvidia,tegra186-pwm-tachometer" Renamed dt property values of clock-names and reset-names to "tachometer" from "tach" .../bindings/pwm/pwm-tegra-tachometer.txt | 31 ++ 1 file changed, 31 insertions(+) create mode 100644 Documentation/devicetree/bindings/pwm/pwm-tegra-tachometer.txt diff --git a/Documentation/devicetree/bindings/pwm/pwm-tegra-tachometer.txt b/Documentation/devicetree/bindings/pwm/pwm-tegra-tachometer.txt new file mode 100644 index 000..4a7ead4 --- /dev/null +++ b/Documentation/devicetree/bindings/pwm/pwm-tegra-tachometer.txt @@ -0,0 +1,31 @@ +Bindings for a PWM based Tachometer driver + +Required properties: +- compatible: Must be "nvidia,tegra186-pwm-tachometer" +- reg: physical base addresses of the controller and length of + memory mapped region. +- #pwm-cells: should be 2. See pwm.txt in this directory for a + description of the cells format. +- clocks: phandle list of tachometer clocks +- clock-names: should be "tachometer". See clock-bindings.txt in documentations +- resets: phandle to the reset controller for the Tachometer IP +- reset-names: should be "tachometer". See reset.txt in documentations +- nvidia,pulse-per-rev: Integer, pulses per revolution of a Fan. This value + obtained from Fan specification document. +- nvidia,capture-window-len: Integer, window of the Fan Tach monitor, it indicates + that how many period of the input fan tach signal will the FAN TACH logic + monitor. Valid values are 1, 2, 4 and 8 only. + +Example: + tegra_tachometer: tachometer@39c { + compatible = "nvidia,tegra186-pwm-tachometer"; + reg = <0x0 0x039c 0x0 0x10>; + #pwm-cells = <2>; + clocks = <_car TEGRA186_CLK_TACH>; + clock-names = "tachometer"; + resets = <_car TEGRA186_RESET_TACH>; + reset-names = "tachometer"; + nvidia,pulse-per-rev = <2>; + nvidia,capture-window-len = <2>; + status = "disabled"; + }; -- 2.1.4
[PATCH V2 2/9] arm64: tegra: Add PWM controller on Tegra186 soc
The NVIDIA Tegra186 SoC has a PWM controller which is used in FAN control use case. Signed-off-by: Rajkumar Rampelli --- V2: no changes in this patch arch/arm64/boot/dts/nvidia/tegra186.dtsi | 11 +++ 1 file changed, 11 insertions(+) diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi index b762227..731cd01 100644 --- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi @@ -1031,4 +1031,15 @@ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>; interrupt-parent = <>; }; + + pwm@c34 { + compatible = "nvidia,tegra186-pwm"; + reg = <0x0 0xc34 0x0 0x1>; + clocks = < TEGRA186_CLK_PWM4>; + clock-names = "pwm"; + #pwm-cells = <2>; + resets = < TEGRA186_RESET_PWM4>; + reset-names = "pwm"; + status = "disabled"; + }; }; -- 2.1.4
[PATCH V2 3/9] dt-bindings: Tegra186 tachometer device tree bindings
Supply Device tree binding documentation for the NVIDIA Tegra186 SoC's Tachometer Controller Signed-off-by: Rajkumar Rampelli --- V2: Renamed compatible string to "nvidia,tegra186-pwm-tachometer" Renamed dt property values of clock-names and reset-names to "tachometer" from "tach" .../bindings/pwm/pwm-tegra-tachometer.txt | 31 ++ 1 file changed, 31 insertions(+) create mode 100644 Documentation/devicetree/bindings/pwm/pwm-tegra-tachometer.txt diff --git a/Documentation/devicetree/bindings/pwm/pwm-tegra-tachometer.txt b/Documentation/devicetree/bindings/pwm/pwm-tegra-tachometer.txt new file mode 100644 index 000..4a7ead4 --- /dev/null +++ b/Documentation/devicetree/bindings/pwm/pwm-tegra-tachometer.txt @@ -0,0 +1,31 @@ +Bindings for a PWM based Tachometer driver + +Required properties: +- compatible: Must be "nvidia,tegra186-pwm-tachometer" +- reg: physical base addresses of the controller and length of + memory mapped region. +- #pwm-cells: should be 2. See pwm.txt in this directory for a + description of the cells format. +- clocks: phandle list of tachometer clocks +- clock-names: should be "tachometer". See clock-bindings.txt in documentations +- resets: phandle to the reset controller for the Tachometer IP +- reset-names: should be "tachometer". See reset.txt in documentations +- nvidia,pulse-per-rev: Integer, pulses per revolution of a Fan. This value + obtained from Fan specification document. +- nvidia,capture-window-len: Integer, window of the Fan Tach monitor, it indicates + that how many period of the input fan tach signal will the FAN TACH logic + monitor. Valid values are 1, 2, 4 and 8 only. + +Example: + tegra_tachometer: tachometer@39c { + compatible = "nvidia,tegra186-pwm-tachometer"; + reg = <0x0 0x039c 0x0 0x10>; + #pwm-cells = <2>; + clocks = <_car TEGRA186_CLK_TACH>; + clock-names = "tachometer"; + resets = <_car TEGRA186_RESET_TACH>; + reset-names = "tachometer"; + nvidia,pulse-per-rev = <2>; + nvidia,capture-window-len = <2>; + status = "disabled"; + }; -- 2.1.4
[PATCH v3 2/2] staging: media: davinci_vpfe: add kfree() on goto err statement
It needs to free of allocated params value in the goto error statement. Signed-off-by: Ji-Hun Kim--- Changes since v2: - add kfree(params) on the error case of the function - rename unclear goto statement name - declare the params value at start of the function, so it can be free end of the function drivers/staging/media/davinci_vpfe/dm365_ipipe.c | 24 +++- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c index ffcd86d..735d8b5 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c +++ b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c @@ -1263,6 +1263,7 @@ static int ipipe_get_cgs_params(struct vpfe_ipipe_device *ipipe, void *param) static int ipipe_s_config(struct v4l2_subdev *sd, struct vpfe_ipipe_config *cfg) { struct vpfe_ipipe_device *ipipe = v4l2_get_subdevdata(sd); + struct ipipe_module_params *params; unsigned int i; int rval = 0; @@ -1272,7 +1273,6 @@ static int ipipe_s_config(struct v4l2_subdev *sd, struct vpfe_ipipe_config *cfg) if (cfg->flag & bit) { const struct ipipe_module_if *module_if = _modules[i]; - struct ipipe_module_params *params; void __user *from = *(void * __user *) ((void *)cfg + module_if->config_offset); size_t size; @@ -1289,26 +1289,30 @@ static int ipipe_s_config(struct v4l2_subdev *sd, struct vpfe_ipipe_config *cfg) if (to && from && size) { if (copy_from_user(to, from, size)) { rval = -EFAULT; - break; + goto err_free_params; } rval = module_if->set(ipipe, to); if (rval) - goto error; + goto err_free_params; } else if (to && !from && size) { rval = module_if->set(ipipe, NULL); if (rval) - goto error; + goto err_free_params; } kfree(params); } } -error: + return 0; + +err_free_params: + kfree(params); return rval; } static int ipipe_g_config(struct v4l2_subdev *sd, struct vpfe_ipipe_config *cfg) { struct vpfe_ipipe_device *ipipe = v4l2_get_subdevdata(sd); + struct ipipe_module_params *params; unsigned int i; int rval = 0; @@ -1318,7 +1322,6 @@ static int ipipe_g_config(struct v4l2_subdev *sd, struct vpfe_ipipe_config *cfg) if (cfg->flag & bit) { const struct ipipe_module_if *module_if = _modules[i]; - struct ipipe_module_params *params; void __user *to = *(void * __user *) ((void *)cfg + module_if->config_offset); size_t size; @@ -1335,16 +1338,19 @@ static int ipipe_g_config(struct v4l2_subdev *sd, struct vpfe_ipipe_config *cfg) if (to && from && size) { rval = module_if->get(ipipe, from); if (rval) - goto error; + goto err_free_params; if (copy_to_user(to, from, size)) { rval = -EFAULT; - break; + goto err_free_params; } } kfree(params); } } -error: + return 0; + +err_free_params: + kfree(params); return rval; } -- 1.9.1
[PATCH v3 2/2] staging: media: davinci_vpfe: add kfree() on goto err statement
It needs to free of allocated params value in the goto error statement. Signed-off-by: Ji-Hun Kim --- Changes since v2: - add kfree(params) on the error case of the function - rename unclear goto statement name - declare the params value at start of the function, so it can be free end of the function drivers/staging/media/davinci_vpfe/dm365_ipipe.c | 24 +++- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c index ffcd86d..735d8b5 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c +++ b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c @@ -1263,6 +1263,7 @@ static int ipipe_get_cgs_params(struct vpfe_ipipe_device *ipipe, void *param) static int ipipe_s_config(struct v4l2_subdev *sd, struct vpfe_ipipe_config *cfg) { struct vpfe_ipipe_device *ipipe = v4l2_get_subdevdata(sd); + struct ipipe_module_params *params; unsigned int i; int rval = 0; @@ -1272,7 +1273,6 @@ static int ipipe_s_config(struct v4l2_subdev *sd, struct vpfe_ipipe_config *cfg) if (cfg->flag & bit) { const struct ipipe_module_if *module_if = _modules[i]; - struct ipipe_module_params *params; void __user *from = *(void * __user *) ((void *)cfg + module_if->config_offset); size_t size; @@ -1289,26 +1289,30 @@ static int ipipe_s_config(struct v4l2_subdev *sd, struct vpfe_ipipe_config *cfg) if (to && from && size) { if (copy_from_user(to, from, size)) { rval = -EFAULT; - break; + goto err_free_params; } rval = module_if->set(ipipe, to); if (rval) - goto error; + goto err_free_params; } else if (to && !from && size) { rval = module_if->set(ipipe, NULL); if (rval) - goto error; + goto err_free_params; } kfree(params); } } -error: + return 0; + +err_free_params: + kfree(params); return rval; } static int ipipe_g_config(struct v4l2_subdev *sd, struct vpfe_ipipe_config *cfg) { struct vpfe_ipipe_device *ipipe = v4l2_get_subdevdata(sd); + struct ipipe_module_params *params; unsigned int i; int rval = 0; @@ -1318,7 +1322,6 @@ static int ipipe_g_config(struct v4l2_subdev *sd, struct vpfe_ipipe_config *cfg) if (cfg->flag & bit) { const struct ipipe_module_if *module_if = _modules[i]; - struct ipipe_module_params *params; void __user *to = *(void * __user *) ((void *)cfg + module_if->config_offset); size_t size; @@ -1335,16 +1338,19 @@ static int ipipe_g_config(struct v4l2_subdev *sd, struct vpfe_ipipe_config *cfg) if (to && from && size) { rval = module_if->get(ipipe, from); if (rval) - goto error; + goto err_free_params; if (copy_to_user(to, from, size)) { rval = -EFAULT; - break; + goto err_free_params; } } kfree(params); } } -error: + return 0; + +err_free_params: + kfree(params); return rval; } -- 1.9.1
Re: [PATCH 15/15] mm/hmm: use device driver encoding for HMM pfn v2
On 03/19/2018 07:00 PM, jgli...@redhat.com wrote: > From: Jérôme Glisse> > User of hmm_vma_fault() and hmm_vma_get_pfns() provide a flags array > and pfn shift value allowing them to define their own encoding for HMM > pfn that are fill inside the pfns array of the hmm_range struct. With > this device driver can get pfn that match their own private encoding > out of HMM without having to do any conversion. > > Changed since v1: > - Split flags and special values for clarification > - Improved comments and provide examples > > Signed-off-by: Jérôme Glisse > Cc: Evgeny Baskakov > Cc: Ralph Campbell > Cc: Mark Hairgrove > Cc: John Hubbard > --- > include/linux/hmm.h | 130 > +--- > mm/hmm.c| 85 +++--- > 2 files changed, 142 insertions(+), 73 deletions(-) > > diff --git a/include/linux/hmm.h b/include/linux/hmm.h > index 0f7ea3074175..5d26e0a223d9 100644 > --- a/include/linux/hmm.h > +++ b/include/linux/hmm.h > @@ -80,68 +80,145 @@ > struct hmm; > > /* > + * hmm_pfn_flag_e - HMM flag enums > + * > * Flags: > * HMM_PFN_VALID: pfn is valid. It has, at least, read permission. > * HMM_PFN_WRITE: CPU page table has write permission set > + * HMM_PFN_DEVICE_PRIVATE: private device memory (ZONE_DEVICE) > + * > + * The driver provide a flags array, if driver valid bit for an entry is bit > + * 3 ie (entry & (1 << 3)) is true if entry is valid then driver must provide > + * an array in hmm_range.flags with hmm_range.flags[HMM_PFN_VALID] == 1 << 3. > + * Same logic apply to all flags. This is same idea as vm_page_prot in vma > + * except that this is per device driver rather than per architecture. Hi Jerome, If we go with this approach--and I hope not, I'll try to talk you down from the ledge, in a moment--then maybe we should add the following to the comments: "There is only one bit ever set in each hmm_range.flags[entry]." Or maybe we'll get pushback, that the code shows that already, but IMHO this is strange way to do things (especially when there is a much easier way), and deserves that extra bit of helpful documentation. More below... > + */ > +enum hmm_pfn_flag_e { > + HMM_PFN_VALID = 0, > + HMM_PFN_WRITE, > + HMM_PFN_DEVICE_PRIVATE, > + HMM_PFN_FLAG_MAX > +}; > + > +/* > + * hmm_pfn_value_e - HMM pfn special value > + * > + * Flags: > * HMM_PFN_ERROR: corresponding CPU page table entry points to poisoned > memory > + * HMM_PFN_NONE: corresponding CPU page table entry is pte_none() > * HMM_PFN_SPECIAL: corresponding CPU page table entry is special; i.e., the > * result of vm_insert_pfn() or vm_insert_page(). Therefore, it should > not > * be mirrored by a device, because the entry will never have > HMM_PFN_VALID > * set and the pfn value is undefined. > - * HMM_PFN_DEVICE_PRIVATE: unaddressable device memory (ZONE_DEVICE) > + * > + * Driver provide entry value for none entry, error entry and special entry, > + * driver can alias (ie use same value for error and special for instance). > It > + * should not alias none and error or special. > + * > + * HMM pfn value returned by hmm_vma_get_pfns() or hmm_vma_fault() will be: > + * hmm_range.values[HMM_PFN_ERROR] if CPU page table entry is poisonous, > + * hmm_range.values[HMM_PFN_NONE] if there is no CPU page table > + * hmm_range.values[HMM_PFN_SPECIAL] if CPU page table entry is a special one > */ > -#define HMM_PFN_VALID (1 << 0) > -#define HMM_PFN_WRITE (1 << 1) > -#define HMM_PFN_ERROR (1 << 2) > -#define HMM_PFN_SPECIAL (1 << 3) > -#define HMM_PFN_DEVICE_PRIVATE (1 << 4) > -#define HMM_PFN_SHIFT 5 > +enum hmm_pfn_value_e { > + HMM_PFN_ERROR, > + HMM_PFN_NONE, > + HMM_PFN_SPECIAL, > + HMM_PFN_VALUE_MAX > +}; I can think of perhaps two good solid ways to get what you want, without moving to what I consider an unnecessary excursion into arrays of flags. If I understand correctly, you want to let each architecture specify which bit to use for each of the above HMM_PFN_* flags. The way you have it now, the code does things like this: cpu_flags & range->flags[HMM_PFN_WRITE] but that array entry is mostly empty space, and it's confusing. It would be nicer to see: cpu_flags & HMM_PFN_WRITE ...which you can easily do, by defining HMM_PFN_WRITE and friends in an arch-specific header file. The other way to make this more readable would be to use helper routines similar to what the vm_pgprot* routines do: static pgprot_t vm_pgprot_modify(pgprot_t oldprot, unsigned long vm_flags) { return pgprot_modify(oldprot, vm_get_page_prot(vm_flags)); } ...but that's also unnecessary. Let's just keep it simple, and go back to the bitmap flags! thanks, -- John Hubbard NVIDIA
Re: [PATCH 15/15] mm/hmm: use device driver encoding for HMM pfn v2
On 03/19/2018 07:00 PM, jgli...@redhat.com wrote: > From: Jérôme Glisse > > User of hmm_vma_fault() and hmm_vma_get_pfns() provide a flags array > and pfn shift value allowing them to define their own encoding for HMM > pfn that are fill inside the pfns array of the hmm_range struct. With > this device driver can get pfn that match their own private encoding > out of HMM without having to do any conversion. > > Changed since v1: > - Split flags and special values for clarification > - Improved comments and provide examples > > Signed-off-by: Jérôme Glisse > Cc: Evgeny Baskakov > Cc: Ralph Campbell > Cc: Mark Hairgrove > Cc: John Hubbard > --- > include/linux/hmm.h | 130 > +--- > mm/hmm.c| 85 +++--- > 2 files changed, 142 insertions(+), 73 deletions(-) > > diff --git a/include/linux/hmm.h b/include/linux/hmm.h > index 0f7ea3074175..5d26e0a223d9 100644 > --- a/include/linux/hmm.h > +++ b/include/linux/hmm.h > @@ -80,68 +80,145 @@ > struct hmm; > > /* > + * hmm_pfn_flag_e - HMM flag enums > + * > * Flags: > * HMM_PFN_VALID: pfn is valid. It has, at least, read permission. > * HMM_PFN_WRITE: CPU page table has write permission set > + * HMM_PFN_DEVICE_PRIVATE: private device memory (ZONE_DEVICE) > + * > + * The driver provide a flags array, if driver valid bit for an entry is bit > + * 3 ie (entry & (1 << 3)) is true if entry is valid then driver must provide > + * an array in hmm_range.flags with hmm_range.flags[HMM_PFN_VALID] == 1 << 3. > + * Same logic apply to all flags. This is same idea as vm_page_prot in vma > + * except that this is per device driver rather than per architecture. Hi Jerome, If we go with this approach--and I hope not, I'll try to talk you down from the ledge, in a moment--then maybe we should add the following to the comments: "There is only one bit ever set in each hmm_range.flags[entry]." Or maybe we'll get pushback, that the code shows that already, but IMHO this is strange way to do things (especially when there is a much easier way), and deserves that extra bit of helpful documentation. More below... > + */ > +enum hmm_pfn_flag_e { > + HMM_PFN_VALID = 0, > + HMM_PFN_WRITE, > + HMM_PFN_DEVICE_PRIVATE, > + HMM_PFN_FLAG_MAX > +}; > + > +/* > + * hmm_pfn_value_e - HMM pfn special value > + * > + * Flags: > * HMM_PFN_ERROR: corresponding CPU page table entry points to poisoned > memory > + * HMM_PFN_NONE: corresponding CPU page table entry is pte_none() > * HMM_PFN_SPECIAL: corresponding CPU page table entry is special; i.e., the > * result of vm_insert_pfn() or vm_insert_page(). Therefore, it should > not > * be mirrored by a device, because the entry will never have > HMM_PFN_VALID > * set and the pfn value is undefined. > - * HMM_PFN_DEVICE_PRIVATE: unaddressable device memory (ZONE_DEVICE) > + * > + * Driver provide entry value for none entry, error entry and special entry, > + * driver can alias (ie use same value for error and special for instance). > It > + * should not alias none and error or special. > + * > + * HMM pfn value returned by hmm_vma_get_pfns() or hmm_vma_fault() will be: > + * hmm_range.values[HMM_PFN_ERROR] if CPU page table entry is poisonous, > + * hmm_range.values[HMM_PFN_NONE] if there is no CPU page table > + * hmm_range.values[HMM_PFN_SPECIAL] if CPU page table entry is a special one > */ > -#define HMM_PFN_VALID (1 << 0) > -#define HMM_PFN_WRITE (1 << 1) > -#define HMM_PFN_ERROR (1 << 2) > -#define HMM_PFN_SPECIAL (1 << 3) > -#define HMM_PFN_DEVICE_PRIVATE (1 << 4) > -#define HMM_PFN_SHIFT 5 > +enum hmm_pfn_value_e { > + HMM_PFN_ERROR, > + HMM_PFN_NONE, > + HMM_PFN_SPECIAL, > + HMM_PFN_VALUE_MAX > +}; I can think of perhaps two good solid ways to get what you want, without moving to what I consider an unnecessary excursion into arrays of flags. If I understand correctly, you want to let each architecture specify which bit to use for each of the above HMM_PFN_* flags. The way you have it now, the code does things like this: cpu_flags & range->flags[HMM_PFN_WRITE] but that array entry is mostly empty space, and it's confusing. It would be nicer to see: cpu_flags & HMM_PFN_WRITE ...which you can easily do, by defining HMM_PFN_WRITE and friends in an arch-specific header file. The other way to make this more readable would be to use helper routines similar to what the vm_pgprot* routines do: static pgprot_t vm_pgprot_modify(pgprot_t oldprot, unsigned long vm_flags) { return pgprot_modify(oldprot, vm_get_page_prot(vm_flags)); } ...but that's also unnecessary. Let's just keep it simple, and go back to the bitmap flags! thanks, -- John Hubbard NVIDIA
[PATCH v3 1/2] staging: media: davinci_vpfe: add error handling on kmalloc failure
There is no failure checking on the param value which will be allocated memory by kmalloc. Add a null pointer checking statement. Then goto error: and return -ENOMEM error code when kmalloc is failed. Signed-off-by: Ji-Hun Kim--- Changes since v1: - Return with -ENOMEM directly, instead of goto error: then return. - [Patch v3 1/2] is same with [patch v2] drivers/staging/media/davinci_vpfe/dm365_ipipe.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c index 6a3434c..ffcd86d 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c +++ b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c @@ -1280,6 +1280,9 @@ static int ipipe_s_config(struct v4l2_subdev *sd, struct vpfe_ipipe_config *cfg) params = kmalloc(sizeof(struct ipipe_module_params), GFP_KERNEL); + if (!params) + return -ENOMEM; + to = (void *)params + module_if->param_offset; size = module_if->param_size; @@ -1323,6 +1326,9 @@ static int ipipe_g_config(struct v4l2_subdev *sd, struct vpfe_ipipe_config *cfg) params = kmalloc(sizeof(struct ipipe_module_params), GFP_KERNEL); + if (!params) + return -ENOMEM; + from = (void *)params + module_if->param_offset; size = module_if->param_size; -- 1.9.1
[PATCH v3 1/2] staging: media: davinci_vpfe: add error handling on kmalloc failure
There is no failure checking on the param value which will be allocated memory by kmalloc. Add a null pointer checking statement. Then goto error: and return -ENOMEM error code when kmalloc is failed. Signed-off-by: Ji-Hun Kim --- Changes since v1: - Return with -ENOMEM directly, instead of goto error: then return. - [Patch v3 1/2] is same with [patch v2] drivers/staging/media/davinci_vpfe/dm365_ipipe.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c index 6a3434c..ffcd86d 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c +++ b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c @@ -1280,6 +1280,9 @@ static int ipipe_s_config(struct v4l2_subdev *sd, struct vpfe_ipipe_config *cfg) params = kmalloc(sizeof(struct ipipe_module_params), GFP_KERNEL); + if (!params) + return -ENOMEM; + to = (void *)params + module_if->param_offset; size = module_if->param_size; @@ -1323,6 +1326,9 @@ static int ipipe_g_config(struct v4l2_subdev *sd, struct vpfe_ipipe_config *cfg) params = kmalloc(sizeof(struct ipipe_module_params), GFP_KERNEL); + if (!params) + return -ENOMEM; + from = (void *)params + module_if->param_offset; size = module_if->param_size; -- 1.9.1
[PATCH 1/1] mm/page_owner: fix recursion bug after changing skip entries
This patch fixes "5f48f0bd4e368425db4424b9afd1bd251d32367a". (mm, page_owner: skip unnecessary stack_trace entries) Because if we skip first two entries then logic of checking count value as 2 for recursion is broken and code will go in one depth recursion. so we need to check only one call of _RET_IP(__set_page_owner) while checking for recursion. Current Backtrace while checking for recursion:- (save_stack) from (__set_page_owner) // (But recursion returns true here) (__set_page_owner) from (get_page_from_freelist) (get_page_from_freelist) from (__alloc_pages_nodemask) (__alloc_pages_nodemask) from (depot_save_stack) (depot_save_stack) from (save_stack) // recursion should return true here (save_stack) from (__set_page_owner) (__set_page_owner) from (get_page_from_freelist) (get_page_from_freelist) from (__alloc_pages_nodemask+) (__alloc_pages_nodemask) from (depot_save_stack) (depot_save_stack) from (save_stack) (save_stack) from (__set_page_owner) (__set_page_owner) from (get_page_from_freelist) Correct Backtrace with fix: (save_stack) from (__set_page_owner) // recursion returned true here (__set_page_owner) from (get_page_from_freelist) (get_page_from_freelist) from (__alloc_pages_nodemask+) (__alloc_pages_nodemask) from (depot_save_stack) (depot_save_stack) from (save_stack) (save_stack) from (__set_page_owner) (__set_page_owner) from (get_page_from_freelist) Signed-off-by: Maninder SinghSigned-off-by: Vaneet Narang --- mm/page_owner.c |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mm/page_owner.c b/mm/page_owner.c index 8592543..46ab1c4 100644 --- a/mm/page_owner.c +++ b/mm/page_owner.c @@ -123,13 +123,13 @@ void __reset_page_owner(struct page *page, unsigned int order) static inline bool check_recursive_alloc(struct stack_trace *trace, unsigned long ip) { - int i, count; + int i; if (!trace->nr_entries) return false; - for (i = 0, count = 0; i < trace->nr_entries; i++) { - if (trace->entries[i] == ip && ++count == 2) + for (i = 0; i < trace->nr_entries; i++) { + if (trace->entries[i] == ip) return true; } -- 1.7.1
[PATCH 1/1] mm/page_owner: fix recursion bug after changing skip entries
This patch fixes "5f48f0bd4e368425db4424b9afd1bd251d32367a". (mm, page_owner: skip unnecessary stack_trace entries) Because if we skip first two entries then logic of checking count value as 2 for recursion is broken and code will go in one depth recursion. so we need to check only one call of _RET_IP(__set_page_owner) while checking for recursion. Current Backtrace while checking for recursion:- (save_stack) from (__set_page_owner) // (But recursion returns true here) (__set_page_owner) from (get_page_from_freelist) (get_page_from_freelist) from (__alloc_pages_nodemask) (__alloc_pages_nodemask) from (depot_save_stack) (depot_save_stack) from (save_stack) // recursion should return true here (save_stack) from (__set_page_owner) (__set_page_owner) from (get_page_from_freelist) (get_page_from_freelist) from (__alloc_pages_nodemask+) (__alloc_pages_nodemask) from (depot_save_stack) (depot_save_stack) from (save_stack) (save_stack) from (__set_page_owner) (__set_page_owner) from (get_page_from_freelist) Correct Backtrace with fix: (save_stack) from (__set_page_owner) // recursion returned true here (__set_page_owner) from (get_page_from_freelist) (get_page_from_freelist) from (__alloc_pages_nodemask+) (__alloc_pages_nodemask) from (depot_save_stack) (depot_save_stack) from (save_stack) (save_stack) from (__set_page_owner) (__set_page_owner) from (get_page_from_freelist) Signed-off-by: Maninder Singh Signed-off-by: Vaneet Narang --- mm/page_owner.c |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mm/page_owner.c b/mm/page_owner.c index 8592543..46ab1c4 100644 --- a/mm/page_owner.c +++ b/mm/page_owner.c @@ -123,13 +123,13 @@ void __reset_page_owner(struct page *page, unsigned int order) static inline bool check_recursive_alloc(struct stack_trace *trace, unsigned long ip) { - int i, count; + int i; if (!trace->nr_entries) return false; - for (i = 0, count = 0; i < trace->nr_entries; i++) { - if (trace->entries[i] == ip && ++count == 2) + for (i = 0; i < trace->nr_entries; i++) { + if (trace->entries[i] == ip) return true; } -- 1.7.1
Re: linux-next: manual merge of the ftrace tree with the jc_docs tree
Hi all, On Wed, 21 Mar 2018 15:31:27 +1100 Stephen Rothwellwrote: > > Today's linux-next merge of the ftrace tree got a conflict in: > > Documentation/trace/ftrace.txt > (converted to Documentation/trace/ftrace.rst) There was another conflict involving Documentation/trace/events.{txt,rst} Unfortunately, I accidentally deleted the report email before sending it :-( -- Cheers, Stephen Rothwell pgpq3nAHzFjVj.pgp Description: OpenPGP digital signature
Re: linux-next: manual merge of the ftrace tree with the jc_docs tree
Hi all, On Wed, 21 Mar 2018 15:31:27 +1100 Stephen Rothwell wrote: > > Today's linux-next merge of the ftrace tree got a conflict in: > > Documentation/trace/ftrace.txt > (converted to Documentation/trace/ftrace.rst) There was another conflict involving Documentation/trace/events.{txt,rst} Unfortunately, I accidentally deleted the report email before sending it :-( -- Cheers, Stephen Rothwell pgpq3nAHzFjVj.pgp Description: OpenPGP digital signature
[PATCH] tty/nozomi: refactor macros and functions
Cleanup a few messy sections of code by replacing constructs like `len__ > TMP_BUF_MAX ? TMP_BUF_MAX : len__` with `min_t(u32, len__, TMP_BUF_MAX)` and naming identifiers more descriptively (where appropriate). A few sections were nested pretty deeply and have been replaced with shallower (but semantically equivalent) logic. In addition, simplify and coalesce a few of the return paths / loop conditionals and correct a few pointless Initializations, redundant parentheses/break statements, and inconsistently indented line. Signed-off-by: Joey Pabalinas1 file changed, 181 insertions(+), 181 deletions(-) diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c index b57b35066ebea94639..7b7474b8530d85e5d9 100644 --- a/drivers/tty/nozomi.c +++ b/drivers/tty/nozomi.c @@ -72,19 +72,19 @@ do { \ #define TMP_BUF_MAX 256 -#define DUMP(buf__,len__) \ - do { \ -char tbuf[TMP_BUF_MAX] = {0};\ -if (len__ > 1) {\ - snprintf(tbuf, len__ > TMP_BUF_MAX ? TMP_BUF_MAX : len__, "%s", buf__);\ - if (tbuf[len__-2] == '\r') {\ - tbuf[len__-2] = 'r';\ - } \ - DBG1("SENDING: '%s' (%d+n)", tbuf, len__);\ -} else {\ - DBG1("SENDING: '%s' (%d)", tbuf, len__);\ -} \ -} while (0) +#define DUMP(buf__, len__) \ + do {\ + char tbuf[TMP_BUF_MAX] = {0}; \ + if (len__ > 1) {\ + u32 data_len = min_t(u32, len__, TMP_BUF_MAX); \ + strscpy(tbuf, buf__, data_len); \ + if (tbuf[data_len - 2] == '\r') \ + tbuf[data_len - 2] = 'r'; \ + DBG1("SENDING: '%s' (%d+n)", tbuf, len__); \ + } else {\ + DBG1("SENDING: '%s' (%d)", tbuf, len__);\ + } \ + } while (0) /*Defines */ #define NOZOMI_NAME"nozomi" @@ -102,41 +102,41 @@ do { \ #define RECEIVE_BUF_MAX4 -#define R_IIR 0x /* Interrupt Identity Register */ -#define R_FCR 0x /* Flow Control Register */ -#define R_IER 0x0004 /* Interrupt Enable Register */ +#define R_IIR 0x /* Interrupt Identity Register */ +#define R_FCR 0x /* Flow Control Register */ +#define R_IER 0x0004 /* Interrupt Enable Register */ #define NOZOMI_CONFIG_MAGIC0xEFEFFEFE #define TOGGLE_VALID 0x /* Definition of interrupt tokens */ -#define MDM_DL10x0001 -#define MDM_UL10x0002 -#define MDM_DL20x0004 -#define MDM_UL20x0008 -#define DIAG_DL1 0x0010 -#define DIAG_DL2 0x0020 -#define DIAG_UL0x0040 -#define APP1_DL0x0080 -#define APP1_UL0x0100 -#define APP2_DL0x0200 -#define APP2_UL0x0400 -#define CTRL_DL0x0800 -#define CTRL_UL0x1000 -#define RESET 0x8000 +#define MDM_DL10x0001 +#define MDM_UL10x0002 +#define MDM_DL20x0004 +#define MDM_UL20x0008 +#define DIAG_DL1 0x0010 +#define DIAG_DL2 0x0020 +#define DIAG_UL0x0040 +#define APP1_DL0x0080 +#define APP1_UL0x0100 +#define APP2_DL0x0200 +#define APP2_UL0x0400 +#define CTRL_DL0x0800 +#define CTRL_UL0x1000 +#define RESET 0x8000 -#define MDM_DL (MDM_DL1 | MDM_DL2) -#define MDM_UL (MDM_UL1 | MDM_UL2) -#define DIAG_DL(DIAG_DL1 | DIAG_DL2) +#define MDM_DL (MDM_DL1 | MDM_DL2) +#define MDM_UL (MDM_UL1 | MDM_UL2) +#define DIAG_DL(DIAG_DL1 | DIAG_DL2) /* modem signal definition */ -#define CTRL_DSR 0x0001 -#define CTRL_DCD 0x0002 -#define CTRL_RI0x0004 -#define CTRL_CTS 0x0008 +#define CTRL_DSR 0x0001 +#define CTRL_DCD 0x0002 +#define CTRL_RI0x0004 +#define CTRL_CTS 0x0008 -#define CTRL_DTR 0x0001 -#define CTRL_RTS 0x0002 +#define CTRL_DTR 0x0001 +#define CTRL_RTS 0x0002 #define MAX_PORT 4 #define NOZOMI_MAX_PORTS 5 @@ -365,7 +365,7 @@ struct buffer {
[PATCH] tty/nozomi: refactor macros and functions
Cleanup a few messy sections of code by replacing constructs like `len__ > TMP_BUF_MAX ? TMP_BUF_MAX : len__` with `min_t(u32, len__, TMP_BUF_MAX)` and naming identifiers more descriptively (where appropriate). A few sections were nested pretty deeply and have been replaced with shallower (but semantically equivalent) logic. In addition, simplify and coalesce a few of the return paths / loop conditionals and correct a few pointless Initializations, redundant parentheses/break statements, and inconsistently indented line. Signed-off-by: Joey Pabalinas 1 file changed, 181 insertions(+), 181 deletions(-) diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c index b57b35066ebea94639..7b7474b8530d85e5d9 100644 --- a/drivers/tty/nozomi.c +++ b/drivers/tty/nozomi.c @@ -72,19 +72,19 @@ do { \ #define TMP_BUF_MAX 256 -#define DUMP(buf__,len__) \ - do { \ -char tbuf[TMP_BUF_MAX] = {0};\ -if (len__ > 1) {\ - snprintf(tbuf, len__ > TMP_BUF_MAX ? TMP_BUF_MAX : len__, "%s", buf__);\ - if (tbuf[len__-2] == '\r') {\ - tbuf[len__-2] = 'r';\ - } \ - DBG1("SENDING: '%s' (%d+n)", tbuf, len__);\ -} else {\ - DBG1("SENDING: '%s' (%d)", tbuf, len__);\ -} \ -} while (0) +#define DUMP(buf__, len__) \ + do {\ + char tbuf[TMP_BUF_MAX] = {0}; \ + if (len__ > 1) {\ + u32 data_len = min_t(u32, len__, TMP_BUF_MAX); \ + strscpy(tbuf, buf__, data_len); \ + if (tbuf[data_len - 2] == '\r') \ + tbuf[data_len - 2] = 'r'; \ + DBG1("SENDING: '%s' (%d+n)", tbuf, len__); \ + } else {\ + DBG1("SENDING: '%s' (%d)", tbuf, len__);\ + } \ + } while (0) /*Defines */ #define NOZOMI_NAME"nozomi" @@ -102,41 +102,41 @@ do { \ #define RECEIVE_BUF_MAX4 -#define R_IIR 0x /* Interrupt Identity Register */ -#define R_FCR 0x /* Flow Control Register */ -#define R_IER 0x0004 /* Interrupt Enable Register */ +#define R_IIR 0x /* Interrupt Identity Register */ +#define R_FCR 0x /* Flow Control Register */ +#define R_IER 0x0004 /* Interrupt Enable Register */ #define NOZOMI_CONFIG_MAGIC0xEFEFFEFE #define TOGGLE_VALID 0x /* Definition of interrupt tokens */ -#define MDM_DL10x0001 -#define MDM_UL10x0002 -#define MDM_DL20x0004 -#define MDM_UL20x0008 -#define DIAG_DL1 0x0010 -#define DIAG_DL2 0x0020 -#define DIAG_UL0x0040 -#define APP1_DL0x0080 -#define APP1_UL0x0100 -#define APP2_DL0x0200 -#define APP2_UL0x0400 -#define CTRL_DL0x0800 -#define CTRL_UL0x1000 -#define RESET 0x8000 +#define MDM_DL10x0001 +#define MDM_UL10x0002 +#define MDM_DL20x0004 +#define MDM_UL20x0008 +#define DIAG_DL1 0x0010 +#define DIAG_DL2 0x0020 +#define DIAG_UL0x0040 +#define APP1_DL0x0080 +#define APP1_UL0x0100 +#define APP2_DL0x0200 +#define APP2_UL0x0400 +#define CTRL_DL0x0800 +#define CTRL_UL0x1000 +#define RESET 0x8000 -#define MDM_DL (MDM_DL1 | MDM_DL2) -#define MDM_UL (MDM_UL1 | MDM_UL2) -#define DIAG_DL(DIAG_DL1 | DIAG_DL2) +#define MDM_DL (MDM_DL1 | MDM_DL2) +#define MDM_UL (MDM_UL1 | MDM_UL2) +#define DIAG_DL(DIAG_DL1 | DIAG_DL2) /* modem signal definition */ -#define CTRL_DSR 0x0001 -#define CTRL_DCD 0x0002 -#define CTRL_RI0x0004 -#define CTRL_CTS 0x0008 +#define CTRL_DSR 0x0001 +#define CTRL_DCD 0x0002 +#define CTRL_RI0x0004 +#define CTRL_CTS 0x0008 -#define CTRL_DTR 0x0001 -#define CTRL_RTS 0x0002 +#define CTRL_DTR 0x0001 +#define CTRL_RTS 0x0002 #define MAX_PORT 4 #define NOZOMI_MAX_PORTS 5 @@ -365,7 +365,7 @@ struct buffer { u8 *data; }
linux-next: manual merge of the ftrace tree with the jc_docs tree
Hi Steven, Today's linux-next merge of the ftrace tree got a conflict in: Documentation/trace/ftrace.txt (converted to Documentation/trace/ftrace.rst) between commit: 1f198e22bc3a ("trace doc: convert trace/ftrace.txt to rst format") from the jc_docs tree and commit: 2c1ea60b195d ("tracing: Add timestamp_mode trace file") from the ftrace tree. I fixed it up (I deleted the file and added the merge fix patch below - which probably needs more work) and can carry the fix as necessary. This is now fixed as far as linux-next is concerned, but any non trivial conflicts should be mentioned to your upstream maintainer when your tree is submitted for merging. You may also want to consider cooperating with the maintainer of the conflicting tree to minimise any particularly complex conflicts. From: Stephen RothwellDate: Wed, 21 Mar 2018 15:29:08 +1100 Subject: [PATCH] trace doc: merge fix for rst conversion of ftrace.txt Signed-off-by: Stephen Rothwell --- Documentation/trace/ftrace.rst | 24 1 file changed, 24 insertions(+) diff --git a/Documentation/trace/ftrace.rst b/Documentation/trace/ftrace.rst index 55637926abdc..8aad686ff9a5 100644 --- a/Documentation/trace/ftrace.rst +++ b/Documentation/trace/ftrace.rst @@ -543,6 +543,30 @@ of ftrace. Here is a list of some of the key files: See events.txt for more information. + timestamp_mode: + + Certain tracers may change the timestamp mode used when + logging trace events into the event buffer. Events with + different modes can coexist within a buffer but the mode in + effect when an event is logged determines which timestamp mode + is used for that event. The default timestamp mode is + 'delta'. + + Usual timestamp modes for tracing: + + # cat timestamp_mode + [delta] absolute + + The timestamp mode with the square brackets around it is the + one in effect. + + delta: Default timestamp mode - timestamp is a delta against +a per-buffer timestamp. + + absolute: The timestamp is a full timestamp, not a delta + against some other value. As such it takes up more + space and is less efficient. + hwlat_detector: Directory for the Hardware Latency Detector. -- 2.16.1 -- Cheers, Stephen Rothwell pgpC25VqH4Njg.pgp Description: OpenPGP digital signature
linux-next: manual merge of the ftrace tree with the jc_docs tree
Hi Steven, Today's linux-next merge of the ftrace tree got a conflict in: Documentation/trace/ftrace.txt (converted to Documentation/trace/ftrace.rst) between commit: 1f198e22bc3a ("trace doc: convert trace/ftrace.txt to rst format") from the jc_docs tree and commit: 2c1ea60b195d ("tracing: Add timestamp_mode trace file") from the ftrace tree. I fixed it up (I deleted the file and added the merge fix patch below - which probably needs more work) and can carry the fix as necessary. This is now fixed as far as linux-next is concerned, but any non trivial conflicts should be mentioned to your upstream maintainer when your tree is submitted for merging. You may also want to consider cooperating with the maintainer of the conflicting tree to minimise any particularly complex conflicts. From: Stephen Rothwell Date: Wed, 21 Mar 2018 15:29:08 +1100 Subject: [PATCH] trace doc: merge fix for rst conversion of ftrace.txt Signed-off-by: Stephen Rothwell --- Documentation/trace/ftrace.rst | 24 1 file changed, 24 insertions(+) diff --git a/Documentation/trace/ftrace.rst b/Documentation/trace/ftrace.rst index 55637926abdc..8aad686ff9a5 100644 --- a/Documentation/trace/ftrace.rst +++ b/Documentation/trace/ftrace.rst @@ -543,6 +543,30 @@ of ftrace. Here is a list of some of the key files: See events.txt for more information. + timestamp_mode: + + Certain tracers may change the timestamp mode used when + logging trace events into the event buffer. Events with + different modes can coexist within a buffer but the mode in + effect when an event is logged determines which timestamp mode + is used for that event. The default timestamp mode is + 'delta'. + + Usual timestamp modes for tracing: + + # cat timestamp_mode + [delta] absolute + + The timestamp mode with the square brackets around it is the + one in effect. + + delta: Default timestamp mode - timestamp is a delta against +a per-buffer timestamp. + + absolute: The timestamp is a full timestamp, not a delta + against some other value. As such it takes up more + space and is less efficient. + hwlat_detector: Directory for the Hardware Latency Detector. -- 2.16.1 -- Cheers, Stephen Rothwell pgpC25VqH4Njg.pgp Description: OpenPGP digital signature
[PATCH] libnvdimm, region: hide persistence_domain when unknown
Similar to other region attributes, do not emit the persistence_domain attribute if its contents are empty. Fixes: 96c3a239054a ("libnvdimm: expose platform persistence attr...") Cc: Dave JiangSigned-off-by: Dan Williams --- drivers/nvdimm/region_devs.c |7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c index e6d01911e092..a8e9d428c0a5 100644 --- a/drivers/nvdimm/region_devs.c +++ b/drivers/nvdimm/region_devs.c @@ -593,6 +593,13 @@ static umode_t region_visible(struct kobject *kobj, struct attribute *a, int n) return 0; } + if (a == _attr_persistence_domain.attr) { + if ((nd_region->flags & (BIT(ND_REGION_PERSIST_CACHE) + | BIT(ND_REGION_PERSIST_MEMCTRL))) == 0) + return 0; + return a->mode; + } + if (a != _attr_set_cookie.attr && a != _attr_available_size.attr) return a->mode;
[PATCH] libnvdimm, region: hide persistence_domain when unknown
Similar to other region attributes, do not emit the persistence_domain attribute if its contents are empty. Fixes: 96c3a239054a ("libnvdimm: expose platform persistence attr...") Cc: Dave Jiang Signed-off-by: Dan Williams --- drivers/nvdimm/region_devs.c |7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c index e6d01911e092..a8e9d428c0a5 100644 --- a/drivers/nvdimm/region_devs.c +++ b/drivers/nvdimm/region_devs.c @@ -593,6 +593,13 @@ static umode_t region_visible(struct kobject *kobj, struct attribute *a, int n) return 0; } + if (a == _attr_persistence_domain.attr) { + if ((nd_region->flags & (BIT(ND_REGION_PERSIST_CACHE) + | BIT(ND_REGION_PERSIST_MEMCTRL))) == 0) + return 0; + return a->mode; + } + if (a != _attr_set_cookie.attr && a != _attr_available_size.attr) return a->mode;
Re: [PATCH 04/15] mm/hmm: unregister mmu_notifier when last HMM client quit
On 03/19/2018 07:00 PM, jgli...@redhat.com wrote: > From: Jérôme Glisse> > This code was lost in translation at one point. This properly call > mmu_notifier_unregister_no_release() once last user is gone. This > fix the zombie mm_struct as without this patch we do not drop the > refcount we have on it. > > Signed-off-by: Jérôme Glisse > Cc: Evgeny Baskakov > Cc: Ralph Campbell > Cc: Mark Hairgrove > Cc: John Hubbard > --- > mm/hmm.c | 19 +++ > 1 file changed, 19 insertions(+) > > diff --git a/mm/hmm.c b/mm/hmm.c > index 6088fa6ed137..667944630dc9 100644 > --- a/mm/hmm.c > +++ b/mm/hmm.c > @@ -244,10 +244,29 @@ EXPORT_SYMBOL(hmm_mirror_register); > void hmm_mirror_unregister(struct hmm_mirror *mirror) > { > struct hmm *hmm = mirror->hmm; > + struct mm_struct *mm = NULL; > + bool unregister = false; > > down_write(>mirrors_sem); > list_del_init(>list); > + unregister = list_empty(>mirrors); Hi Jerome, This first minor point may be irrelevant, depending on how you fix the other problem below, but: tiny naming idea: rename unregister to either "should_unregister", or "mirror_snapshot_empty"...the latter helps show that this is stale information, once the lock is dropped. > up_write(>mirrors_sem); > + > + if (!unregister) > + return; Whee, here I am, lock-free, in the middle of a race condition window. :) Right here, someone (hmm_mirror_register) could be adding another mirror. It's not immediately clear to me what the best solution is. I'd be happier if we didn't have to drop one lock and take another like this, but if we do, then maybe rechecking that the list hasn't changed...safely, somehow, is a way forward here. > + > + spin_lock(>mm->page_table_lock); > + if (hmm->mm->hmm == hmm) { > + mm = hmm->mm; > + mm->hmm = NULL; > + } > + spin_unlock(>mm->page_table_lock); > + > + if (mm == NULL) > + return; > + > + mmu_notifier_unregister_no_release(>mmu_notifier, mm); > + kfree(hmm); > } > EXPORT_SYMBOL(hmm_mirror_unregister); > thanks, -- John Hubbard NVIDIA
Re: [PATCH 04/15] mm/hmm: unregister mmu_notifier when last HMM client quit
On 03/19/2018 07:00 PM, jgli...@redhat.com wrote: > From: Jérôme Glisse > > This code was lost in translation at one point. This properly call > mmu_notifier_unregister_no_release() once last user is gone. This > fix the zombie mm_struct as without this patch we do not drop the > refcount we have on it. > > Signed-off-by: Jérôme Glisse > Cc: Evgeny Baskakov > Cc: Ralph Campbell > Cc: Mark Hairgrove > Cc: John Hubbard > --- > mm/hmm.c | 19 +++ > 1 file changed, 19 insertions(+) > > diff --git a/mm/hmm.c b/mm/hmm.c > index 6088fa6ed137..667944630dc9 100644 > --- a/mm/hmm.c > +++ b/mm/hmm.c > @@ -244,10 +244,29 @@ EXPORT_SYMBOL(hmm_mirror_register); > void hmm_mirror_unregister(struct hmm_mirror *mirror) > { > struct hmm *hmm = mirror->hmm; > + struct mm_struct *mm = NULL; > + bool unregister = false; > > down_write(>mirrors_sem); > list_del_init(>list); > + unregister = list_empty(>mirrors); Hi Jerome, This first minor point may be irrelevant, depending on how you fix the other problem below, but: tiny naming idea: rename unregister to either "should_unregister", or "mirror_snapshot_empty"...the latter helps show that this is stale information, once the lock is dropped. > up_write(>mirrors_sem); > + > + if (!unregister) > + return; Whee, here I am, lock-free, in the middle of a race condition window. :) Right here, someone (hmm_mirror_register) could be adding another mirror. It's not immediately clear to me what the best solution is. I'd be happier if we didn't have to drop one lock and take another like this, but if we do, then maybe rechecking that the list hasn't changed...safely, somehow, is a way forward here. > + > + spin_lock(>mm->page_table_lock); > + if (hmm->mm->hmm == hmm) { > + mm = hmm->mm; > + mm->hmm = NULL; > + } > + spin_unlock(>mm->page_table_lock); > + > + if (mm == NULL) > + return; > + > + mmu_notifier_unregister_no_release(>mmu_notifier, mm); > + kfree(hmm); > } > EXPORT_SYMBOL(hmm_mirror_unregister); > thanks, -- John Hubbard NVIDIA
Re: [PATCH 03/15] mm/hmm: HMM should have a callback before MM is destroyed v2
On 03/19/2018 07:00 PM, jgli...@redhat.com wrote: > From: Ralph Campbell> > The hmm_mirror_register() function registers a callback for when > the CPU pagetable is modified. Normally, the device driver will > call hmm_mirror_unregister() when the process using the device is > finished. However, if the process exits uncleanly, the struct_mm > can be destroyed with no warning to the device driver. > > Changed since v1: > - dropped VM_BUG_ON() > - cc stable > > Signed-off-by: Ralph Campbell > Signed-off-by: Jérôme Glisse > Cc: sta...@vger.kernel.org > Cc: Evgeny Baskakov > Cc: Mark Hairgrove > Cc: John Hubbard > --- > include/linux/hmm.h | 10 ++ > mm/hmm.c| 18 +- > 2 files changed, 27 insertions(+), 1 deletion(-) > > diff --git a/include/linux/hmm.h b/include/linux/hmm.h > index 36dd21fe5caf..fa7b51f65905 100644 > --- a/include/linux/hmm.h > +++ b/include/linux/hmm.h > @@ -218,6 +218,16 @@ enum hmm_update_type { > * @update: callback to update range on a device > */ > struct hmm_mirror_ops { > + /* release() - release hmm_mirror > + * > + * @mirror: pointer to struct hmm_mirror > + * > + * This is called when the mm_struct is being released. > + * The callback should make sure no references to the mirror occur > + * after the callback returns. > + */ > + void (*release)(struct hmm_mirror *mirror); > + > /* sync_cpu_device_pagetables() - synchronize page tables >* >* @mirror: pointer to struct hmm_mirror > diff --git a/mm/hmm.c b/mm/hmm.c > index 320545b98ff5..6088fa6ed137 100644 > --- a/mm/hmm.c > +++ b/mm/hmm.c > @@ -160,6 +160,21 @@ static void hmm_invalidate_range(struct hmm *hmm, > up_read(>mirrors_sem); > } > > +static void hmm_release(struct mmu_notifier *mn, struct mm_struct *mm) > +{ > + struct hmm *hmm = mm->hmm; > + struct hmm_mirror *mirror; > + struct hmm_mirror *mirror_next; > + > + down_write(>mirrors_sem); > + list_for_each_entry_safe(mirror, mirror_next, >mirrors, list) { > + list_del_init(>list); > + if (mirror->ops->release) > + mirror->ops->release(mirror); Hi Jerome, This presents a deadlock problem (details below). As for solution ideas, Mark Hairgrove points out that the MMU notifiers had to solve the same sort of problem, and part of the solution involves "avoid holding locks when issuing these callbacks". That's not an entire solution description, of course, but it seems like a good start. Anyway, for the deadlock problem: Each of these ->release callbacks potentially has to wait for the hmm_invalidate_range() callbacks to finish. That is not shown in any code directly, but it's because: when a device driver is processing the above ->release callback, it has to allow any in-progress operations to finish up (as specified clearly in your comment documentation above). Some of those operations will invariably need to do things that result in page invalidations, thus triggering the hmm_invalidate_range() callback. Then, the hmm_invalidate_range() callback tries to acquire the same hmm->mirrors_sem lock, thus leading to deadlock: hmm_invalidate_range(): // ... down_read(>mirrors_sem); list_for_each_entry(mirror, >mirrors, list) mirror->ops->sync_cpu_device_pagetables(mirror, action, start, end); up_read(>mirrors_sem); thanks, -- John Hubbard NVIDIA
Re: [PATCH 03/15] mm/hmm: HMM should have a callback before MM is destroyed v2
On 03/19/2018 07:00 PM, jgli...@redhat.com wrote: > From: Ralph Campbell > > The hmm_mirror_register() function registers a callback for when > the CPU pagetable is modified. Normally, the device driver will > call hmm_mirror_unregister() when the process using the device is > finished. However, if the process exits uncleanly, the struct_mm > can be destroyed with no warning to the device driver. > > Changed since v1: > - dropped VM_BUG_ON() > - cc stable > > Signed-off-by: Ralph Campbell > Signed-off-by: Jérôme Glisse > Cc: sta...@vger.kernel.org > Cc: Evgeny Baskakov > Cc: Mark Hairgrove > Cc: John Hubbard > --- > include/linux/hmm.h | 10 ++ > mm/hmm.c| 18 +- > 2 files changed, 27 insertions(+), 1 deletion(-) > > diff --git a/include/linux/hmm.h b/include/linux/hmm.h > index 36dd21fe5caf..fa7b51f65905 100644 > --- a/include/linux/hmm.h > +++ b/include/linux/hmm.h > @@ -218,6 +218,16 @@ enum hmm_update_type { > * @update: callback to update range on a device > */ > struct hmm_mirror_ops { > + /* release() - release hmm_mirror > + * > + * @mirror: pointer to struct hmm_mirror > + * > + * This is called when the mm_struct is being released. > + * The callback should make sure no references to the mirror occur > + * after the callback returns. > + */ > + void (*release)(struct hmm_mirror *mirror); > + > /* sync_cpu_device_pagetables() - synchronize page tables >* >* @mirror: pointer to struct hmm_mirror > diff --git a/mm/hmm.c b/mm/hmm.c > index 320545b98ff5..6088fa6ed137 100644 > --- a/mm/hmm.c > +++ b/mm/hmm.c > @@ -160,6 +160,21 @@ static void hmm_invalidate_range(struct hmm *hmm, > up_read(>mirrors_sem); > } > > +static void hmm_release(struct mmu_notifier *mn, struct mm_struct *mm) > +{ > + struct hmm *hmm = mm->hmm; > + struct hmm_mirror *mirror; > + struct hmm_mirror *mirror_next; > + > + down_write(>mirrors_sem); > + list_for_each_entry_safe(mirror, mirror_next, >mirrors, list) { > + list_del_init(>list); > + if (mirror->ops->release) > + mirror->ops->release(mirror); Hi Jerome, This presents a deadlock problem (details below). As for solution ideas, Mark Hairgrove points out that the MMU notifiers had to solve the same sort of problem, and part of the solution involves "avoid holding locks when issuing these callbacks". That's not an entire solution description, of course, but it seems like a good start. Anyway, for the deadlock problem: Each of these ->release callbacks potentially has to wait for the hmm_invalidate_range() callbacks to finish. That is not shown in any code directly, but it's because: when a device driver is processing the above ->release callback, it has to allow any in-progress operations to finish up (as specified clearly in your comment documentation above). Some of those operations will invariably need to do things that result in page invalidations, thus triggering the hmm_invalidate_range() callback. Then, the hmm_invalidate_range() callback tries to acquire the same hmm->mirrors_sem lock, thus leading to deadlock: hmm_invalidate_range(): // ... down_read(>mirrors_sem); list_for_each_entry(mirror, >mirrors, list) mirror->ops->sync_cpu_device_pagetables(mirror, action, start, end); up_read(>mirrors_sem); thanks, -- John Hubbard NVIDIA
Re: [PATCH v4 0/5] PCI endpoint 64-bit BAR fixes
On Mon, Mar 19, 2018 at 04:52:34PM +, Lorenzo Pieralisi wrote: > On Thu, Mar 08, 2018 at 02:33:25PM +0100, Niklas Cassel wrote: > > PCI endpoint fixes to improve the way 64-bit BARs are handled. > > > > > > There are still future improvements that could be made: > > > > pci-epf-test.c always allocates space for > > 6 BARs, even when using 64-bit BARs (which > > really only requires us to allocate 3 BARs). > > > > pcitest.sh will print "NOT OKAY" for BAR1, > > BAR3, and BAR5 when using 64-bit BARs. > > This could probably be improved to say > > something like "N/A (64-bit BAR)". > > > > Niklas Cassel (5): > > PCI: endpoint: BAR width should not depend on sizeof dma_addr_t > > PCI: designware-ep: Make dw_pcie_ep_set_bar() handle 64-bit BARs > > properly > > PCI: designware-ep: Make dw_pcie_ep_reset_bar() handle 64-bit BARs > > properly > > PCI: endpoint: Make pci_epc_set_bar() return the BAR width that was > > set-up > > misc: pci_endpoint_test: Handle 64-bit BARs properly > > > > drivers/misc/pci_endpoint_test.c | 12 +++- > > drivers/pci/cadence/pcie-cadence-ep.c | 2 +- > > drivers/pci/dwc/pcie-designware-ep.c | 22 ++ > > drivers/pci/endpoint/functions/pci-epf-test.c | 22 +++--- > > 4 files changed, 41 insertions(+), 17 deletions(-) > > Niklas, > > I am fine with the series but I'd need Kishon ACKs (and Greg's for the > last patch), I am ready to queue them then. Hello Kishon, could you please have a look at this series? Kind regards, Niklas
Re: [PATCH v4 0/5] PCI endpoint 64-bit BAR fixes
On Mon, Mar 19, 2018 at 04:52:34PM +, Lorenzo Pieralisi wrote: > On Thu, Mar 08, 2018 at 02:33:25PM +0100, Niklas Cassel wrote: > > PCI endpoint fixes to improve the way 64-bit BARs are handled. > > > > > > There are still future improvements that could be made: > > > > pci-epf-test.c always allocates space for > > 6 BARs, even when using 64-bit BARs (which > > really only requires us to allocate 3 BARs). > > > > pcitest.sh will print "NOT OKAY" for BAR1, > > BAR3, and BAR5 when using 64-bit BARs. > > This could probably be improved to say > > something like "N/A (64-bit BAR)". > > > > Niklas Cassel (5): > > PCI: endpoint: BAR width should not depend on sizeof dma_addr_t > > PCI: designware-ep: Make dw_pcie_ep_set_bar() handle 64-bit BARs > > properly > > PCI: designware-ep: Make dw_pcie_ep_reset_bar() handle 64-bit BARs > > properly > > PCI: endpoint: Make pci_epc_set_bar() return the BAR width that was > > set-up > > misc: pci_endpoint_test: Handle 64-bit BARs properly > > > > drivers/misc/pci_endpoint_test.c | 12 +++- > > drivers/pci/cadence/pcie-cadence-ep.c | 2 +- > > drivers/pci/dwc/pcie-designware-ep.c | 22 ++ > > drivers/pci/endpoint/functions/pci-epf-test.c | 22 +++--- > > 4 files changed, 41 insertions(+), 17 deletions(-) > > Niklas, > > I am fine with the series but I'd need Kishon ACKs (and Greg's for the > last patch), I am ready to queue them then. Hello Kishon, could you please have a look at this series? Kind regards, Niklas
Re: [PATCH 1/2] big key: get rid of stack array allocation
Hi Eric, On Wed, Mar 14, 2018 at 06:51:39PM -0700, Eric Biggers wrote: > On Mon, Mar 12, 2018 at 10:29:06PM -0600, Tycho Andersen wrote: > > We're interested in getting rid of all of the stack allocated arrays in the > > kernel [1]. This patch removes one in keys by switching to malloc/free. > > Note that we use kzalloc, to avoid leaking the nonce. I'm not sure this is > > really necessary, but extra paranoia seems prudent. > > > > Manually tested using the program from the add_key man page to trigger > > big_key. > > > > [1]: https://lkml.org/lkml/2018/3/7/621 > > > > Signed-off-by: Tycho Andersen> > CC: David Howells > > CC: James Morris > > CC: "Serge E. Hallyn" > > CC: Jason A. Donenfeld > > --- > > security/keys/big_key.c | 12 +--- > > 1 file changed, 9 insertions(+), 3 deletions(-) > > > > diff --git a/security/keys/big_key.c b/security/keys/big_key.c > > index fa728f662a6f..70f9f785c59d 100644 > > --- a/security/keys/big_key.c > > +++ b/security/keys/big_key.c > > @@ -108,13 +108,18 @@ static int big_key_crypt(enum big_key_op op, struct > > big_key_buf *buf, size_t dat > > * an .update function, so there's no chance we'll wind up reusing the > > * key to encrypt updated data. Simply put: one key, one encryption. > > */ > > - u8 zero_nonce[crypto_aead_ivsize(big_key_aead)]; > > + u8 *zero_nonce; > > + > > + zero_nonce = kzalloc(crypto_aead_ivsize(big_key_aead), GFP_KERNEL); > > + if (!zero_nonce) > > + return -ENOMEM; > > > > aead_req = aead_request_alloc(big_key_aead, GFP_KERNEL); > > - if (!aead_req) > > + if (!aead_req) { > > + kfree(zero_nonce); > > return -ENOMEM; > > + } > > > > - memset(zero_nonce, 0, sizeof(zero_nonce)); > > aead_request_set_crypt(aead_req, buf->sg, buf->sg, datalen, zero_nonce); > > aead_request_set_callback(aead_req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, > > NULL); > > aead_request_set_ad(aead_req, 0); > > @@ -131,6 +136,7 @@ static int big_key_crypt(enum big_key_op op, struct > > big_key_buf *buf, size_t dat > > error: > > mutex_unlock(_key_aead_lock); > > aead_request_free(aead_req); > > + kzfree(zero_nonce); > > return ret; > > A dynamic allocation here doesn't make sense -- the algorithm is hard-coded to > AES-GCM, so the IV size is fixed. You should just include and > use GCM_AES_IV_LEN. As a sanity check you can add > 'BUG_ON(crypto_aead_ivsize(big_key_aead) != GCM_AES_IV_LEN' to big_key_init(). > > kzfree() also doesn't make sense since the nonce is not secret information. Thanks, I've fixed this for v2. Cheers, Tycho
Re: [PATCH 1/2] big key: get rid of stack array allocation
Hi Eric, On Wed, Mar 14, 2018 at 06:51:39PM -0700, Eric Biggers wrote: > On Mon, Mar 12, 2018 at 10:29:06PM -0600, Tycho Andersen wrote: > > We're interested in getting rid of all of the stack allocated arrays in the > > kernel [1]. This patch removes one in keys by switching to malloc/free. > > Note that we use kzalloc, to avoid leaking the nonce. I'm not sure this is > > really necessary, but extra paranoia seems prudent. > > > > Manually tested using the program from the add_key man page to trigger > > big_key. > > > > [1]: https://lkml.org/lkml/2018/3/7/621 > > > > Signed-off-by: Tycho Andersen > > CC: David Howells > > CC: James Morris > > CC: "Serge E. Hallyn" > > CC: Jason A. Donenfeld > > --- > > security/keys/big_key.c | 12 +--- > > 1 file changed, 9 insertions(+), 3 deletions(-) > > > > diff --git a/security/keys/big_key.c b/security/keys/big_key.c > > index fa728f662a6f..70f9f785c59d 100644 > > --- a/security/keys/big_key.c > > +++ b/security/keys/big_key.c > > @@ -108,13 +108,18 @@ static int big_key_crypt(enum big_key_op op, struct > > big_key_buf *buf, size_t dat > > * an .update function, so there's no chance we'll wind up reusing the > > * key to encrypt updated data. Simply put: one key, one encryption. > > */ > > - u8 zero_nonce[crypto_aead_ivsize(big_key_aead)]; > > + u8 *zero_nonce; > > + > > + zero_nonce = kzalloc(crypto_aead_ivsize(big_key_aead), GFP_KERNEL); > > + if (!zero_nonce) > > + return -ENOMEM; > > > > aead_req = aead_request_alloc(big_key_aead, GFP_KERNEL); > > - if (!aead_req) > > + if (!aead_req) { > > + kfree(zero_nonce); > > return -ENOMEM; > > + } > > > > - memset(zero_nonce, 0, sizeof(zero_nonce)); > > aead_request_set_crypt(aead_req, buf->sg, buf->sg, datalen, zero_nonce); > > aead_request_set_callback(aead_req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, > > NULL); > > aead_request_set_ad(aead_req, 0); > > @@ -131,6 +136,7 @@ static int big_key_crypt(enum big_key_op op, struct > > big_key_buf *buf, size_t dat > > error: > > mutex_unlock(_key_aead_lock); > > aead_request_free(aead_req); > > + kzfree(zero_nonce); > > return ret; > > A dynamic allocation here doesn't make sense -- the algorithm is hard-coded to > AES-GCM, so the IV size is fixed. You should just include and > use GCM_AES_IV_LEN. As a sanity check you can add > 'BUG_ON(crypto_aead_ivsize(big_key_aead) != GCM_AES_IV_LEN' to big_key_init(). > > kzfree() also doesn't make sense since the nonce is not secret information. Thanks, I've fixed this for v2. Cheers, Tycho
Re: [PATCH 2/2] dh key: get rid of stack array allocation
Hi Eric, On Wed, Mar 14, 2018 at 07:21:12PM -0700, Eric Biggers wrote: > On Mon, Mar 12, 2018 at 10:29:07PM -0600, Tycho Andersen wrote: > > Similarly to the previous patch, we would like to get rid of stack > > allocated arrays: https://lkml.org/lkml/2018/3/7/621 > > > > In this case, we can also use a malloc style approach to free the temporary > > buffer, being careful to also use kzfree to free them (indeed, at least one > > of these has a memzero_explicit, but it seems like maybe they both > > should?). > > > > Signed-off-by: Tycho Andersen> > CC: David Howells > > CC: James Morris > > CC: "Serge E. Hallyn" > > --- > > security/keys/dh.c | 27 +-- > > 1 file changed, 21 insertions(+), 6 deletions(-) > > > > diff --git a/security/keys/dh.c b/security/keys/dh.c > > index d1ea9f325f94..f02261b24759 100644 > > --- a/security/keys/dh.c > > +++ b/security/keys/dh.c > > @@ -162,19 +162,27 @@ static int kdf_ctr(struct kdf_sdesc *sdesc, const u8 > > *src, unsigned int slen, > > goto err; > > > > if (zlen && h) { > > - u8 tmpbuffer[h]; > > + u8 *tmpbuffer; > > size_t chunk = min_t(size_t, zlen, h); > > - memset(tmpbuffer, 0, chunk); > > + > > + err = -ENOMEM; > > + tmpbuffer = kzalloc(chunk, GFP_KERNEL); > > + if (!tmpbuffer) > > + goto err; > > > > do { > > err = crypto_shash_update(desc, tmpbuffer, > > chunk); > > - if (err) > > + if (err) { > > + kzfree(tmpbuffer); > > goto err; > > + } > > > > zlen -= chunk; > > chunk = min_t(size_t, zlen, h); > > } while (zlen); > > + > > + kzfree(tmpbuffer); > > } > > This is just hashing zeroes. Why not use the zeroes at the end of the 'src' > buffer which was allocated as 'outbuf' in __keyctl_dh_compute()? It's already > the right size. It might even simplify the code a bit since > crypto_shash_update() would no longer need to be in a loop. Can you clarify what you mean by the "end" here? It looks like the end is copied over with the user string just before it's passed into keyctl_dh_compute_kdf(). In any case, I agree that it's dumb to do this allocation in a loop now. What if instead we just do one big long allocation of zlen, hash it, and then free it? This has the advantage that it's not allocated two functions away from where it's used... > > > > if (src && slen) { > > @@ -184,13 +192,20 @@ static int kdf_ctr(struct kdf_sdesc *sdesc, const u8 > > *src, unsigned int slen, > > } > > > > if (dlen < h) { > > - u8 tmpbuffer[h]; > > + u8 *tmpbuffer; > > + > > + err = -ENOMEM; > > + tmpbuffer = kzalloc(h, GFP_KERNEL); > > + if (!tmpbuffer) > > + goto err; > > > > err = crypto_shash_final(desc, tmpbuffer); > > - if (err) > > + if (err) { > > + kzfree(tmpbuffer); > > goto err; > > + } > > memcpy(dst, tmpbuffer, dlen); > > - memzero_explicit(tmpbuffer, h); > > + kzfree(tmpbuffer); > > return 0; > > } else { > > err = crypto_shash_final(desc, dst); > > -- > > Why not instead round the allocated size of 'outbuf' in > keyctl_dh_compute_kdf() > up to the next 'crypto_shash_digestsize()'-boundary? Then this temporary > buffer > wouldn't be needed at all. Thanks, I've made this change (and split it out into a separate patch) for v2. Tycho
Re: [PATCH 2/2] dh key: get rid of stack array allocation
Hi Eric, On Wed, Mar 14, 2018 at 07:21:12PM -0700, Eric Biggers wrote: > On Mon, Mar 12, 2018 at 10:29:07PM -0600, Tycho Andersen wrote: > > Similarly to the previous patch, we would like to get rid of stack > > allocated arrays: https://lkml.org/lkml/2018/3/7/621 > > > > In this case, we can also use a malloc style approach to free the temporary > > buffer, being careful to also use kzfree to free them (indeed, at least one > > of these has a memzero_explicit, but it seems like maybe they both > > should?). > > > > Signed-off-by: Tycho Andersen > > CC: David Howells > > CC: James Morris > > CC: "Serge E. Hallyn" > > --- > > security/keys/dh.c | 27 +-- > > 1 file changed, 21 insertions(+), 6 deletions(-) > > > > diff --git a/security/keys/dh.c b/security/keys/dh.c > > index d1ea9f325f94..f02261b24759 100644 > > --- a/security/keys/dh.c > > +++ b/security/keys/dh.c > > @@ -162,19 +162,27 @@ static int kdf_ctr(struct kdf_sdesc *sdesc, const u8 > > *src, unsigned int slen, > > goto err; > > > > if (zlen && h) { > > - u8 tmpbuffer[h]; > > + u8 *tmpbuffer; > > size_t chunk = min_t(size_t, zlen, h); > > - memset(tmpbuffer, 0, chunk); > > + > > + err = -ENOMEM; > > + tmpbuffer = kzalloc(chunk, GFP_KERNEL); > > + if (!tmpbuffer) > > + goto err; > > > > do { > > err = crypto_shash_update(desc, tmpbuffer, > > chunk); > > - if (err) > > + if (err) { > > + kzfree(tmpbuffer); > > goto err; > > + } > > > > zlen -= chunk; > > chunk = min_t(size_t, zlen, h); > > } while (zlen); > > + > > + kzfree(tmpbuffer); > > } > > This is just hashing zeroes. Why not use the zeroes at the end of the 'src' > buffer which was allocated as 'outbuf' in __keyctl_dh_compute()? It's already > the right size. It might even simplify the code a bit since > crypto_shash_update() would no longer need to be in a loop. Can you clarify what you mean by the "end" here? It looks like the end is copied over with the user string just before it's passed into keyctl_dh_compute_kdf(). In any case, I agree that it's dumb to do this allocation in a loop now. What if instead we just do one big long allocation of zlen, hash it, and then free it? This has the advantage that it's not allocated two functions away from where it's used... > > > > if (src && slen) { > > @@ -184,13 +192,20 @@ static int kdf_ctr(struct kdf_sdesc *sdesc, const u8 > > *src, unsigned int slen, > > } > > > > if (dlen < h) { > > - u8 tmpbuffer[h]; > > + u8 *tmpbuffer; > > + > > + err = -ENOMEM; > > + tmpbuffer = kzalloc(h, GFP_KERNEL); > > + if (!tmpbuffer) > > + goto err; > > > > err = crypto_shash_final(desc, tmpbuffer); > > - if (err) > > + if (err) { > > + kzfree(tmpbuffer); > > goto err; > > + } > > memcpy(dst, tmpbuffer, dlen); > > - memzero_explicit(tmpbuffer, h); > > + kzfree(tmpbuffer); > > return 0; > > } else { > > err = crypto_shash_final(desc, dst); > > -- > > Why not instead round the allocated size of 'outbuf' in > keyctl_dh_compute_kdf() > up to the next 'crypto_shash_digestsize()'-boundary? Then this temporary > buffer > wouldn't be needed at all. Thanks, I've made this change (and split it out into a separate patch) for v2. Tycho
Re: [PATCH v4 5/5] misc: pci_endpoint_test: Handle 64-bit BARs properly
Hello Greg, Lorenzo is fine with this series ( https://marc.info/?l=linux-kernel=152147837619191=2 ) However, he wants your ack on this patch before merging. Could you please have a look at this patch? Kind regards, Niklas On Thu, Mar 08, 2018 at 02:33:30PM +0100, Niklas Cassel wrote: > A 64-bit BAR consists of a BAR pair, where the second BAR has the > upper bits, so we cannot simply call pci_ioremap_bar() on every single > BAR index. > > The second BAR in a BAR pair will not have the IORESOURCE_MEM resource > flag set. Only call ioremap on BARs that have the IORESOURCE_MEM > resource flag set. > > pci :01:00.0: BAR 4: assigned [mem 0xc030-0xc031 64bit] > pci :01:00.0: BAR 2: assigned [mem 0xc032-0xc03203ff 64bit] > pci :01:00.0: BAR 0: assigned [mem 0xc0320400-0xc03204ff 64bit] > pci-endpoint-test :01:00.0: can't ioremap BAR 1: [??? 0x flags > 0x0] > pci-endpoint-test :01:00.0: failed to read BAR1 > pci-endpoint-test :01:00.0: can't ioremap BAR 3: [??? 0x flags > 0x0] > pci-endpoint-test :01:00.0: failed to read BAR3 > pci-endpoint-test :01:00.0: can't ioremap BAR 5: [??? 0x flags > 0x0] > pci-endpoint-test :01:00.0: failed to read BAR5 > > Signed-off-by: Niklas Cassel> --- > drivers/misc/pci_endpoint_test.c | 12 +++- > 1 file changed, 7 insertions(+), 5 deletions(-) > > diff --git a/drivers/misc/pci_endpoint_test.c > b/drivers/misc/pci_endpoint_test.c > index 320276f42653..fe8897e64635 100644 > --- a/drivers/misc/pci_endpoint_test.c > +++ b/drivers/misc/pci_endpoint_test.c > @@ -534,12 +534,14 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev, > } > > for (bar = BAR_0; bar <= BAR_5; bar++) { > - base = pci_ioremap_bar(pdev, bar); > - if (!base) { > - dev_err(dev, "failed to read BAR%d\n", bar); > - WARN_ON(bar == test_reg_bar); > + if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM) { > + base = pci_ioremap_bar(pdev, bar); > + if (!base) { > + dev_err(dev, "failed to read BAR%d\n", bar); > + WARN_ON(bar == test_reg_bar); > + } > + test->bar[bar] = base; > } > - test->bar[bar] = base; > } > > test->base = test->bar[test_reg_bar]; > -- > 2.14.2 >
Re: [PATCH v4 5/5] misc: pci_endpoint_test: Handle 64-bit BARs properly
Hello Greg, Lorenzo is fine with this series ( https://marc.info/?l=linux-kernel=152147837619191=2 ) However, he wants your ack on this patch before merging. Could you please have a look at this patch? Kind regards, Niklas On Thu, Mar 08, 2018 at 02:33:30PM +0100, Niklas Cassel wrote: > A 64-bit BAR consists of a BAR pair, where the second BAR has the > upper bits, so we cannot simply call pci_ioremap_bar() on every single > BAR index. > > The second BAR in a BAR pair will not have the IORESOURCE_MEM resource > flag set. Only call ioremap on BARs that have the IORESOURCE_MEM > resource flag set. > > pci :01:00.0: BAR 4: assigned [mem 0xc030-0xc031 64bit] > pci :01:00.0: BAR 2: assigned [mem 0xc032-0xc03203ff 64bit] > pci :01:00.0: BAR 0: assigned [mem 0xc0320400-0xc03204ff 64bit] > pci-endpoint-test :01:00.0: can't ioremap BAR 1: [??? 0x flags > 0x0] > pci-endpoint-test :01:00.0: failed to read BAR1 > pci-endpoint-test :01:00.0: can't ioremap BAR 3: [??? 0x flags > 0x0] > pci-endpoint-test :01:00.0: failed to read BAR3 > pci-endpoint-test :01:00.0: can't ioremap BAR 5: [??? 0x flags > 0x0] > pci-endpoint-test :01:00.0: failed to read BAR5 > > Signed-off-by: Niklas Cassel > --- > drivers/misc/pci_endpoint_test.c | 12 +++- > 1 file changed, 7 insertions(+), 5 deletions(-) > > diff --git a/drivers/misc/pci_endpoint_test.c > b/drivers/misc/pci_endpoint_test.c > index 320276f42653..fe8897e64635 100644 > --- a/drivers/misc/pci_endpoint_test.c > +++ b/drivers/misc/pci_endpoint_test.c > @@ -534,12 +534,14 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev, > } > > for (bar = BAR_0; bar <= BAR_5; bar++) { > - base = pci_ioremap_bar(pdev, bar); > - if (!base) { > - dev_err(dev, "failed to read BAR%d\n", bar); > - WARN_ON(bar == test_reg_bar); > + if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM) { > + base = pci_ioremap_bar(pdev, bar); > + if (!base) { > + dev_err(dev, "failed to read BAR%d\n", bar); > + WARN_ON(bar == test_reg_bar); > + } > + test->bar[bar] = base; > } > - test->bar[bar] = base; > } > > test->base = test->bar[test_reg_bar]; > -- > 2.14.2 >
Re: uvcvideo: Unknown video format,00000032-0002-0010-8000-00aa00389b71
Le mardi 20 mars 2018 à 20:04 +0200, Laurent Pinchart a écrit : > Hi Nicolas, > > On Tuesday, 20 March 2018 19:45:51 EET Nicolas Dufresne wrote: > > Le mardi 20 mars 2018 à 13:20 +0100, Paul Menzel a écrit : > > > Dear Linux folks, > > > > > > > > > On the Dell XPS 13 9370, Linux 4.16-rc6 outputs the messages below. > > > > > > ``` > > > [2.338094] calling uvc_init+0x0/0x1000 [uvcvideo] @ 295 > > > [2.338569] calling iTCO_wdt_init_module+0x0/0x1000 [iTCO_wdt] @ 280 > > > [2.338570] iTCO_wdt: Intel TCO WatchDog Timer Driver v1.11 > > > [2.338713] iTCO_wdt: Found a Intel PCH TCO device (Version=4, > > > TCOBASE=0x0400) > > > [2.338755] uvcvideo: Found UVC 1.00 device Integrated_Webcam_HD > > > (0bda:58f4) > > > [2.338827] iTCO_wdt: initialized. heartbeat=30 sec (nowayout=0) > > > [2.338851] initcall iTCO_wdt_init_module+0x0/0x1000 [iTCO_wdt] > > > returned 0 after 271 usecs > > > [2.340669] uvcvideo 1-5:1.0: Entity type for entity Extension 4 was > > > not initialized! > > > [2.340670] uvcvideo 1-5:1.0: Entity type for entity Extension 7 was > > > not initialized! > > > [2.340672] uvcvideo 1-5:1.0: Entity type for entity Processing 2 was > > > not initialized! > > > [2.340673] uvcvideo 1-5:1.0: Entity type for entity Camera 1 was not > > > initialized! > > > [2.340736] input: Integrated_Webcam_HD: Integrate as > > > /devices/pci:00/:00:14.0/usb1/1-5/1-5:1.0/input/input9 > > > [2.341447] uvcvideo: Unknown video format > > > 0032-0002-0010-8000-00aa00389b71 > > > > While the 0002 is suspicious, this is pretty close to a color format. > > I've recently come across of similar format using D3DFORMAT instead of > > GUID. According to the vendor*, this camera module includes an infrared > > camera (340x340), so I suspect this is to specify the format it > > outputs. A good guess to start with would be that this is > > D3DFMT_X8L8V8U8 (0x32). > > Isn't 0x32 D3DFMT_L8, not D3DFMT_X8L8V8U8 ? You are right, sorry about that, I totally miss-translate. It felt weird. This is much more likely yes. So maybe it's the same mapping (but with the -2- instead) as what I added for the HoloLense Camera. > > > To test it, you could map this > > V4L2_PIX_FMT_YUV32/xRGB and see if the driver is happy with the buffer > > size. > > VideoStreaming Interface Descriptor: > bLength30 > bDescriptorType36 > bDescriptorSubtype 5 (FRAME_UNCOMPRESSED) > bFrameIndex 1 > bmCapabilities 0x00 > Still image unsupported > wWidth340 > wHeight 340 > dwMinBitRate 55488000 > dwMaxBitRate 55488000 > dwMaxVideoFrameBufferSize 115600 > dwDefaultFrameInterval 16 > bFrameIntervalType 1 > dwFrameInterval( 0)16 > > 340*340 is 115600, so this should be a 8-bit format. Indeed, that matches. > > > Then render it to make sure it looks some image of some sort. A > > new format will need to be defined as this format is in the wrong > > order, and is ambiguous (it may mean AYUV or xYUV). I'm not sure if we > > need specific formats to differentiate infrared data from YUV images, > > need to be discussed. > > If the format is indeed D3DFMT_L8, it should map to V4L2_PIX_FMT_GREY (8-bit > luminance). I suspect the camera transmits a depth map though. I wonder if we should think of a way to tell userspace this is fnfrared data rather then black and white ? > > > *https://dustinweb.azureedge.net/media/338953/xps-13-9370.pdf > > > > > [2.341450] uvcvideo: Found UVC 1.00 device Integrated_Webcam_HD > > > (0bda:58f4) > > > [2.343371] uvcvideo: Unable to create debugfs 1-2 directory. > > > [2.343420] uvcvideo 1-5:1.2: Entity type for entity Extension 10 was > > > not initialized! > > > [2.343422] uvcvideo 1-5:1.2: Entity type for entity Extension 12 was > > > not initialized! > > > [2.343423] uvcvideo 1-5:1.2: Entity type for entity Processing 9 was > > > not initialized! > > > [2.343424] uvcvideo 1-5:1.2: Entity type for entity Camera 11 was > > > not initialized! > > > [2.343472] input: Integrated_Webcam_HD: Integrate as > > > /devices/pci:00/:00:14.0/usb1/1-5/1-5:1.2/input/input10 > > > [2.343496] usbcore: registered new interface driver uvcvideo > > > [2.343496] USB Video Class driver (1.1.1) > > > [2.343501] initcall uvc_init+0x0/0x1000 [uvcvideo] returned 0 after > > > 5275 usecs > > > ``` > > > > > > Please tell me, what I can do to improve the situation. > >
Re: uvcvideo: Unknown video format,00000032-0002-0010-8000-00aa00389b71
Le mardi 20 mars 2018 à 20:04 +0200, Laurent Pinchart a écrit : > Hi Nicolas, > > On Tuesday, 20 March 2018 19:45:51 EET Nicolas Dufresne wrote: > > Le mardi 20 mars 2018 à 13:20 +0100, Paul Menzel a écrit : > > > Dear Linux folks, > > > > > > > > > On the Dell XPS 13 9370, Linux 4.16-rc6 outputs the messages below. > > > > > > ``` > > > [2.338094] calling uvc_init+0x0/0x1000 [uvcvideo] @ 295 > > > [2.338569] calling iTCO_wdt_init_module+0x0/0x1000 [iTCO_wdt] @ 280 > > > [2.338570] iTCO_wdt: Intel TCO WatchDog Timer Driver v1.11 > > > [2.338713] iTCO_wdt: Found a Intel PCH TCO device (Version=4, > > > TCOBASE=0x0400) > > > [2.338755] uvcvideo: Found UVC 1.00 device Integrated_Webcam_HD > > > (0bda:58f4) > > > [2.338827] iTCO_wdt: initialized. heartbeat=30 sec (nowayout=0) > > > [2.338851] initcall iTCO_wdt_init_module+0x0/0x1000 [iTCO_wdt] > > > returned 0 after 271 usecs > > > [2.340669] uvcvideo 1-5:1.0: Entity type for entity Extension 4 was > > > not initialized! > > > [2.340670] uvcvideo 1-5:1.0: Entity type for entity Extension 7 was > > > not initialized! > > > [2.340672] uvcvideo 1-5:1.0: Entity type for entity Processing 2 was > > > not initialized! > > > [2.340673] uvcvideo 1-5:1.0: Entity type for entity Camera 1 was not > > > initialized! > > > [2.340736] input: Integrated_Webcam_HD: Integrate as > > > /devices/pci:00/:00:14.0/usb1/1-5/1-5:1.0/input/input9 > > > [2.341447] uvcvideo: Unknown video format > > > 0032-0002-0010-8000-00aa00389b71 > > > > While the 0002 is suspicious, this is pretty close to a color format. > > I've recently come across of similar format using D3DFORMAT instead of > > GUID. According to the vendor*, this camera module includes an infrared > > camera (340x340), so I suspect this is to specify the format it > > outputs. A good guess to start with would be that this is > > D3DFMT_X8L8V8U8 (0x32). > > Isn't 0x32 D3DFMT_L8, not D3DFMT_X8L8V8U8 ? You are right, sorry about that, I totally miss-translate. It felt weird. This is much more likely yes. So maybe it's the same mapping (but with the -2- instead) as what I added for the HoloLense Camera. > > > To test it, you could map this > > V4L2_PIX_FMT_YUV32/xRGB and see if the driver is happy with the buffer > > size. > > VideoStreaming Interface Descriptor: > bLength30 > bDescriptorType36 > bDescriptorSubtype 5 (FRAME_UNCOMPRESSED) > bFrameIndex 1 > bmCapabilities 0x00 > Still image unsupported > wWidth340 > wHeight 340 > dwMinBitRate 55488000 > dwMaxBitRate 55488000 > dwMaxVideoFrameBufferSize 115600 > dwDefaultFrameInterval 16 > bFrameIntervalType 1 > dwFrameInterval( 0)16 > > 340*340 is 115600, so this should be a 8-bit format. Indeed, that matches. > > > Then render it to make sure it looks some image of some sort. A > > new format will need to be defined as this format is in the wrong > > order, and is ambiguous (it may mean AYUV or xYUV). I'm not sure if we > > need specific formats to differentiate infrared data from YUV images, > > need to be discussed. > > If the format is indeed D3DFMT_L8, it should map to V4L2_PIX_FMT_GREY (8-bit > luminance). I suspect the camera transmits a depth map though. I wonder if we should think of a way to tell userspace this is fnfrared data rather then black and white ? > > > *https://dustinweb.azureedge.net/media/338953/xps-13-9370.pdf > > > > > [2.341450] uvcvideo: Found UVC 1.00 device Integrated_Webcam_HD > > > (0bda:58f4) > > > [2.343371] uvcvideo: Unable to create debugfs 1-2 directory. > > > [2.343420] uvcvideo 1-5:1.2: Entity type for entity Extension 10 was > > > not initialized! > > > [2.343422] uvcvideo 1-5:1.2: Entity type for entity Extension 12 was > > > not initialized! > > > [2.343423] uvcvideo 1-5:1.2: Entity type for entity Processing 9 was > > > not initialized! > > > [2.343424] uvcvideo 1-5:1.2: Entity type for entity Camera 11 was > > > not initialized! > > > [2.343472] input: Integrated_Webcam_HD: Integrate as > > > /devices/pci:00/:00:14.0/usb1/1-5/1-5:1.2/input/input10 > > > [2.343496] usbcore: registered new interface driver uvcvideo > > > [2.343496] USB Video Class driver (1.1.1) > > > [2.343501] initcall uvc_init+0x0/0x1000 [uvcvideo] returned 0 after > > > 5275 usecs > > > ``` > > > > > > Please tell me, what I can do to improve the situation. > >