Re: [PATCH v2 1/2] gpio: davinci: Shuffle IRQ resource fetching from DT to beginning of probe
On Tuesday, June 12, 2018, 7:27:52 AM CEST Keerthy wrote: > This is needed in case of PROBE_DEFER if IRQ resource is not yet ready. > > Signed-off-by: Keerthy > --- > [...] > --- a/drivers/gpio/gpio-davinci.c > +++ b/drivers/gpio/gpio-davinci.c > [...] > @@ -168,7 +168,7 @@ static int davinci_gpio_probe(struct platform_device > *pdev) > { > static int ctrl_num, bank_base; > int gpio, bank, ret = 0; > - unsigned ngpio, nbank; > + unsigned ngpio, nbank, bank_irq; bank_irq should be an int, not unsigned, no? > struct davinci_gpio_controller *chips; > struct davinci_gpio_platform_data *pdata; > struct device *dev = >dev; > @@ -209,6 +209,12 @@ static int davinci_gpio_probe(struct platform_device > *pdev) > if (IS_ERR(gpio_base)) > return PTR_ERR(gpio_base); > > + bank_irq = platform_get_irq(pdev, 0); > + if (bank_irq < 0) { This won't work using an unsigned. Best regards, Alexander
Re: [PATCH v2 1/2] gpio: davinci: Shuffle IRQ resource fetching from DT to beginning of probe
On Tuesday, June 12, 2018, 7:27:52 AM CEST Keerthy wrote: > This is needed in case of PROBE_DEFER if IRQ resource is not yet ready. > > Signed-off-by: Keerthy > --- > [...] > --- a/drivers/gpio/gpio-davinci.c > +++ b/drivers/gpio/gpio-davinci.c > [...] > @@ -168,7 +168,7 @@ static int davinci_gpio_probe(struct platform_device > *pdev) > { > static int ctrl_num, bank_base; > int gpio, bank, ret = 0; > - unsigned ngpio, nbank; > + unsigned ngpio, nbank, bank_irq; bank_irq should be an int, not unsigned, no? > struct davinci_gpio_controller *chips; > struct davinci_gpio_platform_data *pdata; > struct device *dev = >dev; > @@ -209,6 +209,12 @@ static int davinci_gpio_probe(struct platform_device > *pdev) > if (IS_ERR(gpio_base)) > return PTR_ERR(gpio_base); > > + bank_irq = platform_get_irq(pdev, 0); > + if (bank_irq < 0) { This won't work using an unsigned. Best regards, Alexander
Re: [PATCH v2 1/2] gpio: davinci: Shuffle IRQ resource fetching from DT to beginning of probe
On Tuesday 12 June 2018 11:15 AM, Alexander Stein wrote: > On Tuesday, June 12, 2018, 7:27:52 AM CEST Keerthy wrote: >> This is needed in case of PROBE_DEFER if IRQ resource is not yet ready. >> >> Signed-off-by: Keerthy >> --- >> [...] >> --- a/drivers/gpio/gpio-davinci.c >> +++ b/drivers/gpio/gpio-davinci.c >> [...] >> @@ -168,7 +168,7 @@ static int davinci_gpio_probe(struct platform_device >> *pdev) >> { >> static int ctrl_num, bank_base; >> int gpio, bank, ret = 0; >> -unsigned ngpio, nbank; >> +unsigned ngpio, nbank, bank_irq; > > bank_irq should be an int, not unsigned, no? Yes > >> struct davinci_gpio_controller *chips; >> struct davinci_gpio_platform_data *pdata; >> struct device *dev = >dev; >> @@ -209,6 +209,12 @@ static int davinci_gpio_probe(struct platform_device >> *pdev) >> if (IS_ERR(gpio_base)) >> return PTR_ERR(gpio_base); >> >> +bank_irq = platform_get_irq(pdev, 0); >> +if (bank_irq < 0) { > > This won't work using an unsigned. Thanks for catching this. I will correct this in v3. > > Best regards, > Alexander > > >
Re: [PATCH v2 1/2] gpio: davinci: Shuffle IRQ resource fetching from DT to beginning of probe
On Tuesday 12 June 2018 11:15 AM, Alexander Stein wrote: > On Tuesday, June 12, 2018, 7:27:52 AM CEST Keerthy wrote: >> This is needed in case of PROBE_DEFER if IRQ resource is not yet ready. >> >> Signed-off-by: Keerthy >> --- >> [...] >> --- a/drivers/gpio/gpio-davinci.c >> +++ b/drivers/gpio/gpio-davinci.c >> [...] >> @@ -168,7 +168,7 @@ static int davinci_gpio_probe(struct platform_device >> *pdev) >> { >> static int ctrl_num, bank_base; >> int gpio, bank, ret = 0; >> -unsigned ngpio, nbank; >> +unsigned ngpio, nbank, bank_irq; > > bank_irq should be an int, not unsigned, no? Yes > >> struct davinci_gpio_controller *chips; >> struct davinci_gpio_platform_data *pdata; >> struct device *dev = >dev; >> @@ -209,6 +209,12 @@ static int davinci_gpio_probe(struct platform_device >> *pdev) >> if (IS_ERR(gpio_base)) >> return PTR_ERR(gpio_base); >> >> +bank_irq = platform_get_irq(pdev, 0); >> +if (bank_irq < 0) { > > This won't work using an unsigned. Thanks for catching this. I will correct this in v3. > > Best regards, > Alexander > > >
uapi headers userspace build results
Hi, Here is what I have so far. It begins with a makefile and some template files that are added to. There's a good bit of Perl also. I put all of these files in tools/uapi/ and run them from there. There is one .c file generated for each .h file in builddir/usr/include (O=builddir). Out of 889 header files, I see 45 errors. That is better than I expected. The makefiles and scripts are attached (tar), as well as the output (I used 'make -ik' so that make would keep going after errors and attempt to build all target files). have fun! -- ~Randy gcc "-I../../xx64/usr/include" -c -o drm.i810_drm.o drm.i810_drm.c gcc "-I../../xx64/usr/include" -c -o drm.drm_fourcc.o drm.drm_fourcc.c gcc "-I../../xx64/usr/include" -c -o drm.etnaviv_drm.o drm.etnaviv_drm.c gcc "-I../../xx64/usr/include" -c -o drm.i915_drm.o drm.i915_drm.c gcc "-I../../xx64/usr/include" -c -o drm.drm_mode.o drm.drm_mode.c gcc "-I../../xx64/usr/include" -c -o drm.vc4_drm.o drm.vc4_drm.c gcc "-I../../xx64/usr/include" -c -o drm.mga_drm.o drm.mga_drm.c gcc "-I../../xx64/usr/include" -c -o drm.v3d_drm.o drm.v3d_drm.c gcc "-I../../xx64/usr/include" -c -o drm.msm_drm.o drm.msm_drm.c gcc "-I../../xx64/usr/include" -c -o drm.amdgpu_drm.o drm.amdgpu_drm.c gcc "-I../../xx64/usr/include" -c -o drm.exynos_drm.o drm.exynos_drm.c gcc "-I../../xx64/usr/include" -c -o drm.sis_drm.o drm.sis_drm.c gcc "-I../../xx64/usr/include" -c -o drm.armada_drm.o drm.armada_drm.c gcc "-I../../xx64/usr/include" -c -o drm.savage_drm.o drm.savage_drm.c gcc "-I../../xx64/usr/include" -c -o drm.r128_drm.o drm.r128_drm.c gcc "-I../../xx64/usr/include" -c -o drm.qxl_drm.o drm.qxl_drm.c gcc "-I../../xx64/usr/include" -c -o drm.vmwgfx_drm.o drm.vmwgfx_drm.c gcc "-I../../xx64/usr/include" -c -o drm.drm_sarea.o drm.drm_sarea.c gcc "-I../../xx64/usr/include" -c -o drm.via_drm.o drm.via_drm.c gcc "-I../../xx64/usr/include" -c -o drm.tegra_drm.o drm.tegra_drm.c gcc "-I../../xx64/usr/include" -c -o drm.omap_drm.o drm.omap_drm.c gcc "-I../../xx64/usr/include" -c -o drm.radeon_drm.o drm.radeon_drm.c gcc "-I../../xx64/usr/include" -c -o drm.virtgpu_drm.o drm.virtgpu_drm.c gcc "-I../../xx64/usr/include" -c -o drm.vgem_drm.o drm.vgem_drm.c gcc "-I../../xx64/usr/include" -c -o drm.nouveau_drm.o drm.nouveau_drm.c gcc "-I../../xx64/usr/include" -c -o drm.drm.o drm.drm.c gcc "-I../../xx64/usr/include" -c -o mtd.mtd-user.o mtd.mtd-user.c gcc "-I../../xx64/usr/include" -c -o mtd.ubi-user.o mtd.ubi-user.c gcc "-I../../xx64/usr/include" -c -o mtd.nftl-user.o mtd.nftl-user.c gcc "-I../../xx64/usr/include" -c -o mtd.mtd-abi.o mtd.mtd-abi.c gcc "-I../../xx64/usr/include" -c -o mtd.inftl-user.o mtd.inftl-user.c gcc "-I../../xx64/usr/include" -c -o sound.emu10k1.o sound.emu10k1.c gcc "-I../../xx64/usr/include" -c -o sound.sb16_csp.o sound.sb16_csp.c gcc "-I../../xx64/usr/include" -c -o sound.firewire.o sound.firewire.c gcc "-I../../xx64/usr/include" -c -o sound.asound_fm.o sound.asound_fm.c gcc "-I../../xx64/usr/include" -c -o sound.usb_stream.o sound.usb_stream.c gcc "-I../../xx64/usr/include" -c -o sound.compress_params.o sound.compress_params.c gcc "-I../../xx64/usr/include" -c -o sound.asoc.o sound.asoc.c gcc "-I../../xx64/usr/include" -c -o sound.sfnt_info.o sound.sfnt_info.c gcc "-I../../xx64/usr/include" -c -o sound.snd_sst_tokens.o sound.snd_sst_tokens.c gcc "-I../../xx64/usr/include" -c -o sound.compress_offload.o sound.compress_offload.c gcc "-I../../xx64/usr/include" -c -o sound.asequencer.o sound.asequencer.c gcc "-I../../xx64/usr/include" -c -o sound.hdspm.o sound.hdspm.c gcc "-I../../xx64/usr/include" -c -o sound.tlv.o sound.tlv.c gcc "-I../../xx64/usr/include" -c -o sound.asound.o sound.asound.c gcc "-I../../xx64/usr/include" -c -o sound.hdsp.o sound.hdsp.c gcc "-I../../xx64/usr/include" -c -o rdma.mlx5_user_ioctl_verbs.o rdma.mlx5_user_ioctl_verbs.c gcc "-I../../xx64/usr/include" -c -o rdma.ib_user_mad.o rdma.ib_user_mad.c gcc "-I../../xx64/usr/include" -c -o rdma.rdma_user_rxe.o rdma.rdma_user_rxe.c gcc "-I../../xx64/usr/include" -c -o rdma.ocrdma-abi.o rdma.ocrdma-abi.c gcc "-I../../xx64/usr/include" -c -o rdma.ib_user_cm.o rdma.ib_user_cm.c gcc "-I../../xx64/usr/include" -c -o rdma.ib_user_ioctl_cmds.o rdma.ib_user_ioctl_cmds.c gcc "-I../../xx64/usr/include" -c -o rdma.i40iw-abi.o rdma.i40iw-abi.c gcc "-I../../xx64/usr/include" -c -o rdma.rdma_netlink.o rdma.rdma_netlink.c gcc "-I../../xx64/usr/include" -c -o rdma.cxgb4-abi.o rdma.cxgb4-abi.c gcc "-I../../xx64/usr/include" -c -o rdma.ib_user_sa.o rdma.ib_user_sa.c gcc "-I../../xx64/usr/include" -c -o rdma.hns-abi.o rdma.hns-abi.c gcc "-I../../xx64/usr/include" -c -o rdma.rdma_user_cm.o rdma.rdma_user_cm.c gcc "-I../../xx64/usr/include" -c -o rdma.bnxt_re-abi.o rdma.bnxt_re-abi.c gcc "-I../../xx64/usr/include" -c -o rdma.mthca-abi.o rdma.mthca-abi.c gcc "-I../../xx64/usr/include" -c -o rdma.qedr-abi.o rdma.qedr-abi.c gcc "-I../../xx64/usr/include" -c -o
uapi headers userspace build results
Hi, Here is what I have so far. It begins with a makefile and some template files that are added to. There's a good bit of Perl also. I put all of these files in tools/uapi/ and run them from there. There is one .c file generated for each .h file in builddir/usr/include (O=builddir). Out of 889 header files, I see 45 errors. That is better than I expected. The makefiles and scripts are attached (tar), as well as the output (I used 'make -ik' so that make would keep going after errors and attempt to build all target files). have fun! -- ~Randy gcc "-I../../xx64/usr/include" -c -o drm.i810_drm.o drm.i810_drm.c gcc "-I../../xx64/usr/include" -c -o drm.drm_fourcc.o drm.drm_fourcc.c gcc "-I../../xx64/usr/include" -c -o drm.etnaviv_drm.o drm.etnaviv_drm.c gcc "-I../../xx64/usr/include" -c -o drm.i915_drm.o drm.i915_drm.c gcc "-I../../xx64/usr/include" -c -o drm.drm_mode.o drm.drm_mode.c gcc "-I../../xx64/usr/include" -c -o drm.vc4_drm.o drm.vc4_drm.c gcc "-I../../xx64/usr/include" -c -o drm.mga_drm.o drm.mga_drm.c gcc "-I../../xx64/usr/include" -c -o drm.v3d_drm.o drm.v3d_drm.c gcc "-I../../xx64/usr/include" -c -o drm.msm_drm.o drm.msm_drm.c gcc "-I../../xx64/usr/include" -c -o drm.amdgpu_drm.o drm.amdgpu_drm.c gcc "-I../../xx64/usr/include" -c -o drm.exynos_drm.o drm.exynos_drm.c gcc "-I../../xx64/usr/include" -c -o drm.sis_drm.o drm.sis_drm.c gcc "-I../../xx64/usr/include" -c -o drm.armada_drm.o drm.armada_drm.c gcc "-I../../xx64/usr/include" -c -o drm.savage_drm.o drm.savage_drm.c gcc "-I../../xx64/usr/include" -c -o drm.r128_drm.o drm.r128_drm.c gcc "-I../../xx64/usr/include" -c -o drm.qxl_drm.o drm.qxl_drm.c gcc "-I../../xx64/usr/include" -c -o drm.vmwgfx_drm.o drm.vmwgfx_drm.c gcc "-I../../xx64/usr/include" -c -o drm.drm_sarea.o drm.drm_sarea.c gcc "-I../../xx64/usr/include" -c -o drm.via_drm.o drm.via_drm.c gcc "-I../../xx64/usr/include" -c -o drm.tegra_drm.o drm.tegra_drm.c gcc "-I../../xx64/usr/include" -c -o drm.omap_drm.o drm.omap_drm.c gcc "-I../../xx64/usr/include" -c -o drm.radeon_drm.o drm.radeon_drm.c gcc "-I../../xx64/usr/include" -c -o drm.virtgpu_drm.o drm.virtgpu_drm.c gcc "-I../../xx64/usr/include" -c -o drm.vgem_drm.o drm.vgem_drm.c gcc "-I../../xx64/usr/include" -c -o drm.nouveau_drm.o drm.nouveau_drm.c gcc "-I../../xx64/usr/include" -c -o drm.drm.o drm.drm.c gcc "-I../../xx64/usr/include" -c -o mtd.mtd-user.o mtd.mtd-user.c gcc "-I../../xx64/usr/include" -c -o mtd.ubi-user.o mtd.ubi-user.c gcc "-I../../xx64/usr/include" -c -o mtd.nftl-user.o mtd.nftl-user.c gcc "-I../../xx64/usr/include" -c -o mtd.mtd-abi.o mtd.mtd-abi.c gcc "-I../../xx64/usr/include" -c -o mtd.inftl-user.o mtd.inftl-user.c gcc "-I../../xx64/usr/include" -c -o sound.emu10k1.o sound.emu10k1.c gcc "-I../../xx64/usr/include" -c -o sound.sb16_csp.o sound.sb16_csp.c gcc "-I../../xx64/usr/include" -c -o sound.firewire.o sound.firewire.c gcc "-I../../xx64/usr/include" -c -o sound.asound_fm.o sound.asound_fm.c gcc "-I../../xx64/usr/include" -c -o sound.usb_stream.o sound.usb_stream.c gcc "-I../../xx64/usr/include" -c -o sound.compress_params.o sound.compress_params.c gcc "-I../../xx64/usr/include" -c -o sound.asoc.o sound.asoc.c gcc "-I../../xx64/usr/include" -c -o sound.sfnt_info.o sound.sfnt_info.c gcc "-I../../xx64/usr/include" -c -o sound.snd_sst_tokens.o sound.snd_sst_tokens.c gcc "-I../../xx64/usr/include" -c -o sound.compress_offload.o sound.compress_offload.c gcc "-I../../xx64/usr/include" -c -o sound.asequencer.o sound.asequencer.c gcc "-I../../xx64/usr/include" -c -o sound.hdspm.o sound.hdspm.c gcc "-I../../xx64/usr/include" -c -o sound.tlv.o sound.tlv.c gcc "-I../../xx64/usr/include" -c -o sound.asound.o sound.asound.c gcc "-I../../xx64/usr/include" -c -o sound.hdsp.o sound.hdsp.c gcc "-I../../xx64/usr/include" -c -o rdma.mlx5_user_ioctl_verbs.o rdma.mlx5_user_ioctl_verbs.c gcc "-I../../xx64/usr/include" -c -o rdma.ib_user_mad.o rdma.ib_user_mad.c gcc "-I../../xx64/usr/include" -c -o rdma.rdma_user_rxe.o rdma.rdma_user_rxe.c gcc "-I../../xx64/usr/include" -c -o rdma.ocrdma-abi.o rdma.ocrdma-abi.c gcc "-I../../xx64/usr/include" -c -o rdma.ib_user_cm.o rdma.ib_user_cm.c gcc "-I../../xx64/usr/include" -c -o rdma.ib_user_ioctl_cmds.o rdma.ib_user_ioctl_cmds.c gcc "-I../../xx64/usr/include" -c -o rdma.i40iw-abi.o rdma.i40iw-abi.c gcc "-I../../xx64/usr/include" -c -o rdma.rdma_netlink.o rdma.rdma_netlink.c gcc "-I../../xx64/usr/include" -c -o rdma.cxgb4-abi.o rdma.cxgb4-abi.c gcc "-I../../xx64/usr/include" -c -o rdma.ib_user_sa.o rdma.ib_user_sa.c gcc "-I../../xx64/usr/include" -c -o rdma.hns-abi.o rdma.hns-abi.c gcc "-I../../xx64/usr/include" -c -o rdma.rdma_user_cm.o rdma.rdma_user_cm.c gcc "-I../../xx64/usr/include" -c -o rdma.bnxt_re-abi.o rdma.bnxt_re-abi.c gcc "-I../../xx64/usr/include" -c -o rdma.mthca-abi.o rdma.mthca-abi.c gcc "-I../../xx64/usr/include" -c -o rdma.qedr-abi.o rdma.qedr-abi.c gcc "-I../../xx64/usr/include" -c -o
[PATCH 5/7] tty: serial: lantiq: Convert global lock to per device lock
Previous implementation uses one global lock to protect the resource. If the serial driver have multiple entries, this kind of lock will slow down the performance. Add the lock at device level. This will lock only when the function calling only to the same device. So that it can avoid useless lock protection. Signed-off-by: Songjun Wu --- drivers/tty/serial/lantiq.c | 51 ++--- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/drivers/tty/serial/lantiq.c b/drivers/tty/serial/lantiq.c index 1127586dbc94..72aab1b05265 100644 --- a/drivers/tty/serial/lantiq.c +++ b/drivers/tty/serial/lantiq.c @@ -107,7 +107,6 @@ static void lqasc_tx_chars(struct uart_port *port); static struct ltq_uart_port *lqasc_port[MAXPORTS]; static struct uart_driver lqasc_reg; -static DEFINE_SPINLOCK(ltq_asc_lock); struct ltq_uart_port { struct uart_portport; @@ -118,6 +117,7 @@ struct ltq_uart_port { unsigned inttx_irq; unsigned intrx_irq; unsigned interr_irq; + spinlock_t lock; /* exclusive access for multi core */ }; static inline struct ltq_uart_port *to_ltq_uart_port(struct uart_port *port) @@ -133,10 +133,11 @@ static void lqasc_stop_tx(struct uart_port *port) static void lqasc_start_tx(struct uart_port *port) { unsigned long flags; - spin_lock_irqsave(_asc_lock, flags); + struct ltq_uart_port *ltq_port = to_ltq_uart_port(port); + + spin_lock_irqsave(_port->lock, flags); lqasc_tx_chars(port); - spin_unlock_irqrestore(_asc_lock, flags); - return; + spin_unlock_irqrestore(_port->lock, flags); } static void lqasc_stop_rx(struct uart_port *port) @@ -238,10 +239,14 @@ static irqreturn_t lqasc_tx_int(int irq, void *_port) { unsigned long flags; struct uart_port *port = (struct uart_port *)_port; - spin_lock_irqsave(_asc_lock, flags); + struct ltq_uart_port *ltq_port = to_ltq_uart_port(port); + + spin_lock_irqsave(_port->lock, flags); writel(ASC_IRNCR_TIR, port->membase + LTQ_ASC_IRNCR); - spin_unlock_irqrestore(_asc_lock, flags); + spin_unlock_irqrestore(_port->lock, flags); + lqasc_start_tx(port); + return IRQ_HANDLED; } @@ -250,8 +255,9 @@ static irqreturn_t lqasc_err_int(int irq, void *_port) unsigned long flags; u32 stat; struct uart_port *port = (struct uart_port *)_port; + struct ltq_uart_port *ltq_port = to_ltq_uart_port(port); - spin_lock_irqsave(_asc_lock, flags); + spin_lock_irqsave(_port->lock, flags); /* clear any pending interrupts */ writel(ASC_IRNCR_EIR, port->membase + LTQ_ASC_IRNCR); stat = readl(port->membase + LTQ_ASC_STATE); @@ -266,7 +272,7 @@ static irqreturn_t lqasc_err_int(int irq, void *_port) port->icount.overrun++; } asc_w32_mask(0, ASCWHBSTATE_CLRALL, port->membase + LTQ_ASC_WHBSTATE); - spin_unlock_irqrestore(_asc_lock, flags); + spin_unlock_irqrestore(_port->lock, flags); return IRQ_HANDLED; } @@ -275,10 +281,13 @@ static irqreturn_t lqasc_rx_int(int irq, void *_port) { unsigned long flags; struct uart_port *port = (struct uart_port *)_port; - spin_lock_irqsave(_asc_lock, flags); + struct ltq_uart_port *ltq_port = to_ltq_uart_port(port); + + spin_lock_irqsave(_port->lock, flags); writel(ASC_IRNCR_RIR, port->membase + LTQ_ASC_IRNCR); lqasc_rx_chars(port); - spin_unlock_irqrestore(_asc_lock, flags); + spin_unlock_irqrestore(_port->lock, flags); + return IRQ_HANDLED; } @@ -309,11 +318,13 @@ lqasc_startup(struct uart_port *port) { struct ltq_uart_port *ltq_port = to_ltq_uart_port(port); int retval; + unsigned long flags; if (!IS_ERR(ltq_port->clk)) clk_enable(ltq_port->clk); port->uartclk = clk_get_rate(ltq_port->fpiclk); + spin_lock_irqsave(_port->lock, flags); asc_w32_mask(ASCCLC_DISS | ASCCLC_RMCMASK, (1 << ASCCLC_RMCOFFSET), port->membase + LTQ_ASC_CLC); @@ -330,6 +341,7 @@ lqasc_startup(struct uart_port *port) wmb(); asc_w32_mask(0, ASCCON_M_8ASYNC | ASCCON_FEN | ASCCON_TOEN | ASCCON_ROEN, port->membase + LTQ_ASC_CON); + spin_unlock_irqrestore(_port->lock, flags); retval = request_irq(ltq_port->tx_irq, lqasc_tx_int, 0, "asc_tx", port); @@ -410,6 +422,7 @@ static void lqasc_set_termios(struct uart_port *port, unsigned long flags; u32 fdv = 0; u32 reload = 0; + struct ltq_uart_port *ltq_port = to_ltq_uart_port(port); cflag = new->c_cflag; iflag = new->c_iflag; @@ -463,7 +476,7 @@ static void lqasc_set_termios(struct uart_port *port, /* set error signals - framing, parity and overrun, enable
[PATCH 4/7] tty: serial: lantiq: Always use readl()/writel()
Previous implementation uses platform-dependent functions ltq_w32()/ltq_r32() to access registers. Those functions are not available for other SoC which uses the same IP. Change to OS provided readl()/writel() and readb()/writeb(), so that different SoCs can use the same driver. Signed-off-by: Songjun Wu --- arch/mips/Kconfig | 1 - drivers/tty/serial/lantiq.c | 236 2 files changed, 128 insertions(+), 109 deletions(-) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index c82cebeb6192..7bae259edd0b 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -395,7 +395,6 @@ config LANTIQ select SYS_SUPPORTS_VPE_LOADER select SYS_HAS_EARLY_PRINTK select GPIOLIB - select SWAP_IO_SPACE select BOOT_RAW select CLKDEV_LOOKUP select USE_OF diff --git a/drivers/tty/serial/lantiq.c b/drivers/tty/serial/lantiq.c index 044128277248..1127586dbc94 100644 --- a/drivers/tty/serial/lantiq.c +++ b/drivers/tty/serial/lantiq.c @@ -49,7 +49,8 @@ #define LTQ_ASC_RXFCON 0x0040 #define LTQ_ASC_CON0x0010 #define LTQ_ASC_BG 0x0050 -#define LTQ_ASC_IRNREN 0x00F4 +#define LTQ_ASC_FDV0x0058 +#define LTQ_ASC_IRNEN 0x00F4 #define ASC_IRNREN_TX 0x1 #define ASC_IRNREN_RX 0x2 @@ -62,6 +63,7 @@ #define ASCOPT_CSIZE 0x3 #define TXFIFO_FL 1 #define RXFIFO_FL 1 +#define ASCCLC_DISR0x1 #define ASCCLC_DISS0x2 #define ASCCLC_RMCMASK 0xFF00 #define ASCCLC_RMCOFFSET 8 @@ -84,6 +86,7 @@ #define ASCWHBSTATE_CLRPE 0x0004 #define ASCWHBSTATE_CLRFE 0x0008 #define ASCWHBSTATE_CLRROE 0x0020 +#define ASCWHBSTATE_CLRALL 0x00FC #define ASCTXFCON_TXFEN0x0001 #define ASCTXFCON_TXFFLU 0x0002 #define ASCTXFCON_TXFITLMASK 0x3F00 @@ -97,6 +100,10 @@ #define ASCFSTAT_TXFREEMASK0x3F00 #define ASCFSTAT_TXFREEOFF 24 +#define asc_w32_mask(clear, set, reg) \ + ({ typeof(reg) reg_ = (reg);\ + writel((readl(reg_) & ~(clear)) | (set), reg_); }) + static void lqasc_tx_chars(struct uart_port *port); static struct ltq_uart_port *lqasc_port[MAXPORTS]; static struct uart_driver lqasc_reg; @@ -113,20 +120,17 @@ struct ltq_uart_port { unsigned interr_irq; }; -static inline struct -ltq_uart_port *to_ltq_uart_port(struct uart_port *port) +static inline struct ltq_uart_port *to_ltq_uart_port(struct uart_port *port) { return container_of(port, struct ltq_uart_port, port); } -static void -lqasc_stop_tx(struct uart_port *port) +static void lqasc_stop_tx(struct uart_port *port) { return; } -static void -lqasc_start_tx(struct uart_port *port) +static void lqasc_start_tx(struct uart_port *port) { unsigned long flags; spin_lock_irqsave(_asc_lock, flags); @@ -135,23 +139,21 @@ lqasc_start_tx(struct uart_port *port) return; } -static void -lqasc_stop_rx(struct uart_port *port) +static void lqasc_stop_rx(struct uart_port *port) { - ltq_w32(ASCWHBSTATE_CLRREN, port->membase + LTQ_ASC_WHBSTATE); + writel(ASCWHBSTATE_CLRREN, port->membase + LTQ_ASC_WHBSTATE); } -static int -lqasc_rx_chars(struct uart_port *port) +static int lqasc_rx_chars(struct uart_port *port) { struct tty_port *tport = >state->port; unsigned int ch = 0, rsr = 0, fifocnt; - fifocnt = ltq_r32(port->membase + LTQ_ASC_FSTAT) & ASCFSTAT_RXFFLMASK; + fifocnt = readl(port->membase + LTQ_ASC_FSTAT) & ASCFSTAT_RXFFLMASK; while (fifocnt--) { u8 flag = TTY_NORMAL; - ch = ltq_r8(port->membase + LTQ_ASC_RBUF); - rsr = (ltq_r32(port->membase + LTQ_ASC_STATE) + ch = readb(port->membase + LTQ_ASC_RBUF); + rsr = (readl(port->membase + LTQ_ASC_STATE) & ASCSTATE_ANY) | UART_DUMMY_UER_RX; tty_flip_buffer_push(tport); port->icount.rx++; @@ -163,16 +165,16 @@ lqasc_rx_chars(struct uart_port *port) if (rsr & ASCSTATE_ANY) { if (rsr & ASCSTATE_PE) { port->icount.parity++; - ltq_w32_mask(0, ASCWHBSTATE_CLRPE, + asc_w32_mask(0, ASCWHBSTATE_CLRPE, port->membase + LTQ_ASC_WHBSTATE); } else if (rsr & ASCSTATE_FE) { port->icount.frame++; - ltq_w32_mask(0, ASCWHBSTATE_CLRFE, + asc_w32_mask(0, ASCWHBSTATE_CLRFE, port->membase + LTQ_ASC_WHBSTATE); } if (rsr & ASCSTATE_ROE) { port->icount.overrun++; -
[PATCH 5/7] tty: serial: lantiq: Convert global lock to per device lock
Previous implementation uses one global lock to protect the resource. If the serial driver have multiple entries, this kind of lock will slow down the performance. Add the lock at device level. This will lock only when the function calling only to the same device. So that it can avoid useless lock protection. Signed-off-by: Songjun Wu --- drivers/tty/serial/lantiq.c | 51 ++--- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/drivers/tty/serial/lantiq.c b/drivers/tty/serial/lantiq.c index 1127586dbc94..72aab1b05265 100644 --- a/drivers/tty/serial/lantiq.c +++ b/drivers/tty/serial/lantiq.c @@ -107,7 +107,6 @@ static void lqasc_tx_chars(struct uart_port *port); static struct ltq_uart_port *lqasc_port[MAXPORTS]; static struct uart_driver lqasc_reg; -static DEFINE_SPINLOCK(ltq_asc_lock); struct ltq_uart_port { struct uart_portport; @@ -118,6 +117,7 @@ struct ltq_uart_port { unsigned inttx_irq; unsigned intrx_irq; unsigned interr_irq; + spinlock_t lock; /* exclusive access for multi core */ }; static inline struct ltq_uart_port *to_ltq_uart_port(struct uart_port *port) @@ -133,10 +133,11 @@ static void lqasc_stop_tx(struct uart_port *port) static void lqasc_start_tx(struct uart_port *port) { unsigned long flags; - spin_lock_irqsave(_asc_lock, flags); + struct ltq_uart_port *ltq_port = to_ltq_uart_port(port); + + spin_lock_irqsave(_port->lock, flags); lqasc_tx_chars(port); - spin_unlock_irqrestore(_asc_lock, flags); - return; + spin_unlock_irqrestore(_port->lock, flags); } static void lqasc_stop_rx(struct uart_port *port) @@ -238,10 +239,14 @@ static irqreturn_t lqasc_tx_int(int irq, void *_port) { unsigned long flags; struct uart_port *port = (struct uart_port *)_port; - spin_lock_irqsave(_asc_lock, flags); + struct ltq_uart_port *ltq_port = to_ltq_uart_port(port); + + spin_lock_irqsave(_port->lock, flags); writel(ASC_IRNCR_TIR, port->membase + LTQ_ASC_IRNCR); - spin_unlock_irqrestore(_asc_lock, flags); + spin_unlock_irqrestore(_port->lock, flags); + lqasc_start_tx(port); + return IRQ_HANDLED; } @@ -250,8 +255,9 @@ static irqreturn_t lqasc_err_int(int irq, void *_port) unsigned long flags; u32 stat; struct uart_port *port = (struct uart_port *)_port; + struct ltq_uart_port *ltq_port = to_ltq_uart_port(port); - spin_lock_irqsave(_asc_lock, flags); + spin_lock_irqsave(_port->lock, flags); /* clear any pending interrupts */ writel(ASC_IRNCR_EIR, port->membase + LTQ_ASC_IRNCR); stat = readl(port->membase + LTQ_ASC_STATE); @@ -266,7 +272,7 @@ static irqreturn_t lqasc_err_int(int irq, void *_port) port->icount.overrun++; } asc_w32_mask(0, ASCWHBSTATE_CLRALL, port->membase + LTQ_ASC_WHBSTATE); - spin_unlock_irqrestore(_asc_lock, flags); + spin_unlock_irqrestore(_port->lock, flags); return IRQ_HANDLED; } @@ -275,10 +281,13 @@ static irqreturn_t lqasc_rx_int(int irq, void *_port) { unsigned long flags; struct uart_port *port = (struct uart_port *)_port; - spin_lock_irqsave(_asc_lock, flags); + struct ltq_uart_port *ltq_port = to_ltq_uart_port(port); + + spin_lock_irqsave(_port->lock, flags); writel(ASC_IRNCR_RIR, port->membase + LTQ_ASC_IRNCR); lqasc_rx_chars(port); - spin_unlock_irqrestore(_asc_lock, flags); + spin_unlock_irqrestore(_port->lock, flags); + return IRQ_HANDLED; } @@ -309,11 +318,13 @@ lqasc_startup(struct uart_port *port) { struct ltq_uart_port *ltq_port = to_ltq_uart_port(port); int retval; + unsigned long flags; if (!IS_ERR(ltq_port->clk)) clk_enable(ltq_port->clk); port->uartclk = clk_get_rate(ltq_port->fpiclk); + spin_lock_irqsave(_port->lock, flags); asc_w32_mask(ASCCLC_DISS | ASCCLC_RMCMASK, (1 << ASCCLC_RMCOFFSET), port->membase + LTQ_ASC_CLC); @@ -330,6 +341,7 @@ lqasc_startup(struct uart_port *port) wmb(); asc_w32_mask(0, ASCCON_M_8ASYNC | ASCCON_FEN | ASCCON_TOEN | ASCCON_ROEN, port->membase + LTQ_ASC_CON); + spin_unlock_irqrestore(_port->lock, flags); retval = request_irq(ltq_port->tx_irq, lqasc_tx_int, 0, "asc_tx", port); @@ -410,6 +422,7 @@ static void lqasc_set_termios(struct uart_port *port, unsigned long flags; u32 fdv = 0; u32 reload = 0; + struct ltq_uart_port *ltq_port = to_ltq_uart_port(port); cflag = new->c_cflag; iflag = new->c_iflag; @@ -463,7 +476,7 @@ static void lqasc_set_termios(struct uart_port *port, /* set error signals - framing, parity and overrun, enable
[PATCH 4/7] tty: serial: lantiq: Always use readl()/writel()
Previous implementation uses platform-dependent functions ltq_w32()/ltq_r32() to access registers. Those functions are not available for other SoC which uses the same IP. Change to OS provided readl()/writel() and readb()/writeb(), so that different SoCs can use the same driver. Signed-off-by: Songjun Wu --- arch/mips/Kconfig | 1 - drivers/tty/serial/lantiq.c | 236 2 files changed, 128 insertions(+), 109 deletions(-) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index c82cebeb6192..7bae259edd0b 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -395,7 +395,6 @@ config LANTIQ select SYS_SUPPORTS_VPE_LOADER select SYS_HAS_EARLY_PRINTK select GPIOLIB - select SWAP_IO_SPACE select BOOT_RAW select CLKDEV_LOOKUP select USE_OF diff --git a/drivers/tty/serial/lantiq.c b/drivers/tty/serial/lantiq.c index 044128277248..1127586dbc94 100644 --- a/drivers/tty/serial/lantiq.c +++ b/drivers/tty/serial/lantiq.c @@ -49,7 +49,8 @@ #define LTQ_ASC_RXFCON 0x0040 #define LTQ_ASC_CON0x0010 #define LTQ_ASC_BG 0x0050 -#define LTQ_ASC_IRNREN 0x00F4 +#define LTQ_ASC_FDV0x0058 +#define LTQ_ASC_IRNEN 0x00F4 #define ASC_IRNREN_TX 0x1 #define ASC_IRNREN_RX 0x2 @@ -62,6 +63,7 @@ #define ASCOPT_CSIZE 0x3 #define TXFIFO_FL 1 #define RXFIFO_FL 1 +#define ASCCLC_DISR0x1 #define ASCCLC_DISS0x2 #define ASCCLC_RMCMASK 0xFF00 #define ASCCLC_RMCOFFSET 8 @@ -84,6 +86,7 @@ #define ASCWHBSTATE_CLRPE 0x0004 #define ASCWHBSTATE_CLRFE 0x0008 #define ASCWHBSTATE_CLRROE 0x0020 +#define ASCWHBSTATE_CLRALL 0x00FC #define ASCTXFCON_TXFEN0x0001 #define ASCTXFCON_TXFFLU 0x0002 #define ASCTXFCON_TXFITLMASK 0x3F00 @@ -97,6 +100,10 @@ #define ASCFSTAT_TXFREEMASK0x3F00 #define ASCFSTAT_TXFREEOFF 24 +#define asc_w32_mask(clear, set, reg) \ + ({ typeof(reg) reg_ = (reg);\ + writel((readl(reg_) & ~(clear)) | (set), reg_); }) + static void lqasc_tx_chars(struct uart_port *port); static struct ltq_uart_port *lqasc_port[MAXPORTS]; static struct uart_driver lqasc_reg; @@ -113,20 +120,17 @@ struct ltq_uart_port { unsigned interr_irq; }; -static inline struct -ltq_uart_port *to_ltq_uart_port(struct uart_port *port) +static inline struct ltq_uart_port *to_ltq_uart_port(struct uart_port *port) { return container_of(port, struct ltq_uart_port, port); } -static void -lqasc_stop_tx(struct uart_port *port) +static void lqasc_stop_tx(struct uart_port *port) { return; } -static void -lqasc_start_tx(struct uart_port *port) +static void lqasc_start_tx(struct uart_port *port) { unsigned long flags; spin_lock_irqsave(_asc_lock, flags); @@ -135,23 +139,21 @@ lqasc_start_tx(struct uart_port *port) return; } -static void -lqasc_stop_rx(struct uart_port *port) +static void lqasc_stop_rx(struct uart_port *port) { - ltq_w32(ASCWHBSTATE_CLRREN, port->membase + LTQ_ASC_WHBSTATE); + writel(ASCWHBSTATE_CLRREN, port->membase + LTQ_ASC_WHBSTATE); } -static int -lqasc_rx_chars(struct uart_port *port) +static int lqasc_rx_chars(struct uart_port *port) { struct tty_port *tport = >state->port; unsigned int ch = 0, rsr = 0, fifocnt; - fifocnt = ltq_r32(port->membase + LTQ_ASC_FSTAT) & ASCFSTAT_RXFFLMASK; + fifocnt = readl(port->membase + LTQ_ASC_FSTAT) & ASCFSTAT_RXFFLMASK; while (fifocnt--) { u8 flag = TTY_NORMAL; - ch = ltq_r8(port->membase + LTQ_ASC_RBUF); - rsr = (ltq_r32(port->membase + LTQ_ASC_STATE) + ch = readb(port->membase + LTQ_ASC_RBUF); + rsr = (readl(port->membase + LTQ_ASC_STATE) & ASCSTATE_ANY) | UART_DUMMY_UER_RX; tty_flip_buffer_push(tport); port->icount.rx++; @@ -163,16 +165,16 @@ lqasc_rx_chars(struct uart_port *port) if (rsr & ASCSTATE_ANY) { if (rsr & ASCSTATE_PE) { port->icount.parity++; - ltq_w32_mask(0, ASCWHBSTATE_CLRPE, + asc_w32_mask(0, ASCWHBSTATE_CLRPE, port->membase + LTQ_ASC_WHBSTATE); } else if (rsr & ASCSTATE_FE) { port->icount.frame++; - ltq_w32_mask(0, ASCWHBSTATE_CLRFE, + asc_w32_mask(0, ASCWHBSTATE_CLRFE, port->membase + LTQ_ASC_WHBSTATE); } if (rsr & ASCSTATE_ROE) { port->icount.overrun++; -
[PATCH 3/7] MIPS: intel: Add initial support for Intel MIPS SoCs
From: Hua Ma Add initial support for Intel MIPS interAptiv SoCs made by Intel. This series will add support for the GRX500 family. The series allows booting a minimal system using a initramfs. Signed-off-by: Hua ma Signed-off-by: Songjun Wu --- arch/mips/Kbuild.platforms | 1 + arch/mips/Kconfig | 36 arch/mips/boot/dts/Makefile| 1 + arch/mips/boot/dts/intel-mips/Makefile | 3 + arch/mips/boot/dts/intel-mips/easy350_anywan.dts | 20 +++ arch/mips/boot/dts/intel-mips/xrx500.dtsi | 196 + arch/mips/configs/grx500_defconfig | 165 + .../asm/mach-intel-mips/cpu-feature-overrides.h| 61 +++ arch/mips/include/asm/mach-intel-mips/ioremap.h| 39 arch/mips/include/asm/mach-intel-mips/irq.h| 17 ++ .../asm/mach-intel-mips/kernel-entry-init.h| 76 arch/mips/include/asm/mach-intel-mips/spaces.h | 29 +++ arch/mips/include/asm/mach-intel-mips/war.h| 18 ++ arch/mips/intel-mips/Kconfig | 22 +++ arch/mips/intel-mips/Makefile | 3 + arch/mips/intel-mips/Platform | 11 ++ arch/mips/intel-mips/irq.c | 36 arch/mips/intel-mips/prom.c| 184 +++ arch/mips/intel-mips/time.c| 56 ++ 19 files changed, 974 insertions(+) create mode 100644 arch/mips/boot/dts/intel-mips/Makefile create mode 100644 arch/mips/boot/dts/intel-mips/easy350_anywan.dts create mode 100644 arch/mips/boot/dts/intel-mips/xrx500.dtsi create mode 100644 arch/mips/configs/grx500_defconfig create mode 100644 arch/mips/include/asm/mach-intel-mips/cpu-feature-overrides.h create mode 100644 arch/mips/include/asm/mach-intel-mips/ioremap.h create mode 100644 arch/mips/include/asm/mach-intel-mips/irq.h create mode 100644 arch/mips/include/asm/mach-intel-mips/kernel-entry-init.h create mode 100644 arch/mips/include/asm/mach-intel-mips/spaces.h create mode 100644 arch/mips/include/asm/mach-intel-mips/war.h create mode 100644 arch/mips/intel-mips/Kconfig create mode 100644 arch/mips/intel-mips/Makefile create mode 100644 arch/mips/intel-mips/Platform create mode 100644 arch/mips/intel-mips/irq.c create mode 100644 arch/mips/intel-mips/prom.c create mode 100644 arch/mips/intel-mips/time.c diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms index ac7ad54f984f..bcd647060f3e 100644 --- a/arch/mips/Kbuild.platforms +++ b/arch/mips/Kbuild.platforms @@ -12,6 +12,7 @@ platforms += cobalt platforms += dec platforms += emma platforms += generic +platforms += intel-mips platforms += jazz platforms += jz4740 platforms += lantiq diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 225c95da23ce..c82cebeb6192 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -404,6 +404,41 @@ config LANTIQ select ARCH_HAS_RESET_CONTROLLER select RESET_CONTROLLER +config INTEL_MIPS + bool "Intel MIPS interAptiv SoC based platforms" + select ARCH_HAS_RESET_CONTROLLER + select ARCH_SUPPORTS_MSI + select BOOT_RAW + select CEVT_R4K + select COMMON_CLK + select CPU_MIPS32_3_5_EVA + select CPU_MIPS32_3_5_FEATURES + select CPU_MIPSR2_IRQ_EI + select CPU_MIPSR2_IRQ_VI + select CSRC_R4K + select DMA_NONCOHERENT + select GENERIC_ISA_DMA + select GPIOLIB + select HW_HAS_PCI + select IRQ_MIPS_CPU + select MFD_CORE + select MFD_SYSCON + select MIPS_CPU_SCACHE + select MIPS_GIC + select PCI_DRIVERS_GENERIC + select RESET_CONTROLLER + select SYS_HAS_CPU_MIPS32_R1 + select SYS_HAS_CPU_MIPS32_R2 + select SYS_HAS_CPU_MIPS32_R3_5 + select SYS_HAS_EARLY_PRINTK + select SYS_SUPPORTS_BIG_ENDIAN + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_MIPS_CPS + select SYS_SUPPORTS_MULTITHREADING + select SYS_SUPPORTS_ZBOOT + select TIMER_OF + select USE_OF + config LASAT bool "LASAT Networks platforms" select CEVT_R4K @@ -1010,6 +1045,7 @@ source "arch/mips/bcm47xx/Kconfig" source "arch/mips/bcm63xx/Kconfig" source "arch/mips/bmips/Kconfig" source "arch/mips/generic/Kconfig" +source "arch/mips/intel-mips/Kconfig" source "arch/mips/jazz/Kconfig" source "arch/mips/jz4740/Kconfig" source "arch/mips/lantiq/Kconfig" diff --git a/arch/mips/boot/dts/Makefile b/arch/mips/boot/dts/Makefile index 1e79cab8e269..05f52f279047 100644 --- a/arch/mips/boot/dts/Makefile +++ b/arch/mips/boot/dts/Makefile @@ -3,6 +3,7 @@ subdir-y+= brcm subdir-y += cavium-octeon subdir-y += img subdir-y += ingenic +subdir-y += intel-mips subdir-y += lantiq subdir-y += mscc subdir-y += mti diff --git
[PATCH 3/7] MIPS: intel: Add initial support for Intel MIPS SoCs
From: Hua Ma Add initial support for Intel MIPS interAptiv SoCs made by Intel. This series will add support for the GRX500 family. The series allows booting a minimal system using a initramfs. Signed-off-by: Hua ma Signed-off-by: Songjun Wu --- arch/mips/Kbuild.platforms | 1 + arch/mips/Kconfig | 36 arch/mips/boot/dts/Makefile| 1 + arch/mips/boot/dts/intel-mips/Makefile | 3 + arch/mips/boot/dts/intel-mips/easy350_anywan.dts | 20 +++ arch/mips/boot/dts/intel-mips/xrx500.dtsi | 196 + arch/mips/configs/grx500_defconfig | 165 + .../asm/mach-intel-mips/cpu-feature-overrides.h| 61 +++ arch/mips/include/asm/mach-intel-mips/ioremap.h| 39 arch/mips/include/asm/mach-intel-mips/irq.h| 17 ++ .../asm/mach-intel-mips/kernel-entry-init.h| 76 arch/mips/include/asm/mach-intel-mips/spaces.h | 29 +++ arch/mips/include/asm/mach-intel-mips/war.h| 18 ++ arch/mips/intel-mips/Kconfig | 22 +++ arch/mips/intel-mips/Makefile | 3 + arch/mips/intel-mips/Platform | 11 ++ arch/mips/intel-mips/irq.c | 36 arch/mips/intel-mips/prom.c| 184 +++ arch/mips/intel-mips/time.c| 56 ++ 19 files changed, 974 insertions(+) create mode 100644 arch/mips/boot/dts/intel-mips/Makefile create mode 100644 arch/mips/boot/dts/intel-mips/easy350_anywan.dts create mode 100644 arch/mips/boot/dts/intel-mips/xrx500.dtsi create mode 100644 arch/mips/configs/grx500_defconfig create mode 100644 arch/mips/include/asm/mach-intel-mips/cpu-feature-overrides.h create mode 100644 arch/mips/include/asm/mach-intel-mips/ioremap.h create mode 100644 arch/mips/include/asm/mach-intel-mips/irq.h create mode 100644 arch/mips/include/asm/mach-intel-mips/kernel-entry-init.h create mode 100644 arch/mips/include/asm/mach-intel-mips/spaces.h create mode 100644 arch/mips/include/asm/mach-intel-mips/war.h create mode 100644 arch/mips/intel-mips/Kconfig create mode 100644 arch/mips/intel-mips/Makefile create mode 100644 arch/mips/intel-mips/Platform create mode 100644 arch/mips/intel-mips/irq.c create mode 100644 arch/mips/intel-mips/prom.c create mode 100644 arch/mips/intel-mips/time.c diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms index ac7ad54f984f..bcd647060f3e 100644 --- a/arch/mips/Kbuild.platforms +++ b/arch/mips/Kbuild.platforms @@ -12,6 +12,7 @@ platforms += cobalt platforms += dec platforms += emma platforms += generic +platforms += intel-mips platforms += jazz platforms += jz4740 platforms += lantiq diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 225c95da23ce..c82cebeb6192 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -404,6 +404,41 @@ config LANTIQ select ARCH_HAS_RESET_CONTROLLER select RESET_CONTROLLER +config INTEL_MIPS + bool "Intel MIPS interAptiv SoC based platforms" + select ARCH_HAS_RESET_CONTROLLER + select ARCH_SUPPORTS_MSI + select BOOT_RAW + select CEVT_R4K + select COMMON_CLK + select CPU_MIPS32_3_5_EVA + select CPU_MIPS32_3_5_FEATURES + select CPU_MIPSR2_IRQ_EI + select CPU_MIPSR2_IRQ_VI + select CSRC_R4K + select DMA_NONCOHERENT + select GENERIC_ISA_DMA + select GPIOLIB + select HW_HAS_PCI + select IRQ_MIPS_CPU + select MFD_CORE + select MFD_SYSCON + select MIPS_CPU_SCACHE + select MIPS_GIC + select PCI_DRIVERS_GENERIC + select RESET_CONTROLLER + select SYS_HAS_CPU_MIPS32_R1 + select SYS_HAS_CPU_MIPS32_R2 + select SYS_HAS_CPU_MIPS32_R3_5 + select SYS_HAS_EARLY_PRINTK + select SYS_SUPPORTS_BIG_ENDIAN + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_MIPS_CPS + select SYS_SUPPORTS_MULTITHREADING + select SYS_SUPPORTS_ZBOOT + select TIMER_OF + select USE_OF + config LASAT bool "LASAT Networks platforms" select CEVT_R4K @@ -1010,6 +1045,7 @@ source "arch/mips/bcm47xx/Kconfig" source "arch/mips/bcm63xx/Kconfig" source "arch/mips/bmips/Kconfig" source "arch/mips/generic/Kconfig" +source "arch/mips/intel-mips/Kconfig" source "arch/mips/jazz/Kconfig" source "arch/mips/jz4740/Kconfig" source "arch/mips/lantiq/Kconfig" diff --git a/arch/mips/boot/dts/Makefile b/arch/mips/boot/dts/Makefile index 1e79cab8e269..05f52f279047 100644 --- a/arch/mips/boot/dts/Makefile +++ b/arch/mips/boot/dts/Makefile @@ -3,6 +3,7 @@ subdir-y+= brcm subdir-y += cavium-octeon subdir-y += img subdir-y += ingenic +subdir-y += intel-mips subdir-y += lantiq subdir-y += mscc subdir-y += mti diff --git
[PATCH 6/7] tty: serial: lantiq: Remove unneeded header includes and macros
Update the author list with Intel Corporation. Sort the header includes in alphabetical orders. Remove unneeded header includes and macros. Signed-off-by: Songjun Wu --- drivers/tty/serial/lantiq.c | 29 +++-- 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/drivers/tty/serial/lantiq.c b/drivers/tty/serial/lantiq.c index 72aab1b05265..cc33208c93ac 100644 --- a/drivers/tty/serial/lantiq.c +++ b/drivers/tty/serial/lantiq.c @@ -6,24 +6,23 @@ * Copyright (C) 2007 Felix Fietkau * Copyright (C) 2007 John Crispin * Copyright (C) 2010 Thomas Langer, + * Copyright (C) 2017 Intel Corporation. */ -#include -#include -#include +#include #include -#include #include -#include -#include -#include -#include +#include +#include +#include #include #include #include -#include -#include -#include +#include +#include +#include +#include +#include #include @@ -43,7 +42,6 @@ #define LTQ_ASC_STATE 0x0014 #define LTQ_ASC_IRNCR 0x00F8 #define LTQ_ASC_CLC0x -#define LTQ_ASC_ID 0x0008 #define LTQ_ASC_PISEL 0x0004 #define LTQ_ASC_TXFCON 0x0044 #define LTQ_ASC_RXFCON 0x0040 @@ -51,16 +49,12 @@ #define LTQ_ASC_BG 0x0050 #define LTQ_ASC_FDV0x0058 #define LTQ_ASC_IRNEN 0x00F4 - #define ASC_IRNREN_TX 0x1 #define ASC_IRNREN_RX 0x2 #define ASC_IRNREN_ERR 0x4 -#define ASC_IRNREN_TX_BUF 0x8 #define ASC_IRNCR_TIR 0x1 #define ASC_IRNCR_RIR 0x2 #define ASC_IRNCR_EIR 0x4 - -#define ASCOPT_CSIZE 0x3 #define TXFIFO_FL 1 #define RXFIFO_FL 1 #define ASCCLC_DISR0x1 @@ -71,7 +65,6 @@ #define ASCCON_M_7ASYNC0x2 #define ASCCON_ODD 0x0020 #define ASCCON_STP 0x0080 -#define ASCCON_BRS 0x0100 #define ASCCON_FDE 0x0200 #define ASCCON_R 0x8000 #define ASCCON_FEN 0x0002 @@ -80,7 +73,7 @@ #define ASCSTATE_PE0x0001 #define ASCSTATE_FE0x0002 #define ASCSTATE_ROE 0x0008 -#define ASCSTATE_ANY (ASCSTATE_ROE|ASCSTATE_PE|ASCSTATE_FE) +#define ASCSTATE_ANY (ASCSTATE_ROE | ASCSTATE_PE | ASCSTATE_FE) #define ASCWHBSTATE_CLRREN 0x0001 #define ASCWHBSTATE_SETREN 0x0002 #define ASCWHBSTATE_CLRPE 0x0004 -- 2.11.0
Re: [PATCH 2/2] nvmem: Add Spreadtrum SC27XX efuse support
Hi Randy, On 12 June 2018 at 13:27, Randy Dunlap wrote: > On 06/11/2018 10:24 PM, Baolin Wang wrote: >> From: Freeman Liu >> >> This patch add the efuse driver which is embeded in Spreadtrum SC27XX >> series PMICs. The sc27xx efuse contains 32 blocks and each block's >> data width is 16 bits. >> >> Signed-off-by: Freeman Liu >> Signed-off-by: Baolin Wang >> --- >> drivers/nvmem/Kconfig| 11 ++ >> drivers/nvmem/Makefile |3 +- >> drivers/nvmem/sc27xx-efuse.c | 263 >> ++ >> 3 files changed, 276 insertions(+), 1 deletion(-) >> create mode 100644 drivers/nvmem/sc27xx-efuse.c >> >> diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig >> index 54a3c29..3dca608 100644 >> --- a/drivers/nvmem/Kconfig >> +++ b/drivers/nvmem/Kconfig >> @@ -181,4 +181,15 @@ config RAVE_SP_EEPROM >> help >> Say y here to enable Rave SP EEPROM support. >> >> +config SC27XX_EFUSE >> + tristate "Spreadtrum SC27XX eFuse Support" >> + depends on MFD_SC27XX_PMIC || COMPILE_TEST >> + depends on HAS_IOMEM >> + help >> + This is a simple drive to dump specified values of Spreadtrum > >driver Sorry for the typo and will fix in next version. Thanks. -- Baolin.wang Best Regards
[PATCH 6/7] tty: serial: lantiq: Remove unneeded header includes and macros
Update the author list with Intel Corporation. Sort the header includes in alphabetical orders. Remove unneeded header includes and macros. Signed-off-by: Songjun Wu --- drivers/tty/serial/lantiq.c | 29 +++-- 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/drivers/tty/serial/lantiq.c b/drivers/tty/serial/lantiq.c index 72aab1b05265..cc33208c93ac 100644 --- a/drivers/tty/serial/lantiq.c +++ b/drivers/tty/serial/lantiq.c @@ -6,24 +6,23 @@ * Copyright (C) 2007 Felix Fietkau * Copyright (C) 2007 John Crispin * Copyright (C) 2010 Thomas Langer, + * Copyright (C) 2017 Intel Corporation. */ -#include -#include -#include +#include #include -#include #include -#include -#include -#include -#include +#include +#include +#include #include #include #include -#include -#include -#include +#include +#include +#include +#include +#include #include @@ -43,7 +42,6 @@ #define LTQ_ASC_STATE 0x0014 #define LTQ_ASC_IRNCR 0x00F8 #define LTQ_ASC_CLC0x -#define LTQ_ASC_ID 0x0008 #define LTQ_ASC_PISEL 0x0004 #define LTQ_ASC_TXFCON 0x0044 #define LTQ_ASC_RXFCON 0x0040 @@ -51,16 +49,12 @@ #define LTQ_ASC_BG 0x0050 #define LTQ_ASC_FDV0x0058 #define LTQ_ASC_IRNEN 0x00F4 - #define ASC_IRNREN_TX 0x1 #define ASC_IRNREN_RX 0x2 #define ASC_IRNREN_ERR 0x4 -#define ASC_IRNREN_TX_BUF 0x8 #define ASC_IRNCR_TIR 0x1 #define ASC_IRNCR_RIR 0x2 #define ASC_IRNCR_EIR 0x4 - -#define ASCOPT_CSIZE 0x3 #define TXFIFO_FL 1 #define RXFIFO_FL 1 #define ASCCLC_DISR0x1 @@ -71,7 +65,6 @@ #define ASCCON_M_7ASYNC0x2 #define ASCCON_ODD 0x0020 #define ASCCON_STP 0x0080 -#define ASCCON_BRS 0x0100 #define ASCCON_FDE 0x0200 #define ASCCON_R 0x8000 #define ASCCON_FEN 0x0002 @@ -80,7 +73,7 @@ #define ASCSTATE_PE0x0001 #define ASCSTATE_FE0x0002 #define ASCSTATE_ROE 0x0008 -#define ASCSTATE_ANY (ASCSTATE_ROE|ASCSTATE_PE|ASCSTATE_FE) +#define ASCSTATE_ANY (ASCSTATE_ROE | ASCSTATE_PE | ASCSTATE_FE) #define ASCWHBSTATE_CLRREN 0x0001 #define ASCWHBSTATE_SETREN 0x0002 #define ASCWHBSTATE_CLRPE 0x0004 -- 2.11.0
Re: [PATCH 2/2] nvmem: Add Spreadtrum SC27XX efuse support
Hi Randy, On 12 June 2018 at 13:27, Randy Dunlap wrote: > On 06/11/2018 10:24 PM, Baolin Wang wrote: >> From: Freeman Liu >> >> This patch add the efuse driver which is embeded in Spreadtrum SC27XX >> series PMICs. The sc27xx efuse contains 32 blocks and each block's >> data width is 16 bits. >> >> Signed-off-by: Freeman Liu >> Signed-off-by: Baolin Wang >> --- >> drivers/nvmem/Kconfig| 11 ++ >> drivers/nvmem/Makefile |3 +- >> drivers/nvmem/sc27xx-efuse.c | 263 >> ++ >> 3 files changed, 276 insertions(+), 1 deletion(-) >> create mode 100644 drivers/nvmem/sc27xx-efuse.c >> >> diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig >> index 54a3c29..3dca608 100644 >> --- a/drivers/nvmem/Kconfig >> +++ b/drivers/nvmem/Kconfig >> @@ -181,4 +181,15 @@ config RAVE_SP_EEPROM >> help >> Say y here to enable Rave SP EEPROM support. >> >> +config SC27XX_EFUSE >> + tristate "Spreadtrum SC27XX eFuse Support" >> + depends on MFD_SC27XX_PMIC || COMPILE_TEST >> + depends on HAS_IOMEM >> + help >> + This is a simple drive to dump specified values of Spreadtrum > >driver Sorry for the typo and will fix in next version. Thanks. -- Baolin.wang Best Regards
[PATCH 1/7] MIPS: dts: Add aliases node for lantiq danube serial
Previous implementation uses a hard-coded register value to check if the current serial entity is the console entity. Now the lantiq serial driver uses the aliases for the index of the serial port. The lantiq danube serial dts are updated with aliases to support this. Signed-off-by: Songjun Wu --- arch/mips/boot/dts/lantiq/danube.dtsi | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/mips/boot/dts/lantiq/danube.dtsi b/arch/mips/boot/dts/lantiq/danube.dtsi index 2dd950181f8a..7a9e15da6bd0 100644 --- a/arch/mips/boot/dts/lantiq/danube.dtsi +++ b/arch/mips/boot/dts/lantiq/danube.dtsi @@ -4,6 +4,10 @@ #size-cells = <1>; compatible = "lantiq,xway", "lantiq,danube"; + aliases { + serial0 = + }; + cpus { cpu@0 { compatible = "mips,mips24Kc"; @@ -74,7 +78,7 @@ reg = <0xE100A00 0x100>; }; - serial@E100C00 { + asc1: serial@E100C00 { compatible = "lantiq,asc"; reg = <0xE100C00 0x400>; interrupt-parent = <>; -- 2.11.0
[PATCH 7/7] tty: serial: lantiq: Add CCF support
Previous implementation uses platform-dependent API to get the clock. Those functions are not available for other SoC which uses the same IP. The CCF (Common Clock Framework) have an abstraction based APIs for clock. Change to use CCF APIs to get clock and rate. So that different SoCs can use the same driver. Clocks and clock-names are updated in device tree binding. Signed-off-by: Songjun Wu --- .../devicetree/bindings/serial/lantiq_asc.txt | 15 +++ drivers/tty/serial/Kconfig | 2 +- drivers/tty/serial/lantiq.c| 101 + 3 files changed, 98 insertions(+), 20 deletions(-) diff --git a/Documentation/devicetree/bindings/serial/lantiq_asc.txt b/Documentation/devicetree/bindings/serial/lantiq_asc.txt index 3acbd309ab9d..608f0c87a4af 100644 --- a/Documentation/devicetree/bindings/serial/lantiq_asc.txt +++ b/Documentation/devicetree/bindings/serial/lantiq_asc.txt @@ -6,6 +6,10 @@ Required properties: - interrupts: the 3 (tx rx err) interrupt numbers. The interrupt specifier depends on the interrupt-parent interrupt controller. +Optional properties: +- clocks: Should contain frequency clock and gate clock +- clock-names: Should be "freq" and "asc" + Example: asc1: serial@e100c00 { @@ -14,3 +18,14 @@ asc1: serial@e100c00 { interrupt-parent = <>; interrupts = <112 113 114>; }; + +asc0: serial@60 { + compatible = "lantiq,asc"; + reg = <0x60 0x10>; + interrupt-parent = <>; + interrupts = , + , + ; + clocks = < SSX4_CLK>, < GATE_URT_CLK>; + clock-names = "freq", "asc"; +}; diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 0f058df0b070..0f8ac5872a54 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1062,7 +1062,7 @@ config SERIAL_OMAP_CONSOLE config SERIAL_LANTIQ bool "Lantiq serial driver" - depends on LANTIQ + depends on LANTIQ || INTEL_MIPS || COMPILE_TEST select SERIAL_CORE select SERIAL_CORE_CONSOLE select SERIAL_EARLYCON diff --git a/drivers/tty/serial/lantiq.c b/drivers/tty/serial/lantiq.c index cc33208c93ac..fd7ba89daaa2 100644 --- a/drivers/tty/serial/lantiq.c +++ b/drivers/tty/serial/lantiq.c @@ -24,7 +24,9 @@ #include #include +#ifndef CONFIG_COMMON_CLK #include +#endif #define PORT_LTQ_ASC 111 #define MAXPORTS 2 @@ -104,7 +106,7 @@ static struct uart_driver lqasc_reg; struct ltq_uart_port { struct uart_portport; /* clock used to derive divider */ - struct clk *fpiclk; + struct clk *freqclk; /* clock gating of the ASC core */ struct clk *clk; unsigned inttx_irq; @@ -120,7 +122,6 @@ static inline struct ltq_uart_port *to_ltq_uart_port(struct uart_port *port) static void lqasc_stop_tx(struct uart_port *port) { - return; } static void lqasc_start_tx(struct uart_port *port) @@ -291,8 +292,7 @@ static unsigned int lqasc_tx_empty(struct uart_port *port) return status ? 0 : TIOCSER_TEMT; } -static unsigned int -lqasc_get_mctrl(struct uart_port *port) +static unsigned int lqasc_get_mctrl(struct uart_port *port) { return TIOCM_CTS | TIOCM_CAR | TIOCM_DSR; } @@ -301,21 +301,65 @@ static void lqasc_set_mctrl(struct uart_port *port, u_int mctrl) { } -static void -lqasc_break_ctl(struct uart_port *port, int break_state) +static void lqasc_break_ctl(struct uart_port *port, int break_state) { } -static int -lqasc_startup(struct uart_port *port) +static void lqasc_fdv_and_reload_get(struct ltq_uart_port *ltq_port, +unsigned int baudrate, unsigned int *fdv, +unsigned int *reload) +{ + unsigned int asc_clk = clk_get_rate(ltq_port->freqclk); + unsigned int baudrate1 = baudrate * 8192; + unsigned long long baudrate2 = (unsigned long long)baudrate * 1000; + unsigned long long fdv_over_bg_fpi; + unsigned long long fdv_over_bg; + unsigned long long difference; + unsigned long long min_difference; + unsigned int bg; + + /* Sanity check first */ + if (baudrate >= (asc_clk >> 4)) { + pr_err("%s current fpi clock %u can't provide baudrate %u!!!\n", + __func__, asc_clk, baudrate); + return; + } + + min_difference = UINT_MAX; + fdv_over_bg_fpi = baudrate1; + + for (bg = 1; bg <= 8192; bg++, fdv_over_bg_fpi += baudrate1) { + fdv_over_bg = fdv_over_bg_fpi + asc_clk / 2; + do_div(fdv_over_bg, asc_clk); + if (fdv_over_bg <= 512) { + difference = fdv_over_bg * asc_clk * 1000; + do_div(difference, 8192 * bg); + if (difference < baudrate2) + difference =
[PATCH 1/7] MIPS: dts: Add aliases node for lantiq danube serial
Previous implementation uses a hard-coded register value to check if the current serial entity is the console entity. Now the lantiq serial driver uses the aliases for the index of the serial port. The lantiq danube serial dts are updated with aliases to support this. Signed-off-by: Songjun Wu --- arch/mips/boot/dts/lantiq/danube.dtsi | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/mips/boot/dts/lantiq/danube.dtsi b/arch/mips/boot/dts/lantiq/danube.dtsi index 2dd950181f8a..7a9e15da6bd0 100644 --- a/arch/mips/boot/dts/lantiq/danube.dtsi +++ b/arch/mips/boot/dts/lantiq/danube.dtsi @@ -4,6 +4,10 @@ #size-cells = <1>; compatible = "lantiq,xway", "lantiq,danube"; + aliases { + serial0 = + }; + cpus { cpu@0 { compatible = "mips,mips24Kc"; @@ -74,7 +78,7 @@ reg = <0xE100A00 0x100>; }; - serial@E100C00 { + asc1: serial@E100C00 { compatible = "lantiq,asc"; reg = <0xE100C00 0x400>; interrupt-parent = <>; -- 2.11.0
[PATCH 7/7] tty: serial: lantiq: Add CCF support
Previous implementation uses platform-dependent API to get the clock. Those functions are not available for other SoC which uses the same IP. The CCF (Common Clock Framework) have an abstraction based APIs for clock. Change to use CCF APIs to get clock and rate. So that different SoCs can use the same driver. Clocks and clock-names are updated in device tree binding. Signed-off-by: Songjun Wu --- .../devicetree/bindings/serial/lantiq_asc.txt | 15 +++ drivers/tty/serial/Kconfig | 2 +- drivers/tty/serial/lantiq.c| 101 + 3 files changed, 98 insertions(+), 20 deletions(-) diff --git a/Documentation/devicetree/bindings/serial/lantiq_asc.txt b/Documentation/devicetree/bindings/serial/lantiq_asc.txt index 3acbd309ab9d..608f0c87a4af 100644 --- a/Documentation/devicetree/bindings/serial/lantiq_asc.txt +++ b/Documentation/devicetree/bindings/serial/lantiq_asc.txt @@ -6,6 +6,10 @@ Required properties: - interrupts: the 3 (tx rx err) interrupt numbers. The interrupt specifier depends on the interrupt-parent interrupt controller. +Optional properties: +- clocks: Should contain frequency clock and gate clock +- clock-names: Should be "freq" and "asc" + Example: asc1: serial@e100c00 { @@ -14,3 +18,14 @@ asc1: serial@e100c00 { interrupt-parent = <>; interrupts = <112 113 114>; }; + +asc0: serial@60 { + compatible = "lantiq,asc"; + reg = <0x60 0x10>; + interrupt-parent = <>; + interrupts = , + , + ; + clocks = < SSX4_CLK>, < GATE_URT_CLK>; + clock-names = "freq", "asc"; +}; diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 0f058df0b070..0f8ac5872a54 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1062,7 +1062,7 @@ config SERIAL_OMAP_CONSOLE config SERIAL_LANTIQ bool "Lantiq serial driver" - depends on LANTIQ + depends on LANTIQ || INTEL_MIPS || COMPILE_TEST select SERIAL_CORE select SERIAL_CORE_CONSOLE select SERIAL_EARLYCON diff --git a/drivers/tty/serial/lantiq.c b/drivers/tty/serial/lantiq.c index cc33208c93ac..fd7ba89daaa2 100644 --- a/drivers/tty/serial/lantiq.c +++ b/drivers/tty/serial/lantiq.c @@ -24,7 +24,9 @@ #include #include +#ifndef CONFIG_COMMON_CLK #include +#endif #define PORT_LTQ_ASC 111 #define MAXPORTS 2 @@ -104,7 +106,7 @@ static struct uart_driver lqasc_reg; struct ltq_uart_port { struct uart_portport; /* clock used to derive divider */ - struct clk *fpiclk; + struct clk *freqclk; /* clock gating of the ASC core */ struct clk *clk; unsigned inttx_irq; @@ -120,7 +122,6 @@ static inline struct ltq_uart_port *to_ltq_uart_port(struct uart_port *port) static void lqasc_stop_tx(struct uart_port *port) { - return; } static void lqasc_start_tx(struct uart_port *port) @@ -291,8 +292,7 @@ static unsigned int lqasc_tx_empty(struct uart_port *port) return status ? 0 : TIOCSER_TEMT; } -static unsigned int -lqasc_get_mctrl(struct uart_port *port) +static unsigned int lqasc_get_mctrl(struct uart_port *port) { return TIOCM_CTS | TIOCM_CAR | TIOCM_DSR; } @@ -301,21 +301,65 @@ static void lqasc_set_mctrl(struct uart_port *port, u_int mctrl) { } -static void -lqasc_break_ctl(struct uart_port *port, int break_state) +static void lqasc_break_ctl(struct uart_port *port, int break_state) { } -static int -lqasc_startup(struct uart_port *port) +static void lqasc_fdv_and_reload_get(struct ltq_uart_port *ltq_port, +unsigned int baudrate, unsigned int *fdv, +unsigned int *reload) +{ + unsigned int asc_clk = clk_get_rate(ltq_port->freqclk); + unsigned int baudrate1 = baudrate * 8192; + unsigned long long baudrate2 = (unsigned long long)baudrate * 1000; + unsigned long long fdv_over_bg_fpi; + unsigned long long fdv_over_bg; + unsigned long long difference; + unsigned long long min_difference; + unsigned int bg; + + /* Sanity check first */ + if (baudrate >= (asc_clk >> 4)) { + pr_err("%s current fpi clock %u can't provide baudrate %u!!!\n", + __func__, asc_clk, baudrate); + return; + } + + min_difference = UINT_MAX; + fdv_over_bg_fpi = baudrate1; + + for (bg = 1; bg <= 8192; bg++, fdv_over_bg_fpi += baudrate1) { + fdv_over_bg = fdv_over_bg_fpi + asc_clk / 2; + do_div(fdv_over_bg, asc_clk); + if (fdv_over_bg <= 512) { + difference = fdv_over_bg * asc_clk * 1000; + do_div(difference, 8192 * bg); + if (difference < baudrate2) + difference =
[PATCH 2/7] clk: intel: Add clock driver for GRX500 SoC
From: Yixin Zhu PLL of GRX500 provide clock to DDR, CPU, and peripherals as show below +-+ |--->| LCPLL3 0|--PCIe clk--> XO |+-+ +---| |+-+ ||3|--PAE clk--> |--->| PLL0B 2|--GSWIP clk--> ||1|--DDR clk-->DDR PHY clk--> ||0|--CPU1 clk--+ +-+ |+-+|--->0| | | MUX |--CPU clk--> |+-+|--->1| ||0|--CPU0 clk--+ +-+ |--->| PLLOA 1|--SSX4 clk--> |2|--NGI clk--> |3|--CBM clk--> +-+ VCO of all PLLs of GRX500 is not supposed to be reprogrammed. DDR PHY clock is created to show correct clock rate in software point of view. CPU clock of 1Ghz from PLL0B otherwise from PLL0A. Signed-off-by: Yixin Zhu Signed-off-by: Songjun Wu --- .../devicetree/bindings/clock/intel,grx500-clk.txt | 46 ++ drivers/clk/Kconfig| 1 + drivers/clk/Makefile | 1 + drivers/clk/intel/Kconfig | 21 + drivers/clk/intel/Makefile | 7 + drivers/clk/intel/clk-cgu-api.c| 676 + drivers/clk/intel/clk-cgu-api.h| 120 drivers/clk/intel/clk-grx500.c | 236 +++ include/dt-bindings/clock/intel,grx500-clk.h | 61 ++ 9 files changed, 1169 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/intel,grx500-clk.txt create mode 100644 drivers/clk/intel/Kconfig create mode 100644 drivers/clk/intel/Makefile create mode 100644 drivers/clk/intel/clk-cgu-api.c create mode 100644 drivers/clk/intel/clk-cgu-api.h create mode 100644 drivers/clk/intel/clk-grx500.c create mode 100644 include/dt-bindings/clock/intel,grx500-clk.h diff --git a/Documentation/devicetree/bindings/clock/intel,grx500-clk.txt b/Documentation/devicetree/bindings/clock/intel,grx500-clk.txt new file mode 100644 index ..dd761d900dc9 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/intel,grx500-clk.txt @@ -0,0 +1,46 @@ +Device Tree Clock bindings for GRX500 PLL controller. + +This binding uses the common clock binding: + Documentation/devicetree/bindings/clock/clock-bindings.txt + +This GRX500 PLL controller provides the 5 main clock domain of the SoC: CPU/DDR, XBAR, +Voice, WLAN, PCIe and gate clocks for HW modules. + +Required properties for osc clock node +- compatible: Should be intel,grx500-xxx-clk +- reg: offset address of the controller memory area. +- clocks: phandle of the external reference clock +- #clock-cells: can be one or zero. +- clock-output-names: Names of the output clocks. + +Example: + pll0aclk: pll0aclk { + #clock-cells = <1>; + compatible = "intel,grx500-pll0a-clk"; + clocks = <>; + reg = <0x8>; + clock-output-names = "cbmclk", "ngiclk", "ssx4clk", "cpu0clk"; + }; + + cpuclk: cpuclk { + #clock-cells = <0>; + compatible = "intel,grx500-cpu-clk"; + clocks = < CPU0_CLK>, < CPU1_CLK>; + reg = <0x8>; + clock-output-names = "cpu"; + }; + +Required properties for gate node: +- compatible: Should be intel,grx500-gatex-clk +- reg: offset address of the controller memory area. +- #clock-cells: Should be <1> +- clock-output-names: Names of the output clocks. + +Example: + clkgate0: clkgate0 { + #clock-cells = <1>; + compatible = "intel,grx500-gate0-clk"; + reg = <0x114>; + clock-output-names = "gate_xbar0", "gate_xbar1", "gate_xbar2", + "gate_xbar3", "gate_xbar6", "gate_xbar7"; + }; diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 34968a381d0f..9e2e19a1170a 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -280,6 +280,7 @@ config COMMON_CLK_STM32H7 source "drivers/clk/bcm/Kconfig" source "drivers/clk/hisilicon/Kconfig" source "drivers/clk/imgtec/Kconfig" +source "drivers/clk/intel/Kconfig" source "drivers/clk/keystone/Kconfig" source "drivers/clk/mediatek/Kconfig" source "drivers/clk/meson/Kconfig" diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index de6d06ac790b..ef3e270005a1 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -105,3 +105,4 @@ obj-$(CONFIG_X86) += x86/ endif obj-$(CONFIG_ARCH_ZX) += zte/ obj-$(CONFIG_ARCH_ZYNQ)+= zynq/ +obj-$(CONFIG_COMMON_CLK_INTEL) += intel/ diff --git a/drivers/clk/intel/Kconfig b/drivers/clk/intel/Kconfig new file mode 100644 index ..d40a92ae7462 --- /dev/null +++ b/drivers/clk/intel/Kconfig @@
[PATCH 2/7] clk: intel: Add clock driver for GRX500 SoC
From: Yixin Zhu PLL of GRX500 provide clock to DDR, CPU, and peripherals as show below +-+ |--->| LCPLL3 0|--PCIe clk--> XO |+-+ +---| |+-+ ||3|--PAE clk--> |--->| PLL0B 2|--GSWIP clk--> ||1|--DDR clk-->DDR PHY clk--> ||0|--CPU1 clk--+ +-+ |+-+|--->0| | | MUX |--CPU clk--> |+-+|--->1| ||0|--CPU0 clk--+ +-+ |--->| PLLOA 1|--SSX4 clk--> |2|--NGI clk--> |3|--CBM clk--> +-+ VCO of all PLLs of GRX500 is not supposed to be reprogrammed. DDR PHY clock is created to show correct clock rate in software point of view. CPU clock of 1Ghz from PLL0B otherwise from PLL0A. Signed-off-by: Yixin Zhu Signed-off-by: Songjun Wu --- .../devicetree/bindings/clock/intel,grx500-clk.txt | 46 ++ drivers/clk/Kconfig| 1 + drivers/clk/Makefile | 1 + drivers/clk/intel/Kconfig | 21 + drivers/clk/intel/Makefile | 7 + drivers/clk/intel/clk-cgu-api.c| 676 + drivers/clk/intel/clk-cgu-api.h| 120 drivers/clk/intel/clk-grx500.c | 236 +++ include/dt-bindings/clock/intel,grx500-clk.h | 61 ++ 9 files changed, 1169 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/intel,grx500-clk.txt create mode 100644 drivers/clk/intel/Kconfig create mode 100644 drivers/clk/intel/Makefile create mode 100644 drivers/clk/intel/clk-cgu-api.c create mode 100644 drivers/clk/intel/clk-cgu-api.h create mode 100644 drivers/clk/intel/clk-grx500.c create mode 100644 include/dt-bindings/clock/intel,grx500-clk.h diff --git a/Documentation/devicetree/bindings/clock/intel,grx500-clk.txt b/Documentation/devicetree/bindings/clock/intel,grx500-clk.txt new file mode 100644 index ..dd761d900dc9 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/intel,grx500-clk.txt @@ -0,0 +1,46 @@ +Device Tree Clock bindings for GRX500 PLL controller. + +This binding uses the common clock binding: + Documentation/devicetree/bindings/clock/clock-bindings.txt + +This GRX500 PLL controller provides the 5 main clock domain of the SoC: CPU/DDR, XBAR, +Voice, WLAN, PCIe and gate clocks for HW modules. + +Required properties for osc clock node +- compatible: Should be intel,grx500-xxx-clk +- reg: offset address of the controller memory area. +- clocks: phandle of the external reference clock +- #clock-cells: can be one or zero. +- clock-output-names: Names of the output clocks. + +Example: + pll0aclk: pll0aclk { + #clock-cells = <1>; + compatible = "intel,grx500-pll0a-clk"; + clocks = <>; + reg = <0x8>; + clock-output-names = "cbmclk", "ngiclk", "ssx4clk", "cpu0clk"; + }; + + cpuclk: cpuclk { + #clock-cells = <0>; + compatible = "intel,grx500-cpu-clk"; + clocks = < CPU0_CLK>, < CPU1_CLK>; + reg = <0x8>; + clock-output-names = "cpu"; + }; + +Required properties for gate node: +- compatible: Should be intel,grx500-gatex-clk +- reg: offset address of the controller memory area. +- #clock-cells: Should be <1> +- clock-output-names: Names of the output clocks. + +Example: + clkgate0: clkgate0 { + #clock-cells = <1>; + compatible = "intel,grx500-gate0-clk"; + reg = <0x114>; + clock-output-names = "gate_xbar0", "gate_xbar1", "gate_xbar2", + "gate_xbar3", "gate_xbar6", "gate_xbar7"; + }; diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 34968a381d0f..9e2e19a1170a 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -280,6 +280,7 @@ config COMMON_CLK_STM32H7 source "drivers/clk/bcm/Kconfig" source "drivers/clk/hisilicon/Kconfig" source "drivers/clk/imgtec/Kconfig" +source "drivers/clk/intel/Kconfig" source "drivers/clk/keystone/Kconfig" source "drivers/clk/mediatek/Kconfig" source "drivers/clk/meson/Kconfig" diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index de6d06ac790b..ef3e270005a1 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -105,3 +105,4 @@ obj-$(CONFIG_X86) += x86/ endif obj-$(CONFIG_ARCH_ZX) += zte/ obj-$(CONFIG_ARCH_ZYNQ)+= zynq/ +obj-$(CONFIG_COMMON_CLK_INTEL) += intel/ diff --git a/drivers/clk/intel/Kconfig b/drivers/clk/intel/Kconfig new file mode 100644 index ..d40a92ae7462 --- /dev/null +++ b/drivers/clk/intel/Kconfig @@
[PATCH 0/7] MIPS: intel: add initial support for Intel MIPS SoCs
This patch series is for adding the support for Intel MIPS interAptiv SoC GRX500 family. It includes CCF support, serial driver optimization and DTS modification. This patch series is applied on top of v4.17.1. Basic verification is performed on GRX500 board. Any comments on this would be appreciated. We propose merging this patch series into MIPS Linux tree. Hua Ma (1): MIPS: intel: Add initial support for Intel MIPS SoCs Songjun Wu (5): MIPS: dts: Add aliases node for lantiq danube serial tty: serial: lantiq: Always use readl()/writel() tty: serial: lantiq: Convert global lock to per device lock tty: serial: lantiq: Remove unneeded header includes and macros tty: serial: lantiq: Add CCF support Yixin Zhu (1): clk: intel: Add clock driver for GRX500 SoC .../devicetree/bindings/clock/intel,grx500-clk.txt | 46 ++ .../devicetree/bindings/serial/lantiq_asc.txt | 15 + arch/mips/Kbuild.platforms | 1 + arch/mips/Kconfig | 37 +- arch/mips/boot/dts/Makefile| 1 + arch/mips/boot/dts/intel-mips/Makefile | 3 + arch/mips/boot/dts/intel-mips/easy350_anywan.dts | 20 + arch/mips/boot/dts/intel-mips/xrx500.dtsi | 196 ++ arch/mips/boot/dts/lantiq/danube.dtsi | 6 +- arch/mips/configs/grx500_defconfig | 165 + .../asm/mach-intel-mips/cpu-feature-overrides.h| 61 ++ arch/mips/include/asm/mach-intel-mips/ioremap.h| 39 ++ arch/mips/include/asm/mach-intel-mips/irq.h| 17 + .../asm/mach-intel-mips/kernel-entry-init.h| 76 +++ arch/mips/include/asm/mach-intel-mips/spaces.h | 29 + arch/mips/include/asm/mach-intel-mips/war.h| 18 + arch/mips/intel-mips/Kconfig | 22 + arch/mips/intel-mips/Makefile | 3 + arch/mips/intel-mips/Platform | 11 + arch/mips/intel-mips/irq.c | 36 ++ arch/mips/intel-mips/prom.c| 184 ++ arch/mips/intel-mips/time.c| 56 ++ drivers/clk/Kconfig| 1 + drivers/clk/Makefile | 1 + drivers/clk/intel/Kconfig | 21 + drivers/clk/intel/Makefile | 7 + drivers/clk/intel/clk-cgu-api.c| 676 + drivers/clk/intel/clk-cgu-api.h| 120 drivers/clk/intel/clk-grx500.c | 236 +++ drivers/tty/serial/Kconfig | 2 +- drivers/tty/serial/lantiq.c| 415 - include/dt-bindings/clock/intel,grx500-clk.h | 61 ++ 32 files changed, 2418 insertions(+), 164 deletions(-) create mode 100644 Documentation/devicetree/bindings/clock/intel,grx500-clk.txt create mode 100644 arch/mips/boot/dts/intel-mips/Makefile create mode 100644 arch/mips/boot/dts/intel-mips/easy350_anywan.dts create mode 100644 arch/mips/boot/dts/intel-mips/xrx500.dtsi create mode 100644 arch/mips/configs/grx500_defconfig create mode 100644 arch/mips/include/asm/mach-intel-mips/cpu-feature-overrides.h create mode 100644 arch/mips/include/asm/mach-intel-mips/ioremap.h create mode 100644 arch/mips/include/asm/mach-intel-mips/irq.h create mode 100644 arch/mips/include/asm/mach-intel-mips/kernel-entry-init.h create mode 100644 arch/mips/include/asm/mach-intel-mips/spaces.h create mode 100644 arch/mips/include/asm/mach-intel-mips/war.h create mode 100644 arch/mips/intel-mips/Kconfig create mode 100644 arch/mips/intel-mips/Makefile create mode 100644 arch/mips/intel-mips/Platform create mode 100644 arch/mips/intel-mips/irq.c create mode 100644 arch/mips/intel-mips/prom.c create mode 100644 arch/mips/intel-mips/time.c create mode 100644 drivers/clk/intel/Kconfig create mode 100644 drivers/clk/intel/Makefile create mode 100644 drivers/clk/intel/clk-cgu-api.c create mode 100644 drivers/clk/intel/clk-cgu-api.h create mode 100644 drivers/clk/intel/clk-grx500.c create mode 100644 include/dt-bindings/clock/intel,grx500-clk.h -- 2.11.0
[PATCH 0/7] MIPS: intel: add initial support for Intel MIPS SoCs
This patch series is for adding the support for Intel MIPS interAptiv SoC GRX500 family. It includes CCF support, serial driver optimization and DTS modification. This patch series is applied on top of v4.17.1. Basic verification is performed on GRX500 board. Any comments on this would be appreciated. We propose merging this patch series into MIPS Linux tree. Hua Ma (1): MIPS: intel: Add initial support for Intel MIPS SoCs Songjun Wu (5): MIPS: dts: Add aliases node for lantiq danube serial tty: serial: lantiq: Always use readl()/writel() tty: serial: lantiq: Convert global lock to per device lock tty: serial: lantiq: Remove unneeded header includes and macros tty: serial: lantiq: Add CCF support Yixin Zhu (1): clk: intel: Add clock driver for GRX500 SoC .../devicetree/bindings/clock/intel,grx500-clk.txt | 46 ++ .../devicetree/bindings/serial/lantiq_asc.txt | 15 + arch/mips/Kbuild.platforms | 1 + arch/mips/Kconfig | 37 +- arch/mips/boot/dts/Makefile| 1 + arch/mips/boot/dts/intel-mips/Makefile | 3 + arch/mips/boot/dts/intel-mips/easy350_anywan.dts | 20 + arch/mips/boot/dts/intel-mips/xrx500.dtsi | 196 ++ arch/mips/boot/dts/lantiq/danube.dtsi | 6 +- arch/mips/configs/grx500_defconfig | 165 + .../asm/mach-intel-mips/cpu-feature-overrides.h| 61 ++ arch/mips/include/asm/mach-intel-mips/ioremap.h| 39 ++ arch/mips/include/asm/mach-intel-mips/irq.h| 17 + .../asm/mach-intel-mips/kernel-entry-init.h| 76 +++ arch/mips/include/asm/mach-intel-mips/spaces.h | 29 + arch/mips/include/asm/mach-intel-mips/war.h| 18 + arch/mips/intel-mips/Kconfig | 22 + arch/mips/intel-mips/Makefile | 3 + arch/mips/intel-mips/Platform | 11 + arch/mips/intel-mips/irq.c | 36 ++ arch/mips/intel-mips/prom.c| 184 ++ arch/mips/intel-mips/time.c| 56 ++ drivers/clk/Kconfig| 1 + drivers/clk/Makefile | 1 + drivers/clk/intel/Kconfig | 21 + drivers/clk/intel/Makefile | 7 + drivers/clk/intel/clk-cgu-api.c| 676 + drivers/clk/intel/clk-cgu-api.h| 120 drivers/clk/intel/clk-grx500.c | 236 +++ drivers/tty/serial/Kconfig | 2 +- drivers/tty/serial/lantiq.c| 415 - include/dt-bindings/clock/intel,grx500-clk.h | 61 ++ 32 files changed, 2418 insertions(+), 164 deletions(-) create mode 100644 Documentation/devicetree/bindings/clock/intel,grx500-clk.txt create mode 100644 arch/mips/boot/dts/intel-mips/Makefile create mode 100644 arch/mips/boot/dts/intel-mips/easy350_anywan.dts create mode 100644 arch/mips/boot/dts/intel-mips/xrx500.dtsi create mode 100644 arch/mips/configs/grx500_defconfig create mode 100644 arch/mips/include/asm/mach-intel-mips/cpu-feature-overrides.h create mode 100644 arch/mips/include/asm/mach-intel-mips/ioremap.h create mode 100644 arch/mips/include/asm/mach-intel-mips/irq.h create mode 100644 arch/mips/include/asm/mach-intel-mips/kernel-entry-init.h create mode 100644 arch/mips/include/asm/mach-intel-mips/spaces.h create mode 100644 arch/mips/include/asm/mach-intel-mips/war.h create mode 100644 arch/mips/intel-mips/Kconfig create mode 100644 arch/mips/intel-mips/Makefile create mode 100644 arch/mips/intel-mips/Platform create mode 100644 arch/mips/intel-mips/irq.c create mode 100644 arch/mips/intel-mips/prom.c create mode 100644 arch/mips/intel-mips/time.c create mode 100644 drivers/clk/intel/Kconfig create mode 100644 drivers/clk/intel/Makefile create mode 100644 drivers/clk/intel/clk-cgu-api.c create mode 100644 drivers/clk/intel/clk-cgu-api.h create mode 100644 drivers/clk/intel/clk-grx500.c create mode 100644 include/dt-bindings/clock/intel,grx500-clk.h -- 2.11.0
Re: [PATCH v3 5/7] dt-bindings: power: Add qcom rpmh power domain driver bindings
On Mon 11 Jun 21:40 PDT 2018, Rajendra Nayak wrote: > Add DT bindings to describe the rpmh powerdomains found on Qualcomm > Technologies, Inc. SoCs. These power domains communicate a performance > state to RPMh, which then translates it into corresponding voltage on > a PMIC rail. > > Signed-off-by: Rajendra Nayak > --- > .../devicetree/bindings/power/qcom,rpmhpd.txt | 65 +++ > 1 file changed, 65 insertions(+) > create mode 100644 Documentation/devicetree/bindings/power/qcom,rpmhpd.txt > > diff --git a/Documentation/devicetree/bindings/power/qcom,rpmhpd.txt > b/Documentation/devicetree/bindings/power/qcom,rpmhpd.txt > new file mode 100644 > index ..41ef7afa6b24 > --- /dev/null > +++ b/Documentation/devicetree/bindings/power/qcom,rpmhpd.txt > @@ -0,0 +1,65 @@ > +Qualcomm RPMh Power domains > + > +For RPMh Power domains, we communicate a performance state to RPMh > +which then translates it into a corresponding voltage on a rail > + > +Required Properties: > + - compatible: Should be one of the following > + * qcom,sdm845-rpmhpd: RPMh Power domain for the sdm845 family of SoC Afaict this binding is identical to the one introduced in patch 1, so I would suggest that you just add the compatible there. Regards, Bjorn > + - power-domain-cells: number of cells in power domain specifier > + must be 1 > + - operating-points-v2: Phandle to the OPP table for the power-domain. > + Refer to Documentation/devicetree/bindings/power/power_domain.txt > + and Documentation/devicetree/bindings/opp/qcom-opp.txt for more details > + > +Example: > + > + rpmhpd: power-controller { > + compatible = "qcom,sdm845-rpmhpd"; > + #power-domain-cells = <1>; > + operating-points-v2 = <_opp_table>; > + }; > + > + rpmhpd_opp_table: opp-table { > + compatible = "operating-points-v2-qcom-level"; > + > + rpmhpd_opp_ret: opp1 { > + qcom-level = <16>; > + }; > + > + rpmhpd_opp_min_svs: opp2 { > + qcom-level = <48>; > + }; > + > + rpmhpd_opp_low_svs: opp3 { > + qcom-level = <64>; > + }; > + > + rpmhpd_opp_svs: opp4 { > + qcom-level = <128>; > + }; > + > + rpmhpd_opp_svs_l1: opp5 { > + qcom-level = <192>; > + }; > + > + rpmhpd_opp_nom: opp6 { > + qcom-level = <256>; > + }; > + > + rpmhpd_opp_nom_l1: opp7 { > + qcom-level = <320>; > + }; > + > + rpmhpd_opp_nom_l2: opp8 { > + qcom-level = <336>; > + }; > + > + rpmhpd_opp_turbo: opp9 { > + qcom-level = <384>; > + }; > + > + rpmhpd_opp_turbo_l1: opp10 { > + qcom-level = <416>; > + }; > + }; > -- > QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member > of Code Aurora Forum, hosted by The Linux Foundation >
Re: [PATCH v3 5/7] dt-bindings: power: Add qcom rpmh power domain driver bindings
On Mon 11 Jun 21:40 PDT 2018, Rajendra Nayak wrote: > Add DT bindings to describe the rpmh powerdomains found on Qualcomm > Technologies, Inc. SoCs. These power domains communicate a performance > state to RPMh, which then translates it into corresponding voltage on > a PMIC rail. > > Signed-off-by: Rajendra Nayak > --- > .../devicetree/bindings/power/qcom,rpmhpd.txt | 65 +++ > 1 file changed, 65 insertions(+) > create mode 100644 Documentation/devicetree/bindings/power/qcom,rpmhpd.txt > > diff --git a/Documentation/devicetree/bindings/power/qcom,rpmhpd.txt > b/Documentation/devicetree/bindings/power/qcom,rpmhpd.txt > new file mode 100644 > index ..41ef7afa6b24 > --- /dev/null > +++ b/Documentation/devicetree/bindings/power/qcom,rpmhpd.txt > @@ -0,0 +1,65 @@ > +Qualcomm RPMh Power domains > + > +For RPMh Power domains, we communicate a performance state to RPMh > +which then translates it into a corresponding voltage on a rail > + > +Required Properties: > + - compatible: Should be one of the following > + * qcom,sdm845-rpmhpd: RPMh Power domain for the sdm845 family of SoC Afaict this binding is identical to the one introduced in patch 1, so I would suggest that you just add the compatible there. Regards, Bjorn > + - power-domain-cells: number of cells in power domain specifier > + must be 1 > + - operating-points-v2: Phandle to the OPP table for the power-domain. > + Refer to Documentation/devicetree/bindings/power/power_domain.txt > + and Documentation/devicetree/bindings/opp/qcom-opp.txt for more details > + > +Example: > + > + rpmhpd: power-controller { > + compatible = "qcom,sdm845-rpmhpd"; > + #power-domain-cells = <1>; > + operating-points-v2 = <_opp_table>; > + }; > + > + rpmhpd_opp_table: opp-table { > + compatible = "operating-points-v2-qcom-level"; > + > + rpmhpd_opp_ret: opp1 { > + qcom-level = <16>; > + }; > + > + rpmhpd_opp_min_svs: opp2 { > + qcom-level = <48>; > + }; > + > + rpmhpd_opp_low_svs: opp3 { > + qcom-level = <64>; > + }; > + > + rpmhpd_opp_svs: opp4 { > + qcom-level = <128>; > + }; > + > + rpmhpd_opp_svs_l1: opp5 { > + qcom-level = <192>; > + }; > + > + rpmhpd_opp_nom: opp6 { > + qcom-level = <256>; > + }; > + > + rpmhpd_opp_nom_l1: opp7 { > + qcom-level = <320>; > + }; > + > + rpmhpd_opp_nom_l2: opp8 { > + qcom-level = <336>; > + }; > + > + rpmhpd_opp_turbo: opp9 { > + qcom-level = <384>; > + }; > + > + rpmhpd_opp_turbo_l1: opp10 { > + qcom-level = <416>; > + }; > + }; > -- > QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member > of Code Aurora Forum, hosted by The Linux Foundation >
Re: [PATCH] fanotify: add error handling for kmem_cache_create
On Tue, Jun 12, 2018 at 7:19 AM, Zhouyang Jia wrote: > When kmem_cache_create fails, the lack of error-handling code may > cause unexpected results. > > This patch adds error-handling code after calling kmem_cache_create. > > Signed-off-by: Zhouyang Jia > --- > fs/notify/fanotify/fanotify_user.c | 5 + > 1 file changed, 5 insertions(+) > > diff --git a/fs/notify/fanotify/fanotify_user.c > b/fs/notify/fanotify/fanotify_user.c > index ec4d8c5..e3fa861 100644 > --- a/fs/notify/fanotify/fanotify_user.c > +++ b/fs/notify/fanotify/fanotify_user.c > @@ -959,9 +959,14 @@ static int __init fanotify_user_setup(void) > { > fanotify_mark_cache = KMEM_CACHE(fsnotify_mark, SLAB_PANIC); > fanotify_event_cachep = KMEM_CACHE(fanotify_event_info, SLAB_PANIC); > + if (!fanotify_mark_cache || !fanotify_event_cachep) > + return -ENOMEM; If only one failed need to free the other. > + > if (IS_ENABLED(CONFIG_FANOTIFY_ACCESS_PERMISSIONS)) { > fanotify_perm_event_cachep = > KMEM_CACHE(fanotify_perm_event_info, SLAB_PANIC); > + if (!fanotify_perm_event_cachep) > + return -ENOMEM; here as well. best implement as goto fail > } > > return 0; fail: if (fanotify_mark_cache) kmem_cache_destroy(fanotify_mark_cache); ... return -ENOMEM; Thanks, Amir.
Re: [PATCH] fanotify: add error handling for kmem_cache_create
On Tue, Jun 12, 2018 at 7:19 AM, Zhouyang Jia wrote: > When kmem_cache_create fails, the lack of error-handling code may > cause unexpected results. > > This patch adds error-handling code after calling kmem_cache_create. > > Signed-off-by: Zhouyang Jia > --- > fs/notify/fanotify/fanotify_user.c | 5 + > 1 file changed, 5 insertions(+) > > diff --git a/fs/notify/fanotify/fanotify_user.c > b/fs/notify/fanotify/fanotify_user.c > index ec4d8c5..e3fa861 100644 > --- a/fs/notify/fanotify/fanotify_user.c > +++ b/fs/notify/fanotify/fanotify_user.c > @@ -959,9 +959,14 @@ static int __init fanotify_user_setup(void) > { > fanotify_mark_cache = KMEM_CACHE(fsnotify_mark, SLAB_PANIC); > fanotify_event_cachep = KMEM_CACHE(fanotify_event_info, SLAB_PANIC); > + if (!fanotify_mark_cache || !fanotify_event_cachep) > + return -ENOMEM; If only one failed need to free the other. > + > if (IS_ENABLED(CONFIG_FANOTIFY_ACCESS_PERMISSIONS)) { > fanotify_perm_event_cachep = > KMEM_CACHE(fanotify_perm_event_info, SLAB_PANIC); > + if (!fanotify_perm_event_cachep) > + return -ENOMEM; here as well. best implement as goto fail > } > > return 0; fail: if (fanotify_mark_cache) kmem_cache_destroy(fanotify_mark_cache); ... return -ENOMEM; Thanks, Amir.
RE: [PATCH] Input: add error handling for da9052_reg_write
On 11 June 2018 18:30 wrote Dmitry Torokhov > Subject: Re: [PATCH] Input: add error handling for da9052_reg_write > > Hi Zhouyang, > > On Mon, Jun 11, 2018 at 01:23:39PM +0800, Zhouyang Jia wrote: > > When da9052_reg_write fails, the lack of error-handling code may > > cause unexpected results. > > > > This patch adds error-handling code after calling da9052_reg_write. > > > > Signed-off-by: Zhouyang Jia > > --- > > drivers/input/touchscreen/da9052_tsi.c | 5 - > > 1 file changed, 4 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/input/touchscreen/da9052_tsi.c > b/drivers/input/touchscreen/da9052_tsi.c > > index b5dfd594..60c82a0 100644 > > --- a/drivers/input/touchscreen/da9052_tsi.c > > +++ b/drivers/input/touchscreen/da9052_tsi.c > > @@ -319,8 +319,11 @@ static int da9052_ts_probe(struct platform_device > > *pdev) > > static int da9052_ts_remove(struct platform_device *pdev) > > { > > struct da9052_tsi *tsi = platform_get_drvdata(pdev); > > + int error; > > > > - da9052_reg_write(tsi->da9052, DA9052_LDO9_REG, 0x19); > > + error = da9052_reg_write(tsi->da9052, DA9052_LDO9_REG, 0x19); > > + if (error < 0) > > + return error; > > No, this does not help anything. The remove() action must not fail > (really, having it return an int and not void was an API mistake made > long time ago), and thus returning early in and event of error failing > to communicate with the device is a mistake. You really want to release > the interrupts and memory and unregister input device before returning. > > > > > da9052_free_irq(tsi->da9052, DA9052_IRQ_TSIREADY, tsi); > > da9052_free_irq(tsi->da9052, DA9052_IRQ_PENDOWN, tsi); > > -- > > 2.7.4 > > script? https://patchwork.kernel.org/project/LKML/list/?submitter=181001
RE: [PATCH] Input: add error handling for da9052_reg_write
On 11 June 2018 18:30 wrote Dmitry Torokhov > Subject: Re: [PATCH] Input: add error handling for da9052_reg_write > > Hi Zhouyang, > > On Mon, Jun 11, 2018 at 01:23:39PM +0800, Zhouyang Jia wrote: > > When da9052_reg_write fails, the lack of error-handling code may > > cause unexpected results. > > > > This patch adds error-handling code after calling da9052_reg_write. > > > > Signed-off-by: Zhouyang Jia > > --- > > drivers/input/touchscreen/da9052_tsi.c | 5 - > > 1 file changed, 4 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/input/touchscreen/da9052_tsi.c > b/drivers/input/touchscreen/da9052_tsi.c > > index b5dfd594..60c82a0 100644 > > --- a/drivers/input/touchscreen/da9052_tsi.c > > +++ b/drivers/input/touchscreen/da9052_tsi.c > > @@ -319,8 +319,11 @@ static int da9052_ts_probe(struct platform_device > > *pdev) > > static int da9052_ts_remove(struct platform_device *pdev) > > { > > struct da9052_tsi *tsi = platform_get_drvdata(pdev); > > + int error; > > > > - da9052_reg_write(tsi->da9052, DA9052_LDO9_REG, 0x19); > > + error = da9052_reg_write(tsi->da9052, DA9052_LDO9_REG, 0x19); > > + if (error < 0) > > + return error; > > No, this does not help anything. The remove() action must not fail > (really, having it return an int and not void was an API mistake made > long time ago), and thus returning early in and event of error failing > to communicate with the device is a mistake. You really want to release > the interrupts and memory and unregister input device before returning. > > > > > da9052_free_irq(tsi->da9052, DA9052_IRQ_TSIREADY, tsi); > > da9052_free_irq(tsi->da9052, DA9052_IRQ_PENDOWN, tsi); > > -- > > 2.7.4 > > script? https://patchwork.kernel.org/project/LKML/list/?submitter=181001
Re: [PATCH] fsnotify: add error handling for kmem_cache_create
On Tue, Jun 12, 2018 at 7:16 AM, Zhouyang Jia wrote: > When kmem_cache_create fails, the lack of error-handling code may > cause unexpected results. > > This patch adds error-handling code after calling kmem_cache_create. > > Signed-off-by: Zhouyang Jia > --- > fs/notify/dnotify/dnotify.c | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c > index 63a1ca4..216b411 100644 > --- a/fs/notify/dnotify/dnotify.c > +++ b/fs/notify/dnotify/dnotify.c > @@ -387,6 +387,9 @@ static int __init dnotify_init(void) > dnotify_struct_cache = KMEM_CACHE(dnotify_struct, SLAB_PANIC); > dnotify_mark_cache = KMEM_CACHE(dnotify_mark, SLAB_PANIC); > > + if (!dnotify_struct_cache || !dnotify_mark_cache) > + return -ENOMEM; > + If only one failed need to free the other. > dnotify_group = fsnotify_alloc_group(_fsnotify_ops); > if (IS_ERR(dnotify_group)) > panic("unable to allocate fsnotify group for dnotify\n"); > -- > 2.7.4 >
Re: [PATCH] fsnotify: add error handling for kmem_cache_create
On Tue, Jun 12, 2018 at 7:16 AM, Zhouyang Jia wrote: > When kmem_cache_create fails, the lack of error-handling code may > cause unexpected results. > > This patch adds error-handling code after calling kmem_cache_create. > > Signed-off-by: Zhouyang Jia > --- > fs/notify/dnotify/dnotify.c | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c > index 63a1ca4..216b411 100644 > --- a/fs/notify/dnotify/dnotify.c > +++ b/fs/notify/dnotify/dnotify.c > @@ -387,6 +387,9 @@ static int __init dnotify_init(void) > dnotify_struct_cache = KMEM_CACHE(dnotify_struct, SLAB_PANIC); > dnotify_mark_cache = KMEM_CACHE(dnotify_mark, SLAB_PANIC); > > + if (!dnotify_struct_cache || !dnotify_mark_cache) > + return -ENOMEM; > + If only one failed need to free the other. > dnotify_group = fsnotify_alloc_group(_fsnotify_ops); > if (IS_ERR(dnotify_group)) > panic("unable to allocate fsnotify group for dnotify\n"); > -- > 2.7.4 >
[PATCH v2 2/2] gpio: davinci: Do not assume continuous IRQ numbering
Currently the driver assumes that the interrupts are continuous and does platform_get_irq only once and assumes the rest are continuous, instead call platform_get_irq for all the interrupts and store them in an array for later use. Signed-off-by: Keerthy --- Tested for GPIO Interrupts on da850-lcdk and keystone-k2g-evm boards. Changes in v2: * Extended the logic of using saved IRQs to unbanked IRQs as per Grygorii's suggestion. drivers/gpio/gpio-davinci.c| 53 +++--- include/linux/platform_data/gpio-davinci.h | 3 +- 2 files changed, 36 insertions(+), 20 deletions(-) diff --git a/drivers/gpio/gpio-davinci.c b/drivers/gpio/gpio-davinci.c index 861f35b..b2119c0 100644 --- a/drivers/gpio/gpio-davinci.c +++ b/drivers/gpio/gpio-davinci.c @@ -55,7 +55,7 @@ static inline struct davinci_gpio_regs __iomem *irq2regs(struct irq_data *d) return g; } -static int davinci_gpio_irq_setup(struct platform_device *pdev, int bank_irq); +static int davinci_gpio_irq_setup(struct platform_device *pdev); /*--*/ @@ -168,7 +168,8 @@ static int davinci_gpio_probe(struct platform_device *pdev) { static int ctrl_num, bank_base; int gpio, bank, ret = 0; - unsigned ngpio, nbank, bank_irq; + unsigned int ngpio, nbank, nirq; + int i; struct davinci_gpio_controller *chips; struct davinci_gpio_platform_data *pdata; struct device *dev = >dev; @@ -197,6 +198,16 @@ static int davinci_gpio_probe(struct platform_device *pdev) if (WARN_ON(ARCH_NR_GPIOS < ngpio)) ngpio = ARCH_NR_GPIOS; + /* +* If there are unbanked interrupts then the number of +* interrupts is equal to number of gpios else all are banked so +* number of interrupts is equal to number of banks(each with 16 gpios) +*/ + if (pdata->gpio_unbanked) + nirq = pdata->gpio_unbanked; + else + nirq = DIV_ROUND_UP(ngpio, 16); + nbank = DIV_ROUND_UP(ngpio, 32); chips = devm_kzalloc(dev, nbank * sizeof(struct davinci_gpio_controller), @@ -209,10 +220,13 @@ static int davinci_gpio_probe(struct platform_device *pdev) if (IS_ERR(gpio_base)) return PTR_ERR(gpio_base); - bank_irq = platform_get_irq(pdev, 0); - if (bank_irq < 0) { - dev_dbg(dev, "IRQ not populated\n"); - return bank_irq; + for (i = 0; i < nirq; i++) { + chips->irqs[i] = platform_get_irq(pdev, i); + if (chips->irqs[i] < 0) { + dev_info(dev, "IRQ not populated, err = %d\n", +chips->irqs[i]); + return chips->irqs[i]; + } } snprintf(label, MAX_LABEL_SIZE, "davinci_gpio.%d", ctrl_num++); @@ -249,7 +263,7 @@ static int davinci_gpio_probe(struct platform_device *pdev) goto err; platform_set_drvdata(pdev, chips); - ret = davinci_gpio_irq_setup(pdev, bank_irq); + ret = davinci_gpio_irq_setup(pdev); if (ret) goto err; @@ -383,7 +397,7 @@ static int gpio_to_irq_unbanked(struct gpio_chip *chip, unsigned offset) * can provide direct-mapped IRQs to AINTC (up to 32 GPIOs). */ if (offset < d->gpio_unbanked) - return d->base_irq + offset; + return d->irqs[offset]; else return -ENODEV; } @@ -396,7 +410,7 @@ static int gpio_irq_type_unbanked(struct irq_data *data, unsigned trigger) d = (struct davinci_gpio_controller *)irq_data_get_irq_handler_data(data); g = (struct davinci_gpio_regs __iomem *)d->regs[0]; - mask = __gpio_mask(data->irq - d->base_irq); + mask = __gpio_mask(data->irq - d->irqs[0]); if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) return -EINVAL; @@ -458,7 +472,7 @@ static struct irq_chip *keystone_gpio_get_irq_chip(unsigned int irq) * (dm6446) can be set appropriately for GPIOV33 pins. */ -static int davinci_gpio_irq_setup(struct platform_device *pdev, int bank_irq) +static int davinci_gpio_irq_setup(struct platform_device *pdev) { unsignedgpio, bank; int irq; @@ -492,6 +506,7 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev, int bank_irq) dev_err(dev, "Error %ld getting gpio clock\n", PTR_ERR(clk)); return PTR_ERR(clk); } + ret = clk_prepare_enable(clk); if (ret) return ret; @@ -531,12 +546,11 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev, int bank_irq) if (pdata->gpio_unbanked) { /* pass "bank 0" GPIO IRQs to AINTC */ chips->chip.to_irq = gpio_to_irq_unbanked; -
[PATCH v2 2/2] gpio: davinci: Do not assume continuous IRQ numbering
Currently the driver assumes that the interrupts are continuous and does platform_get_irq only once and assumes the rest are continuous, instead call platform_get_irq for all the interrupts and store them in an array for later use. Signed-off-by: Keerthy --- Tested for GPIO Interrupts on da850-lcdk and keystone-k2g-evm boards. Changes in v2: * Extended the logic of using saved IRQs to unbanked IRQs as per Grygorii's suggestion. drivers/gpio/gpio-davinci.c| 53 +++--- include/linux/platform_data/gpio-davinci.h | 3 +- 2 files changed, 36 insertions(+), 20 deletions(-) diff --git a/drivers/gpio/gpio-davinci.c b/drivers/gpio/gpio-davinci.c index 861f35b..b2119c0 100644 --- a/drivers/gpio/gpio-davinci.c +++ b/drivers/gpio/gpio-davinci.c @@ -55,7 +55,7 @@ static inline struct davinci_gpio_regs __iomem *irq2regs(struct irq_data *d) return g; } -static int davinci_gpio_irq_setup(struct platform_device *pdev, int bank_irq); +static int davinci_gpio_irq_setup(struct platform_device *pdev); /*--*/ @@ -168,7 +168,8 @@ static int davinci_gpio_probe(struct platform_device *pdev) { static int ctrl_num, bank_base; int gpio, bank, ret = 0; - unsigned ngpio, nbank, bank_irq; + unsigned int ngpio, nbank, nirq; + int i; struct davinci_gpio_controller *chips; struct davinci_gpio_platform_data *pdata; struct device *dev = >dev; @@ -197,6 +198,16 @@ static int davinci_gpio_probe(struct platform_device *pdev) if (WARN_ON(ARCH_NR_GPIOS < ngpio)) ngpio = ARCH_NR_GPIOS; + /* +* If there are unbanked interrupts then the number of +* interrupts is equal to number of gpios else all are banked so +* number of interrupts is equal to number of banks(each with 16 gpios) +*/ + if (pdata->gpio_unbanked) + nirq = pdata->gpio_unbanked; + else + nirq = DIV_ROUND_UP(ngpio, 16); + nbank = DIV_ROUND_UP(ngpio, 32); chips = devm_kzalloc(dev, nbank * sizeof(struct davinci_gpio_controller), @@ -209,10 +220,13 @@ static int davinci_gpio_probe(struct platform_device *pdev) if (IS_ERR(gpio_base)) return PTR_ERR(gpio_base); - bank_irq = platform_get_irq(pdev, 0); - if (bank_irq < 0) { - dev_dbg(dev, "IRQ not populated\n"); - return bank_irq; + for (i = 0; i < nirq; i++) { + chips->irqs[i] = platform_get_irq(pdev, i); + if (chips->irqs[i] < 0) { + dev_info(dev, "IRQ not populated, err = %d\n", +chips->irqs[i]); + return chips->irqs[i]; + } } snprintf(label, MAX_LABEL_SIZE, "davinci_gpio.%d", ctrl_num++); @@ -249,7 +263,7 @@ static int davinci_gpio_probe(struct platform_device *pdev) goto err; platform_set_drvdata(pdev, chips); - ret = davinci_gpio_irq_setup(pdev, bank_irq); + ret = davinci_gpio_irq_setup(pdev); if (ret) goto err; @@ -383,7 +397,7 @@ static int gpio_to_irq_unbanked(struct gpio_chip *chip, unsigned offset) * can provide direct-mapped IRQs to AINTC (up to 32 GPIOs). */ if (offset < d->gpio_unbanked) - return d->base_irq + offset; + return d->irqs[offset]; else return -ENODEV; } @@ -396,7 +410,7 @@ static int gpio_irq_type_unbanked(struct irq_data *data, unsigned trigger) d = (struct davinci_gpio_controller *)irq_data_get_irq_handler_data(data); g = (struct davinci_gpio_regs __iomem *)d->regs[0]; - mask = __gpio_mask(data->irq - d->base_irq); + mask = __gpio_mask(data->irq - d->irqs[0]); if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) return -EINVAL; @@ -458,7 +472,7 @@ static struct irq_chip *keystone_gpio_get_irq_chip(unsigned int irq) * (dm6446) can be set appropriately for GPIOV33 pins. */ -static int davinci_gpio_irq_setup(struct platform_device *pdev, int bank_irq) +static int davinci_gpio_irq_setup(struct platform_device *pdev) { unsignedgpio, bank; int irq; @@ -492,6 +506,7 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev, int bank_irq) dev_err(dev, "Error %ld getting gpio clock\n", PTR_ERR(clk)); return PTR_ERR(clk); } + ret = clk_prepare_enable(clk); if (ret) return ret; @@ -531,12 +546,11 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev, int bank_irq) if (pdata->gpio_unbanked) { /* pass "bank 0" GPIO IRQs to AINTC */ chips->chip.to_irq = gpio_to_irq_unbanked; -
[PATCH v2 1/2] gpio: davinci: Shuffle IRQ resource fetching from DT to beginning of probe
This is needed in case of PROBE_DEFER if IRQ resource is not yet ready. Signed-off-by: Keerthy --- Tested for GPIO Interrupts on da850-lcdk and keystone-k2g-evm boards. No Changes in v2 drivers/gpio/gpio-davinci.c | 29 +++-- 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/drivers/gpio/gpio-davinci.c b/drivers/gpio/gpio-davinci.c index 987126c..861f35b 100644 --- a/drivers/gpio/gpio-davinci.c +++ b/drivers/gpio/gpio-davinci.c @@ -55,7 +55,7 @@ static inline struct davinci_gpio_regs __iomem *irq2regs(struct irq_data *d) return g; } -static int davinci_gpio_irq_setup(struct platform_device *pdev); +static int davinci_gpio_irq_setup(struct platform_device *pdev, int bank_irq); /*--*/ @@ -168,7 +168,7 @@ static int davinci_gpio_probe(struct platform_device *pdev) { static int ctrl_num, bank_base; int gpio, bank, ret = 0; - unsigned ngpio, nbank; + unsigned ngpio, nbank, bank_irq; struct davinci_gpio_controller *chips; struct davinci_gpio_platform_data *pdata; struct device *dev = >dev; @@ -209,6 +209,12 @@ static int davinci_gpio_probe(struct platform_device *pdev) if (IS_ERR(gpio_base)) return PTR_ERR(gpio_base); + bank_irq = platform_get_irq(pdev, 0); + if (bank_irq < 0) { + dev_dbg(dev, "IRQ not populated\n"); + return bank_irq; + } + snprintf(label, MAX_LABEL_SIZE, "davinci_gpio.%d", ctrl_num++); chips->chip.label = devm_kstrdup(dev, label, GFP_KERNEL); if (!chips->chip.label) @@ -243,7 +249,7 @@ static int davinci_gpio_probe(struct platform_device *pdev) goto err; platform_set_drvdata(pdev, chips); - ret = davinci_gpio_irq_setup(pdev); + ret = davinci_gpio_irq_setup(pdev, bank_irq); if (ret) goto err; @@ -452,16 +458,15 @@ static struct irq_chip *keystone_gpio_get_irq_chip(unsigned int irq) * (dm6446) can be set appropriately for GPIOV33 pins. */ -static int davinci_gpio_irq_setup(struct platform_device *pdev) +static int davinci_gpio_irq_setup(struct platform_device *pdev, int bank_irq) { unsignedgpio, bank; int irq; int ret; struct clk *clk; u32 binten = 0; - unsignedngpio, bank_irq; + unsignedngpio; struct device *dev = >dev; - struct resource *res; struct davinci_gpio_controller *chips = platform_get_drvdata(pdev); struct davinci_gpio_platform_data *pdata = dev->platform_data; struct davinci_gpio_regs __iomem *g; @@ -481,18 +486,6 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev) gpio_get_irq_chip = (gpio_get_irq_chip_cb_t)match->data; ngpio = pdata->ngpio; - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!res) { - dev_err(dev, "Invalid IRQ resource\n"); - return -EBUSY; - } - - bank_irq = res->start; - - if (!bank_irq) { - dev_err(dev, "Invalid IRQ resource\n"); - return -ENODEV; - } clk = devm_clk_get(dev, "gpio"); if (IS_ERR(clk)) { -- 1.9.1
Re: [PATCH 2/2] nvmem: Add Spreadtrum SC27XX efuse support
On 06/11/2018 10:24 PM, Baolin Wang wrote: > From: Freeman Liu > > This patch add the efuse driver which is embeded in Spreadtrum SC27XX > series PMICs. The sc27xx efuse contains 32 blocks and each block's > data width is 16 bits. > > Signed-off-by: Freeman Liu > Signed-off-by: Baolin Wang > --- > drivers/nvmem/Kconfig| 11 ++ > drivers/nvmem/Makefile |3 +- > drivers/nvmem/sc27xx-efuse.c | 263 > ++ > 3 files changed, 276 insertions(+), 1 deletion(-) > create mode 100644 drivers/nvmem/sc27xx-efuse.c > > diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig > index 54a3c29..3dca608 100644 > --- a/drivers/nvmem/Kconfig > +++ b/drivers/nvmem/Kconfig > @@ -181,4 +181,15 @@ config RAVE_SP_EEPROM > help > Say y here to enable Rave SP EEPROM support. > > +config SC27XX_EFUSE > + tristate "Spreadtrum SC27XX eFuse Support" > + depends on MFD_SC27XX_PMIC || COMPILE_TEST > + depends on HAS_IOMEM > + help > + This is a simple drive to dump specified values of Spreadtrum driver > + SC27XX PMICs from eFuse. > + > + This driver can also be built as a module. If so, the module > + will be called nvmem-sc27xx-efuse. > + > endif -- ~Randy
[PATCH v2 1/2] gpio: davinci: Shuffle IRQ resource fetching from DT to beginning of probe
This is needed in case of PROBE_DEFER if IRQ resource is not yet ready. Signed-off-by: Keerthy --- Tested for GPIO Interrupts on da850-lcdk and keystone-k2g-evm boards. No Changes in v2 drivers/gpio/gpio-davinci.c | 29 +++-- 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/drivers/gpio/gpio-davinci.c b/drivers/gpio/gpio-davinci.c index 987126c..861f35b 100644 --- a/drivers/gpio/gpio-davinci.c +++ b/drivers/gpio/gpio-davinci.c @@ -55,7 +55,7 @@ static inline struct davinci_gpio_regs __iomem *irq2regs(struct irq_data *d) return g; } -static int davinci_gpio_irq_setup(struct platform_device *pdev); +static int davinci_gpio_irq_setup(struct platform_device *pdev, int bank_irq); /*--*/ @@ -168,7 +168,7 @@ static int davinci_gpio_probe(struct platform_device *pdev) { static int ctrl_num, bank_base; int gpio, bank, ret = 0; - unsigned ngpio, nbank; + unsigned ngpio, nbank, bank_irq; struct davinci_gpio_controller *chips; struct davinci_gpio_platform_data *pdata; struct device *dev = >dev; @@ -209,6 +209,12 @@ static int davinci_gpio_probe(struct platform_device *pdev) if (IS_ERR(gpio_base)) return PTR_ERR(gpio_base); + bank_irq = platform_get_irq(pdev, 0); + if (bank_irq < 0) { + dev_dbg(dev, "IRQ not populated\n"); + return bank_irq; + } + snprintf(label, MAX_LABEL_SIZE, "davinci_gpio.%d", ctrl_num++); chips->chip.label = devm_kstrdup(dev, label, GFP_KERNEL); if (!chips->chip.label) @@ -243,7 +249,7 @@ static int davinci_gpio_probe(struct platform_device *pdev) goto err; platform_set_drvdata(pdev, chips); - ret = davinci_gpio_irq_setup(pdev); + ret = davinci_gpio_irq_setup(pdev, bank_irq); if (ret) goto err; @@ -452,16 +458,15 @@ static struct irq_chip *keystone_gpio_get_irq_chip(unsigned int irq) * (dm6446) can be set appropriately for GPIOV33 pins. */ -static int davinci_gpio_irq_setup(struct platform_device *pdev) +static int davinci_gpio_irq_setup(struct platform_device *pdev, int bank_irq) { unsignedgpio, bank; int irq; int ret; struct clk *clk; u32 binten = 0; - unsignedngpio, bank_irq; + unsignedngpio; struct device *dev = >dev; - struct resource *res; struct davinci_gpio_controller *chips = platform_get_drvdata(pdev); struct davinci_gpio_platform_data *pdata = dev->platform_data; struct davinci_gpio_regs __iomem *g; @@ -481,18 +486,6 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev) gpio_get_irq_chip = (gpio_get_irq_chip_cb_t)match->data; ngpio = pdata->ngpio; - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!res) { - dev_err(dev, "Invalid IRQ resource\n"); - return -EBUSY; - } - - bank_irq = res->start; - - if (!bank_irq) { - dev_err(dev, "Invalid IRQ resource\n"); - return -ENODEV; - } clk = devm_clk_get(dev, "gpio"); if (IS_ERR(clk)) { -- 1.9.1
Re: [PATCH 2/2] nvmem: Add Spreadtrum SC27XX efuse support
On 06/11/2018 10:24 PM, Baolin Wang wrote: > From: Freeman Liu > > This patch add the efuse driver which is embeded in Spreadtrum SC27XX > series PMICs. The sc27xx efuse contains 32 blocks and each block's > data width is 16 bits. > > Signed-off-by: Freeman Liu > Signed-off-by: Baolin Wang > --- > drivers/nvmem/Kconfig| 11 ++ > drivers/nvmem/Makefile |3 +- > drivers/nvmem/sc27xx-efuse.c | 263 > ++ > 3 files changed, 276 insertions(+), 1 deletion(-) > create mode 100644 drivers/nvmem/sc27xx-efuse.c > > diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig > index 54a3c29..3dca608 100644 > --- a/drivers/nvmem/Kconfig > +++ b/drivers/nvmem/Kconfig > @@ -181,4 +181,15 @@ config RAVE_SP_EEPROM > help > Say y here to enable Rave SP EEPROM support. > > +config SC27XX_EFUSE > + tristate "Spreadtrum SC27XX eFuse Support" > + depends on MFD_SC27XX_PMIC || COMPILE_TEST > + depends on HAS_IOMEM > + help > + This is a simple drive to dump specified values of Spreadtrum driver > + SC27XX PMICs from eFuse. > + > + This driver can also be built as a module. If so, the module > + will be called nvmem-sc27xx-efuse. > + > endif -- ~Randy
Re: [PATCH] staging: lustre: add error handling for try_module_get
On Tue, Jun 12 2018, Zhouyang Jia wrote: > When try_module_get fails, the lack of error-handling code may > cause unexpected results. > > This patch adds error-handling code after calling try_module_get. > > Signed-off-by: Zhouyang Jia > --- > drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c | 5 - > 1 file changed, 4 insertions(+), 1 deletion(-) > > diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > index 7086678..72a42bd 100644 > --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > @@ -2422,7 +2422,10 @@ ksocknal_base_startup(void) > > /* flag lists/ptrs/locks initialised */ > ksocknal_data.ksnd_init = SOCKNAL_INIT_DATA; > - try_module_get(THIS_MODULE); > + if (!try_module_get(THIS_MODULE)) { > + CERROR("%s: cannot get module\n", __func__); > + goto failed; > + } > > ksocknal_data.ksnd_sched_info = cfs_percpt_alloc(lnet_cpt_table(), >sizeof(*info)); Thanks for the patch I agree that this is probably a bug, but the code is still buggy after you patch, just in a different way. Try following through the code and see what happens when you 'goto failed'. NeilBrown signature.asc Description: PGP signature
Re: [PATCH] staging: lustre: add error handling for try_module_get
On Tue, Jun 12 2018, Zhouyang Jia wrote: > When try_module_get fails, the lack of error-handling code may > cause unexpected results. > > This patch adds error-handling code after calling try_module_get. > > Signed-off-by: Zhouyang Jia > --- > drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c | 5 - > 1 file changed, 4 insertions(+), 1 deletion(-) > > diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > index 7086678..72a42bd 100644 > --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > @@ -2422,7 +2422,10 @@ ksocknal_base_startup(void) > > /* flag lists/ptrs/locks initialised */ > ksocknal_data.ksnd_init = SOCKNAL_INIT_DATA; > - try_module_get(THIS_MODULE); > + if (!try_module_get(THIS_MODULE)) { > + CERROR("%s: cannot get module\n", __func__); > + goto failed; > + } > > ksocknal_data.ksnd_sched_info = cfs_percpt_alloc(lnet_cpt_table(), >sizeof(*info)); Thanks for the patch I agree that this is probably a bug, but the code is still buggy after you patch, just in a different way. Try following through the code and see what happens when you 'goto failed'. NeilBrown signature.asc Description: PGP signature
[PATCH 2/2] nvmem: Add Spreadtrum SC27XX efuse support
From: Freeman Liu This patch add the efuse driver which is embeded in Spreadtrum SC27XX series PMICs. The sc27xx efuse contains 32 blocks and each block's data width is 16 bits. Signed-off-by: Freeman Liu Signed-off-by: Baolin Wang --- drivers/nvmem/Kconfig| 11 ++ drivers/nvmem/Makefile |3 +- drivers/nvmem/sc27xx-efuse.c | 263 ++ 3 files changed, 276 insertions(+), 1 deletion(-) create mode 100644 drivers/nvmem/sc27xx-efuse.c diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig index 54a3c29..3dca608 100644 --- a/drivers/nvmem/Kconfig +++ b/drivers/nvmem/Kconfig @@ -181,4 +181,15 @@ config RAVE_SP_EEPROM help Say y here to enable Rave SP EEPROM support. +config SC27XX_EFUSE + tristate "Spreadtrum SC27XX eFuse Support" + depends on MFD_SC27XX_PMIC || COMPILE_TEST + depends on HAS_IOMEM + help + This is a simple drive to dump specified values of Spreadtrum + SC27XX PMICs from eFuse. + + This driver can also be built as a module. If so, the module + will be called nvmem-sc27xx-efuse. + endif diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile index 27e96a8..4e8c616 100644 --- a/drivers/nvmem/Makefile +++ b/drivers/nvmem/Makefile @@ -39,4 +39,5 @@ obj-$(CONFIG_NVMEM_SNVS_LPGPR)+= nvmem_snvs_lpgpr.o nvmem_snvs_lpgpr-y := snvs_lpgpr.o obj-$(CONFIG_RAVE_SP_EEPROM) += nvmem-rave-sp-eeprom.o nvmem-rave-sp-eeprom-y := rave-sp-eeprom.o - +obj-$(CONFIG_SC27XX_EFUSE) += nvmem-sc27xx-efuse.o +nvmem-sc27xx-efuse-y := sc27xx-efuse.o diff --git a/drivers/nvmem/sc27xx-efuse.c b/drivers/nvmem/sc27xx-efuse.c new file mode 100644 index 000..07c210c --- /dev/null +++ b/drivers/nvmem/sc27xx-efuse.c @@ -0,0 +1,263 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 Spreadtrum Communications Inc. + +#include +#include +#include +#include +#include +#include + +/* PMIC global registers definition */ +#define SC27XX_MODULE_EN 0xc08 +#define SC27XX_EFUSE_ENBIT(6) + +/* Efuse controller registers definition */ +#define SC27XX_EFUSE_GLB_CTRL 0x0 +#define SC27XX_EFUSE_DATA_RD 0x4 +#define SC27XX_EFUSE_DATA_WR 0x8 +#define SC27XX_EFUSE_BLOCK_INDEX 0xc +#define SC27XX_EFUSE_MODE_CTRL 0x10 +#define SC27XX_EFUSE_STATUS0x14 +#define SC27XX_EFUSE_WR_TIMING_CTRL0x20 +#define SC27XX_EFUSE_RD_TIMING_CTRL0x24 +#define SC27XX_EFUSE_EFUSE_DEB_CTRL0x28 + +/* Mask definition for SC27XX_EFUSE_BLOCK_INDEX register */ +#define SC27XX_EFUSE_BLOCK_MASKGENMASK(4, 0) + +/* Bits definitions for SC27XX_EFUSE_MODE_CTRL register */ +#define SC27XX_EFUSE_PG_START BIT(0) +#define SC27XX_EFUSE_RD_START BIT(1) +#define SC27XX_EFUSE_CLR_RDDONEBIT(2) + +/* Bits definitions for SC27XX_EFUSE_STATUS register */ +#define SC27XX_EFUSE_PGM_BUSY BIT(0) +#define SC27XX_EFUSE_READ_BUSY BIT(1) +#define SC27XX_EFUSE_STANDBY BIT(2) +#define SC27XX_EFUSE_GLOBAL_PROT BIT(3) +#define SC27XX_EFUSE_RD_DONE BIT(4) + +/* Block number and block width (bytes) definitions */ +#define SC27XX_EFUSE_BLOCK_MAX 32 +#define SC27XX_EFUSE_BLOCK_WIDTH 2 + +/* Timeout (ms) for the trylock of hardware spinlocks */ +#define SC27XX_EFUSE_HWLOCK_TIMEOUT5000 + +/* Timeout (us) of polling the status */ +#define SC27XX_EFUSE_POLL_TIMEOUT 300 +#define SC27XX_EFUSE_POLL_DELAY_US 1 + +struct sc27xx_efuse { + struct device *dev; + struct regmap *regmap; + struct hwspinlock *hwlock; + struct mutex mutex; + u32 base; +}; + +/* + * On Spreadtrum platform, we have multi-subsystems will access the unique + * efuse controller, so we need one hardware spinlock to synchronize between + * the multiple subsystems. + */ +static int sc27xx_efuse_lock(struct sc27xx_efuse *efuse) +{ + int ret; + + mutex_lock(>mutex); + + ret = hwspin_lock_timeout_raw(efuse->hwlock, + SC27XX_EFUSE_HWLOCK_TIMEOUT); + if (ret) { + dev_err(efuse->dev, "timeout to get the hwspinlock\n"); + mutex_unlock(>mutex); + return ret; + } + + return 0; +} + +static void sc27xx_efuse_unlock(struct sc27xx_efuse *efuse) +{ + hwspin_unlock_raw(efuse->hwlock); + mutex_unlock(>mutex); +} + +static int sc27xx_efuse_poll_status(struct sc27xx_efuse *efuse, u32 bits) +{ + int ret; + u32 val; + + ret = regmap_read_poll_timeout(efuse->regmap, + efuse->base + SC27XX_EFUSE_STATUS, + val, (val & bits), + SC27XX_EFUSE_POLL_DELAY_US, + SC27XX_EFUSE_POLL_TIMEOUT); + if (ret) { +
[PATCH 1/2] dt-bindings: nvmem: Add Spreadtrum SC27XX efuse controller documentation
This patch adds the binding documentation for Spreadtrum SC27XX series PMICs efuse controller device. Signed-off-by: Baolin Wang --- .../devicetree/bindings/nvmem/sc27xx-efuse.txt | 52 1 file changed, 52 insertions(+) create mode 100644 Documentation/devicetree/bindings/nvmem/sc27xx-efuse.txt diff --git a/Documentation/devicetree/bindings/nvmem/sc27xx-efuse.txt b/Documentation/devicetree/bindings/nvmem/sc27xx-efuse.txt new file mode 100644 index 000..586c082 --- /dev/null +++ b/Documentation/devicetree/bindings/nvmem/sc27xx-efuse.txt @@ -0,0 +1,52 @@ += Spreadtrum SC27XX PMIC eFuse device tree bindings = + +Required properties: +- compatible: Should be one of the following. + "sprd,sc2720-efuse" + "sprd,sc2721-efuse" + "sprd,sc2723-efuse" + "sprd,sc2730-efuse" + "sprd,sc2731-efuse" +- reg: Specify the address offset of efuse controller. +- hwlocks: Reference to a phandle of a hwlock provider node. + += Data cells = +Are child nodes of eFuse, bindings of which as described in +bindings/nvmem/nvmem.txt + +Example: + + sc2731_pmic: pmic@0 { + compatible = "sprd,sc2731"; + reg = <0>; + spi-max-frequency = <2600>; + interrupts = ; + interrupt-controller; + #interrupt-cells = <2>; + #address-cells = <1>; + #size-cells = <0>; + + efuse@380 { + compatible = "sprd,sc2731-efuse"; + reg = <0x380>; + #address-cells = <1>; + #size-cells = <1>; + hwlocks = < 12>; + + /* Data cells */ + thermal_calib: calib@10 { + reg = <0x10 0x2>; + }; + }; + }; + += Data consumers = +Are device nodes which consume nvmem data cells. + +Example: + + thermal { + ... + nvmem-cells = <_calib>; + nvmem-cell-names = "calibration"; + }; -- 1.7.9.5
[PATCH 2/2] nvmem: Add Spreadtrum SC27XX efuse support
From: Freeman Liu This patch add the efuse driver which is embeded in Spreadtrum SC27XX series PMICs. The sc27xx efuse contains 32 blocks and each block's data width is 16 bits. Signed-off-by: Freeman Liu Signed-off-by: Baolin Wang --- drivers/nvmem/Kconfig| 11 ++ drivers/nvmem/Makefile |3 +- drivers/nvmem/sc27xx-efuse.c | 263 ++ 3 files changed, 276 insertions(+), 1 deletion(-) create mode 100644 drivers/nvmem/sc27xx-efuse.c diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig index 54a3c29..3dca608 100644 --- a/drivers/nvmem/Kconfig +++ b/drivers/nvmem/Kconfig @@ -181,4 +181,15 @@ config RAVE_SP_EEPROM help Say y here to enable Rave SP EEPROM support. +config SC27XX_EFUSE + tristate "Spreadtrum SC27XX eFuse Support" + depends on MFD_SC27XX_PMIC || COMPILE_TEST + depends on HAS_IOMEM + help + This is a simple drive to dump specified values of Spreadtrum + SC27XX PMICs from eFuse. + + This driver can also be built as a module. If so, the module + will be called nvmem-sc27xx-efuse. + endif diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile index 27e96a8..4e8c616 100644 --- a/drivers/nvmem/Makefile +++ b/drivers/nvmem/Makefile @@ -39,4 +39,5 @@ obj-$(CONFIG_NVMEM_SNVS_LPGPR)+= nvmem_snvs_lpgpr.o nvmem_snvs_lpgpr-y := snvs_lpgpr.o obj-$(CONFIG_RAVE_SP_EEPROM) += nvmem-rave-sp-eeprom.o nvmem-rave-sp-eeprom-y := rave-sp-eeprom.o - +obj-$(CONFIG_SC27XX_EFUSE) += nvmem-sc27xx-efuse.o +nvmem-sc27xx-efuse-y := sc27xx-efuse.o diff --git a/drivers/nvmem/sc27xx-efuse.c b/drivers/nvmem/sc27xx-efuse.c new file mode 100644 index 000..07c210c --- /dev/null +++ b/drivers/nvmem/sc27xx-efuse.c @@ -0,0 +1,263 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 Spreadtrum Communications Inc. + +#include +#include +#include +#include +#include +#include + +/* PMIC global registers definition */ +#define SC27XX_MODULE_EN 0xc08 +#define SC27XX_EFUSE_ENBIT(6) + +/* Efuse controller registers definition */ +#define SC27XX_EFUSE_GLB_CTRL 0x0 +#define SC27XX_EFUSE_DATA_RD 0x4 +#define SC27XX_EFUSE_DATA_WR 0x8 +#define SC27XX_EFUSE_BLOCK_INDEX 0xc +#define SC27XX_EFUSE_MODE_CTRL 0x10 +#define SC27XX_EFUSE_STATUS0x14 +#define SC27XX_EFUSE_WR_TIMING_CTRL0x20 +#define SC27XX_EFUSE_RD_TIMING_CTRL0x24 +#define SC27XX_EFUSE_EFUSE_DEB_CTRL0x28 + +/* Mask definition for SC27XX_EFUSE_BLOCK_INDEX register */ +#define SC27XX_EFUSE_BLOCK_MASKGENMASK(4, 0) + +/* Bits definitions for SC27XX_EFUSE_MODE_CTRL register */ +#define SC27XX_EFUSE_PG_START BIT(0) +#define SC27XX_EFUSE_RD_START BIT(1) +#define SC27XX_EFUSE_CLR_RDDONEBIT(2) + +/* Bits definitions for SC27XX_EFUSE_STATUS register */ +#define SC27XX_EFUSE_PGM_BUSY BIT(0) +#define SC27XX_EFUSE_READ_BUSY BIT(1) +#define SC27XX_EFUSE_STANDBY BIT(2) +#define SC27XX_EFUSE_GLOBAL_PROT BIT(3) +#define SC27XX_EFUSE_RD_DONE BIT(4) + +/* Block number and block width (bytes) definitions */ +#define SC27XX_EFUSE_BLOCK_MAX 32 +#define SC27XX_EFUSE_BLOCK_WIDTH 2 + +/* Timeout (ms) for the trylock of hardware spinlocks */ +#define SC27XX_EFUSE_HWLOCK_TIMEOUT5000 + +/* Timeout (us) of polling the status */ +#define SC27XX_EFUSE_POLL_TIMEOUT 300 +#define SC27XX_EFUSE_POLL_DELAY_US 1 + +struct sc27xx_efuse { + struct device *dev; + struct regmap *regmap; + struct hwspinlock *hwlock; + struct mutex mutex; + u32 base; +}; + +/* + * On Spreadtrum platform, we have multi-subsystems will access the unique + * efuse controller, so we need one hardware spinlock to synchronize between + * the multiple subsystems. + */ +static int sc27xx_efuse_lock(struct sc27xx_efuse *efuse) +{ + int ret; + + mutex_lock(>mutex); + + ret = hwspin_lock_timeout_raw(efuse->hwlock, + SC27XX_EFUSE_HWLOCK_TIMEOUT); + if (ret) { + dev_err(efuse->dev, "timeout to get the hwspinlock\n"); + mutex_unlock(>mutex); + return ret; + } + + return 0; +} + +static void sc27xx_efuse_unlock(struct sc27xx_efuse *efuse) +{ + hwspin_unlock_raw(efuse->hwlock); + mutex_unlock(>mutex); +} + +static int sc27xx_efuse_poll_status(struct sc27xx_efuse *efuse, u32 bits) +{ + int ret; + u32 val; + + ret = regmap_read_poll_timeout(efuse->regmap, + efuse->base + SC27XX_EFUSE_STATUS, + val, (val & bits), + SC27XX_EFUSE_POLL_DELAY_US, + SC27XX_EFUSE_POLL_TIMEOUT); + if (ret) { +
[PATCH 1/2] dt-bindings: nvmem: Add Spreadtrum SC27XX efuse controller documentation
This patch adds the binding documentation for Spreadtrum SC27XX series PMICs efuse controller device. Signed-off-by: Baolin Wang --- .../devicetree/bindings/nvmem/sc27xx-efuse.txt | 52 1 file changed, 52 insertions(+) create mode 100644 Documentation/devicetree/bindings/nvmem/sc27xx-efuse.txt diff --git a/Documentation/devicetree/bindings/nvmem/sc27xx-efuse.txt b/Documentation/devicetree/bindings/nvmem/sc27xx-efuse.txt new file mode 100644 index 000..586c082 --- /dev/null +++ b/Documentation/devicetree/bindings/nvmem/sc27xx-efuse.txt @@ -0,0 +1,52 @@ += Spreadtrum SC27XX PMIC eFuse device tree bindings = + +Required properties: +- compatible: Should be one of the following. + "sprd,sc2720-efuse" + "sprd,sc2721-efuse" + "sprd,sc2723-efuse" + "sprd,sc2730-efuse" + "sprd,sc2731-efuse" +- reg: Specify the address offset of efuse controller. +- hwlocks: Reference to a phandle of a hwlock provider node. + += Data cells = +Are child nodes of eFuse, bindings of which as described in +bindings/nvmem/nvmem.txt + +Example: + + sc2731_pmic: pmic@0 { + compatible = "sprd,sc2731"; + reg = <0>; + spi-max-frequency = <2600>; + interrupts = ; + interrupt-controller; + #interrupt-cells = <2>; + #address-cells = <1>; + #size-cells = <0>; + + efuse@380 { + compatible = "sprd,sc2731-efuse"; + reg = <0x380>; + #address-cells = <1>; + #size-cells = <1>; + hwlocks = < 12>; + + /* Data cells */ + thermal_calib: calib@10 { + reg = <0x10 0x2>; + }; + }; + }; + += Data consumers = +Are device nodes which consume nvmem data cells. + +Example: + + thermal { + ... + nvmem-cells = <_calib>; + nvmem-cell-names = "calibration"; + }; -- 1.7.9.5
Re: [PATCH 1/2] arm64: dts: qcom: sdm845: Add I2C, SPI, and UART9 nodes
Hi, On Mon, Jun 11, 2018 at 10:01 PM, Bjorn Andersson wrote: > On Thu 07 Jun 13:46 PDT 2018, Douglas Anderson wrote: > >> This adds nodes to SDM845-dtsi for all the I2C ports, all the SPI >> ports, and UART9. Note that I2C / SPI / UART are a bit strange on >> sdm845 because each "serial engine" has 4 pins associated with it and >> depending on which firmware has been loaded into the serial engine >> (loaded by the BIOS) the serial engine can behave like an I2C port, a >> SPI port, or a UART. As per the landed bindings that means that we >> need to create one node for each possible mode that the port could be >> in. With 16 serial engines that means 16 x 3 = 48 nodes. >> >> We get away with only creating 33 nodes for now because it seems very >> likely that SDM845-based boards will actually all use the same UART >> (UART 9) for debug purposes. While another UART could be used for >> something like Bluetooth communication we can cross that path when we >> come to it. Some documentation that I saw implied that using a UART >> for "high speed" communications actually needs yet another different >> serial engine firmware anyway. >> >> Note that quick measurements adding all these nodes adds ~10k of extra >> space per dtb that they're included with. If this becomes a problem >> we may need to think of a different way to structure this so that >> boards only get the nodes they need (or figure out how to get dtc to >> strip 'disabled' nodes). For now it seems OK. >> >> These nodes were programmatically generated with a fairly dumb python >> script. See http://crosreview.com/1091631 for the source. >> >> Signed-off-by: Douglas Anderson > > Reviewed-by: Bjorn Andersson Thanks for the review! One note is that I have since come to find that it might not be so wise to define the sleep pinctrl state here. For the SPI driver at least I dug in and I saw the the sleep state is selected when we're runtime PMed. ...and with the currently posted SPI driver that can happen in some cases even when the chip select is supposed to be kept low. For now it's more prudent to keep the "sleep" state out of the device tree and we can always add it in later. I'll plan to re-spin the patch on Wednesday (I'm unavailable tomorrow). For other's reference: I chatted offline with Bjorn offline and this sounded fine to him. -Doug
Re: [PATCH 1/2] arm64: dts: qcom: sdm845: Add I2C, SPI, and UART9 nodes
Hi, On Mon, Jun 11, 2018 at 10:01 PM, Bjorn Andersson wrote: > On Thu 07 Jun 13:46 PDT 2018, Douglas Anderson wrote: > >> This adds nodes to SDM845-dtsi for all the I2C ports, all the SPI >> ports, and UART9. Note that I2C / SPI / UART are a bit strange on >> sdm845 because each "serial engine" has 4 pins associated with it and >> depending on which firmware has been loaded into the serial engine >> (loaded by the BIOS) the serial engine can behave like an I2C port, a >> SPI port, or a UART. As per the landed bindings that means that we >> need to create one node for each possible mode that the port could be >> in. With 16 serial engines that means 16 x 3 = 48 nodes. >> >> We get away with only creating 33 nodes for now because it seems very >> likely that SDM845-based boards will actually all use the same UART >> (UART 9) for debug purposes. While another UART could be used for >> something like Bluetooth communication we can cross that path when we >> come to it. Some documentation that I saw implied that using a UART >> for "high speed" communications actually needs yet another different >> serial engine firmware anyway. >> >> Note that quick measurements adding all these nodes adds ~10k of extra >> space per dtb that they're included with. If this becomes a problem >> we may need to think of a different way to structure this so that >> boards only get the nodes they need (or figure out how to get dtc to >> strip 'disabled' nodes). For now it seems OK. >> >> These nodes were programmatically generated with a fairly dumb python >> script. See http://crosreview.com/1091631 for the source. >> >> Signed-off-by: Douglas Anderson > > Reviewed-by: Bjorn Andersson Thanks for the review! One note is that I have since come to find that it might not be so wise to define the sleep pinctrl state here. For the SPI driver at least I dug in and I saw the the sleep state is selected when we're runtime PMed. ...and with the currently posted SPI driver that can happen in some cases even when the chip select is supposed to be kept low. For now it's more prudent to keep the "sleep" state out of the device tree and we can always add it in later. I'll plan to re-spin the patch on Wednesday (I'm unavailable tomorrow). For other's reference: I chatted offline with Bjorn offline and this sounded fine to him. -Doug
Re: [PATCH] proc: add error handling for kmem_cache_create
Hi, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on linus/master] [also build test WARNING on v4.17 next-20180608] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/linux-kernel-owner-vger-kernel-org/proc-add-error-handling-for-kmem_cache_create/20180612-122737 config: i386-randconfig-x012-201823 (attached as .config) compiler: gcc-7 (Debian 7.3.0-16) 7.3.0 reproduce: # save the attached .config to linux build tree make ARCH=i386 All warnings (new ones prefixed by >>): fs/proc/inode.c: In function 'proc_init_kmemcache': >> fs/proc/inode.c:108:10: warning: 'return' with a value, in function >> returning void return -ENOMEM; ^ fs/proc/inode.c:96:13: note: declared here void __init proc_init_kmemcache(void) ^~~ vim +/return +108 fs/proc/inode.c 95 96 void __init proc_init_kmemcache(void) 97 { 98 proc_inode_cachep = kmem_cache_create("proc_inode_cache", 99 sizeof(struct proc_inode), 100 0, (SLAB_RECLAIM_ACCOUNT| 101 SLAB_MEM_SPREAD|SLAB_ACCOUNT| 102 SLAB_PANIC), 103 init_once); 104 pde_opener_cache = 105 kmem_cache_create("pde_opener", sizeof(struct pde_opener), 0, 106SLAB_ACCOUNT|SLAB_PANIC, NULL); 107 if (!proc_inode_cachep || !pde_opener_cache) > 108 return -ENOMEM; 109 110 proc_dir_entry_cache = kmem_cache_create_usercopy( 111 "proc_dir_entry", sizeof(struct proc_dir_entry), 0, SLAB_PANIC, 112 offsetof(struct proc_dir_entry, inline_name), 113 sizeof_field(struct proc_dir_entry, inline_name), NULL); 114 } 115 --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH] proc: add error handling for kmem_cache_create
Hi, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on linus/master] [also build test WARNING on v4.17 next-20180608] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/linux-kernel-owner-vger-kernel-org/proc-add-error-handling-for-kmem_cache_create/20180612-122737 config: i386-randconfig-x012-201823 (attached as .config) compiler: gcc-7 (Debian 7.3.0-16) 7.3.0 reproduce: # save the attached .config to linux build tree make ARCH=i386 All warnings (new ones prefixed by >>): fs/proc/inode.c: In function 'proc_init_kmemcache': >> fs/proc/inode.c:108:10: warning: 'return' with a value, in function >> returning void return -ENOMEM; ^ fs/proc/inode.c:96:13: note: declared here void __init proc_init_kmemcache(void) ^~~ vim +/return +108 fs/proc/inode.c 95 96 void __init proc_init_kmemcache(void) 97 { 98 proc_inode_cachep = kmem_cache_create("proc_inode_cache", 99 sizeof(struct proc_inode), 100 0, (SLAB_RECLAIM_ACCOUNT| 101 SLAB_MEM_SPREAD|SLAB_ACCOUNT| 102 SLAB_PANIC), 103 init_once); 104 pde_opener_cache = 105 kmem_cache_create("pde_opener", sizeof(struct pde_opener), 0, 106SLAB_ACCOUNT|SLAB_PANIC, NULL); 107 if (!proc_inode_cachep || !pde_opener_cache) > 108 return -ENOMEM; 109 110 proc_dir_entry_cache = kmem_cache_create_usercopy( 111 "proc_dir_entry", sizeof(struct proc_dir_entry), 0, SLAB_PANIC, 112 offsetof(struct proc_dir_entry, inline_name), 113 sizeof_field(struct proc_dir_entry, inline_name), NULL); 114 } 115 --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
[RFC PATCH 2/5] fsi/scom: Whitespace fixes
No functional changes Signed-off-by: Benjamin Herrenschmidt --- drivers/fsi/fsi-scom.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/fsi/fsi-scom.c b/drivers/fsi/fsi-scom.c index 3cba0eb645e1..8a608db0aa07 100644 --- a/drivers/fsi/fsi-scom.c +++ b/drivers/fsi/fsi-scom.c @@ -49,7 +49,7 @@ static struct list_head scom_devices; static DEFINE_IDA(scom_ida); static int put_scom(struct scom_device *scom_dev, uint64_t value, - uint32_t addr) + uint32_t addr) { int rc; uint32_t data; @@ -77,7 +77,7 @@ static int put_scom(struct scom_device *scom_dev, uint64_t value, } static int get_scom(struct scom_device *scom_dev, uint64_t *value, - uint32_t addr) + uint32_t addr) { uint32_t result, data; int rc; @@ -110,7 +110,7 @@ static int get_scom(struct scom_device *scom_dev, uint64_t *value, } static ssize_t scom_read(struct file *filep, char __user *buf, size_t len, - loff_t *offset) +loff_t *offset) { int rc; struct miscdevice *mdev = @@ -136,7 +136,7 @@ static ssize_t scom_read(struct file *filep, char __user *buf, size_t len, } static ssize_t scom_write(struct file *filep, const char __user *buf, - size_t len, loff_t *offset) + size_t len, loff_t *offset) { int rc; struct miscdevice *mdev = filep->private_data; -- 2.17.0
[RFC PATCH 2/5] fsi/scom: Whitespace fixes
No functional changes Signed-off-by: Benjamin Herrenschmidt --- drivers/fsi/fsi-scom.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/fsi/fsi-scom.c b/drivers/fsi/fsi-scom.c index 3cba0eb645e1..8a608db0aa07 100644 --- a/drivers/fsi/fsi-scom.c +++ b/drivers/fsi/fsi-scom.c @@ -49,7 +49,7 @@ static struct list_head scom_devices; static DEFINE_IDA(scom_ida); static int put_scom(struct scom_device *scom_dev, uint64_t value, - uint32_t addr) + uint32_t addr) { int rc; uint32_t data; @@ -77,7 +77,7 @@ static int put_scom(struct scom_device *scom_dev, uint64_t value, } static int get_scom(struct scom_device *scom_dev, uint64_t *value, - uint32_t addr) + uint32_t addr) { uint32_t result, data; int rc; @@ -110,7 +110,7 @@ static int get_scom(struct scom_device *scom_dev, uint64_t *value, } static ssize_t scom_read(struct file *filep, char __user *buf, size_t len, - loff_t *offset) +loff_t *offset) { int rc; struct miscdevice *mdev = @@ -136,7 +136,7 @@ static ssize_t scom_read(struct file *filep, char __user *buf, size_t len, } static ssize_t scom_write(struct file *filep, const char __user *buf, - size_t len, loff_t *offset) + size_t len, loff_t *offset) { int rc; struct miscdevice *mdev = filep->private_data; -- 2.17.0
[RFC PATCH 3/5] fsi/scom: Fixup endian annotations
Use the proper annotated type __be32 and fixup the accessor used for get_scom() Signed-off-by: Benjamin Herrenschmidt --- drivers/fsi/fsi-scom.c | 9 - 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/fsi/fsi-scom.c b/drivers/fsi/fsi-scom.c index 8a608db0aa07..6ddfb6021420 100644 --- a/drivers/fsi/fsi-scom.c +++ b/drivers/fsi/fsi-scom.c @@ -51,8 +51,8 @@ static DEFINE_IDA(scom_ida); static int put_scom(struct scom_device *scom_dev, uint64_t value, uint32_t addr) { + __be32 data; int rc; - uint32_t data; mutex_lock(_dev->lock); @@ -79,7 +79,7 @@ static int put_scom(struct scom_device *scom_dev, uint64_t value, static int get_scom(struct scom_device *scom_dev, uint64_t *value, uint32_t addr) { - uint32_t result, data; + __be32 result, data; int rc; @@ -96,14 +96,13 @@ static int get_scom(struct scom_device *scom_dev, uint64_t *value, if (rc) goto bail; - *value |= (uint64_t)cpu_to_be32(result) << 32; + *value |= (uint64_t)be32_to_cpu(result) << 32; rc = fsi_device_read(scom_dev->fsi_dev, SCOM_DATA1_REG, , sizeof(uint32_t)); if (rc) goto bail; - *value |= cpu_to_be32(result); - + *value |= be32_to_cpu(result); bail: mutex_unlock(_dev->lock); return rc; -- 2.17.0
[RFC PATCH 3/5] fsi/scom: Fixup endian annotations
Use the proper annotated type __be32 and fixup the accessor used for get_scom() Signed-off-by: Benjamin Herrenschmidt --- drivers/fsi/fsi-scom.c | 9 - 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/fsi/fsi-scom.c b/drivers/fsi/fsi-scom.c index 8a608db0aa07..6ddfb6021420 100644 --- a/drivers/fsi/fsi-scom.c +++ b/drivers/fsi/fsi-scom.c @@ -51,8 +51,8 @@ static DEFINE_IDA(scom_ida); static int put_scom(struct scom_device *scom_dev, uint64_t value, uint32_t addr) { + __be32 data; int rc; - uint32_t data; mutex_lock(_dev->lock); @@ -79,7 +79,7 @@ static int put_scom(struct scom_device *scom_dev, uint64_t value, static int get_scom(struct scom_device *scom_dev, uint64_t *value, uint32_t addr) { - uint32_t result, data; + __be32 result, data; int rc; @@ -96,14 +96,13 @@ static int get_scom(struct scom_device *scom_dev, uint64_t *value, if (rc) goto bail; - *value |= (uint64_t)cpu_to_be32(result) << 32; + *value |= (uint64_t)be32_to_cpu(result) << 32; rc = fsi_device_read(scom_dev->fsi_dev, SCOM_DATA1_REG, , sizeof(uint32_t)); if (rc) goto bail; - *value |= cpu_to_be32(result); - + *value |= be32_to_cpu(result); bail: mutex_unlock(_dev->lock); return rc; -- 2.17.0
[RFC PATCH 4/5] fsi/scom: Add register definitions
Add a few more register and bit definitions, also define and use SCOM_READ_CMD (which is 0 but it makes the code clearer) Signed-off-by: Benjamin Herrenschmidt --- drivers/fsi/fsi-scom.c | 19 ++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/fsi/fsi-scom.c b/drivers/fsi/fsi-scom.c index 6ddfb6021420..e98573ecdae1 100644 --- a/drivers/fsi/fsi-scom.c +++ b/drivers/fsi/fsi-scom.c @@ -30,8 +30,25 @@ #define SCOM_DATA0_REG 0x00 #define SCOM_DATA1_REG 0x04 #define SCOM_CMD_REG 0x08 +#define SCOM_FSI2PIB_RESET_REG 0x18 +#define SCOM_STATUS_REG0x1C /* Read */ +#define SCOM_PIB_RESET_REG 0x1C /* Write */ +/* Command register */ #define SCOM_WRITE_CMD 0x8000 +#define SCOM_READ_CMD 0x + +/* Status register bits */ +#define SCOM_STATUS_ERR_SUMMARY0x8000 +#define SCOM_STATUS_PROTECTION 0x0100 +#define SCOM_STATUS_PIB_ABORT 0x0010 +#define SCOM_STATUS_PIB_RESP_MASK 0x7000 +#define SCOM_STATUS_PIB_RESP_SHIFT 12 + +#define SCOM_STATUS_ANY_ERR(SCOM_STATUS_ERR_SUMMARY | \ +SCOM_STATUS_PROTECTION | \ +SCOM_STATUS_PIB_ABORT | \ +SCOM_STATUS_PIB_RESP_MASK) struct scom_device { struct list_head link; @@ -85,7 +102,7 @@ static int get_scom(struct scom_device *scom_dev, uint64_t *value, mutex_lock(_dev->lock); *value = 0ULL; - data = cpu_to_be32(addr); + data = cpu_to_be32(SCOM_READ_CMD | addr); rc = fsi_device_write(scom_dev->fsi_dev, SCOM_CMD_REG, , sizeof(uint32_t)); if (rc) -- 2.17.0
[RFC PATCH 5/5] fsi/scom: Major overhaul
This was too hard to split ... this adds a number of features to the SCOM user interface: - Support for indirect SCOMs - read()/write() interface now handle errors and retries - New ioctl() "raw" interface for use by debuggers Signed-off-by: Benjamin Herrenschmidt --- drivers/fsi/fsi-scom.c | 424 --- include/uapi/linux/fsi.h | 56 ++ 2 files changed, 450 insertions(+), 30 deletions(-) create mode 100644 include/uapi/linux/fsi.h diff --git a/drivers/fsi/fsi-scom.c b/drivers/fsi/fsi-scom.c index e98573ecdae1..39c74351f1bf 100644 --- a/drivers/fsi/fsi-scom.c +++ b/drivers/fsi/fsi-scom.c @@ -24,6 +24,8 @@ #include #include +#include + #define FSI_ENGID_SCOM 0x5 /* SCOM engine register set */ @@ -41,14 +43,36 @@ /* Status register bits */ #define SCOM_STATUS_ERR_SUMMARY0x8000 #define SCOM_STATUS_PROTECTION 0x0100 +#define SCOM_STATUS_PARITY 0x0400 #define SCOM_STATUS_PIB_ABORT 0x0010 #define SCOM_STATUS_PIB_RESP_MASK 0x7000 #define SCOM_STATUS_PIB_RESP_SHIFT 12 #define SCOM_STATUS_ANY_ERR(SCOM_STATUS_ERR_SUMMARY | \ SCOM_STATUS_PROTECTION | \ +SCOM_STATUS_PARITY | \ SCOM_STATUS_PIB_ABORT | \ SCOM_STATUS_PIB_RESP_MASK) +/* SCOM address encodings */ +#define XSCOM_ADDR_IND_FLAGBIT_ULL(63) +#define XSCOM_ADDR_INF_FORM1 BIT_ULL(60) + +/* SCOM indirect stuff */ +#define XSCOM_ADDR_DIRECT_PART 0x7fffull +#define XSCOM_ADDR_INDIRECT_PART 0x000full +#define XSCOM_DATA_IND_READBIT_ULL(63) +#define XSCOM_DATA_IND_COMPLETEBIT_ULL(31) +#define XSCOM_DATA_IND_ERR_MASK0x7000ull +#define XSCOM_DATA_IND_ERR_SHIFT 28 +#define XSCOM_DATA_IND_DATA0xull +#define XSCOM_DATA_IND_FORM1_DATA 0x000full +#define XSCOM_ADDR_FORM1_LOW 0x000ull +#define XSCOM_ADDR_FORM1_HI0xfffull +#define XSCOM_ADDR_FORM1_HI_SHIFT 20 + +/* Retries */ +#define SCOM_MAX_RETRIES 100 /* Retries on busy */ +#define SCOM_MAX_IND_RETRIES 10 /* Retries indirect not ready */ struct scom_device { struct list_head link; @@ -56,7 +80,7 @@ struct scom_device { struct miscdevice mdev; struct mutex lock; charname[32]; - int idx; + int idx; }; #define to_scom_dev(x) container_of((x), struct scom_device, mdev) @@ -65,80 +89,304 @@ static struct list_head scom_devices; static DEFINE_IDA(scom_ida); -static int put_scom(struct scom_device *scom_dev, uint64_t value, - uint32_t addr) +static int __put_scom(struct scom_device *scom_dev, uint64_t value, + uint32_t addr, uint32_t *status) { - __be32 data; + __be32 data, raw_status; int rc; - mutex_lock(_dev->lock); - data = cpu_to_be32((value >> 32) & 0x); rc = fsi_device_write(scom_dev->fsi_dev, SCOM_DATA0_REG, , sizeof(uint32_t)); if (rc) - goto bail; + return rc; data = cpu_to_be32(value & 0x); rc = fsi_device_write(scom_dev->fsi_dev, SCOM_DATA1_REG, , sizeof(uint32_t)); if (rc) - goto bail; + return rc; data = cpu_to_be32(SCOM_WRITE_CMD | addr); rc = fsi_device_write(scom_dev->fsi_dev, SCOM_CMD_REG, , sizeof(uint32_t)); - bail: - mutex_unlock(_dev->lock); - return rc; + if (rc) + return rc; + rc = fsi_device_read(scom_dev->fsi_dev, SCOM_STATUS_REG, _status, +sizeof(uint32_t)); + if (rc) + return rc; + *status = be32_to_cpu(raw_status); + + return 0; } -static int get_scom(struct scom_device *scom_dev, uint64_t *value, - uint32_t addr) +static int __get_scom(struct scom_device *scom_dev, uint64_t *value, + uint32_t addr, uint32_t *status) { - __be32 result, data; + __be32 data, raw_status; int rc; - mutex_lock(_dev->lock); *value = 0ULL; data = cpu_to_be32(SCOM_READ_CMD | addr); rc = fsi_device_write(scom_dev->fsi_dev, SCOM_CMD_REG, , sizeof(uint32_t)); if (rc) - goto bail; + return rc; + rc = fsi_device_read(scom_dev->fsi_dev, SCOM_STATUS_REG, _status, +sizeof(uint32_t)); + if (rc) + return rc; - rc = fsi_device_read(scom_dev->fsi_dev, SCOM_DATA0_REG, , + /* +* Read the data
Re: linux-next: build failure after merge of the drivers-x86 tree
On June 11, 2018 6:23:10 PM PDT, Stephen Rothwell wrote: >Hi all, > >After merging the drivers-x86 tree, today's linux-next build (x86_64 >allmodconfig) failed like this: > >drivers/platform/x86/silead_dmi.c:84:21: error: variable >'chuwi_vi10_data' has initializer but incomplete type > static const struct ts_dmi_data chuwi_vi10_data = { > ^~~ ... >Caused by commit > >2da502a0aea7 ("platform/x86: silead_dmi: Add touchscreen info for the >Chuwi Vi10 tablet") > >I have reverted that commit for today. More care please. Grmbl. Thanks Stephen. I'll work with Andy tonight to get for-next back into good shape. -- Sent from my Android device with K-9 Mail. Please excuse my brevity.
[RFC PATCH 4/5] fsi/scom: Add register definitions
Add a few more register and bit definitions, also define and use SCOM_READ_CMD (which is 0 but it makes the code clearer) Signed-off-by: Benjamin Herrenschmidt --- drivers/fsi/fsi-scom.c | 19 ++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/fsi/fsi-scom.c b/drivers/fsi/fsi-scom.c index 6ddfb6021420..e98573ecdae1 100644 --- a/drivers/fsi/fsi-scom.c +++ b/drivers/fsi/fsi-scom.c @@ -30,8 +30,25 @@ #define SCOM_DATA0_REG 0x00 #define SCOM_DATA1_REG 0x04 #define SCOM_CMD_REG 0x08 +#define SCOM_FSI2PIB_RESET_REG 0x18 +#define SCOM_STATUS_REG0x1C /* Read */ +#define SCOM_PIB_RESET_REG 0x1C /* Write */ +/* Command register */ #define SCOM_WRITE_CMD 0x8000 +#define SCOM_READ_CMD 0x + +/* Status register bits */ +#define SCOM_STATUS_ERR_SUMMARY0x8000 +#define SCOM_STATUS_PROTECTION 0x0100 +#define SCOM_STATUS_PIB_ABORT 0x0010 +#define SCOM_STATUS_PIB_RESP_MASK 0x7000 +#define SCOM_STATUS_PIB_RESP_SHIFT 12 + +#define SCOM_STATUS_ANY_ERR(SCOM_STATUS_ERR_SUMMARY | \ +SCOM_STATUS_PROTECTION | \ +SCOM_STATUS_PIB_ABORT | \ +SCOM_STATUS_PIB_RESP_MASK) struct scom_device { struct list_head link; @@ -85,7 +102,7 @@ static int get_scom(struct scom_device *scom_dev, uint64_t *value, mutex_lock(_dev->lock); *value = 0ULL; - data = cpu_to_be32(addr); + data = cpu_to_be32(SCOM_READ_CMD | addr); rc = fsi_device_write(scom_dev->fsi_dev, SCOM_CMD_REG, , sizeof(uint32_t)); if (rc) -- 2.17.0
[RFC PATCH 5/5] fsi/scom: Major overhaul
This was too hard to split ... this adds a number of features to the SCOM user interface: - Support for indirect SCOMs - read()/write() interface now handle errors and retries - New ioctl() "raw" interface for use by debuggers Signed-off-by: Benjamin Herrenschmidt --- drivers/fsi/fsi-scom.c | 424 --- include/uapi/linux/fsi.h | 56 ++ 2 files changed, 450 insertions(+), 30 deletions(-) create mode 100644 include/uapi/linux/fsi.h diff --git a/drivers/fsi/fsi-scom.c b/drivers/fsi/fsi-scom.c index e98573ecdae1..39c74351f1bf 100644 --- a/drivers/fsi/fsi-scom.c +++ b/drivers/fsi/fsi-scom.c @@ -24,6 +24,8 @@ #include #include +#include + #define FSI_ENGID_SCOM 0x5 /* SCOM engine register set */ @@ -41,14 +43,36 @@ /* Status register bits */ #define SCOM_STATUS_ERR_SUMMARY0x8000 #define SCOM_STATUS_PROTECTION 0x0100 +#define SCOM_STATUS_PARITY 0x0400 #define SCOM_STATUS_PIB_ABORT 0x0010 #define SCOM_STATUS_PIB_RESP_MASK 0x7000 #define SCOM_STATUS_PIB_RESP_SHIFT 12 #define SCOM_STATUS_ANY_ERR(SCOM_STATUS_ERR_SUMMARY | \ SCOM_STATUS_PROTECTION | \ +SCOM_STATUS_PARITY | \ SCOM_STATUS_PIB_ABORT | \ SCOM_STATUS_PIB_RESP_MASK) +/* SCOM address encodings */ +#define XSCOM_ADDR_IND_FLAGBIT_ULL(63) +#define XSCOM_ADDR_INF_FORM1 BIT_ULL(60) + +/* SCOM indirect stuff */ +#define XSCOM_ADDR_DIRECT_PART 0x7fffull +#define XSCOM_ADDR_INDIRECT_PART 0x000full +#define XSCOM_DATA_IND_READBIT_ULL(63) +#define XSCOM_DATA_IND_COMPLETEBIT_ULL(31) +#define XSCOM_DATA_IND_ERR_MASK0x7000ull +#define XSCOM_DATA_IND_ERR_SHIFT 28 +#define XSCOM_DATA_IND_DATA0xull +#define XSCOM_DATA_IND_FORM1_DATA 0x000full +#define XSCOM_ADDR_FORM1_LOW 0x000ull +#define XSCOM_ADDR_FORM1_HI0xfffull +#define XSCOM_ADDR_FORM1_HI_SHIFT 20 + +/* Retries */ +#define SCOM_MAX_RETRIES 100 /* Retries on busy */ +#define SCOM_MAX_IND_RETRIES 10 /* Retries indirect not ready */ struct scom_device { struct list_head link; @@ -56,7 +80,7 @@ struct scom_device { struct miscdevice mdev; struct mutex lock; charname[32]; - int idx; + int idx; }; #define to_scom_dev(x) container_of((x), struct scom_device, mdev) @@ -65,80 +89,304 @@ static struct list_head scom_devices; static DEFINE_IDA(scom_ida); -static int put_scom(struct scom_device *scom_dev, uint64_t value, - uint32_t addr) +static int __put_scom(struct scom_device *scom_dev, uint64_t value, + uint32_t addr, uint32_t *status) { - __be32 data; + __be32 data, raw_status; int rc; - mutex_lock(_dev->lock); - data = cpu_to_be32((value >> 32) & 0x); rc = fsi_device_write(scom_dev->fsi_dev, SCOM_DATA0_REG, , sizeof(uint32_t)); if (rc) - goto bail; + return rc; data = cpu_to_be32(value & 0x); rc = fsi_device_write(scom_dev->fsi_dev, SCOM_DATA1_REG, , sizeof(uint32_t)); if (rc) - goto bail; + return rc; data = cpu_to_be32(SCOM_WRITE_CMD | addr); rc = fsi_device_write(scom_dev->fsi_dev, SCOM_CMD_REG, , sizeof(uint32_t)); - bail: - mutex_unlock(_dev->lock); - return rc; + if (rc) + return rc; + rc = fsi_device_read(scom_dev->fsi_dev, SCOM_STATUS_REG, _status, +sizeof(uint32_t)); + if (rc) + return rc; + *status = be32_to_cpu(raw_status); + + return 0; } -static int get_scom(struct scom_device *scom_dev, uint64_t *value, - uint32_t addr) +static int __get_scom(struct scom_device *scom_dev, uint64_t *value, + uint32_t addr, uint32_t *status) { - __be32 result, data; + __be32 data, raw_status; int rc; - mutex_lock(_dev->lock); *value = 0ULL; data = cpu_to_be32(SCOM_READ_CMD | addr); rc = fsi_device_write(scom_dev->fsi_dev, SCOM_CMD_REG, , sizeof(uint32_t)); if (rc) - goto bail; + return rc; + rc = fsi_device_read(scom_dev->fsi_dev, SCOM_STATUS_REG, _status, +sizeof(uint32_t)); + if (rc) + return rc; - rc = fsi_device_read(scom_dev->fsi_dev, SCOM_DATA0_REG, , + /* +* Read the data
Re: linux-next: build failure after merge of the drivers-x86 tree
On June 11, 2018 6:23:10 PM PDT, Stephen Rothwell wrote: >Hi all, > >After merging the drivers-x86 tree, today's linux-next build (x86_64 >allmodconfig) failed like this: > >drivers/platform/x86/silead_dmi.c:84:21: error: variable >'chuwi_vi10_data' has initializer but incomplete type > static const struct ts_dmi_data chuwi_vi10_data = { > ^~~ ... >Caused by commit > >2da502a0aea7 ("platform/x86: silead_dmi: Add touchscreen info for the >Chuwi Vi10 tablet") > >I have reverted that commit for today. More care please. Grmbl. Thanks Stephen. I'll work with Andy tonight to get for-next back into good shape. -- Sent from my Android device with K-9 Mail. Please excuse my brevity.
[RFC PATCH 1/5] fsi/scom: Add mutex around FSI2PIB accesses
Otherwise, multiple clients can open the driver and attempt to access the PIB at the same time, thus clobbering each other in the process. Signed-off-by: Benjamin Herrenschmidt --- drivers/fsi/fsi-scom.c | 25 ++--- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/drivers/fsi/fsi-scom.c b/drivers/fsi/fsi-scom.c index c8eb5e5b94a7..3cba0eb645e1 100644 --- a/drivers/fsi/fsi-scom.c +++ b/drivers/fsi/fsi-scom.c @@ -37,6 +37,7 @@ struct scom_device { struct list_head link; struct fsi_device *fsi_dev; struct miscdevice mdev; + struct mutex lock; charname[32]; int idx; }; @@ -53,21 +54,26 @@ static int put_scom(struct scom_device *scom_dev, uint64_t value, int rc; uint32_t data; + mutex_lock(_dev->lock); + data = cpu_to_be32((value >> 32) & 0x); rc = fsi_device_write(scom_dev->fsi_dev, SCOM_DATA0_REG, , sizeof(uint32_t)); if (rc) - return rc; + goto bail; data = cpu_to_be32(value & 0x); rc = fsi_device_write(scom_dev->fsi_dev, SCOM_DATA1_REG, , sizeof(uint32_t)); if (rc) - return rc; + goto bail; data = cpu_to_be32(SCOM_WRITE_CMD | addr); - return fsi_device_write(scom_dev->fsi_dev, SCOM_CMD_REG, , + rc = fsi_device_write(scom_dev->fsi_dev, SCOM_CMD_REG, , sizeof(uint32_t)); + bail: + mutex_unlock(_dev->lock); + return rc; } static int get_scom(struct scom_device *scom_dev, uint64_t *value, @@ -76,27 +82,31 @@ static int get_scom(struct scom_device *scom_dev, uint64_t *value, uint32_t result, data; int rc; + + mutex_lock(_dev->lock); *value = 0ULL; data = cpu_to_be32(addr); rc = fsi_device_write(scom_dev->fsi_dev, SCOM_CMD_REG, , sizeof(uint32_t)); if (rc) - return rc; + goto bail; rc = fsi_device_read(scom_dev->fsi_dev, SCOM_DATA0_REG, , sizeof(uint32_t)); if (rc) - return rc; + goto bail; *value |= (uint64_t)cpu_to_be32(result) << 32; rc = fsi_device_read(scom_dev->fsi_dev, SCOM_DATA1_REG, , sizeof(uint32_t)); if (rc) - return rc; + goto bail; *value |= cpu_to_be32(result); - return 0; + bail: + mutex_unlock(_dev->lock); + return rc; } static ssize_t scom_read(struct file *filep, char __user *buf, size_t len, @@ -183,6 +193,7 @@ static int scom_probe(struct device *dev) if (!scom) return -ENOMEM; + mutex_init(>lock); scom->idx = ida_simple_get(_ida, 1, INT_MAX, GFP_KERNEL); snprintf(scom->name, sizeof(scom->name), "scom%d", scom->idx); scom->fsi_dev = fsi_dev; -- 2.17.0
[RFC PATCH 1/5] fsi/scom: Add mutex around FSI2PIB accesses
Otherwise, multiple clients can open the driver and attempt to access the PIB at the same time, thus clobbering each other in the process. Signed-off-by: Benjamin Herrenschmidt --- drivers/fsi/fsi-scom.c | 25 ++--- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/drivers/fsi/fsi-scom.c b/drivers/fsi/fsi-scom.c index c8eb5e5b94a7..3cba0eb645e1 100644 --- a/drivers/fsi/fsi-scom.c +++ b/drivers/fsi/fsi-scom.c @@ -37,6 +37,7 @@ struct scom_device { struct list_head link; struct fsi_device *fsi_dev; struct miscdevice mdev; + struct mutex lock; charname[32]; int idx; }; @@ -53,21 +54,26 @@ static int put_scom(struct scom_device *scom_dev, uint64_t value, int rc; uint32_t data; + mutex_lock(_dev->lock); + data = cpu_to_be32((value >> 32) & 0x); rc = fsi_device_write(scom_dev->fsi_dev, SCOM_DATA0_REG, , sizeof(uint32_t)); if (rc) - return rc; + goto bail; data = cpu_to_be32(value & 0x); rc = fsi_device_write(scom_dev->fsi_dev, SCOM_DATA1_REG, , sizeof(uint32_t)); if (rc) - return rc; + goto bail; data = cpu_to_be32(SCOM_WRITE_CMD | addr); - return fsi_device_write(scom_dev->fsi_dev, SCOM_CMD_REG, , + rc = fsi_device_write(scom_dev->fsi_dev, SCOM_CMD_REG, , sizeof(uint32_t)); + bail: + mutex_unlock(_dev->lock); + return rc; } static int get_scom(struct scom_device *scom_dev, uint64_t *value, @@ -76,27 +82,31 @@ static int get_scom(struct scom_device *scom_dev, uint64_t *value, uint32_t result, data; int rc; + + mutex_lock(_dev->lock); *value = 0ULL; data = cpu_to_be32(addr); rc = fsi_device_write(scom_dev->fsi_dev, SCOM_CMD_REG, , sizeof(uint32_t)); if (rc) - return rc; + goto bail; rc = fsi_device_read(scom_dev->fsi_dev, SCOM_DATA0_REG, , sizeof(uint32_t)); if (rc) - return rc; + goto bail; *value |= (uint64_t)cpu_to_be32(result) << 32; rc = fsi_device_read(scom_dev->fsi_dev, SCOM_DATA1_REG, , sizeof(uint32_t)); if (rc) - return rc; + goto bail; *value |= cpu_to_be32(result); - return 0; + bail: + mutex_unlock(_dev->lock); + return rc; } static ssize_t scom_read(struct file *filep, char __user *buf, size_t len, @@ -183,6 +193,7 @@ static int scom_probe(struct device *dev) if (!scom) return -ENOMEM; + mutex_init(>lock); scom->idx = ida_simple_get(_ida, 1, INT_MAX, GFP_KERNEL); snprintf(scom->name, sizeof(scom->name), "scom%d", scom->idx); scom->fsi_dev = fsi_dev; -- 2.17.0
[RFC PATCH 0/5] FSI scom driver overhaul
The current FSI scom driver is a bit too simplistic (and buggy). This fixes a locking bug, cleans a few things up, then overhaul the driver more thoroughly by providing proper support for the different type of SCOM accesses (direct and indirect), handling errors properly in the read/write interface, and adding a lower level ioctl interface needed by system debugger (such as cronus) that need to be able to access the raw status register content resulting from the access attempt and do their own error handling. I will send patches separately for pdbg and cronus to use the new debugger interface. Note: It is unfortunate that the read/write interface does NOT use the same addressing scheme as the host-side equivalent xscom debugfs interface. However I didn't want to change the user ABI by "fixing" this as I'm not entirely sure what other users we might have of that existing interface. The patches apply on top of the other FSI changes posted recently and at this point are meant to discuss the new user API.
[RFC PATCH 0/5] FSI scom driver overhaul
The current FSI scom driver is a bit too simplistic (and buggy). This fixes a locking bug, cleans a few things up, then overhaul the driver more thoroughly by providing proper support for the different type of SCOM accesses (direct and indirect), handling errors properly in the read/write interface, and adding a lower level ioctl interface needed by system debugger (such as cronus) that need to be able to access the raw status register content resulting from the access attempt and do their own error handling. I will send patches separately for pdbg and cronus to use the new debugger interface. Note: It is unfortunate that the read/write interface does NOT use the same addressing scheme as the host-side equivalent xscom debugfs interface. However I didn't want to change the user ABI by "fixing" this as I'm not entirely sure what other users we might have of that existing interface. The patches apply on top of the other FSI changes posted recently and at this point are meant to discuss the new user API.
Re: linux-next: build failure after merge of the drivers-x86 tree
On Tue, Jun 12, 2018 at 11:23:10AM +1000, Stephen Rothwell wrote: > Hi all, > > After merging the drivers-x86 tree, today's linux-next build (x86_64 > allmodconfig) failed like this: > > drivers/platform/x86/silead_dmi.c:84:21: error: variable 'chuwi_vi10_data' > has initializer but incomplete type > static const struct ts_dmi_data chuwi_vi10_data = { > ^~~ > drivers/platform/x86/silead_dmi.c:85:3: error: 'const struct ts_dmi_data' has > no member named 'acpi_name' > .acpi_name = "MSSL0002:00", >^ > drivers/platform/x86/silead_dmi.c:85:20: warning: excess elements in struct > initializer > .acpi_name = "MSSL0002:00", > ^ > drivers/platform/x86/silead_dmi.c:85:20: note: (near initialization for > 'chuwi_vi10_data') > drivers/platform/x86/silead_dmi.c:86:3: error: 'const struct ts_dmi_data' has > no member named 'properties' > .properties = chuwi_vi10_props, >^~ > drivers/platform/x86/silead_dmi.c:86:20: warning: excess elements in struct > initializer > .properties = chuwi_vi10_props, > ^~~~ > drivers/platform/x86/silead_dmi.c:86:20: note: (near initialization for > 'chuwi_vi10_data') > drivers/platform/x86/silead_dmi.c:84:33: error: storage size of > 'chuwi_vi10_data' isn't known > static const struct ts_dmi_data chuwi_vi10_data = { > ^~~ > > Caused by commit > > 2da502a0aea7 ("platform/x86: silead_dmi: Add touchscreen info for the Chuwi > Vi10 tablet") > > I have reverted that commit for today. More care please. Thank you Stephen. We caught this earlier, but failed to remove it from for-next while repairing the series. Our apologies. I have removed this series back to the known good patch in for-next: 26ed9d1 platform/x86: silead_dmi: Add entry for Chuwi Hi8 tablet touchscreen Andy has this reworked already and is working on completing testing before pushing the update to for-next. -- Darren Hart VMware Open Source Technology Center
Re: linux-next: build failure after merge of the drivers-x86 tree
On Tue, Jun 12, 2018 at 11:23:10AM +1000, Stephen Rothwell wrote: > Hi all, > > After merging the drivers-x86 tree, today's linux-next build (x86_64 > allmodconfig) failed like this: > > drivers/platform/x86/silead_dmi.c:84:21: error: variable 'chuwi_vi10_data' > has initializer but incomplete type > static const struct ts_dmi_data chuwi_vi10_data = { > ^~~ > drivers/platform/x86/silead_dmi.c:85:3: error: 'const struct ts_dmi_data' has > no member named 'acpi_name' > .acpi_name = "MSSL0002:00", >^ > drivers/platform/x86/silead_dmi.c:85:20: warning: excess elements in struct > initializer > .acpi_name = "MSSL0002:00", > ^ > drivers/platform/x86/silead_dmi.c:85:20: note: (near initialization for > 'chuwi_vi10_data') > drivers/platform/x86/silead_dmi.c:86:3: error: 'const struct ts_dmi_data' has > no member named 'properties' > .properties = chuwi_vi10_props, >^~ > drivers/platform/x86/silead_dmi.c:86:20: warning: excess elements in struct > initializer > .properties = chuwi_vi10_props, > ^~~~ > drivers/platform/x86/silead_dmi.c:86:20: note: (near initialization for > 'chuwi_vi10_data') > drivers/platform/x86/silead_dmi.c:84:33: error: storage size of > 'chuwi_vi10_data' isn't known > static const struct ts_dmi_data chuwi_vi10_data = { > ^~~ > > Caused by commit > > 2da502a0aea7 ("platform/x86: silead_dmi: Add touchscreen info for the Chuwi > Vi10 tablet") > > I have reverted that commit for today. More care please. Thank you Stephen. We caught this earlier, but failed to remove it from for-next while repairing the series. Our apologies. I have removed this series back to the known good patch in for-next: 26ed9d1 platform/x86: silead_dmi: Add entry for Chuwi Hi8 tablet touchscreen Andy has this reworked already and is working on completing testing before pushing the update to for-next. -- Darren Hart VMware Open Source Technology Center
[PATCH v2 2/2] ALSA: hda: add dock and led support for HP ProBook 640 G4
This patch adds missing initialisation for HP 2013 UltraSlim Dock Line-In/Out PINs and activates keyboard mute/micmute leds for HP ProBook 640 G4 Signed-off-by: Dennis Wassenberg --- sound/pci/hda/patch_conexant.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index bca71f35b34f..ff0c52e98977 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -959,6 +959,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = { SND_PCI_QUIRK(0x103c, 0x807C, "HP EliteBook 820 G3", CXT_FIXUP_HP_DOCK), SND_PCI_QUIRK(0x103c, 0x80FD, "HP ProBook 640 G2", CXT_FIXUP_HP_DOCK), SND_PCI_QUIRK(0x103c, 0x83b3, "HP EliteBook 830 G5", CXT_FIXUP_HP_DOCK), + SND_PCI_QUIRK(0x103c, 0x83d3, "HP ProBook 640 G4", CXT_FIXUP_HP_DOCK), SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE), SND_PCI_QUIRK(0x103c, 0x8115, "HP Z1 Gen3", CXT_FIXUP_HP_GATE_MIC), SND_PCI_QUIRK(0x103c, 0x814f, "HP ZBook 15u G3", CXT_FIXUP_MUTE_LED_GPIO), -- 2.17.1
[PATCH v2 2/2] ALSA: hda: add dock and led support for HP ProBook 640 G4
This patch adds missing initialisation for HP 2013 UltraSlim Dock Line-In/Out PINs and activates keyboard mute/micmute leds for HP ProBook 640 G4 Signed-off-by: Dennis Wassenberg --- sound/pci/hda/patch_conexant.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index bca71f35b34f..ff0c52e98977 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -959,6 +959,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = { SND_PCI_QUIRK(0x103c, 0x807C, "HP EliteBook 820 G3", CXT_FIXUP_HP_DOCK), SND_PCI_QUIRK(0x103c, 0x80FD, "HP ProBook 640 G2", CXT_FIXUP_HP_DOCK), SND_PCI_QUIRK(0x103c, 0x83b3, "HP EliteBook 830 G5", CXT_FIXUP_HP_DOCK), + SND_PCI_QUIRK(0x103c, 0x83d3, "HP ProBook 640 G4", CXT_FIXUP_HP_DOCK), SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE), SND_PCI_QUIRK(0x103c, 0x8115, "HP Z1 Gen3", CXT_FIXUP_HP_GATE_MIC), SND_PCI_QUIRK(0x103c, 0x814f, "HP ZBook 15u G3", CXT_FIXUP_MUTE_LED_GPIO), -- 2.17.1
[PATCH v2 1/2] ALSA: hda: add dock and led support for HP EliteBook 830 G5
This patch adds missing initialisation for HP 2013 UltraSlim Dock Line-In/Out PINs and activates keyboard mute/micmute leds for HP EliteBook 830 G5 Signed-off-by: Dennis Wassenberg --- sound/pci/hda/patch_conexant.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 5b4dbcec6de8..bca71f35b34f 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -958,6 +958,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = { SND_PCI_QUIRK(0x103c, 0x8079, "HP EliteBook 840 G3", CXT_FIXUP_HP_DOCK), SND_PCI_QUIRK(0x103c, 0x807C, "HP EliteBook 820 G3", CXT_FIXUP_HP_DOCK), SND_PCI_QUIRK(0x103c, 0x80FD, "HP ProBook 640 G2", CXT_FIXUP_HP_DOCK), + SND_PCI_QUIRK(0x103c, 0x83b3, "HP EliteBook 830 G5", CXT_FIXUP_HP_DOCK), SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE), SND_PCI_QUIRK(0x103c, 0x8115, "HP Z1 Gen3", CXT_FIXUP_HP_GATE_MIC), SND_PCI_QUIRK(0x103c, 0x814f, "HP ZBook 15u G3", CXT_FIXUP_MUTE_LED_GPIO), -- 2.17.1
[PATCH v2 1/2] ALSA: hda: add dock and led support for HP EliteBook 830 G5
This patch adds missing initialisation for HP 2013 UltraSlim Dock Line-In/Out PINs and activates keyboard mute/micmute leds for HP EliteBook 830 G5 Signed-off-by: Dennis Wassenberg --- sound/pci/hda/patch_conexant.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 5b4dbcec6de8..bca71f35b34f 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -958,6 +958,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = { SND_PCI_QUIRK(0x103c, 0x8079, "HP EliteBook 840 G3", CXT_FIXUP_HP_DOCK), SND_PCI_QUIRK(0x103c, 0x807C, "HP EliteBook 820 G3", CXT_FIXUP_HP_DOCK), SND_PCI_QUIRK(0x103c, 0x80FD, "HP ProBook 640 G2", CXT_FIXUP_HP_DOCK), + SND_PCI_QUIRK(0x103c, 0x83b3, "HP EliteBook 830 G5", CXT_FIXUP_HP_DOCK), SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE), SND_PCI_QUIRK(0x103c, 0x8115, "HP Z1 Gen3", CXT_FIXUP_HP_GATE_MIC), SND_PCI_QUIRK(0x103c, 0x814f, "HP ZBook 15u G3", CXT_FIXUP_MUTE_LED_GPIO), -- 2.17.1
Re: [PATCH] proc: add error handling for kmem_cache_create
On Tue, Jun 12, 2018 at 12:23:52PM +0800, Zhouyang Jia wrote: > When kmem_cache_create fails, the lack of error-handling code may > cause unexpected results. > > This patch adds error-handling code after calling kmem_cache_create. > pde_opener_cache = > kmem_cache_create("pde_opener", sizeof(struct pde_opener), 0, > SLAB_ACCOUNT|SLAB_PANIC, NULL); > + if (!proc_inode_cachep || !pde_opener_cache) > + return -ENOMEM; SLAB_PANIC was added to not worry about error handling.
Re: [PATCH] proc: add error handling for kmem_cache_create
On Tue, Jun 12, 2018 at 12:23:52PM +0800, Zhouyang Jia wrote: > When kmem_cache_create fails, the lack of error-handling code may > cause unexpected results. > > This patch adds error-handling code after calling kmem_cache_create. > pde_opener_cache = > kmem_cache_create("pde_opener", sizeof(struct pde_opener), 0, > SLAB_ACCOUNT|SLAB_PANIC, NULL); > + if (!proc_inode_cachep || !pde_opener_cache) > + return -ENOMEM; SLAB_PANIC was added to not worry about error handling.
Re: [PATCH 2/2] IB/mad: Use IDR for agent IDs
On Mon, 11 Jun 2018 10:19:18 -0600 Jason Gunthorpe wrote: > On Mon, Jun 11, 2018 at 09:19:14AM +0300, jackm wrote: > > On Sun, 10 Jun 2018 22:42:03 -0600 > > Jason Gunthorpe wrote: > > > > > Er, the spec has nothing to do with this. In Linux the TID is made > > > unique because the core code provides 32 bits that are unique and > > > the user provides another 32 bits that are unique. The driver > > > cannot change any of those bits without risking non-uniquenes, > > > which is exactly the bug mlx4 created when it stepped outside its > > > bounds and improperly overrode bits in the TID for its own > > > internal use. > > > > Actually, the opposite is true here. When SRIOV is active, each VM > > generates its *own* TIDs -- with 32 bits of agent number and 32 bits > > of counter. > > And it does it while re-using the LRH of the host, so all VMs and the > host are now forced to share a TID space, yes I know. > > > There is a chance that two different VMs can generate the same TID! > > Encoding the slave (VM) number in the packet actually guarantees > > uniqueness here. > > Virtualizing the TID in the driver would be fine, but it must > virtualize all the TIDs (even those generated by the HOST). It DOES do so. The host slave id is 0. Slave numbers start with 1. If the MS byte contains a zero after paravirtualization, the MAD was sent by the host. In fact, ALL mads are paravirtualized -- including those to/from the host. > > Just blindly assuming the host doesn't generate TID's that overlap > with the virtualization process is a bug. > Not the case, host mads are also paravirtualized. > > There is nothing wrong with modifying the TID in a reversible way in > > order to: a. guarantee uniqueness b. identify the VM which should > > receive the response packet > > Sure, as long as *all* TID's sharing a LRH are vitalized like this. > > > The problem was created when the agent-id numbers started to use the > > most-significant byte (thus making the MSB slave-id addition > > impossible). > > It hasn't always been this way? What commit? > Commit: 37bfc7c1e83f1 ("IB/mlx4: SR-IOV multiplex and demultiplex MADs"): Code snippet which replaces the MS byte is below (file drivers/infiniband/hw/mlx4/mad.c, procedure mlx4_ib_multiplex_mad() ). Just an aside: Oracle noted the problem on the *host*: The host's message log contained the warning issued on line 1529, with slave=0 (which is the hypervisor). 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1519) switch (tunnel->mad.mad_hdr.method) { 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1520) case IB_MGMT_METHOD_SET: 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1521) case IB_MGMT_METHOD_GET: 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1522) case IB_MGMT_METHOD_REPORT: 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1523) case IB_SA_METHOD_GET_TABLE: 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1524) case IB_SA_METHOD_DELETE: 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1525) case IB_SA_METHOD_GET_MULTI: 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1526) case IB_SA_METHOD_GET_TRACE_TBL: 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1527) slave_id = (u8 *) >mad.mad_hdr.tid; 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1528) if (*slave_id) { 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1529) mlx4_ib_warn(ctx->ib_dev, "egress mad has non-null tid msb:%d " 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1530) "class:%d slave:%d\n", *slave_id, 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1531) tunnel->mad.mad_hdr.mgmt_class, slave); 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1532) return; 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1533) } else 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1534) *slave_id = slave; 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1535) default: 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1536) /* nothing */; 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1537) } > Jason
Re: [PATCH 2/2] IB/mad: Use IDR for agent IDs
On Mon, 11 Jun 2018 10:19:18 -0600 Jason Gunthorpe wrote: > On Mon, Jun 11, 2018 at 09:19:14AM +0300, jackm wrote: > > On Sun, 10 Jun 2018 22:42:03 -0600 > > Jason Gunthorpe wrote: > > > > > Er, the spec has nothing to do with this. In Linux the TID is made > > > unique because the core code provides 32 bits that are unique and > > > the user provides another 32 bits that are unique. The driver > > > cannot change any of those bits without risking non-uniquenes, > > > which is exactly the bug mlx4 created when it stepped outside its > > > bounds and improperly overrode bits in the TID for its own > > > internal use. > > > > Actually, the opposite is true here. When SRIOV is active, each VM > > generates its *own* TIDs -- with 32 bits of agent number and 32 bits > > of counter. > > And it does it while re-using the LRH of the host, so all VMs and the > host are now forced to share a TID space, yes I know. > > > There is a chance that two different VMs can generate the same TID! > > Encoding the slave (VM) number in the packet actually guarantees > > uniqueness here. > > Virtualizing the TID in the driver would be fine, but it must > virtualize all the TIDs (even those generated by the HOST). It DOES do so. The host slave id is 0. Slave numbers start with 1. If the MS byte contains a zero after paravirtualization, the MAD was sent by the host. In fact, ALL mads are paravirtualized -- including those to/from the host. > > Just blindly assuming the host doesn't generate TID's that overlap > with the virtualization process is a bug. > Not the case, host mads are also paravirtualized. > > There is nothing wrong with modifying the TID in a reversible way in > > order to: a. guarantee uniqueness b. identify the VM which should > > receive the response packet > > Sure, as long as *all* TID's sharing a LRH are vitalized like this. > > > The problem was created when the agent-id numbers started to use the > > most-significant byte (thus making the MSB slave-id addition > > impossible). > > It hasn't always been this way? What commit? > Commit: 37bfc7c1e83f1 ("IB/mlx4: SR-IOV multiplex and demultiplex MADs"): Code snippet which replaces the MS byte is below (file drivers/infiniband/hw/mlx4/mad.c, procedure mlx4_ib_multiplex_mad() ). Just an aside: Oracle noted the problem on the *host*: The host's message log contained the warning issued on line 1529, with slave=0 (which is the hypervisor). 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1519) switch (tunnel->mad.mad_hdr.method) { 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1520) case IB_MGMT_METHOD_SET: 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1521) case IB_MGMT_METHOD_GET: 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1522) case IB_MGMT_METHOD_REPORT: 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1523) case IB_SA_METHOD_GET_TABLE: 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1524) case IB_SA_METHOD_DELETE: 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1525) case IB_SA_METHOD_GET_MULTI: 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1526) case IB_SA_METHOD_GET_TRACE_TBL: 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1527) slave_id = (u8 *) >mad.mad_hdr.tid; 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1528) if (*slave_id) { 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1529) mlx4_ib_warn(ctx->ib_dev, "egress mad has non-null tid msb:%d " 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1530) "class:%d slave:%d\n", *slave_id, 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1531) tunnel->mad.mad_hdr.mgmt_class, slave); 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1532) return; 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1533) } else 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1534) *slave_id = slave; 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1535) default: 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1536) /* nothing */; 37bfc7c1e (Jack Morgenstein2012-08-03 08:40:44 + 1537) } > Jason
Re: [PATCH 2/2] arm64: dts: qcom: sdm845: Enable debug UART and I2C10 on sdm845-mtp
On Thu 07 Jun 13:46 PDT 2018, Douglas Anderson wrote: > The debug UART is very useful to have. I2C10 is enabled as an example > of a I2C port we can talk on for now. Eventually we'll want to put > peripherals under it. > > Signed-off-by: Douglas Anderson Reviewed-by: Bjorn Andersson Tested-by: Bjorn Andersson Regards, Bjorn > --- > > arch/arm64/boot/dts/qcom/sdm845-mtp.dts | 52 + > 1 file changed, 52 insertions(+) > > diff --git a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts > b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts > index 979ab49913f1..e1eda143a725 100644 > --- a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts > +++ b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts > @@ -12,4 +12,56 @@ > / { > model = "Qualcomm Technologies, Inc. SDM845 MTP"; > compatible = "qcom,sdm845-mtp"; > + > + aliases { > + serial0 = > + }; > + > + chosen { > + stdout-path = "serial0:115200n8"; > + }; > +}; > + > + { > + status = "okay"; > + clock-frequency = <40>; > +}; > + > +_id_1 { > + status = "okay"; > +}; > + > + { > + status = "okay"; > +}; > + > +/* PINCTRL - additions to nodes defined in sdm845.dtsi */ > + > +_i2c10_default { > + pinconf { > + pins = "gpio55", "gpio56"; > + drive-strength = <2>; > + bias-disable; > + }; > +}; > + > +_uart9_default { > + pinconf-tx { > + pins = "gpio4"; > + drive-strength = <2>; > + bias-disable; > + }; > + > + pinconf-rx { > + pins = "gpio5"; > + drive-strength = <2>; > + bias-pull-up; > + }; > +}; > + > +_uart9_sleep { > + pinconf { > + pins = "gpio4", "gpio5"; > + bias-pull-down; > + }; > }; > -- > 2.17.1.1185.g55be947832-goog >
Re: [PATCH 1/2] arm64: dts: qcom: sdm845: Add I2C, SPI, and UART9 nodes
On Thu 07 Jun 13:46 PDT 2018, Douglas Anderson wrote: > This adds nodes to SDM845-dtsi for all the I2C ports, all the SPI > ports, and UART9. Note that I2C / SPI / UART are a bit strange on > sdm845 because each "serial engine" has 4 pins associated with it and > depending on which firmware has been loaded into the serial engine > (loaded by the BIOS) the serial engine can behave like an I2C port, a > SPI port, or a UART. As per the landed bindings that means that we > need to create one node for each possible mode that the port could be > in. With 16 serial engines that means 16 x 3 = 48 nodes. > > We get away with only creating 33 nodes for now because it seems very > likely that SDM845-based boards will actually all use the same UART > (UART 9) for debug purposes. While another UART could be used for > something like Bluetooth communication we can cross that path when we > come to it. Some documentation that I saw implied that using a UART > for "high speed" communications actually needs yet another different > serial engine firmware anyway. > > Note that quick measurements adding all these nodes adds ~10k of extra > space per dtb that they're included with. If this becomes a problem > we may need to think of a different way to structure this so that > boards only get the nodes they need (or figure out how to get dtc to > strip 'disabled' nodes). For now it seems OK. > > These nodes were programmatically generated with a fairly dumb python > script. See http://crosreview.com/1091631 for the source. > > Signed-off-by: Douglas Anderson Reviewed-by: Bjorn Andersson Regards, Bjorn > --- > > arch/arm64/boot/dts/qcom/sdm845.dtsi | 1013 ++ > 1 file changed, 1013 insertions(+) > > diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi > b/arch/arm64/boot/dts/qcom/sdm845.dtsi > index cdaabeb3c995..2dc5c7dcc9aa 100644 > --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi > +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi > @@ -5,6 +5,7 @@ > * Copyright (c) 2018, The Linux Foundation. All rights reserved. > */ > > +#include > #include > > / { > @@ -13,6 +14,41 @@ > #address-cells = <2>; > #size-cells = <2>; > > + aliases { > + i2c0 = > + i2c1 = > + i2c2 = > + i2c3 = > + i2c4 = > + i2c5 = > + i2c6 = > + i2c7 = > + i2c8 = > + i2c9 = > + i2c10 = > + i2c11 = > + i2c12 = > + i2c13 = > + i2c14 = > + i2c15 = > + spi0 = > + spi1 = > + spi2 = > + spi3 = > + spi4 = > + spi5 = > + spi6 = > + spi7 = > + spi8 = > + spi9 = > + spi10 = > + spi11 = > + spi12 = > + spi13 = > + spi14 = > + spi15 = > + }; > + > chosen { }; > > memory@8000 { > @@ -206,6 +242,489 @@ > #power-domain-cells = <1>; > }; > > + qupv3_id_0: geniqup@8c { > + compatible = "qcom,geni-se-qup"; > + reg = <0x8c 0x6000>; > + clock-names = "m-ahb", "s-ahb"; > + clocks = < GCC_QUPV3_WRAP_0_M_AHB_CLK>, > + < GCC_QUPV3_WRAP_0_S_AHB_CLK>; > + #address-cells = <1>; > + #size-cells = <1>; > + ranges; > + > + i2c0: i2c@88 { > + compatible = "qcom,geni-i2c"; > + reg = <0x88 0x4000>; > + clock-names = "se"; > + clocks = < GCC_QUPV3_WRAP0_S0_CLK>; > + pinctrl-names = "default", "sleep"; > + pinctrl-0 = <_i2c0_default>; > + pinctrl-1 = <_i2c0_sleep>; > + interrupts = ; > + #address-cells = <1>; > + #size-cells = <0>; > + status = "disabled"; > + }; > + > + spi0: spi@88 { > + compatible = "qcom,geni-spi"; > + reg = <0x88 0x4000>; > + clock-names = "se"; > + clocks = < GCC_QUPV3_WRAP0_S0_CLK>; > + pinctrl-names = "default", "sleep"; > + pinctrl-0 = <_spi0_default>; > + pinctrl-1 = <_spi0_sleep>; > + interrupts = ; > + #address-cells = <1>; > + #size-cells = <0>; > + status = "disabled"; > +
Re: [PATCH 2/2] arm64: dts: qcom: sdm845: Enable debug UART and I2C10 on sdm845-mtp
On Thu 07 Jun 13:46 PDT 2018, Douglas Anderson wrote: > The debug UART is very useful to have. I2C10 is enabled as an example > of a I2C port we can talk on for now. Eventually we'll want to put > peripherals under it. > > Signed-off-by: Douglas Anderson Reviewed-by: Bjorn Andersson Tested-by: Bjorn Andersson Regards, Bjorn > --- > > arch/arm64/boot/dts/qcom/sdm845-mtp.dts | 52 + > 1 file changed, 52 insertions(+) > > diff --git a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts > b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts > index 979ab49913f1..e1eda143a725 100644 > --- a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts > +++ b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts > @@ -12,4 +12,56 @@ > / { > model = "Qualcomm Technologies, Inc. SDM845 MTP"; > compatible = "qcom,sdm845-mtp"; > + > + aliases { > + serial0 = > + }; > + > + chosen { > + stdout-path = "serial0:115200n8"; > + }; > +}; > + > + { > + status = "okay"; > + clock-frequency = <40>; > +}; > + > +_id_1 { > + status = "okay"; > +}; > + > + { > + status = "okay"; > +}; > + > +/* PINCTRL - additions to nodes defined in sdm845.dtsi */ > + > +_i2c10_default { > + pinconf { > + pins = "gpio55", "gpio56"; > + drive-strength = <2>; > + bias-disable; > + }; > +}; > + > +_uart9_default { > + pinconf-tx { > + pins = "gpio4"; > + drive-strength = <2>; > + bias-disable; > + }; > + > + pinconf-rx { > + pins = "gpio5"; > + drive-strength = <2>; > + bias-pull-up; > + }; > +}; > + > +_uart9_sleep { > + pinconf { > + pins = "gpio4", "gpio5"; > + bias-pull-down; > + }; > }; > -- > 2.17.1.1185.g55be947832-goog >
Re: [PATCH 1/2] arm64: dts: qcom: sdm845: Add I2C, SPI, and UART9 nodes
On Thu 07 Jun 13:46 PDT 2018, Douglas Anderson wrote: > This adds nodes to SDM845-dtsi for all the I2C ports, all the SPI > ports, and UART9. Note that I2C / SPI / UART are a bit strange on > sdm845 because each "serial engine" has 4 pins associated with it and > depending on which firmware has been loaded into the serial engine > (loaded by the BIOS) the serial engine can behave like an I2C port, a > SPI port, or a UART. As per the landed bindings that means that we > need to create one node for each possible mode that the port could be > in. With 16 serial engines that means 16 x 3 = 48 nodes. > > We get away with only creating 33 nodes for now because it seems very > likely that SDM845-based boards will actually all use the same UART > (UART 9) for debug purposes. While another UART could be used for > something like Bluetooth communication we can cross that path when we > come to it. Some documentation that I saw implied that using a UART > for "high speed" communications actually needs yet another different > serial engine firmware anyway. > > Note that quick measurements adding all these nodes adds ~10k of extra > space per dtb that they're included with. If this becomes a problem > we may need to think of a different way to structure this so that > boards only get the nodes they need (or figure out how to get dtc to > strip 'disabled' nodes). For now it seems OK. > > These nodes were programmatically generated with a fairly dumb python > script. See http://crosreview.com/1091631 for the source. > > Signed-off-by: Douglas Anderson Reviewed-by: Bjorn Andersson Regards, Bjorn > --- > > arch/arm64/boot/dts/qcom/sdm845.dtsi | 1013 ++ > 1 file changed, 1013 insertions(+) > > diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi > b/arch/arm64/boot/dts/qcom/sdm845.dtsi > index cdaabeb3c995..2dc5c7dcc9aa 100644 > --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi > +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi > @@ -5,6 +5,7 @@ > * Copyright (c) 2018, The Linux Foundation. All rights reserved. > */ > > +#include > #include > > / { > @@ -13,6 +14,41 @@ > #address-cells = <2>; > #size-cells = <2>; > > + aliases { > + i2c0 = > + i2c1 = > + i2c2 = > + i2c3 = > + i2c4 = > + i2c5 = > + i2c6 = > + i2c7 = > + i2c8 = > + i2c9 = > + i2c10 = > + i2c11 = > + i2c12 = > + i2c13 = > + i2c14 = > + i2c15 = > + spi0 = > + spi1 = > + spi2 = > + spi3 = > + spi4 = > + spi5 = > + spi6 = > + spi7 = > + spi8 = > + spi9 = > + spi10 = > + spi11 = > + spi12 = > + spi13 = > + spi14 = > + spi15 = > + }; > + > chosen { }; > > memory@8000 { > @@ -206,6 +242,489 @@ > #power-domain-cells = <1>; > }; > > + qupv3_id_0: geniqup@8c { > + compatible = "qcom,geni-se-qup"; > + reg = <0x8c 0x6000>; > + clock-names = "m-ahb", "s-ahb"; > + clocks = < GCC_QUPV3_WRAP_0_M_AHB_CLK>, > + < GCC_QUPV3_WRAP_0_S_AHB_CLK>; > + #address-cells = <1>; > + #size-cells = <1>; > + ranges; > + > + i2c0: i2c@88 { > + compatible = "qcom,geni-i2c"; > + reg = <0x88 0x4000>; > + clock-names = "se"; > + clocks = < GCC_QUPV3_WRAP0_S0_CLK>; > + pinctrl-names = "default", "sleep"; > + pinctrl-0 = <_i2c0_default>; > + pinctrl-1 = <_i2c0_sleep>; > + interrupts = ; > + #address-cells = <1>; > + #size-cells = <0>; > + status = "disabled"; > + }; > + > + spi0: spi@88 { > + compatible = "qcom,geni-spi"; > + reg = <0x88 0x4000>; > + clock-names = "se"; > + clocks = < GCC_QUPV3_WRAP0_S0_CLK>; > + pinctrl-names = "default", "sleep"; > + pinctrl-0 = <_spi0_default>; > + pinctrl-1 = <_spi0_sleep>; > + interrupts = ; > + #address-cells = <1>; > + #size-cells = <0>; > + status = "disabled"; > +
Re: [intel-sgx-kernel-dev] [PATCH v11 13/13] intel_sgx: in-kernel launch enclave
On Mon, Jun 11, 2018 at 4:52 AM Neil Horman wrote: > > On Sun, Jun 10, 2018 at 10:17:13PM -0700, Andy Lutomirski wrote: > > > On Jun 9, 2018, at 10:39 PM, Andy Lutomirski wrote: > > > > > > On Fri, Jun 8, 2018 at 10:32 AM Jarkko Sakkinen > > > wrote: > > >> > > >> The Launch Enclave (LE) generates cryptographic launch tokens for user > > >> enclaves. A launch token is used by EINIT to check whether the enclave > > >> is authorized to launch or not. By having its own launch enclave, Linux > > >> has full control of the enclave launch process. > > >> > > >> LE is wrapped into a user space proxy program that reads enclave > > >> signatures outputs launch tokens. The kernel-side glue code is > > >> implemented by using the user space helper framework. The IPC between > > >> the LE proxy program and kernel is handled with an anonymous inode. > > >> > > >> The commit also adds enclave signing tool that is used by kbuild to > > >> measure and sign the launch enclave. CONFIG_INTEL_SGX_SIGNING_KEY points > > >> to a PEM-file for the 3072-bit RSA key that is used as the LE public key > > >> pair. The default location is: > > >> > > >> drivers/platform/x86/intel_sgx/sgx_signing_key.pem > > >> > > >> If the default key does not exist kbuild will generate a random key and > > >> place it to this location. KBUILD_SGX_SIGN_PIN can be used to specify > > >> the passphrase for the LE public key. > > > > > > It seems to me that it might be more useful to just commit a key pair > > > into the kernel. As far as I know, there is no security whatsoever > > > gained by keeping the private key private, so why not make > > > reproducible builds easier by simply fixing the key? > > > > Having thought about this some more, I think that you should > > completely remove support for specifying a key. Provide a fixed key > > pair, hard code the cache, and call it a day. If you make the key > > configurable, every vendor that has any vendor keys (Debian, Ubuntu, > > Fedora, Red Hat, SuSE, Clear Linux, etc) will see that config option > > and set up their own key pair for no gain whatsoever. Instead, it'll > > give some illusion of security and it'll slow down operations in a VM > > guest due to swapping out the values of the MSRs. And, if the code to > > support a locked MSR that just happens to have the right value stays > > in the kernel, then we'll risk having vendors actually ship one > > distro's public key hash, and that will seriously suck. > > > If you hard code the key pair however, doesn't that imply that anyone can > sign a > user space binary as a launch enclave, and potentially gain control of the > token > granting process? Yes and no. First of all, the kernel driver shouldn't be allowing user code to launch a launch enclave regardless of signature. I haven't gotten far enough in reviewing the code to see whether that's the case, but if it's not, it should be fixed before it's merged. But keep in mind that control of the token granting process is not the same thing as control over the right to launch an enclave. On systems without the LE hash MSRs, Intel controls the token granting process and, barring some attack, an enclave that isn't blessed by Intel can't be launched. Support for that model will not be merged into upstream Linux. But on systems that have the LE hash MSRs and leave them unlocked, there is effectively no hardware-enforced launch control. Instead we have good old kernel policy. If a user wants to launch an enclave, they need to get the kernel to launch the enclave, and the kernel needs to apply its policy. The patch here (the in-kernel launch enclave) has a wide-open policy. So, as a practical matter, if every distro has their own LE key and keeps it totally safe, then a system that locks the MSRs to one distro's key makes it quite annoying to run another distro's intel_sgx driver, but there is no effect on the actual security of the system. > It was my understanding that the value of the key pair was > that the end user was guaranteed autonomy and security over which processes > could start enclaves. By publishing a fixed key pair, it seems to remove that > ability. If someone comes up with an actual machine that grants the actual end user (where the end user is the person who bought the thing, not the OEM) control over the MSRs, *and* the actual end user wants to limit what enclaves can be launched even if the kernel is compromised, *and* there is some actual argument for why this is useful (as opposed to some compliance checkbox), then Linux could reasonably consider adding support for this use case. But that would be a separate patch. > > What would be nicer (I think) would be the abilty to specify both the public > and > the private key at run time. the use case here is not one in which a vendor > or > os distribution ships a key pair, but one in which a downstream user doesn't > want a vendor/os distribution to have any cryptographic information installed > on > their
Re: [intel-sgx-kernel-dev] [PATCH v11 13/13] intel_sgx: in-kernel launch enclave
On Mon, Jun 11, 2018 at 4:52 AM Neil Horman wrote: > > On Sun, Jun 10, 2018 at 10:17:13PM -0700, Andy Lutomirski wrote: > > > On Jun 9, 2018, at 10:39 PM, Andy Lutomirski wrote: > > > > > > On Fri, Jun 8, 2018 at 10:32 AM Jarkko Sakkinen > > > wrote: > > >> > > >> The Launch Enclave (LE) generates cryptographic launch tokens for user > > >> enclaves. A launch token is used by EINIT to check whether the enclave > > >> is authorized to launch or not. By having its own launch enclave, Linux > > >> has full control of the enclave launch process. > > >> > > >> LE is wrapped into a user space proxy program that reads enclave > > >> signatures outputs launch tokens. The kernel-side glue code is > > >> implemented by using the user space helper framework. The IPC between > > >> the LE proxy program and kernel is handled with an anonymous inode. > > >> > > >> The commit also adds enclave signing tool that is used by kbuild to > > >> measure and sign the launch enclave. CONFIG_INTEL_SGX_SIGNING_KEY points > > >> to a PEM-file for the 3072-bit RSA key that is used as the LE public key > > >> pair. The default location is: > > >> > > >> drivers/platform/x86/intel_sgx/sgx_signing_key.pem > > >> > > >> If the default key does not exist kbuild will generate a random key and > > >> place it to this location. KBUILD_SGX_SIGN_PIN can be used to specify > > >> the passphrase for the LE public key. > > > > > > It seems to me that it might be more useful to just commit a key pair > > > into the kernel. As far as I know, there is no security whatsoever > > > gained by keeping the private key private, so why not make > > > reproducible builds easier by simply fixing the key? > > > > Having thought about this some more, I think that you should > > completely remove support for specifying a key. Provide a fixed key > > pair, hard code the cache, and call it a day. If you make the key > > configurable, every vendor that has any vendor keys (Debian, Ubuntu, > > Fedora, Red Hat, SuSE, Clear Linux, etc) will see that config option > > and set up their own key pair for no gain whatsoever. Instead, it'll > > give some illusion of security and it'll slow down operations in a VM > > guest due to swapping out the values of the MSRs. And, if the code to > > support a locked MSR that just happens to have the right value stays > > in the kernel, then we'll risk having vendors actually ship one > > distro's public key hash, and that will seriously suck. > > > If you hard code the key pair however, doesn't that imply that anyone can > sign a > user space binary as a launch enclave, and potentially gain control of the > token > granting process? Yes and no. First of all, the kernel driver shouldn't be allowing user code to launch a launch enclave regardless of signature. I haven't gotten far enough in reviewing the code to see whether that's the case, but if it's not, it should be fixed before it's merged. But keep in mind that control of the token granting process is not the same thing as control over the right to launch an enclave. On systems without the LE hash MSRs, Intel controls the token granting process and, barring some attack, an enclave that isn't blessed by Intel can't be launched. Support for that model will not be merged into upstream Linux. But on systems that have the LE hash MSRs and leave them unlocked, there is effectively no hardware-enforced launch control. Instead we have good old kernel policy. If a user wants to launch an enclave, they need to get the kernel to launch the enclave, and the kernel needs to apply its policy. The patch here (the in-kernel launch enclave) has a wide-open policy. So, as a practical matter, if every distro has their own LE key and keeps it totally safe, then a system that locks the MSRs to one distro's key makes it quite annoying to run another distro's intel_sgx driver, but there is no effect on the actual security of the system. > It was my understanding that the value of the key pair was > that the end user was guaranteed autonomy and security over which processes > could start enclaves. By publishing a fixed key pair, it seems to remove that > ability. If someone comes up with an actual machine that grants the actual end user (where the end user is the person who bought the thing, not the OEM) control over the MSRs, *and* the actual end user wants to limit what enclaves can be launched even if the kernel is compromised, *and* there is some actual argument for why this is useful (as opposed to some compliance checkbox), then Linux could reasonably consider adding support for this use case. But that would be a separate patch. > > What would be nicer (I think) would be the abilty to specify both the public > and > the private key at run time. the use case here is not one in which a vendor > or > os distribution ships a key pair, but one in which a downstream user doesn't > want a vendor/os distribution to have any cryptographic information installed > on > their
Re: [PATCH 2/2] fs/lock: show locks taken by processes from another pidns
On Fri, Jun 08, 2018 at 05:27:12PM +0300, Konstantin Khorenko wrote: > Currently if we face a lock taken by a process invisible in the current > pidns we skip the lock completely, but this > > 1) makes the output not that nice > (root@vz7)/: cat /proc/${PID_A2}/fdinfo/3 > pos:4 > flags: 0212 > mnt_id: 257 > lock: (root@vz7)/: > > 2) makes it more difficult to debug issues with leaked flocks >if you get error on lock, but don't see any locks in /proc/$id/fdinfo/$file 3) breaks the CRIU project. criu reads fdinfo to dump file locks. > > Let's show information about such locks again as previously, but > show zero in the owner pid field. > > After the patch: > === > (root@vz7)/:cat /proc/${PID_A2}/fdinfo/3 > pos:4 > flags: 0212 > mnt_id: 295 > lock: 1: FLOCK ADVISORY WRITE 0 b6:f8a61:529946 0 EOF > I think initially this was broken in this commit: Fixes: d67fd44f697d ("locks: Filter /proc/locks output on proc pid ns") Acked-by: Andrei Vagin Thanks, Andrei > Fixes: 9d5b86ac13c5 ("fs/locks: Remove fl_nspid and use fs-specific l_pid for > remote locks") > Signed-off-by: Konstantin Khorenko > --- > fs/locks.c | 8 +++- > 1 file changed, 3 insertions(+), 5 deletions(-) > > diff --git a/fs/locks.c b/fs/locks.c > index bfee5b7f2862..e533623e2e99 100644 > --- a/fs/locks.c > +++ b/fs/locks.c > @@ -2633,12 +2633,10 @@ static void lock_get_status(struct seq_file *f, > struct file_lock *fl, > > fl_pid = locks_translate_pid(fl, proc_pidns); > /* > - * If there isn't a fl_pid don't display who is waiting on > - * the lock if we are called from locks_show, or if we are > - * called from __show_fd_info - skip lock entirely > + * If lock owner is dead (and pid is freed) or not visible in current > + * pidns, zero is shown as a pid value. Check lock info from > + * init_pid_ns to get saved lock pid value. >*/ > - if (fl_pid == 0) > - return; > > if (fl->fl_file != NULL) > inode = locks_inode(fl->fl_file); > -- > 2.15.1 >
Re: [PATCH 2/2] fs/lock: show locks taken by processes from another pidns
On Fri, Jun 08, 2018 at 05:27:12PM +0300, Konstantin Khorenko wrote: > Currently if we face a lock taken by a process invisible in the current > pidns we skip the lock completely, but this > > 1) makes the output not that nice > (root@vz7)/: cat /proc/${PID_A2}/fdinfo/3 > pos:4 > flags: 0212 > mnt_id: 257 > lock: (root@vz7)/: > > 2) makes it more difficult to debug issues with leaked flocks >if you get error on lock, but don't see any locks in /proc/$id/fdinfo/$file 3) breaks the CRIU project. criu reads fdinfo to dump file locks. > > Let's show information about such locks again as previously, but > show zero in the owner pid field. > > After the patch: > === > (root@vz7)/:cat /proc/${PID_A2}/fdinfo/3 > pos:4 > flags: 0212 > mnt_id: 295 > lock: 1: FLOCK ADVISORY WRITE 0 b6:f8a61:529946 0 EOF > I think initially this was broken in this commit: Fixes: d67fd44f697d ("locks: Filter /proc/locks output on proc pid ns") Acked-by: Andrei Vagin Thanks, Andrei > Fixes: 9d5b86ac13c5 ("fs/locks: Remove fl_nspid and use fs-specific l_pid for > remote locks") > Signed-off-by: Konstantin Khorenko > --- > fs/locks.c | 8 +++- > 1 file changed, 3 insertions(+), 5 deletions(-) > > diff --git a/fs/locks.c b/fs/locks.c > index bfee5b7f2862..e533623e2e99 100644 > --- a/fs/locks.c > +++ b/fs/locks.c > @@ -2633,12 +2633,10 @@ static void lock_get_status(struct seq_file *f, > struct file_lock *fl, > > fl_pid = locks_translate_pid(fl, proc_pidns); > /* > - * If there isn't a fl_pid don't display who is waiting on > - * the lock if we are called from locks_show, or if we are > - * called from __show_fd_info - skip lock entirely > + * If lock owner is dead (and pid is freed) or not visible in current > + * pidns, zero is shown as a pid value. Check lock info from > + * init_pid_ns to get saved lock pid value. >*/ > - if (fl_pid == 0) > - return; > > if (fl->fl_file != NULL) > inode = locks_inode(fl->fl_file); > -- > 2.15.1 >
[PATCH] staging: lustre: add error handling for try_module_get
When try_module_get fails, the lack of error-handling code may cause unexpected results. This patch adds error-handling code after calling try_module_get. Signed-off-by: Zhouyang Jia --- drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c index 7086678..72a42bd 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c @@ -2422,7 +2422,10 @@ ksocknal_base_startup(void) /* flag lists/ptrs/locks initialised */ ksocknal_data.ksnd_init = SOCKNAL_INIT_DATA; - try_module_get(THIS_MODULE); + if (!try_module_get(THIS_MODULE)) { + CERROR("%s: cannot get module\n", __func__); + goto failed; + } ksocknal_data.ksnd_sched_info = cfs_percpt_alloc(lnet_cpt_table(), sizeof(*info)); -- 2.7.4
[PATCH] staging: lustre: add error handling for try_module_get
When try_module_get fails, the lack of error-handling code may cause unexpected results. This patch adds error-handling code after calling try_module_get. Signed-off-by: Zhouyang Jia --- drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c index 7086678..72a42bd 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c @@ -2422,7 +2422,10 @@ ksocknal_base_startup(void) /* flag lists/ptrs/locks initialised */ ksocknal_data.ksnd_init = SOCKNAL_INIT_DATA; - try_module_get(THIS_MODULE); + if (!try_module_get(THIS_MODULE)) { + CERROR("%s: cannot get module\n", __func__); + goto failed; + } ksocknal_data.ksnd_sched_info = cfs_percpt_alloc(lnet_cpt_table(), sizeof(*info)); -- 2.7.4
Re: [PATCH v2 2/2] tpm: add support for nonblocking operation
On 06/11/2018 07:53 PM, kbuild test robot wrote: > Hi Tadeusz, > > Thank you for the patch! Yet something to improve: > > [auto build test ERROR on char-misc/char-misc-testing] > [also build test ERROR on next-20180608] > [cannot apply to v4.17] Hi, Thanks for the report. This patch should go on top of https://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security.git/?h=next-tpm I will check the config tomorrow. Thanks, -- Tadeusz
Re: [PATCH v2 2/2] tpm: add support for nonblocking operation
On 06/11/2018 07:53 PM, kbuild test robot wrote: > Hi Tadeusz, > > Thank you for the patch! Yet something to improve: > > [auto build test ERROR on char-misc/char-misc-testing] > [also build test ERROR on next-20180608] > [cannot apply to v4.17] Hi, Thanks for the report. This patch should go on top of https://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security.git/?h=next-tpm I will check the config tomorrow. Thanks, -- Tadeusz
[PATCH v3 4/7] arm64: dts: msm8996: Add rpmpd device node
Add rpmpd device node and its OPP table Signed-off-by: Rajendra Nayak Signed-off-by: Viresh Kumar --- arch/arm64/boot/dts/qcom/msm8996.dtsi | 34 +++ 1 file changed, 34 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi index 8c7f9ca25b53..404a08630ccd 100644 --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi @@ -308,6 +308,40 @@ #clock-cells = <1>; }; + rpmpd: power-controller { + compatible = "qcom,msm8996-rpmpd"; + #power-domain-cells = <1>; + operating-points-v2 = <_opp_table>; + }; + + rpmpd_opp_table: opp-table { + compatible = "operating-points-v2-qcom-level"; + + rpmpd_opp1: opp1 { + qcom,level = <1>; + }; + + rpmpd_opp2: opp2 { + qcom,level = <2>; + }; + + rpmpd_opp3: opp3 { + qcom,level = <3>; + }; + + rpmpd_opp4: opp4 { + qcom,level = <4>; + }; + + rpmpd_opp5: opp5 { + qcom,level = <5>; + }; + + rpmpd_opp6: opp6 { + qcom,level = <6>; + }; + }; + pm8994-regulators { compatible = "qcom,rpm-pm8994-regulators"; -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH v3 4/7] arm64: dts: msm8996: Add rpmpd device node
Add rpmpd device node and its OPP table Signed-off-by: Rajendra Nayak Signed-off-by: Viresh Kumar --- arch/arm64/boot/dts/qcom/msm8996.dtsi | 34 +++ 1 file changed, 34 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi index 8c7f9ca25b53..404a08630ccd 100644 --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi @@ -308,6 +308,40 @@ #clock-cells = <1>; }; + rpmpd: power-controller { + compatible = "qcom,msm8996-rpmpd"; + #power-domain-cells = <1>; + operating-points-v2 = <_opp_table>; + }; + + rpmpd_opp_table: opp-table { + compatible = "operating-points-v2-qcom-level"; + + rpmpd_opp1: opp1 { + qcom,level = <1>; + }; + + rpmpd_opp2: opp2 { + qcom,level = <2>; + }; + + rpmpd_opp3: opp3 { + qcom,level = <3>; + }; + + rpmpd_opp4: opp4 { + qcom,level = <4>; + }; + + rpmpd_opp5: opp5 { + qcom,level = <5>; + }; + + rpmpd_opp6: opp6 { + qcom,level = <6>; + }; + }; + pm8994-regulators { compatible = "qcom,rpm-pm8994-regulators"; -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH v3 2/7] soc: qcom: rpmpd: Add a Power domain driver to model corners
The Power domains for corners just pass the performance state set by the consumers to the RPM (Remote Power manager) which then takes care of setting the appropriate voltage on the corresponding rails to meet the performance needs. We add all Power domain data needed on msm8996 here. This driver can easily be extended by adding data for other qualcomm SoCs as well. Signed-off-by: Rajendra Nayak Signed-off-by: Viresh Kumar --- drivers/soc/qcom/Kconfig | 9 + drivers/soc/qcom/Makefile | 1 + drivers/soc/qcom/rpmpd.c | 301 + include/dt-bindings/power/qcom-rpmpd.h | 16 ++ 4 files changed, 327 insertions(+) create mode 100644 drivers/soc/qcom/rpmpd.c create mode 100644 include/dt-bindings/power/qcom-rpmpd.h diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index 9dc02f390ba3..5c54931a7b99 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig @@ -74,6 +74,15 @@ config QCOM_RMTFS_MEM Say y here if you intend to boot the modem remoteproc. +config QCOM_RPMPD + tristate "Qualcomm RPM Power domain driver" + depends on MFD_QCOM_RPM && QCOM_SMD_RPM + help + QCOM RPM Power domain driver to support power-domains with + performance states. The driver communicates a performance state + value to RPM which then translates it into corresponding voltage + for the voltage rail. + config QCOM_SMEM tristate "Qualcomm Shared Memory Manager (SMEM)" depends on ARCH_QCOM diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index 19dcf957cb3a..9550c170de93 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -15,3 +15,4 @@ obj-$(CONFIG_QCOM_SMP2P) += smp2p.o obj-$(CONFIG_QCOM_SMSM)+= smsm.o obj-$(CONFIG_QCOM_WCNSS_CTRL) += wcnss_ctrl.o obj-$(CONFIG_QCOM_APR) += apr.o +obj-$(CONFIG_QCOM_RPMPD) += rpmpd.o diff --git a/drivers/soc/qcom/rpmpd.c b/drivers/soc/qcom/rpmpd.c new file mode 100644 index ..c5e7a91f278c --- /dev/null +++ b/drivers/soc/qcom/rpmpd.c @@ -0,0 +1,301 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define domain_to_rpmpd(domain) container_of(domain, struct rpmpd, pd) + +/* Resource types */ +#define RPMPD_SMPA 0x61706d73 +#define RPMPD_LDOA 0x616f646c + +/* Operation Keys */ +#define KEY_CORNER 0x6e726f63 /* corn */ +#define KEY_ENABLE 0x6e657773 /* swen */ +#define KEY_FLOOR_CORNER 0x636676 /* vfc */ + +#define DEFINE_RPMPD_CORN_SMPA(_platform, _name, _active, r_id) \ + static struct rpmpd _platform##_##_active; \ + static struct rpmpd _platform##_##_name = { \ + .pd = { .name = #_name, }, \ + .peer = &_platform##_##_active, \ + .res_type = RPMPD_SMPA, \ + .res_id = r_id, \ + .key = KEY_CORNER, \ + }; \ + static struct rpmpd _platform##_##_active = { \ + .pd = { .name = #_active, },\ + .peer = &_platform##_##_name, \ + .active_only = true,\ + .res_type = RPMPD_SMPA, \ + .res_id = r_id, \ + .key = KEY_CORNER, \ + } + +#define DEFINE_RPMPD_CORN_LDOA(_platform, _name, r_id) \ + static struct rpmpd _platform##_##_name = { \ + .pd = { .name = #_name, }, \ + .res_type = RPMPD_LDOA, \ + .res_id = r_id, \ + .key = KEY_CORNER, \ + } + +#define DEFINE_RPMPD_VFC(_platform, _name, r_id, r_type) \ + static struct rpmpd _platform##_##_name = { \ + .pd = { .name = #_name, }, \ + .res_type = r_type, \ + .res_id = r_id, \ + .key = KEY_FLOOR_CORNER,\ + } + +#define DEFINE_RPMPD_VFC_SMPA(_platform, _name, r_id) \ + DEFINE_RPMPD_VFC(_platform, _name, r_id, RPMPD_SMPA) +
[PATCH v3 2/7] soc: qcom: rpmpd: Add a Power domain driver to model corners
The Power domains for corners just pass the performance state set by the consumers to the RPM (Remote Power manager) which then takes care of setting the appropriate voltage on the corresponding rails to meet the performance needs. We add all Power domain data needed on msm8996 here. This driver can easily be extended by adding data for other qualcomm SoCs as well. Signed-off-by: Rajendra Nayak Signed-off-by: Viresh Kumar --- drivers/soc/qcom/Kconfig | 9 + drivers/soc/qcom/Makefile | 1 + drivers/soc/qcom/rpmpd.c | 301 + include/dt-bindings/power/qcom-rpmpd.h | 16 ++ 4 files changed, 327 insertions(+) create mode 100644 drivers/soc/qcom/rpmpd.c create mode 100644 include/dt-bindings/power/qcom-rpmpd.h diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index 9dc02f390ba3..5c54931a7b99 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig @@ -74,6 +74,15 @@ config QCOM_RMTFS_MEM Say y here if you intend to boot the modem remoteproc. +config QCOM_RPMPD + tristate "Qualcomm RPM Power domain driver" + depends on MFD_QCOM_RPM && QCOM_SMD_RPM + help + QCOM RPM Power domain driver to support power-domains with + performance states. The driver communicates a performance state + value to RPM which then translates it into corresponding voltage + for the voltage rail. + config QCOM_SMEM tristate "Qualcomm Shared Memory Manager (SMEM)" depends on ARCH_QCOM diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index 19dcf957cb3a..9550c170de93 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -15,3 +15,4 @@ obj-$(CONFIG_QCOM_SMP2P) += smp2p.o obj-$(CONFIG_QCOM_SMSM)+= smsm.o obj-$(CONFIG_QCOM_WCNSS_CTRL) += wcnss_ctrl.o obj-$(CONFIG_QCOM_APR) += apr.o +obj-$(CONFIG_QCOM_RPMPD) += rpmpd.o diff --git a/drivers/soc/qcom/rpmpd.c b/drivers/soc/qcom/rpmpd.c new file mode 100644 index ..c5e7a91f278c --- /dev/null +++ b/drivers/soc/qcom/rpmpd.c @@ -0,0 +1,301 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define domain_to_rpmpd(domain) container_of(domain, struct rpmpd, pd) + +/* Resource types */ +#define RPMPD_SMPA 0x61706d73 +#define RPMPD_LDOA 0x616f646c + +/* Operation Keys */ +#define KEY_CORNER 0x6e726f63 /* corn */ +#define KEY_ENABLE 0x6e657773 /* swen */ +#define KEY_FLOOR_CORNER 0x636676 /* vfc */ + +#define DEFINE_RPMPD_CORN_SMPA(_platform, _name, _active, r_id) \ + static struct rpmpd _platform##_##_active; \ + static struct rpmpd _platform##_##_name = { \ + .pd = { .name = #_name, }, \ + .peer = &_platform##_##_active, \ + .res_type = RPMPD_SMPA, \ + .res_id = r_id, \ + .key = KEY_CORNER, \ + }; \ + static struct rpmpd _platform##_##_active = { \ + .pd = { .name = #_active, },\ + .peer = &_platform##_##_name, \ + .active_only = true,\ + .res_type = RPMPD_SMPA, \ + .res_id = r_id, \ + .key = KEY_CORNER, \ + } + +#define DEFINE_RPMPD_CORN_LDOA(_platform, _name, r_id) \ + static struct rpmpd _platform##_##_name = { \ + .pd = { .name = #_name, }, \ + .res_type = RPMPD_LDOA, \ + .res_id = r_id, \ + .key = KEY_CORNER, \ + } + +#define DEFINE_RPMPD_VFC(_platform, _name, r_id, r_type) \ + static struct rpmpd _platform##_##_name = { \ + .pd = { .name = #_name, }, \ + .res_type = r_type, \ + .res_id = r_id, \ + .key = KEY_FLOOR_CORNER,\ + } + +#define DEFINE_RPMPD_VFC_SMPA(_platform, _name, r_id) \ + DEFINE_RPMPD_VFC(_platform, _name, r_id, RPMPD_SMPA) +
[PATCH v3 7/7] soc: qcom: rpmpd/rpmhpd: Add a max vote on all corners at init
As we move from no clients/consumers in kernel voting on corners, to *some* voting and some not voting, we might end up in a situation where the clients which remove votes can adversly impact others who still don't have a way to vote. To avoid this situation, have a max vote on all corners at init. This should/can be removed once we have all clients moved to be able to vote/unvote for themselves. Signed-off-by: Rajendra Nayak Acked-by: Viresh Kumar --- drivers/soc/qcom/rpmhpd.c | 12 +++- drivers/soc/qcom/rpmpd.c | 9 + 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/soc/qcom/rpmhpd.c b/drivers/soc/qcom/rpmhpd.c index 7083ec1590ff..3c753d33aeee 100644 --- a/drivers/soc/qcom/rpmhpd.c +++ b/drivers/soc/qcom/rpmhpd.c @@ -329,7 +329,7 @@ static int rpmhpd_update_level_mapping(struct rpmhpd *rpmhpd) static int rpmhpd_probe(struct platform_device *pdev) { - int i, ret; + int i, ret, max_level; size_t num; struct genpd_onecell_data *data; struct rpmhpd **rpmhpds; @@ -390,6 +390,16 @@ static int rpmhpd_probe(struct platform_device *pdev) pm_genpd_init([i]->pd, NULL, true); data->domains[i] = [i]->pd; + + /* +* Until we have all consumers voting on corners +* just vote the max corner on all PDs +* This should ideally be *removed* once we have +* all (most) consumers being able to vote +*/ + max_level = rpmhpds[i]->level_count - 1; + rpmhpd_set_performance([i]->pd, rpmhpds[i]->level[max_level]); + rpmhpd_power_on([i]->pd); } return of_genpd_add_provider_onecell(pdev->dev.of_node, data); diff --git a/drivers/soc/qcom/rpmpd.c b/drivers/soc/qcom/rpmpd.c index 53209454c1f3..6440163305e3 100644 --- a/drivers/soc/qcom/rpmpd.c +++ b/drivers/soc/qcom/rpmpd.c @@ -310,6 +310,15 @@ static int rpmpd_probe(struct platform_device *pdev) pm_genpd_init([i]->pd, NULL, true); data->domains[i] = [i]->pd; + + /* +* Until we have all consumers voting on corners +* just vote the max corner on all PDs +* This should ideally be *removed* once we have +* all (most) consumers being able to vote +*/ + rpmpd_set_performance([i]->pd, MAX_RPMPD_STATE); + rpmpd_power_on([i]->pd); } return of_genpd_add_provider_onecell(pdev->dev.of_node, data); -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH v3 7/7] soc: qcom: rpmpd/rpmhpd: Add a max vote on all corners at init
As we move from no clients/consumers in kernel voting on corners, to *some* voting and some not voting, we might end up in a situation where the clients which remove votes can adversly impact others who still don't have a way to vote. To avoid this situation, have a max vote on all corners at init. This should/can be removed once we have all clients moved to be able to vote/unvote for themselves. Signed-off-by: Rajendra Nayak Acked-by: Viresh Kumar --- drivers/soc/qcom/rpmhpd.c | 12 +++- drivers/soc/qcom/rpmpd.c | 9 + 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/soc/qcom/rpmhpd.c b/drivers/soc/qcom/rpmhpd.c index 7083ec1590ff..3c753d33aeee 100644 --- a/drivers/soc/qcom/rpmhpd.c +++ b/drivers/soc/qcom/rpmhpd.c @@ -329,7 +329,7 @@ static int rpmhpd_update_level_mapping(struct rpmhpd *rpmhpd) static int rpmhpd_probe(struct platform_device *pdev) { - int i, ret; + int i, ret, max_level; size_t num; struct genpd_onecell_data *data; struct rpmhpd **rpmhpds; @@ -390,6 +390,16 @@ static int rpmhpd_probe(struct platform_device *pdev) pm_genpd_init([i]->pd, NULL, true); data->domains[i] = [i]->pd; + + /* +* Until we have all consumers voting on corners +* just vote the max corner on all PDs +* This should ideally be *removed* once we have +* all (most) consumers being able to vote +*/ + max_level = rpmhpds[i]->level_count - 1; + rpmhpd_set_performance([i]->pd, rpmhpds[i]->level[max_level]); + rpmhpd_power_on([i]->pd); } return of_genpd_add_provider_onecell(pdev->dev.of_node, data); diff --git a/drivers/soc/qcom/rpmpd.c b/drivers/soc/qcom/rpmpd.c index 53209454c1f3..6440163305e3 100644 --- a/drivers/soc/qcom/rpmpd.c +++ b/drivers/soc/qcom/rpmpd.c @@ -310,6 +310,15 @@ static int rpmpd_probe(struct platform_device *pdev) pm_genpd_init([i]->pd, NULL, true); data->domains[i] = [i]->pd; + + /* +* Until we have all consumers voting on corners +* just vote the max corner on all PDs +* This should ideally be *removed* once we have +* all (most) consumers being able to vote +*/ + rpmpd_set_performance([i]->pd, MAX_RPMPD_STATE); + rpmpd_power_on([i]->pd); } return of_genpd_add_provider_onecell(pdev->dev.of_node, data); -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH v3 3/7] soc: qcom: rpmpd: Add support for get/set performance state
Add support for the .set_performace_state() and .opp_to_performance_state() callbacks in the rpmpd driver. Signed-off-by: Rajendra Nayak Signed-off-by: Viresh Kumar --- drivers/soc/qcom/rpmpd.c | 46 1 file changed, 46 insertions(+) diff --git a/drivers/soc/qcom/rpmpd.c b/drivers/soc/qcom/rpmpd.c index c5e7a91f278c..53209454c1f3 100644 --- a/drivers/soc/qcom/rpmpd.c +++ b/drivers/soc/qcom/rpmpd.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -28,6 +29,8 @@ #define KEY_ENABLE 0x6e657773 /* swen */ #define KEY_FLOOR_CORNER 0x636676 /* vfc */ +#define MAX_RPMPD_STATE6 + #define DEFINE_RPMPD_CORN_SMPA(_platform, _name, _active, r_id) \ static struct rpmpd _platform##_##_active; \ static struct rpmpd _platform##_##_name = { \ @@ -221,6 +224,47 @@ static int rpmpd_power_off(struct generic_pm_domain *domain) return ret; } +static int rpmpd_set_performance(struct generic_pm_domain *domain, +unsigned int state) +{ + int ret = 0; + struct rpmpd *pd = domain_to_rpmpd(domain); + + mutex_lock(_lock); + + if (state > MAX_RPMPD_STATE) + goto out; + + pd->corner = state; + + if (!pd->enabled && (pd->key != KEY_FLOOR_CORNER)) + goto out; + + ret = rpmpd_aggregate_corner(pd); + +out: + mutex_unlock(_lock); + + return ret; +} + +static unsigned int rpmpd_get_performance(struct generic_pm_domain *genpd, + struct dev_pm_opp *opp) +{ + struct device_node *np; + unsigned int corner = 0; + + np = dev_pm_opp_get_of_node(opp); + if (of_property_read_u32(np, "qcom,level", )) { + pr_err("%s: missing 'qcom,level' property\n", __func__); + return 0; + } + + of_node_put(np); + + return corner; +} + static int rpmpd_probe(struct platform_device *pdev) { int i; @@ -261,6 +305,8 @@ static int rpmpd_probe(struct platform_device *pdev) rpmpds[i]->rpm = rpm; rpmpds[i]->pd.power_off = rpmpd_power_off; rpmpds[i]->pd.power_on = rpmpd_power_on; + rpmpds[i]->pd.set_performance_state = rpmpd_set_performance; + rpmpds[i]->pd.opp_to_performance_state = rpmpd_get_performance; pm_genpd_init([i]->pd, NULL, true); data->domains[i] = [i]->pd; -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH v3 6/7] soc: qcom: Add RPMh Power domain driver
The RPMh Power domain driver aggregates the corner votes from various consumers for the ARC resources and communicates it to RPMh. We also add data for all power domains on sdm845 SoC as part of the patch. The driver can be extended to support other SoCs which support RPMh Signed-off-by: Rajendra Nayak --- drivers/soc/qcom/Kconfig| 9 + drivers/soc/qcom/Makefile | 1 + drivers/soc/qcom/rpmhpd.c | 427 include/dt-bindings/power/qcom-rpmhpd.h | 31 ++ 4 files changed, 468 insertions(+) create mode 100644 drivers/soc/qcom/rpmhpd.c create mode 100644 include/dt-bindings/power/qcom-rpmhpd.h diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index 5c54931a7b99..7cb7eba2b997 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig @@ -74,6 +74,15 @@ config QCOM_RMTFS_MEM Say y here if you intend to boot the modem remoteproc. +config QCOM_RPMHPD + tristate "Qualcomm RPMh Power domain driver" + depends on QCOM_RPMH && QCOM_COMMAND_DB + help + QCOM RPMh Power domain driver to support power-domains with + performance states. The driver communicates a performance state + value to RPMh which then translates it into corresponding voltage + for the voltage rail. + config QCOM_RPMPD tristate "Qualcomm RPM Power domain driver" depends on MFD_QCOM_RPM && QCOM_SMD_RPM diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index 9550c170de93..499513f63bef 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -16,3 +16,4 @@ obj-$(CONFIG_QCOM_SMSM) += smsm.o obj-$(CONFIG_QCOM_WCNSS_CTRL) += wcnss_ctrl.o obj-$(CONFIG_QCOM_APR) += apr.o obj-$(CONFIG_QCOM_RPMPD) += rpmpd.o +obj-$(CONFIG_QCOM_RPMHPD) += rpmhpd.o diff --git a/drivers/soc/qcom/rpmhpd.c b/drivers/soc/qcom/rpmhpd.c new file mode 100644 index ..7083ec1590ff --- /dev/null +++ b/drivers/soc/qcom/rpmhpd.c @@ -0,0 +1,427 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2018, The Linux Foundation. All rights reserved.*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define domain_to_rpmhpd(domain) container_of(domain, struct rpmhpd, pd) + +#define DEFINE_RPMHPD_AO(_platform, _name, _active)\ + static struct rpmhpd _platform##_##_active; \ + static struct rpmhpd _platform##_##_name = {\ + .pd = { .name = #_name, }, \ + .peer = &_platform##_##_active, \ + .res_name = #_name".lvl", \ + .valid_state_mask = (BIT(RPMH_ACTIVE_ONLY_STATE) | \ + BIT(RPMH_WAKE_ONLY_STATE) | \ + BIT(RPMH_SLEEP_STATE)), \ + }; \ + static struct rpmhpd _platform##_##_active = { \ + .pd = { .name = #_active, },\ + .peer = &_platform##_##_name, \ + .active_only = true,\ + .res_name = #_name".lvl", \ + .valid_state_mask = (BIT(RPMH_ACTIVE_ONLY_STATE) | \ + BIT(RPMH_WAKE_ONLY_STATE) | \ + BIT(RPMH_SLEEP_STATE)), \ + } + +#define DEFINE_RPMHPD(_platform, _name) \ + static struct rpmhpd _platform##_##_name = {\ + .pd = { .name = #_name, }, \ + .res_name = #_name".lvl", \ + .valid_state_mask = BIT(RPMH_ACTIVE_ONLY_STATE),\ + } + +/* + * This is the number of bytes used for each command DB aux data entry of an + * ARC resource. + */ +#define RPMH_ARC_LEVEL_SIZE2 +#define RPMH_ARC_MAX_LEVELS16 + +struct rpmhpd { + struct device *dev; + struct generic_pm_domain pd; + struct rpmhpd *peer; + const bool active_only; + unsigned intcorner; + unsigned intactive_corner; + u32 level[RPMH_ARC_MAX_LEVELS]; + int level_count; + boolenabled; + const char *res_name; + u32 addr; + u8 valid_state_mask; +}; + +struct rpmhpd_desc { + struct rpmhpd **rpmhpds; + size_t num_pds; +}; + +static DEFINE_MUTEX(rpmhpd_lock); + +/* sdm845 RPMh Power domains */ +DEFINE_RPMHPD(sdm845, ebi); +DEFINE_RPMHPD_AO(sdm845, mx, mx_ao); +DEFINE_RPMHPD_AO(sdm845,
[PATCH v3 5/7] dt-bindings: power: Add qcom rpmh power domain driver bindings
Add DT bindings to describe the rpmh powerdomains found on Qualcomm Technologies, Inc. SoCs. These power domains communicate a performance state to RPMh, which then translates it into corresponding voltage on a PMIC rail. Signed-off-by: Rajendra Nayak --- .../devicetree/bindings/power/qcom,rpmhpd.txt | 65 +++ 1 file changed, 65 insertions(+) create mode 100644 Documentation/devicetree/bindings/power/qcom,rpmhpd.txt diff --git a/Documentation/devicetree/bindings/power/qcom,rpmhpd.txt b/Documentation/devicetree/bindings/power/qcom,rpmhpd.txt new file mode 100644 index ..41ef7afa6b24 --- /dev/null +++ b/Documentation/devicetree/bindings/power/qcom,rpmhpd.txt @@ -0,0 +1,65 @@ +Qualcomm RPMh Power domains + +For RPMh Power domains, we communicate a performance state to RPMh +which then translates it into a corresponding voltage on a rail + +Required Properties: + - compatible: Should be one of the following + * qcom,sdm845-rpmhpd: RPMh Power domain for the sdm845 family of SoC + - power-domain-cells: number of cells in power domain specifier + must be 1 + - operating-points-v2: Phandle to the OPP table for the power-domain. + Refer to Documentation/devicetree/bindings/power/power_domain.txt + and Documentation/devicetree/bindings/opp/qcom-opp.txt for more details + +Example: + + rpmhpd: power-controller { + compatible = "qcom,sdm845-rpmhpd"; + #power-domain-cells = <1>; + operating-points-v2 = <_opp_table>; + }; + + rpmhpd_opp_table: opp-table { + compatible = "operating-points-v2-qcom-level"; + + rpmhpd_opp_ret: opp1 { + qcom-level = <16>; + }; + + rpmhpd_opp_min_svs: opp2 { + qcom-level = <48>; + }; + + rpmhpd_opp_low_svs: opp3 { + qcom-level = <64>; + }; + + rpmhpd_opp_svs: opp4 { + qcom-level = <128>; + }; + + rpmhpd_opp_svs_l1: opp5 { + qcom-level = <192>; + }; + + rpmhpd_opp_nom: opp6 { + qcom-level = <256>; + }; + + rpmhpd_opp_nom_l1: opp7 { + qcom-level = <320>; + }; + + rpmhpd_opp_nom_l2: opp8 { + qcom-level = <336>; + }; + + rpmhpd_opp_turbo: opp9 { + qcom-level = <384>; + }; + + rpmhpd_opp_turbo_l1: opp10 { + qcom-level = <416>; + }; + }; -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH v3 3/7] soc: qcom: rpmpd: Add support for get/set performance state
Add support for the .set_performace_state() and .opp_to_performance_state() callbacks in the rpmpd driver. Signed-off-by: Rajendra Nayak Signed-off-by: Viresh Kumar --- drivers/soc/qcom/rpmpd.c | 46 1 file changed, 46 insertions(+) diff --git a/drivers/soc/qcom/rpmpd.c b/drivers/soc/qcom/rpmpd.c index c5e7a91f278c..53209454c1f3 100644 --- a/drivers/soc/qcom/rpmpd.c +++ b/drivers/soc/qcom/rpmpd.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -28,6 +29,8 @@ #define KEY_ENABLE 0x6e657773 /* swen */ #define KEY_FLOOR_CORNER 0x636676 /* vfc */ +#define MAX_RPMPD_STATE6 + #define DEFINE_RPMPD_CORN_SMPA(_platform, _name, _active, r_id) \ static struct rpmpd _platform##_##_active; \ static struct rpmpd _platform##_##_name = { \ @@ -221,6 +224,47 @@ static int rpmpd_power_off(struct generic_pm_domain *domain) return ret; } +static int rpmpd_set_performance(struct generic_pm_domain *domain, +unsigned int state) +{ + int ret = 0; + struct rpmpd *pd = domain_to_rpmpd(domain); + + mutex_lock(_lock); + + if (state > MAX_RPMPD_STATE) + goto out; + + pd->corner = state; + + if (!pd->enabled && (pd->key != KEY_FLOOR_CORNER)) + goto out; + + ret = rpmpd_aggregate_corner(pd); + +out: + mutex_unlock(_lock); + + return ret; +} + +static unsigned int rpmpd_get_performance(struct generic_pm_domain *genpd, + struct dev_pm_opp *opp) +{ + struct device_node *np; + unsigned int corner = 0; + + np = dev_pm_opp_get_of_node(opp); + if (of_property_read_u32(np, "qcom,level", )) { + pr_err("%s: missing 'qcom,level' property\n", __func__); + return 0; + } + + of_node_put(np); + + return corner; +} + static int rpmpd_probe(struct platform_device *pdev) { int i; @@ -261,6 +305,8 @@ static int rpmpd_probe(struct platform_device *pdev) rpmpds[i]->rpm = rpm; rpmpds[i]->pd.power_off = rpmpd_power_off; rpmpds[i]->pd.power_on = rpmpd_power_on; + rpmpds[i]->pd.set_performance_state = rpmpd_set_performance; + rpmpds[i]->pd.opp_to_performance_state = rpmpd_get_performance; pm_genpd_init([i]->pd, NULL, true); data->domains[i] = [i]->pd; -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH v3 6/7] soc: qcom: Add RPMh Power domain driver
The RPMh Power domain driver aggregates the corner votes from various consumers for the ARC resources and communicates it to RPMh. We also add data for all power domains on sdm845 SoC as part of the patch. The driver can be extended to support other SoCs which support RPMh Signed-off-by: Rajendra Nayak --- drivers/soc/qcom/Kconfig| 9 + drivers/soc/qcom/Makefile | 1 + drivers/soc/qcom/rpmhpd.c | 427 include/dt-bindings/power/qcom-rpmhpd.h | 31 ++ 4 files changed, 468 insertions(+) create mode 100644 drivers/soc/qcom/rpmhpd.c create mode 100644 include/dt-bindings/power/qcom-rpmhpd.h diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index 5c54931a7b99..7cb7eba2b997 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig @@ -74,6 +74,15 @@ config QCOM_RMTFS_MEM Say y here if you intend to boot the modem remoteproc. +config QCOM_RPMHPD + tristate "Qualcomm RPMh Power domain driver" + depends on QCOM_RPMH && QCOM_COMMAND_DB + help + QCOM RPMh Power domain driver to support power-domains with + performance states. The driver communicates a performance state + value to RPMh which then translates it into corresponding voltage + for the voltage rail. + config QCOM_RPMPD tristate "Qualcomm RPM Power domain driver" depends on MFD_QCOM_RPM && QCOM_SMD_RPM diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index 9550c170de93..499513f63bef 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -16,3 +16,4 @@ obj-$(CONFIG_QCOM_SMSM) += smsm.o obj-$(CONFIG_QCOM_WCNSS_CTRL) += wcnss_ctrl.o obj-$(CONFIG_QCOM_APR) += apr.o obj-$(CONFIG_QCOM_RPMPD) += rpmpd.o +obj-$(CONFIG_QCOM_RPMHPD) += rpmhpd.o diff --git a/drivers/soc/qcom/rpmhpd.c b/drivers/soc/qcom/rpmhpd.c new file mode 100644 index ..7083ec1590ff --- /dev/null +++ b/drivers/soc/qcom/rpmhpd.c @@ -0,0 +1,427 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2018, The Linux Foundation. All rights reserved.*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define domain_to_rpmhpd(domain) container_of(domain, struct rpmhpd, pd) + +#define DEFINE_RPMHPD_AO(_platform, _name, _active)\ + static struct rpmhpd _platform##_##_active; \ + static struct rpmhpd _platform##_##_name = {\ + .pd = { .name = #_name, }, \ + .peer = &_platform##_##_active, \ + .res_name = #_name".lvl", \ + .valid_state_mask = (BIT(RPMH_ACTIVE_ONLY_STATE) | \ + BIT(RPMH_WAKE_ONLY_STATE) | \ + BIT(RPMH_SLEEP_STATE)), \ + }; \ + static struct rpmhpd _platform##_##_active = { \ + .pd = { .name = #_active, },\ + .peer = &_platform##_##_name, \ + .active_only = true,\ + .res_name = #_name".lvl", \ + .valid_state_mask = (BIT(RPMH_ACTIVE_ONLY_STATE) | \ + BIT(RPMH_WAKE_ONLY_STATE) | \ + BIT(RPMH_SLEEP_STATE)), \ + } + +#define DEFINE_RPMHPD(_platform, _name) \ + static struct rpmhpd _platform##_##_name = {\ + .pd = { .name = #_name, }, \ + .res_name = #_name".lvl", \ + .valid_state_mask = BIT(RPMH_ACTIVE_ONLY_STATE),\ + } + +/* + * This is the number of bytes used for each command DB aux data entry of an + * ARC resource. + */ +#define RPMH_ARC_LEVEL_SIZE2 +#define RPMH_ARC_MAX_LEVELS16 + +struct rpmhpd { + struct device *dev; + struct generic_pm_domain pd; + struct rpmhpd *peer; + const bool active_only; + unsigned intcorner; + unsigned intactive_corner; + u32 level[RPMH_ARC_MAX_LEVELS]; + int level_count; + boolenabled; + const char *res_name; + u32 addr; + u8 valid_state_mask; +}; + +struct rpmhpd_desc { + struct rpmhpd **rpmhpds; + size_t num_pds; +}; + +static DEFINE_MUTEX(rpmhpd_lock); + +/* sdm845 RPMh Power domains */ +DEFINE_RPMHPD(sdm845, ebi); +DEFINE_RPMHPD_AO(sdm845, mx, mx_ao); +DEFINE_RPMHPD_AO(sdm845,
[PATCH v3 5/7] dt-bindings: power: Add qcom rpmh power domain driver bindings
Add DT bindings to describe the rpmh powerdomains found on Qualcomm Technologies, Inc. SoCs. These power domains communicate a performance state to RPMh, which then translates it into corresponding voltage on a PMIC rail. Signed-off-by: Rajendra Nayak --- .../devicetree/bindings/power/qcom,rpmhpd.txt | 65 +++ 1 file changed, 65 insertions(+) create mode 100644 Documentation/devicetree/bindings/power/qcom,rpmhpd.txt diff --git a/Documentation/devicetree/bindings/power/qcom,rpmhpd.txt b/Documentation/devicetree/bindings/power/qcom,rpmhpd.txt new file mode 100644 index ..41ef7afa6b24 --- /dev/null +++ b/Documentation/devicetree/bindings/power/qcom,rpmhpd.txt @@ -0,0 +1,65 @@ +Qualcomm RPMh Power domains + +For RPMh Power domains, we communicate a performance state to RPMh +which then translates it into a corresponding voltage on a rail + +Required Properties: + - compatible: Should be one of the following + * qcom,sdm845-rpmhpd: RPMh Power domain for the sdm845 family of SoC + - power-domain-cells: number of cells in power domain specifier + must be 1 + - operating-points-v2: Phandle to the OPP table for the power-domain. + Refer to Documentation/devicetree/bindings/power/power_domain.txt + and Documentation/devicetree/bindings/opp/qcom-opp.txt for more details + +Example: + + rpmhpd: power-controller { + compatible = "qcom,sdm845-rpmhpd"; + #power-domain-cells = <1>; + operating-points-v2 = <_opp_table>; + }; + + rpmhpd_opp_table: opp-table { + compatible = "operating-points-v2-qcom-level"; + + rpmhpd_opp_ret: opp1 { + qcom-level = <16>; + }; + + rpmhpd_opp_min_svs: opp2 { + qcom-level = <48>; + }; + + rpmhpd_opp_low_svs: opp3 { + qcom-level = <64>; + }; + + rpmhpd_opp_svs: opp4 { + qcom-level = <128>; + }; + + rpmhpd_opp_svs_l1: opp5 { + qcom-level = <192>; + }; + + rpmhpd_opp_nom: opp6 { + qcom-level = <256>; + }; + + rpmhpd_opp_nom_l1: opp7 { + qcom-level = <320>; + }; + + rpmhpd_opp_nom_l2: opp8 { + qcom-level = <336>; + }; + + rpmhpd_opp_turbo: opp9 { + qcom-level = <384>; + }; + + rpmhpd_opp_turbo_l1: opp10 { + qcom-level = <416>; + }; + }; -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH v3 0/7] Add powerdomain driver for corners on msm8996/sdm845
Changes in v3: * Bindings split into seperate patches * Bindings updated to remove duplicate OPP table phandles * DT headers defining macros for Power domain indexes and OPP levels * Optimisations to use rpmh_write_async() whereever applicable * Fixed up handling of ACTIVE_ONLY/WAKE_ONLY/SLEEP voting for RPMh * Fixed the vlvl to hlvl conversions in set_performance * Other minor fixes based on review of v2 * TODO: This series does not handle the case where all VDD_MX votes should be higher than VDD_CX from APPs, as pointed out by David Collins in v2. This needs support at genpd to propogate performance state up the parents, if we model these as Parent/Child to handle the interdependency. Changes in v2: * added a powerdomain driver for sdm845 which supports communicating to RPMh * dropped the changes to sdhc driver to move over to using OPP as there is active discussion on using OPP as the interface vs handling all of it in clock drivers * Other minor binding updates based on review of v1 With performance state support for genpd/OPP merged, this is an effort to model a powerdomain driver to communicate corner/level values for qualcomm platforms to RPM (Remote Power Manager) and RPMh. Rajendra Nayak (7): dt-bindings: power: Add qcom rpm power domain driver bindings soc: qcom: rpmpd: Add a Power domain driver to model corners soc: qcom: rpmpd: Add support for get/set performance state arm64: dts: msm8996: Add rpmpd device node dt-bindings: power: Add qcom rpmh power domain driver bindings soc: qcom: Add RPMh Power domain driver soc: qcom: rpmpd/rpmhpd: Add a max vote on all corners at init .../devicetree/bindings/power/qcom,rpmhpd.txt | 65 +++ .../devicetree/bindings/power/qcom,rpmpd.txt | 49 ++ arch/arm64/boot/dts/qcom/msm8996.dtsi | 34 ++ drivers/soc/qcom/Kconfig | 18 + drivers/soc/qcom/Makefile | 2 + drivers/soc/qcom/rpmhpd.c | 437 ++ drivers/soc/qcom/rpmpd.c | 356 ++ include/dt-bindings/power/qcom-rpmhpd.h | 31 ++ include/dt-bindings/power/qcom-rpmpd.h| 16 + 9 files changed, 1008 insertions(+) create mode 100644 Documentation/devicetree/bindings/power/qcom,rpmhpd.txt create mode 100644 Documentation/devicetree/bindings/power/qcom,rpmpd.txt create mode 100644 drivers/soc/qcom/rpmhpd.c create mode 100644 drivers/soc/qcom/rpmpd.c create mode 100644 include/dt-bindings/power/qcom-rpmhpd.h create mode 100644 include/dt-bindings/power/qcom-rpmpd.h -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH v3 1/7] dt-bindings: power: Add qcom rpm power domain driver bindings
Add DT bindings to describe the rpm power domains found on Qualcomm Technologies, Inc. SoCs. These power domains communicate a performance state to RPM, which then translates it into corresponding voltage on a PMIC rail. Signed-off-by: Rajendra Nayak Signed-off-by: Viresh Kumar --- .../devicetree/bindings/power/qcom,rpmpd.txt | 49 +++ 1 file changed, 49 insertions(+) create mode 100644 Documentation/devicetree/bindings/power/qcom,rpmpd.txt diff --git a/Documentation/devicetree/bindings/power/qcom,rpmpd.txt b/Documentation/devicetree/bindings/power/qcom,rpmpd.txt new file mode 100644 index ..61a0e2687940 --- /dev/null +++ b/Documentation/devicetree/bindings/power/qcom,rpmpd.txt @@ -0,0 +1,49 @@ +Qualcomm RPM Power domains + +For RPM Power domains, we communicate a performance state to RPM +which then translates it into a corresponding voltage on a rail + +Required Properties: + - compatible: Should be one of the following + * qcom,msm8996-rpmpd: RPM Power domain for the msm8996 family of SoC + - power-domain-cells: number of cells in Power domain specifier + must be 1. + - operating-points-v2: Phandle to the OPP table for the Power domain. + Refer to Documentation/devicetree/bindings/power/power_domain.txt + and Documentation/devicetree/bindings/opp/qcom-opp.txt for more details + +Example: + + rpmpd: power-controller { + compatible = "qcom,msm8996-rpmpd"; + #power-domain-cells = <1>; + operating-points-v2 = <_opp_table>; + }; + + rpmpd_opp_table: opp-table { + compatible = "operating-points-v2-qcom-level"; + + rpmpd_opp1: opp1 { + qcom,level = <1>; + }; + + rpmpd_opp2: opp2 { + qcom,level = <2>; + }; + + rpmpd_opp3: opp3 { + qcom,level = <3>; + }; + + rpmpd_opp4: opp4 { + qcom,level = <4>; + }; + + rpmpd_opp5: opp5 { + qcom,level = <5>; + }; + + rpmpd_opp6: opp6 { + qcom,level = <6>; + }; + }; -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH v3 0/7] Add powerdomain driver for corners on msm8996/sdm845
Changes in v3: * Bindings split into seperate patches * Bindings updated to remove duplicate OPP table phandles * DT headers defining macros for Power domain indexes and OPP levels * Optimisations to use rpmh_write_async() whereever applicable * Fixed up handling of ACTIVE_ONLY/WAKE_ONLY/SLEEP voting for RPMh * Fixed the vlvl to hlvl conversions in set_performance * Other minor fixes based on review of v2 * TODO: This series does not handle the case where all VDD_MX votes should be higher than VDD_CX from APPs, as pointed out by David Collins in v2. This needs support at genpd to propogate performance state up the parents, if we model these as Parent/Child to handle the interdependency. Changes in v2: * added a powerdomain driver for sdm845 which supports communicating to RPMh * dropped the changes to sdhc driver to move over to using OPP as there is active discussion on using OPP as the interface vs handling all of it in clock drivers * Other minor binding updates based on review of v1 With performance state support for genpd/OPP merged, this is an effort to model a powerdomain driver to communicate corner/level values for qualcomm platforms to RPM (Remote Power Manager) and RPMh. Rajendra Nayak (7): dt-bindings: power: Add qcom rpm power domain driver bindings soc: qcom: rpmpd: Add a Power domain driver to model corners soc: qcom: rpmpd: Add support for get/set performance state arm64: dts: msm8996: Add rpmpd device node dt-bindings: power: Add qcom rpmh power domain driver bindings soc: qcom: Add RPMh Power domain driver soc: qcom: rpmpd/rpmhpd: Add a max vote on all corners at init .../devicetree/bindings/power/qcom,rpmhpd.txt | 65 +++ .../devicetree/bindings/power/qcom,rpmpd.txt | 49 ++ arch/arm64/boot/dts/qcom/msm8996.dtsi | 34 ++ drivers/soc/qcom/Kconfig | 18 + drivers/soc/qcom/Makefile | 2 + drivers/soc/qcom/rpmhpd.c | 437 ++ drivers/soc/qcom/rpmpd.c | 356 ++ include/dt-bindings/power/qcom-rpmhpd.h | 31 ++ include/dt-bindings/power/qcom-rpmpd.h| 16 + 9 files changed, 1008 insertions(+) create mode 100644 Documentation/devicetree/bindings/power/qcom,rpmhpd.txt create mode 100644 Documentation/devicetree/bindings/power/qcom,rpmpd.txt create mode 100644 drivers/soc/qcom/rpmhpd.c create mode 100644 drivers/soc/qcom/rpmpd.c create mode 100644 include/dt-bindings/power/qcom-rpmhpd.h create mode 100644 include/dt-bindings/power/qcom-rpmpd.h -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH v3 1/7] dt-bindings: power: Add qcom rpm power domain driver bindings
Add DT bindings to describe the rpm power domains found on Qualcomm Technologies, Inc. SoCs. These power domains communicate a performance state to RPM, which then translates it into corresponding voltage on a PMIC rail. Signed-off-by: Rajendra Nayak Signed-off-by: Viresh Kumar --- .../devicetree/bindings/power/qcom,rpmpd.txt | 49 +++ 1 file changed, 49 insertions(+) create mode 100644 Documentation/devicetree/bindings/power/qcom,rpmpd.txt diff --git a/Documentation/devicetree/bindings/power/qcom,rpmpd.txt b/Documentation/devicetree/bindings/power/qcom,rpmpd.txt new file mode 100644 index ..61a0e2687940 --- /dev/null +++ b/Documentation/devicetree/bindings/power/qcom,rpmpd.txt @@ -0,0 +1,49 @@ +Qualcomm RPM Power domains + +For RPM Power domains, we communicate a performance state to RPM +which then translates it into a corresponding voltage on a rail + +Required Properties: + - compatible: Should be one of the following + * qcom,msm8996-rpmpd: RPM Power domain for the msm8996 family of SoC + - power-domain-cells: number of cells in Power domain specifier + must be 1. + - operating-points-v2: Phandle to the OPP table for the Power domain. + Refer to Documentation/devicetree/bindings/power/power_domain.txt + and Documentation/devicetree/bindings/opp/qcom-opp.txt for more details + +Example: + + rpmpd: power-controller { + compatible = "qcom,msm8996-rpmpd"; + #power-domain-cells = <1>; + operating-points-v2 = <_opp_table>; + }; + + rpmpd_opp_table: opp-table { + compatible = "operating-points-v2-qcom-level"; + + rpmpd_opp1: opp1 { + qcom,level = <1>; + }; + + rpmpd_opp2: opp2 { + qcom,level = <2>; + }; + + rpmpd_opp3: opp3 { + qcom,level = <3>; + }; + + rpmpd_opp4: opp4 { + qcom,level = <4>; + }; + + rpmpd_opp5: opp5 { + qcom,level = <5>; + }; + + rpmpd_opp6: opp6 { + qcom,level = <6>; + }; + }; -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation