Re: [PATCH v2 05/10] drm/rockchip: analogix_dp: add rk3399 eDP support
On 05/24/2016 06:17 PM, Heiko Stuebner wrote: Am Dienstag, 24. Mai 2016, 14:57:23 schrieb Yakir Yang: [] diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index 29c4105..d5d4e04 100644 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c @@ -148,6 +148,10 @@ rockchip_dp_drm_encoder_atomic_check(struct drm_encoder *encoder, struct drm_connector_state *conn_state) { struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state); + struct rockchip_dp_device *dp = to_dp(encoder); + int ret; + + s->output_type = DRM_MODE_CONNECTOR_eDP; /* * FIXME(Yakir): driver should configure the CRTC output video @@ -162,8 +166,27 @@ rockchip_dp_drm_encoder_atomic_check(struct drm_encoder *encoder, * But if I configure CTRC to RGBaaa, and eDP driver still keep * RGB666 input video mode, then screen would works prefect. */ - s->output_mode = ROCKCHIP_OUT_MODE_; - s->output_type = DRM_MODE_CONNECTOR_eDP; + + ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, encoder); + if (ret < 0) + return; this needs a value returned (probably ret), otherwise you create a warning: ‘return’ with no value, in function returning non-void Done, Thanks, - Yakir drm_of_encoder_active_endpoint_id also always returns -EINVAL on rk3288- veyron-jerry because encoder->crtc is unset in drm_of_encoder_active_endpoint and that breaks display output right now. Looking through drm code it seems only two functions would set encoder->crtc - drm_atomic_helper_update_legacy_modeset_state - drm_crtc_helper_set_config drm_crtc_helper_set_config callback got dropped in the atomic-conversion and the other sounds to be somewhat in the legacy area. After that drm-internals get a bit confusing. Heiko
Re: [PATCH v2 05/10] drm/rockchip: analogix_dp: add rk3399 eDP support
On 05/24/2016 06:17 PM, Heiko Stuebner wrote: Am Dienstag, 24. Mai 2016, 14:57:23 schrieb Yakir Yang: [] diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index 29c4105..d5d4e04 100644 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c @@ -148,6 +148,10 @@ rockchip_dp_drm_encoder_atomic_check(struct drm_encoder *encoder, struct drm_connector_state *conn_state) { struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state); + struct rockchip_dp_device *dp = to_dp(encoder); + int ret; + + s->output_type = DRM_MODE_CONNECTOR_eDP; /* * FIXME(Yakir): driver should configure the CRTC output video @@ -162,8 +166,27 @@ rockchip_dp_drm_encoder_atomic_check(struct drm_encoder *encoder, * But if I configure CTRC to RGBaaa, and eDP driver still keep * RGB666 input video mode, then screen would works prefect. */ - s->output_mode = ROCKCHIP_OUT_MODE_; - s->output_type = DRM_MODE_CONNECTOR_eDP; + + ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, encoder); + if (ret < 0) + return; this needs a value returned (probably ret), otherwise you create a warning: ‘return’ with no value, in function returning non-void Done, Thanks, - Yakir drm_of_encoder_active_endpoint_id also always returns -EINVAL on rk3288- veyron-jerry because encoder->crtc is unset in drm_of_encoder_active_endpoint and that breaks display output right now. Looking through drm code it seems only two functions would set encoder->crtc - drm_atomic_helper_update_legacy_modeset_state - drm_crtc_helper_set_config drm_crtc_helper_set_config callback got dropped in the atomic-conversion and the other sounds to be somewhat in the legacy area. After that drm-internals get a bit confusing. Heiko
Re: [PATCH v2 05/10] drm/rockchip: analogix_dp: add rk3399 eDP support
On 05/25/2016 02:23 AM, Heiko Stuebner wrote: Am Dienstag, 24. Mai 2016, 11:12:20 schrieb Doug Anderson: Hi, On Tue, May 24, 2016 at 3:17 AM, Heiko Stuebnerwrote: --- a/Documentation/devicetree/bindings/display/bridge/analogix_dp.txt +++ b/Documentation/devicetree/bindings/display/bridge/analogix_dp.txt @@ -5,6 +5,7 @@ Required properties for dp-controller: platform specific such as: * "samsung,exynos5-dp" * "rockchip,rk3288-dp" + * "rockchip,rk3399-edp" the cleanlines-freak in my likes to know if there is a difference between the rk3399 being called -edp here and -dp on the rk3288 :-) [...] If I was a guessing man (which I'm not, but if I was), I'd guess that this is because on rk3288 there was only one DP port and it was an EDP port. ...but since there was only one people just referred to it as the "DP" port and that was codified in the bindings. On rk3399 there are two ports: one EDP and one DP. All of a sudden we need to differentiate. Any better suggestions for how to deal with that? nope - everything as it should be in that regard then - the rk3288-dp is permanent now anyway. But it looks like I'm sort of blind blind and only now have seen the separate DP controller chapter in the TRM (probably because I somehow didn't expect a second controller). RK3399 eDP controller have cut off the DP-Audio function and DP-HDCP function, so it can't be treated as DP interfaces any more, that's why I call it "eDP".
Re: [PATCH v2 05/10] drm/rockchip: analogix_dp: add rk3399 eDP support
On 05/25/2016 02:23 AM, Heiko Stuebner wrote: Am Dienstag, 24. Mai 2016, 11:12:20 schrieb Doug Anderson: Hi, On Tue, May 24, 2016 at 3:17 AM, Heiko Stuebner wrote: --- a/Documentation/devicetree/bindings/display/bridge/analogix_dp.txt +++ b/Documentation/devicetree/bindings/display/bridge/analogix_dp.txt @@ -5,6 +5,7 @@ Required properties for dp-controller: platform specific such as: * "samsung,exynos5-dp" * "rockchip,rk3288-dp" + * "rockchip,rk3399-edp" the cleanlines-freak in my likes to know if there is a difference between the rk3399 being called -edp here and -dp on the rk3288 :-) [...] If I was a guessing man (which I'm not, but if I was), I'd guess that this is because on rk3288 there was only one DP port and it was an EDP port. ...but since there was only one people just referred to it as the "DP" port and that was codified in the bindings. On rk3399 there are two ports: one EDP and one DP. All of a sudden we need to differentiate. Any better suggestions for how to deal with that? nope - everything as it should be in that regard then - the rk3288-dp is permanent now anyway. But it looks like I'm sort of blind blind and only now have seen the separate DP controller chapter in the TRM (probably because I somehow didn't expect a second controller). RK3399 eDP controller have cut off the DP-Audio function and DP-HDCP function, so it can't be treated as DP interfaces any more, that's why I call it "eDP".
Re: [PATCH 2/5] iommu: Set PCI_BUS_FLAGS_MSI_REMAP if IOMMU have capability of IRQ remapping
On 2016/5/25 5:11, Bjorn Helgaas wrote: On Wed, Apr 27, 2016 at 08:43:27PM +0800, Yongji Xie wrote: The capability of IRQ remapping is abstracted on IOMMU side on some archs. There is a existing flag IOMMU_CAP_INTR_REMAP for this. To have a universal flag to test this capability for different archs on PCI side, we set PCI_BUS_FLAGS_MSI_REMAP for PCI buses when IOMMU_CAP_INTR_REMAP is set. Signed-off-by: Yongji Xie--- drivers/iommu/iommu.c | 15 +++ 1 file changed, 15 insertions(+) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 0e3b009..5d2b6f6 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -813,6 +813,16 @@ struct iommu_group *pci_device_group(struct device *dev) return group; } +static void pci_check_msi_remapping(struct pci_dev *pdev, + const struct iommu_ops *ops) +{ + struct pci_bus *bus = pdev->bus; + + if (ops->capable(IOMMU_CAP_INTR_REMAP) && + !(bus->bus_flags & PCI_BUS_FLAGS_MSI_REMAP)) + bus->bus_flags |= PCI_BUS_FLAGS_MSI_REMAP; +} This looks an awful lot like the pci_bus_check_msi_remapping() you add elsewhere. Why do we need both? I will modify this function as you suggested. And we add this function here because some iommu drivers would be initialed after PCI probing. /** * iommu_group_get_for_dev - Find or create the IOMMU group for a device * @dev: target device @@ -871,6 +881,9 @@ static int add_iommu_group(struct device *dev, void *data) const struct iommu_ops *ops = cb->ops; int ret; + if (dev_is_pci(dev) && ops->capable) + pci_check_msi_remapping(to_pci_dev(dev), ops); + if (!ops->add_device) return 0; @@ -913,6 +926,8 @@ static int iommu_bus_notifier(struct notifier_block *nb, * result in ADD/DEL notifiers to group->notifier */ if (action == BUS_NOTIFY_ADD_DEVICE) { + if (dev_is_pci(dev) && ops->capable) + pci_check_msi_remapping(to_pci_dev(dev), ops); These calls don't smell right either. Why do we need dev_is_pci() checks here? Some platform devices may also call this. Can't this be done in the PCI probe path somehow, e.g., in pci_set_bus_msi_domain() or something? Yes, this can be done in pci_create_root_bus(). But it could only handle the case that iommu drivers are initialed before PCI probing. Regards, Yongji
Re: [PATCH 2/5] iommu: Set PCI_BUS_FLAGS_MSI_REMAP if IOMMU have capability of IRQ remapping
On 2016/5/25 5:11, Bjorn Helgaas wrote: On Wed, Apr 27, 2016 at 08:43:27PM +0800, Yongji Xie wrote: The capability of IRQ remapping is abstracted on IOMMU side on some archs. There is a existing flag IOMMU_CAP_INTR_REMAP for this. To have a universal flag to test this capability for different archs on PCI side, we set PCI_BUS_FLAGS_MSI_REMAP for PCI buses when IOMMU_CAP_INTR_REMAP is set. Signed-off-by: Yongji Xie --- drivers/iommu/iommu.c | 15 +++ 1 file changed, 15 insertions(+) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 0e3b009..5d2b6f6 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -813,6 +813,16 @@ struct iommu_group *pci_device_group(struct device *dev) return group; } +static void pci_check_msi_remapping(struct pci_dev *pdev, + const struct iommu_ops *ops) +{ + struct pci_bus *bus = pdev->bus; + + if (ops->capable(IOMMU_CAP_INTR_REMAP) && + !(bus->bus_flags & PCI_BUS_FLAGS_MSI_REMAP)) + bus->bus_flags |= PCI_BUS_FLAGS_MSI_REMAP; +} This looks an awful lot like the pci_bus_check_msi_remapping() you add elsewhere. Why do we need both? I will modify this function as you suggested. And we add this function here because some iommu drivers would be initialed after PCI probing. /** * iommu_group_get_for_dev - Find or create the IOMMU group for a device * @dev: target device @@ -871,6 +881,9 @@ static int add_iommu_group(struct device *dev, void *data) const struct iommu_ops *ops = cb->ops; int ret; + if (dev_is_pci(dev) && ops->capable) + pci_check_msi_remapping(to_pci_dev(dev), ops); + if (!ops->add_device) return 0; @@ -913,6 +926,8 @@ static int iommu_bus_notifier(struct notifier_block *nb, * result in ADD/DEL notifiers to group->notifier */ if (action == BUS_NOTIFY_ADD_DEVICE) { + if (dev_is_pci(dev) && ops->capable) + pci_check_msi_remapping(to_pci_dev(dev), ops); These calls don't smell right either. Why do we need dev_is_pci() checks here? Some platform devices may also call this. Can't this be done in the PCI probe path somehow, e.g., in pci_set_bus_msi_domain() or something? Yes, this can be done in pci_create_root_bus(). But it could only handle the case that iommu drivers are initialed before PCI probing. Regards, Yongji
Re: [PATCH 3/5] PCI: Set PCI_BUS_FLAGS_MSI_REMAP if MSI controller supports IRQ remapping
On 2016/5/25 5:04, Bjorn Helgaas wrote: On Wed, Apr 27, 2016 at 08:43:28PM +0800, Yongji Xie wrote: On ARM HW the capability of IRQ remapping is abstracted on MSI controller side. MSI_FLAG_IRQ_REMAPPING is used to advertise this [1]. To have a universal flag to test this capability for different archs on PCI side, we set PCI_BUS_FLAGS_MSI_REMAP for PCI buses when MSI_FLAG_IRQ_REMAPPING is set. [1] http://www.spinics.net/lists/kvm/msg130256.html Signed-off-by: Yongji Xie--- drivers/pci/msi.c | 12 drivers/pci/probe.c |3 +++ include/linux/msi.h |6 +- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index a080f44..1661cdf 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -1134,6 +1134,18 @@ void *msi_desc_to_pci_sysdata(struct msi_desc *desc) } EXPORT_SYMBOL_GPL(msi_desc_to_pci_sysdata); +void pci_bus_check_msi_remapping(struct pci_bus *bus, +struct irq_domain *domain) +{ +#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN + struct msi_domain_info *info; + + info = msi_get_domain_info(domain); + if (info->flags & MSI_FLAG_IRQ_REMAPPING) + bus->bus_flags |= PCI_BUS_FLAGS_MSI_REMAP; +#endif +} Functions named "check_foo" are a pet peeve of mine because the name doesn't tell us anything about what the function *does*. In this case, we know it checks something about MSI remapping, but we don't know whether we're checking whether it's enabled, disabled, or some other property. I'd prefer something like: int pci_bus_msi_isolated(struct pci_bus *bus, struct irq_domain *domain) { struct msi_domain_info *info; if (!domain) return 0; info = msi_get_domain_info(domain); if (info->flags & MSI_FLAG_IRQ_REMAPPING) return 1; return 0; } void pci_set_bus_msi_domain(struct pci_bus *bus) { ... if (b == bus && pci_bus_msi_isolated(bus, d)) bus->bus_flags |= PCI_BUS_FLAGS_MSI_REMAP; Yes. This looks more reasonable. Thank you! Regards, Yongji
Re: [PATCH 3/5] PCI: Set PCI_BUS_FLAGS_MSI_REMAP if MSI controller supports IRQ remapping
On 2016/5/25 5:04, Bjorn Helgaas wrote: On Wed, Apr 27, 2016 at 08:43:28PM +0800, Yongji Xie wrote: On ARM HW the capability of IRQ remapping is abstracted on MSI controller side. MSI_FLAG_IRQ_REMAPPING is used to advertise this [1]. To have a universal flag to test this capability for different archs on PCI side, we set PCI_BUS_FLAGS_MSI_REMAP for PCI buses when MSI_FLAG_IRQ_REMAPPING is set. [1] http://www.spinics.net/lists/kvm/msg130256.html Signed-off-by: Yongji Xie --- drivers/pci/msi.c | 12 drivers/pci/probe.c |3 +++ include/linux/msi.h |6 +- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index a080f44..1661cdf 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -1134,6 +1134,18 @@ void *msi_desc_to_pci_sysdata(struct msi_desc *desc) } EXPORT_SYMBOL_GPL(msi_desc_to_pci_sysdata); +void pci_bus_check_msi_remapping(struct pci_bus *bus, +struct irq_domain *domain) +{ +#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN + struct msi_domain_info *info; + + info = msi_get_domain_info(domain); + if (info->flags & MSI_FLAG_IRQ_REMAPPING) + bus->bus_flags |= PCI_BUS_FLAGS_MSI_REMAP; +#endif +} Functions named "check_foo" are a pet peeve of mine because the name doesn't tell us anything about what the function *does*. In this case, we know it checks something about MSI remapping, but we don't know whether we're checking whether it's enabled, disabled, or some other property. I'd prefer something like: int pci_bus_msi_isolated(struct pci_bus *bus, struct irq_domain *domain) { struct msi_domain_info *info; if (!domain) return 0; info = msi_get_domain_info(domain); if (info->flags & MSI_FLAG_IRQ_REMAPPING) return 1; return 0; } void pci_set_bus_msi_domain(struct pci_bus *bus) { ... if (b == bus && pci_bus_msi_isolated(bus, d)) bus->bus_flags |= PCI_BUS_FLAGS_MSI_REMAP; Yes. This looks more reasonable. Thank you! Regards, Yongji
[PATCH v3 00/12] J-core J2 cpu and SoC peripherals support
The following patchset adds support for the J-core J2, an open-source VHDL reimplementation of the SH-2 ISA, and drivers for the associated SoC devices (interrupt controller, clocksource, and SPI). As arch/sh co-maintainer my intent is to include as much as possible in my pull request for the linux-sh tree. If there are parts outside of arch/sh that can be included in this, please let me know. I'm not clear yet on what the right path to upstream is for the clocksource and irq drivers that are currently only useful/interesting for one arch, or for the DT binding patches. Even if some drivers are delayed going upstream, I would really like to get DT bindings acked and ideally merged, because we want to go ahead with moving the DTB into J2 boot rom where it belongs, and that should only happen with stable bindings. Rich Felker (12): of: add vendor prefix for J-Core of: add J-Core cpu bindings of: add J-Core interrupt controller bindings of: add J-Core timer bindings of: add J-Core SPI master bindings sh: add support for J-Core J2 processor sh: add AT_HWCAP flag for J-Core cas.l instruction irqchip: add J-Core AIC driver clocksource: add J-Core timer/clocksource driver spi: add driver for J-Core SPI controller sh: add defconfig for J-Core J2 sh: add device tree source for J2 FPGA on Mimas v2 board .../bindings/interrupt-controller/jcore,aic.txt| 29 +++ Documentation/devicetree/bindings/jcore/cpus.txt | 92 +++ .../devicetree/bindings/spi/jcore,spi.txt | 23 ++ .../devicetree/bindings/timer/jcore,pit.txt| 28 ++ .../devicetree/bindings/vendor-prefixes.txt| 1 + arch/sh/Kconfig| 8 + arch/sh/Makefile | 1 + arch/sh/boot/dts/j2_mimas_v2.dts | 87 +++ arch/sh/configs/j2_defconfig | 38 +++ arch/sh/include/asm/processor.h| 2 +- arch/sh/include/uapi/asm/cpu-features.h| 1 + arch/sh/kernel/cpu/init.c | 2 +- arch/sh/kernel/cpu/proc.c | 1 + arch/sh/kernel/cpu/sh2/entry.S | 5 + arch/sh/kernel/cpu/sh2/probe.c | 36 ++- arch/sh/mm/Makefile| 3 +- arch/sh/mm/cache-j2.c | 58 + arch/sh/mm/cache.c | 6 +- drivers/clocksource/Kconfig| 8 + drivers/clocksource/Makefile | 1 + drivers/clocksource/jcore-pit.c| 282 + drivers/irqchip/Kconfig| 6 + drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-jcore-aic.c| 95 +++ drivers/spi/Kconfig| 4 + drivers/spi/Makefile | 1 + drivers/spi/spi-jcore.c| 209 +++ 27 files changed, 1023 insertions(+), 5 deletions(-) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/jcore,aic.txt create mode 100644 Documentation/devicetree/bindings/jcore/cpus.txt create mode 100644 Documentation/devicetree/bindings/spi/jcore,spi.txt create mode 100644 Documentation/devicetree/bindings/timer/jcore,pit.txt create mode 100755 arch/sh/boot/dts/j2_mimas_v2.dts create mode 100644 arch/sh/configs/j2_defconfig create mode 100644 arch/sh/mm/cache-j2.c create mode 100644 drivers/clocksource/jcore-pit.c create mode 100644 drivers/irqchip/irq-jcore-aic.c create mode 100644 drivers/spi/spi-jcore.c -- 2.8.1
[PATCH v3 03/12] of: add J-Core interrupt controller bindings
Signed-off-by: Rich Felker--- .../bindings/interrupt-controller/jcore,aic.txt| 29 ++ 1 file changed, 29 insertions(+) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/jcore,aic.txt diff --git a/Documentation/devicetree/bindings/interrupt-controller/jcore,aic.txt b/Documentation/devicetree/bindings/interrupt-controller/jcore,aic.txt new file mode 100644 index 000..5dc99b9 --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/jcore,aic.txt @@ -0,0 +1,29 @@ +J-Core Advanced Interrupt Controller + +Required properties: + +- compatible : Should be "jcore,aic1" for the (obsolete) first-generation aic + with 8 interrupt lines with programmable priorities, or "jcore,aic2" for + the "aic2" core with 64 interrupts. + +- reg : Memory region for configuration. + +- interrupt-controller : Identifies the node as an interrupt controller + +- #interrupt-cells : Specifies the number of cells needed to encode an + interrupt source. The value shall be 1. + +Optional properties: + +- cpu-offset : For SMP, the offset to the per-cpu memory region for + configuration, to be scaled by the cpu number. + + +Example: + +aic: interrupt-controller@200 { + compatible = "jcore,aic2"; + reg = < 0x200 0x10 >; + interrupt-controller; + #interrupt-cells = <1>; +}; -- 2.8.1
Re: [PATCH 1/5] PCI: Add a new PCI_BUS_FLAGS_MSI_REMAP flag
On 2016/5/25 4:55, Bjorn Helgaas wrote: On Wed, Apr 27, 2016 at 08:43:26PM +0800, Yongji Xie wrote: We introduce a new pci_bus_flags, PCI_BUS_FLAGS_MSI_REMAP which indicates all devices on the bus are protected by the hardware which supports IRQ remapping(intel naming). This changelog is ambiguous. It's possible that there is hardware that *supports* IRQ remapping, but does not actually *do* IRQ remapping. For example, an IRQ remapping capability may be present but not enabled. I think your intent is to set this flag only when MSI remapping is actually *enabled* for all devices on the bus. Yes. This is exactly my intent. Thank you for the correction! I'd also like to know exactly what protection is implied by PCI_BUS_FLAGS_MSI_REMAP and IOMMU_CAP_INTR_REMAP. I guess it means a device can only generate MSIs to a certain set of CPUs? I assume the remapping hardware only checks the target address, not the data being written? When IRQ remapping is enabled, the hardware will check both target address and data, then compute the interrupt_index from them. Interrupt_index will be used to find a specific Interrupt Remapping Table Entry containing some fields which could be used to identify a device or a group of devices(these devices should be in the same isolation domain). Then hardware can use this to verify the interrupt request. If the interrupt request is not from the specific devices, it will be blocked. So this flag indicate that the hardware can ensure that a given PCI device can only shoot the MSIs assigned for it. When there is something wrong with MSI in device or device driver, this can prevent all damage from it. Regards, Yongji
[PATCH v3 06/12] sh: add support for J-Core J2 processor
At the CPU/ISA level, the J2 is compatible with SH-2, and thus the changes to add J2 support build on existing SH-2 support. However, J2 does not duplicate the memory-mapped SH-2 features like the cache interface. Instead, the cache interfaces is described in the device tree, and new code is added to be able to access the flat device tree at early boot before it is unflattened. Support is also added for receiving interrupts on trap numbers in the range 16 to 31, since the J-Core aic1 interrupt controller generates these traps. This range was unused but nominally for hardware exceptions on SH-2, and a few values in this range were used for exceptions on SH-2A, but SH-2A has its own version of the relevant code. No individual cpu subtypes are added for J2 since the intent moving forward is to represent SoCs with device tree rather than as hard-coded subtypes in the kernel. The CPU_SUBTYPE_J2 Kconfig item exists only to fit into the existing cpu selection mechanism until it is overhauled. Signed-off-by: Rich Felker--- Aside from adding commit message, this version of patch #6 in the series only makes minor changes: spelling out SEI's name in a copyright comment, and moving one asm insn that was placed on the wrong side of an #ifdef (harmless but wrong). arch/sh/Kconfig | 8 ++ arch/sh/Makefile| 1 + arch/sh/include/asm/processor.h | 2 +- arch/sh/kernel/cpu/init.c | 2 +- arch/sh/kernel/cpu/proc.c | 1 + arch/sh/kernel/cpu/sh2/entry.S | 5 arch/sh/kernel/cpu/sh2/probe.c | 34 +++- arch/sh/mm/Makefile | 3 ++- arch/sh/mm/cache-j2.c | 58 + arch/sh/mm/cache.c | 6 - 10 files changed, 115 insertions(+), 5 deletions(-) create mode 100644 arch/sh/mm/cache-j2.c diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 4fa5894..efb0af4 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -182,6 +182,10 @@ config CPU_SH2A select CPU_SH2 select UNCACHED_MAPPING +config CPU_J2 + bool + select CPU_SH2 + config CPU_SH3 bool select CPU_HAS_INTEVT @@ -248,6 +252,10 @@ config CPU_SUBTYPE_SH7619 select CPU_SH2 select SYS_SUPPORTS_SH_CMT +config CPU_SUBTYPE_J2 + bool "Support J2 processor" + select CPU_J2 + # SH-2A Processor Support config CPU_SUBTYPE_SH7201 diff --git a/arch/sh/Makefile b/arch/sh/Makefile index 3b2c8b4..0047666 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -31,6 +31,7 @@ isa-y := $(isa-y)-up endif cflags-$(CONFIG_CPU_SH2) := $(call cc-option,-m2,) +cflags-$(CONFIG_CPU_J2):= $(call cc-option,-mj2,) cflags-$(CONFIG_CPU_SH2A) += $(call cc-option,-m2a,) \ $(call cc-option,-m2a-nofpu,) \ $(call cc-option,-m4-nofpu,) diff --git a/arch/sh/include/asm/processor.h b/arch/sh/include/asm/processor.h index 1506897..f9a0994 100644 --- a/arch/sh/include/asm/processor.h +++ b/arch/sh/include/asm/processor.h @@ -15,7 +15,7 @@ */ enum cpu_type { /* SH-2 types */ - CPU_SH7619, + CPU_SH7619, CPU_J2, /* SH-2A types */ CPU_SH7201, CPU_SH7203, CPU_SH7206, CPU_SH7263, CPU_SH7264, CPU_SH7269, diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c index bfd9e27..c8b3be1 100644 --- a/arch/sh/kernel/cpu/init.c +++ b/arch/sh/kernel/cpu/init.c @@ -106,7 +106,7 @@ void __attribute__ ((weak)) l2_cache_init(void) /* * Generic first-level cache init */ -#ifdef CONFIG_SUPERH32 +#if defined(CONFIG_SUPERH32) && !defined(CONFIG_CPU_J2) static void cache_init(void) { unsigned long ccr, flags; diff --git a/arch/sh/kernel/cpu/proc.c b/arch/sh/kernel/cpu/proc.c index 9e6624c..4df4b28 100644 --- a/arch/sh/kernel/cpu/proc.c +++ b/arch/sh/kernel/cpu/proc.c @@ -27,6 +27,7 @@ static const char *cpu_name[] = { [CPU_MXG] = "MX-G", [CPU_SH7723]= "SH7723", [CPU_SH7366]= "SH7366", [CPU_SH7724]= "SH7724", [CPU_SH7372]= "SH7372", [CPU_SH7734]= "SH7734", + [CPU_J2]= "J2", [CPU_SH_NONE] = "Unknown" }; diff --git a/arch/sh/kernel/cpu/sh2/entry.S b/arch/sh/kernel/cpu/sh2/entry.S index a150595..16bde0e 100644 --- a/arch/sh/kernel/cpu/sh2/entry.S +++ b/arch/sh/kernel/cpu/sh2/entry.S @@ -147,6 +147,11 @@ ENTRY(exception_handler) mov #31,r8 cmp/hs r8,r9 bt trap_entry ! 64 > vec >= 31 is trap +#ifdef CONFIG_CPU_J2 + mov #16,r8 + cmp/hs r8,r9 + bt interrupt_entry ! 31 > vec >= 16 is interrupt +#endif mov.l 4f,r8 mov r9,r4 diff --git a/arch/sh/kernel/cpu/sh2/probe.c b/arch/sh/kernel/cpu/sh2/probe.c index 6c687ae..3dd8187 100644 --- a/arch/sh/kernel/cpu/sh2/probe.c +++
[PATCH v3 09/12] clocksource: add J-Core timer/clocksource driver
At the hardware level, the J-Core PIT is integrated with the interrupt controller, but it is represented as its own device and has an independent programming interface. It provides a 12-bit countdown timer, which is not presently used, and a periodic timer. The interval length for the latter is programmable via a 32-bit throttle register whose units are determined by a bus-period register. The periodic timer is used to implement both periodic and oneshot clock event modes; in oneshot mode the interrupt handler simply disables the timer as soon as it fires. Despite its device tree node representing an interrupt for the PIT, the actual irq generated is programmable, not hard-wired. The driver is responsible for programming the PIT to generate the hardware irq number that the DT assigns to it. On SMP configurations, J-Core provides cpu-local instances of the PIT; no broadcast timer is needed. This driver supports the creation of the necessary per-cpu clock_event_device instances. The code has been tested and works on SMP, but will not be usable without additional J-Core SMP-support patches and appropriate hardware capable of running SMP. A nanosecond-resolution clocksource is provided using the J-Core "RTC" registers, which give a 64-bit seconds count and 32-bit nanoseconds. The driver converts these to a 64-bit nanoseconds count. Signed-off-by: Rich Felker--- This driver has undergone significant changes based on feedback from Daniel Lezcano. I've split out helper functions, eliminated the repeated percpu offset computations, properly mapped each percpu base, used container_of instead of static storage for driver data, added comments for enable_val setup, removed confusing use of "RTC" name, removed excess includes, used the "jcore_" prefix in naming identifiers, and made error handling more extensive. drivers/clocksource/Kconfig | 8 ++ drivers/clocksource/Makefile| 1 + drivers/clocksource/jcore-pit.c | 282 3 files changed, 291 insertions(+) create mode 100644 drivers/clocksource/jcore-pit.c diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index c346be6..7bd39d2 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -297,6 +297,14 @@ config SYS_SUPPORTS_SH_TMU config SYS_SUPPORTS_EM_STI bool +config CLKSRC_JCORE_PIT + bool "J-Core PIT timer driver" + depends on GENERIC_CLOCKEVENTS + depends on HAS_IOMEM + help + This enables build of clocksource and clockevent driver for + the integrated PIT in the J-Core synthesizable, open source SoC. + config SH_TIMER_CMT bool "Renesas CMT timer driver" if COMPILE_TEST depends on GENERIC_CLOCKEVENTS diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index dc2b899..d825fcf 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_ATMEL_TCB_CLKSRC) += tcb_clksrc.o obj-$(CONFIG_X86_PM_TIMER) += acpi_pm.o obj-$(CONFIG_SCx200HR_TIMER) += scx200_hrt.o obj-$(CONFIG_CS5535_CLOCK_EVENT_SRC) += cs5535-clockevt.o +obj-$(CONFIG_CLKSRC_JCORE_PIT) += jcore-pit.o obj-$(CONFIG_SH_TIMER_CMT) += sh_cmt.o obj-$(CONFIG_SH_TIMER_MTU2)+= sh_mtu2.o obj-$(CONFIG_SH_TIMER_TMU) += sh_tmu.o diff --git a/drivers/clocksource/jcore-pit.c b/drivers/clocksource/jcore-pit.c new file mode 100644 index 000..dd78fcd --- /dev/null +++ b/drivers/clocksource/jcore-pit.c @@ -0,0 +1,282 @@ +/* + * J-Core SoC PIT/clocksource driver + * + * Copyright (C) 2015-2016 Smart Energy Instruments, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define PIT_IRQ_SHIFT 12 +#define PIT_PRIO_SHIFT 20 +#define PIT_ENABLE_SHIFT 26 +#define PIT_IRQ_MASK 0x3f +#define PIT_PRIO_MASK 0xf + +#define REG_PITEN 0x00 +#define REG_THROT 0x10 +#define REG_COUNT 0x14 +#define REG_BUSPD 0x18 +#define REG_SECHI 0x20 +#define REG_SECLO 0x24 +#define REG_NSEC 0x28 + +struct jcore_clocksource { + struct clocksource cs; + __iomem void *base; +}; + +struct jcore_pit { + struct clock_event_device ced; + __iomem void *base; + unsigned long periodic_delta; + unsigned cpu; + phys_addr_t paddr; + resource_size_t psize; + u32 enable_val; +}; + +struct jcore_pit_nb { + struct notifier_block nb; + struct jcore_pit __percpu *pit_percpu; +}; + +static cycle_t jcore_clocksource_read(struct clocksource *cs) +{ + __iomem void *base = + container_of(cs, struct jcore_clocksource, cs)->base; + u32 sechi, seclo, nsec, sechi0, seclo0; + + sechi = __raw_readl(base + REG_SECHI); + seclo = __raw_readl(base + REG_SECLO); + do
[PATCH v3 04/12] of: add J-Core timer bindings
Signed-off-by: Rich Felker--- .../devicetree/bindings/timer/jcore,pit.txt| 28 ++ 1 file changed, 28 insertions(+) create mode 100644 Documentation/devicetree/bindings/timer/jcore,pit.txt diff --git a/Documentation/devicetree/bindings/timer/jcore,pit.txt b/Documentation/devicetree/bindings/timer/jcore,pit.txt new file mode 100644 index 000..96c6815 --- /dev/null +++ b/Documentation/devicetree/bindings/timer/jcore,pit.txt @@ -0,0 +1,28 @@ +J-Core Programmable Interval Timer and Clocksource + +Required properties: + +- compatible: Must be "jcore,pit". + +- reg: Memory region for timer/clocksource registers. + +- interrupts: An interrupt to assign for the timer. The actual pit + core is integrated with the aic and allows the timer interrupt + assignment to be programmed by software, but this property is + required in order to reserve an interrupt number that doesn't + conflict with other devices. + +Optional properties: + +- cpu-offset: For SMP, the per-cpu offset to the local timer + programming memory range. + + +Example: + +timer@200 { + compatible = "jcore,pit"; + reg = < 0x200 0x30 >; + cpu-offset = < 0x300 >; + interrupts = < 0x48 >; +}; -- 2.8.1
[PATCH v3 00/12] J-core J2 cpu and SoC peripherals support
The following patchset adds support for the J-core J2, an open-source VHDL reimplementation of the SH-2 ISA, and drivers for the associated SoC devices (interrupt controller, clocksource, and SPI). As arch/sh co-maintainer my intent is to include as much as possible in my pull request for the linux-sh tree. If there are parts outside of arch/sh that can be included in this, please let me know. I'm not clear yet on what the right path to upstream is for the clocksource and irq drivers that are currently only useful/interesting for one arch, or for the DT binding patches. Even if some drivers are delayed going upstream, I would really like to get DT bindings acked and ideally merged, because we want to go ahead with moving the DTB into J2 boot rom where it belongs, and that should only happen with stable bindings. Rich Felker (12): of: add vendor prefix for J-Core of: add J-Core cpu bindings of: add J-Core interrupt controller bindings of: add J-Core timer bindings of: add J-Core SPI master bindings sh: add support for J-Core J2 processor sh: add AT_HWCAP flag for J-Core cas.l instruction irqchip: add J-Core AIC driver clocksource: add J-Core timer/clocksource driver spi: add driver for J-Core SPI controller sh: add defconfig for J-Core J2 sh: add device tree source for J2 FPGA on Mimas v2 board .../bindings/interrupt-controller/jcore,aic.txt| 29 +++ Documentation/devicetree/bindings/jcore/cpus.txt | 92 +++ .../devicetree/bindings/spi/jcore,spi.txt | 23 ++ .../devicetree/bindings/timer/jcore,pit.txt| 28 ++ .../devicetree/bindings/vendor-prefixes.txt| 1 + arch/sh/Kconfig| 8 + arch/sh/Makefile | 1 + arch/sh/boot/dts/j2_mimas_v2.dts | 87 +++ arch/sh/configs/j2_defconfig | 38 +++ arch/sh/include/asm/processor.h| 2 +- arch/sh/include/uapi/asm/cpu-features.h| 1 + arch/sh/kernel/cpu/init.c | 2 +- arch/sh/kernel/cpu/proc.c | 1 + arch/sh/kernel/cpu/sh2/entry.S | 5 + arch/sh/kernel/cpu/sh2/probe.c | 36 ++- arch/sh/mm/Makefile| 3 +- arch/sh/mm/cache-j2.c | 58 + arch/sh/mm/cache.c | 6 +- drivers/clocksource/Kconfig| 8 + drivers/clocksource/Makefile | 1 + drivers/clocksource/jcore-pit.c| 282 + drivers/irqchip/Kconfig| 6 + drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-jcore-aic.c| 95 +++ drivers/spi/Kconfig| 4 + drivers/spi/Makefile | 1 + drivers/spi/spi-jcore.c| 209 +++ 27 files changed, 1023 insertions(+), 5 deletions(-) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/jcore,aic.txt create mode 100644 Documentation/devicetree/bindings/jcore/cpus.txt create mode 100644 Documentation/devicetree/bindings/spi/jcore,spi.txt create mode 100644 Documentation/devicetree/bindings/timer/jcore,pit.txt create mode 100755 arch/sh/boot/dts/j2_mimas_v2.dts create mode 100644 arch/sh/configs/j2_defconfig create mode 100644 arch/sh/mm/cache-j2.c create mode 100644 drivers/clocksource/jcore-pit.c create mode 100644 drivers/irqchip/irq-jcore-aic.c create mode 100644 drivers/spi/spi-jcore.c -- 2.8.1
[PATCH v3 03/12] of: add J-Core interrupt controller bindings
Signed-off-by: Rich Felker --- .../bindings/interrupt-controller/jcore,aic.txt| 29 ++ 1 file changed, 29 insertions(+) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/jcore,aic.txt diff --git a/Documentation/devicetree/bindings/interrupt-controller/jcore,aic.txt b/Documentation/devicetree/bindings/interrupt-controller/jcore,aic.txt new file mode 100644 index 000..5dc99b9 --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/jcore,aic.txt @@ -0,0 +1,29 @@ +J-Core Advanced Interrupt Controller + +Required properties: + +- compatible : Should be "jcore,aic1" for the (obsolete) first-generation aic + with 8 interrupt lines with programmable priorities, or "jcore,aic2" for + the "aic2" core with 64 interrupts. + +- reg : Memory region for configuration. + +- interrupt-controller : Identifies the node as an interrupt controller + +- #interrupt-cells : Specifies the number of cells needed to encode an + interrupt source. The value shall be 1. + +Optional properties: + +- cpu-offset : For SMP, the offset to the per-cpu memory region for + configuration, to be scaled by the cpu number. + + +Example: + +aic: interrupt-controller@200 { + compatible = "jcore,aic2"; + reg = < 0x200 0x10 >; + interrupt-controller; + #interrupt-cells = <1>; +}; -- 2.8.1
Re: [PATCH 1/5] PCI: Add a new PCI_BUS_FLAGS_MSI_REMAP flag
On 2016/5/25 4:55, Bjorn Helgaas wrote: On Wed, Apr 27, 2016 at 08:43:26PM +0800, Yongji Xie wrote: We introduce a new pci_bus_flags, PCI_BUS_FLAGS_MSI_REMAP which indicates all devices on the bus are protected by the hardware which supports IRQ remapping(intel naming). This changelog is ambiguous. It's possible that there is hardware that *supports* IRQ remapping, but does not actually *do* IRQ remapping. For example, an IRQ remapping capability may be present but not enabled. I think your intent is to set this flag only when MSI remapping is actually *enabled* for all devices on the bus. Yes. This is exactly my intent. Thank you for the correction! I'd also like to know exactly what protection is implied by PCI_BUS_FLAGS_MSI_REMAP and IOMMU_CAP_INTR_REMAP. I guess it means a device can only generate MSIs to a certain set of CPUs? I assume the remapping hardware only checks the target address, not the data being written? When IRQ remapping is enabled, the hardware will check both target address and data, then compute the interrupt_index from them. Interrupt_index will be used to find a specific Interrupt Remapping Table Entry containing some fields which could be used to identify a device or a group of devices(these devices should be in the same isolation domain). Then hardware can use this to verify the interrupt request. If the interrupt request is not from the specific devices, it will be blocked. So this flag indicate that the hardware can ensure that a given PCI device can only shoot the MSIs assigned for it. When there is something wrong with MSI in device or device driver, this can prevent all damage from it. Regards, Yongji
[PATCH v3 06/12] sh: add support for J-Core J2 processor
At the CPU/ISA level, the J2 is compatible with SH-2, and thus the changes to add J2 support build on existing SH-2 support. However, J2 does not duplicate the memory-mapped SH-2 features like the cache interface. Instead, the cache interfaces is described in the device tree, and new code is added to be able to access the flat device tree at early boot before it is unflattened. Support is also added for receiving interrupts on trap numbers in the range 16 to 31, since the J-Core aic1 interrupt controller generates these traps. This range was unused but nominally for hardware exceptions on SH-2, and a few values in this range were used for exceptions on SH-2A, but SH-2A has its own version of the relevant code. No individual cpu subtypes are added for J2 since the intent moving forward is to represent SoCs with device tree rather than as hard-coded subtypes in the kernel. The CPU_SUBTYPE_J2 Kconfig item exists only to fit into the existing cpu selection mechanism until it is overhauled. Signed-off-by: Rich Felker --- Aside from adding commit message, this version of patch #6 in the series only makes minor changes: spelling out SEI's name in a copyright comment, and moving one asm insn that was placed on the wrong side of an #ifdef (harmless but wrong). arch/sh/Kconfig | 8 ++ arch/sh/Makefile| 1 + arch/sh/include/asm/processor.h | 2 +- arch/sh/kernel/cpu/init.c | 2 +- arch/sh/kernel/cpu/proc.c | 1 + arch/sh/kernel/cpu/sh2/entry.S | 5 arch/sh/kernel/cpu/sh2/probe.c | 34 +++- arch/sh/mm/Makefile | 3 ++- arch/sh/mm/cache-j2.c | 58 + arch/sh/mm/cache.c | 6 - 10 files changed, 115 insertions(+), 5 deletions(-) create mode 100644 arch/sh/mm/cache-j2.c diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 4fa5894..efb0af4 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -182,6 +182,10 @@ config CPU_SH2A select CPU_SH2 select UNCACHED_MAPPING +config CPU_J2 + bool + select CPU_SH2 + config CPU_SH3 bool select CPU_HAS_INTEVT @@ -248,6 +252,10 @@ config CPU_SUBTYPE_SH7619 select CPU_SH2 select SYS_SUPPORTS_SH_CMT +config CPU_SUBTYPE_J2 + bool "Support J2 processor" + select CPU_J2 + # SH-2A Processor Support config CPU_SUBTYPE_SH7201 diff --git a/arch/sh/Makefile b/arch/sh/Makefile index 3b2c8b4..0047666 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -31,6 +31,7 @@ isa-y := $(isa-y)-up endif cflags-$(CONFIG_CPU_SH2) := $(call cc-option,-m2,) +cflags-$(CONFIG_CPU_J2):= $(call cc-option,-mj2,) cflags-$(CONFIG_CPU_SH2A) += $(call cc-option,-m2a,) \ $(call cc-option,-m2a-nofpu,) \ $(call cc-option,-m4-nofpu,) diff --git a/arch/sh/include/asm/processor.h b/arch/sh/include/asm/processor.h index 1506897..f9a0994 100644 --- a/arch/sh/include/asm/processor.h +++ b/arch/sh/include/asm/processor.h @@ -15,7 +15,7 @@ */ enum cpu_type { /* SH-2 types */ - CPU_SH7619, + CPU_SH7619, CPU_J2, /* SH-2A types */ CPU_SH7201, CPU_SH7203, CPU_SH7206, CPU_SH7263, CPU_SH7264, CPU_SH7269, diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c index bfd9e27..c8b3be1 100644 --- a/arch/sh/kernel/cpu/init.c +++ b/arch/sh/kernel/cpu/init.c @@ -106,7 +106,7 @@ void __attribute__ ((weak)) l2_cache_init(void) /* * Generic first-level cache init */ -#ifdef CONFIG_SUPERH32 +#if defined(CONFIG_SUPERH32) && !defined(CONFIG_CPU_J2) static void cache_init(void) { unsigned long ccr, flags; diff --git a/arch/sh/kernel/cpu/proc.c b/arch/sh/kernel/cpu/proc.c index 9e6624c..4df4b28 100644 --- a/arch/sh/kernel/cpu/proc.c +++ b/arch/sh/kernel/cpu/proc.c @@ -27,6 +27,7 @@ static const char *cpu_name[] = { [CPU_MXG] = "MX-G", [CPU_SH7723]= "SH7723", [CPU_SH7366]= "SH7366", [CPU_SH7724]= "SH7724", [CPU_SH7372]= "SH7372", [CPU_SH7734]= "SH7734", + [CPU_J2]= "J2", [CPU_SH_NONE] = "Unknown" }; diff --git a/arch/sh/kernel/cpu/sh2/entry.S b/arch/sh/kernel/cpu/sh2/entry.S index a150595..16bde0e 100644 --- a/arch/sh/kernel/cpu/sh2/entry.S +++ b/arch/sh/kernel/cpu/sh2/entry.S @@ -147,6 +147,11 @@ ENTRY(exception_handler) mov #31,r8 cmp/hs r8,r9 bt trap_entry ! 64 > vec >= 31 is trap +#ifdef CONFIG_CPU_J2 + mov #16,r8 + cmp/hs r8,r9 + bt interrupt_entry ! 31 > vec >= 16 is interrupt +#endif mov.l 4f,r8 mov r9,r4 diff --git a/arch/sh/kernel/cpu/sh2/probe.c b/arch/sh/kernel/cpu/sh2/probe.c index 6c687ae..3dd8187 100644 --- a/arch/sh/kernel/cpu/sh2/probe.c +++
[PATCH v3 04/12] of: add J-Core timer bindings
Signed-off-by: Rich Felker --- .../devicetree/bindings/timer/jcore,pit.txt| 28 ++ 1 file changed, 28 insertions(+) create mode 100644 Documentation/devicetree/bindings/timer/jcore,pit.txt diff --git a/Documentation/devicetree/bindings/timer/jcore,pit.txt b/Documentation/devicetree/bindings/timer/jcore,pit.txt new file mode 100644 index 000..96c6815 --- /dev/null +++ b/Documentation/devicetree/bindings/timer/jcore,pit.txt @@ -0,0 +1,28 @@ +J-Core Programmable Interval Timer and Clocksource + +Required properties: + +- compatible: Must be "jcore,pit". + +- reg: Memory region for timer/clocksource registers. + +- interrupts: An interrupt to assign for the timer. The actual pit + core is integrated with the aic and allows the timer interrupt + assignment to be programmed by software, but this property is + required in order to reserve an interrupt number that doesn't + conflict with other devices. + +Optional properties: + +- cpu-offset: For SMP, the per-cpu offset to the local timer + programming memory range. + + +Example: + +timer@200 { + compatible = "jcore,pit"; + reg = < 0x200 0x30 >; + cpu-offset = < 0x300 >; + interrupts = < 0x48 >; +}; -- 2.8.1
[PATCH v3 09/12] clocksource: add J-Core timer/clocksource driver
At the hardware level, the J-Core PIT is integrated with the interrupt controller, but it is represented as its own device and has an independent programming interface. It provides a 12-bit countdown timer, which is not presently used, and a periodic timer. The interval length for the latter is programmable via a 32-bit throttle register whose units are determined by a bus-period register. The periodic timer is used to implement both periodic and oneshot clock event modes; in oneshot mode the interrupt handler simply disables the timer as soon as it fires. Despite its device tree node representing an interrupt for the PIT, the actual irq generated is programmable, not hard-wired. The driver is responsible for programming the PIT to generate the hardware irq number that the DT assigns to it. On SMP configurations, J-Core provides cpu-local instances of the PIT; no broadcast timer is needed. This driver supports the creation of the necessary per-cpu clock_event_device instances. The code has been tested and works on SMP, but will not be usable without additional J-Core SMP-support patches and appropriate hardware capable of running SMP. A nanosecond-resolution clocksource is provided using the J-Core "RTC" registers, which give a 64-bit seconds count and 32-bit nanoseconds. The driver converts these to a 64-bit nanoseconds count. Signed-off-by: Rich Felker --- This driver has undergone significant changes based on feedback from Daniel Lezcano. I've split out helper functions, eliminated the repeated percpu offset computations, properly mapped each percpu base, used container_of instead of static storage for driver data, added comments for enable_val setup, removed confusing use of "RTC" name, removed excess includes, used the "jcore_" prefix in naming identifiers, and made error handling more extensive. drivers/clocksource/Kconfig | 8 ++ drivers/clocksource/Makefile| 1 + drivers/clocksource/jcore-pit.c | 282 3 files changed, 291 insertions(+) create mode 100644 drivers/clocksource/jcore-pit.c diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index c346be6..7bd39d2 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -297,6 +297,14 @@ config SYS_SUPPORTS_SH_TMU config SYS_SUPPORTS_EM_STI bool +config CLKSRC_JCORE_PIT + bool "J-Core PIT timer driver" + depends on GENERIC_CLOCKEVENTS + depends on HAS_IOMEM + help + This enables build of clocksource and clockevent driver for + the integrated PIT in the J-Core synthesizable, open source SoC. + config SH_TIMER_CMT bool "Renesas CMT timer driver" if COMPILE_TEST depends on GENERIC_CLOCKEVENTS diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index dc2b899..d825fcf 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_ATMEL_TCB_CLKSRC) += tcb_clksrc.o obj-$(CONFIG_X86_PM_TIMER) += acpi_pm.o obj-$(CONFIG_SCx200HR_TIMER) += scx200_hrt.o obj-$(CONFIG_CS5535_CLOCK_EVENT_SRC) += cs5535-clockevt.o +obj-$(CONFIG_CLKSRC_JCORE_PIT) += jcore-pit.o obj-$(CONFIG_SH_TIMER_CMT) += sh_cmt.o obj-$(CONFIG_SH_TIMER_MTU2)+= sh_mtu2.o obj-$(CONFIG_SH_TIMER_TMU) += sh_tmu.o diff --git a/drivers/clocksource/jcore-pit.c b/drivers/clocksource/jcore-pit.c new file mode 100644 index 000..dd78fcd --- /dev/null +++ b/drivers/clocksource/jcore-pit.c @@ -0,0 +1,282 @@ +/* + * J-Core SoC PIT/clocksource driver + * + * Copyright (C) 2015-2016 Smart Energy Instruments, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define PIT_IRQ_SHIFT 12 +#define PIT_PRIO_SHIFT 20 +#define PIT_ENABLE_SHIFT 26 +#define PIT_IRQ_MASK 0x3f +#define PIT_PRIO_MASK 0xf + +#define REG_PITEN 0x00 +#define REG_THROT 0x10 +#define REG_COUNT 0x14 +#define REG_BUSPD 0x18 +#define REG_SECHI 0x20 +#define REG_SECLO 0x24 +#define REG_NSEC 0x28 + +struct jcore_clocksource { + struct clocksource cs; + __iomem void *base; +}; + +struct jcore_pit { + struct clock_event_device ced; + __iomem void *base; + unsigned long periodic_delta; + unsigned cpu; + phys_addr_t paddr; + resource_size_t psize; + u32 enable_val; +}; + +struct jcore_pit_nb { + struct notifier_block nb; + struct jcore_pit __percpu *pit_percpu; +}; + +static cycle_t jcore_clocksource_read(struct clocksource *cs) +{ + __iomem void *base = + container_of(cs, struct jcore_clocksource, cs)->base; + u32 sechi, seclo, nsec, sechi0, seclo0; + + sechi = __raw_readl(base + REG_SECHI); + seclo = __raw_readl(base + REG_SECLO); + do { +
[PATCH v3 02/12] of: add J-Core cpu bindings
Signed-off-by: Rich Felker--- Documentation/devicetree/bindings/jcore/cpus.txt | 92 1 file changed, 92 insertions(+) create mode 100644 Documentation/devicetree/bindings/jcore/cpus.txt diff --git a/Documentation/devicetree/bindings/jcore/cpus.txt b/Documentation/devicetree/bindings/jcore/cpus.txt new file mode 100644 index 000..9d77ec1 --- /dev/null +++ b/Documentation/devicetree/bindings/jcore/cpus.txt @@ -0,0 +1,92 @@ +=== +J-Core cpu bindings +=== + +The J-Core processors are open source CPU cores that can be built as FPGA +soft cores or ASICs. The device tree is also responsible for describing the +cache controls and, for SMP configurations, all details of the SMP method, +as documented below. + + +- +Top-level "cpus" node +- + +Required properties: + +- #address-cells: Must be 1. + +- #size-cells: Must be 0. + +Optional properties: + +- enable-method: Required only for SMP systems. If present, must be + "jcore,spin-table". + + + +Individual cpu nodes + + +Required properties: + +- device_type: Must be "cpu". + +- compatible: Must be "jcore,j2". + +- reg: Must be 0 on uniprocessor systems, or the sequential, zero-based + hardware cpu id on SMP systems. + +Optional properties: + +- clock-frequency: Clock frequency of the cpu in Hz. + +- cpu-release-addr: Necessary only for secondary processors on SMP systems + using the "jcore,spin-table" enable method. If present, must consist of + two cells containing physical addresses. The first cell contains an + address which, when written, unblocks the secondary cpu. The second cell + contains an address from which the cpu will read its initial program + counter when unblocked. + + +- +Cache controller node +- + +Required properties: + +- compatible: Must be "jcore,cache". + +- reg: A memory range for the cache controller registers. + + + +IPI node + + +Device trees for SMP systems must have an IPI node representing the mechanism +used for inter-processor interrupt generation. + +Required properties: + +- compatible: Must be "jcore,ipi-controller". + +- reg: A memory range used to IPI generation. + +- interrupts: An irq on which IPI will be received. + + +-- +CPUID node +-- + +Device trees for SMP systems must have a CPUID node representing the mechanism +used to identify the current processor on which execution is taking place. + +Required properties: + +- compatible: Must be "jcore,cpuid-mmio". + +- reg: A memory range containing a single 32-bit mmio register which produces + the current cpu id (matching the "reg" property of the cpu performing the + read) when read. -- 2.8.1
[PATCH v3 02/12] of: add J-Core cpu bindings
Signed-off-by: Rich Felker --- Documentation/devicetree/bindings/jcore/cpus.txt | 92 1 file changed, 92 insertions(+) create mode 100644 Documentation/devicetree/bindings/jcore/cpus.txt diff --git a/Documentation/devicetree/bindings/jcore/cpus.txt b/Documentation/devicetree/bindings/jcore/cpus.txt new file mode 100644 index 000..9d77ec1 --- /dev/null +++ b/Documentation/devicetree/bindings/jcore/cpus.txt @@ -0,0 +1,92 @@ +=== +J-Core cpu bindings +=== + +The J-Core processors are open source CPU cores that can be built as FPGA +soft cores or ASICs. The device tree is also responsible for describing the +cache controls and, for SMP configurations, all details of the SMP method, +as documented below. + + +- +Top-level "cpus" node +- + +Required properties: + +- #address-cells: Must be 1. + +- #size-cells: Must be 0. + +Optional properties: + +- enable-method: Required only for SMP systems. If present, must be + "jcore,spin-table". + + + +Individual cpu nodes + + +Required properties: + +- device_type: Must be "cpu". + +- compatible: Must be "jcore,j2". + +- reg: Must be 0 on uniprocessor systems, or the sequential, zero-based + hardware cpu id on SMP systems. + +Optional properties: + +- clock-frequency: Clock frequency of the cpu in Hz. + +- cpu-release-addr: Necessary only for secondary processors on SMP systems + using the "jcore,spin-table" enable method. If present, must consist of + two cells containing physical addresses. The first cell contains an + address which, when written, unblocks the secondary cpu. The second cell + contains an address from which the cpu will read its initial program + counter when unblocked. + + +- +Cache controller node +- + +Required properties: + +- compatible: Must be "jcore,cache". + +- reg: A memory range for the cache controller registers. + + + +IPI node + + +Device trees for SMP systems must have an IPI node representing the mechanism +used for inter-processor interrupt generation. + +Required properties: + +- compatible: Must be "jcore,ipi-controller". + +- reg: A memory range used to IPI generation. + +- interrupts: An irq on which IPI will be received. + + +-- +CPUID node +-- + +Device trees for SMP systems must have a CPUID node representing the mechanism +used to identify the current processor on which execution is taking place. + +Required properties: + +- compatible: Must be "jcore,cpuid-mmio". + +- reg: A memory range containing a single 32-bit mmio register which produces + the current cpu id (matching the "reg" property of the cpu performing the + read) when read. -- 2.8.1
[PATCH v3 10/12] spi: add driver for J-Core SPI controller
The J-Core "spi2" device is a PIO-based SPI master controller. It differs from "bitbang" devices in that that it's clocked in hardware rather than via soft clock modulation over gpio, and performs byte-at-a-time transfers between the cpu and SPI controller. This driver will be extended to support future versions of the J-Core SPI controller with DMA transfers when they become available. Signed-off-by: Rich Felker--- This version of the SPI patch eliminates USE_MESSAGE_MODE (the open coding of transfer_one_message logic) and makes severl other minor changes based on ml discussion of the v2 patch. The chipselect change has not been made yet, except for rewriting the current logic to be more clear. If the decision is that it's needed, I can do it easily, but it needs testing still. drivers/spi/Kconfig | 4 + drivers/spi/Makefile| 1 + drivers/spi/spi-jcore.c | 209 3 files changed, 214 insertions(+) create mode 100644 drivers/spi/spi-jcore.c diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 9d8c84b..5bd2ccf 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -285,6 +285,10 @@ config SPI_IMX This enables using the Freescale i.MX SPI controllers in master mode. +config SPI_JCORE + tristate "J-Core SPI Master" + depends on OF + config SPI_LM70_LLP tristate "Parallel port adapter for LM70 eval board (DEVELOPMENT)" depends on PARPORT diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index fbb255c..6a34124 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -46,6 +46,7 @@ obj-$(CONFIG_SPI_FSL_SPI) += spi-fsl-spi.o obj-$(CONFIG_SPI_GPIO) += spi-gpio.o obj-$(CONFIG_SPI_IMG_SPFI) += spi-img-spfi.o obj-$(CONFIG_SPI_IMX) += spi-imx.o +obj-$(CONFIG_SPI_JCORE)+= spi-jcore.o obj-$(CONFIG_SPI_LM70_LLP) += spi-lm70llp.o obj-$(CONFIG_SPI_LP8841_RTC) += spi-lp8841-rtc.o obj-$(CONFIG_SPI_MESON_SPIFC) += spi-meson-spifc.o diff --git a/drivers/spi/spi-jcore.c b/drivers/spi/spi-jcore.c new file mode 100644 index 000..f239087 --- /dev/null +++ b/drivers/spi/spi-jcore.c @@ -0,0 +1,209 @@ +/* + * J-Core SPI controller driver + * + * Copyright (C) 2012-2016 Smart Energy Instruments, Inc. + * + * Current version by Rich Felker + * Based loosely on initial version by Oleksandr G Zhadan + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRV_NAME "jcore_spi" + +#define MAX_SPI_SPEED 1250/* 12.5 MHz */ + +#define CTRL_REG 0x0 +#define DATA_REG 0x4 + +#define SPI_NOCHIP_CS 0 +#define SPI_FLASH_CS 1 +#define SPI_CONF_CS2 +#define SPI_SD_CS 2 +#define SPI_CODEC_CS 3 + +#define JCORE_SPI_CTRL_XMIT0x02 +#define JCORE_SPI_STAT_BUSY0x02 +#define JCORE_SPI_CTRL_LOOP0x08 +#define JCORE_SPI_CTRL_CS_BITS 0x15 + +#define JCORE_SPI_WAIT_RDY_MAX_LOOP200 + +struct jcore_spi { + struct spi_master *master; + void __iomem *base; + volatile unsigned int ctrlReg; + unsigned int csReg; + unsigned int speedReg; + unsigned int speed_hz; +}; + +static void jcore_spi_wait_till_ready(struct jcore_spi *hw, int timeout) +{ + while (timeout--) { + hw->ctrlReg = readl(hw->base + CTRL_REG); + if (!(hw->ctrlReg & JCORE_SPI_STAT_BUSY)) + return; + cpu_relax(); + } + dev_err(hw->master->dev.parent, "%s: Timeout..\n", __func__); +} + +static void jcore_spi_program(struct jcore_spi *hw) +{ + jcore_spi_wait_till_ready(hw, JCORE_SPI_WAIT_RDY_MAX_LOOP); + writel(hw->csReg | hw->speedReg, hw->base + CTRL_REG); +} + +static void jcore_spi_chipsel(struct spi_device *spi, bool value) +{ + struct jcore_spi *hw = spi_master_get_devdata(spi->master); + + dev_dbg(hw->master->dev.parent, "%s: CS=%d\n", __func__, value); + + hw->csReg = JCORE_SPI_CTRL_CS_BITS ^ (!value << 2*spi->chip_select); + + jcore_spi_program(hw); +} + +static void jcore_spi_baudrate(struct jcore_spi *hw, int speed) +{ + if (speed == hw->speed_hz) return; + hw->speed_hz = speed; + hw->speedReg = ((MAX_SPI_SPEED / speed) - 1) << 27; + jcore_spi_program(hw); + dev_dbg(hw->master->dev.parent, "%s: speed=%d pre=0x%x\n", + __func__, speed, hw->speedReg); +} + +static int jcore_spi_txrx(struct spi_master *master, struct spi_device *spi, + struct spi_transfer *t) +{ + struct jcore_spi *hw = spi_master_get_devdata(master); + + void *ctrl_reg = hw->base + CTRL_REG; + void *data_reg = hw->base + DATA_REG; + unsigned int timeout; + u32 xmit; + u32 status; + + /* data buffers */ + const unsigned char *tx; +
[PATCH v3 12/12] sh: add device tree source for J2 FPGA on Mimas v2 board
Signed-off-by: Rich Felker--- arch/sh/boot/dts/j2_mimas_v2.dts | 87 1 file changed, 87 insertions(+) create mode 100755 arch/sh/boot/dts/j2_mimas_v2.dts diff --git a/arch/sh/boot/dts/j2_mimas_v2.dts b/arch/sh/boot/dts/j2_mimas_v2.dts new file mode 100755 index 000..4a66cda --- /dev/null +++ b/arch/sh/boot/dts/j2_mimas_v2.dts @@ -0,0 +1,87 @@ +/dts-v1/; + +/ { + compatible = "jcore,j2-soc"; + model = "J2 FPGA SoC on Mimas v2 board"; + + #address-cells = <1>; + #size-cells = <1>; + + interrupt-parent = <>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "jcore,j2"; + reg = < 0 >; + clock-frequency = < 5000 >; + }; + }; + + memory@1000 { + device_type = "memory"; + reg = < 0x1000 0x400 >; + }; + + chosen { + stdout-path = "/soc@abcd/serial@100"; + }; + + soc@abcd { + compatible = "simple-bus"; + ranges = <0 0xabcd 0x10>; + + #address-cells = <1>; + #size-cells = <1>; + + aic: interrupt-controller@200 { + compatible = "jcore,aic1"; + reg = < 0x200 0x10 >; + interrupt-controller; + #interrupt-cells = <1>; + }; + + cache-controller@c0 { + compatible = "jcore,cache"; + reg = < 0xc0 4 >; + }; + + timer@200 { + compatible = "jcore,pit"; + reg = < 0x200 0x30 >; + interrupts = < 0x48 >; + }; + + spi@40 { + compatible = "jcore,spi2"; + + #address-cells = <1>; + #size-cells = <0>; + + spi-max-frequency = <1250>; + + reg = < 0x40 0x8 >; + + sdcard@0 { + compatible = "mmc-spi-slot"; + reg = <0>; + spi-max-frequency = <1250>; + voltage-ranges = <3200 3400>; + mode = <0>; + }; + }; + + serial@100 { + clock-frequency = <12500>; + compatible = "xlnx,xps-uartlite-1.00.a"; + current-speed = <19200>; + device_type = "serial"; + interrupts = < 0x12 >; + port-number = <0>; + reg = < 0x100 0x10 >; + }; + }; +}; -- 2.8.1
[PATCH v3 11/12] sh: add defconfig for J-Core J2
This defconfig is intended not to be specific to a particular board; it enables drivers for all currently-supported hardware, and should be updated to include additional drivers as they are added. Signed-off-by: Rich Felker--- arch/sh/configs/j2_defconfig | 38 ++ 1 file changed, 38 insertions(+) create mode 100644 arch/sh/configs/j2_defconfig diff --git a/arch/sh/configs/j2_defconfig b/arch/sh/configs/j2_defconfig new file mode 100644 index 000..fca167f --- /dev/null +++ b/arch/sh/configs/j2_defconfig @@ -0,0 +1,38 @@ +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_CPU_SUBTYPE_J2=y +CONFIG_MEMORY_START=0x1000 +CONFIG_MEMORY_SIZE=0x0400 +CONFIG_CPU_BIG_ENDIAN=y +CONFIG_SH_DEVICE_TREE=y +CONFIG_HZ_100=y +CONFIG_CMDLINE_OVERWRITE=y +CONFIG_CMDLINE="console=ttyUL0 earlycon" +CONFIG_BINFMT_ELF_FDPIC=y +CONFIG_BINFMT_FLAT=y +CONFIG_NET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_NETDEVICES=y +CONFIG_SERIAL_UARTLITE=y +CONFIG_SERIAL_UARTLITE_CONSOLE=y +CONFIG_I2C=y +CONFIG_SPI=y +CONFIG_SPI_JCORE=y +CONFIG_WATCHDOG=y +CONFIG_MMC=y +CONFIG_MMC_SPI=y +CONFIG_CLKSRC_JCORE_PIT=y +CONFIG_JCORE_AIC=y +CONFIG_EXT4_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_IOCHARSET="ascii" +CONFIG_FAT_DEFAULT_UTF8=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ASCII=y +CONFIG_NLS_UTF8=y -- 2.8.1
[PATCH v3 08/12] irqchip: add J-Core AIC driver
There are two versions of the J-Core interrupt controller in use, aic1 which generates interrupts with programmable priorities, but only supports 8 irq lines and maps them to cpu traps in the range 17 to 24, and aic2 which uses traps in the range 64-127 and supports up to 128 irqs, with priorities dependent on the interrupt number. The Linux driver does not make use of priorities anyway. For simplicity, there is no aic1-specific logic in the driver beyond setting the priority register, which is necessary for interrupts to work at all. Eventually aic1 will likely be phased out, but it's currently in use in deployments and all released bitstream binaries. Signed-off-by: Rich Felker--- This version fixes a missing "static" reported in the previous version of the patch. I missed Marc Zyngier's reply to the v2 when preparing the v3 patch series, but I'm still not sure exactly what, if any, changes should come out of that discussion, and they'll probably mostly in the area of comments or changelog. drivers/irqchip/Kconfig | 6 +++ drivers/irqchip/Makefile| 1 + drivers/irqchip/irq-jcore-aic.c | 95 + 3 files changed, 102 insertions(+) create mode 100644 drivers/irqchip/irq-jcore-aic.c diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 3e12479..3cb37d6 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -149,6 +149,12 @@ config PIC32_EVIC select GENERIC_IRQ_CHIP select IRQ_DOMAIN +config JCORE_AIC + bool "J-Core integrated AIC" + select IRQ_DOMAIN + help + Support for the J-Core integrated AIC. + config RENESAS_INTC_IRQPIN bool select IRQ_DOMAIN diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index b03cfcb..5a1f1bf 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_I8259) += irq-i8259.o obj-$(CONFIG_IMGPDC_IRQ) += irq-imgpdc.o obj-$(CONFIG_IRQ_MIPS_CPU) += irq-mips-cpu.o obj-$(CONFIG_SIRF_IRQ) += irq-sirfsoc.o +obj-$(CONFIG_JCORE_AIC)+= irq-jcore-aic.o obj-$(CONFIG_RENESAS_INTC_IRQPIN) += irq-renesas-intc-irqpin.o obj-$(CONFIG_RENESAS_IRQC) += irq-renesas-irqc.o obj-$(CONFIG_VERSATILE_FPGA_IRQ) += irq-versatile-fpga.o diff --git a/drivers/irqchip/irq-jcore-aic.c b/drivers/irqchip/irq-jcore-aic.c new file mode 100644 index 000..1348cdb --- /dev/null +++ b/drivers/irqchip/irq-jcore-aic.c @@ -0,0 +1,95 @@ +/* + * J-Core SoC AIC driver + * + * Copyright (C) 2015-2016 Smart Energy Instruments, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define AIC1_INTPRI 8 + +static struct aic_data { + unsigned char __iomem *base; + u32 cpu_offset; + struct irq_chip chip; + struct irq_domain *domain; + struct notifier_block nb; +} aic_data; + +static int aic_irqdomain_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hwirq) +{ + struct aic_data *aic = d->host_data; + + irq_set_chip_data(irq, aic); + irq_set_chip_and_handler(irq, >chip, handle_simple_irq); + irq_set_probe(irq); + + return 0; +} + +static const struct irq_domain_ops aic_irqdomain_ops = { + .map = aic_irqdomain_map, + .xlate = irq_domain_xlate_onecell, +}; + +static void noop(struct irq_data *data) +{ +} + +static void aic1_localenable(struct aic_data *aic) +{ + unsigned cpu = smp_processor_id(); + pr_info("Local AIC enable on cpu %u\n", cpu); + writel(0x, aic->base + cpu * aic->cpu_offset + AIC1_INTPRI); +} + +static int aic1_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) +{ + switch (action & ~CPU_TASKS_FROZEN) { + case CPU_STARTING: + aic1_localenable(container_of(self, struct aic_data, nb)); + break; + } + return NOTIFY_OK; +} + +int __init aic_irq_of_init(struct device_node *node, struct device_node *parent) +{ + struct aic_data *aic = _data; + + aic->base = of_iomap(node, 0); + of_property_read_u32(node, "cpu-offset", >cpu_offset); + + pr_info("Initializing J-Core AIC at %p\n", aic->base); + + if (of_device_is_compatible(node, "jcore,aic1")) { + /* For aic1, need to enabled zero-priority-by-default irqs */ + aic->nb.notifier_call = aic1_cpu_notify; + register_cpu_notifier(>nb); + aic1_localenable(aic); + } + + aic->chip.name = node->name; + aic->chip.irq_mask = noop; + aic->chip.irq_unmask = noop; + + aic->domain = irq_domain_add_linear(node, 128,
[PATCH v3 05/12] of: add J-Core SPI master bindings
Signed-off-by: Rich Felker--- .../devicetree/bindings/spi/jcore,spi.txt | 23 ++ 1 file changed, 23 insertions(+) create mode 100644 Documentation/devicetree/bindings/spi/jcore,spi.txt diff --git a/Documentation/devicetree/bindings/spi/jcore,spi.txt b/Documentation/devicetree/bindings/spi/jcore,spi.txt new file mode 100644 index 000..7bff8c0 --- /dev/null +++ b/Documentation/devicetree/bindings/spi/jcore,spi.txt @@ -0,0 +1,23 @@ +J-Core SPI master + +Required properties: + +- compatible: Must be "jcore,spi2". + +- reg: Memory region for registers. + +- #address-cells: Must be 1. + +- #size-cells: Must be 0. + +See spi-bus.txt for additional properties not specific to this device. + +Example: + +spi@40 { + compatible = "jcore,spi2"; + #address-cells = <1>; + #size-cells = <0>; + reg = < 0x40 0x8 >; + spi-max-frequency = <1250>; +} -- 2.8.1
[PATCH v3 11/12] sh: add defconfig for J-Core J2
This defconfig is intended not to be specific to a particular board; it enables drivers for all currently-supported hardware, and should be updated to include additional drivers as they are added. Signed-off-by: Rich Felker --- arch/sh/configs/j2_defconfig | 38 ++ 1 file changed, 38 insertions(+) create mode 100644 arch/sh/configs/j2_defconfig diff --git a/arch/sh/configs/j2_defconfig b/arch/sh/configs/j2_defconfig new file mode 100644 index 000..fca167f --- /dev/null +++ b/arch/sh/configs/j2_defconfig @@ -0,0 +1,38 @@ +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_CPU_SUBTYPE_J2=y +CONFIG_MEMORY_START=0x1000 +CONFIG_MEMORY_SIZE=0x0400 +CONFIG_CPU_BIG_ENDIAN=y +CONFIG_SH_DEVICE_TREE=y +CONFIG_HZ_100=y +CONFIG_CMDLINE_OVERWRITE=y +CONFIG_CMDLINE="console=ttyUL0 earlycon" +CONFIG_BINFMT_ELF_FDPIC=y +CONFIG_BINFMT_FLAT=y +CONFIG_NET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_NETDEVICES=y +CONFIG_SERIAL_UARTLITE=y +CONFIG_SERIAL_UARTLITE_CONSOLE=y +CONFIG_I2C=y +CONFIG_SPI=y +CONFIG_SPI_JCORE=y +CONFIG_WATCHDOG=y +CONFIG_MMC=y +CONFIG_MMC_SPI=y +CONFIG_CLKSRC_JCORE_PIT=y +CONFIG_JCORE_AIC=y +CONFIG_EXT4_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_IOCHARSET="ascii" +CONFIG_FAT_DEFAULT_UTF8=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ASCII=y +CONFIG_NLS_UTF8=y -- 2.8.1
[PATCH v3 08/12] irqchip: add J-Core AIC driver
There are two versions of the J-Core interrupt controller in use, aic1 which generates interrupts with programmable priorities, but only supports 8 irq lines and maps them to cpu traps in the range 17 to 24, and aic2 which uses traps in the range 64-127 and supports up to 128 irqs, with priorities dependent on the interrupt number. The Linux driver does not make use of priorities anyway. For simplicity, there is no aic1-specific logic in the driver beyond setting the priority register, which is necessary for interrupts to work at all. Eventually aic1 will likely be phased out, but it's currently in use in deployments and all released bitstream binaries. Signed-off-by: Rich Felker --- This version fixes a missing "static" reported in the previous version of the patch. I missed Marc Zyngier's reply to the v2 when preparing the v3 patch series, but I'm still not sure exactly what, if any, changes should come out of that discussion, and they'll probably mostly in the area of comments or changelog. drivers/irqchip/Kconfig | 6 +++ drivers/irqchip/Makefile| 1 + drivers/irqchip/irq-jcore-aic.c | 95 + 3 files changed, 102 insertions(+) create mode 100644 drivers/irqchip/irq-jcore-aic.c diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 3e12479..3cb37d6 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -149,6 +149,12 @@ config PIC32_EVIC select GENERIC_IRQ_CHIP select IRQ_DOMAIN +config JCORE_AIC + bool "J-Core integrated AIC" + select IRQ_DOMAIN + help + Support for the J-Core integrated AIC. + config RENESAS_INTC_IRQPIN bool select IRQ_DOMAIN diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index b03cfcb..5a1f1bf 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_I8259) += irq-i8259.o obj-$(CONFIG_IMGPDC_IRQ) += irq-imgpdc.o obj-$(CONFIG_IRQ_MIPS_CPU) += irq-mips-cpu.o obj-$(CONFIG_SIRF_IRQ) += irq-sirfsoc.o +obj-$(CONFIG_JCORE_AIC)+= irq-jcore-aic.o obj-$(CONFIG_RENESAS_INTC_IRQPIN) += irq-renesas-intc-irqpin.o obj-$(CONFIG_RENESAS_IRQC) += irq-renesas-irqc.o obj-$(CONFIG_VERSATILE_FPGA_IRQ) += irq-versatile-fpga.o diff --git a/drivers/irqchip/irq-jcore-aic.c b/drivers/irqchip/irq-jcore-aic.c new file mode 100644 index 000..1348cdb --- /dev/null +++ b/drivers/irqchip/irq-jcore-aic.c @@ -0,0 +1,95 @@ +/* + * J-Core SoC AIC driver + * + * Copyright (C) 2015-2016 Smart Energy Instruments, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define AIC1_INTPRI 8 + +static struct aic_data { + unsigned char __iomem *base; + u32 cpu_offset; + struct irq_chip chip; + struct irq_domain *domain; + struct notifier_block nb; +} aic_data; + +static int aic_irqdomain_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hwirq) +{ + struct aic_data *aic = d->host_data; + + irq_set_chip_data(irq, aic); + irq_set_chip_and_handler(irq, >chip, handle_simple_irq); + irq_set_probe(irq); + + return 0; +} + +static const struct irq_domain_ops aic_irqdomain_ops = { + .map = aic_irqdomain_map, + .xlate = irq_domain_xlate_onecell, +}; + +static void noop(struct irq_data *data) +{ +} + +static void aic1_localenable(struct aic_data *aic) +{ + unsigned cpu = smp_processor_id(); + pr_info("Local AIC enable on cpu %u\n", cpu); + writel(0x, aic->base + cpu * aic->cpu_offset + AIC1_INTPRI); +} + +static int aic1_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) +{ + switch (action & ~CPU_TASKS_FROZEN) { + case CPU_STARTING: + aic1_localenable(container_of(self, struct aic_data, nb)); + break; + } + return NOTIFY_OK; +} + +int __init aic_irq_of_init(struct device_node *node, struct device_node *parent) +{ + struct aic_data *aic = _data; + + aic->base = of_iomap(node, 0); + of_property_read_u32(node, "cpu-offset", >cpu_offset); + + pr_info("Initializing J-Core AIC at %p\n", aic->base); + + if (of_device_is_compatible(node, "jcore,aic1")) { + /* For aic1, need to enabled zero-priority-by-default irqs */ + aic->nb.notifier_call = aic1_cpu_notify; + register_cpu_notifier(>nb); + aic1_localenable(aic); + } + + aic->chip.name = node->name; + aic->chip.irq_mask = noop; + aic->chip.irq_unmask = noop; + + aic->domain = irq_domain_add_linear(node, 128, _irqdomain_ops, aic); +
[PATCH v3 05/12] of: add J-Core SPI master bindings
Signed-off-by: Rich Felker --- .../devicetree/bindings/spi/jcore,spi.txt | 23 ++ 1 file changed, 23 insertions(+) create mode 100644 Documentation/devicetree/bindings/spi/jcore,spi.txt diff --git a/Documentation/devicetree/bindings/spi/jcore,spi.txt b/Documentation/devicetree/bindings/spi/jcore,spi.txt new file mode 100644 index 000..7bff8c0 --- /dev/null +++ b/Documentation/devicetree/bindings/spi/jcore,spi.txt @@ -0,0 +1,23 @@ +J-Core SPI master + +Required properties: + +- compatible: Must be "jcore,spi2". + +- reg: Memory region for registers. + +- #address-cells: Must be 1. + +- #size-cells: Must be 0. + +See spi-bus.txt for additional properties not specific to this device. + +Example: + +spi@40 { + compatible = "jcore,spi2"; + #address-cells = <1>; + #size-cells = <0>; + reg = < 0x40 0x8 >; + spi-max-frequency = <1250>; +} -- 2.8.1
[PATCH v3 10/12] spi: add driver for J-Core SPI controller
The J-Core "spi2" device is a PIO-based SPI master controller. It differs from "bitbang" devices in that that it's clocked in hardware rather than via soft clock modulation over gpio, and performs byte-at-a-time transfers between the cpu and SPI controller. This driver will be extended to support future versions of the J-Core SPI controller with DMA transfers when they become available. Signed-off-by: Rich Felker --- This version of the SPI patch eliminates USE_MESSAGE_MODE (the open coding of transfer_one_message logic) and makes severl other minor changes based on ml discussion of the v2 patch. The chipselect change has not been made yet, except for rewriting the current logic to be more clear. If the decision is that it's needed, I can do it easily, but it needs testing still. drivers/spi/Kconfig | 4 + drivers/spi/Makefile| 1 + drivers/spi/spi-jcore.c | 209 3 files changed, 214 insertions(+) create mode 100644 drivers/spi/spi-jcore.c diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 9d8c84b..5bd2ccf 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -285,6 +285,10 @@ config SPI_IMX This enables using the Freescale i.MX SPI controllers in master mode. +config SPI_JCORE + tristate "J-Core SPI Master" + depends on OF + config SPI_LM70_LLP tristate "Parallel port adapter for LM70 eval board (DEVELOPMENT)" depends on PARPORT diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index fbb255c..6a34124 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -46,6 +46,7 @@ obj-$(CONFIG_SPI_FSL_SPI) += spi-fsl-spi.o obj-$(CONFIG_SPI_GPIO) += spi-gpio.o obj-$(CONFIG_SPI_IMG_SPFI) += spi-img-spfi.o obj-$(CONFIG_SPI_IMX) += spi-imx.o +obj-$(CONFIG_SPI_JCORE)+= spi-jcore.o obj-$(CONFIG_SPI_LM70_LLP) += spi-lm70llp.o obj-$(CONFIG_SPI_LP8841_RTC) += spi-lp8841-rtc.o obj-$(CONFIG_SPI_MESON_SPIFC) += spi-meson-spifc.o diff --git a/drivers/spi/spi-jcore.c b/drivers/spi/spi-jcore.c new file mode 100644 index 000..f239087 --- /dev/null +++ b/drivers/spi/spi-jcore.c @@ -0,0 +1,209 @@ +/* + * J-Core SPI controller driver + * + * Copyright (C) 2012-2016 Smart Energy Instruments, Inc. + * + * Current version by Rich Felker + * Based loosely on initial version by Oleksandr G Zhadan + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRV_NAME "jcore_spi" + +#define MAX_SPI_SPEED 1250/* 12.5 MHz */ + +#define CTRL_REG 0x0 +#define DATA_REG 0x4 + +#define SPI_NOCHIP_CS 0 +#define SPI_FLASH_CS 1 +#define SPI_CONF_CS2 +#define SPI_SD_CS 2 +#define SPI_CODEC_CS 3 + +#define JCORE_SPI_CTRL_XMIT0x02 +#define JCORE_SPI_STAT_BUSY0x02 +#define JCORE_SPI_CTRL_LOOP0x08 +#define JCORE_SPI_CTRL_CS_BITS 0x15 + +#define JCORE_SPI_WAIT_RDY_MAX_LOOP200 + +struct jcore_spi { + struct spi_master *master; + void __iomem *base; + volatile unsigned int ctrlReg; + unsigned int csReg; + unsigned int speedReg; + unsigned int speed_hz; +}; + +static void jcore_spi_wait_till_ready(struct jcore_spi *hw, int timeout) +{ + while (timeout--) { + hw->ctrlReg = readl(hw->base + CTRL_REG); + if (!(hw->ctrlReg & JCORE_SPI_STAT_BUSY)) + return; + cpu_relax(); + } + dev_err(hw->master->dev.parent, "%s: Timeout..\n", __func__); +} + +static void jcore_spi_program(struct jcore_spi *hw) +{ + jcore_spi_wait_till_ready(hw, JCORE_SPI_WAIT_RDY_MAX_LOOP); + writel(hw->csReg | hw->speedReg, hw->base + CTRL_REG); +} + +static void jcore_spi_chipsel(struct spi_device *spi, bool value) +{ + struct jcore_spi *hw = spi_master_get_devdata(spi->master); + + dev_dbg(hw->master->dev.parent, "%s: CS=%d\n", __func__, value); + + hw->csReg = JCORE_SPI_CTRL_CS_BITS ^ (!value << 2*spi->chip_select); + + jcore_spi_program(hw); +} + +static void jcore_spi_baudrate(struct jcore_spi *hw, int speed) +{ + if (speed == hw->speed_hz) return; + hw->speed_hz = speed; + hw->speedReg = ((MAX_SPI_SPEED / speed) - 1) << 27; + jcore_spi_program(hw); + dev_dbg(hw->master->dev.parent, "%s: speed=%d pre=0x%x\n", + __func__, speed, hw->speedReg); +} + +static int jcore_spi_txrx(struct spi_master *master, struct spi_device *spi, + struct spi_transfer *t) +{ + struct jcore_spi *hw = spi_master_get_devdata(master); + + void *ctrl_reg = hw->base + CTRL_REG; + void *data_reg = hw->base + DATA_REG; + unsigned int timeout; + u32 xmit; + u32 status; + + /* data buffers */ + const unsigned char *tx; + unsigned char
[PATCH v3 12/12] sh: add device tree source for J2 FPGA on Mimas v2 board
Signed-off-by: Rich Felker --- arch/sh/boot/dts/j2_mimas_v2.dts | 87 1 file changed, 87 insertions(+) create mode 100755 arch/sh/boot/dts/j2_mimas_v2.dts diff --git a/arch/sh/boot/dts/j2_mimas_v2.dts b/arch/sh/boot/dts/j2_mimas_v2.dts new file mode 100755 index 000..4a66cda --- /dev/null +++ b/arch/sh/boot/dts/j2_mimas_v2.dts @@ -0,0 +1,87 @@ +/dts-v1/; + +/ { + compatible = "jcore,j2-soc"; + model = "J2 FPGA SoC on Mimas v2 board"; + + #address-cells = <1>; + #size-cells = <1>; + + interrupt-parent = <>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "jcore,j2"; + reg = < 0 >; + clock-frequency = < 5000 >; + }; + }; + + memory@1000 { + device_type = "memory"; + reg = < 0x1000 0x400 >; + }; + + chosen { + stdout-path = "/soc@abcd/serial@100"; + }; + + soc@abcd { + compatible = "simple-bus"; + ranges = <0 0xabcd 0x10>; + + #address-cells = <1>; + #size-cells = <1>; + + aic: interrupt-controller@200 { + compatible = "jcore,aic1"; + reg = < 0x200 0x10 >; + interrupt-controller; + #interrupt-cells = <1>; + }; + + cache-controller@c0 { + compatible = "jcore,cache"; + reg = < 0xc0 4 >; + }; + + timer@200 { + compatible = "jcore,pit"; + reg = < 0x200 0x30 >; + interrupts = < 0x48 >; + }; + + spi@40 { + compatible = "jcore,spi2"; + + #address-cells = <1>; + #size-cells = <0>; + + spi-max-frequency = <1250>; + + reg = < 0x40 0x8 >; + + sdcard@0 { + compatible = "mmc-spi-slot"; + reg = <0>; + spi-max-frequency = <1250>; + voltage-ranges = <3200 3400>; + mode = <0>; + }; + }; + + serial@100 { + clock-frequency = <12500>; + compatible = "xlnx,xps-uartlite-1.00.a"; + current-speed = <19200>; + device_type = "serial"; + interrupts = < 0x12 >; + port-number = <0>; + reg = < 0x100 0x10 >; + }; + }; +}; -- 2.8.1
[PATCH v3 01/12] of: add vendor prefix for J-Core
The J-Core project (j-core.org) produces open source cpu and SoC peripheral cores synthesizable as FPGA bitstreams or ASICs. Signed-off-by: Rich Felker--- Documentation/devicetree/bindings/vendor-prefixes.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 86740d4..9c070b8 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -126,6 +126,7 @@ invensense InvenSense Inc. isee ISEE 2007 S.L. isil Intersil issi Integrated Silicon Solutions Inc. +jcore J-Core.org jedec JEDEC Solid State Technology Association karo Ka-Ro electronics GmbH keymileKeymile GmbH -- 2.8.1
[PATCH v3 01/12] of: add vendor prefix for J-Core
The J-Core project (j-core.org) produces open source cpu and SoC peripheral cores synthesizable as FPGA bitstreams or ASICs. Signed-off-by: Rich Felker --- Documentation/devicetree/bindings/vendor-prefixes.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 86740d4..9c070b8 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -126,6 +126,7 @@ invensense InvenSense Inc. isee ISEE 2007 S.L. isil Intersil issi Integrated Silicon Solutions Inc. +jcore J-Core.org jedec JEDEC Solid State Technology Association karo Ka-Ro electronics GmbH keymileKeymile GmbH -- 2.8.1
[PATCH v3 07/12] sh: add AT_HWCAP flag for J-Core cas.l instruction
Signed-off-by: Rich Felker--- arch/sh/include/uapi/asm/cpu-features.h | 1 + arch/sh/kernel/cpu/sh2/probe.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/arch/sh/include/uapi/asm/cpu-features.h b/arch/sh/include/uapi/asm/cpu-features.h index 694abe4..2f1bc85 100644 --- a/arch/sh/include/uapi/asm/cpu-features.h +++ b/arch/sh/include/uapi/asm/cpu-features.h @@ -22,5 +22,6 @@ #define CPU_HAS_L2_CACHE 0x0080 /* Secondary cache / URAM */ #define CPU_HAS_OP32 0x0100 /* 32-bit instruction support */ #define CPU_HAS_PTEAEX 0x0200 /* PTE ASID Extension support */ +#define CPU_HAS_CAS_L 0x0400 /* cas.l atomic compare-and-swap */ #endif /* __ASM_SH_CPU_FEATURES_H */ diff --git a/arch/sh/kernel/cpu/sh2/probe.c b/arch/sh/kernel/cpu/sh2/probe.c index 3dd8187..665fcfb 100644 --- a/arch/sh/kernel/cpu/sh2/probe.c +++ b/arch/sh/kernel/cpu/sh2/probe.c @@ -54,6 +54,8 @@ void __ref cpu_probe(void) boot_cpu_data.dcache.entry_shift= 5; boot_cpu_data.dcache.linesz = 32; boot_cpu_data.dcache.flags = 0; + + boot_cpu_data.flags |= CPU_HAS_CAS_L; #else /* * SH-2 doesn't have separate caches -- 2.8.1
[PATCH v3 07/12] sh: add AT_HWCAP flag for J-Core cas.l instruction
Signed-off-by: Rich Felker --- arch/sh/include/uapi/asm/cpu-features.h | 1 + arch/sh/kernel/cpu/sh2/probe.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/arch/sh/include/uapi/asm/cpu-features.h b/arch/sh/include/uapi/asm/cpu-features.h index 694abe4..2f1bc85 100644 --- a/arch/sh/include/uapi/asm/cpu-features.h +++ b/arch/sh/include/uapi/asm/cpu-features.h @@ -22,5 +22,6 @@ #define CPU_HAS_L2_CACHE 0x0080 /* Secondary cache / URAM */ #define CPU_HAS_OP32 0x0100 /* 32-bit instruction support */ #define CPU_HAS_PTEAEX 0x0200 /* PTE ASID Extension support */ +#define CPU_HAS_CAS_L 0x0400 /* cas.l atomic compare-and-swap */ #endif /* __ASM_SH_CPU_FEATURES_H */ diff --git a/arch/sh/kernel/cpu/sh2/probe.c b/arch/sh/kernel/cpu/sh2/probe.c index 3dd8187..665fcfb 100644 --- a/arch/sh/kernel/cpu/sh2/probe.c +++ b/arch/sh/kernel/cpu/sh2/probe.c @@ -54,6 +54,8 @@ void __ref cpu_probe(void) boot_cpu_data.dcache.entry_shift= 5; boot_cpu_data.dcache.linesz = 32; boot_cpu_data.dcache.flags = 0; + + boot_cpu_data.flags |= CPU_HAS_CAS_L; #else /* * SH-2 doesn't have separate caches -- 2.8.1
Re: [RFC][PATCH 1/3] locking: Introduce smp_acquire__after_ctrl_dep
On Tue, May 24, 2016 at 09:53:29PM -0700, Paul E. McKenney wrote: > On Tue, May 24, 2016 at 11:01:21PM -0400, Waiman Long wrote: > > On 05/24/2016 10:27 AM, Peter Zijlstra wrote: > > >Introduce smp_acquire__after_ctrl_dep(), this construct is not > > >uncommen, but the lack of this barrier is. > > > > > >Signed-off-by: Peter Zijlstra (Intel)> > >--- > > > include/linux/compiler.h | 14 ++ > > > ipc/sem.c| 14 ++ > > > 2 files changed, 12 insertions(+), 16 deletions(-) > > > > > >--- a/include/linux/compiler.h > > >+++ b/include/linux/compiler.h > > >@@ -305,20 +305,26 @@ static __always_inline void __write_once > > > }) > > > > > > /** > > >+ * smp_acquire__after_ctrl_dep() - Provide ACQUIRE ordering after a > > >control dependency > > >+ * > > >+ * A control dependency provides a LOAD->STORE order, the additional RMB > > >+ * provides LOAD->LOAD order, together they provide LOAD->{LOAD,STORE} > > >order, > > >+ * aka. ACQUIRE. > > >+ */ > > >+#define smp_acquire__after_ctrl_dep() smp_rmb() > > >+ > > >+/** > > > * smp_cond_acquire() - Spin wait for cond with ACQUIRE ordering > > > * @cond: boolean expression to wait for > > > * > > > * Equivalent to using smp_load_acquire() on the condition variable but > > > employs > > > * the control dependency of the wait to reduce the barrier on many > > > platforms. > > > * > > >- * The control dependency provides a LOAD->STORE order, the additional RMB > > >- * provides LOAD->LOAD order, together they provide LOAD->{LOAD,STORE} > > >order, > > >- * aka. ACQUIRE. > > > */ > > > #define smp_cond_acquire(cond) do {\ > > > while (!(cond)) \ > > > cpu_relax();\ > > >- smp_rmb(); /* ctrl + rmb := acquire */ \ > > >+ smp_acquire__after_ctrl_dep(); \ > > > } while (0) > > > > > > > > > > I have a question about the claim that control dependence + rmb is > > equivalent to an acquire memory barrier. For example, > > > > S1:if (a) > > S2: b = 1; > >smp_rmb() > > S3:c = 2; > > > > Since c is independent of both a and b, is it possible that the cpu > > may reorder to execute store statement S3 first before S1 and S2? > > The CPUs I know of won't do, nor should the compiler, at least assuming > "a" (AKA "cond") includes READ_ONCE(). Ditto "b" and WRITE_ONCE(). > Otherwise, the compiler could do quite a few "interesting" things, > especially if it knows the value of "b". For example, if the compiler > knows that b==1, without the volatile casts, the compiler could just > throw away both S1 and S2, eliminating any ordering. This can get > quite tricky -- see memory-barriers.txt for more mischief. > > The smp_rmb() is not needed in this example because S3 is a write, not but S3 needs to be an WRITE_ONCE(), right? IOW, the following code can result in reordering: S1: if (READ_ONCE(a)) S2: WRITE_ONCE(b, 1); S3: c = 2; // this can be reordered before READ_ONCE(a) but if we change S3 to WRITE_ONCE(c, 2), the reordering can not happen for the CPUs you are aware of, right? Regards, Boqun > a read. Perhaps you meant something more like this: > > if (READ_ONCE(a)) > WRITE_ONCE(b, 1); > smp_rmb(); > r1 = READ_ONCE(c); > > This sequence would guarantee that "a" was read before "c". > > Thanx, Paul > signature.asc Description: PGP signature
Re: [RFC][PATCH 1/3] locking: Introduce smp_acquire__after_ctrl_dep
On Tue, May 24, 2016 at 09:53:29PM -0700, Paul E. McKenney wrote: > On Tue, May 24, 2016 at 11:01:21PM -0400, Waiman Long wrote: > > On 05/24/2016 10:27 AM, Peter Zijlstra wrote: > > >Introduce smp_acquire__after_ctrl_dep(), this construct is not > > >uncommen, but the lack of this barrier is. > > > > > >Signed-off-by: Peter Zijlstra (Intel) > > >--- > > > include/linux/compiler.h | 14 ++ > > > ipc/sem.c| 14 ++ > > > 2 files changed, 12 insertions(+), 16 deletions(-) > > > > > >--- a/include/linux/compiler.h > > >+++ b/include/linux/compiler.h > > >@@ -305,20 +305,26 @@ static __always_inline void __write_once > > > }) > > > > > > /** > > >+ * smp_acquire__after_ctrl_dep() - Provide ACQUIRE ordering after a > > >control dependency > > >+ * > > >+ * A control dependency provides a LOAD->STORE order, the additional RMB > > >+ * provides LOAD->LOAD order, together they provide LOAD->{LOAD,STORE} > > >order, > > >+ * aka. ACQUIRE. > > >+ */ > > >+#define smp_acquire__after_ctrl_dep() smp_rmb() > > >+ > > >+/** > > > * smp_cond_acquire() - Spin wait for cond with ACQUIRE ordering > > > * @cond: boolean expression to wait for > > > * > > > * Equivalent to using smp_load_acquire() on the condition variable but > > > employs > > > * the control dependency of the wait to reduce the barrier on many > > > platforms. > > > * > > >- * The control dependency provides a LOAD->STORE order, the additional RMB > > >- * provides LOAD->LOAD order, together they provide LOAD->{LOAD,STORE} > > >order, > > >- * aka. ACQUIRE. > > > */ > > > #define smp_cond_acquire(cond) do {\ > > > while (!(cond)) \ > > > cpu_relax();\ > > >- smp_rmb(); /* ctrl + rmb := acquire */ \ > > >+ smp_acquire__after_ctrl_dep(); \ > > > } while (0) > > > > > > > > > > I have a question about the claim that control dependence + rmb is > > equivalent to an acquire memory barrier. For example, > > > > S1:if (a) > > S2: b = 1; > >smp_rmb() > > S3:c = 2; > > > > Since c is independent of both a and b, is it possible that the cpu > > may reorder to execute store statement S3 first before S1 and S2? > > The CPUs I know of won't do, nor should the compiler, at least assuming > "a" (AKA "cond") includes READ_ONCE(). Ditto "b" and WRITE_ONCE(). > Otherwise, the compiler could do quite a few "interesting" things, > especially if it knows the value of "b". For example, if the compiler > knows that b==1, without the volatile casts, the compiler could just > throw away both S1 and S2, eliminating any ordering. This can get > quite tricky -- see memory-barriers.txt for more mischief. > > The smp_rmb() is not needed in this example because S3 is a write, not but S3 needs to be an WRITE_ONCE(), right? IOW, the following code can result in reordering: S1: if (READ_ONCE(a)) S2: WRITE_ONCE(b, 1); S3: c = 2; // this can be reordered before READ_ONCE(a) but if we change S3 to WRITE_ONCE(c, 2), the reordering can not happen for the CPUs you are aware of, right? Regards, Boqun > a read. Perhaps you meant something more like this: > > if (READ_ONCE(a)) > WRITE_ONCE(b, 1); > smp_rmb(); > r1 = READ_ONCE(c); > > This sequence would guarantee that "a" was read before "c". > > Thanx, Paul > signature.asc Description: PGP signature
Re: [PATCH] net: alx: use custom skb allocator
Hi Jarod, On Fri, May 20, 2016 at 02:26:57PM -0400, Jarod Wilson wrote: > On Fri, May 20, 2016 at 03:56:23PM +0800, Feng Tang wrote: > > Hi, > > > > Please ignore this patch. > > > > I found the problem and made the patch with kernel 4.4 with Ubuntu 12.04 > > on Lenovo Y580. > > > > After submitting the patch, I tried to google the datasheet for > > Atheros 8161 dev, and found there was already a kernel bugzilla > > https://bugzilla.kernel.org/show_bug.cgi?id=70761 > > that had a fix from Jarod Wilson which get merged in v4.5 (commit > > c406700cd) > > > > Per my test, the new 4.6.0 kernel works fine with Jarod's patch. > > Might not hurt to get this some testing by people for whom my patch didn't > fix things. It seems to help for a fair number of people, but not > everyone, so perhaps this would be of use as well. Thanks for the suggestion, and you are right. Some users whose AR8161 can't be cured by your path report the device is working with my patch, though one reported the TX is slower while RX is not (which can't be reproduced on my Lenovo Y580). https://bugzilla.kernel.org/show_bug.cgi?id=70761 So I think this patch is better to be merged, and I will send out a v2 I did some more debug, it looks very likely to be related with the RX DMA address, specifically 0x...f80, if RX buffer get 0x...f80 several times, their will be RX overflow error and card will stop working. For kernel 4.5.0 which merged Jarod's patch and works fine with my AR8161/Lennov Y580, if I made some change to the __netdev_alloc_skb --> __alloc_page_frag() to make the allocated buffer can get an address with 0x...f80, then the same error happens. If I make it to 0x...f40 or 0xfc0, every thing is still fine. So I tend to believe that the 0x..f80 address cause the silicon to behave abnormally. Thanks, Feng > > Personally, my own alx-driven hardware didn't have a problem to begin > with, so I'm not able to do more than make sure things don't regress > w/already functioning hardware. > > > > On Fri, May 20, 2016 at 01:41:03PM +0800, Feng Tang wrote: > > > This patch follows Eric Dumazet's commit 7b70176421 to fix one > > > exactly same bug in alx driver, that the network link will > > > be lost in 1-5 minutes after the device is up. > > > > > > Following is a git log from Eric's 7b70176421: > > > > > > "We had reports ( https://bugzilla.kernel.org/show_bug.cgi?id=54021 ) > > > that using high order pages for skb allocations is problematic for atl1c > > > > > > We do not know exactly what the problem is, but we suspect that crossing > > > 4K pages is not well supported by this hardware. > > > > > > Use a custom allocator, using page allocator and 2K fragments for > > > optimal stack behavior. We might make this allocator generic > > > in future kernels." > > > > > > And my debug shows the same suspect, most of the errors happen > > > when there is a RX buffer address with 0x..f80, hopefully > > > this will get noticed and fixed from silicon side. > > > > > > My victim is a Lenovo Y580 Laptop with Atheros ALX AR8161 etherenet > > > device(PCI ID 1969:1091), with this patch the ethernet dev > > > works just fine > > > > > > Signed-off-by: Feng Tang
Re: [PATCH] net: alx: use custom skb allocator
Hi Jarod, On Fri, May 20, 2016 at 02:26:57PM -0400, Jarod Wilson wrote: > On Fri, May 20, 2016 at 03:56:23PM +0800, Feng Tang wrote: > > Hi, > > > > Please ignore this patch. > > > > I found the problem and made the patch with kernel 4.4 with Ubuntu 12.04 > > on Lenovo Y580. > > > > After submitting the patch, I tried to google the datasheet for > > Atheros 8161 dev, and found there was already a kernel bugzilla > > https://bugzilla.kernel.org/show_bug.cgi?id=70761 > > that had a fix from Jarod Wilson which get merged in v4.5 (commit > > c406700cd) > > > > Per my test, the new 4.6.0 kernel works fine with Jarod's patch. > > Might not hurt to get this some testing by people for whom my patch didn't > fix things. It seems to help for a fair number of people, but not > everyone, so perhaps this would be of use as well. Thanks for the suggestion, and you are right. Some users whose AR8161 can't be cured by your path report the device is working with my patch, though one reported the TX is slower while RX is not (which can't be reproduced on my Lenovo Y580). https://bugzilla.kernel.org/show_bug.cgi?id=70761 So I think this patch is better to be merged, and I will send out a v2 I did some more debug, it looks very likely to be related with the RX DMA address, specifically 0x...f80, if RX buffer get 0x...f80 several times, their will be RX overflow error and card will stop working. For kernel 4.5.0 which merged Jarod's patch and works fine with my AR8161/Lennov Y580, if I made some change to the __netdev_alloc_skb --> __alloc_page_frag() to make the allocated buffer can get an address with 0x...f80, then the same error happens. If I make it to 0x...f40 or 0xfc0, every thing is still fine. So I tend to believe that the 0x..f80 address cause the silicon to behave abnormally. Thanks, Feng > > Personally, my own alx-driven hardware didn't have a problem to begin > with, so I'm not able to do more than make sure things don't regress > w/already functioning hardware. > > > > On Fri, May 20, 2016 at 01:41:03PM +0800, Feng Tang wrote: > > > This patch follows Eric Dumazet's commit 7b70176421 to fix one > > > exactly same bug in alx driver, that the network link will > > > be lost in 1-5 minutes after the device is up. > > > > > > Following is a git log from Eric's 7b70176421: > > > > > > "We had reports ( https://bugzilla.kernel.org/show_bug.cgi?id=54021 ) > > > that using high order pages for skb allocations is problematic for atl1c > > > > > > We do not know exactly what the problem is, but we suspect that crossing > > > 4K pages is not well supported by this hardware. > > > > > > Use a custom allocator, using page allocator and 2K fragments for > > > optimal stack behavior. We might make this allocator generic > > > in future kernels." > > > > > > And my debug shows the same suspect, most of the errors happen > > > when there is a RX buffer address with 0x..f80, hopefully > > > this will get noticed and fixed from silicon side. > > > > > > My victim is a Lenovo Y580 Laptop with Atheros ALX AR8161 etherenet > > > device(PCI ID 1969:1091), with this patch the ethernet dev > > > works just fine > > > > > > Signed-off-by: Feng Tang
Re: [RFC PATCH] drivers/pinctrl: Add pinctrl-ast2400
Hi Linus, On Mon, 2016-05-23 at 14:38 +0200, Linus Walleij wrote: > Hi sorry for taking so long before reviewing. Too busy, what can I say. No worries, I expected as much. Thanks for taking the time! > > On Fri, May 6, 2016 at 8:20 AM, Andrew Jefferywrote: > > > > > Add pinctrl/pinmux support for the Aspeed AST2400 SoC. Configuration of > > the SoC is somewhat involved: Enabling functions can involve writes of > > multiple bits to multiple registers, and signals provided by a pin are > > determined on a priority basis. That is, without care, it's possible to > > configure a function in the mux and to not gain expected functionality. > > > > Signed-off-by: Andrew Jeffery > > > > +#include > > +#include > > +#include > > +#include > You should include your changes to Kconfig and Makefile in the patch > so it is a complete driver. This is an example of why: if I can't see if > your driver is really tristate in Kconfig I don't know whether > should be included or not. > > If it is a bool don't include this. > If it is a bool, don't use any MODULE_* macros either. Okay. I'll do so when I send follow-up patches. > > > > > +/* Challenges in the AST2400 Multifunction Pin Design > > + * -- > > + * > > + * * Reasonable number of pins (216) > > + * > > + * * The SoC function enabled on a pin is determined on a priority basis > > + * > > + * * Using the priority system, pins can provide up to 3 different signals > > + * types > > + * > > + * * The signal active on a pin is often described by compound logical > > + * expressions involving multiple operators, registers and bits > > + * > > + * * The high and low priority functions' bit masks are frequently not > > the > > + * same > > + * (i.e. cannot just flip a bit to change from high to low), or even > > in the > > + * same register. > > + * > > + * * Not all functions are disabled by unsetting bits, some require > > setting > > + * bits > > + * > > + * * Not all signals can be deactivated as some expressions depend on > > values > > + * in the hardware strapping register, which is treated as read-only. > Try to compresse the bullet list to text. This looks like a powerpoint > presentation. Will do. > > > > > + * SoC Multi-function Pin Expression Examples > > + * -- > > + * > > + * Here are some sample mux configurations from the datasheet to > > illustrate the > > + * corner cases, roughly in order of least to most corner. In the table, > > HP and > > + * LP are high- and low- priority respectively. > I believe that you got the hardware details right. Only someone with > experience with the same hardware could review these gory details. > So I will just trust that you got that part right. > > > > > + * * Pins provide two to three signals in a priority order > > + * > > + * * For priorities levels defined on a pin, each priority provides one > > signal > > + * > > + * * Enabling lower priority signals requires higher priority signals be > > + * disabled > (...) > > > > + * * A signal at a given priority on a given pin is active if any of the > > + * functions in which the signal participates are active, and no higher > > + * priority signal on the pin is active > That's a pretty baroque design. I wonder who came up with the idea > that this needed to be a priority-based state machine thing. Did they > have a usecase of different software threads independently competing > about using the hardware or what? > > Or is it some hardware aid to help the programmer from shooting > him/herself in the foot? The datasheet doesn't appear to explain the motivation, so we're in the dark. > > > > > +#define A4 2 > > +SSSF_PIN_DECL(A4, GPIOA2, TIMER3, FUNC_DESC_SET(SCU80, 2)); > > + > > +FUNC_EXPR_DECL_SINGLE(SD1, FUNC_DESC_SET(SCU90, 0)); > > + > > +FUNC_EXPR_DECL_SINGLE(I2C10, FUNC_DESC_SET(SCU90, 23)); > > + > > +#define C4 16 > > +MS_PIN_DECL(C4, GPIOC0, SD1, I2C10); > > +#define B3 17 > > +MS_PIN_DECL(B3, GPIOC1, SD1, I2C10); > These things look very terse. But I guess there is no way to alleviate > the terseness that you can think of? Less terse in what way? Something other than more descriptive/longer the macro names? Since sending the patch I've been concentrating on other things, but I've had some half-baked thoughts about alternative approaches. My intent was a roughly iterative approach, and with this first patch revision I was trying to understand the problem of the hardware's function priorities and capturing a signal's bitfield relationships. The motivation for sending the patch as it is (now that I have an understanding of the problems that need solving) was to find out if there were existing patterns that could be used to shape the implementation. Or if not, whether the approach was reasonable. However, that was at the expense of a deeper understanding of the
Re: [RFC PATCH] drivers/pinctrl: Add pinctrl-ast2400
Hi Linus, On Mon, 2016-05-23 at 14:38 +0200, Linus Walleij wrote: > Hi sorry for taking so long before reviewing. Too busy, what can I say. No worries, I expected as much. Thanks for taking the time! > > On Fri, May 6, 2016 at 8:20 AM, Andrew Jeffery wrote: > > > > > Add pinctrl/pinmux support for the Aspeed AST2400 SoC. Configuration of > > the SoC is somewhat involved: Enabling functions can involve writes of > > multiple bits to multiple registers, and signals provided by a pin are > > determined on a priority basis. That is, without care, it's possible to > > configure a function in the mux and to not gain expected functionality. > > > > Signed-off-by: Andrew Jeffery > > > > +#include > > +#include > > +#include > > +#include > You should include your changes to Kconfig and Makefile in the patch > so it is a complete driver. This is an example of why: if I can't see if > your driver is really tristate in Kconfig I don't know whether > should be included or not. > > If it is a bool don't include this. > If it is a bool, don't use any MODULE_* macros either. Okay. I'll do so when I send follow-up patches. > > > > > +/* Challenges in the AST2400 Multifunction Pin Design > > + * -- > > + * > > + * * Reasonable number of pins (216) > > + * > > + * * The SoC function enabled on a pin is determined on a priority basis > > + * > > + * * Using the priority system, pins can provide up to 3 different signals > > + * types > > + * > > + * * The signal active on a pin is often described by compound logical > > + * expressions involving multiple operators, registers and bits > > + * > > + * * The high and low priority functions' bit masks are frequently not > > the > > + * same > > + * (i.e. cannot just flip a bit to change from high to low), or even > > in the > > + * same register. > > + * > > + * * Not all functions are disabled by unsetting bits, some require > > setting > > + * bits > > + * > > + * * Not all signals can be deactivated as some expressions depend on > > values > > + * in the hardware strapping register, which is treated as read-only. > Try to compresse the bullet list to text. This looks like a powerpoint > presentation. Will do. > > > > > + * SoC Multi-function Pin Expression Examples > > + * -- > > + * > > + * Here are some sample mux configurations from the datasheet to > > illustrate the > > + * corner cases, roughly in order of least to most corner. In the table, > > HP and > > + * LP are high- and low- priority respectively. > I believe that you got the hardware details right. Only someone with > experience with the same hardware could review these gory details. > So I will just trust that you got that part right. > > > > > + * * Pins provide two to three signals in a priority order > > + * > > + * * For priorities levels defined on a pin, each priority provides one > > signal > > + * > > + * * Enabling lower priority signals requires higher priority signals be > > + * disabled > (...) > > > > + * * A signal at a given priority on a given pin is active if any of the > > + * functions in which the signal participates are active, and no higher > > + * priority signal on the pin is active > That's a pretty baroque design. I wonder who came up with the idea > that this needed to be a priority-based state machine thing. Did they > have a usecase of different software threads independently competing > about using the hardware or what? > > Or is it some hardware aid to help the programmer from shooting > him/herself in the foot? The datasheet doesn't appear to explain the motivation, so we're in the dark. > > > > > +#define A4 2 > > +SSSF_PIN_DECL(A4, GPIOA2, TIMER3, FUNC_DESC_SET(SCU80, 2)); > > + > > +FUNC_EXPR_DECL_SINGLE(SD1, FUNC_DESC_SET(SCU90, 0)); > > + > > +FUNC_EXPR_DECL_SINGLE(I2C10, FUNC_DESC_SET(SCU90, 23)); > > + > > +#define C4 16 > > +MS_PIN_DECL(C4, GPIOC0, SD1, I2C10); > > +#define B3 17 > > +MS_PIN_DECL(B3, GPIOC1, SD1, I2C10); > These things look very terse. But I guess there is no way to alleviate > the terseness that you can think of? Less terse in what way? Something other than more descriptive/longer the macro names? Since sending the patch I've been concentrating on other things, but I've had some half-baked thoughts about alternative approaches. My intent was a roughly iterative approach, and with this first patch revision I was trying to understand the problem of the hardware's function priorities and capturing a signal's bitfield relationships. The motivation for sending the patch as it is (now that I have an understanding of the problems that need solving) was to find out if there were existing patterns that could be used to shape the implementation. Or if not, whether the approach was reasonable. However, that was at the expense of a deeper understanding of the approaches to integrating a solution into
Re: [PATCH] ACPI / Thermal / video: fix max_level incorrect value
Valdis, can you please give the patch a try? Thanks. -Aaron On Sat, May 21, 2016 at 03:55:00PM +0800, Aaron Lu wrote: > I think I have found the problem, please give the patch a test, thanks. > > From: Aaron Lu> Date: Sat, 21 May 2016 15:30:46 +0800 > Subject: [PATCH] ACPI / Thermal / video: fix max_level incorrect value > > commit 059500940def("ACPI/video: export acpi_video_get_levels") > mistakenly dropped the correct value of max_level and that caused the > set_level function following failed and the acpi_video backlight interface > didn't get created. Fix this by passing back the correct max_level value. > > While at it, also fix the param used in acpi_video_device_lcd_query_levels > where acpi_handle is expected but acpi_video_device is passed. > > Reported-by: Valdis Kletnieks > Signed-off-by: Aaron Lu > --- > drivers/acpi/acpi_video.c | 9 ++--- > drivers/thermal/int340x_thermal/int3406_thermal.c | 2 +- > include/acpi/video.h | 6 -- > 3 files changed, 11 insertions(+), 6 deletions(-) > > diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c > index 3d5b8a099351..c1d138e128cb 100644 > --- a/drivers/acpi/acpi_video.c > +++ b/drivers/acpi/acpi_video.c > @@ -754,7 +754,8 @@ static int acpi_video_bqc_quirk(struct acpi_video_device > *device, > } > > int acpi_video_get_levels(struct acpi_device *device, > - struct acpi_video_device_brightness **dev_br) > + struct acpi_video_device_brightness **dev_br, > + int *pmax_level) > { > union acpi_object *obj = NULL; > int i, max_level = 0, count = 0, level_ac_battery = 0; > @@ -841,6 +842,8 @@ int acpi_video_get_levels(struct acpi_device *device, > > br->count = count; > *dev_br = br; > + if (pmax_level) > + *pmax_level = max_level; > > out: > kfree(obj); > @@ -869,7 +872,7 @@ acpi_video_init_brightness(struct acpi_video_device > *device) > struct acpi_video_device_brightness *br = NULL; > int result = -EINVAL; > > - result = acpi_video_get_levels(device->dev, ); > + result = acpi_video_get_levels(device->dev, , _level); > if (result) > return result; > device->brightness = br; > @@ -1737,7 +1740,7 @@ static void acpi_video_run_bcl_for_osi(struct > acpi_video_bus *video) > > mutex_lock(>device_list_lock); > list_for_each_entry(dev, >video_device_list, entry) { > - if (!acpi_video_device_lcd_query_levels(dev, )) > + if (!acpi_video_device_lcd_query_levels(dev->dev->handle, > )) > kfree(levels); > } > mutex_unlock(>device_list_lock); > diff --git a/drivers/thermal/int340x_thermal/int3406_thermal.c > b/drivers/thermal/int340x_thermal/int3406_thermal.c > index 13d431cbd29e..a578cd257db4 100644 > --- a/drivers/thermal/int340x_thermal/int3406_thermal.c > +++ b/drivers/thermal/int340x_thermal/int3406_thermal.c > @@ -177,7 +177,7 @@ static int int3406_thermal_probe(struct platform_device > *pdev) > return -ENODEV; > d->raw_bd = bd; > > - ret = acpi_video_get_levels(ACPI_COMPANION(>dev), >br); > + ret = acpi_video_get_levels(ACPI_COMPANION(>dev), >br, NULL); > if (ret) > return ret; > > diff --git a/include/acpi/video.h b/include/acpi/video.h > index 70a41f742037..5731ccb42585 100644 > --- a/include/acpi/video.h > +++ b/include/acpi/video.h > @@ -51,7 +51,8 @@ extern void acpi_video_set_dmi_backlight_type(enum > acpi_backlight_type type); > */ > extern bool acpi_video_handles_brightness_key_presses(void); > extern int acpi_video_get_levels(struct acpi_device *device, > - struct acpi_video_device_brightness **dev_br); > + struct acpi_video_device_brightness **dev_br, > + int *pmax_level); > #else > static inline int acpi_video_register(void) { return 0; } > static inline void acpi_video_unregister(void) { return; } > @@ -72,7 +73,8 @@ static inline bool > acpi_video_handles_brightness_key_presses(void) > return false; > } > static inline int acpi_video_get_levels(struct acpi_device *device, > - struct acpi_video_device_brightness **dev_br) > + struct acpi_video_device_brightness **dev_br, > + int *pmax_level) > { > return -ENODEV; > } > -- > 2.5.5 >
Re: [PATCH] ACPI / Thermal / video: fix max_level incorrect value
Valdis, can you please give the patch a try? Thanks. -Aaron On Sat, May 21, 2016 at 03:55:00PM +0800, Aaron Lu wrote: > I think I have found the problem, please give the patch a test, thanks. > > From: Aaron Lu > Date: Sat, 21 May 2016 15:30:46 +0800 > Subject: [PATCH] ACPI / Thermal / video: fix max_level incorrect value > > commit 059500940def("ACPI/video: export acpi_video_get_levels") > mistakenly dropped the correct value of max_level and that caused the > set_level function following failed and the acpi_video backlight interface > didn't get created. Fix this by passing back the correct max_level value. > > While at it, also fix the param used in acpi_video_device_lcd_query_levels > where acpi_handle is expected but acpi_video_device is passed. > > Reported-by: Valdis Kletnieks > Signed-off-by: Aaron Lu > --- > drivers/acpi/acpi_video.c | 9 ++--- > drivers/thermal/int340x_thermal/int3406_thermal.c | 2 +- > include/acpi/video.h | 6 -- > 3 files changed, 11 insertions(+), 6 deletions(-) > > diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c > index 3d5b8a099351..c1d138e128cb 100644 > --- a/drivers/acpi/acpi_video.c > +++ b/drivers/acpi/acpi_video.c > @@ -754,7 +754,8 @@ static int acpi_video_bqc_quirk(struct acpi_video_device > *device, > } > > int acpi_video_get_levels(struct acpi_device *device, > - struct acpi_video_device_brightness **dev_br) > + struct acpi_video_device_brightness **dev_br, > + int *pmax_level) > { > union acpi_object *obj = NULL; > int i, max_level = 0, count = 0, level_ac_battery = 0; > @@ -841,6 +842,8 @@ int acpi_video_get_levels(struct acpi_device *device, > > br->count = count; > *dev_br = br; > + if (pmax_level) > + *pmax_level = max_level; > > out: > kfree(obj); > @@ -869,7 +872,7 @@ acpi_video_init_brightness(struct acpi_video_device > *device) > struct acpi_video_device_brightness *br = NULL; > int result = -EINVAL; > > - result = acpi_video_get_levels(device->dev, ); > + result = acpi_video_get_levels(device->dev, , _level); > if (result) > return result; > device->brightness = br; > @@ -1737,7 +1740,7 @@ static void acpi_video_run_bcl_for_osi(struct > acpi_video_bus *video) > > mutex_lock(>device_list_lock); > list_for_each_entry(dev, >video_device_list, entry) { > - if (!acpi_video_device_lcd_query_levels(dev, )) > + if (!acpi_video_device_lcd_query_levels(dev->dev->handle, > )) > kfree(levels); > } > mutex_unlock(>device_list_lock); > diff --git a/drivers/thermal/int340x_thermal/int3406_thermal.c > b/drivers/thermal/int340x_thermal/int3406_thermal.c > index 13d431cbd29e..a578cd257db4 100644 > --- a/drivers/thermal/int340x_thermal/int3406_thermal.c > +++ b/drivers/thermal/int340x_thermal/int3406_thermal.c > @@ -177,7 +177,7 @@ static int int3406_thermal_probe(struct platform_device > *pdev) > return -ENODEV; > d->raw_bd = bd; > > - ret = acpi_video_get_levels(ACPI_COMPANION(>dev), >br); > + ret = acpi_video_get_levels(ACPI_COMPANION(>dev), >br, NULL); > if (ret) > return ret; > > diff --git a/include/acpi/video.h b/include/acpi/video.h > index 70a41f742037..5731ccb42585 100644 > --- a/include/acpi/video.h > +++ b/include/acpi/video.h > @@ -51,7 +51,8 @@ extern void acpi_video_set_dmi_backlight_type(enum > acpi_backlight_type type); > */ > extern bool acpi_video_handles_brightness_key_presses(void); > extern int acpi_video_get_levels(struct acpi_device *device, > - struct acpi_video_device_brightness **dev_br); > + struct acpi_video_device_brightness **dev_br, > + int *pmax_level); > #else > static inline int acpi_video_register(void) { return 0; } > static inline void acpi_video_unregister(void) { return; } > @@ -72,7 +73,8 @@ static inline bool > acpi_video_handles_brightness_key_presses(void) > return false; > } > static inline int acpi_video_get_levels(struct acpi_device *device, > - struct acpi_video_device_brightness **dev_br) > + struct acpi_video_device_brightness **dev_br, > + int *pmax_level) > { > return -ENODEV; > } > -- > 2.5.5 >
Re: [PATCH v6 11/12] zsmalloc: page migration support
Hello Sergey, On Tue, May 24, 2016 at 03:28:01PM +0900, Minchan Kim wrote: > > hm... zsmalloc is getting sooo complex now. > > > > `system_wq' -- can we have problems here when the system is getting > > low on memory and workers are getting increasingly busy trying to > > allocate the memory for some other purposes? > > > > _theoretically_ zsmalloc can stack a number of ready-to-release zspages, > > which won't be accessible to zsmalloc, nor will they be released. how likely > > is this? hm, can zsmalloc take zspages from that deferred release list when > > it wants to allocate a new zspage? > > Done. > > > > > do you also want to kick the deferred page release from the shrinker > > callback, for example? > > Yeb, it can be. I will do it at next revision. :) > Thanks! > I tried it now but I feel strongly we want to fix shrinker first. Now, shrinker doesn't consider VM's request(i.e., sc->nr_to_scan) but shrink all objects which could make latency huge. I want to fix it as another issue and then adding ZS_EMPTY pool pages purging logic based on it because many works for zsmalloc stucked with this patchset now which churns old code heavily. :(
Re: [PATCH v6 11/12] zsmalloc: page migration support
Hello Sergey, On Tue, May 24, 2016 at 03:28:01PM +0900, Minchan Kim wrote: > > hm... zsmalloc is getting sooo complex now. > > > > `system_wq' -- can we have problems here when the system is getting > > low on memory and workers are getting increasingly busy trying to > > allocate the memory for some other purposes? > > > > _theoretically_ zsmalloc can stack a number of ready-to-release zspages, > > which won't be accessible to zsmalloc, nor will they be released. how likely > > is this? hm, can zsmalloc take zspages from that deferred release list when > > it wants to allocate a new zspage? > > Done. > > > > > do you also want to kick the deferred page release from the shrinker > > callback, for example? > > Yeb, it can be. I will do it at next revision. :) > Thanks! > I tried it now but I feel strongly we want to fix shrinker first. Now, shrinker doesn't consider VM's request(i.e., sc->nr_to_scan) but shrink all objects which could make latency huge. I want to fix it as another issue and then adding ZS_EMPTY pool pages purging logic based on it because many works for zsmalloc stucked with this patchset now which churns old code heavily. :(
[PATCH] pinctrl: copy per-pin driver private data to struct pin_desc
Currently, struct pinctrl_pin_desc can have per-pin driver private data, but it is not copied to struct pin_desc. For a driver with sparse pin space, for-loop search like below would be necessary in order to get the driver-specific data for a desired pin number. for (i = 0; i < pctldev->desc->npins; i++) if (pin_number == pctldev->desc->pins[i].number) return pctldev->desc->pins[i].drv_data; This is not efficient for a driver with a large number of pins. So, copy the data to struct pin_desc when each pin is registered for the faster radix tree lookup. Signed-off-by: Masahiro Yamada--- drivers/pinctrl/core.c | 22 -- drivers/pinctrl/core.h | 2 ++ 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 03c08c1..fb38e20 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -225,13 +225,14 @@ static void pinctrl_free_pindescs(struct pinctrl_dev *pctldev, } static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev, - unsigned number, const char *name) + const struct pinctrl_pin_desc *pin) { struct pin_desc *pindesc; - pindesc = pin_desc_get(pctldev, number); + pindesc = pin_desc_get(pctldev, pin->number); if (pindesc != NULL) { - dev_err(pctldev->dev, "pin %d already registered\n", number); + dev_err(pctldev->dev, "pin %d already registered\n", + pin->number); return -EINVAL; } @@ -245,10 +246,10 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev, pindesc->pctldev = pctldev; /* Copy basic pin info */ - if (name) { - pindesc->name = name; + if (pin->name) { + pindesc->name = pin->name; } else { - pindesc->name = kasprintf(GFP_KERNEL, "PIN%u", number); + pindesc->name = kasprintf(GFP_KERNEL, "PIN%u", pin->number); if (pindesc->name == NULL) { kfree(pindesc); return -ENOMEM; @@ -256,9 +257,11 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev, pindesc->dynamic_name = true; } - radix_tree_insert(>pin_desc_tree, number, pindesc); + pindesc->drv_data = pin->drv_data; + + radix_tree_insert(>pin_desc_tree, pin->number, pindesc); pr_debug("registered pin %d (%s) on %s\n", -number, pindesc->name, pctldev->desc->name); +pin->number, pindesc->name, pctldev->desc->name); return 0; } @@ -270,8 +273,7 @@ static int pinctrl_register_pins(struct pinctrl_dev *pctldev, int ret = 0; for (i = 0; i < num_descs; i++) { - ret = pinctrl_register_one_pin(pctldev, - pins[i].number, pins[i].name); + ret = pinctrl_register_one_pin(pctldev, [i]); if (ret) return ret; } diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index ca08723..747c423 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h @@ -134,6 +134,7 @@ struct pinctrl_setting { * @name: a name for the pin, e.g. the name of the pin/pad/finger on a * datasheet or such * @dynamic_name: if the name of this pin was dynamically allocated + * @drv_data: driver-defined per-pin data. pinctrl core does not touch this * @mux_usecount: If zero, the pin is not claimed, and @owner should be NULL. * If non-zero, this pin is claimed by @owner. This field is an integer * rather than a boolean, since pinctrl_get() might process multiple @@ -148,6 +149,7 @@ struct pin_desc { struct pinctrl_dev *pctldev; const char *name; bool dynamic_name; + void *drv_data; /* These fields only added when supporting pinmux drivers */ #ifdef CONFIG_PINMUX unsigned mux_usecount; -- 1.9.1
[PATCH] pinctrl: copy per-pin driver private data to struct pin_desc
Currently, struct pinctrl_pin_desc can have per-pin driver private data, but it is not copied to struct pin_desc. For a driver with sparse pin space, for-loop search like below would be necessary in order to get the driver-specific data for a desired pin number. for (i = 0; i < pctldev->desc->npins; i++) if (pin_number == pctldev->desc->pins[i].number) return pctldev->desc->pins[i].drv_data; This is not efficient for a driver with a large number of pins. So, copy the data to struct pin_desc when each pin is registered for the faster radix tree lookup. Signed-off-by: Masahiro Yamada --- drivers/pinctrl/core.c | 22 -- drivers/pinctrl/core.h | 2 ++ 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 03c08c1..fb38e20 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -225,13 +225,14 @@ static void pinctrl_free_pindescs(struct pinctrl_dev *pctldev, } static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev, - unsigned number, const char *name) + const struct pinctrl_pin_desc *pin) { struct pin_desc *pindesc; - pindesc = pin_desc_get(pctldev, number); + pindesc = pin_desc_get(pctldev, pin->number); if (pindesc != NULL) { - dev_err(pctldev->dev, "pin %d already registered\n", number); + dev_err(pctldev->dev, "pin %d already registered\n", + pin->number); return -EINVAL; } @@ -245,10 +246,10 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev, pindesc->pctldev = pctldev; /* Copy basic pin info */ - if (name) { - pindesc->name = name; + if (pin->name) { + pindesc->name = pin->name; } else { - pindesc->name = kasprintf(GFP_KERNEL, "PIN%u", number); + pindesc->name = kasprintf(GFP_KERNEL, "PIN%u", pin->number); if (pindesc->name == NULL) { kfree(pindesc); return -ENOMEM; @@ -256,9 +257,11 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev, pindesc->dynamic_name = true; } - radix_tree_insert(>pin_desc_tree, number, pindesc); + pindesc->drv_data = pin->drv_data; + + radix_tree_insert(>pin_desc_tree, pin->number, pindesc); pr_debug("registered pin %d (%s) on %s\n", -number, pindesc->name, pctldev->desc->name); +pin->number, pindesc->name, pctldev->desc->name); return 0; } @@ -270,8 +273,7 @@ static int pinctrl_register_pins(struct pinctrl_dev *pctldev, int ret = 0; for (i = 0; i < num_descs; i++) { - ret = pinctrl_register_one_pin(pctldev, - pins[i].number, pins[i].name); + ret = pinctrl_register_one_pin(pctldev, [i]); if (ret) return ret; } diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index ca08723..747c423 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h @@ -134,6 +134,7 @@ struct pinctrl_setting { * @name: a name for the pin, e.g. the name of the pin/pad/finger on a * datasheet or such * @dynamic_name: if the name of this pin was dynamically allocated + * @drv_data: driver-defined per-pin data. pinctrl core does not touch this * @mux_usecount: If zero, the pin is not claimed, and @owner should be NULL. * If non-zero, this pin is claimed by @owner. This field is an integer * rather than a boolean, since pinctrl_get() might process multiple @@ -148,6 +149,7 @@ struct pin_desc { struct pinctrl_dev *pctldev; const char *name; bool dynamic_name; + void *drv_data; /* These fields only added when supporting pinmux drivers */ #ifdef CONFIG_PINMUX unsigned mux_usecount; -- 1.9.1
[PATCH v5 7/8] perf tools: Don't warn about out of order event if write_backward is used
If write_backward attribute is set, records are written into kernel ring buffer from end to beginning, but read from beginning to end. To avoid 'XX out of order events recorded' warning message (timestamps of records is in reverse order when using write_backward), suppress the warning message if write_backward is selected by at lease one event. Result: Before this patch: # perf record -m 1 -e raw_syscalls:sys_exit/overwrite/ \ -e raw_syscalls:sys_enter \ dd if=/dev/zero of=/dev/null count=300 300+0 records in 300+0 records out 153600 bytes (154 kB) copied, 0.000601617 s, 255 MB/s [ perf record: Woken up 5 times to write data ] Warning: 40 out of order events recorded. [ perf record: Captured and wrote 0.096 MB perf.data (696 samples) ] After this patch: # perf record -m 1 -e raw_syscalls:sys_exit/overwrite/ \ -e raw_syscalls:sys_enter \ dd if=/dev/zero of=/dev/null count=300 300+0 records in 300+0 records out 153600 bytes (154 kB) copied, 0.000644873 s, 238 MB/s [ perf record: Woken up 5 times to write data ] [ perf record: Captured and wrote 0.096 MB perf.data (696 samples) ] Signed-off-by: Wang NanSigned-off-by: He Kuang Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Zefan Li Cc: pi3or...@163.com --- tools/perf/util/session.c | 22 +++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 2335b28..8e3d9d4 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1495,10 +1495,27 @@ int perf_session__register_idle_thread(struct perf_session *session) return err; } +static void +perf_session__warn_order(const struct perf_session *session) +{ + const struct ordered_events *oe = >ordered_events; + struct perf_evsel *evsel; + bool should_warn = true; + + evlist__for_each(session->evlist, evsel) { + if (evsel->attr.write_backward) + should_warn = false; + } + + if (!should_warn) + return; + if (oe->nr_unordered_events != 0) + ui__warning("%u out of order events recorded.\n", oe->nr_unordered_events); +} + static void perf_session__warn_about_errors(const struct perf_session *session) { const struct events_stats *stats = >evlist->stats; - const struct ordered_events *oe = >ordered_events; if (session->tool->lost == perf_event__process_lost && stats->nr_events[PERF_RECORD_LOST] != 0) { @@ -1555,8 +1572,7 @@ static void perf_session__warn_about_errors(const struct perf_session *session) stats->nr_unprocessable_samples); } - if (oe->nr_unordered_events != 0) - ui__warning("%u out of order events recorded.\n", oe->nr_unordered_events); + perf_session__warn_order(session); events_stats__auxtrace_error_warn(stats); -- 1.8.3.4
[PATCH v5 2/8] perf tools: Choose correct reading direction according to evlist->backward
Now we have evlist->backward to indicate the mmap direction. Make perf_evlist__mmap_read() choose right direction automatically. Signed-off-by: Wang NanCc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Zefan Li Cc: He Kuang --- tools/perf/util/evlist.c | 9 - tools/perf/util/evlist.h | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index f916d25..8f7b44e 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -778,7 +778,7 @@ broken_event: return event; } -union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx) +union perf_event *perf_evlist__mmap_read_forward(struct perf_evlist *evlist, int idx) { struct perf_mmap *md = >mmap[idx]; u64 head; @@ -833,6 +833,13 @@ perf_evlist__mmap_read_backward(struct perf_evlist *evlist, int idx) return perf_mmap__read(md, false, start, end, >prev); } +union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx) +{ + if (!evlist->backward) + return perf_evlist__mmap_read_forward(evlist, idx); + return perf_evlist__mmap_read_backward(evlist, idx); +} + void perf_evlist__mmap_read_catchup(struct perf_evlist *evlist, int idx) { struct perf_mmap *md = >mmap[idx]; diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 0505012..41e65ac 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -134,6 +134,8 @@ struct perf_sample_id *perf_evlist__id2sid(struct perf_evlist *evlist, u64 id); union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx); +union perf_event *perf_evlist__mmap_read_forward(struct perf_evlist *evlist, +int idx); union perf_event *perf_evlist__mmap_read_backward(struct perf_evlist *evlist, int idx); void perf_evlist__mmap_read_catchup(struct perf_evlist *evlist, int idx); -- 1.8.3.4
[PATCH v5 7/8] perf tools: Don't warn about out of order event if write_backward is used
If write_backward attribute is set, records are written into kernel ring buffer from end to beginning, but read from beginning to end. To avoid 'XX out of order events recorded' warning message (timestamps of records is in reverse order when using write_backward), suppress the warning message if write_backward is selected by at lease one event. Result: Before this patch: # perf record -m 1 -e raw_syscalls:sys_exit/overwrite/ \ -e raw_syscalls:sys_enter \ dd if=/dev/zero of=/dev/null count=300 300+0 records in 300+0 records out 153600 bytes (154 kB) copied, 0.000601617 s, 255 MB/s [ perf record: Woken up 5 times to write data ] Warning: 40 out of order events recorded. [ perf record: Captured and wrote 0.096 MB perf.data (696 samples) ] After this patch: # perf record -m 1 -e raw_syscalls:sys_exit/overwrite/ \ -e raw_syscalls:sys_enter \ dd if=/dev/zero of=/dev/null count=300 300+0 records in 300+0 records out 153600 bytes (154 kB) copied, 0.000644873 s, 238 MB/s [ perf record: Woken up 5 times to write data ] [ perf record: Captured and wrote 0.096 MB perf.data (696 samples) ] Signed-off-by: Wang Nan Signed-off-by: He Kuang Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Zefan Li Cc: pi3or...@163.com --- tools/perf/util/session.c | 22 +++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 2335b28..8e3d9d4 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1495,10 +1495,27 @@ int perf_session__register_idle_thread(struct perf_session *session) return err; } +static void +perf_session__warn_order(const struct perf_session *session) +{ + const struct ordered_events *oe = >ordered_events; + struct perf_evsel *evsel; + bool should_warn = true; + + evlist__for_each(session->evlist, evsel) { + if (evsel->attr.write_backward) + should_warn = false; + } + + if (!should_warn) + return; + if (oe->nr_unordered_events != 0) + ui__warning("%u out of order events recorded.\n", oe->nr_unordered_events); +} + static void perf_session__warn_about_errors(const struct perf_session *session) { const struct events_stats *stats = >evlist->stats; - const struct ordered_events *oe = >ordered_events; if (session->tool->lost == perf_event__process_lost && stats->nr_events[PERF_RECORD_LOST] != 0) { @@ -1555,8 +1572,7 @@ static void perf_session__warn_about_errors(const struct perf_session *session) stats->nr_unprocessable_samples); } - if (oe->nr_unordered_events != 0) - ui__warning("%u out of order events recorded.\n", oe->nr_unordered_events); + perf_session__warn_order(session); events_stats__auxtrace_error_warn(stats); -- 1.8.3.4
[PATCH v5 2/8] perf tools: Choose correct reading direction according to evlist->backward
Now we have evlist->backward to indicate the mmap direction. Make perf_evlist__mmap_read() choose right direction automatically. Signed-off-by: Wang Nan Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Zefan Li Cc: He Kuang --- tools/perf/util/evlist.c | 9 - tools/perf/util/evlist.h | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index f916d25..8f7b44e 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -778,7 +778,7 @@ broken_event: return event; } -union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx) +union perf_event *perf_evlist__mmap_read_forward(struct perf_evlist *evlist, int idx) { struct perf_mmap *md = >mmap[idx]; u64 head; @@ -833,6 +833,13 @@ perf_evlist__mmap_read_backward(struct perf_evlist *evlist, int idx) return perf_mmap__read(md, false, start, end, >prev); } +union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx) +{ + if (!evlist->backward) + return perf_evlist__mmap_read_forward(evlist, idx); + return perf_evlist__mmap_read_backward(evlist, idx); +} + void perf_evlist__mmap_read_catchup(struct perf_evlist *evlist, int idx) { struct perf_mmap *md = >mmap[idx]; diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 0505012..41e65ac 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -134,6 +134,8 @@ struct perf_sample_id *perf_evlist__id2sid(struct perf_evlist *evlist, u64 id); union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx); +union perf_event *perf_evlist__mmap_read_forward(struct perf_evlist *evlist, +int idx); union perf_event *perf_evlist__mmap_read_backward(struct perf_evlist *evlist, int idx); void perf_evlist__mmap_read_catchup(struct perf_evlist *evlist, int idx); -- 1.8.3.4
Re: [PATCH 4/4] MAINTAINERS: mark bcache as orphan
On Tue, 24 May 2016, Joe Perches wrote: > > The submitted patches are not being reacted upon, and Jens is only picking > > up stable fixes on an rather ad-hoc basis. > > > > Link: lkml.kernel.org/r/574462c5.40...@kernel.dk > > Signed-off-by: Jiri Kosina> > --- > > MAINTAINERS | 2 +- > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > diff --git a/MAINTAINERS b/MAINTAINERS > > index 5f83015..c9906d6 100644 > > --- a/MAINTAINERS > > +++ b/MAINTAINERS > > @@ -2288,7 +2288,7 @@ BCACHE (BLOCK LAYER CACHE) > > M: Kent Overstreet > > L: linux-bca...@vger.kernel.org > > W: http://bcache.evilpiepirate.org > > -S: Maintained > > +S: Orphan > > F: drivers/md/bcache/ > > Sections marked as Orphan generally > don't also have a named maintainer. > > Should Kent still be listed here? Thanks for the remark. I'd leave this up to Jens, as apparently at the end of the day he's the one relaying stability bugfixes upstream; so it might actually make sense to have him listed there eventually (while keeping the Orphan status). -- Jiri Kosina SUSE Labs
Re: [PATCH 4/4] MAINTAINERS: mark bcache as orphan
On Tue, 24 May 2016, Joe Perches wrote: > > The submitted patches are not being reacted upon, and Jens is only picking > > up stable fixes on an rather ad-hoc basis. > > > > Link: lkml.kernel.org/r/574462c5.40...@kernel.dk > > Signed-off-by: Jiri Kosina > > --- > > MAINTAINERS | 2 +- > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > diff --git a/MAINTAINERS b/MAINTAINERS > > index 5f83015..c9906d6 100644 > > --- a/MAINTAINERS > > +++ b/MAINTAINERS > > @@ -2288,7 +2288,7 @@ BCACHE (BLOCK LAYER CACHE) > > M: Kent Overstreet > > L: linux-bca...@vger.kernel.org > > W: http://bcache.evilpiepirate.org > > -S: Maintained > > +S: Orphan > > F: drivers/md/bcache/ > > Sections marked as Orphan generally > don't also have a named maintainer. > > Should Kent still be listed here? Thanks for the remark. I'd leave this up to Jens, as apparently at the end of the day he's the one relaying stability bugfixes upstream; so it might actually make sense to have him listed there eventually (while keeping the Orphan status). -- Jiri Kosina SUSE Labs
[PATCH v5 0/8] perf tools: Support overwritable ring buffer
This patch set enables daemonized perf recording by utilizing overwritable backward ring buffer. With this feature one can put perf background, and dump ring buffer records by a SIGUSR2 when he/she find something unusual. For example, following command record system calls, schedule events and samples on cpu cycles continously: # perf record -g -e cycles -e raw_syscalls:*/call-graph=no/ \ -e sched:sched_switch/call-graph=no/ \ --switch-output --overwrite -a Then by sending SIGUSR2 to perf when lagging is happen, we get multiple perf.data output, each of them correspond a abnormal event, and the data size is reasonable: # ls -l ./perf.data* -rw--- 1 root root 5122165 May 13 23:51 ./perf.data.2016051323511683 -rw--- 1 root root 5135093 May 13 23:51 ./perf.data.2016051323512107 -rw--- 1 root root 5135213 May 13 23:51 ./perf.data.2016051323512215 -rw--- 1 root root 5135157 May 13 23:51 ./perf.data.2016051323512387 v1 -> v2: Totally redesign: drop the principle of 'channal', use auxiliary evlist instead. Fix missing documentation. v2 -> v3: Rename perf_evlist__toggle_paused() to perf_evlist__pause/resume. v3 -> v4: Update commit message to describe auxiliary evlist more clearly. v4 -> v5: Reorder commits, ensure '--overwrite' works right after perf support the option. Add test cases for auxiliary evlist. Avoid bug if main evlist is empty. Wang Nan (8): perf tools: Check 'base' pointer before checking refcnt when put a mmap perf tools: Choose correct reading direction according to evlist->backward perf tests: Add testcase for auxiliary evlist perf record: Introduce rec->overwrite_evlist for overwritable events perf record: Toggle overwrite ring buffer for reading perf tools: Enable overwrite settings perf tools: Don't warn about out of order event if write_backward is used perf tools: Check write_backward during evlist config tools/perf/Documentation/perf-record.txt | 14 ++ tools/perf/builtin-record.c | 285 +++ tools/perf/perf.h| 1 + tools/perf/tests/backward-ring-buffer.c | 86 +++--- tools/perf/util/evlist.c | 15 +- tools/perf/util/evlist.h | 2 + tools/perf/util/evsel.c | 27 +-- tools/perf/util/evsel.h | 15 ++ tools/perf/util/parse-events.c | 20 ++- tools/perf/util/parse-events.h | 2 + tools/perf/util/parse-events.l | 2 + tools/perf/util/record.c | 17 ++ tools/perf/util/session.c| 22 ++- 13 files changed, 435 insertions(+), 73 deletions(-) Cc: Arnaldo Carvalho de MeloCc: He Kuang Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Wang Nan Cc: Zefan Li Cc: pi3or...@163.com -- 1.8.3.4
[PATCH v5 5/8] perf record: Toggle overwrite ring buffer for reading
overwrite_evt_state is introduced to reflect the state of overwritable ring buffers. It is a state machine with 3 states: RUNNING --(1)--> DATA_PENDING --(2)--> EMPTY ^ ^ | | |___(disallow)___/| || \_(3)__/ RUNNING : Overwritable ring buffers are recording DATA_PENDING : We are required to collect overwritable ring buffers EMPTY: We have collected data from those ring buffers. (1): Pause ring buffers for reading (2): Read from ring buffers (3): Resume ring buffers for recording We can't avoid this complexity. Because we deliberately drop records from overwritable ring buffer, we can't detect remaining data by checking head and old pointers. Therefore, DATA_PENDING state is mandatory. Signed-off-by: Wang NanSigned-off-by: He Kuang Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Zefan Li Cc: pi3or...@163.com --- tools/perf/builtin-record.c | 146 +--- 1 file changed, 136 insertions(+), 10 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index e7be4e1..d5bb947 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -42,6 +42,28 @@ #include #include +/* + * State machine of overwrite_evt_state: + * + * RUNNING --(1)--> DATA_PENDING --(2)--> EMPTY + *^ ^ | + *| |___(disallow)___/| + *|| + * \_(3)__/ + * + * RUNNING : Overwritable ring buffers are recording + * DATA_PENDING : We are required to collect overwritable ring buffers + * EMPTY: We have collected data from those ring buffers. + * + * (1): Pause ring buffers for reading + * (2): Read from ring buffers + * (3): Resume ring buffers for recording + */ +enum overwrite_evt_state { + OVERWRITE_EVT_RUNNING, + OVERWRITE_EVT_DATA_PENDING, + OVERWRITE_EVT_EMPTY, +}; struct record { struct perf_tooltool; @@ -61,6 +83,7 @@ struct record { boolbuildid_all; booltimestamp_filename; boolswitch_output; + enum overwrite_evt_state overwrite_evt_state; unsigned long long samples; }; @@ -132,9 +155,9 @@ rb_find_range(struct perf_evlist *evlist, return backward_rb_find_range(data, mask, head, start, end); } -static int record__mmap_read(struct record *rec, int idx) +static int record__mmap_read(struct record *rec, struct perf_evlist *evlist, int idx) { - struct perf_mmap *md = >evlist->mmap[idx]; + struct perf_mmap *md = >mmap[idx]; u64 head = perf_mmap__read_head(md); u64 old = md->prev; u64 end = head, start = old; @@ -143,7 +166,7 @@ static int record__mmap_read(struct record *rec, int idx) void *buf; int rc = 0; - if (rb_find_range(rec->evlist, data, md->mask, head, + if (rb_find_range(evlist, data, md->mask, head, old, , )) return -1; @@ -157,7 +180,7 @@ static int record__mmap_read(struct record *rec, int idx) WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n"); md->prev = head; - perf_evlist__mmap_consume(rec->evlist, idx); + perf_evlist__mmap_consume(evlist, idx); return 0; } @@ -182,7 +205,7 @@ static int record__mmap_read(struct record *rec, int idx) } md->prev = head; - perf_evlist__mmap_consume(rec->evlist, idx); + perf_evlist__mmap_consume(evlist, idx); out: return rc; } @@ -468,6 +491,7 @@ try_again: goto out; session->evlist = evlist; perf_session__set_id_hdr_size(session); + rec->overwrite_evt_state = OVERWRITE_EVT_RUNNING; out: return rc; } @@ -548,17 +572,72 @@ static struct perf_event_header finished_round_event = { .type = PERF_RECORD_FINISHED_ROUND, }; -static int record__mmap_read_all(struct record *rec) +static void +record__toggle_overwrite_evsels(struct record *rec, + enum overwrite_evt_state state) +{ + struct perf_evlist *evlist = rec->overwrite_evlist; + enum overwrite_evt_state old_state = rec->overwrite_evt_state; + enum action { + NONE, + PAUSE, + RESUME, + } action = NONE; + + switch (old_state) { + case OVERWRITE_EVT_RUNNING: + if (state != OVERWRITE_EVT_RUNNING) + action = PAUSE; + break; + case OVERWRITE_EVT_DATA_PENDING: +
Re: [PATCH v4 08/10] powerpc/powernv: Add platform support for stop instruction
Hi Shreyas, On Tue, May 24, 2016 at 06:45:12PM +0530, Shreyas B. Prabhu wrote: > POWER ISA v3 defines a new idle processor core mechanism. In summary, > a) new instruction named stop is added. This instruction replaces > instructions like nap, sleep, rvwinkle. > b) new per thread SPR named Processor Stop Status and Control Register > (PSSCR) is added which controls the behavior of stop instruction. > > PSSCR layout: > -- > | PLS | /// | SD | ESL | EC | PSLL | /// | TR | MTL | RL | > -- > 0 4 41 4243 44 4854 5660 > > PSSCR key fields: > Bits 0:3 - Power-Saving Level Status. This field indicates the lowest > power-saving state the thread entered since stop instruction was last > executed. > > Bit 42 - Enable State Loss > 0 - No state is lost irrespective of other fields > 1 - Allows state loss > > Bits 44:47 - Power-Saving Level Limit > This limits the power-saving level that can be entered into. > > Bits 60:63 - Requested Level > Used to specify which power-saving level must be entered on executing > stop instruction > > This patch adds support for stop instruction and PSSCR handling. This version looks good to me. Reviewed-by: Gautham R. Shenoy-- Thanks and Regards gautham.
[PATCH v5 0/8] perf tools: Support overwritable ring buffer
This patch set enables daemonized perf recording by utilizing overwritable backward ring buffer. With this feature one can put perf background, and dump ring buffer records by a SIGUSR2 when he/she find something unusual. For example, following command record system calls, schedule events and samples on cpu cycles continously: # perf record -g -e cycles -e raw_syscalls:*/call-graph=no/ \ -e sched:sched_switch/call-graph=no/ \ --switch-output --overwrite -a Then by sending SIGUSR2 to perf when lagging is happen, we get multiple perf.data output, each of them correspond a abnormal event, and the data size is reasonable: # ls -l ./perf.data* -rw--- 1 root root 5122165 May 13 23:51 ./perf.data.2016051323511683 -rw--- 1 root root 5135093 May 13 23:51 ./perf.data.2016051323512107 -rw--- 1 root root 5135213 May 13 23:51 ./perf.data.2016051323512215 -rw--- 1 root root 5135157 May 13 23:51 ./perf.data.2016051323512387 v1 -> v2: Totally redesign: drop the principle of 'channal', use auxiliary evlist instead. Fix missing documentation. v2 -> v3: Rename perf_evlist__toggle_paused() to perf_evlist__pause/resume. v3 -> v4: Update commit message to describe auxiliary evlist more clearly. v4 -> v5: Reorder commits, ensure '--overwrite' works right after perf support the option. Add test cases for auxiliary evlist. Avoid bug if main evlist is empty. Wang Nan (8): perf tools: Check 'base' pointer before checking refcnt when put a mmap perf tools: Choose correct reading direction according to evlist->backward perf tests: Add testcase for auxiliary evlist perf record: Introduce rec->overwrite_evlist for overwritable events perf record: Toggle overwrite ring buffer for reading perf tools: Enable overwrite settings perf tools: Don't warn about out of order event if write_backward is used perf tools: Check write_backward during evlist config tools/perf/Documentation/perf-record.txt | 14 ++ tools/perf/builtin-record.c | 285 +++ tools/perf/perf.h| 1 + tools/perf/tests/backward-ring-buffer.c | 86 +++--- tools/perf/util/evlist.c | 15 +- tools/perf/util/evlist.h | 2 + tools/perf/util/evsel.c | 27 +-- tools/perf/util/evsel.h | 15 ++ tools/perf/util/parse-events.c | 20 ++- tools/perf/util/parse-events.h | 2 + tools/perf/util/parse-events.l | 2 + tools/perf/util/record.c | 17 ++ tools/perf/util/session.c| 22 ++- 13 files changed, 435 insertions(+), 73 deletions(-) Cc: Arnaldo Carvalho de Melo Cc: He Kuang Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Wang Nan Cc: Zefan Li Cc: pi3or...@163.com -- 1.8.3.4
[PATCH v5 5/8] perf record: Toggle overwrite ring buffer for reading
overwrite_evt_state is introduced to reflect the state of overwritable ring buffers. It is a state machine with 3 states: RUNNING --(1)--> DATA_PENDING --(2)--> EMPTY ^ ^ | | |___(disallow)___/| || \_(3)__/ RUNNING : Overwritable ring buffers are recording DATA_PENDING : We are required to collect overwritable ring buffers EMPTY: We have collected data from those ring buffers. (1): Pause ring buffers for reading (2): Read from ring buffers (3): Resume ring buffers for recording We can't avoid this complexity. Because we deliberately drop records from overwritable ring buffer, we can't detect remaining data by checking head and old pointers. Therefore, DATA_PENDING state is mandatory. Signed-off-by: Wang Nan Signed-off-by: He Kuang Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Zefan Li Cc: pi3or...@163.com --- tools/perf/builtin-record.c | 146 +--- 1 file changed, 136 insertions(+), 10 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index e7be4e1..d5bb947 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -42,6 +42,28 @@ #include #include +/* + * State machine of overwrite_evt_state: + * + * RUNNING --(1)--> DATA_PENDING --(2)--> EMPTY + *^ ^ | + *| |___(disallow)___/| + *|| + * \_(3)__/ + * + * RUNNING : Overwritable ring buffers are recording + * DATA_PENDING : We are required to collect overwritable ring buffers + * EMPTY: We have collected data from those ring buffers. + * + * (1): Pause ring buffers for reading + * (2): Read from ring buffers + * (3): Resume ring buffers for recording + */ +enum overwrite_evt_state { + OVERWRITE_EVT_RUNNING, + OVERWRITE_EVT_DATA_PENDING, + OVERWRITE_EVT_EMPTY, +}; struct record { struct perf_tooltool; @@ -61,6 +83,7 @@ struct record { boolbuildid_all; booltimestamp_filename; boolswitch_output; + enum overwrite_evt_state overwrite_evt_state; unsigned long long samples; }; @@ -132,9 +155,9 @@ rb_find_range(struct perf_evlist *evlist, return backward_rb_find_range(data, mask, head, start, end); } -static int record__mmap_read(struct record *rec, int idx) +static int record__mmap_read(struct record *rec, struct perf_evlist *evlist, int idx) { - struct perf_mmap *md = >evlist->mmap[idx]; + struct perf_mmap *md = >mmap[idx]; u64 head = perf_mmap__read_head(md); u64 old = md->prev; u64 end = head, start = old; @@ -143,7 +166,7 @@ static int record__mmap_read(struct record *rec, int idx) void *buf; int rc = 0; - if (rb_find_range(rec->evlist, data, md->mask, head, + if (rb_find_range(evlist, data, md->mask, head, old, , )) return -1; @@ -157,7 +180,7 @@ static int record__mmap_read(struct record *rec, int idx) WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n"); md->prev = head; - perf_evlist__mmap_consume(rec->evlist, idx); + perf_evlist__mmap_consume(evlist, idx); return 0; } @@ -182,7 +205,7 @@ static int record__mmap_read(struct record *rec, int idx) } md->prev = head; - perf_evlist__mmap_consume(rec->evlist, idx); + perf_evlist__mmap_consume(evlist, idx); out: return rc; } @@ -468,6 +491,7 @@ try_again: goto out; session->evlist = evlist; perf_session__set_id_hdr_size(session); + rec->overwrite_evt_state = OVERWRITE_EVT_RUNNING; out: return rc; } @@ -548,17 +572,72 @@ static struct perf_event_header finished_round_event = { .type = PERF_RECORD_FINISHED_ROUND, }; -static int record__mmap_read_all(struct record *rec) +static void +record__toggle_overwrite_evsels(struct record *rec, + enum overwrite_evt_state state) +{ + struct perf_evlist *evlist = rec->overwrite_evlist; + enum overwrite_evt_state old_state = rec->overwrite_evt_state; + enum action { + NONE, + PAUSE, + RESUME, + } action = NONE; + + switch (old_state) { + case OVERWRITE_EVT_RUNNING: + if (state != OVERWRITE_EVT_RUNNING) + action = PAUSE; + break; + case OVERWRITE_EVT_DATA_PENDING: + if (state == OVERWRITE_EVT_RUNNING) + action = RESUME; + break; + case OVERWRITE_EVT_EMPTY: +
Re: [PATCH v4 08/10] powerpc/powernv: Add platform support for stop instruction
Hi Shreyas, On Tue, May 24, 2016 at 06:45:12PM +0530, Shreyas B. Prabhu wrote: > POWER ISA v3 defines a new idle processor core mechanism. In summary, > a) new instruction named stop is added. This instruction replaces > instructions like nap, sleep, rvwinkle. > b) new per thread SPR named Processor Stop Status and Control Register > (PSSCR) is added which controls the behavior of stop instruction. > > PSSCR layout: > -- > | PLS | /// | SD | ESL | EC | PSLL | /// | TR | MTL | RL | > -- > 0 4 41 4243 44 4854 5660 > > PSSCR key fields: > Bits 0:3 - Power-Saving Level Status. This field indicates the lowest > power-saving state the thread entered since stop instruction was last > executed. > > Bit 42 - Enable State Loss > 0 - No state is lost irrespective of other fields > 1 - Allows state loss > > Bits 44:47 - Power-Saving Level Limit > This limits the power-saving level that can be entered into. > > Bits 60:63 - Requested Level > Used to specify which power-saving level must be entered on executing > stop instruction > > This patch adds support for stop instruction and PSSCR handling. This version looks good to me. Reviewed-by: Gautham R. Shenoy -- Thanks and Regards gautham.
[PATCH v5 1/8] perf tools: Check 'base' pointer before checking refcnt when put a mmap
evlist->mmap[i]->refcnt could be 0 if an evlist has no evsel or all evsels don't match the evlist during mmap. For example, when all evsels are overwritable but the evlist itself is normal. To avoid crashing, perf should check 'base' pointer before checking refcnt, and raise bug only when base is not NULL. Signed-off-by: Wang NanCc: He Kuang Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Zefan Li Cc: pi3or...@163.com --- tools/perf/util/evlist.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index fbd0d47..f916d25 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -857,9 +857,11 @@ static void perf_evlist__mmap_get(struct perf_evlist *evlist, int idx) static void perf_evlist__mmap_put(struct perf_evlist *evlist, int idx) { - BUG_ON(atomic_read(>mmap[idx].refcnt) == 0); + struct perf_mmap *mmap = >mmap[idx]; - if (atomic_dec_and_test(>mmap[idx].refcnt)) + BUG_ON(mmap->base && atomic_read(>refcnt) == 0); + + if (atomic_dec_and_test(>refcnt)) __perf_evlist__munmap(evlist, idx); } -- 1.8.3.4
[PATCH v5 6/8] perf tools: Enable overwrite settings
This patch allows following config terms and option: Globally setting events to overwrite; # perf record --overwrite ... Set specific events to be overwrite or no-overwrite. # perf record --event cycles/overwrite/ ... # perf record --event cycles/no-overwrite/ ... Add missing config terms and update config term array size because the longest string length is changed. For overwritable events, automatically select attr.write_backward since perf requires it to be backward for reading. Test result: # perf record --overwrite -e syscalls:*enter_nanosleep* usleep 1 [ perf record: Woken up 2 times to write data ] [ perf record: Captured and wrote 0.011 MB perf.data (1 samples) ] # perf evlist -v syscalls:sys_enter_nanosleep: type: 2, size: 112, config: 0x134, { sample_period, sample_freq }: 1, sample_type: IP|TID|TIME|CPU|PERIOD|RAW, disabled: 1, inherit: 1, mmap: 1, comm: 1, enable_on_exec: 1, task: 1, sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1, write_backward: 1 # Tip: use 'perf evlist --trace-fields' to show fields for tracepoint events Signed-off-by: Wang NanSigned-off-by: He Kuang Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Zefan Li Cc: pi3or...@163.com --- tools/perf/Documentation/perf-record.txt | 14 ++ tools/perf/builtin-record.c | 1 + tools/perf/perf.h| 1 + tools/perf/tests/backward-ring-buffer.c | 15 ++- tools/perf/util/evsel.c | 12 tools/perf/util/evsel.h | 2 ++ tools/perf/util/parse-events.c | 20 ++-- tools/perf/util/parse-events.h | 2 ++ tools/perf/util/parse-events.l | 2 ++ 9 files changed, 58 insertions(+), 11 deletions(-) diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index 8dbee83..f5cb932 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt @@ -360,6 +360,20 @@ particular perf.data snapshot should be kept or not. Implies --timestamp-filename, --no-buildid and --no-buildid-cache. +--overwrite:: +Makes all events use overwritable ring buffer. Event with overwritable ring +buffer works like a flight recorder: when buffer gets full, instead of dumping +records into output file, kernel overwrites old records silently. Perf dumps +data from overwritable ring buffer when switching output (see --switch-output) +and before terminate. + +Perf behaves like a daemon when '--overwrite' and '--switch-output' are +provided. It record and drop events in background, and dumps data when +something unusual is detected. + +'overwrite' attribute can also be set or canceled for specific event using +config terms like 'cycles/overwrite/' and 'instructions/no-overwrite/'. + SEE ALSO linkperf:perf-stat[1], linkperf:perf-list[1] diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index d5bb947..bf63515 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -1524,6 +1524,7 @@ struct option __record_options[] = { OPT_BOOLEAN_SET('i', "no-inherit", _inherit, _inherit_set, "child tasks do not inherit counters"), + OPT_BOOLEAN(0, "overwrite", , "use overwrite mode"), OPT_UINTEGER('F', "freq", _freq, "profile at this frequency"), OPT_CALLBACK('m', "mmap-pages", , "pages[,pages]", "number of mmap data pages and AUX area tracing mmap pages", diff --git a/tools/perf/perf.h b/tools/perf/perf.h index cd8f1b1..608b42b 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h @@ -59,6 +59,7 @@ struct record_opts { bool record_switch_events; bool all_kernel; bool all_user; + bool overwrite; unsigned int freq; unsigned int mmap_pages; unsigned int auxtrace_mmap_pages; diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index 76e34c0..bba0b83 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -130,27 +130,24 @@ int test__backward_ring_buffer(int subtest __maybe_unused) } bzero(_error, sizeof(parse_error)); - err = parse_events(evlist, "syscalls:sys_enter_prctl", _error); + /* +* Set backward bit, ring buffer should be writing from end. Record +* it in aux evlist +*/ + err = parse_events(evlist, "syscalls:sys_enter_prctl/overwrite/", _error); if (err) { pr_debug("Failed to parse tracepoint event, try use root\n"); ret = TEST_SKIP; goto out_delete_evlist; } - /* -* Set
[PATCH v5 1/8] perf tools: Check 'base' pointer before checking refcnt when put a mmap
evlist->mmap[i]->refcnt could be 0 if an evlist has no evsel or all evsels don't match the evlist during mmap. For example, when all evsels are overwritable but the evlist itself is normal. To avoid crashing, perf should check 'base' pointer before checking refcnt, and raise bug only when base is not NULL. Signed-off-by: Wang Nan Cc: He Kuang Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Zefan Li Cc: pi3or...@163.com --- tools/perf/util/evlist.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index fbd0d47..f916d25 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -857,9 +857,11 @@ static void perf_evlist__mmap_get(struct perf_evlist *evlist, int idx) static void perf_evlist__mmap_put(struct perf_evlist *evlist, int idx) { - BUG_ON(atomic_read(>mmap[idx].refcnt) == 0); + struct perf_mmap *mmap = >mmap[idx]; - if (atomic_dec_and_test(>mmap[idx].refcnt)) + BUG_ON(mmap->base && atomic_read(>refcnt) == 0); + + if (atomic_dec_and_test(>refcnt)) __perf_evlist__munmap(evlist, idx); } -- 1.8.3.4
[PATCH v5 6/8] perf tools: Enable overwrite settings
This patch allows following config terms and option: Globally setting events to overwrite; # perf record --overwrite ... Set specific events to be overwrite or no-overwrite. # perf record --event cycles/overwrite/ ... # perf record --event cycles/no-overwrite/ ... Add missing config terms and update config term array size because the longest string length is changed. For overwritable events, automatically select attr.write_backward since perf requires it to be backward for reading. Test result: # perf record --overwrite -e syscalls:*enter_nanosleep* usleep 1 [ perf record: Woken up 2 times to write data ] [ perf record: Captured and wrote 0.011 MB perf.data (1 samples) ] # perf evlist -v syscalls:sys_enter_nanosleep: type: 2, size: 112, config: 0x134, { sample_period, sample_freq }: 1, sample_type: IP|TID|TIME|CPU|PERIOD|RAW, disabled: 1, inherit: 1, mmap: 1, comm: 1, enable_on_exec: 1, task: 1, sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1, write_backward: 1 # Tip: use 'perf evlist --trace-fields' to show fields for tracepoint events Signed-off-by: Wang Nan Signed-off-by: He Kuang Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Zefan Li Cc: pi3or...@163.com --- tools/perf/Documentation/perf-record.txt | 14 ++ tools/perf/builtin-record.c | 1 + tools/perf/perf.h| 1 + tools/perf/tests/backward-ring-buffer.c | 15 ++- tools/perf/util/evsel.c | 12 tools/perf/util/evsel.h | 2 ++ tools/perf/util/parse-events.c | 20 ++-- tools/perf/util/parse-events.h | 2 ++ tools/perf/util/parse-events.l | 2 ++ 9 files changed, 58 insertions(+), 11 deletions(-) diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index 8dbee83..f5cb932 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt @@ -360,6 +360,20 @@ particular perf.data snapshot should be kept or not. Implies --timestamp-filename, --no-buildid and --no-buildid-cache. +--overwrite:: +Makes all events use overwritable ring buffer. Event with overwritable ring +buffer works like a flight recorder: when buffer gets full, instead of dumping +records into output file, kernel overwrites old records silently. Perf dumps +data from overwritable ring buffer when switching output (see --switch-output) +and before terminate. + +Perf behaves like a daemon when '--overwrite' and '--switch-output' are +provided. It record and drop events in background, and dumps data when +something unusual is detected. + +'overwrite' attribute can also be set or canceled for specific event using +config terms like 'cycles/overwrite/' and 'instructions/no-overwrite/'. + SEE ALSO linkperf:perf-stat[1], linkperf:perf-list[1] diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index d5bb947..bf63515 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -1524,6 +1524,7 @@ struct option __record_options[] = { OPT_BOOLEAN_SET('i', "no-inherit", _inherit, _inherit_set, "child tasks do not inherit counters"), + OPT_BOOLEAN(0, "overwrite", , "use overwrite mode"), OPT_UINTEGER('F', "freq", _freq, "profile at this frequency"), OPT_CALLBACK('m', "mmap-pages", , "pages[,pages]", "number of mmap data pages and AUX area tracing mmap pages", diff --git a/tools/perf/perf.h b/tools/perf/perf.h index cd8f1b1..608b42b 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h @@ -59,6 +59,7 @@ struct record_opts { bool record_switch_events; bool all_kernel; bool all_user; + bool overwrite; unsigned int freq; unsigned int mmap_pages; unsigned int auxtrace_mmap_pages; diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index 76e34c0..bba0b83 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -130,27 +130,24 @@ int test__backward_ring_buffer(int subtest __maybe_unused) } bzero(_error, sizeof(parse_error)); - err = parse_events(evlist, "syscalls:sys_enter_prctl", _error); + /* +* Set backward bit, ring buffer should be writing from end. Record +* it in aux evlist +*/ + err = parse_events(evlist, "syscalls:sys_enter_prctl/overwrite/", _error); if (err) { pr_debug("Failed to parse tracepoint event, try use root\n"); ret = TEST_SKIP; goto out_delete_evlist; } - /* -* Set backward bit, ring buffer should be writing from end. Record -* it in aux evlist -*/ - perf_evlist__last(evlist)->overwrite = true;
[PATCH v5 4/8] perf record: Introduce rec->overwrite_evlist for overwritable events
Create an auxiliary evlist for overwritable events. Before mmap, build this evlist and set 'overwrite' and 'backward' attribute. Since perf_evlist__mmap_ex() only maps events when evsel->overwrite matches evlist's corresponding attributes, with these two evlists an event goes to either rec->evlist or rec->overwrite_evlist. Signed-off-by: Wang NanCc: He Kuang Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Zefan Li Cc: pi3or...@163.com --- tools/perf/builtin-record.c | 138 1 file changed, 114 insertions(+), 24 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index d4cf1b0..e7be4e1 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -50,6 +50,7 @@ struct record { struct perf_data_file file; struct auxtrace_record *itr; struct perf_evlist *evlist; + struct perf_evlist *overwrite_evlist; struct perf_session *session; const char *progname; int realtime_prio; @@ -341,6 +342,84 @@ int auxtrace_record__snapshot_start(struct auxtrace_record *itr __maybe_unused) #endif +static int record__create_overwrite_evlist(struct record *rec) +{ + struct perf_evlist *evlist = rec->evlist; + struct perf_evsel *pos; + + evlist__for_each(evlist, pos) { + if (!pos->overwrite) + continue; + + if (!rec->overwrite_evlist) { + rec->overwrite_evlist = perf_evlist__new_aux(evlist); + if (rec->overwrite_evlist) { + rec->overwrite_evlist->backward = true; + rec->overwrite_evlist->overwrite = true; + return 0; + } else + return -ENOMEM; + } + } + return 0; +} + +static int record__mmap_evlist(struct record *rec, + struct perf_evlist *evlist, + bool overwrite) +{ + struct record_opts *opts = >opts; + char msg[512]; + + /* +* Don't use evlist->overwrite because it is logically an +* internal attribute and is set by perf_evlist__mmap_ex(). +* Avoid circular dependency. +*/ + if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, overwrite, +opts->auxtrace_mmap_pages, +opts->auxtrace_snapshot_mode) < 0) { + if (errno == EPERM) { + pr_err("Permission error mapping pages.\n" + "Consider increasing " + "/proc/sys/kernel/perf_event_mlock_kb,\n" + "or try again with a smaller value of -m/--mmap_pages.\n" + "(current value: %u,%u)\n", + opts->mmap_pages, opts->auxtrace_mmap_pages); + return -errno; + } else { + pr_err("failed to mmap with %d (%s)\n", errno, + strerror_r(errno, msg, sizeof(msg))); + if (errno) + return -errno; + else + return -EINVAL; + } + } + return 0; +} + +static int record__mmap(struct record *rec) +{ + int err; + + err = record__create_overwrite_evlist(rec); + if (err) + return err; + + err = record__mmap_evlist(rec, rec->evlist, false); + if (err) + return err; + + if (!rec->overwrite_evlist) + return 0; + + err = record__mmap_evlist(rec, rec->overwrite_evlist, true); + if (err) + return err; + return 0; +} + static int record__open(struct record *rec) { char msg[512]; @@ -353,6 +432,13 @@ static int record__open(struct record *rec) perf_evlist__config(evlist, opts, _param); evlist__for_each(evlist, pos) { + if (pos->overwrite) { + if (!pos->attr.write_backward) { + ui__warning("Unable to read from overwrite ring buffer\n\n"); + rc = -ENOSYS; + goto out; + } + } try_again: if (perf_evsel__open(pos, pos->cpus, pos->threads) < 0) { if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) { @@ -377,28 +463,9 @@ try_again: goto out; } - if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, false, -
[PATCH v5 3/8] perf tests: Add testcase for auxiliary evlist
Improve test backward-ring-buffer, trace both enter and exit event of prctl() syscall, utilize auxiliary evlist to mmap enter and exit event into separated mmaps. Signed-off-by: Wang NanCc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Zefan Li Cc: He Kuang --- tools/perf/tests/backward-ring-buffer.c | 87 ++--- 1 file changed, 68 insertions(+), 19 deletions(-) diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index d9ba991..76e34c0 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -31,16 +31,19 @@ static int count_samples(struct perf_evlist *evlist, int *sample_count, for (i = 0; i < evlist->nr_mmaps; i++) { union perf_event *event; - perf_evlist__mmap_read_catchup(evlist, i); - while ((event = perf_evlist__mmap_read_backward(evlist, i)) != NULL) { + if (evlist->backward) + perf_evlist__mmap_read_catchup(evlist, i); + while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) { const u32 type = event->header.type; switch (type) { case PERF_RECORD_SAMPLE: - (*sample_count)++; + if (sample_count) + (*sample_count)++; break; case PERF_RECORD_COMM: - (*comm_count)++; + if (comm_count) + (*comm_count)++; break; default: pr_err("Unexpected record of type %d\n", type); @@ -51,34 +54,53 @@ static int count_samples(struct perf_evlist *evlist, int *sample_count, return TEST_OK; } -static int do_test(struct perf_evlist *evlist, int mmap_pages, - int *sample_count, int *comm_count) +static int do_test(struct perf_evlist *evlist, + struct perf_evlist *aux_evlist, + int mmap_pages, + int *enter_sample_count, + int *exit_sample_count, + int *comm_count) { int err; char sbuf[STRERR_BUFSIZE]; - err = perf_evlist__mmap(evlist, mmap_pages, true); + err = perf_evlist__mmap(evlist, mmap_pages, false); if (err < 0) { pr_debug("perf_evlist__mmap: %s\n", strerror_r(errno, sbuf, sizeof(sbuf))); return TEST_FAIL; } + err = perf_evlist__mmap(aux_evlist, mmap_pages, true); + if (err < 0) { + pr_debug("perf_evlist__mmap for aux_evlist: %s\n", +strerror_r(errno, sbuf, sizeof(sbuf))); + return TEST_FAIL; + } + perf_evlist__enable(evlist); testcase(); perf_evlist__disable(evlist); - err = count_samples(evlist, sample_count, comm_count); + err = count_samples(aux_evlist, exit_sample_count, comm_count); + if (err) + goto errout; + err = count_samples(evlist, enter_sample_count, NULL); + if (err) + goto errout; +errout: perf_evlist__munmap(evlist); + perf_evlist__munmap(aux_evlist); return err; } int test__backward_ring_buffer(int subtest __maybe_unused) { - int ret = TEST_SKIP, err, sample_count = 0, comm_count = 0; + int ret = TEST_SKIP, err; + int enter_sample_count = 0, exit_sample_count = 0, comm_count = 0; char pid[16], sbuf[STRERR_BUFSIZE]; - struct perf_evlist *evlist; + struct perf_evlist *evlist, *aux_evlist = NULL; struct perf_evsel *evsel __maybe_unused; struct parse_events_error parse_error; struct record_opts opts = { @@ -115,11 +137,22 @@ int test__backward_ring_buffer(int subtest __maybe_unused) goto out_delete_evlist; } - perf_evlist__config(evlist, , NULL); + /* +* Set backward bit, ring buffer should be writing from end. Record +* it in aux evlist +*/ + perf_evlist__last(evlist)->overwrite = true; + perf_evlist__last(evlist)->attr.write_backward = 1; - /* Set backward bit, ring buffer should be writing from end */ - evlist__for_each(evlist, evsel) - evsel->attr.write_backward = 1; + err = parse_events(evlist, "syscalls:sys_exit_prctl", _error); + if (err) { + pr_debug("Failed to parse tracepoint event, try use root\n"); + ret = TEST_SKIP; + goto out_delete_evlist; + } + /* Don't set
[PATCH v5 8/8] perf tools: Check write_backward during evlist config
Before this patch, when using overwritable ring buffer on an old kernel, error message is misleading: # ~/perf record -m 1 -e raw_syscalls:*/overwrite/ -a Error: The raw_syscalls:sys_enter event is not supported. This patch output clear error message to tell user his/her kernel is too old: # ~/perf record -m 1 -e raw_syscalls:*/overwrite/ -a Reading from overwrite event is not supported by this kernel Error: The raw_syscalls:sys_enter event is not supported. Signed-off-by: Wang NanCc: He Kuang Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Zefan Li Cc: pi3or...@163.com --- tools/perf/util/evsel.c | 17 + tools/perf/util/evsel.h | 13 + tools/perf/util/record.c | 17 + 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 6330a4f..994310f 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -29,17 +29,7 @@ #include "trace-event.h" #include "stat.h" -static struct { - bool sample_id_all; - bool exclude_guest; - bool mmap2; - bool cloexec; - bool clockid; - bool clockid_wrong; - bool lbr_flags; - bool write_backward; -} perf_missing_features; - +struct perf_missing_features perf_missing_features; static clockid_t clockid; static int perf_evsel__no_extra_init(struct perf_evsel *evsel __maybe_unused) @@ -684,8 +674,11 @@ static void apply_config_terms(struct perf_evsel *evsel, * possible to set overwrite globally, without config * terms. */ - if (evsel->overwrite) + if (evsel->overwrite) { + WARN_ONCE(perf_missing_features.write_backward, + "Reading from overwrite event is not supported by this kernel\n"); attr->write_backward = 1; + } /* User explicitly set per-event callgraph, clear the old setting and reset. */ if ((callgraph_buf != NULL) || (dump_size > 0)) { diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index bce99fa..c9b6716 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -11,6 +11,19 @@ #include "cpumap.h" #include "counts.h" +struct perf_missing_features { + bool sample_id_all; + bool exclude_guest; + bool mmap2; + bool cloexec; + bool clockid; + bool clockid_wrong; + bool lbr_flags; + bool write_backward; +}; + +extern struct perf_missing_features perf_missing_features; + struct perf_evsel; /* diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index 481792c..e3ab812 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c @@ -90,6 +90,11 @@ static void perf_probe_context_switch(struct perf_evsel *evsel) evsel->attr.context_switch = 1; } +static void perf_probe_write_backward(struct perf_evsel *evsel) +{ + evsel->attr.write_backward = 1; +} + bool perf_can_sample_identifier(void) { return perf_probe_api(perf_probe_sample_identifier); @@ -129,6 +134,17 @@ bool perf_can_record_cpu_wide(void) return true; } +static void perf_check_write_backward(void) +{ + static bool checked = false; + + if (!checked) { + perf_missing_features.write_backward = + !perf_probe_api(perf_probe_write_backward); + checked = true; + } +} + void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts, struct callchain_param *callchain) { @@ -136,6 +152,7 @@ void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts, bool use_sample_identifier = false; bool use_comm_exec; + perf_check_write_backward(); /* * Set the evsel leader links before we configure attributes, * since some might depend on this info. -- 1.8.3.4
[PATCH v5 4/8] perf record: Introduce rec->overwrite_evlist for overwritable events
Create an auxiliary evlist for overwritable events. Before mmap, build this evlist and set 'overwrite' and 'backward' attribute. Since perf_evlist__mmap_ex() only maps events when evsel->overwrite matches evlist's corresponding attributes, with these two evlists an event goes to either rec->evlist or rec->overwrite_evlist. Signed-off-by: Wang Nan Cc: He Kuang Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Zefan Li Cc: pi3or...@163.com --- tools/perf/builtin-record.c | 138 1 file changed, 114 insertions(+), 24 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index d4cf1b0..e7be4e1 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -50,6 +50,7 @@ struct record { struct perf_data_file file; struct auxtrace_record *itr; struct perf_evlist *evlist; + struct perf_evlist *overwrite_evlist; struct perf_session *session; const char *progname; int realtime_prio; @@ -341,6 +342,84 @@ int auxtrace_record__snapshot_start(struct auxtrace_record *itr __maybe_unused) #endif +static int record__create_overwrite_evlist(struct record *rec) +{ + struct perf_evlist *evlist = rec->evlist; + struct perf_evsel *pos; + + evlist__for_each(evlist, pos) { + if (!pos->overwrite) + continue; + + if (!rec->overwrite_evlist) { + rec->overwrite_evlist = perf_evlist__new_aux(evlist); + if (rec->overwrite_evlist) { + rec->overwrite_evlist->backward = true; + rec->overwrite_evlist->overwrite = true; + return 0; + } else + return -ENOMEM; + } + } + return 0; +} + +static int record__mmap_evlist(struct record *rec, + struct perf_evlist *evlist, + bool overwrite) +{ + struct record_opts *opts = >opts; + char msg[512]; + + /* +* Don't use evlist->overwrite because it is logically an +* internal attribute and is set by perf_evlist__mmap_ex(). +* Avoid circular dependency. +*/ + if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, overwrite, +opts->auxtrace_mmap_pages, +opts->auxtrace_snapshot_mode) < 0) { + if (errno == EPERM) { + pr_err("Permission error mapping pages.\n" + "Consider increasing " + "/proc/sys/kernel/perf_event_mlock_kb,\n" + "or try again with a smaller value of -m/--mmap_pages.\n" + "(current value: %u,%u)\n", + opts->mmap_pages, opts->auxtrace_mmap_pages); + return -errno; + } else { + pr_err("failed to mmap with %d (%s)\n", errno, + strerror_r(errno, msg, sizeof(msg))); + if (errno) + return -errno; + else + return -EINVAL; + } + } + return 0; +} + +static int record__mmap(struct record *rec) +{ + int err; + + err = record__create_overwrite_evlist(rec); + if (err) + return err; + + err = record__mmap_evlist(rec, rec->evlist, false); + if (err) + return err; + + if (!rec->overwrite_evlist) + return 0; + + err = record__mmap_evlist(rec, rec->overwrite_evlist, true); + if (err) + return err; + return 0; +} + static int record__open(struct record *rec) { char msg[512]; @@ -353,6 +432,13 @@ static int record__open(struct record *rec) perf_evlist__config(evlist, opts, _param); evlist__for_each(evlist, pos) { + if (pos->overwrite) { + if (!pos->attr.write_backward) { + ui__warning("Unable to read from overwrite ring buffer\n\n"); + rc = -ENOSYS; + goto out; + } + } try_again: if (perf_evsel__open(pos, pos->cpus, pos->threads) < 0) { if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) { @@ -377,28 +463,9 @@ try_again: goto out; } - if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, false, -opts->auxtrace_mmap_pages, -opts->auxtrace_snapshot_mode) < 0) { - if (errno == EPERM) { -
[PATCH v5 3/8] perf tests: Add testcase for auxiliary evlist
Improve test backward-ring-buffer, trace both enter and exit event of prctl() syscall, utilize auxiliary evlist to mmap enter and exit event into separated mmaps. Signed-off-by: Wang Nan Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Zefan Li Cc: He Kuang --- tools/perf/tests/backward-ring-buffer.c | 87 ++--- 1 file changed, 68 insertions(+), 19 deletions(-) diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index d9ba991..76e34c0 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -31,16 +31,19 @@ static int count_samples(struct perf_evlist *evlist, int *sample_count, for (i = 0; i < evlist->nr_mmaps; i++) { union perf_event *event; - perf_evlist__mmap_read_catchup(evlist, i); - while ((event = perf_evlist__mmap_read_backward(evlist, i)) != NULL) { + if (evlist->backward) + perf_evlist__mmap_read_catchup(evlist, i); + while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) { const u32 type = event->header.type; switch (type) { case PERF_RECORD_SAMPLE: - (*sample_count)++; + if (sample_count) + (*sample_count)++; break; case PERF_RECORD_COMM: - (*comm_count)++; + if (comm_count) + (*comm_count)++; break; default: pr_err("Unexpected record of type %d\n", type); @@ -51,34 +54,53 @@ static int count_samples(struct perf_evlist *evlist, int *sample_count, return TEST_OK; } -static int do_test(struct perf_evlist *evlist, int mmap_pages, - int *sample_count, int *comm_count) +static int do_test(struct perf_evlist *evlist, + struct perf_evlist *aux_evlist, + int mmap_pages, + int *enter_sample_count, + int *exit_sample_count, + int *comm_count) { int err; char sbuf[STRERR_BUFSIZE]; - err = perf_evlist__mmap(evlist, mmap_pages, true); + err = perf_evlist__mmap(evlist, mmap_pages, false); if (err < 0) { pr_debug("perf_evlist__mmap: %s\n", strerror_r(errno, sbuf, sizeof(sbuf))); return TEST_FAIL; } + err = perf_evlist__mmap(aux_evlist, mmap_pages, true); + if (err < 0) { + pr_debug("perf_evlist__mmap for aux_evlist: %s\n", +strerror_r(errno, sbuf, sizeof(sbuf))); + return TEST_FAIL; + } + perf_evlist__enable(evlist); testcase(); perf_evlist__disable(evlist); - err = count_samples(evlist, sample_count, comm_count); + err = count_samples(aux_evlist, exit_sample_count, comm_count); + if (err) + goto errout; + err = count_samples(evlist, enter_sample_count, NULL); + if (err) + goto errout; +errout: perf_evlist__munmap(evlist); + perf_evlist__munmap(aux_evlist); return err; } int test__backward_ring_buffer(int subtest __maybe_unused) { - int ret = TEST_SKIP, err, sample_count = 0, comm_count = 0; + int ret = TEST_SKIP, err; + int enter_sample_count = 0, exit_sample_count = 0, comm_count = 0; char pid[16], sbuf[STRERR_BUFSIZE]; - struct perf_evlist *evlist; + struct perf_evlist *evlist, *aux_evlist = NULL; struct perf_evsel *evsel __maybe_unused; struct parse_events_error parse_error; struct record_opts opts = { @@ -115,11 +137,22 @@ int test__backward_ring_buffer(int subtest __maybe_unused) goto out_delete_evlist; } - perf_evlist__config(evlist, , NULL); + /* +* Set backward bit, ring buffer should be writing from end. Record +* it in aux evlist +*/ + perf_evlist__last(evlist)->overwrite = true; + perf_evlist__last(evlist)->attr.write_backward = 1; - /* Set backward bit, ring buffer should be writing from end */ - evlist__for_each(evlist, evsel) - evsel->attr.write_backward = 1; + err = parse_events(evlist, "syscalls:sys_exit_prctl", _error); + if (err) { + pr_debug("Failed to parse tracepoint event, try use root\n"); + ret = TEST_SKIP; + goto out_delete_evlist; + } + /* Don't set backward bit for exit event. Record it in main evlist */ + + perf_evlist__config(evlist, , NULL); err =
[PATCH v5 8/8] perf tools: Check write_backward during evlist config
Before this patch, when using overwritable ring buffer on an old kernel, error message is misleading: # ~/perf record -m 1 -e raw_syscalls:*/overwrite/ -a Error: The raw_syscalls:sys_enter event is not supported. This patch output clear error message to tell user his/her kernel is too old: # ~/perf record -m 1 -e raw_syscalls:*/overwrite/ -a Reading from overwrite event is not supported by this kernel Error: The raw_syscalls:sys_enter event is not supported. Signed-off-by: Wang Nan Cc: He Kuang Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Zefan Li Cc: pi3or...@163.com --- tools/perf/util/evsel.c | 17 + tools/perf/util/evsel.h | 13 + tools/perf/util/record.c | 17 + 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 6330a4f..994310f 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -29,17 +29,7 @@ #include "trace-event.h" #include "stat.h" -static struct { - bool sample_id_all; - bool exclude_guest; - bool mmap2; - bool cloexec; - bool clockid; - bool clockid_wrong; - bool lbr_flags; - bool write_backward; -} perf_missing_features; - +struct perf_missing_features perf_missing_features; static clockid_t clockid; static int perf_evsel__no_extra_init(struct perf_evsel *evsel __maybe_unused) @@ -684,8 +674,11 @@ static void apply_config_terms(struct perf_evsel *evsel, * possible to set overwrite globally, without config * terms. */ - if (evsel->overwrite) + if (evsel->overwrite) { + WARN_ONCE(perf_missing_features.write_backward, + "Reading from overwrite event is not supported by this kernel\n"); attr->write_backward = 1; + } /* User explicitly set per-event callgraph, clear the old setting and reset. */ if ((callgraph_buf != NULL) || (dump_size > 0)) { diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index bce99fa..c9b6716 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -11,6 +11,19 @@ #include "cpumap.h" #include "counts.h" +struct perf_missing_features { + bool sample_id_all; + bool exclude_guest; + bool mmap2; + bool cloexec; + bool clockid; + bool clockid_wrong; + bool lbr_flags; + bool write_backward; +}; + +extern struct perf_missing_features perf_missing_features; + struct perf_evsel; /* diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index 481792c..e3ab812 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c @@ -90,6 +90,11 @@ static void perf_probe_context_switch(struct perf_evsel *evsel) evsel->attr.context_switch = 1; } +static void perf_probe_write_backward(struct perf_evsel *evsel) +{ + evsel->attr.write_backward = 1; +} + bool perf_can_sample_identifier(void) { return perf_probe_api(perf_probe_sample_identifier); @@ -129,6 +134,17 @@ bool perf_can_record_cpu_wide(void) return true; } +static void perf_check_write_backward(void) +{ + static bool checked = false; + + if (!checked) { + perf_missing_features.write_backward = + !perf_probe_api(perf_probe_write_backward); + checked = true; + } +} + void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts, struct callchain_param *callchain) { @@ -136,6 +152,7 @@ void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts, bool use_sample_identifier = false; bool use_comm_exec; + perf_check_write_backward(); /* * Set the evsel leader links before we configure attributes, * since some might depend on this info. -- 1.8.3.4
Re: [PATCH][v7] x86, suspend: Save/restore extra MSR registers for suspend
Hi Len, On Wed, May 25, 2016 at 12:09 AM, Len Brownwrote: > +mjg59, who may be seeing this issue on a skylake laptop > > Chen-yu, > > Great debugging, but I think there is a more general fix possible than > this DMI quirk. > > I agree that in this example, a grantley server, it seems the BIOS is > erroneously > returning a bogus value of MSR_IA32_THERM_CONTROL on resume from S3. > > But another scenario is also possible. Consider a laptop that is resuming HOT > and the BIOS correctly enables throttling. If this code were invoked, it > would > restore the COLD setting. > > Instead, it seems to me that the ACPI processor driver should upon .resume > check if throttling should be enabled or not, and proceed accordingly. > That would always do the "right thing", and would not need a DMI list. > Does that make sense? I agree, to let the related drivers customize their restoring process would be more robust, and we can not only take care of boot CPU but also nonboot CPUs in this way. I think we can add something like acpi_processor_reevaluate_tstate in the resume hook,I'll make a double check. thanks, Yu
Re: [PATCH][v7] x86, suspend: Save/restore extra MSR registers for suspend
Hi Len, On Wed, May 25, 2016 at 12:09 AM, Len Brown wrote: > +mjg59, who may be seeing this issue on a skylake laptop > > Chen-yu, > > Great debugging, but I think there is a more general fix possible than > this DMI quirk. > > I agree that in this example, a grantley server, it seems the BIOS is > erroneously > returning a bogus value of MSR_IA32_THERM_CONTROL on resume from S3. > > But another scenario is also possible. Consider a laptop that is resuming HOT > and the BIOS correctly enables throttling. If this code were invoked, it > would > restore the COLD setting. > > Instead, it seems to me that the ACPI processor driver should upon .resume > check if throttling should be enabled or not, and proceed accordingly. > That would always do the "right thing", and would not need a DMI list. > Does that make sense? I agree, to let the related drivers customize their restoring process would be more robust, and we can not only take care of boot CPU but also nonboot CPUs in this way. I think we can add something like acpi_processor_reevaluate_tstate in the resume hook,I'll make a double check. thanks, Yu
Re: [RFC][PATCH 1/3] locking: Introduce smp_acquire__after_ctrl_dep
On Tue, May 24, 2016 at 11:01:21PM -0400, Waiman Long wrote: > On 05/24/2016 10:27 AM, Peter Zijlstra wrote: > >Introduce smp_acquire__after_ctrl_dep(), this construct is not > >uncommen, but the lack of this barrier is. > > > >Signed-off-by: Peter Zijlstra (Intel)> >--- > > include/linux/compiler.h | 14 ++ > > ipc/sem.c| 14 ++ > > 2 files changed, 12 insertions(+), 16 deletions(-) > > > >--- a/include/linux/compiler.h > >+++ b/include/linux/compiler.h > >@@ -305,20 +305,26 @@ static __always_inline void __write_once > > }) > > > > /** > >+ * smp_acquire__after_ctrl_dep() - Provide ACQUIRE ordering after a control > >dependency > >+ * > >+ * A control dependency provides a LOAD->STORE order, the additional RMB > >+ * provides LOAD->LOAD order, together they provide LOAD->{LOAD,STORE} > >order, > >+ * aka. ACQUIRE. > >+ */ > >+#define smp_acquire__after_ctrl_dep() smp_rmb() > >+ > >+/** > > * smp_cond_acquire() - Spin wait for cond with ACQUIRE ordering > > * @cond: boolean expression to wait for > > * > > * Equivalent to using smp_load_acquire() on the condition variable but > > employs > > * the control dependency of the wait to reduce the barrier on many > > platforms. > > * > >- * The control dependency provides a LOAD->STORE order, the additional RMB > >- * provides LOAD->LOAD order, together they provide LOAD->{LOAD,STORE} > >order, > >- * aka. ACQUIRE. > > */ > > #define smp_cond_acquire(cond) do {\ > > while (!(cond)) \ > > cpu_relax();\ > >-smp_rmb(); /* ctrl + rmb := acquire */ \ > >+smp_acquire__after_ctrl_dep(); \ > > } while (0) > > > > > > I have a question about the claim that control dependence + rmb is > equivalent to an acquire memory barrier. For example, > > S1:if (a) > S2: b = 1; >smp_rmb() > S3:c = 2; > > Since c is independent of both a and b, is it possible that the cpu > may reorder to execute store statement S3 first before S1 and S2? The CPUs I know of won't do, nor should the compiler, at least assuming "a" (AKA "cond") includes READ_ONCE(). Ditto "b" and WRITE_ONCE(). Otherwise, the compiler could do quite a few "interesting" things, especially if it knows the value of "b". For example, if the compiler knows that b==1, without the volatile casts, the compiler could just throw away both S1 and S2, eliminating any ordering. This can get quite tricky -- see memory-barriers.txt for more mischief. The smp_rmb() is not needed in this example because S3 is a write, not a read. Perhaps you meant something more like this: if (READ_ONCE(a)) WRITE_ONCE(b, 1); smp_rmb(); r1 = READ_ONCE(c); This sequence would guarantee that "a" was read before "c". Thanx, Paul
Re: [RFC][PATCH 1/3] locking: Introduce smp_acquire__after_ctrl_dep
On Tue, May 24, 2016 at 11:01:21PM -0400, Waiman Long wrote: > On 05/24/2016 10:27 AM, Peter Zijlstra wrote: > >Introduce smp_acquire__after_ctrl_dep(), this construct is not > >uncommen, but the lack of this barrier is. > > > >Signed-off-by: Peter Zijlstra (Intel) > >--- > > include/linux/compiler.h | 14 ++ > > ipc/sem.c| 14 ++ > > 2 files changed, 12 insertions(+), 16 deletions(-) > > > >--- a/include/linux/compiler.h > >+++ b/include/linux/compiler.h > >@@ -305,20 +305,26 @@ static __always_inline void __write_once > > }) > > > > /** > >+ * smp_acquire__after_ctrl_dep() - Provide ACQUIRE ordering after a control > >dependency > >+ * > >+ * A control dependency provides a LOAD->STORE order, the additional RMB > >+ * provides LOAD->LOAD order, together they provide LOAD->{LOAD,STORE} > >order, > >+ * aka. ACQUIRE. > >+ */ > >+#define smp_acquire__after_ctrl_dep() smp_rmb() > >+ > >+/** > > * smp_cond_acquire() - Spin wait for cond with ACQUIRE ordering > > * @cond: boolean expression to wait for > > * > > * Equivalent to using smp_load_acquire() on the condition variable but > > employs > > * the control dependency of the wait to reduce the barrier on many > > platforms. > > * > >- * The control dependency provides a LOAD->STORE order, the additional RMB > >- * provides LOAD->LOAD order, together they provide LOAD->{LOAD,STORE} > >order, > >- * aka. ACQUIRE. > > */ > > #define smp_cond_acquire(cond) do {\ > > while (!(cond)) \ > > cpu_relax();\ > >-smp_rmb(); /* ctrl + rmb := acquire */ \ > >+smp_acquire__after_ctrl_dep(); \ > > } while (0) > > > > > > I have a question about the claim that control dependence + rmb is > equivalent to an acquire memory barrier. For example, > > S1:if (a) > S2: b = 1; >smp_rmb() > S3:c = 2; > > Since c is independent of both a and b, is it possible that the cpu > may reorder to execute store statement S3 first before S1 and S2? The CPUs I know of won't do, nor should the compiler, at least assuming "a" (AKA "cond") includes READ_ONCE(). Ditto "b" and WRITE_ONCE(). Otherwise, the compiler could do quite a few "interesting" things, especially if it knows the value of "b". For example, if the compiler knows that b==1, without the volatile casts, the compiler could just throw away both S1 and S2, eliminating any ordering. This can get quite tricky -- see memory-barriers.txt for more mischief. The smp_rmb() is not needed in this example because S3 is a write, not a read. Perhaps you meant something more like this: if (READ_ONCE(a)) WRITE_ONCE(b, 1); smp_rmb(); r1 = READ_ONCE(c); This sequence would guarantee that "a" was read before "c". Thanx, Paul
[RESEND][PATCH] drivers: of: of_reserved_mem: fixup the CMA alignment not to affect dma-coherent
From: JaewonThere was an alignment mismatch issue for CMA and it was fixed by commit 1cc8e3458b51 ("drivers: of: of_reserved_mem: fixup the alignment with CMA setup"). However the way of the commit considers not only dma-contiguous(CMA) but also dma-coherent which has no that requirement. This patch checks more to distinguish dma-contiguous(CMA) from dma-coherent. Signed-off-by: Jaewon Kim --- drivers/of/of_reserved_mem.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c index ed01c01..45b873e 100644 --- a/drivers/of/of_reserved_mem.c +++ b/drivers/of/of_reserved_mem.c @@ -127,7 +127,10 @@ static int __init __reserved_mem_alloc_size(unsigned long node, } /* Need adjust the alignment to satisfy the CMA requirement */ - if (IS_ENABLED(CONFIG_CMA) && of_flat_dt_is_compatible(node, "shared-dma-pool")) + if (IS_ENABLED(CONFIG_CMA) + && of_flat_dt_is_compatible(node, "shared-dma-pool") + && of_get_flat_dt_prop(node, "reusable", NULL) + && !of_get_flat_dt_prop(node, "no-map", NULL)) { align = max(align, (phys_addr_t)PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order)); prop = of_get_flat_dt_prop(node, "alloc-ranges", ); -- 1.9.1
[RESEND][PATCH] drivers: of: of_reserved_mem: fixup the CMA alignment not to affect dma-coherent
From: Jaewon There was an alignment mismatch issue for CMA and it was fixed by commit 1cc8e3458b51 ("drivers: of: of_reserved_mem: fixup the alignment with CMA setup"). However the way of the commit considers not only dma-contiguous(CMA) but also dma-coherent which has no that requirement. This patch checks more to distinguish dma-contiguous(CMA) from dma-coherent. Signed-off-by: Jaewon Kim --- drivers/of/of_reserved_mem.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c index ed01c01..45b873e 100644 --- a/drivers/of/of_reserved_mem.c +++ b/drivers/of/of_reserved_mem.c @@ -127,7 +127,10 @@ static int __init __reserved_mem_alloc_size(unsigned long node, } /* Need adjust the alignment to satisfy the CMA requirement */ - if (IS_ENABLED(CONFIG_CMA) && of_flat_dt_is_compatible(node, "shared-dma-pool")) + if (IS_ENABLED(CONFIG_CMA) + && of_flat_dt_is_compatible(node, "shared-dma-pool") + && of_get_flat_dt_prop(node, "reusable", NULL) + && !of_get_flat_dt_prop(node, "no-map", NULL)) { align = max(align, (phys_addr_t)PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order)); prop = of_get_flat_dt_prop(node, "alloc-ranges", ); -- 1.9.1
Re: [PATCH v2 08/12] irqchip: add J-Core AIC driver
On Fri, May 20, 2016 at 09:15:56AM +0100, Marc Zyngier wrote: > On 20/05/16 03:53, Rich Felker wrote: > > Signed-off-by: Rich Felker> > --- > > My previous post of the patch series accidentally omitted omitted > > Cc'ing of subsystem maintainers for the necessary clocksource, > > irqchip, and spi drivers. Please ack if this looks ok because I want > > to get it merged as part of the arch/sh pull request for 4.7. > > For a start, a decent commit message wouldn't hurt. Adding it. > > drivers/irqchip/Kconfig | 6 +++ > > drivers/irqchip/Makefile| 1 + > > drivers/irqchip/irq-jcore-aic.c | 95 > > + > > 3 files changed, 102 insertions(+) > > create mode 100644 drivers/irqchip/irq-jcore-aic.c > > > > diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig > > index 3e12479..3cb37d6 100644 > > --- a/drivers/irqchip/Kconfig > > +++ b/drivers/irqchip/Kconfig > > @@ -149,6 +149,12 @@ config PIC32_EVIC > > select GENERIC_IRQ_CHIP > > select IRQ_DOMAIN > > > > +config JCORE_AIC > > + bool "J-Core integrated AIC" > > + select IRQ_DOMAIN > > + help > > + Support for the J-Core integrated AIC. > > + > > config RENESAS_INTC_IRQPIN > > bool > > select IRQ_DOMAIN > > diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile > > index b03cfcb..5a1f1bf 100644 > > --- a/drivers/irqchip/Makefile > > +++ b/drivers/irqchip/Makefile > > @@ -37,6 +37,7 @@ obj-$(CONFIG_I8259) += irq-i8259.o > > obj-$(CONFIG_IMGPDC_IRQ) += irq-imgpdc.o > > obj-$(CONFIG_IRQ_MIPS_CPU) += irq-mips-cpu.o > > obj-$(CONFIG_SIRF_IRQ) += irq-sirfsoc.o > > +obj-$(CONFIG_JCORE_AIC)+= irq-jcore-aic.o > > obj-$(CONFIG_RENESAS_INTC_IRQPIN) += irq-renesas-intc-irqpin.o > > obj-$(CONFIG_RENESAS_IRQC) += irq-renesas-irqc.o > > obj-$(CONFIG_VERSATILE_FPGA_IRQ) += irq-versatile-fpga.o > > diff --git a/drivers/irqchip/irq-jcore-aic.c > > b/drivers/irqchip/irq-jcore-aic.c > > new file mode 100644 > > index 000..68178fb > > --- /dev/null > > +++ b/drivers/irqchip/irq-jcore-aic.c > > @@ -0,0 +1,95 @@ > > +/* > > + * J-Core SoC AIC driver > > + * > > + * Copyright (C) 2015-2016 Smart Energy Instruments, Inc. > > + * > > + * This file is subject to the terms and conditions of the GNU General > > Public > > + * License. See the file "COPYING" in the main directory of this archive > > + * for more details. > > + */ > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +#define AIC1_INTPRI 8 > > + > > +struct aic_data { > > + unsigned char __iomem *base; > > + u32 cpu_offset; > > + struct irq_chip chip; > > + struct irq_domain *domain; > > + struct notifier_block nb; > > +} aic_data; > > + > > +static int aic_irqdomain_map(struct irq_domain *d, unsigned int irq, > > irq_hw_number_t hwirq) > > +{ > > + struct aic_data *aic = d->host_data; > > + > > + irq_set_chip_data(irq, aic); > > + irq_set_chip_and_handler(irq, >chip, handle_simple_irq); > > + irq_set_probe(irq); > > + > > + return 0; > > +} > > + > > +static const struct irq_domain_ops aic_irqdomain_ops = { > > + .map = aic_irqdomain_map, > > + .xlate = irq_domain_xlate_onecell, > > +}; > > + > > +static void noop(struct irq_data *data) > > +{ > > +} > > + > > +static void aic1_localenable(struct aic_data *aic) > > +{ > > + unsigned cpu = smp_processor_id(); > > + pr_info("Local AIC enable on cpu %u\n", cpu); > > + writel(0x, aic->base + cpu * aic->cpu_offset + AIC1_INTPRI); > > +} > > + > > +static int aic1_cpu_notify(struct notifier_block *self, unsigned long > > action, void *hcpu) > > +{ > > + switch (action & ~CPU_TASKS_FROZEN) { > > + case CPU_STARTING: > > + aic1_localenable(container_of(self, struct aic_data, nb)); > > + break; > > + } > > And nothing happens when the CPU goes down? There is no support for bringing down CPUs (SMP support isn't even going upstream yet in this patch series, but I didn't want to gratuitously rip the SMP support out of the drivers only to add it back later). If/when that's added it will have to be determined at that point whether any action is required. > > + return NOTIFY_OK; > > +} > > + > > +int __init aic_irq_of_init(struct device_node *node, struct device_node > > *parent) > > +{ > > + struct aic_data *aic = _data; > > + > > + aic->base = of_iomap(node, 0); > > + of_property_read_u32(node, "cpu-offset", >cpu_offset); > > + > > + pr_info("Initializing J-Core AIC at %p\n", aic->base); > > + > > + if (of_device_is_compatible(node, "jcore,aic1")) { > > + /* For aic1, need to enabled zero-priority-by-default irqs */ > > + aic->nb.notifier_call = aic1_cpu_notify; > > + register_cpu_notifier(>nb); > > + aic1_localenable(aic); > > + } > > + > >
Re: [PATCH v2 08/12] irqchip: add J-Core AIC driver
On Fri, May 20, 2016 at 09:15:56AM +0100, Marc Zyngier wrote: > On 20/05/16 03:53, Rich Felker wrote: > > Signed-off-by: Rich Felker > > --- > > My previous post of the patch series accidentally omitted omitted > > Cc'ing of subsystem maintainers for the necessary clocksource, > > irqchip, and spi drivers. Please ack if this looks ok because I want > > to get it merged as part of the arch/sh pull request for 4.7. > > For a start, a decent commit message wouldn't hurt. Adding it. > > drivers/irqchip/Kconfig | 6 +++ > > drivers/irqchip/Makefile| 1 + > > drivers/irqchip/irq-jcore-aic.c | 95 > > + > > 3 files changed, 102 insertions(+) > > create mode 100644 drivers/irqchip/irq-jcore-aic.c > > > > diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig > > index 3e12479..3cb37d6 100644 > > --- a/drivers/irqchip/Kconfig > > +++ b/drivers/irqchip/Kconfig > > @@ -149,6 +149,12 @@ config PIC32_EVIC > > select GENERIC_IRQ_CHIP > > select IRQ_DOMAIN > > > > +config JCORE_AIC > > + bool "J-Core integrated AIC" > > + select IRQ_DOMAIN > > + help > > + Support for the J-Core integrated AIC. > > + > > config RENESAS_INTC_IRQPIN > > bool > > select IRQ_DOMAIN > > diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile > > index b03cfcb..5a1f1bf 100644 > > --- a/drivers/irqchip/Makefile > > +++ b/drivers/irqchip/Makefile > > @@ -37,6 +37,7 @@ obj-$(CONFIG_I8259) += irq-i8259.o > > obj-$(CONFIG_IMGPDC_IRQ) += irq-imgpdc.o > > obj-$(CONFIG_IRQ_MIPS_CPU) += irq-mips-cpu.o > > obj-$(CONFIG_SIRF_IRQ) += irq-sirfsoc.o > > +obj-$(CONFIG_JCORE_AIC)+= irq-jcore-aic.o > > obj-$(CONFIG_RENESAS_INTC_IRQPIN) += irq-renesas-intc-irqpin.o > > obj-$(CONFIG_RENESAS_IRQC) += irq-renesas-irqc.o > > obj-$(CONFIG_VERSATILE_FPGA_IRQ) += irq-versatile-fpga.o > > diff --git a/drivers/irqchip/irq-jcore-aic.c > > b/drivers/irqchip/irq-jcore-aic.c > > new file mode 100644 > > index 000..68178fb > > --- /dev/null > > +++ b/drivers/irqchip/irq-jcore-aic.c > > @@ -0,0 +1,95 @@ > > +/* > > + * J-Core SoC AIC driver > > + * > > + * Copyright (C) 2015-2016 Smart Energy Instruments, Inc. > > + * > > + * This file is subject to the terms and conditions of the GNU General > > Public > > + * License. See the file "COPYING" in the main directory of this archive > > + * for more details. > > + */ > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +#define AIC1_INTPRI 8 > > + > > +struct aic_data { > > + unsigned char __iomem *base; > > + u32 cpu_offset; > > + struct irq_chip chip; > > + struct irq_domain *domain; > > + struct notifier_block nb; > > +} aic_data; > > + > > +static int aic_irqdomain_map(struct irq_domain *d, unsigned int irq, > > irq_hw_number_t hwirq) > > +{ > > + struct aic_data *aic = d->host_data; > > + > > + irq_set_chip_data(irq, aic); > > + irq_set_chip_and_handler(irq, >chip, handle_simple_irq); > > + irq_set_probe(irq); > > + > > + return 0; > > +} > > + > > +static const struct irq_domain_ops aic_irqdomain_ops = { > > + .map = aic_irqdomain_map, > > + .xlate = irq_domain_xlate_onecell, > > +}; > > + > > +static void noop(struct irq_data *data) > > +{ > > +} > > + > > +static void aic1_localenable(struct aic_data *aic) > > +{ > > + unsigned cpu = smp_processor_id(); > > + pr_info("Local AIC enable on cpu %u\n", cpu); > > + writel(0x, aic->base + cpu * aic->cpu_offset + AIC1_INTPRI); > > +} > > + > > +static int aic1_cpu_notify(struct notifier_block *self, unsigned long > > action, void *hcpu) > > +{ > > + switch (action & ~CPU_TASKS_FROZEN) { > > + case CPU_STARTING: > > + aic1_localenable(container_of(self, struct aic_data, nb)); > > + break; > > + } > > And nothing happens when the CPU goes down? There is no support for bringing down CPUs (SMP support isn't even going upstream yet in this patch series, but I didn't want to gratuitously rip the SMP support out of the drivers only to add it back later). If/when that's added it will have to be determined at that point whether any action is required. > > + return NOTIFY_OK; > > +} > > + > > +int __init aic_irq_of_init(struct device_node *node, struct device_node > > *parent) > > +{ > > + struct aic_data *aic = _data; > > + > > + aic->base = of_iomap(node, 0); > > + of_property_read_u32(node, "cpu-offset", >cpu_offset); > > + > > + pr_info("Initializing J-Core AIC at %p\n", aic->base); > > + > > + if (of_device_is_compatible(node, "jcore,aic1")) { > > + /* For aic1, need to enabled zero-priority-by-default irqs */ > > + aic->nb.notifier_call = aic1_cpu_notify; > > + register_cpu_notifier(>nb); > > + aic1_localenable(aic); > > + } > > + > > +
[PATCH] ARM64: dts: rockchip: add thermal zone node for rk3399 SoCs
This adds thermal zone node to rk3399 dtsi, rk3399 thermal data is including the cpu and gpu sensor zone node. At the moment, remove the rk3368 thermal data from rk399 dtsi. The thermal zone node is the node containing all the required info for describing a thermal zone, including its cooling device bindings. The thermal zone node must contain, apart from its own properties, one sub-node containing trip nodes and one sub-node containing all the zone cooling maps. The following is the parameter is introduced: * polling-delay: The maximum number of milliseconds to wait between polls * polling-delay-passive: The maximum number of milliseconds to wait between polls when performing passive cooling. * trips: A sub-node which is a container of only trip point nodes required to describe the thermal zone. * cooling-maps: A sub-node which is a container of only cooling device map nodes, used to describe the relation between trips and cooling devices. * cooling-device: A phandle of a cooling device with its specifier, referring to which cooling device is used in this cooling specifier binding. In the cooling specifier, the first cell is the minimum cooling state and the second cell is the maximum cooling state used in this map. Signed-off-by: Caesar Wang--- arch/arm64/boot/dts/rockchip/rk3399.dtsi | 100 +++ 1 file changed, 100 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi index 46f325a..cc4ca2a 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi @@ -45,6 +45,7 @@ #include #include #include +#include / { compatible = "rockchip,rk3399"; @@ -389,6 +390,95 @@ status = "disabled"; }; + thermal-zones { + cpu-thermal: cpu { + polling-delay-passive = <100>; /* milliseconds */ + polling-delay = <1000>; /* milliseconds */ + + thermal-sensors = < 0>; + + trips { + cpu_alert0: cpu_alert0 { + temperature = <7>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "passive"; + }; + cpu_alert1: cpu_alert1 { + temperature = <75000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "passive"; + }; + cpu_crit: cpu_crit { + temperature = <95000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <_alert0>; + cooling-device = + <_b0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + map1 { + trip = <_alert1>; + cooling-device = + <_l0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <_b0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + gpu-thermal: gpu { + polling-delay-passive = <100>; /* milliseconds */ + polling-delay = <1000>; /* milliseconds */ + + thermal-sensors = < 1>; + + trips { + gpu_alert0: gpu_alert0 { + temperature = <75000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "passive"; + }; + gpu_crit: gpu_crit { + temperature = <95000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <_alert0>; + cooling-device = + <_b0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; +
[PATCH] ARM64: dts: rockchip: add thermal zone node for rk3399 SoCs
This adds thermal zone node to rk3399 dtsi, rk3399 thermal data is including the cpu and gpu sensor zone node. At the moment, remove the rk3368 thermal data from rk399 dtsi. The thermal zone node is the node containing all the required info for describing a thermal zone, including its cooling device bindings. The thermal zone node must contain, apart from its own properties, one sub-node containing trip nodes and one sub-node containing all the zone cooling maps. The following is the parameter is introduced: * polling-delay: The maximum number of milliseconds to wait between polls * polling-delay-passive: The maximum number of milliseconds to wait between polls when performing passive cooling. * trips: A sub-node which is a container of only trip point nodes required to describe the thermal zone. * cooling-maps: A sub-node which is a container of only cooling device map nodes, used to describe the relation between trips and cooling devices. * cooling-device: A phandle of a cooling device with its specifier, referring to which cooling device is used in this cooling specifier binding. In the cooling specifier, the first cell is the minimum cooling state and the second cell is the maximum cooling state used in this map. Signed-off-by: Caesar Wang --- arch/arm64/boot/dts/rockchip/rk3399.dtsi | 100 +++ 1 file changed, 100 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi index 46f325a..cc4ca2a 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi @@ -45,6 +45,7 @@ #include #include #include +#include / { compatible = "rockchip,rk3399"; @@ -389,6 +390,95 @@ status = "disabled"; }; + thermal-zones { + cpu-thermal: cpu { + polling-delay-passive = <100>; /* milliseconds */ + polling-delay = <1000>; /* milliseconds */ + + thermal-sensors = < 0>; + + trips { + cpu_alert0: cpu_alert0 { + temperature = <7>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "passive"; + }; + cpu_alert1: cpu_alert1 { + temperature = <75000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "passive"; + }; + cpu_crit: cpu_crit { + temperature = <95000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <_alert0>; + cooling-device = + <_b0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + map1 { + trip = <_alert1>; + cooling-device = + <_l0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <_b0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + gpu-thermal: gpu { + polling-delay-passive = <100>; /* milliseconds */ + polling-delay = <1000>; /* milliseconds */ + + thermal-sensors = < 1>; + + trips { + gpu_alert0: gpu_alert0 { + temperature = <75000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "passive"; + }; + gpu_crit: gpu_crit { + temperature = <95000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <_alert0>; + cooling-device = + <_b0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; +
RE:Custom bags
Hi, Ronta(Xiamen)Co.,LTD, is a well established company working with bags, lanyards and other textile products for many experiences. With many years in this industry, we can offer the right products as what you requested in a short time, no matter it is a big or small order. Please don't hesitate to let me know if there's any inquiry. Kind regards, Jack Xiu Sales manager Ronta(Xiamen)Co.,Ltd www.xmronta.com j...@xmronta.com Please send Unsubscribe if you don't want to receive our e-mails.
RE:Custom bags
Hi, Ronta(Xiamen)Co.,LTD, is a well established company working with bags, lanyards and other textile products for many experiences. With many years in this industry, we can offer the right products as what you requested in a short time, no matter it is a big or small order. Please don't hesitate to let me know if there's any inquiry. Kind regards, Jack Xiu Sales manager Ronta(Xiamen)Co.,Ltd www.xmronta.com j...@xmronta.com Please send Unsubscribe if you don't want to receive our e-mails.
[PATCH 03/24] staging: unisys: visorbus: modify format string to match argument
From: David BinderModifies the format string of snprintf to expect an unsigned int instead of a signed one, per the supplied argument. Signed-off-by: David Binder Signed-off-by: David Kershner --- drivers/staging/unisys/visorbus/visorbus_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/unisys/visorbus/visorbus_main.c b/drivers/staging/unisys/visorbus/visorbus_main.c index cb08ce4..c30b4b2 100644 --- a/drivers/staging/unisys/visorbus/visorbus_main.c +++ b/drivers/staging/unisys/visorbus/visorbus_main.c @@ -433,7 +433,7 @@ static ssize_t client_bus_info_show(struct device *dev, if (vdev->name) partition_name = vdev->name; shift = snprintf(pos, remain, -"Client device / client driver info for %s eartition (vbus #%d):\n", +"Client device / client driver info for %s eartition (vbus #%u):\n", partition_name, vdev->chipset_dev_no); pos += shift; remain -= shift; -- 1.9.1
[PATCH 02/24] staging: unisys: visorbus: remove unused struct
From: David BinderRemoves unused struct definition, channel_size_info, in response to findings by SonarQube. Signed-off-by: David Binder Signed-off-by: David Kershner --- drivers/staging/unisys/visorbus/visorbus_main.c | 6 -- 1 file changed, 6 deletions(-) diff --git a/drivers/staging/unisys/visorbus/visorbus_main.c b/drivers/staging/unisys/visorbus/visorbus_main.c index 8278624..cb08ce4 100644 --- a/drivers/staging/unisys/visorbus/visorbus_main.c +++ b/drivers/staging/unisys/visorbus/visorbus_main.c @@ -1257,12 +1257,6 @@ chipset_device_resume(struct visor_device *dev_info) initiate_chipset_device_pause_resume(dev_info, false); } -struct channel_size_info { - uuid_le guid; - unsigned long min_size; - unsigned long max_size; -}; - int visorbus_init(void) { -- 1.9.1
[PATCH 03/24] staging: unisys: visorbus: modify format string to match argument
From: David Binder Modifies the format string of snprintf to expect an unsigned int instead of a signed one, per the supplied argument. Signed-off-by: David Binder Signed-off-by: David Kershner --- drivers/staging/unisys/visorbus/visorbus_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/unisys/visorbus/visorbus_main.c b/drivers/staging/unisys/visorbus/visorbus_main.c index cb08ce4..c30b4b2 100644 --- a/drivers/staging/unisys/visorbus/visorbus_main.c +++ b/drivers/staging/unisys/visorbus/visorbus_main.c @@ -433,7 +433,7 @@ static ssize_t client_bus_info_show(struct device *dev, if (vdev->name) partition_name = vdev->name; shift = snprintf(pos, remain, -"Client device / client driver info for %s eartition (vbus #%d):\n", +"Client device / client driver info for %s eartition (vbus #%u):\n", partition_name, vdev->chipset_dev_no); pos += shift; remain -= shift; -- 1.9.1
[PATCH 02/24] staging: unisys: visorbus: remove unused struct
From: David Binder Removes unused struct definition, channel_size_info, in response to findings by SonarQube. Signed-off-by: David Binder Signed-off-by: David Kershner --- drivers/staging/unisys/visorbus/visorbus_main.c | 6 -- 1 file changed, 6 deletions(-) diff --git a/drivers/staging/unisys/visorbus/visorbus_main.c b/drivers/staging/unisys/visorbus/visorbus_main.c index 8278624..cb08ce4 100644 --- a/drivers/staging/unisys/visorbus/visorbus_main.c +++ b/drivers/staging/unisys/visorbus/visorbus_main.c @@ -1257,12 +1257,6 @@ chipset_device_resume(struct visor_device *dev_info) initiate_chipset_device_pause_resume(dev_info, false); } -struct channel_size_info { - uuid_le guid; - unsigned long min_size; - unsigned long max_size; -}; - int visorbus_init(void) { -- 1.9.1
Re: [PATCH 0/7] x86: uaccess hardening, easy part
On Tue, May 24, 2016 at 6:48 PM, Andy Lutomirskiwrote: > This series hardens x86's uaccess code a bit. It adds warnings for > some screwups, adds an OOPS for a major exploitable screwup, and it > improves debuggability a bit by indicating non-default fs in oopses. > > It shouldn't cause any new OOPSes except in the particularly > dangerous case where the kernel faults on a kernel address under > USER_DS, which indicates that an access_ok is missing and is likely > to be easily exploitable -- OOPSing will make it harder to exploit. > > I have some draft patches to force OOPSes on user address accesses > under KERNEL_DS (which is a big no-no), but I'd rather make those > warn instead of OOPSing, and I don't have a good implementation of > that yet. Those patches aren't part of this series. > > Andy Lutomirski (7): > x86/xen: Simplify set_aliased_prot > x86/extable: Pass error_code and an extra unsigned long to exhandlers > x86/uaccess: Give uaccess faults their own handler > x86/dumpstack: If addr_limit is non-default, display it > x86/uaccess: Warn on uaccess faults other than #PF > x86/uaccess: Don't fix up USER_DS uaccess faults to kernel addresses > x86/uaccess: OOPS or warn on a fault with KERNEL_DS and > !pagefault_disabled() > > arch/x86/include/asm/uaccess.h | 19 --- > arch/x86/kernel/cpu/mcheck/mce.c | 2 +- > arch/x86/kernel/dumpstack_32.c | 4 ++ > arch/x86/kernel/dumpstack_64.c | 5 ++ > arch/x86/kernel/kprobes/core.c | 6 +- > arch/x86/kernel/traps.c | 6 +- > arch/x86/lib/getuser.S | 12 ++-- > arch/x86/lib/putuser.S | 10 ++-- > arch/x86/mm/extable.c| 120 > ++- > arch/x86/mm/fault.c | 2 +- > arch/x86/xen/enlighten.c | 4 +- > 11 files changed, 145 insertions(+), 45 deletions(-) I'd also like to see the use of set_fs() (which has been grossly misnamed since ancient versions of Linux) significantly reduced. Many of these uses are in compat syscalls, which do: - read the user memory - convert it to the native format - call set_fs(KERNEL_DS) - pass it to the native syscall which does another user copy. By separating the core syscall code from the userspace accesses so that it only touches kernel memory, you can eliminate the set_fs() and the extra copy from the compat case. I had started work on this a while back but never finished it. I'll look at bringing it up to date. -- Brian Gerst
Re: [PATCH 0/7] x86: uaccess hardening, easy part
On Tue, May 24, 2016 at 6:48 PM, Andy Lutomirski wrote: > This series hardens x86's uaccess code a bit. It adds warnings for > some screwups, adds an OOPS for a major exploitable screwup, and it > improves debuggability a bit by indicating non-default fs in oopses. > > It shouldn't cause any new OOPSes except in the particularly > dangerous case where the kernel faults on a kernel address under > USER_DS, which indicates that an access_ok is missing and is likely > to be easily exploitable -- OOPSing will make it harder to exploit. > > I have some draft patches to force OOPSes on user address accesses > under KERNEL_DS (which is a big no-no), but I'd rather make those > warn instead of OOPSing, and I don't have a good implementation of > that yet. Those patches aren't part of this series. > > Andy Lutomirski (7): > x86/xen: Simplify set_aliased_prot > x86/extable: Pass error_code and an extra unsigned long to exhandlers > x86/uaccess: Give uaccess faults their own handler > x86/dumpstack: If addr_limit is non-default, display it > x86/uaccess: Warn on uaccess faults other than #PF > x86/uaccess: Don't fix up USER_DS uaccess faults to kernel addresses > x86/uaccess: OOPS or warn on a fault with KERNEL_DS and > !pagefault_disabled() > > arch/x86/include/asm/uaccess.h | 19 --- > arch/x86/kernel/cpu/mcheck/mce.c | 2 +- > arch/x86/kernel/dumpstack_32.c | 4 ++ > arch/x86/kernel/dumpstack_64.c | 5 ++ > arch/x86/kernel/kprobes/core.c | 6 +- > arch/x86/kernel/traps.c | 6 +- > arch/x86/lib/getuser.S | 12 ++-- > arch/x86/lib/putuser.S | 10 ++-- > arch/x86/mm/extable.c| 120 > ++- > arch/x86/mm/fault.c | 2 +- > arch/x86/xen/enlighten.c | 4 +- > 11 files changed, 145 insertions(+), 45 deletions(-) I'd also like to see the use of set_fs() (which has been grossly misnamed since ancient versions of Linux) significantly reduced. Many of these uses are in compat syscalls, which do: - read the user memory - convert it to the native format - call set_fs(KERNEL_DS) - pass it to the native syscall which does another user copy. By separating the core syscall code from the userspace accesses so that it only touches kernel memory, you can eliminate the set_fs() and the extra copy from the compat case. I had started work on this a while back but never finished it. I'll look at bringing it up to date. -- Brian Gerst
[PATCH 07/24] staging: unisys: visorinput: remove unnecessary locking
From: Tim SellLocking in the _interrupt() function is NOT necessary so long as we ensure that interrupts have been stopped whenever we need to pause or resume the device, which we now do. While a device is paused, we ensure that interrupts stay disabled, i.e. that the _interrupt() function will NOT be called, yet remember the desired state in devdata->interrupts_enabled if open() or close() are called are called while the device is paused. Then when the device is resumed, we restore the actual state of interrupts (i.e., whether _interrupt() is going to be called or not) to the desired state in devdata->interrupts_enabled. Signed-off-by: David Kershner --- drivers/staging/unisys/visorinput/visorinput.c | 57 +- 1 file changed, 47 insertions(+), 10 deletions(-) diff --git a/drivers/staging/unisys/visorinput/visorinput.c b/drivers/staging/unisys/visorinput/visorinput.c index d67cd763..f633985 100644 --- a/drivers/staging/unisys/visorinput/visorinput.c +++ b/drivers/staging/unisys/visorinput/visorinput.c @@ -66,6 +66,7 @@ struct visorinput_devdata { struct rw_semaphore lock_visor_dev; /* lock for dev */ struct input_dev *visorinput_dev; bool paused; + bool interrupts_enabled; unsigned int keycode_table_bytes; /* size of following array */ /* for keyboard devices: visorkbd_keycode[] + visorkbd_ext_keycode[] */ unsigned char keycode_table[0]; @@ -228,7 +229,21 @@ static int visorinput_open(struct input_dev *visorinput_dev) return -EINVAL; } dev_dbg(_dev->dev, "%s opened\n", __func__); + + /* +* If we're not paused, really enable interrupts. +* Regardless of whether we are paused, set a flag indicating +* interrupts should be enabled so when we resume, interrupts +* will really be enabled. +*/ + down_write(>lock_visor_dev); + devdata->interrupts_enabled = true; + if (devdata->paused) + goto out_unlock; visorbus_enable_channel_interrupts(devdata->dev); + +out_unlock: + up_write(>lock_visor_dev); return 0; } @@ -243,7 +258,22 @@ static void visorinput_close(struct input_dev *visorinput_dev) return; } dev_dbg(_dev->dev, "%s closed\n", __func__); + + /* +* If we're not paused, really disable interrupts. +* Regardless of whether we are paused, set a flag indicating +* interrupts should be disabled so when we resume we will +* not re-enable them. +*/ + + down_write(>lock_visor_dev); + devdata->interrupts_enabled = false; + if (devdata->paused) + goto out_unlock; visorbus_disable_channel_interrupts(devdata->dev); + +out_unlock: + up_write(>lock_visor_dev); } /* @@ -438,10 +468,8 @@ visorinput_remove(struct visor_device *dev) * in visorinput_channel_interrupt() */ - down_write(>lock_visor_dev); dev_set_drvdata(>device, NULL); unregister_client_input(devdata->visorinput_dev); - up_write(>lock_visor_dev); kfree(devdata); } @@ -529,13 +557,7 @@ visorinput_channel_interrupt(struct visor_device *dev) if (!devdata) return; - down_write(>lock_visor_dev); - if (devdata->paused) /* don't touch device/channel when paused */ - goto out_locked; - visorinput_dev = devdata->visorinput_dev; - if (!visorinput_dev) - goto out_locked; while (visorchannel_signalremove(dev->visorchannel, 0, )) { scancode = r.activity.arg1; @@ -611,8 +633,6 @@ visorinput_channel_interrupt(struct visor_device *dev) break; } } -out_locked: - up_write(>lock_visor_dev); } static int @@ -632,6 +652,14 @@ visorinput_pause(struct visor_device *dev, rc = -EBUSY; goto out_locked; } + if (devdata->interrupts_enabled) + visorbus_disable_channel_interrupts(dev); + + /* +* due to above, at this time no thread of execution will be +* in visorinput_channel_interrupt() +*/ + devdata->paused = true; complete_func(dev, 0); rc = 0; @@ -659,6 +687,15 @@ visorinput_resume(struct visor_device *dev, } devdata->paused = false; complete_func(dev, 0); + + /* +* Re-establish calls to visorinput_channel_interrupt() if that is +* the desired state that we've kept track of in interrupts_enabled +* while the device was paused. +*/ + if (devdata->interrupts_enabled) + visorbus_enable_channel_interrupts(dev); + rc = 0; out_locked: up_write(>lock_visor_dev); -- 1.9.1
[PATCH 23/24] Documentation: Move visorbus documentation from staging to Documentation/
This patch simple does a git mv of the drivers/staging/unisys/Documentation directory to Documentation. Renames overview.txt to visorbus.txt and renames sysfs-platform-visorchipset to the correct name sysfs-bus-visorbus. Signed-off-by: David Kershner--- .../ABI/stable/sysfs-bus-visorbus | 0 .../unisys/Documentation/overview.txt => Documentation/visorbus.txt | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename drivers/staging/unisys/Documentation/ABI/sysfs-platform-visorchipset => Documentation/ABI/stable/sysfs-bus-visorbus (100%) rename drivers/staging/unisys/Documentation/overview.txt => Documentation/visorbus.txt (100%) diff --git a/drivers/staging/unisys/Documentation/ABI/sysfs-platform-visorchipset b/Documentation/ABI/stable/sysfs-bus-visorbus similarity index 100% rename from drivers/staging/unisys/Documentation/ABI/sysfs-platform-visorchipset rename to Documentation/ABI/stable/sysfs-bus-visorbus diff --git a/drivers/staging/unisys/Documentation/overview.txt b/Documentation/visorbus.txt similarity index 100% rename from drivers/staging/unisys/Documentation/overview.txt rename to Documentation/visorbus.txt -- 1.9.1
[PATCH 07/24] staging: unisys: visorinput: remove unnecessary locking
From: Tim Sell Locking in the _interrupt() function is NOT necessary so long as we ensure that interrupts have been stopped whenever we need to pause or resume the device, which we now do. While a device is paused, we ensure that interrupts stay disabled, i.e. that the _interrupt() function will NOT be called, yet remember the desired state in devdata->interrupts_enabled if open() or close() are called are called while the device is paused. Then when the device is resumed, we restore the actual state of interrupts (i.e., whether _interrupt() is going to be called or not) to the desired state in devdata->interrupts_enabled. Signed-off-by: David Kershner --- drivers/staging/unisys/visorinput/visorinput.c | 57 +- 1 file changed, 47 insertions(+), 10 deletions(-) diff --git a/drivers/staging/unisys/visorinput/visorinput.c b/drivers/staging/unisys/visorinput/visorinput.c index d67cd763..f633985 100644 --- a/drivers/staging/unisys/visorinput/visorinput.c +++ b/drivers/staging/unisys/visorinput/visorinput.c @@ -66,6 +66,7 @@ struct visorinput_devdata { struct rw_semaphore lock_visor_dev; /* lock for dev */ struct input_dev *visorinput_dev; bool paused; + bool interrupts_enabled; unsigned int keycode_table_bytes; /* size of following array */ /* for keyboard devices: visorkbd_keycode[] + visorkbd_ext_keycode[] */ unsigned char keycode_table[0]; @@ -228,7 +229,21 @@ static int visorinput_open(struct input_dev *visorinput_dev) return -EINVAL; } dev_dbg(_dev->dev, "%s opened\n", __func__); + + /* +* If we're not paused, really enable interrupts. +* Regardless of whether we are paused, set a flag indicating +* interrupts should be enabled so when we resume, interrupts +* will really be enabled. +*/ + down_write(>lock_visor_dev); + devdata->interrupts_enabled = true; + if (devdata->paused) + goto out_unlock; visorbus_enable_channel_interrupts(devdata->dev); + +out_unlock: + up_write(>lock_visor_dev); return 0; } @@ -243,7 +258,22 @@ static void visorinput_close(struct input_dev *visorinput_dev) return; } dev_dbg(_dev->dev, "%s closed\n", __func__); + + /* +* If we're not paused, really disable interrupts. +* Regardless of whether we are paused, set a flag indicating +* interrupts should be disabled so when we resume we will +* not re-enable them. +*/ + + down_write(>lock_visor_dev); + devdata->interrupts_enabled = false; + if (devdata->paused) + goto out_unlock; visorbus_disable_channel_interrupts(devdata->dev); + +out_unlock: + up_write(>lock_visor_dev); } /* @@ -438,10 +468,8 @@ visorinput_remove(struct visor_device *dev) * in visorinput_channel_interrupt() */ - down_write(>lock_visor_dev); dev_set_drvdata(>device, NULL); unregister_client_input(devdata->visorinput_dev); - up_write(>lock_visor_dev); kfree(devdata); } @@ -529,13 +557,7 @@ visorinput_channel_interrupt(struct visor_device *dev) if (!devdata) return; - down_write(>lock_visor_dev); - if (devdata->paused) /* don't touch device/channel when paused */ - goto out_locked; - visorinput_dev = devdata->visorinput_dev; - if (!visorinput_dev) - goto out_locked; while (visorchannel_signalremove(dev->visorchannel, 0, )) { scancode = r.activity.arg1; @@ -611,8 +633,6 @@ visorinput_channel_interrupt(struct visor_device *dev) break; } } -out_locked: - up_write(>lock_visor_dev); } static int @@ -632,6 +652,14 @@ visorinput_pause(struct visor_device *dev, rc = -EBUSY; goto out_locked; } + if (devdata->interrupts_enabled) + visorbus_disable_channel_interrupts(dev); + + /* +* due to above, at this time no thread of execution will be +* in visorinput_channel_interrupt() +*/ + devdata->paused = true; complete_func(dev, 0); rc = 0; @@ -659,6 +687,15 @@ visorinput_resume(struct visor_device *dev, } devdata->paused = false; complete_func(dev, 0); + + /* +* Re-establish calls to visorinput_channel_interrupt() if that is +* the desired state that we've kept track of in interrupts_enabled +* while the device was paused. +*/ + if (devdata->interrupts_enabled) + visorbus_enable_channel_interrupts(dev); + rc = 0; out_locked: up_write(>lock_visor_dev); -- 1.9.1
[PATCH 23/24] Documentation: Move visorbus documentation from staging to Documentation/
This patch simple does a git mv of the drivers/staging/unisys/Documentation directory to Documentation. Renames overview.txt to visorbus.txt and renames sysfs-platform-visorchipset to the correct name sysfs-bus-visorbus. Signed-off-by: David Kershner --- .../ABI/stable/sysfs-bus-visorbus | 0 .../unisys/Documentation/overview.txt => Documentation/visorbus.txt | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename drivers/staging/unisys/Documentation/ABI/sysfs-platform-visorchipset => Documentation/ABI/stable/sysfs-bus-visorbus (100%) rename drivers/staging/unisys/Documentation/overview.txt => Documentation/visorbus.txt (100%) diff --git a/drivers/staging/unisys/Documentation/ABI/sysfs-platform-visorchipset b/Documentation/ABI/stable/sysfs-bus-visorbus similarity index 100% rename from drivers/staging/unisys/Documentation/ABI/sysfs-platform-visorchipset rename to Documentation/ABI/stable/sysfs-bus-visorbus diff --git a/drivers/staging/unisys/Documentation/overview.txt b/Documentation/visorbus.txt similarity index 100% rename from drivers/staging/unisys/Documentation/overview.txt rename to Documentation/visorbus.txt -- 1.9.1
[PATCH 00/24] Fixes comments made by tglx, then move visorbus to drivers/virt
tglx: The following patchset fixes issues you raised during your code review of visorbus on 5/18. Greg: I understand that you aren't currently accepting new patces for staging-next, I just wanted to get the following patches out for review. This patchset requires additiional patches that have been sent prior to staging-next. They will not apply directly to staging-next without the previous patches being applied. Converts visorbus to use a kernel timer for periodic device-specific callbacks instead of a workqueue, making the implementation in periodic_work.c and periodic_work.h no longer necessary. These files are then deleted. The visordriver_callback_lock has been switched to a mutex. Several module parameters and structures were removed that were no longer being used. Bryan Thompson (4): staging: unisys: visorbus: Make visordriver_callback_lock a mutex staging: unisys: visorbus: Remove unnecessary EXPORT_SYMBOL statements staging: unisys: visorbus: Remove unused functions staging: unisys: Remove reference to unused STANDALONE_CLIENT David Binder (12): staging: unisys: visorbus: remove unused module parameters staging: unisys: visorbus: remove unused struct staging: unisys: visorbus: modify format string to match argument staging: unisys: visornic: Correct comment spelling mistake staging: unisys: include: Remove thread-related enum members staging: unisys: visorbus: vbusdeviceinfo function descriptions more kerneldoc-like staging: unisys: visorbus: make function descriptions more kerneldoc-like staging: unisys: visorbus: make visorbus_private.h function descriptions more kerneldoc-like staging: unisys: visorbus: make visorchannel function descriptions more kerneldoc-like staging: unisys: visorbus: make visorchipset function descriptions more kerneldoc-like staging: unisys: visorbus: Move visorbus-unique functions to private header staging: unisys: visorbus: Add kerneldoc-style comments for visorbus API David Kershner (4): staging: unisys: Move vbushelper.h to visorbus directory include: linux: visorbus: Add visorbus to include/linux directory Documentation: Move visorbus documentation from staging to Documentation/ drivers: Add visorbus to the drivers directory Tim Sell (4): staging: unisys: visorbus: removed unused periodic_test_workqueue staging: unisys: visorinput: remove unnecessary locking staging: unisys: visorbus: use kernel timer instead of workqueue staging: unisys: visorbus: remove periodic_work.h/.c .../ABI/stable/sysfs-bus-visorbus |0 .../overview.txt => Documentation/visorbus.txt |0 drivers/staging/unisys/Kconfig |3 +- drivers/staging/unisys/MAINTAINERS |2 +- drivers/staging/unisys/Makefile|1 - drivers/staging/unisys/include/periodic_work.h | 40 - drivers/staging/unisys/include/visorbus.h | 234 drivers/staging/unisys/visorbus/Makefile | 12 - drivers/staging/unisys/visorbus/periodic_work.c| 204 --- drivers/staging/unisys/visorbus/visorbus_main.c| 1344 drivers/staging/unisys/visorbus/visorbus_private.h | 68 - drivers/staging/unisys/visorbus/visorchannel.c | 635 - drivers/staging/unisys/visorhba/Makefile |2 - drivers/staging/unisys/visorhba/visorhba_main.c|5 +- drivers/staging/unisys/visorinput/Makefile |2 - drivers/staging/unisys/visorinput/visorinput.c | 63 +- drivers/staging/unisys/visornic/Makefile |2 - drivers/staging/unisys/visornic/visornic_main.c|7 +- drivers/virt/Kconfig |2 + drivers/virt/Makefile |1 + drivers/{staging/unisys => virt}/visorbus/Kconfig |0 drivers/virt/visorbus/Makefile |9 + .../unisys => virt}/visorbus/controlvmchannel.h|2 +- .../visorbus/controlvmcompletionstatus.h |0 .../unisys => virt}/visorbus/iovmcall_gnuc.h |0 .../unisys => virt}/visorbus/vbuschannel.h |3 +- .../unisys => virt}/visorbus/vbusdeviceinfo.h | 11 +- .../unisys/include => virt/visorbus}/vbushelper.h |0 drivers/virt/visorbus/visorbus_main.c | 1260 ++ drivers/virt/visorbus/visorbus_private.h | 96 ++ drivers/virt/visorbus/visorchannel.c | 459 +++ .../unisys => virt}/visorbus/visorchipset.c| 52 +- .../unisys => virt}/visorbus/vmcallinterface.h |5 +- .../include => include/linux/visorbus}/channel.h |0 .../linux/visorbus}/channel_guid.h |0 .../linux/visorbus}/diagchannel.h |0 .../linux/visorbus}/guestlinuxdebug.h |4 +- .../include => include/linux/visorbus}/iochannel.h |0 .../include => include/linux/visorbus}/version.h |0
[PATCH 01/24] staging: unisys: visorbus: remove unused module parameters
From: David BinderRemoves unused module parameters from visorbus_main.c, in response to findings by SonarQube. Signed-off-by: David Binder Signed-off-by: David Kershner --- drivers/staging/unisys/visorbus/visorbus_main.c | 9 + 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/staging/unisys/visorbus/visorbus_main.c b/drivers/staging/unisys/visorbus/visorbus_main.c index d32b898..8278624 100644 --- a/drivers/staging/unisys/visorbus/visorbus_main.c +++ b/drivers/staging/unisys/visorbus/visorbus_main.c @@ -27,10 +27,9 @@ #define MYDRVNAME "visorbus" /* module parameters */ -static int visorbus_debug; static int visorbus_forcematch; static int visorbus_forcenomatch; -static int visorbus_debugref; + #define SERIALLOOPBACKCHANADDR (100 * 1024 * 1024) /* Display string that is guaranteed to be no longer the 99 characters*/ @@ -1329,9 +1328,6 @@ visorbus_exit(void) remove_bus_type(); } -module_param_named(debug, visorbus_debug, int, S_IRUGO); -MODULE_PARM_DESC(visorbus_debug, "1 to debug"); - module_param_named(forcematch, visorbus_forcematch, int, S_IRUGO); MODULE_PARM_DESC(visorbus_forcematch, "1 to force a successful dev <--> drv match"); @@ -1339,6 +1335,3 @@ MODULE_PARM_DESC(visorbus_forcematch, module_param_named(forcenomatch, visorbus_forcenomatch, int, S_IRUGO); MODULE_PARM_DESC(visorbus_forcenomatch, "1 to force an UNsuccessful dev <--> drv match"); - -module_param_named(debugref, visorbus_debugref, int, S_IRUGO); -MODULE_PARM_DESC(visorbus_debugref, "1 to debug reference counting"); -- 1.9.1
[PATCH 00/24] Fixes comments made by tglx, then move visorbus to drivers/virt
tglx: The following patchset fixes issues you raised during your code review of visorbus on 5/18. Greg: I understand that you aren't currently accepting new patces for staging-next, I just wanted to get the following patches out for review. This patchset requires additiional patches that have been sent prior to staging-next. They will not apply directly to staging-next without the previous patches being applied. Converts visorbus to use a kernel timer for periodic device-specific callbacks instead of a workqueue, making the implementation in periodic_work.c and periodic_work.h no longer necessary. These files are then deleted. The visordriver_callback_lock has been switched to a mutex. Several module parameters and structures were removed that were no longer being used. Bryan Thompson (4): staging: unisys: visorbus: Make visordriver_callback_lock a mutex staging: unisys: visorbus: Remove unnecessary EXPORT_SYMBOL statements staging: unisys: visorbus: Remove unused functions staging: unisys: Remove reference to unused STANDALONE_CLIENT David Binder (12): staging: unisys: visorbus: remove unused module parameters staging: unisys: visorbus: remove unused struct staging: unisys: visorbus: modify format string to match argument staging: unisys: visornic: Correct comment spelling mistake staging: unisys: include: Remove thread-related enum members staging: unisys: visorbus: vbusdeviceinfo function descriptions more kerneldoc-like staging: unisys: visorbus: make function descriptions more kerneldoc-like staging: unisys: visorbus: make visorbus_private.h function descriptions more kerneldoc-like staging: unisys: visorbus: make visorchannel function descriptions more kerneldoc-like staging: unisys: visorbus: make visorchipset function descriptions more kerneldoc-like staging: unisys: visorbus: Move visorbus-unique functions to private header staging: unisys: visorbus: Add kerneldoc-style comments for visorbus API David Kershner (4): staging: unisys: Move vbushelper.h to visorbus directory include: linux: visorbus: Add visorbus to include/linux directory Documentation: Move visorbus documentation from staging to Documentation/ drivers: Add visorbus to the drivers directory Tim Sell (4): staging: unisys: visorbus: removed unused periodic_test_workqueue staging: unisys: visorinput: remove unnecessary locking staging: unisys: visorbus: use kernel timer instead of workqueue staging: unisys: visorbus: remove periodic_work.h/.c .../ABI/stable/sysfs-bus-visorbus |0 .../overview.txt => Documentation/visorbus.txt |0 drivers/staging/unisys/Kconfig |3 +- drivers/staging/unisys/MAINTAINERS |2 +- drivers/staging/unisys/Makefile|1 - drivers/staging/unisys/include/periodic_work.h | 40 - drivers/staging/unisys/include/visorbus.h | 234 drivers/staging/unisys/visorbus/Makefile | 12 - drivers/staging/unisys/visorbus/periodic_work.c| 204 --- drivers/staging/unisys/visorbus/visorbus_main.c| 1344 drivers/staging/unisys/visorbus/visorbus_private.h | 68 - drivers/staging/unisys/visorbus/visorchannel.c | 635 - drivers/staging/unisys/visorhba/Makefile |2 - drivers/staging/unisys/visorhba/visorhba_main.c|5 +- drivers/staging/unisys/visorinput/Makefile |2 - drivers/staging/unisys/visorinput/visorinput.c | 63 +- drivers/staging/unisys/visornic/Makefile |2 - drivers/staging/unisys/visornic/visornic_main.c|7 +- drivers/virt/Kconfig |2 + drivers/virt/Makefile |1 + drivers/{staging/unisys => virt}/visorbus/Kconfig |0 drivers/virt/visorbus/Makefile |9 + .../unisys => virt}/visorbus/controlvmchannel.h|2 +- .../visorbus/controlvmcompletionstatus.h |0 .../unisys => virt}/visorbus/iovmcall_gnuc.h |0 .../unisys => virt}/visorbus/vbuschannel.h |3 +- .../unisys => virt}/visorbus/vbusdeviceinfo.h | 11 +- .../unisys/include => virt/visorbus}/vbushelper.h |0 drivers/virt/visorbus/visorbus_main.c | 1260 ++ drivers/virt/visorbus/visorbus_private.h | 96 ++ drivers/virt/visorbus/visorchannel.c | 459 +++ .../unisys => virt}/visorbus/visorchipset.c| 52 +- .../unisys => virt}/visorbus/vmcallinterface.h |5 +- .../include => include/linux/visorbus}/channel.h |0 .../linux/visorbus}/channel_guid.h |0 .../linux/visorbus}/diagchannel.h |0 .../linux/visorbus}/guestlinuxdebug.h |4 +- .../include => include/linux/visorbus}/iochannel.h |0 .../include => include/linux/visorbus}/version.h |0
[PATCH 01/24] staging: unisys: visorbus: remove unused module parameters
From: David Binder Removes unused module parameters from visorbus_main.c, in response to findings by SonarQube. Signed-off-by: David Binder Signed-off-by: David Kershner --- drivers/staging/unisys/visorbus/visorbus_main.c | 9 + 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/staging/unisys/visorbus/visorbus_main.c b/drivers/staging/unisys/visorbus/visorbus_main.c index d32b898..8278624 100644 --- a/drivers/staging/unisys/visorbus/visorbus_main.c +++ b/drivers/staging/unisys/visorbus/visorbus_main.c @@ -27,10 +27,9 @@ #define MYDRVNAME "visorbus" /* module parameters */ -static int visorbus_debug; static int visorbus_forcematch; static int visorbus_forcenomatch; -static int visorbus_debugref; + #define SERIALLOOPBACKCHANADDR (100 * 1024 * 1024) /* Display string that is guaranteed to be no longer the 99 characters*/ @@ -1329,9 +1328,6 @@ visorbus_exit(void) remove_bus_type(); } -module_param_named(debug, visorbus_debug, int, S_IRUGO); -MODULE_PARM_DESC(visorbus_debug, "1 to debug"); - module_param_named(forcematch, visorbus_forcematch, int, S_IRUGO); MODULE_PARM_DESC(visorbus_forcematch, "1 to force a successful dev <--> drv match"); @@ -1339,6 +1335,3 @@ MODULE_PARM_DESC(visorbus_forcematch, module_param_named(forcenomatch, visorbus_forcenomatch, int, S_IRUGO); MODULE_PARM_DESC(visorbus_forcenomatch, "1 to force an UNsuccessful dev <--> drv match"); - -module_param_named(debugref, visorbus_debugref, int, S_IRUGO); -MODULE_PARM_DESC(visorbus_debugref, "1 to debug reference counting"); -- 1.9.1
RE: [PATCH v8 08/14] usb: otg: add OTG/dual-role core
> -Original Message- > From: Peter Chen [mailto:hzpeterc...@gmail.com] > Sent: Wednesday, May 25, 2016 10:44 AM > To: Roger Quadros> Cc: peter.c...@freescale.com; ba...@kernel.org; t...@atomide.com; > gre...@linuxfoundation.org; dan.j.willi...@intel.com; > mathias.ny...@linux.intel.com; joao.pi...@synopsys.com; > sergei.shtyl...@cogentembedded.com; jun...@freescale.com; > grygorii.stras...@ti.com; yoshihiro.shimoda...@renesas.com; > r...@kernel.org; nsek...@ti.com; b-...@ti.com; linux-...@vger.kernel.org; > linux-o...@vger.kernel.org; linux-kernel@vger.kernel.org; > devicet...@vger.kernel.org > Subject: Re: [PATCH v8 08/14] usb: otg: add OTG/dual-role core > > On Tue, May 24, 2016 at 12:45:46PM +0300, Roger Quadros wrote: > > Hi Peter, > > > > I have one question here. Please see below. > > > > On 13/05/16 13:03, Roger Quadros wrote: > > > It provides APIs for the following tasks > > > > > > - Registering an OTG/dual-role capable controller > > > - Registering Host and Gadget controllers to OTG core > > > - Providing inputs to and kicking the OTG state machine > > > > > > Provide a dual-role device (DRD) state machine. > > > DRD mode is a reduced functionality OTG mode. In this mode we don't > > > support SRP, HNP and dynamic role-swap. > > > > > > In DRD operation, the controller mode (Host or Peripheral) is > > > decided based on the ID pin status. Once a cable plug (Type-A or > > > Type-B) is attached the controller selects the state and doesn't > > > change till the cable in unplugged and a different cable type is > > > inserted. > > > > > > As we don't need most of the complex OTG states and OTG timers we > > > implement a lean DRD state machine in usb-otg.c. > > > The DRD state machine is only interested in 2 hardware inputs 'id' > > > and 'b_sess_vld'. > > > > > > Signed-off-by: Roger Quadros > > > --- > > > drivers/usb/common/Makefile |2 +- > > > drivers/usb/common/usb-otg.c | 1042 > ++ > > > drivers/usb/core/Kconfig |4 +- > > > include/linux/usb/gadget.h |2 + > > > include/linux/usb/hcd.h |1 + > > > include/linux/usb/otg-fsm.h |7 + > > > include/linux/usb/otg.h | 154 ++- > > > 7 files changed, 1206 insertions(+), 6 deletions(-) create mode > > > 100644 drivers/usb/common/usb-otg.c > > > > > > > > > > > > + > > > +/** > > > + * usb_otg_register() - Register the OTG/dual-role device to OTG > > > +core > > > + * @dev: OTG/dual-role controller device. > > > + * @config: OTG configuration. > > > + * > > > + * Registers the OTG/dual-role controller device with the USB OTG > core. > > > + * > > > + * Return: struct usb_otg * if success, ERR_PTR() if error. > > > + */ > > > +struct usb_otg *usb_otg_register(struct device *dev, > > > + struct usb_otg_config *config) { > > > + struct usb_otg *otg; > > > + struct otg_wait_data *wait; > > > + int ret = 0; > > > + > > > + if (!dev || !config || !config->fsm_ops) > > > + return ERR_PTR(-EINVAL); > > > + > > > + /* already in list? */ > > > + mutex_lock(_list_mutex); > > > + if (usb_otg_get_data(dev)) { > > > + dev_err(dev, "otg: %s: device already in otg list\n", > > > + __func__); > > > + ret = -EINVAL; > > > + goto unlock; > > > + } > > > + > > > + /* allocate and add to list */ > > > + otg = kzalloc(sizeof(*otg), GFP_KERNEL); > > > + if (!otg) { > > > + ret = -ENOMEM; > > > + goto unlock; > > > + } > > > + > > > + otg->dev = dev; > > > + otg->caps = config->otg_caps; > > > > Here, we should be checking if user needs to disable any OTG features. > > So, > > > > if (dev->of_node) > > of_usb_update_otg_caps(dev->of_node, >caps); > > > > Do you agree? > > This means we need to change otg->caps from 'struct usb_otg_caps *caps;' > > to 'struct usb_otg_caps caps;' so that we can modify the local copy > > instead of the one passed by the OTG controller. > > Why can't modify the one from OTG controller directly? Yes, if user wants to disable any OTG features, this should have been done in 'config->otg_caps', if not, 'config->otg_caps' from controller driver is invalid and making no sense. > > > > > We can also move of_usb_update_otg_caps() to otg.h. > > > > We will also need to modify the udc-core code so that it sets > > gadget->otg_caps to the modified otg_caps from the OTG core. This will > > ensure that the right OTG descriptors are sent. > > > > So we will have to introduce an API. > > > > struct usb_otg_caps *usb_otg_get_otg_caps(struct device *otg_dev) > > > > And in udc-core.c, > > > > static int udc_bind_to_driver(struct usb_udc *udc, struct > > usb_gadget_driver *driver) { .. > > ret = driver->bind(udc->gadget, driver); > > if (ret) > > goto err1; > > > > /* If OTG, the otg core starts the UDC when needed */ > > if (udc->gadget->otg_dev) { > > +
[PATCH 05/24] staging: unisys: include: Remove thread-related enum members
From: David BinderCode relating to ktheads was previously removed from s-Par driver code. This patch cleans up lingering remnants of kthreads by removing thread- related enum types. Signed-off-by: David Binder Signed-off-by: David Kershner --- drivers/staging/unisys/include/guestlinuxdebug.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/unisys/include/guestlinuxdebug.h b/drivers/staging/unisys/include/guestlinuxdebug.h index b81287f..5af3f77 100644 --- a/drivers/staging/unisys/include/guestlinuxdebug.h +++ b/drivers/staging/unisys/include/guestlinuxdebug.h @@ -56,7 +56,7 @@ enum driver_pc { /* POSTCODE driver identifier tuples */ UISLIB_PC = 0xD0, UISLIB_PC_uislib_c = 0xD1, UISLIB_PC_uisqueue_c = 0xD2, - UISLIB_PC_uisthread_c = 0xD3, + /* 0xD3 RESERVED */ UISLIB_PC_uisutils_c = 0xD4, }; @@ -91,7 +91,7 @@ enum event_pc { /* POSTCODE event identifier tuples */ DRIVER_EXIT_PC = 0x0AC, MALLOC_FAILURE_PC = 0x0AD, QUEUE_DELAYED_WORK_PC = 0x0AE, - UISLIB_THREAD_FAILURE_PC = 0x0B7, + /* 0x0B7 RESERVED */ VBUS_CHANNEL_ENTRY_PC = 0x0B8, VBUS_CHANNEL_FAILURE_PC = 0x0B9, VBUS_CHANNEL_EXIT_PC = 0x0BA, -- 1.9.1
RE: [PATCH v8 08/14] usb: otg: add OTG/dual-role core
> -Original Message- > From: Peter Chen [mailto:hzpeterc...@gmail.com] > Sent: Wednesday, May 25, 2016 10:44 AM > To: Roger Quadros > Cc: peter.c...@freescale.com; ba...@kernel.org; t...@atomide.com; > gre...@linuxfoundation.org; dan.j.willi...@intel.com; > mathias.ny...@linux.intel.com; joao.pi...@synopsys.com; > sergei.shtyl...@cogentembedded.com; jun...@freescale.com; > grygorii.stras...@ti.com; yoshihiro.shimoda...@renesas.com; > r...@kernel.org; nsek...@ti.com; b-...@ti.com; linux-...@vger.kernel.org; > linux-o...@vger.kernel.org; linux-kernel@vger.kernel.org; > devicet...@vger.kernel.org > Subject: Re: [PATCH v8 08/14] usb: otg: add OTG/dual-role core > > On Tue, May 24, 2016 at 12:45:46PM +0300, Roger Quadros wrote: > > Hi Peter, > > > > I have one question here. Please see below. > > > > On 13/05/16 13:03, Roger Quadros wrote: > > > It provides APIs for the following tasks > > > > > > - Registering an OTG/dual-role capable controller > > > - Registering Host and Gadget controllers to OTG core > > > - Providing inputs to and kicking the OTG state machine > > > > > > Provide a dual-role device (DRD) state machine. > > > DRD mode is a reduced functionality OTG mode. In this mode we don't > > > support SRP, HNP and dynamic role-swap. > > > > > > In DRD operation, the controller mode (Host or Peripheral) is > > > decided based on the ID pin status. Once a cable plug (Type-A or > > > Type-B) is attached the controller selects the state and doesn't > > > change till the cable in unplugged and a different cable type is > > > inserted. > > > > > > As we don't need most of the complex OTG states and OTG timers we > > > implement a lean DRD state machine in usb-otg.c. > > > The DRD state machine is only interested in 2 hardware inputs 'id' > > > and 'b_sess_vld'. > > > > > > Signed-off-by: Roger Quadros > > > --- > > > drivers/usb/common/Makefile |2 +- > > > drivers/usb/common/usb-otg.c | 1042 > ++ > > > drivers/usb/core/Kconfig |4 +- > > > include/linux/usb/gadget.h |2 + > > > include/linux/usb/hcd.h |1 + > > > include/linux/usb/otg-fsm.h |7 + > > > include/linux/usb/otg.h | 154 ++- > > > 7 files changed, 1206 insertions(+), 6 deletions(-) create mode > > > 100644 drivers/usb/common/usb-otg.c > > > > > > > > > > > > + > > > +/** > > > + * usb_otg_register() - Register the OTG/dual-role device to OTG > > > +core > > > + * @dev: OTG/dual-role controller device. > > > + * @config: OTG configuration. > > > + * > > > + * Registers the OTG/dual-role controller device with the USB OTG > core. > > > + * > > > + * Return: struct usb_otg * if success, ERR_PTR() if error. > > > + */ > > > +struct usb_otg *usb_otg_register(struct device *dev, > > > + struct usb_otg_config *config) { > > > + struct usb_otg *otg; > > > + struct otg_wait_data *wait; > > > + int ret = 0; > > > + > > > + if (!dev || !config || !config->fsm_ops) > > > + return ERR_PTR(-EINVAL); > > > + > > > + /* already in list? */ > > > + mutex_lock(_list_mutex); > > > + if (usb_otg_get_data(dev)) { > > > + dev_err(dev, "otg: %s: device already in otg list\n", > > > + __func__); > > > + ret = -EINVAL; > > > + goto unlock; > > > + } > > > + > > > + /* allocate and add to list */ > > > + otg = kzalloc(sizeof(*otg), GFP_KERNEL); > > > + if (!otg) { > > > + ret = -ENOMEM; > > > + goto unlock; > > > + } > > > + > > > + otg->dev = dev; > > > + otg->caps = config->otg_caps; > > > > Here, we should be checking if user needs to disable any OTG features. > > So, > > > > if (dev->of_node) > > of_usb_update_otg_caps(dev->of_node, >caps); > > > > Do you agree? > > This means we need to change otg->caps from 'struct usb_otg_caps *caps;' > > to 'struct usb_otg_caps caps;' so that we can modify the local copy > > instead of the one passed by the OTG controller. > > Why can't modify the one from OTG controller directly? Yes, if user wants to disable any OTG features, this should have been done in 'config->otg_caps', if not, 'config->otg_caps' from controller driver is invalid and making no sense. > > > > > We can also move of_usb_update_otg_caps() to otg.h. > > > > We will also need to modify the udc-core code so that it sets > > gadget->otg_caps to the modified otg_caps from the OTG core. This will > > ensure that the right OTG descriptors are sent. > > > > So we will have to introduce an API. > > > > struct usb_otg_caps *usb_otg_get_otg_caps(struct device *otg_dev) > > > > And in udc-core.c, > > > > static int udc_bind_to_driver(struct usb_udc *udc, struct > > usb_gadget_driver *driver) { .. > > ret = driver->bind(udc->gadget, driver); > > if (ret) > > goto err1; > > > > /* If OTG, the otg core starts the UDC when needed */ > > if (udc->gadget->otg_dev) { > > + udc->gadget->is_otg = true; > >
[PATCH 05/24] staging: unisys: include: Remove thread-related enum members
From: David Binder Code relating to ktheads was previously removed from s-Par driver code. This patch cleans up lingering remnants of kthreads by removing thread- related enum types. Signed-off-by: David Binder Signed-off-by: David Kershner --- drivers/staging/unisys/include/guestlinuxdebug.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/unisys/include/guestlinuxdebug.h b/drivers/staging/unisys/include/guestlinuxdebug.h index b81287f..5af3f77 100644 --- a/drivers/staging/unisys/include/guestlinuxdebug.h +++ b/drivers/staging/unisys/include/guestlinuxdebug.h @@ -56,7 +56,7 @@ enum driver_pc { /* POSTCODE driver identifier tuples */ UISLIB_PC = 0xD0, UISLIB_PC_uislib_c = 0xD1, UISLIB_PC_uisqueue_c = 0xD2, - UISLIB_PC_uisthread_c = 0xD3, + /* 0xD3 RESERVED */ UISLIB_PC_uisutils_c = 0xD4, }; @@ -91,7 +91,7 @@ enum event_pc { /* POSTCODE event identifier tuples */ DRIVER_EXIT_PC = 0x0AC, MALLOC_FAILURE_PC = 0x0AD, QUEUE_DELAYED_WORK_PC = 0x0AE, - UISLIB_THREAD_FAILURE_PC = 0x0B7, + /* 0x0B7 RESERVED */ VBUS_CHANNEL_ENTRY_PC = 0x0B8, VBUS_CHANNEL_FAILURE_PC = 0x0B9, VBUS_CHANNEL_EXIT_PC = 0x0BA, -- 1.9.1