Re: [RESEND PATCH v3 2/2] usb: dwc3: Add driver for Xilinx platforms
Hi Manish! On Tue, Dec 15, 2020 at 12:24:51PM +0530, Manish Narani wrote: Add a new driver for supporting Xilinx platforms. This driver is used for some sequence of operations required for Xilinx USB controllers. This driver is also used to choose between PIPE clock coming from SerDes and the Suspend Clock. Before the controller is out of reset, the clock selection should be changed to PIPE clock in order to make the USB controller work. There is a register added in Xilinx USB controller register space for the same. Signed-off-by: Manish Narani --- drivers/usb/dwc3/Kconfig | 9 + drivers/usb/dwc3/Makefile | 1 + drivers/usb/dwc3/dwc3-of-simple.c | 1 - drivers/usb/dwc3/dwc3-xilinx.c| 334 ++ 4 files changed, 344 insertions(+), 1 deletion(-) create mode 100644 drivers/usb/dwc3/dwc3-xilinx.c diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index 7a2304565a73..0e00e6dfccd8 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -139,4 +139,13 @@ config USB_DWC3_QCOM for peripheral mode support. Say 'Y' or 'M' if you have one such device. +config USB_DWC3_XILINX + tristate "Xilinx Platforms" + depends on (ARCH_ZYNQMP || ARCH_VERSAL) && OF + default USB_DWC3 + help + Support Xilinx SoCs with DesignWare Core USB3 IP. + This driver handles both ZynqMP and Versal SoC operations. + Say 'Y' or 'M' if you have one such device. + endif diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile index ae86da0dc5bd..add567578b1f 100644 --- a/drivers/usb/dwc3/Makefile +++ b/drivers/usb/dwc3/Makefile @@ -51,3 +51,4 @@ obj-$(CONFIG_USB_DWC3_MESON_G12A) += dwc3-meson-g12a.o obj-$(CONFIG_USB_DWC3_OF_SIMPLE)+= dwc3-of-simple.o obj-$(CONFIG_USB_DWC3_ST) += dwc3-st.o obj-$(CONFIG_USB_DWC3_QCOM) += dwc3-qcom.o +obj-$(CONFIG_USB_DWC3_XILINX) += dwc3-xilinx.o diff --git a/drivers/usb/dwc3/dwc3-of-simple.c b/drivers/usb/dwc3/dwc3-of-simple.c index e62ecd22b3ed..71fd620c5161 100644 --- a/drivers/usb/dwc3/dwc3-of-simple.c +++ b/drivers/usb/dwc3/dwc3-of-simple.c @@ -172,7 +172,6 @@ static const struct dev_pm_ops dwc3_of_simple_dev_pm_ops = { static const struct of_device_id of_dwc3_simple_match[] = { { .compatible = "rockchip,rk3399-dwc3" }, - { .compatible = "xlnx,zynqmp-dwc3" }, { .compatible = "cavium,octeon-7130-usb-uctl" }, { .compatible = "sprd,sc9860-dwc3" }, { .compatible = "allwinner,sun50i-h6-dwc3" }, diff --git a/drivers/usb/dwc3/dwc3-xilinx.c b/drivers/usb/dwc3/dwc3-xilinx.c new file mode 100644 index ..7e485951d2f7 --- /dev/null +++ b/drivers/usb/dwc3/dwc3-xilinx.c @@ -0,0 +1,334 @@ +// SPDX-License-Identifier: GPL-2.0 +/** + * dwc3-xilinx.c - Xilinx DWC3 controller specific glue driver + * + * Authors: Manish Narani + * Anurag Kumar Vulisha + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* USB phy reset mask register */ +#define XLNX_USB_PHY_RST_EN0x001C +#define XLNX_PHY_RST_MASK 0x1 + +/* Xilinx USB 3.0 IP Register */ +#define XLNX_USB_TRAFFIC_ROUTE_CONFIG 0x005C +#define XLNX_USB_TRAFFIC_ROUTE_FPD 0x1 + +/* Versal USB Reset ID */ +#define VERSAL_USB_RESET_ID0xC104036 + +#define XLNX_USB_FPD_PIPE_CLK 0x7c +#define PIPE_CLK_DESELECT 1 +#define PIPE_CLK_SELECT0 +#define XLNX_USB_FPD_POWER_PRSNT 0x80 +#define PIPE_POWER_ON 1 +#define PIPE_POWER_OFF 0 + +struct dwc3_xlnx { + int num_clocks; + struct clk_bulk_data*clks; + struct device *dev; + void __iomem*regs; + int (*pltfm_init)(struct dwc3_xlnx *data); +}; + +static void dwc3_xlnx_mask_phy_rst(struct dwc3_xlnx *priv_data, bool mask) +{ + u32 reg; + + /* +* Enable or disable ULPI PHY reset from USB Controller. +* This does not actually reset the phy, but just controls +* whether USB controller can or cannot reset ULPI PHY. +*/ + reg = readl(priv_data->regs + XLNX_USB_PHY_RST_EN); + + if (mask) + reg &= ~XLNX_PHY_RST_MASK; + else + reg |= XLNX_PHY_RST_MASK; + + writel(reg, priv_data->regs + XLNX_USB_PHY_RST_EN); +} + +static int dwc3_xlnx_init_versal(struct dwc3_xlnx *priv_data) +{ + struct device *dev = priv_data->dev; + int ret; + + dwc3_xlnx_mask_phy_rst(priv_data, false); + + /* Assert and De-assert reset */ + ret = zynqmp_pm_reset_assert(VERSAL_USB_RESET_ID, +
Re: [RESEND PATCH v3 2/2] usb: dwc3: Add driver for Xilinx platforms
Adding Tinh Nguyen to CC: On Tue, Feb 09, 2021 at 09:02:00PM +0100, Michael Grzeschik wrote: Hi Manish, On Tue, Feb 09, 2021 at 06:01:58AM +, Manish Narani wrote: Hi Michael, -Original Message- From: Michael Grzeschik Sent: Tuesday, February 9, 2021 5:26 AM To: Manish Narani Cc: devicet...@vger.kernel.org; p.za...@pengutronix.de; ba...@kernel.org; gre...@linuxfoundation.org; linux-...@vger.kernel.org; linux- ker...@vger.kernel.org; robh...@kernel.org; Michal Simek ; git ; ker...@pengutronix.de; linux- arm-ker...@lists.infradead.org Subject: Re: [RESEND PATCH v3 2/2] usb: dwc3: Add driver for Xilinx platforms Hi Manish! On Thu, Jan 28, 2021 at 12:36:07AM +0100, Michael Grzeschik wrote: On Fri, Jan 22, 2021 at 02:34:52PM +0100, Michael Grzeschik wrote: On Fri, Jan 22, 2021 at 01:06:22PM +, Manish Narani wrote: Hi Michael, -Original Message- From: Michael Grzeschik Sent: Friday, January 22, 2021 1:39 PM To: Manish Narani Cc: devicet...@vger.kernel.org; ker...@pengutronix.de; ba...@kernel.org; gre...@linuxfoundation.org; linux-...@vger.kernel.org; Michal Simek ; linux-kernel@vger.kernel.org; robh...@kernel.org; git ; p.za...@pengutronix.de; linux-arm- ker...@lists.infradead.org Subject: Re: [RESEND PATCH v3 2/2] usb: dwc3: Add driver for Xilinx platforms Hello! On Mon, Jan 18, 2021 at 02:42:24PM +0100, Michael Grzeschik wrote: Hi! On Tue, Dec 15, 2020 at 12:24:51PM +0530, Manish Narani wrote: Add a new driver for supporting Xilinx platforms. This driver is used for some sequence of operations required for Xilinx USB controllers. This driver is also used to choose between PIPE clock coming from SerDes and the Suspend Clock. Before the controller is out of reset, the clock selection should be changed to PIPE clock in order to make the USB controller work. There is a register added in Xilinx USB controller register space for the same. I tried out this driver with the vanilla kernel on an zynqmp. Without this patch the USB-Gadget is already acting buggy. In the gadget mode, some iterations of plug/unplug results to an stalled gadget which will never come back without a reboot. With the corresponding code of this driver (reset assert, clk modify, reset deassert) in the downstream kernels phy driver we found out it is totaly stable. But using this exact glue driver which should do the same as the downstream code, the gadget still was buggy the way described above. I suspect the difference lays in the different order of operations. While the downstream code is runing the resets inside the phy driver which is powered and initialized in the dwc3-core itself. With this glue layser approach of this patch the whole phy init is done before even touching dwc3-core in any way. It seems not to have the same effect, though. If really the order of operations is limiting us, we probably need another solution than this glue layer. Any Ideas? I found out what the difference between the Downstream and this Glue is. When using vanilla with this Glue code we may not set the following bit: https://www.xilinx.com/html_docs/registers/ug1087/ug1087-zynq- ultrascale-registers.html#usb3_regs___fpd_power_prsnt.html + /* Set PIPE Power Present signal in FPD Power Present Register*/ + writel(PIPE_POWER_ON, priv_data->regs + XLNX_USB_FPD_POWER_PRSNT); When I comment this out, the link stays stable. This is different in the Downstream Xilinx Kernel, where the bit is also set but has no negativ effect. Manish, can you give me a pointer what to look for? So setting this will also work with mainline? I am looking further on this but from what I see here is that, In order to make USB function properly, there are some dt changes needed in mainline for USB node which include defining clocks coming from serdes. The DT changes are pending to be sent to mainline. Can you push that state somewhere, so I could test it? Or is in the downstream kernel some things to copy? Can you share the DT settings for USB node on your side? Here is my current configuration for the device node at usb0: zynqmp.dtsi zynqmp_reset: reset-controller { compatible = "xlnx,zynqmp-reset"; #reset-cells = <1>; }; usb0: usb@ff9d { #address-cells = <2>; #size-cells = <2>; status = "disabled"; compatible = "xlnx,zynqmp-dwc3"; reg = <0x0 0xff9d 0x0 0x100>; clock-names = "bus_clk", "ref_clk"; power-domains = <_firmware PD_USB_0>; ranges; resets = <_reset ZYNQMP_RESET_USB0_CORERESET>, <_reset ZYNQMP_RESET_USB0_HIBERRESET>, <_reset ZYNQMP_RESET_USB0_APB>; reset-names = "usb_crst", "usb_hibrst", "usb_apbrst"; phy-names = "usb3-phy"; phys = < 2 PHY_TYPE_USB3 0 2>; usb0_dwc3: dwc3@fe20 {
Re: [RESEND PATCH v3 2/2] usb: dwc3: Add driver for Xilinx platforms
Hi Manish, On Tue, Feb 09, 2021 at 06:01:58AM +, Manish Narani wrote: Hi Michael, -Original Message- From: Michael Grzeschik Sent: Tuesday, February 9, 2021 5:26 AM To: Manish Narani Cc: devicet...@vger.kernel.org; p.za...@pengutronix.de; ba...@kernel.org; gre...@linuxfoundation.org; linux-...@vger.kernel.org; linux- ker...@vger.kernel.org; robh...@kernel.org; Michal Simek ; git ; ker...@pengutronix.de; linux- arm-ker...@lists.infradead.org Subject: Re: [RESEND PATCH v3 2/2] usb: dwc3: Add driver for Xilinx platforms Hi Manish! On Thu, Jan 28, 2021 at 12:36:07AM +0100, Michael Grzeschik wrote: >On Fri, Jan 22, 2021 at 02:34:52PM +0100, Michael Grzeschik wrote: >>On Fri, Jan 22, 2021 at 01:06:22PM +, Manish Narani wrote: >>>Hi Michael, >>> >>>>-Original Message- >>>>From: Michael Grzeschik >>>>Sent: Friday, January 22, 2021 1:39 PM >>>>To: Manish Narani >>>>Cc: devicet...@vger.kernel.org; ker...@pengutronix.de; ba...@kernel.org; >>>>gre...@linuxfoundation.org; linux-...@vger.kernel.org; Michal Simek >>>>; linux-kernel@vger.kernel.org; robh...@kernel.org; >>>>git ; p.za...@pengutronix.de; linux-arm- >>>>ker...@lists.infradead.org >>>>Subject: Re: [RESEND PATCH v3 2/2] usb: dwc3: Add driver for Xilinx >>>>platforms >>>> >>>>Hello! >>>> >>>>On Mon, Jan 18, 2021 at 02:42:24PM +0100, Michael Grzeschik wrote: >>>>>Hi! >>>>> >>>>>On Tue, Dec 15, 2020 at 12:24:51PM +0530, Manish Narani wrote: >>>>>>Add a new driver for supporting Xilinx platforms. This driver is used >>>>>>for some sequence of operations required for Xilinx USB controllers. >>>>>>This driver is also used to choose between PIPE clock coming from SerDes >>>>>>and the Suspend Clock. Before the controller is out of reset, the clock >>>>>>selection should be changed to PIPE clock in order to make the USB >>>>>>controller work. There is a register added in Xilinx USB controller >>>>>>register space for the same. >>>>> >>>>>I tried out this driver with the vanilla kernel on an zynqmp. Without >>>>>this patch the USB-Gadget is already acting buggy. In the gadget mode, >>>>>some iterations of plug/unplug results to an stalled gadget which will >>>>>never come back without a reboot. >>>>> >>>>>With the corresponding code of this driver (reset assert, clk modify, >>>>>reset deassert) in the downstream kernels phy driver we found out it is >>>>>totaly stable. But using this exact glue driver which should do the same >>>>>as the downstream code, the gadget still was buggy the way described >>>>>above. >>>>> >>>>>I suspect the difference lays in the different order of operations. >>>>>While the downstream code is runing the resets inside the phy driver >>>>>which is powered and initialized in the dwc3-core itself. With this glue >>>>>layser approach of this patch the whole phy init is done before even >>>>>touching dwc3-core in any way. It seems not to have the same effect, >>>>>though. >>>>> >>>>>If really the order of operations is limiting us, we probably need >>>>>another solution than this glue layer. Any Ideas? >>>> >>>>I found out what the difference between the Downstream and this >>>>Glue is. When using vanilla with this Glue code we may not set >>>>the following bit: >>>> >>>>https://www.xilinx.com/html_docs/registers/ug1087/ug1087-zynq- >>>>ultrascale-registers.html#usb3_regs___fpd_power_prsnt.html >>>> >>>>>>+ /* Set PIPE Power Present signal in FPD Power Present Register*/ >>>>>>+ writel(PIPE_POWER_ON, priv_data->regs + >>>>XLNX_USB_FPD_POWER_PRSNT); >>>> >>>>When I comment this out, the link stays stable. This is different in >>>>the Downstream Xilinx Kernel, where the bit is also set but has no >>>>negativ effect. >>>> >>>>Manish, can you give me a pointer what to look for? >>>>So setting this will also work with mainline? >>>I am looking further on this but from what I see here is that, >>>In order to make USB function properly, there are some dt changes needed in mainline for >>>USB node which include defining clocks coming from serdes. >>>The DT chan
Re: [RESEND PATCH v3 2/2] usb: dwc3: Add driver for Xilinx platforms
Hi Manish! On Thu, Jan 28, 2021 at 12:36:07AM +0100, Michael Grzeschik wrote: On Fri, Jan 22, 2021 at 02:34:52PM +0100, Michael Grzeschik wrote: On Fri, Jan 22, 2021 at 01:06:22PM +, Manish Narani wrote: Hi Michael, -Original Message- From: Michael Grzeschik Sent: Friday, January 22, 2021 1:39 PM To: Manish Narani Cc: devicet...@vger.kernel.org; ker...@pengutronix.de; ba...@kernel.org; gre...@linuxfoundation.org; linux-...@vger.kernel.org; Michal Simek ; linux-kernel@vger.kernel.org; robh...@kernel.org; git ; p.za...@pengutronix.de; linux-arm- ker...@lists.infradead.org Subject: Re: [RESEND PATCH v3 2/2] usb: dwc3: Add driver for Xilinx platforms Hello! On Mon, Jan 18, 2021 at 02:42:24PM +0100, Michael Grzeschik wrote: Hi! On Tue, Dec 15, 2020 at 12:24:51PM +0530, Manish Narani wrote: Add a new driver for supporting Xilinx platforms. This driver is used for some sequence of operations required for Xilinx USB controllers. This driver is also used to choose between PIPE clock coming from SerDes and the Suspend Clock. Before the controller is out of reset, the clock selection should be changed to PIPE clock in order to make the USB controller work. There is a register added in Xilinx USB controller register space for the same. I tried out this driver with the vanilla kernel on an zynqmp. Without this patch the USB-Gadget is already acting buggy. In the gadget mode, some iterations of plug/unplug results to an stalled gadget which will never come back without a reboot. With the corresponding code of this driver (reset assert, clk modify, reset deassert) in the downstream kernels phy driver we found out it is totaly stable. But using this exact glue driver which should do the same as the downstream code, the gadget still was buggy the way described above. I suspect the difference lays in the different order of operations. While the downstream code is runing the resets inside the phy driver which is powered and initialized in the dwc3-core itself. With this glue layser approach of this patch the whole phy init is done before even touching dwc3-core in any way. It seems not to have the same effect, though. If really the order of operations is limiting us, we probably need another solution than this glue layer. Any Ideas? I found out what the difference between the Downstream and this Glue is. When using vanilla with this Glue code we may not set the following bit: https://www.xilinx.com/html_docs/registers/ug1087/ug1087-zynq- ultrascale-registers.html#usb3_regs___fpd_power_prsnt.html + /* Set PIPE Power Present signal in FPD Power Present Register*/ + writel(PIPE_POWER_ON, priv_data->regs + XLNX_USB_FPD_POWER_PRSNT); When I comment this out, the link stays stable. This is different in the Downstream Xilinx Kernel, where the bit is also set but has no negativ effect. Manish, can you give me a pointer what to look for? So setting this will also work with mainline? I am looking further on this but from what I see here is that, In order to make USB function properly, there are some dt changes needed in mainline for USB node which include defining clocks coming from serdes. The DT changes are pending to be sent to mainline. Can you push that state somewhere, so I could test it? Or is in the downstream kernel some things to copy? Can you share the DT settings for USB node on your side? Here is my current configuration for the device node at usb0: zynqmp.dtsi zynqmp_reset: reset-controller { compatible = "xlnx,zynqmp-reset"; #reset-cells = <1>; }; usb0: usb@ff9d { #address-cells = <2>; #size-cells = <2>; status = "disabled"; compatible = "xlnx,zynqmp-dwc3"; reg = <0x0 0xff9d 0x0 0x100>; clock-names = "bus_clk", "ref_clk"; power-domains = <_firmware PD_USB_0>; ranges; resets = <_reset ZYNQMP_RESET_USB0_CORERESET>, <_reset ZYNQMP_RESET_USB0_HIBERRESET>, <_reset ZYNQMP_RESET_USB0_APB>; reset-names = "usb_crst", "usb_hibrst", "usb_apbrst"; phy-names = "usb3-phy"; phys = < 2 PHY_TYPE_USB3 0 2>; usb0_dwc3: dwc3@fe20 { compatible = "snps,dwc3"; interrupt-parent = <>; interrupts = <0 65 4>; clock-names = "ref", "bus_early", "suspend"; reg = <0x0 0xfe20 0x0 0x4>; }; }; platform.dts { status = "okay"; phy-names = "usb3-phy"; phys = < 2 PHY_TYPE_USB3 0 2>; }; _dwc3 { dr_mode = "peripheral"; /* The following quirks are required, since the bInterval is 1 and we * handle steady ISOC streaming. See Usecase 3 in commit 729dcf
Re: [RESEND PATCH v3 2/2] usb: dwc3: Add driver for Xilinx platforms
On Fri, Jan 22, 2021 at 02:34:52PM +0100, Michael Grzeschik wrote: On Fri, Jan 22, 2021 at 01:06:22PM +, Manish Narani wrote: Hi Michael, -Original Message- From: Michael Grzeschik Sent: Friday, January 22, 2021 1:39 PM To: Manish Narani Cc: devicet...@vger.kernel.org; ker...@pengutronix.de; ba...@kernel.org; gre...@linuxfoundation.org; linux-...@vger.kernel.org; Michal Simek ; linux-kernel@vger.kernel.org; robh...@kernel.org; git ; p.za...@pengutronix.de; linux-arm- ker...@lists.infradead.org Subject: Re: [RESEND PATCH v3 2/2] usb: dwc3: Add driver for Xilinx platforms Hello! On Mon, Jan 18, 2021 at 02:42:24PM +0100, Michael Grzeschik wrote: Hi! On Tue, Dec 15, 2020 at 12:24:51PM +0530, Manish Narani wrote: Add a new driver for supporting Xilinx platforms. This driver is used for some sequence of operations required for Xilinx USB controllers. This driver is also used to choose between PIPE clock coming from SerDes and the Suspend Clock. Before the controller is out of reset, the clock selection should be changed to PIPE clock in order to make the USB controller work. There is a register added in Xilinx USB controller register space for the same. I tried out this driver with the vanilla kernel on an zynqmp. Without this patch the USB-Gadget is already acting buggy. In the gadget mode, some iterations of plug/unplug results to an stalled gadget which will never come back without a reboot. With the corresponding code of this driver (reset assert, clk modify, reset deassert) in the downstream kernels phy driver we found out it is totaly stable. But using this exact glue driver which should do the same as the downstream code, the gadget still was buggy the way described above. I suspect the difference lays in the different order of operations. While the downstream code is runing the resets inside the phy driver which is powered and initialized in the dwc3-core itself. With this glue layser approach of this patch the whole phy init is done before even touching dwc3-core in any way. It seems not to have the same effect, though. If really the order of operations is limiting us, we probably need another solution than this glue layer. Any Ideas? I found out what the difference between the Downstream and this Glue is. When using vanilla with this Glue code we may not set the following bit: https://www.xilinx.com/html_docs/registers/ug1087/ug1087-zynq- ultrascale-registers.html#usb3_regs___fpd_power_prsnt.html + /* Set PIPE Power Present signal in FPD Power Present Register*/ + writel(PIPE_POWER_ON, priv_data->regs + XLNX_USB_FPD_POWER_PRSNT); When I comment this out, the link stays stable. This is different in the Downstream Xilinx Kernel, where the bit is also set but has no negativ effect. Manish, can you give me a pointer what to look for? So setting this will also work with mainline? I am looking further on this but from what I see here is that, In order to make USB function properly, there are some dt changes needed in mainline for USB node which include defining clocks coming from serdes. The DT changes are pending to be sent to mainline. Can you push that state somewhere, so I could test it? Or is in the downstream kernel some things to copy? Can you share the DT settings for USB node on your side? Here is my current configuration for the device node at usb0: zynqmp.dtsi zynqmp_reset: reset-controller { compatible = "xlnx,zynqmp-reset"; #reset-cells = <1>; }; usb0: usb@ff9d { #address-cells = <2>; #size-cells = <2>; status = "disabled"; compatible = "xlnx,zynqmp-dwc3"; reg = <0x0 0xff9d 0x0 0x100>; clock-names = "bus_clk", "ref_clk"; power-domains = <_firmware PD_USB_0>; ranges; resets = <_reset ZYNQMP_RESET_USB0_CORERESET>, <_reset ZYNQMP_RESET_USB0_HIBERRESET>, <_reset ZYNQMP_RESET_USB0_APB>; reset-names = "usb_crst", "usb_hibrst", "usb_apbrst"; phy-names = "usb3-phy"; phys = < 2 PHY_TYPE_USB3 0 2>; usb0_dwc3: dwc3@fe20 { compatible = "snps,dwc3"; interrupt-parent = <>; interrupts = <0 65 4>; clock-names = "ref", "bus_early", "suspend"; reg = <0x0 0xfe20 0x0 0x4>; }; }; platform.dts { status = "okay"; phy-names = "usb3-phy"; phys = < 2 PHY_TYPE_USB3 0 2>; }; _dwc3 { dr_mode = "peripheral"; /* The following quirks are required, since the bInterval is 1 and we * handle steady ISOC streaming. See Usecase 3 in commit 729dcffd1ed3 * ("usb: dwc3: gadget: Add support for disabling U1 and U
Re: [RESEND PATCH v3 2/2] usb: dwc3: Add driver for Xilinx platforms
On Fri, Jan 22, 2021 at 01:06:22PM +, Manish Narani wrote: Hi Michael, -Original Message- From: Michael Grzeschik Sent: Friday, January 22, 2021 1:39 PM To: Manish Narani Cc: devicet...@vger.kernel.org; ker...@pengutronix.de; ba...@kernel.org; gre...@linuxfoundation.org; linux-...@vger.kernel.org; Michal Simek ; linux-kernel@vger.kernel.org; robh...@kernel.org; git ; p.za...@pengutronix.de; linux-arm- ker...@lists.infradead.org Subject: Re: [RESEND PATCH v3 2/2] usb: dwc3: Add driver for Xilinx platforms Hello! On Mon, Jan 18, 2021 at 02:42:24PM +0100, Michael Grzeschik wrote: >Hi! > >On Tue, Dec 15, 2020 at 12:24:51PM +0530, Manish Narani wrote: >>Add a new driver for supporting Xilinx platforms. This driver is used >>for some sequence of operations required for Xilinx USB controllers. >>This driver is also used to choose between PIPE clock coming from SerDes >>and the Suspend Clock. Before the controller is out of reset, the clock >>selection should be changed to PIPE clock in order to make the USB >>controller work. There is a register added in Xilinx USB controller >>register space for the same. > >I tried out this driver with the vanilla kernel on an zynqmp. Without >this patch the USB-Gadget is already acting buggy. In the gadget mode, >some iterations of plug/unplug results to an stalled gadget which will >never come back without a reboot. > >With the corresponding code of this driver (reset assert, clk modify, >reset deassert) in the downstream kernels phy driver we found out it is >totaly stable. But using this exact glue driver which should do the same >as the downstream code, the gadget still was buggy the way described >above. > >I suspect the difference lays in the different order of operations. >While the downstream code is runing the resets inside the phy driver >which is powered and initialized in the dwc3-core itself. With this glue >layser approach of this patch the whole phy init is done before even >touching dwc3-core in any way. It seems not to have the same effect, >though. > >If really the order of operations is limiting us, we probably need >another solution than this glue layer. Any Ideas? I found out what the difference between the Downstream and this Glue is. When using vanilla with this Glue code we may not set the following bit: https://www.xilinx.com/html_docs/registers/ug1087/ug1087-zynq- ultrascale-registers.html#usb3_regs___fpd_power_prsnt.html >>+ /* Set PIPE Power Present signal in FPD Power Present Register*/ >>+ writel(PIPE_POWER_ON, priv_data->regs + XLNX_USB_FPD_POWER_PRSNT); When I comment this out, the link stays stable. This is different in the Downstream Xilinx Kernel, where the bit is also set but has no negativ effect. Manish, can you give me a pointer what to look for? So setting this will also work with mainline? I am looking further on this but from what I see here is that, In order to make USB function properly, there are some dt changes needed in mainline for USB node which include defining clocks coming from serdes. The DT changes are pending to be sent to mainline. Can you push that state somewhere, so I could test it? Or is in the downstream kernel some things to copy? Can you share the DT settings for USB node on your side? Here is my current configuration for the device node at usb0: zynqmp.dtsi zynqmp_reset: reset-controller { compatible = "xlnx,zynqmp-reset"; #reset-cells = <1>; }; usb0: usb@ff9d { #address-cells = <2>; #size-cells = <2>; status = "disabled"; compatible = "xlnx,zynqmp-dwc3"; reg = <0x0 0xff9d 0x0 0x100>; clock-names = "bus_clk", "ref_clk"; power-domains = <_firmware PD_USB_0>; ranges; resets = <_reset ZYNQMP_RESET_USB0_CORERESET>, <_reset ZYNQMP_RESET_USB0_HIBERRESET>, <_reset ZYNQMP_RESET_USB0_APB>; reset-names = "usb_crst", "usb_hibrst", "usb_apbrst"; phy-names = "usb3-phy"; phys = < 2 PHY_TYPE_USB3 0 2>; usb0_dwc3: dwc3@fe20 { compatible = "snps,dwc3"; interrupt-parent = <>; interrupts = <0 65 4>; clock-names = "ref", "bus_early", "suspend"; reg = <0x0 0xfe20 0x0 0x4>; }; }; platform.dts { status = "okay"; phy-names = "usb3-phy"; phys = < 2 PHY_TYPE_USB3 0 2>; }; _dwc3 { dr_mode = "peripheral"; /* The following quirks are required, since the bInterval is 1 and we * handle steady ISOC streaming. See Usecase 3 in
Re: [RESEND PATCH v3 2/2] usb: dwc3: Add driver for Xilinx platforms
Hello! On Mon, Jan 18, 2021 at 02:42:24PM +0100, Michael Grzeschik wrote: Hi! On Tue, Dec 15, 2020 at 12:24:51PM +0530, Manish Narani wrote: Add a new driver for supporting Xilinx platforms. This driver is used for some sequence of operations required for Xilinx USB controllers. This driver is also used to choose between PIPE clock coming from SerDes and the Suspend Clock. Before the controller is out of reset, the clock selection should be changed to PIPE clock in order to make the USB controller work. There is a register added in Xilinx USB controller register space for the same. I tried out this driver with the vanilla kernel on an zynqmp. Without this patch the USB-Gadget is already acting buggy. In the gadget mode, some iterations of plug/unplug results to an stalled gadget which will never come back without a reboot. With the corresponding code of this driver (reset assert, clk modify, reset deassert) in the downstream kernels phy driver we found out it is totaly stable. But using this exact glue driver which should do the same as the downstream code, the gadget still was buggy the way described above. I suspect the difference lays in the different order of operations. While the downstream code is runing the resets inside the phy driver which is powered and initialized in the dwc3-core itself. With this glue layser approach of this patch the whole phy init is done before even touching dwc3-core in any way. It seems not to have the same effect, though. If really the order of operations is limiting us, we probably need another solution than this glue layer. Any Ideas? I found out what the difference between the Downstream and this Glue is. When using vanilla with this Glue code we may not set the following bit: https://www.xilinx.com/html_docs/registers/ug1087/ug1087-zynq-ultrascale-registers.html#usb3_regs___fpd_power_prsnt.html + /* Set PIPE Power Present signal in FPD Power Present Register*/ + writel(PIPE_POWER_ON, priv_data->regs + XLNX_USB_FPD_POWER_PRSNT); When I comment this out, the link stays stable. This is different in the Downstream Xilinx Kernel, where the bit is also set but has no negativ effect. Manish, can you give me a pointer what to look for? So setting this will also work with mainline? Regards, Michael Signed-off-by: Manish Narani --- drivers/usb/dwc3/Kconfig | 9 + drivers/usb/dwc3/Makefile | 1 + drivers/usb/dwc3/dwc3-of-simple.c | 1 - drivers/usb/dwc3/dwc3-xilinx.c| 334 ++ 4 files changed, 344 insertions(+), 1 deletion(-) create mode 100644 drivers/usb/dwc3/dwc3-xilinx.c diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index 7a2304565a73..0e00e6dfccd8 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -139,4 +139,13 @@ config USB_DWC3_QCOM for peripheral mode support. Say 'Y' or 'M' if you have one such device. +config USB_DWC3_XILINX + tristate "Xilinx Platforms" + depends on (ARCH_ZYNQMP || ARCH_VERSAL) && OF + default USB_DWC3 + help + Support Xilinx SoCs with DesignWare Core USB3 IP. + This driver handles both ZynqMP and Versal SoC operations. + Say 'Y' or 'M' if you have one such device. + endif diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile index ae86da0dc5bd..add567578b1f 100644 --- a/drivers/usb/dwc3/Makefile +++ b/drivers/usb/dwc3/Makefile @@ -51,3 +51,4 @@ obj-$(CONFIG_USB_DWC3_MESON_G12A) += dwc3-meson-g12a.o obj-$(CONFIG_USB_DWC3_OF_SIMPLE)+= dwc3-of-simple.o obj-$(CONFIG_USB_DWC3_ST) += dwc3-st.o obj-$(CONFIG_USB_DWC3_QCOM) += dwc3-qcom.o +obj-$(CONFIG_USB_DWC3_XILINX) += dwc3-xilinx.o diff --git a/drivers/usb/dwc3/dwc3-of-simple.c b/drivers/usb/dwc3/dwc3-of-simple.c index e62ecd22b3ed..71fd620c5161 100644 --- a/drivers/usb/dwc3/dwc3-of-simple.c +++ b/drivers/usb/dwc3/dwc3-of-simple.c @@ -172,7 +172,6 @@ static const struct dev_pm_ops dwc3_of_simple_dev_pm_ops = { static const struct of_device_id of_dwc3_simple_match[] = { { .compatible = "rockchip,rk3399-dwc3" }, - { .compatible = "xlnx,zynqmp-dwc3" }, { .compatible = "cavium,octeon-7130-usb-uctl" }, { .compatible = "sprd,sc9860-dwc3" }, { .compatible = "allwinner,sun50i-h6-dwc3" }, diff --git a/drivers/usb/dwc3/dwc3-xilinx.c b/drivers/usb/dwc3/dwc3-xilinx.c new file mode 100644 index ..7e485951d2f7 --- /dev/null +++ b/drivers/usb/dwc3/dwc3-xilinx.c @@ -0,0 +1,334 @@ +// SPDX-License-Identifier: GPL-2.0 +/** + * dwc3-xilinx.c - Xilinx DWC3 controller specific glue driver + * + * Authors: Manish Narani + * Anurag Kumar Vulisha + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* USB phy reset
Re: [RESEND PATCH v3 2/2] usb: dwc3: Add driver for Xilinx platforms
On Mon, Jan 18, 2021 at 05:24:38PM +0200, Felipe Balbi wrote: Hi, Michael Grzeschik writes: On Tue, Dec 15, 2020 at 12:24:51PM +0530, Manish Narani wrote: Add a new driver for supporting Xilinx platforms. This driver is used for some sequence of operations required for Xilinx USB controllers. This driver is also used to choose between PIPE clock coming from SerDes and the Suspend Clock. Before the controller is out of reset, the clock selection should be changed to PIPE clock in order to make the USB controller work. There is a register added in Xilinx USB controller register space for the same. I tried out this driver with the vanilla kernel on an zynqmp. Without this patch the USB-Gadget is already acting buggy. In the gadget mode, some iterations of plug/unplug results to an stalled gadget which will never come back without a reboot. With the corresponding code of this driver (reset assert, clk modify, reset deassert) in the downstream kernels phy driver we found out it is totaly stable. But using this exact glue driver which should do the same as the downstream code, the gadget still was buggy the way described above. I suspect the difference lays in the different order of operations. While the downstream code is runing the resets inside the phy driver which is powered and initialized in the dwc3-core itself. With this glue layser approach of this patch the whole phy init is done before even touching dwc3-core in any way. It seems not to have the same effect, though. If really the order of operations is limiting us, we probably need another solution than this glue layer. Any Ideas? might be a good idea to collect dwc3 trace events. Can you do that? I already did that. In case the port is not working properly, the port was producing several "Erratic Errors" between the plug/unplug events. This was not the case until the reset_assert, pll configure, reset_deassert sequence was applied like in the downstream kernels phy driver on phy_init. Regards, Michael -- Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | signature.asc Description: PGP signature
Re: [RESEND PATCH v3 2/2] usb: dwc3: Add driver for Xilinx platforms
Hi! On Tue, Dec 15, 2020 at 12:24:51PM +0530, Manish Narani wrote: Add a new driver for supporting Xilinx platforms. This driver is used for some sequence of operations required for Xilinx USB controllers. This driver is also used to choose between PIPE clock coming from SerDes and the Suspend Clock. Before the controller is out of reset, the clock selection should be changed to PIPE clock in order to make the USB controller work. There is a register added in Xilinx USB controller register space for the same. I tried out this driver with the vanilla kernel on an zynqmp. Without this patch the USB-Gadget is already acting buggy. In the gadget mode, some iterations of plug/unplug results to an stalled gadget which will never come back without a reboot. With the corresponding code of this driver (reset assert, clk modify, reset deassert) in the downstream kernels phy driver we found out it is totaly stable. But using this exact glue driver which should do the same as the downstream code, the gadget still was buggy the way described above. I suspect the difference lays in the different order of operations. While the downstream code is runing the resets inside the phy driver which is powered and initialized in the dwc3-core itself. With this glue layser approach of this patch the whole phy init is done before even touching dwc3-core in any way. It seems not to have the same effect, though. If really the order of operations is limiting us, we probably need another solution than this glue layer. Any Ideas? Regards, Michael Signed-off-by: Manish Narani --- drivers/usb/dwc3/Kconfig | 9 + drivers/usb/dwc3/Makefile | 1 + drivers/usb/dwc3/dwc3-of-simple.c | 1 - drivers/usb/dwc3/dwc3-xilinx.c| 334 ++ 4 files changed, 344 insertions(+), 1 deletion(-) create mode 100644 drivers/usb/dwc3/dwc3-xilinx.c diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index 7a2304565a73..0e00e6dfccd8 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -139,4 +139,13 @@ config USB_DWC3_QCOM for peripheral mode support. Say 'Y' or 'M' if you have one such device. +config USB_DWC3_XILINX + tristate "Xilinx Platforms" + depends on (ARCH_ZYNQMP || ARCH_VERSAL) && OF + default USB_DWC3 + help + Support Xilinx SoCs with DesignWare Core USB3 IP. + This driver handles both ZynqMP and Versal SoC operations. + Say 'Y' or 'M' if you have one such device. + endif diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile index ae86da0dc5bd..add567578b1f 100644 --- a/drivers/usb/dwc3/Makefile +++ b/drivers/usb/dwc3/Makefile @@ -51,3 +51,4 @@ obj-$(CONFIG_USB_DWC3_MESON_G12A) += dwc3-meson-g12a.o obj-$(CONFIG_USB_DWC3_OF_SIMPLE)+= dwc3-of-simple.o obj-$(CONFIG_USB_DWC3_ST) += dwc3-st.o obj-$(CONFIG_USB_DWC3_QCOM) += dwc3-qcom.o +obj-$(CONFIG_USB_DWC3_XILINX) += dwc3-xilinx.o diff --git a/drivers/usb/dwc3/dwc3-of-simple.c b/drivers/usb/dwc3/dwc3-of-simple.c index e62ecd22b3ed..71fd620c5161 100644 --- a/drivers/usb/dwc3/dwc3-of-simple.c +++ b/drivers/usb/dwc3/dwc3-of-simple.c @@ -172,7 +172,6 @@ static const struct dev_pm_ops dwc3_of_simple_dev_pm_ops = { static const struct of_device_id of_dwc3_simple_match[] = { { .compatible = "rockchip,rk3399-dwc3" }, - { .compatible = "xlnx,zynqmp-dwc3" }, { .compatible = "cavium,octeon-7130-usb-uctl" }, { .compatible = "sprd,sc9860-dwc3" }, { .compatible = "allwinner,sun50i-h6-dwc3" }, diff --git a/drivers/usb/dwc3/dwc3-xilinx.c b/drivers/usb/dwc3/dwc3-xilinx.c new file mode 100644 index ..7e485951d2f7 --- /dev/null +++ b/drivers/usb/dwc3/dwc3-xilinx.c @@ -0,0 +1,334 @@ +// SPDX-License-Identifier: GPL-2.0 +/** + * dwc3-xilinx.c - Xilinx DWC3 controller specific glue driver + * + * Authors: Manish Narani + * Anurag Kumar Vulisha + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* USB phy reset mask register */ +#define XLNX_USB_PHY_RST_EN0x001C +#define XLNX_PHY_RST_MASK 0x1 + +/* Xilinx USB 3.0 IP Register */ +#define XLNX_USB_TRAFFIC_ROUTE_CONFIG 0x005C +#define XLNX_USB_TRAFFIC_ROUTE_FPD 0x1 + +/* Versal USB Reset ID */ +#define VERSAL_USB_RESET_ID0xC104036 + +#define XLNX_USB_FPD_PIPE_CLK 0x7c +#define PIPE_CLK_DESELECT 1 +#define PIPE_CLK_SELECT0 +#define XLNX_USB_FPD_POWER_PRSNT 0x80 +#define PIPE_POWER_ON 1 +#define PIPE_POWER_OFF 0 + +struct dwc3_xlnx { + int num_clocks; + struct clk_bulk_data*clks; + struct device
Re: linux-next: Signed-off-by missing for commit in the imx-mxs tree
On Mon, Jun 24, 2019 at 09:20:57PM +0800, Shawn Guo wrote: > On Mon, Jun 24, 2019 at 10:23:59PM +1000, Stephen Rothwell wrote: > > Hi all, > > > > Commit > > > > 9b5800c21b4d ("ARM: dts: imx6qdl-kontron-samx6i: add Kontron SMARC SoM > > Support") > > > > is missing a Signed-off-by from its author. > > Thanks for spotting it, Stephen. > > @Michael, would you please give your SoB? Otherwise, I will have to > back out the patch. Sure! Signed-off-by: Michael Grzeschik -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | signature.asc Description: PGP signature
[PATCH 0/3] Fix for drm_mode_config_cleanup issue
Fix the issue: "drm/imx: Crash in drm_mode_config_cleanup". Which was documented here: https://www.spinics.net/lists/dri-devel/msg189388.html And tried to address with this: https://patchwork.kernel.org/patch/10633297/ https://patchwork.kernel.org/patch/10633299/ This series fixes the possible case of use after free by adding action functions to the devres cleanup path. So it will ensure the generic cleanup code will not use the already freed memory. Michael Grzeschik (3): ipuv3-crtc: add remove action for devres data ipuv3-ldb: add init list head on bind ipuv3-ldb: add remove action for devres data drivers/gpu/drm/imx/imx-ldb.c| 35 drivers/gpu/drm/imx/ipuv3-crtc.c | 12 +++ 2 files changed, 47 insertions(+) -- 2.20.1
[PATCH 3/3] ipuv3-ldb: add remove action for devres data
The destroy function in drm_mode_config_cleanup will remove the objects in ipu-drm-core by calling its destroy functions if the bind function fails. The drm_encoder is also part of the devres allocated ipu_ldb object. The ipu_ldb object will already be cleaned up if the bind for the crtc fails. This leads drm_encoder_cleanup try to clean already freed memory. We fix this issue by adding the devres action ipu_ldb_remove_head which will remove its head from the objects in ipu-drm-core which then never calls its destroy function anymore. Signed-off-by: Michael Grzeschik --- drivers/gpu/drm/imx/imx-ldb.c | 19 +++ 1 file changed, 19 insertions(+) diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c index a11f8758da70e..0a224036cc68d 100644 --- a/drivers/gpu/drm/imx/imx-ldb.c +++ b/drivers/gpu/drm/imx/imx-ldb.c @@ -581,6 +581,21 @@ static int imx_ldb_panel_ddc(struct device *dev, return 0; } +static void ipu_ldb_remove_head(void *data) +{ + struct imx_ldb *imx_ldb = data; + struct imx_ldb_channel *imx_ldb_ch; + struct drm_encoder *encoder; + + imx_ldb_ch = _ldb->channel[0]; + encoder = _ldb_ch->encoder; + list_del_init(>head); + + imx_ldb_ch = _ldb->channel[1]; + encoder = _ldb_ch->encoder; + list_del_init(>head); +} + static void ipu_ldb_init_encoder_head(struct imx_ldb *imx_ldb) { struct imx_ldb_channel *imx_ldb_ch; @@ -613,6 +628,10 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) ipu_ldb_init_encoder_head(imx_ldb); + ret = devm_add_action(dev, ipu_ldb_remove_head, imx_ldb); + if (ret) + return ret; + imx_ldb->regmap = syscon_regmap_lookup_by_phandle(np, "gpr"); if (IS_ERR(imx_ldb->regmap)) { dev_err(dev, "failed to get parent regmap\n"); -- 2.20.1
[PATCH v4] usbip: dynamically allocate idev by nports found in sysfs
As the amount of available ports varies by the kernels build configuration. To remove the limitation of the fixed 128 ports we allocate the amount of idevs by using the number we get from the kernel. Signed-off-by: Michael Grzeschik <m.grzesc...@pengutronix.de> --- v1 -> v2: - reworked memory allocation into one calloc call - added error path on allocation failure v2 -> v3: - moved check for available nports to beginning of function v3 -> v4: - changed get_nports to get hc_device via parameter - moved calloc after valid get_nports call tools/usb/usbip/libsrc/vhci_driver.c | 32 +--- tools/usb/usbip/libsrc/vhci_driver.h | 3 +-- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index c9c81614a66ad..4204359c9feef 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -135,11 +135,11 @@ static int refresh_imported_device_list(void) return 0; } -static int get_nports(void) +static int get_nports(struct udev_device *hc_device) { const char *attr_nports; - attr_nports = udev_device_get_sysattr_value(vhci_driver->hc_device, "nports"); + attr_nports = udev_device_get_sysattr_value(hc_device, "nports"); if (!attr_nports) { err("udev_device_get_sysattr_value nports failed"); return -1; @@ -242,35 +242,41 @@ static int read_record(int rhport, char *host, unsigned long host_len, int usbip_vhci_driver_open(void) { + int nports; + struct udev_device *hc_device; + udev_context = udev_new(); if (!udev_context) { err("udev_new failed"); return -1; } - vhci_driver = calloc(1, sizeof(struct usbip_vhci_driver)); - /* will be freed in usbip_driver_close() */ - vhci_driver->hc_device = + hc_device = udev_device_new_from_subsystem_sysname(udev_context, USBIP_VHCI_BUS_TYPE, USBIP_VHCI_DEVICE_NAME); - if (!vhci_driver->hc_device) { + if (!hc_device) { err("udev_device_new_from_subsystem_sysname failed"); goto err; } - vhci_driver->nports = get_nports(); - dbg("available ports: %d", vhci_driver->nports); - - if (vhci_driver->nports <= 0) { + nports = get_nports(hc_device); + if (nports <= 0) { err("no available ports"); goto err; - } else if (vhci_driver->nports > MAXNPORT) { - err("port number exceeds %d", MAXNPORT); + } + dbg("available ports: %d", nports); + + vhci_driver = calloc(1, sizeof(struct usbip_vhci_driver) + + nports * sizeof(struct usbip_imported_device)); + if (!vhci_driver) { + err("vhci_driver allocation failed"); goto err; } + vhci_driver->nports = nports; + vhci_driver->hc_device = hc_device; vhci_driver->ncontrollers = get_ncontrollers(); dbg("available controllers: %d", vhci_driver->ncontrollers); @@ -285,7 +291,7 @@ int usbip_vhci_driver_open(void) return 0; err: - udev_device_unref(vhci_driver->hc_device); + udev_device_unref(hc_device); if (vhci_driver) free(vhci_driver); diff --git a/tools/usb/usbip/libsrc/vhci_driver.h b/tools/usb/usbip/libsrc/vhci_driver.h index 418b404d51210..6c9aca2167051 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.h +++ b/tools/usb/usbip/libsrc/vhci_driver.h @@ -13,7 +13,6 @@ #define USBIP_VHCI_BUS_TYPE "platform" #define USBIP_VHCI_DEVICE_NAME "vhci_hcd.0" -#define MAXNPORT 128 enum hub_speed { HUB_SPEED_HIGH = 0, @@ -41,7 +40,7 @@ struct usbip_vhci_driver { int ncontrollers; int nports; - struct usbip_imported_device idev[MAXNPORT]; + struct usbip_imported_device idev[]; }; -- 2.17.0
[PATCH v4] usbip: dynamically allocate idev by nports found in sysfs
As the amount of available ports varies by the kernels build configuration. To remove the limitation of the fixed 128 ports we allocate the amount of idevs by using the number we get from the kernel. Signed-off-by: Michael Grzeschik --- v1 -> v2: - reworked memory allocation into one calloc call - added error path on allocation failure v2 -> v3: - moved check for available nports to beginning of function v3 -> v4: - changed get_nports to get hc_device via parameter - moved calloc after valid get_nports call tools/usb/usbip/libsrc/vhci_driver.c | 32 +--- tools/usb/usbip/libsrc/vhci_driver.h | 3 +-- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index c9c81614a66ad..4204359c9feef 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -135,11 +135,11 @@ static int refresh_imported_device_list(void) return 0; } -static int get_nports(void) +static int get_nports(struct udev_device *hc_device) { const char *attr_nports; - attr_nports = udev_device_get_sysattr_value(vhci_driver->hc_device, "nports"); + attr_nports = udev_device_get_sysattr_value(hc_device, "nports"); if (!attr_nports) { err("udev_device_get_sysattr_value nports failed"); return -1; @@ -242,35 +242,41 @@ static int read_record(int rhport, char *host, unsigned long host_len, int usbip_vhci_driver_open(void) { + int nports; + struct udev_device *hc_device; + udev_context = udev_new(); if (!udev_context) { err("udev_new failed"); return -1; } - vhci_driver = calloc(1, sizeof(struct usbip_vhci_driver)); - /* will be freed in usbip_driver_close() */ - vhci_driver->hc_device = + hc_device = udev_device_new_from_subsystem_sysname(udev_context, USBIP_VHCI_BUS_TYPE, USBIP_VHCI_DEVICE_NAME); - if (!vhci_driver->hc_device) { + if (!hc_device) { err("udev_device_new_from_subsystem_sysname failed"); goto err; } - vhci_driver->nports = get_nports(); - dbg("available ports: %d", vhci_driver->nports); - - if (vhci_driver->nports <= 0) { + nports = get_nports(hc_device); + if (nports <= 0) { err("no available ports"); goto err; - } else if (vhci_driver->nports > MAXNPORT) { - err("port number exceeds %d", MAXNPORT); + } + dbg("available ports: %d", nports); + + vhci_driver = calloc(1, sizeof(struct usbip_vhci_driver) + + nports * sizeof(struct usbip_imported_device)); + if (!vhci_driver) { + err("vhci_driver allocation failed"); goto err; } + vhci_driver->nports = nports; + vhci_driver->hc_device = hc_device; vhci_driver->ncontrollers = get_ncontrollers(); dbg("available controllers: %d", vhci_driver->ncontrollers); @@ -285,7 +291,7 @@ int usbip_vhci_driver_open(void) return 0; err: - udev_device_unref(vhci_driver->hc_device); + udev_device_unref(hc_device); if (vhci_driver) free(vhci_driver); diff --git a/tools/usb/usbip/libsrc/vhci_driver.h b/tools/usb/usbip/libsrc/vhci_driver.h index 418b404d51210..6c9aca2167051 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.h +++ b/tools/usb/usbip/libsrc/vhci_driver.h @@ -13,7 +13,6 @@ #define USBIP_VHCI_BUS_TYPE "platform" #define USBIP_VHCI_DEVICE_NAME "vhci_hcd.0" -#define MAXNPORT 128 enum hub_speed { HUB_SPEED_HIGH = 0, @@ -41,7 +40,7 @@ struct usbip_vhci_driver { int ncontrollers; int nports; - struct usbip_imported_device idev[MAXNPORT]; + struct usbip_imported_device idev[]; }; -- 2.17.0
Re: [PATCH v3] usbip: dynamically allocate idev by nports found in sysfs
On Wed, May 23, 2018 at 10:44:57AM -0600, Shuah Khan wrote: > On 05/23/2018 03:22 AM, Michael Grzeschik wrote: > > As the amount of available ports varies by the kernels build > > configuration. To remove the limitation of the fixed 128 ports > > we allocate the amount of idevs by using the number we get > > from the kernel. > > > > Signed-off-by: Michael Grzeschik <m.grzesc...@pengutronix.de> > > --- > > v1 -> v2: - reworked memory allocation into one calloc call > > - added error path on allocation failure > > v2 -> v3: - moved check for available nports to beginning of function > > > > Hmm. With this patch I see a segfault when I run usbip port command. > I think this patch is incomplete and more changes are needed to the > code that references the idev array. > > I can't take this patch. I missed that get_nports depends on vhci_driver->hc_device which is not initialized that early. I will rework it to get the hc_device by parameter and send v4. Thanks, Michael -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | signature.asc Description: PGP signature
Re: [PATCH v3] usbip: dynamically allocate idev by nports found in sysfs
On Wed, May 23, 2018 at 10:44:57AM -0600, Shuah Khan wrote: > On 05/23/2018 03:22 AM, Michael Grzeschik wrote: > > As the amount of available ports varies by the kernels build > > configuration. To remove the limitation of the fixed 128 ports > > we allocate the amount of idevs by using the number we get > > from the kernel. > > > > Signed-off-by: Michael Grzeschik > > --- > > v1 -> v2: - reworked memory allocation into one calloc call > > - added error path on allocation failure > > v2 -> v3: - moved check for available nports to beginning of function > > > > Hmm. With this patch I see a segfault when I run usbip port command. > I think this patch is incomplete and more changes are needed to the > code that references the idev array. > > I can't take this patch. I missed that get_nports depends on vhci_driver->hc_device which is not initialized that early. I will rework it to get the hc_device by parameter and send v4. Thanks, Michael -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | signature.asc Description: PGP signature
Re: [PATCH v3] usbip: dynamically allocate idev by nports found in sysfs
On Wed, May 23, 2018 at 10:44:57AM -0600, Shuah Khan wrote: > On 05/23/2018 03:22 AM, Michael Grzeschik wrote: > > As the amount of available ports varies by the kernels build > > configuration. To remove the limitation of the fixed 128 ports > > we allocate the amount of idevs by using the number we get > > from the kernel. > > > > Signed-off-by: Michael Grzeschik <m.grzesc...@pengutronix.de> > > --- > > v1 -> v2: - reworked memory allocation into one calloc call > > - added error path on allocation failure > > v2 -> v3: - moved check for available nports to beginning of function > > > > Hmm. With this patch I see a segfault when I run usbip port command. > I think this patch is incomplete and more changes are needed to the > code that references the idev array. > > I can't take this patch. I will test it again tomorrow. Thanks, Michael -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | signature.asc Description: PGP signature
Re: [PATCH v3] usbip: dynamically allocate idev by nports found in sysfs
On Wed, May 23, 2018 at 10:44:57AM -0600, Shuah Khan wrote: > On 05/23/2018 03:22 AM, Michael Grzeschik wrote: > > As the amount of available ports varies by the kernels build > > configuration. To remove the limitation of the fixed 128 ports > > we allocate the amount of idevs by using the number we get > > from the kernel. > > > > Signed-off-by: Michael Grzeschik > > --- > > v1 -> v2: - reworked memory allocation into one calloc call > > - added error path on allocation failure > > v2 -> v3: - moved check for available nports to beginning of function > > > > Hmm. With this patch I see a segfault when I run usbip port command. > I think this patch is incomplete and more changes are needed to the > code that references the idev array. > > I can't take this patch. I will test it again tomorrow. Thanks, Michael -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | signature.asc Description: PGP signature
[PATCH v3] usbip: dynamically allocate idev by nports found in sysfs
As the amount of available ports varies by the kernels build configuration. To remove the limitation of the fixed 128 ports we allocate the amount of idevs by using the number we get from the kernel. Signed-off-by: Michael Grzeschik <m.grzesc...@pengutronix.de> --- v1 -> v2: - reworked memory allocation into one calloc call - added error path on allocation failure v2 -> v3: - moved check for available nports to beginning of function tools/usb/usbip/libsrc/vhci_driver.c | 24 ++-- tools/usb/usbip/libsrc/vhci_driver.h | 3 +-- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index c9c81614a66ad..c5db1be784bab 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -242,13 +242,25 @@ static int read_record(int rhport, char *host, unsigned long host_len, int usbip_vhci_driver_open(void) { + int nports = get_nports(); + + if (nports <= 0) { + err("no available ports"); + return -1; + } + udev_context = udev_new(); if (!udev_context) { err("udev_new failed"); return -1; } - vhci_driver = calloc(1, sizeof(struct usbip_vhci_driver)); + vhci_driver = calloc(1, sizeof(struct usbip_vhci_driver) + + nports * sizeof(struct usbip_imported_device)); + if (!vhci_driver) { + err("vhci_driver allocation failed"); + return -1; + } /* will be freed in usbip_driver_close() */ vhci_driver->hc_device = @@ -260,17 +272,9 @@ int usbip_vhci_driver_open(void) goto err; } - vhci_driver->nports = get_nports(); + vhci_driver->nports = nports; dbg("available ports: %d", vhci_driver->nports); - if (vhci_driver->nports <= 0) { - err("no available ports"); - goto err; - } else if (vhci_driver->nports > MAXNPORT) { - err("port number exceeds %d", MAXNPORT); - goto err; - } - vhci_driver->ncontrollers = get_ncontrollers(); dbg("available controllers: %d", vhci_driver->ncontrollers); diff --git a/tools/usb/usbip/libsrc/vhci_driver.h b/tools/usb/usbip/libsrc/vhci_driver.h index 418b404d51210..6c9aca2167051 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.h +++ b/tools/usb/usbip/libsrc/vhci_driver.h @@ -13,7 +13,6 @@ #define USBIP_VHCI_BUS_TYPE "platform" #define USBIP_VHCI_DEVICE_NAME "vhci_hcd.0" -#define MAXNPORT 128 enum hub_speed { HUB_SPEED_HIGH = 0, @@ -41,7 +40,7 @@ struct usbip_vhci_driver { int ncontrollers; int nports; - struct usbip_imported_device idev[MAXNPORT]; + struct usbip_imported_device idev[]; }; -- 2.17.0
[PATCH v3] usbip: dynamically allocate idev by nports found in sysfs
As the amount of available ports varies by the kernels build configuration. To remove the limitation of the fixed 128 ports we allocate the amount of idevs by using the number we get from the kernel. Signed-off-by: Michael Grzeschik --- v1 -> v2: - reworked memory allocation into one calloc call - added error path on allocation failure v2 -> v3: - moved check for available nports to beginning of function tools/usb/usbip/libsrc/vhci_driver.c | 24 ++-- tools/usb/usbip/libsrc/vhci_driver.h | 3 +-- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index c9c81614a66ad..c5db1be784bab 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -242,13 +242,25 @@ static int read_record(int rhport, char *host, unsigned long host_len, int usbip_vhci_driver_open(void) { + int nports = get_nports(); + + if (nports <= 0) { + err("no available ports"); + return -1; + } + udev_context = udev_new(); if (!udev_context) { err("udev_new failed"); return -1; } - vhci_driver = calloc(1, sizeof(struct usbip_vhci_driver)); + vhci_driver = calloc(1, sizeof(struct usbip_vhci_driver) + + nports * sizeof(struct usbip_imported_device)); + if (!vhci_driver) { + err("vhci_driver allocation failed"); + return -1; + } /* will be freed in usbip_driver_close() */ vhci_driver->hc_device = @@ -260,17 +272,9 @@ int usbip_vhci_driver_open(void) goto err; } - vhci_driver->nports = get_nports(); + vhci_driver->nports = nports; dbg("available ports: %d", vhci_driver->nports); - if (vhci_driver->nports <= 0) { - err("no available ports"); - goto err; - } else if (vhci_driver->nports > MAXNPORT) { - err("port number exceeds %d", MAXNPORT); - goto err; - } - vhci_driver->ncontrollers = get_ncontrollers(); dbg("available controllers: %d", vhci_driver->ncontrollers); diff --git a/tools/usb/usbip/libsrc/vhci_driver.h b/tools/usb/usbip/libsrc/vhci_driver.h index 418b404d51210..6c9aca2167051 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.h +++ b/tools/usb/usbip/libsrc/vhci_driver.h @@ -13,7 +13,6 @@ #define USBIP_VHCI_BUS_TYPE "platform" #define USBIP_VHCI_DEVICE_NAME "vhci_hcd.0" -#define MAXNPORT 128 enum hub_speed { HUB_SPEED_HIGH = 0, @@ -41,7 +40,7 @@ struct usbip_vhci_driver { int ncontrollers; int nports; - struct usbip_imported_device idev[MAXNPORT]; + struct usbip_imported_device idev[]; }; -- 2.17.0
[PATCH v2] usbip: dynamically allocate idev by nports found in sysfs
As the amount of available ports varies by the kernels build configuration. To remove the limitation of the fixed 128 ports we allocate the amount of idevs by using the number we get from the kernel. Signed-off-by: Michael Grzeschik <m.grzesc...@pengutronix.de> --- v1 -> v2: - reworked memory allocation into one calloc call - added error path on allocation failure tools/usb/usbip/libsrc/vhci_driver.c | 14 +- tools/usb/usbip/libsrc/vhci_driver.h | 3 +-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index c9c81614a66ad..6e2a9edfd1f0d 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -242,13 +242,20 @@ static int read_record(int rhport, char *host, unsigned long host_len, int usbip_vhci_driver_open(void) { + int nports = get_nports(); + udev_context = udev_new(); if (!udev_context) { err("udev_new failed"); return -1; } - vhci_driver = calloc(1, sizeof(struct usbip_vhci_driver)); + vhci_driver = calloc(1, sizeof(struct usbip_vhci_driver) + + nports * sizeof(struct usbip_imported_device)); + if (!vhci_driver) { + err("vhci_driver allocation failed"); + return -1; + } /* will be freed in usbip_driver_close() */ vhci_driver->hc_device = @@ -260,15 +267,12 @@ int usbip_vhci_driver_open(void) goto err; } - vhci_driver->nports = get_nports(); + vhci_driver->nports = nports; dbg("available ports: %d", vhci_driver->nports); if (vhci_driver->nports <= 0) { err("no available ports"); goto err; - } else if (vhci_driver->nports > MAXNPORT) { - err("port number exceeds %d", MAXNPORT); - goto err; } vhci_driver->ncontrollers = get_ncontrollers(); diff --git a/tools/usb/usbip/libsrc/vhci_driver.h b/tools/usb/usbip/libsrc/vhci_driver.h index 418b404d51210..6c9aca2167051 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.h +++ b/tools/usb/usbip/libsrc/vhci_driver.h @@ -13,7 +13,6 @@ #define USBIP_VHCI_BUS_TYPE "platform" #define USBIP_VHCI_DEVICE_NAME "vhci_hcd.0" -#define MAXNPORT 128 enum hub_speed { HUB_SPEED_HIGH = 0, @@ -41,7 +40,7 @@ struct usbip_vhci_driver { int ncontrollers; int nports; - struct usbip_imported_device idev[MAXNPORT]; + struct usbip_imported_device idev[]; }; -- 2.17.0
[PATCH v2] usbip: dynamically allocate idev by nports found in sysfs
As the amount of available ports varies by the kernels build configuration. To remove the limitation of the fixed 128 ports we allocate the amount of idevs by using the number we get from the kernel. Signed-off-by: Michael Grzeschik --- v1 -> v2: - reworked memory allocation into one calloc call - added error path on allocation failure tools/usb/usbip/libsrc/vhci_driver.c | 14 +- tools/usb/usbip/libsrc/vhci_driver.h | 3 +-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index c9c81614a66ad..6e2a9edfd1f0d 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -242,13 +242,20 @@ static int read_record(int rhport, char *host, unsigned long host_len, int usbip_vhci_driver_open(void) { + int nports = get_nports(); + udev_context = udev_new(); if (!udev_context) { err("udev_new failed"); return -1; } - vhci_driver = calloc(1, sizeof(struct usbip_vhci_driver)); + vhci_driver = calloc(1, sizeof(struct usbip_vhci_driver) + + nports * sizeof(struct usbip_imported_device)); + if (!vhci_driver) { + err("vhci_driver allocation failed"); + return -1; + } /* will be freed in usbip_driver_close() */ vhci_driver->hc_device = @@ -260,15 +267,12 @@ int usbip_vhci_driver_open(void) goto err; } - vhci_driver->nports = get_nports(); + vhci_driver->nports = nports; dbg("available ports: %d", vhci_driver->nports); if (vhci_driver->nports <= 0) { err("no available ports"); goto err; - } else if (vhci_driver->nports > MAXNPORT) { - err("port number exceeds %d", MAXNPORT); - goto err; } vhci_driver->ncontrollers = get_ncontrollers(); diff --git a/tools/usb/usbip/libsrc/vhci_driver.h b/tools/usb/usbip/libsrc/vhci_driver.h index 418b404d51210..6c9aca2167051 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.h +++ b/tools/usb/usbip/libsrc/vhci_driver.h @@ -13,7 +13,6 @@ #define USBIP_VHCI_BUS_TYPE "platform" #define USBIP_VHCI_DEVICE_NAME "vhci_hcd.0" -#define MAXNPORT 128 enum hub_speed { HUB_SPEED_HIGH = 0, @@ -41,7 +40,7 @@ struct usbip_vhci_driver { int ncontrollers; int nports; - struct usbip_imported_device idev[MAXNPORT]; + struct usbip_imported_device idev[]; }; -- 2.17.0
[PATCH] usbip: dynamically allocate idev by nports found in sysfs
As the amount of available ports varies by the kernels build configuration. To remove the limitation of the fixed 128 ports we allocate the amount of idevs by using the number we get from the kernel. Signed-off-by: Michael Grzeschik <m.grzesc...@pengutronix.de> --- tools/usb/usbip/libsrc/vhci_driver.c | 11 --- tools/usb/usbip/libsrc/vhci_driver.h | 3 +-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index c9c81614a66ad..9a8acfc7697fa 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -266,11 +266,11 @@ int usbip_vhci_driver_open(void) if (vhci_driver->nports <= 0) { err("no available ports"); goto err; - } else if (vhci_driver->nports > MAXNPORT) { - err("port number exceeds %d", MAXNPORT); - goto err; } + vhci_driver->idev = calloc(vhci_driver->nports, + sizeof(struct usbip_imported_device)); + vhci_driver->ncontrollers = get_ncontrollers(); dbg("available controllers: %d", vhci_driver->ncontrollers); @@ -287,6 +287,9 @@ int usbip_vhci_driver_open(void) err: udev_device_unref(vhci_driver->hc_device); + if (vhci_driver->idev) + free(vhci_driver->idev); + if (vhci_driver) free(vhci_driver); @@ -305,6 +308,8 @@ void usbip_vhci_driver_close(void) udev_device_unref(vhci_driver->hc_device); + free(vhci_driver->idev); + free(vhci_driver); vhci_driver = NULL; diff --git a/tools/usb/usbip/libsrc/vhci_driver.h b/tools/usb/usbip/libsrc/vhci_driver.h index 418b404d51210..67dbd1551e159 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.h +++ b/tools/usb/usbip/libsrc/vhci_driver.h @@ -13,7 +13,6 @@ #define USBIP_VHCI_BUS_TYPE "platform" #define USBIP_VHCI_DEVICE_NAME "vhci_hcd.0" -#define MAXNPORT 128 enum hub_speed { HUB_SPEED_HIGH = 0, @@ -41,7 +40,7 @@ struct usbip_vhci_driver { int ncontrollers; int nports; - struct usbip_imported_device idev[MAXNPORT]; + struct usbip_imported_device *idev; }; -- 2.17.0
[PATCH] usbip: dynamically allocate idev by nports found in sysfs
As the amount of available ports varies by the kernels build configuration. To remove the limitation of the fixed 128 ports we allocate the amount of idevs by using the number we get from the kernel. Signed-off-by: Michael Grzeschik --- tools/usb/usbip/libsrc/vhci_driver.c | 11 --- tools/usb/usbip/libsrc/vhci_driver.h | 3 +-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index c9c81614a66ad..9a8acfc7697fa 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -266,11 +266,11 @@ int usbip_vhci_driver_open(void) if (vhci_driver->nports <= 0) { err("no available ports"); goto err; - } else if (vhci_driver->nports > MAXNPORT) { - err("port number exceeds %d", MAXNPORT); - goto err; } + vhci_driver->idev = calloc(vhci_driver->nports, + sizeof(struct usbip_imported_device)); + vhci_driver->ncontrollers = get_ncontrollers(); dbg("available controllers: %d", vhci_driver->ncontrollers); @@ -287,6 +287,9 @@ int usbip_vhci_driver_open(void) err: udev_device_unref(vhci_driver->hc_device); + if (vhci_driver->idev) + free(vhci_driver->idev); + if (vhci_driver) free(vhci_driver); @@ -305,6 +308,8 @@ void usbip_vhci_driver_close(void) udev_device_unref(vhci_driver->hc_device); + free(vhci_driver->idev); + free(vhci_driver); vhci_driver = NULL; diff --git a/tools/usb/usbip/libsrc/vhci_driver.h b/tools/usb/usbip/libsrc/vhci_driver.h index 418b404d51210..67dbd1551e159 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.h +++ b/tools/usb/usbip/libsrc/vhci_driver.h @@ -13,7 +13,6 @@ #define USBIP_VHCI_BUS_TYPE "platform" #define USBIP_VHCI_DEVICE_NAME "vhci_hcd.0" -#define MAXNPORT 128 enum hub_speed { HUB_SPEED_HIGH = 0, @@ -41,7 +40,7 @@ struct usbip_vhci_driver { int ncontrollers; int nports; - struct usbip_imported_device idev[MAXNPORT]; + struct usbip_imported_device *idev; }; -- 2.17.0
[PATCH] gpu: ipu-csi: add rgb/bgr888 24bit support to mbus_code_to_bus_cfg
The 24bit RGB format configuration is currently missing, we add it now. Signed-off-by: Michael Grzeschik <m.grzesc...@pengutronix.de> --- drivers/gpu/ipu-v3/ipu-csi.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/ipu-v3/ipu-csi.c b/drivers/gpu/ipu-v3/ipu-csi.c index caa05b0702e16..1a0ee65fd4859 100644 --- a/drivers/gpu/ipu-v3/ipu-csi.c +++ b/drivers/gpu/ipu-v3/ipu-csi.c @@ -247,6 +247,12 @@ static int mbus_code_to_bus_cfg(struct ipu_csi_bus_config *cfg, u32 mbus_code) cfg->mipi_dt = MIPI_DT_RGB555; cfg->data_width = IPU_CSI_DATA_WIDTH_8; break; + case MEDIA_BUS_FMT_RGB888_1X24: + case MEDIA_BUS_FMT_BGR888_1X24: + cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_RGB_YUV444; + cfg->mipi_dt = MIPI_DT_RGB888; + cfg->data_width = IPU_CSI_DATA_WIDTH_8; + break; case MEDIA_BUS_FMT_UYVY8_2X8: cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_YUV422_UYVY; cfg->mipi_dt = MIPI_DT_YUV422; -- 2.17.0
[PATCH] gpu: ipu-csi: add rgb/bgr888 24bit support to mbus_code_to_bus_cfg
The 24bit RGB format configuration is currently missing, we add it now. Signed-off-by: Michael Grzeschik --- drivers/gpu/ipu-v3/ipu-csi.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/ipu-v3/ipu-csi.c b/drivers/gpu/ipu-v3/ipu-csi.c index caa05b0702e16..1a0ee65fd4859 100644 --- a/drivers/gpu/ipu-v3/ipu-csi.c +++ b/drivers/gpu/ipu-v3/ipu-csi.c @@ -247,6 +247,12 @@ static int mbus_code_to_bus_cfg(struct ipu_csi_bus_config *cfg, u32 mbus_code) cfg->mipi_dt = MIPI_DT_RGB555; cfg->data_width = IPU_CSI_DATA_WIDTH_8; break; + case MEDIA_BUS_FMT_RGB888_1X24: + case MEDIA_BUS_FMT_BGR888_1X24: + cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_RGB_YUV444; + cfg->mipi_dt = MIPI_DT_RGB888; + cfg->data_width = IPU_CSI_DATA_WIDTH_8; + break; case MEDIA_BUS_FMT_UYVY8_2X8: cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_YUV422_UYVY; cfg->mipi_dt = MIPI_DT_YUV422; -- 2.17.0
Re: [PATCH 4/4] rtc: isl1208: add support for isl1219 with hwmon for tamper detection
On Wed, Jan 24, 2018 at 10:03:33AM +0100, Michael Grzeschik wrote: > On Tue, Jan 23, 2018 at 10:22:54AM -0800, Guenter Roeck wrote: > > On Tue, Jan 23, 2018 at 01:18:01PM +0100, Michael Grzeschik wrote: > > > We add support for the ISL1219 chip that got an integrated tamper > > > detection function. This patch implements the feature by using an hwmon > > > interface. > > > > > > The ISL1219 can also describe the timestamp of the intrusion > > > event. For this we add the documentation of the new interface > > > intrusion[0-*]_timestamp. > > > > > > The devicetree documentation for the ISL1219 device tree > > > binding is added with an short example. > > > > > > Signed-off-by: Michael Grzeschik <m.grzesc...@pengutronix.de> > > > Signed-off-by: Denis Osterland <denis.osterl...@diehl.com> > > > --- > > > .../rtc/{intersil,isl1208.txt => isil,isl1208.txt} | 18 +- > > > Documentation/hwmon/sysfs-interface| 7 + > > > drivers/rtc/rtc-isl1208.c | 190 > > > +++-- > > > 3 files changed, 201 insertions(+), 14 deletions(-) > > > rename Documentation/devicetree/bindings/rtc/{intersil,isl1208.txt => > > > isil,isl1208.txt} (57%) > > > > > > diff --git a/Documentation/devicetree/bindings/rtc/intersil,isl1208.txt > > > b/Documentation/devicetree/bindings/rtc/isil,isl1208.txt > > > similarity index 57% > > > rename from Documentation/devicetree/bindings/rtc/intersil,isl1208.txt > > > rename to Documentation/devicetree/bindings/rtc/isil,isl1208.txt > > > index a54e99feae1ca..d549699e1cfc4 100644 > > > --- a/Documentation/devicetree/bindings/rtc/intersil,isl1208.txt > > > +++ b/Documentation/devicetree/bindings/rtc/isil,isl1208.txt > > > @@ -1,14 +1,21 @@ > > > -Intersil ISL1208, ISL1218 I2C RTC/Alarm chip > > > +Intersil ISL1208, ISL1218, ISL1219 I2C RTC/Alarm chip > > > > > > ISL1208 is a trivial I2C device (it has simple device tree bindings, > > > consisting of a compatible field, an address and possibly an interrupt > > > line). > > > > > > +ISL1219 supports tamper detection user space representation through > > > +case intrusion hwmon sensor. > > > +ISL1219 has additional pins EVIN and #EVDET for tamper detection. > > > +I2C devices support only one irq. #IRQ and #EVDET are open-drain active > > > low, > > > +so it is possible layout them to one SoC pin with pull-up. > > > + > > > Required properties supported by the device: > > > > > > - "compatible": must be one of > > > "isil,isl1208" > > > "isil,isl1218" > > > + "isil,isl1219" > > > - "reg": I2C bus address of the device > > > > > > Optional properties: > > > @@ -33,3 +40,12 @@ Example isl1208 node with #IRQ pin connected to SoC > > > gpio1 pin 12: > > > interrupt-parent = <>; > > > interrupts = <12 IRQ_TYPE_EDGE_FALLING>; > > > }; > > > + > > > +Example isl1219 node with #IRQ pin and #EVDET pin connected to SoC gpio1 > > > pin 12: > > > + > > > + isl1219: isl1219@68 { > > > + compatible = "intersil,isl1219"; > > > + reg = <0x68>; > > > + interrupts-extended = < 12 IRQ_TYPE_EDGE_FALLING>; > > > + }; > > > + > > > diff --git a/Documentation/hwmon/sysfs-interface > > > b/Documentation/hwmon/sysfs-interface > > > index fc337c317c673..a12b3c2b2a18c 100644 > > > --- a/Documentation/hwmon/sysfs-interface > > > +++ b/Documentation/hwmon/sysfs-interface > > > @@ -702,6 +702,13 @@ intrusion[0-*]_alarm > > > the user. This is done by writing 0 to the file. Writing > > > other values is unsupported. > > > > > > +intrusion[0-*]_timestamp > > > + Chassis intrusion detection > > > + -MM-DD HH:MM:SS UTC (ts.sec): intrusion detected > > > + RO > > > + The corresponding timestamp on which the intrustion > > > + was detected. > > > + > > > > Sneaky. Nack. You don't just add attributes to the ABI because you want it, > > without serious discussion, and much less so hidden in an RTC driver > > (and even less as unparseable attribute). > > Right; but it was not meant to be sneaky. I s
Re: [PATCH 4/4] rtc: isl1208: add support for isl1219 with hwmon for tamper detection
On Wed, Jan 24, 2018 at 10:03:33AM +0100, Michael Grzeschik wrote: > On Tue, Jan 23, 2018 at 10:22:54AM -0800, Guenter Roeck wrote: > > On Tue, Jan 23, 2018 at 01:18:01PM +0100, Michael Grzeschik wrote: > > > We add support for the ISL1219 chip that got an integrated tamper > > > detection function. This patch implements the feature by using an hwmon > > > interface. > > > > > > The ISL1219 can also describe the timestamp of the intrusion > > > event. For this we add the documentation of the new interface > > > intrusion[0-*]_timestamp. > > > > > > The devicetree documentation for the ISL1219 device tree > > > binding is added with an short example. > > > > > > Signed-off-by: Michael Grzeschik > > > Signed-off-by: Denis Osterland > > > --- > > > .../rtc/{intersil,isl1208.txt => isil,isl1208.txt} | 18 +- > > > Documentation/hwmon/sysfs-interface| 7 + > > > drivers/rtc/rtc-isl1208.c | 190 > > > +++-- > > > 3 files changed, 201 insertions(+), 14 deletions(-) > > > rename Documentation/devicetree/bindings/rtc/{intersil,isl1208.txt => > > > isil,isl1208.txt} (57%) > > > > > > diff --git a/Documentation/devicetree/bindings/rtc/intersil,isl1208.txt > > > b/Documentation/devicetree/bindings/rtc/isil,isl1208.txt > > > similarity index 57% > > > rename from Documentation/devicetree/bindings/rtc/intersil,isl1208.txt > > > rename to Documentation/devicetree/bindings/rtc/isil,isl1208.txt > > > index a54e99feae1ca..d549699e1cfc4 100644 > > > --- a/Documentation/devicetree/bindings/rtc/intersil,isl1208.txt > > > +++ b/Documentation/devicetree/bindings/rtc/isil,isl1208.txt > > > @@ -1,14 +1,21 @@ > > > -Intersil ISL1208, ISL1218 I2C RTC/Alarm chip > > > +Intersil ISL1208, ISL1218, ISL1219 I2C RTC/Alarm chip > > > > > > ISL1208 is a trivial I2C device (it has simple device tree bindings, > > > consisting of a compatible field, an address and possibly an interrupt > > > line). > > > > > > +ISL1219 supports tamper detection user space representation through > > > +case intrusion hwmon sensor. > > > +ISL1219 has additional pins EVIN and #EVDET for tamper detection. > > > +I2C devices support only one irq. #IRQ and #EVDET are open-drain active > > > low, > > > +so it is possible layout them to one SoC pin with pull-up. > > > + > > > Required properties supported by the device: > > > > > > - "compatible": must be one of > > > "isil,isl1208" > > > "isil,isl1218" > > > + "isil,isl1219" > > > - "reg": I2C bus address of the device > > > > > > Optional properties: > > > @@ -33,3 +40,12 @@ Example isl1208 node with #IRQ pin connected to SoC > > > gpio1 pin 12: > > > interrupt-parent = <>; > > > interrupts = <12 IRQ_TYPE_EDGE_FALLING>; > > > }; > > > + > > > +Example isl1219 node with #IRQ pin and #EVDET pin connected to SoC gpio1 > > > pin 12: > > > + > > > + isl1219: isl1219@68 { > > > + compatible = "intersil,isl1219"; > > > + reg = <0x68>; > > > + interrupts-extended = < 12 IRQ_TYPE_EDGE_FALLING>; > > > + }; > > > + > > > diff --git a/Documentation/hwmon/sysfs-interface > > > b/Documentation/hwmon/sysfs-interface > > > index fc337c317c673..a12b3c2b2a18c 100644 > > > --- a/Documentation/hwmon/sysfs-interface > > > +++ b/Documentation/hwmon/sysfs-interface > > > @@ -702,6 +702,13 @@ intrusion[0-*]_alarm > > > the user. This is done by writing 0 to the file. Writing > > > other values is unsupported. > > > > > > +intrusion[0-*]_timestamp > > > + Chassis intrusion detection > > > + -MM-DD HH:MM:SS UTC (ts.sec): intrusion detected > > > + RO > > > + The corresponding timestamp on which the intrustion > > > + was detected. > > > + > > > > Sneaky. Nack. You don't just add attributes to the ABI because you want it, > > without serious discussion, and much less so hidden in an RTC driver > > (and even less as unparseable attribute). > > Right; but it was not meant to be sneaky. I should have stick to my first > thought and label this patch RFC. S
Re: [PATCH 4/4] rtc: isl1208: add support for isl1219 with hwmon for tamper detection
On Tue, Jan 23, 2018 at 10:22:54AM -0800, Guenter Roeck wrote: > On Tue, Jan 23, 2018 at 01:18:01PM +0100, Michael Grzeschik wrote: > > We add support for the ISL1219 chip that got an integrated tamper > > detection function. This patch implements the feature by using an hwmon > > interface. > > > > The ISL1219 can also describe the timestamp of the intrusion > > event. For this we add the documentation of the new interface > > intrusion[0-*]_timestamp. > > > > The devicetree documentation for the ISL1219 device tree > > binding is added with an short example. > > > > Signed-off-by: Michael Grzeschik <m.grzesc...@pengutronix.de> > > Signed-off-by: Denis Osterland <denis.osterl...@diehl.com> > > --- > > .../rtc/{intersil,isl1208.txt => isil,isl1208.txt} | 18 +- > > Documentation/hwmon/sysfs-interface| 7 + > > drivers/rtc/rtc-isl1208.c | 190 > > +++-- > > 3 files changed, 201 insertions(+), 14 deletions(-) > > rename Documentation/devicetree/bindings/rtc/{intersil,isl1208.txt => > > isil,isl1208.txt} (57%) > > > > diff --git a/Documentation/devicetree/bindings/rtc/intersil,isl1208.txt > > b/Documentation/devicetree/bindings/rtc/isil,isl1208.txt > > similarity index 57% > > rename from Documentation/devicetree/bindings/rtc/intersil,isl1208.txt > > rename to Documentation/devicetree/bindings/rtc/isil,isl1208.txt > > index a54e99feae1ca..d549699e1cfc4 100644 > > --- a/Documentation/devicetree/bindings/rtc/intersil,isl1208.txt > > +++ b/Documentation/devicetree/bindings/rtc/isil,isl1208.txt > > @@ -1,14 +1,21 @@ > > -Intersil ISL1208, ISL1218 I2C RTC/Alarm chip > > +Intersil ISL1208, ISL1218, ISL1219 I2C RTC/Alarm chip > > > > ISL1208 is a trivial I2C device (it has simple device tree bindings, > > consisting of a compatible field, an address and possibly an interrupt > > line). > > > > +ISL1219 supports tamper detection user space representation through > > +case intrusion hwmon sensor. > > +ISL1219 has additional pins EVIN and #EVDET for tamper detection. > > +I2C devices support only one irq. #IRQ and #EVDET are open-drain active > > low, > > +so it is possible layout them to one SoC pin with pull-up. > > + > > Required properties supported by the device: > > > > - "compatible": must be one of > > "isil,isl1208" > > "isil,isl1218" > > + "isil,isl1219" > > - "reg": I2C bus address of the device > > > > Optional properties: > > @@ -33,3 +40,12 @@ Example isl1208 node with #IRQ pin connected to SoC > > gpio1 pin 12: > > interrupt-parent = <>; > > interrupts = <12 IRQ_TYPE_EDGE_FALLING>; > > }; > > + > > +Example isl1219 node with #IRQ pin and #EVDET pin connected to SoC gpio1 > > pin 12: > > + > > + isl1219: isl1219@68 { > > + compatible = "intersil,isl1219"; > > + reg = <0x68>; > > + interrupts-extended = < 12 IRQ_TYPE_EDGE_FALLING>; > > + }; > > + > > diff --git a/Documentation/hwmon/sysfs-interface > > b/Documentation/hwmon/sysfs-interface > > index fc337c317c673..a12b3c2b2a18c 100644 > > --- a/Documentation/hwmon/sysfs-interface > > +++ b/Documentation/hwmon/sysfs-interface > > @@ -702,6 +702,13 @@ intrusion[0-*]_alarm > > the user. This is done by writing 0 to the file. Writing > > other values is unsupported. > > > > +intrusion[0-*]_timestamp > > + Chassis intrusion detection > > + -MM-DD HH:MM:SS UTC (ts.sec): intrusion detected > > + RO > > + The corresponding timestamp on which the intrustion > > + was detected. > > + > > Sneaky. Nack. You don't just add attributes to the ABI because you want it, > without serious discussion, and much less so hidden in an RTC driver > (and even less as unparseable attribute). Right; but it was not meant to be sneaky. I should have stick to my first thought and label this patch RFC. Sorry for that. > In addition to that, I consider the attribute unnecessary. The intrusion > already generates an event which should be sufficient for all practical > purposes. Would it make sense in between the other sysfs attributes of this driver? Thanks, Michael > > intrusion[0-*]_beep > > Chassis intrusion beep > > 0: disable > > diff --git a/drivers/rtc/rtc-is
Re: [PATCH 4/4] rtc: isl1208: add support for isl1219 with hwmon for tamper detection
On Tue, Jan 23, 2018 at 10:22:54AM -0800, Guenter Roeck wrote: > On Tue, Jan 23, 2018 at 01:18:01PM +0100, Michael Grzeschik wrote: > > We add support for the ISL1219 chip that got an integrated tamper > > detection function. This patch implements the feature by using an hwmon > > interface. > > > > The ISL1219 can also describe the timestamp of the intrusion > > event. For this we add the documentation of the new interface > > intrusion[0-*]_timestamp. > > > > The devicetree documentation for the ISL1219 device tree > > binding is added with an short example. > > > > Signed-off-by: Michael Grzeschik > > Signed-off-by: Denis Osterland > > --- > > .../rtc/{intersil,isl1208.txt => isil,isl1208.txt} | 18 +- > > Documentation/hwmon/sysfs-interface| 7 + > > drivers/rtc/rtc-isl1208.c | 190 > > +++-- > > 3 files changed, 201 insertions(+), 14 deletions(-) > > rename Documentation/devicetree/bindings/rtc/{intersil,isl1208.txt => > > isil,isl1208.txt} (57%) > > > > diff --git a/Documentation/devicetree/bindings/rtc/intersil,isl1208.txt > > b/Documentation/devicetree/bindings/rtc/isil,isl1208.txt > > similarity index 57% > > rename from Documentation/devicetree/bindings/rtc/intersil,isl1208.txt > > rename to Documentation/devicetree/bindings/rtc/isil,isl1208.txt > > index a54e99feae1ca..d549699e1cfc4 100644 > > --- a/Documentation/devicetree/bindings/rtc/intersil,isl1208.txt > > +++ b/Documentation/devicetree/bindings/rtc/isil,isl1208.txt > > @@ -1,14 +1,21 @@ > > -Intersil ISL1208, ISL1218 I2C RTC/Alarm chip > > +Intersil ISL1208, ISL1218, ISL1219 I2C RTC/Alarm chip > > > > ISL1208 is a trivial I2C device (it has simple device tree bindings, > > consisting of a compatible field, an address and possibly an interrupt > > line). > > > > +ISL1219 supports tamper detection user space representation through > > +case intrusion hwmon sensor. > > +ISL1219 has additional pins EVIN and #EVDET for tamper detection. > > +I2C devices support only one irq. #IRQ and #EVDET are open-drain active > > low, > > +so it is possible layout them to one SoC pin with pull-up. > > + > > Required properties supported by the device: > > > > - "compatible": must be one of > > "isil,isl1208" > > "isil,isl1218" > > + "isil,isl1219" > > - "reg": I2C bus address of the device > > > > Optional properties: > > @@ -33,3 +40,12 @@ Example isl1208 node with #IRQ pin connected to SoC > > gpio1 pin 12: > > interrupt-parent = <>; > > interrupts = <12 IRQ_TYPE_EDGE_FALLING>; > > }; > > + > > +Example isl1219 node with #IRQ pin and #EVDET pin connected to SoC gpio1 > > pin 12: > > + > > + isl1219: isl1219@68 { > > + compatible = "intersil,isl1219"; > > + reg = <0x68>; > > + interrupts-extended = < 12 IRQ_TYPE_EDGE_FALLING>; > > + }; > > + > > diff --git a/Documentation/hwmon/sysfs-interface > > b/Documentation/hwmon/sysfs-interface > > index fc337c317c673..a12b3c2b2a18c 100644 > > --- a/Documentation/hwmon/sysfs-interface > > +++ b/Documentation/hwmon/sysfs-interface > > @@ -702,6 +702,13 @@ intrusion[0-*]_alarm > > the user. This is done by writing 0 to the file. Writing > > other values is unsupported. > > > > +intrusion[0-*]_timestamp > > + Chassis intrusion detection > > + -MM-DD HH:MM:SS UTC (ts.sec): intrusion detected > > + RO > > + The corresponding timestamp on which the intrustion > > + was detected. > > + > > Sneaky. Nack. You don't just add attributes to the ABI because you want it, > without serious discussion, and much less so hidden in an RTC driver > (and even less as unparseable attribute). Right; but it was not meant to be sneaky. I should have stick to my first thought and label this patch RFC. Sorry for that. > In addition to that, I consider the attribute unnecessary. The intrusion > already generates an event which should be sufficient for all practical > purposes. Would it make sense in between the other sysfs attributes of this driver? Thanks, Michael > > intrusion[0-*]_beep > > Chassis intrusion beep > > 0: disable > > diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c > > index a13a4ba79004d..6e4d246
[PATCH 4/4] rtc: isl1208: add support for isl1219 with hwmon for tamper detection
We add support for the ISL1219 chip that got an integrated tamper detection function. This patch implements the feature by using an hwmon interface. The ISL1219 can also describe the timestamp of the intrusion event. For this we add the documentation of the new interface intrusion[0-*]_timestamp. The devicetree documentation for the ISL1219 device tree binding is added with an short example. Signed-off-by: Michael Grzeschik <m.grzesc...@pengutronix.de> Signed-off-by: Denis Osterland <denis.osterl...@diehl.com> --- .../rtc/{intersil,isl1208.txt => isil,isl1208.txt} | 18 +- Documentation/hwmon/sysfs-interface| 7 + drivers/rtc/rtc-isl1208.c | 190 +++-- 3 files changed, 201 insertions(+), 14 deletions(-) rename Documentation/devicetree/bindings/rtc/{intersil,isl1208.txt => isil,isl1208.txt} (57%) diff --git a/Documentation/devicetree/bindings/rtc/intersil,isl1208.txt b/Documentation/devicetree/bindings/rtc/isil,isl1208.txt similarity index 57% rename from Documentation/devicetree/bindings/rtc/intersil,isl1208.txt rename to Documentation/devicetree/bindings/rtc/isil,isl1208.txt index a54e99feae1ca..d549699e1cfc4 100644 --- a/Documentation/devicetree/bindings/rtc/intersil,isl1208.txt +++ b/Documentation/devicetree/bindings/rtc/isil,isl1208.txt @@ -1,14 +1,21 @@ -Intersil ISL1208, ISL1218 I2C RTC/Alarm chip +Intersil ISL1208, ISL1218, ISL1219 I2C RTC/Alarm chip ISL1208 is a trivial I2C device (it has simple device tree bindings, consisting of a compatible field, an address and possibly an interrupt line). +ISL1219 supports tamper detection user space representation through +case intrusion hwmon sensor. +ISL1219 has additional pins EVIN and #EVDET for tamper detection. +I2C devices support only one irq. #IRQ and #EVDET are open-drain active low, +so it is possible layout them to one SoC pin with pull-up. + Required properties supported by the device: - "compatible": must be one of "isil,isl1208" "isil,isl1218" + "isil,isl1219" - "reg": I2C bus address of the device Optional properties: @@ -33,3 +40,12 @@ Example isl1208 node with #IRQ pin connected to SoC gpio1 pin 12: interrupt-parent = <>; interrupts = <12 IRQ_TYPE_EDGE_FALLING>; }; + +Example isl1219 node with #IRQ pin and #EVDET pin connected to SoC gpio1 pin 12: + + isl1219: isl1219@68 { + compatible = "intersil,isl1219"; + reg = <0x68>; + interrupts-extended = < 12 IRQ_TYPE_EDGE_FALLING>; + }; + diff --git a/Documentation/hwmon/sysfs-interface b/Documentation/hwmon/sysfs-interface index fc337c317c673..a12b3c2b2a18c 100644 --- a/Documentation/hwmon/sysfs-interface +++ b/Documentation/hwmon/sysfs-interface @@ -702,6 +702,13 @@ intrusion[0-*]_alarm the user. This is done by writing 0 to the file. Writing other values is unsupported. +intrusion[0-*]_timestamp + Chassis intrusion detection + -MM-DD HH:MM:SS UTC (ts.sec): intrusion detected + RO + The corresponding timestamp on which the intrustion + was detected. + intrusion[0-*]_beep Chassis intrusion beep 0: disable diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c index a13a4ba79004d..6e4d24614d98b 100644 --- a/drivers/rtc/rtc-isl1208.c +++ b/drivers/rtc/rtc-isl1208.c @@ -14,6 +14,8 @@ #include #include #include +#include +#include /* Register map */ /* rtc section */ @@ -33,6 +35,7 @@ #define ISL1208_REG_SR_ARST(1<<7) /* auto reset */ #define ISL1208_REG_SR_XTOSCB (1<<6) /* crystal oscillator */ #define ISL1208_REG_SR_WRTC(1<<4) /* write rtc */ +#define ISL1208_REG_SR_EVT (1<<3) /* event */ #define ISL1208_REG_SR_ALM (1<<2) /* alarm */ #define ISL1208_REG_SR_BAT (1<<1) /* battery */ #define ISL1208_REG_SR_RTCF(1<<0) /* rtc fail */ @@ -57,8 +60,29 @@ #define ISL1208_REG_USR2 0x13 #define ISL1208_USR_SECTION_LEN 2 +/* event section */ +#define ISL1208_REG_SCT 0x14 +#define ISL1208_REG_MNT 0x15 +#define ISL1208_REG_HRT 0x16 +#define ISL1208_REG_DTT 0x17 +#define ISL1208_REG_MOT 0x18 +#define ISL1208_REG_YRT 0x19 +#define ISL1208_EVT_SECTION_LEN 6 + static struct i2c_driver isl1208_driver; +/* ISL1208 various variants */ +enum { + TYPE_ISL1208 = 0, + TYPE_ISL1218, + TYPE_ISL1219, +}; + +struct isl1208 { + struct rtc_device *rtc; + struct device *hwmon; +}; + /* block read */ static int isl1208_i2c_read_regs(struct i2c_client *client, u8 reg, u8 buf[], @@ -80,8 +104,8 @@ isl1208_i2c_read_regs(struct i2c_client *client, u8 reg, u8 buf[], }; int ret; - BUG_ON(reg > ISL1208_REG_USR2); -
[PATCH 4/4] rtc: isl1208: add support for isl1219 with hwmon for tamper detection
We add support for the ISL1219 chip that got an integrated tamper detection function. This patch implements the feature by using an hwmon interface. The ISL1219 can also describe the timestamp of the intrusion event. For this we add the documentation of the new interface intrusion[0-*]_timestamp. The devicetree documentation for the ISL1219 device tree binding is added with an short example. Signed-off-by: Michael Grzeschik Signed-off-by: Denis Osterland --- .../rtc/{intersil,isl1208.txt => isil,isl1208.txt} | 18 +- Documentation/hwmon/sysfs-interface| 7 + drivers/rtc/rtc-isl1208.c | 190 +++-- 3 files changed, 201 insertions(+), 14 deletions(-) rename Documentation/devicetree/bindings/rtc/{intersil,isl1208.txt => isil,isl1208.txt} (57%) diff --git a/Documentation/devicetree/bindings/rtc/intersil,isl1208.txt b/Documentation/devicetree/bindings/rtc/isil,isl1208.txt similarity index 57% rename from Documentation/devicetree/bindings/rtc/intersil,isl1208.txt rename to Documentation/devicetree/bindings/rtc/isil,isl1208.txt index a54e99feae1ca..d549699e1cfc4 100644 --- a/Documentation/devicetree/bindings/rtc/intersil,isl1208.txt +++ b/Documentation/devicetree/bindings/rtc/isil,isl1208.txt @@ -1,14 +1,21 @@ -Intersil ISL1208, ISL1218 I2C RTC/Alarm chip +Intersil ISL1208, ISL1218, ISL1219 I2C RTC/Alarm chip ISL1208 is a trivial I2C device (it has simple device tree bindings, consisting of a compatible field, an address and possibly an interrupt line). +ISL1219 supports tamper detection user space representation through +case intrusion hwmon sensor. +ISL1219 has additional pins EVIN and #EVDET for tamper detection. +I2C devices support only one irq. #IRQ and #EVDET are open-drain active low, +so it is possible layout them to one SoC pin with pull-up. + Required properties supported by the device: - "compatible": must be one of "isil,isl1208" "isil,isl1218" + "isil,isl1219" - "reg": I2C bus address of the device Optional properties: @@ -33,3 +40,12 @@ Example isl1208 node with #IRQ pin connected to SoC gpio1 pin 12: interrupt-parent = <>; interrupts = <12 IRQ_TYPE_EDGE_FALLING>; }; + +Example isl1219 node with #IRQ pin and #EVDET pin connected to SoC gpio1 pin 12: + + isl1219: isl1219@68 { + compatible = "intersil,isl1219"; + reg = <0x68>; + interrupts-extended = < 12 IRQ_TYPE_EDGE_FALLING>; + }; + diff --git a/Documentation/hwmon/sysfs-interface b/Documentation/hwmon/sysfs-interface index fc337c317c673..a12b3c2b2a18c 100644 --- a/Documentation/hwmon/sysfs-interface +++ b/Documentation/hwmon/sysfs-interface @@ -702,6 +702,13 @@ intrusion[0-*]_alarm the user. This is done by writing 0 to the file. Writing other values is unsupported. +intrusion[0-*]_timestamp + Chassis intrusion detection + -MM-DD HH:MM:SS UTC (ts.sec): intrusion detected + RO + The corresponding timestamp on which the intrustion + was detected. + intrusion[0-*]_beep Chassis intrusion beep 0: disable diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c index a13a4ba79004d..6e4d24614d98b 100644 --- a/drivers/rtc/rtc-isl1208.c +++ b/drivers/rtc/rtc-isl1208.c @@ -14,6 +14,8 @@ #include #include #include +#include +#include /* Register map */ /* rtc section */ @@ -33,6 +35,7 @@ #define ISL1208_REG_SR_ARST(1<<7) /* auto reset */ #define ISL1208_REG_SR_XTOSCB (1<<6) /* crystal oscillator */ #define ISL1208_REG_SR_WRTC(1<<4) /* write rtc */ +#define ISL1208_REG_SR_EVT (1<<3) /* event */ #define ISL1208_REG_SR_ALM (1<<2) /* alarm */ #define ISL1208_REG_SR_BAT (1<<1) /* battery */ #define ISL1208_REG_SR_RTCF(1<<0) /* rtc fail */ @@ -57,8 +60,29 @@ #define ISL1208_REG_USR2 0x13 #define ISL1208_USR_SECTION_LEN 2 +/* event section */ +#define ISL1208_REG_SCT 0x14 +#define ISL1208_REG_MNT 0x15 +#define ISL1208_REG_HRT 0x16 +#define ISL1208_REG_DTT 0x17 +#define ISL1208_REG_MOT 0x18 +#define ISL1208_REG_YRT 0x19 +#define ISL1208_EVT_SECTION_LEN 6 + static struct i2c_driver isl1208_driver; +/* ISL1208 various variants */ +enum { + TYPE_ISL1208 = 0, + TYPE_ISL1218, + TYPE_ISL1219, +}; + +struct isl1208 { + struct rtc_device *rtc; + struct device *hwmon; +}; + /* block read */ static int isl1208_i2c_read_regs(struct i2c_client *client, u8 reg, u8 buf[], @@ -80,8 +104,8 @@ isl1208_i2c_read_regs(struct i2c_client *client, u8 reg, u8 buf[], }; int ret; - BUG_ON(reg > ISL1208_REG_USR2); - BUG_ON(reg + len > ISL1208_REG_USR2 + 1); + WARN_ON(reg > IS
[PATCH 2/4] rtc: isl1208: Add device tree binding documentation
From: Denis Osterland <denis.osterl...@diehl.com> Wrote documentation for ISL1208, ISL1218 device tree binding with short examples. Signed-off-by: Denis Osterland <denis.osterl...@diehl.com> Signed-off-by: Michael Grzeschik <m.grzesc...@pengutronix.de> --- .../devicetree/bindings/rtc/intersil,isl1208.txt | 35 ++ 1 file changed, 35 insertions(+) create mode 100644 Documentation/devicetree/bindings/rtc/intersil,isl1208.txt diff --git a/Documentation/devicetree/bindings/rtc/intersil,isl1208.txt b/Documentation/devicetree/bindings/rtc/intersil,isl1208.txt new file mode 100644 index 0..a54e99feae1ca --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/intersil,isl1208.txt @@ -0,0 +1,35 @@ +Intersil ISL1208, ISL1218 I2C RTC/Alarm chip + +ISL1208 is a trivial I2C device (it has simple device tree bindings, +consisting of a compatible field, an address and possibly an interrupt +line). + +Required properties supported by the device: + + - "compatible": must be one of + "isil,isl1208" + "isil,isl1218" + - "reg": I2C bus address of the device + +Optional properties: + + - "interrupt-parent", "interrupts", "interrupts-extended": + for passing the interrupt line of the SoC connected to #IRQ pin + of the RTC chip. + + +Example isl1208 node without #IRQ pin connected: + + isl1208: isl1208@68 { + compatible = "isil,isl1208"; + reg = <0x68>; + }; + +Example isl1208 node with #IRQ pin connected to SoC gpio1 pin 12: + + isl1208: isl1208@68 { + compatible = "isil,isl1208"; + reg = <0x68>; + interrupt-parent = <>; + interrupts = <12 IRQ_TYPE_EDGE_FALLING>; + }; -- 2.11.0
[PATCH 2/4] rtc: isl1208: Add device tree binding documentation
From: Denis Osterland Wrote documentation for ISL1208, ISL1218 device tree binding with short examples. Signed-off-by: Denis Osterland Signed-off-by: Michael Grzeschik --- .../devicetree/bindings/rtc/intersil,isl1208.txt | 35 ++ 1 file changed, 35 insertions(+) create mode 100644 Documentation/devicetree/bindings/rtc/intersil,isl1208.txt diff --git a/Documentation/devicetree/bindings/rtc/intersil,isl1208.txt b/Documentation/devicetree/bindings/rtc/intersil,isl1208.txt new file mode 100644 index 0..a54e99feae1ca --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/intersil,isl1208.txt @@ -0,0 +1,35 @@ +Intersil ISL1208, ISL1218 I2C RTC/Alarm chip + +ISL1208 is a trivial I2C device (it has simple device tree bindings, +consisting of a compatible field, an address and possibly an interrupt +line). + +Required properties supported by the device: + + - "compatible": must be one of + "isil,isl1208" + "isil,isl1218" + - "reg": I2C bus address of the device + +Optional properties: + + - "interrupt-parent", "interrupts", "interrupts-extended": + for passing the interrupt line of the SoC connected to #IRQ pin + of the RTC chip. + + +Example isl1208 node without #IRQ pin connected: + + isl1208: isl1208@68 { + compatible = "isil,isl1208"; + reg = <0x68>; + }; + +Example isl1208 node with #IRQ pin connected to SoC gpio1 pin 12: + + isl1208: isl1208@68 { + compatible = "isil,isl1208"; + reg = <0x68>; + interrupt-parent = <>; + interrupts = <12 IRQ_TYPE_EDGE_FALLING>; + }; -- 2.11.0
[PATCH 1/4] rtc: isl1208: Fix unintended clear of SR bits
From: Denis Osterland <denis.osterl...@diehl.com> After successful sr = isl1208_i2c_set_regs(client, 0, regs, ISL1208_RTC_SECTION_LEN); sr will be 0. As a result sr = i2c_smbus_write_byte_data(client, ISL1208_REG_SR, sr & ~ISL1208_REG_SR_WRTC); is equal to sr = i2c_smbus_write_byte_data(client, ISL1208_REG_SR, 0); which clears all flags in SR. Add an additional read of SR, to have value of SR in sr again. Signed-off-by: Denis Osterland <denis.osterl...@diehl.com> Signed-off-by: Michael Grzeschik <m.grzesc...@pengutronix.de> --- drivers/rtc/rtc-isl1208.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c index 8dd299c6a1f33..c8b4953482296 100644 --- a/drivers/rtc/rtc-isl1208.c +++ b/drivers/rtc/rtc-isl1208.c @@ -459,6 +459,11 @@ isl1208_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm) } /* clear WRTC again */ + sr = isl1208_i2c_get_sr(client); + if (sr < 0) { + dev_err(>dev, "%s: reading SR failed\n", __func__); + return sr; + } sr = i2c_smbus_write_byte_data(client, ISL1208_REG_SR, sr & ~ISL1208_REG_SR_WRTC); if (sr < 0) { -- 2.11.0
[PATCH 1/4] rtc: isl1208: Fix unintended clear of SR bits
From: Denis Osterland After successful sr = isl1208_i2c_set_regs(client, 0, regs, ISL1208_RTC_SECTION_LEN); sr will be 0. As a result sr = i2c_smbus_write_byte_data(client, ISL1208_REG_SR, sr & ~ISL1208_REG_SR_WRTC); is equal to sr = i2c_smbus_write_byte_data(client, ISL1208_REG_SR, 0); which clears all flags in SR. Add an additional read of SR, to have value of SR in sr again. Signed-off-by: Denis Osterland Signed-off-by: Michael Grzeschik --- drivers/rtc/rtc-isl1208.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c index 8dd299c6a1f33..c8b4953482296 100644 --- a/drivers/rtc/rtc-isl1208.c +++ b/drivers/rtc/rtc-isl1208.c @@ -459,6 +459,11 @@ isl1208_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm) } /* clear WRTC again */ + sr = isl1208_i2c_get_sr(client); + if (sr < 0) { + dev_err(>dev, "%s: reading SR failed\n", __func__); + return sr; + } sr = i2c_smbus_write_byte_data(client, ISL1208_REG_SR, sr & ~ISL1208_REG_SR_WRTC); if (sr < 0) { -- 2.11.0
[PATCH 0/4] rtc: isl1208: fixes, documentation and isl1219 support
This series includes fixes regarding the time setup and interrupt preparation. It also adds devicetree binding documentation. It also adds support for the isl1219 device that comes with tamper detection support. For this we also add devicetree binding documentation and instantiate the function via hwmon including the new intrusion[0-*]_timestamp interface. Denis Osterland (2): rtc: isl1208: Fix unintended clear of SR bits rtc: isl1208: Add device tree binding documentation Michael Grzeschik (2): rtc: isl1208: enable interrupt after context preparation rtc: isl1208: add support for isl1219 with hwmon for tamper detection .../devicetree/bindings/rtc/isil,isl1208.txt | 51 + Documentation/hwmon/sysfs-interface| 7 + drivers/rtc/rtc-isl1208.c | 227 ++--- 3 files changed, 256 insertions(+), 29 deletions(-) create mode 100644 Documentation/devicetree/bindings/rtc/isil,isl1208.txt -- 2.11.0
[PATCH 3/4] rtc: isl1208: enable interrupt after context preparation
The interrupt handler got enabled very early. If the interrupt cause is triggering immediately before the context is fully prepared. This can lead to undefined behaviour. Therefor we move the interrupt enable code to the end of the probe function. Signed-off-by: Michael Grzeschik <m.grzesc...@pengutronix.de> Signed-off-by: Denis Osterland <denis.osterl...@diehl.com> --- drivers/rtc/rtc-isl1208.c | 34 +- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c index c8b4953482296..a13a4ba79004d 100644 --- a/drivers/rtc/rtc-isl1208.c +++ b/drivers/rtc/rtc-isl1208.c @@ -635,23 +635,6 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id) if (isl1208_i2c_validate_client(client) < 0) return -ENODEV; - if (client->irq > 0) { - rc = devm_request_threaded_irq(>dev, client->irq, NULL, - isl1208_rtc_interrupt, - IRQF_SHARED | IRQF_ONESHOT, - isl1208_driver.driver.name, - client); - if (!rc) { - device_init_wakeup(>dev, 1); - enable_irq_wake(client->irq); - } else { - dev_err(>dev, - "Unable to request irq %d, no alarm support\n", - client->irq); - client->irq = 0; - } - } - rtc = devm_rtc_device_register(>dev, isl1208_driver.driver.name, _rtc_ops, THIS_MODULE); @@ -674,6 +657,23 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id) if (rc) return rc; + if (client->irq > 0) { + rc = devm_request_threaded_irq(>dev, client->irq, NULL, + isl1208_rtc_interrupt, + IRQF_SHARED | IRQF_ONESHOT, + isl1208_driver.driver.name, + client); + if (!rc) { + device_init_wakeup(>dev, 1); + enable_irq_wake(client->irq); + } else { + dev_err(>dev, + "Unable to request irq %d, no alarm support\n", + client->irq); + client->irq = 0; + } + } + return 0; } -- 2.11.0
[PATCH 0/4] rtc: isl1208: fixes, documentation and isl1219 support
This series includes fixes regarding the time setup and interrupt preparation. It also adds devicetree binding documentation. It also adds support for the isl1219 device that comes with tamper detection support. For this we also add devicetree binding documentation and instantiate the function via hwmon including the new intrusion[0-*]_timestamp interface. Denis Osterland (2): rtc: isl1208: Fix unintended clear of SR bits rtc: isl1208: Add device tree binding documentation Michael Grzeschik (2): rtc: isl1208: enable interrupt after context preparation rtc: isl1208: add support for isl1219 with hwmon for tamper detection .../devicetree/bindings/rtc/isil,isl1208.txt | 51 + Documentation/hwmon/sysfs-interface| 7 + drivers/rtc/rtc-isl1208.c | 227 ++--- 3 files changed, 256 insertions(+), 29 deletions(-) create mode 100644 Documentation/devicetree/bindings/rtc/isil,isl1208.txt -- 2.11.0
[PATCH 3/4] rtc: isl1208: enable interrupt after context preparation
The interrupt handler got enabled very early. If the interrupt cause is triggering immediately before the context is fully prepared. This can lead to undefined behaviour. Therefor we move the interrupt enable code to the end of the probe function. Signed-off-by: Michael Grzeschik Signed-off-by: Denis Osterland --- drivers/rtc/rtc-isl1208.c | 34 +- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c index c8b4953482296..a13a4ba79004d 100644 --- a/drivers/rtc/rtc-isl1208.c +++ b/drivers/rtc/rtc-isl1208.c @@ -635,23 +635,6 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id) if (isl1208_i2c_validate_client(client) < 0) return -ENODEV; - if (client->irq > 0) { - rc = devm_request_threaded_irq(>dev, client->irq, NULL, - isl1208_rtc_interrupt, - IRQF_SHARED | IRQF_ONESHOT, - isl1208_driver.driver.name, - client); - if (!rc) { - device_init_wakeup(>dev, 1); - enable_irq_wake(client->irq); - } else { - dev_err(>dev, - "Unable to request irq %d, no alarm support\n", - client->irq); - client->irq = 0; - } - } - rtc = devm_rtc_device_register(>dev, isl1208_driver.driver.name, _rtc_ops, THIS_MODULE); @@ -674,6 +657,23 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id) if (rc) return rc; + if (client->irq > 0) { + rc = devm_request_threaded_irq(>dev, client->irq, NULL, + isl1208_rtc_interrupt, + IRQF_SHARED | IRQF_ONESHOT, + isl1208_driver.driver.name, + client); + if (!rc) { + device_init_wakeup(>dev, 1); + enable_irq_wake(client->irq); + } else { + dev_err(>dev, + "Unable to request irq %d, no alarm support\n", + client->irq); + client->irq = 0; + } + } + return 0; } -- 2.11.0
Re: [PATCH v2] regmap: irq: allow different device for irq chip and regmap
On Tue, Jul 04, 2017 at 11:44:49AM +0100, Mark Brown wrote: > On Fri, Jun 30, 2017 at 03:33:27PM +0200, Michael Grzeschik wrote: > > On Fri, Jun 23, 2017 at 01:00:43PM +0100, Mark Brown wrote: > > > > syscon is one potential thing here but it seems odd for the sort of > > > hardware that syscon handles to be a good fit for regmap-irq. > > > We have the special case that we use the syscon as the basic driver > > underneath some subdevices that vary in function. We have six arcnet > > controllers sitting side by side in an 8 byte offset. And after them we > > have the next small memory windows for an reset controller and one > > interrupt controller which the other devices reference. > > Why is this a syscon and not a MFD? It sounds exactly like a MFD to me, > syscon is more for cases where things are really jumbled together (even > in single registers) but that sounds like a bunch of separate register > ranges for separate devices that happen to be very close together in > address. You are right. I will rewrite it to MFD. Thanks, Michael -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | signature.asc Description: PGP signature
Re: [PATCH v2] regmap: irq: allow different device for irq chip and regmap
On Tue, Jul 04, 2017 at 11:44:49AM +0100, Mark Brown wrote: > On Fri, Jun 30, 2017 at 03:33:27PM +0200, Michael Grzeschik wrote: > > On Fri, Jun 23, 2017 at 01:00:43PM +0100, Mark Brown wrote: > > > > syscon is one potential thing here but it seems odd for the sort of > > > hardware that syscon handles to be a good fit for regmap-irq. > > > We have the special case that we use the syscon as the basic driver > > underneath some subdevices that vary in function. We have six arcnet > > controllers sitting side by side in an 8 byte offset. And after them we > > have the next small memory windows for an reset controller and one > > interrupt controller which the other devices reference. > > Why is this a syscon and not a MFD? It sounds exactly like a MFD to me, > syscon is more for cases where things are really jumbled together (even > in single registers) but that sounds like a bunch of separate register > ranges for separate devices that happen to be very close together in > address. You are right. I will rewrite it to MFD. Thanks, Michael -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | signature.asc Description: PGP signature
Re: [PATCH v2] regmap: irq: allow different device for irq chip and regmap
On Fri, Jun 23, 2017 at 01:00:43PM +0100, Mark Brown wrote: > On Thu, Jun 22, 2017 at 01:03:20PM +0200, Michael Grzeschik wrote: > > > If the irq chip device is using the regmap of its parent device or > > a syscon regmap that doesn't have an associated device at all, > > allow the driver to provide its own device. That makes it possible > > to reference the irq controller from other devices running on the > > same regmap. > > I would strongly expect that the regmap for a device would be associated > with the physical device, if it's not that seems likely to create > further problems. How is this happening? > > syscon is one potential thing here but it seems odd for the sort of > hardware that syscon handles to be a good fit for regmap-irq. We have the special case that we use the syscon as the basic driver underneath some subdevices that vary in function. We have six arcnet controllers sitting side by side in an 8 byte offset. And after them we have the next small memory windows for an reset controller and one interrupt controller which the other devices reference. For that scenario the interrupt driver sitting under the "devicefree" syscon node, we have to add our own device node with dev_regmap_add_irq_chip. kmae_conf: syscon@0x0900 { compatible = "syscon", "simple-bus"; bits = <32>; reg-io-width = <1>; stride = <1>; reg = <0x0900 0x2>; com20020_1@0x09014000 { compatible = "smsc,com20020"; reg = <0x14000 0x8>; interrupt-parent = <>; interrupts = <0 0x4>; resets = <_reset 0 0>; }; com20020_2@0x09014010 { compatible = "smsc,com20020"; reg = <0x14010 0x8>; interrupt-parent = <>; interrupts = <1 0x4>; resets = <_reset 1 0>; }; com20020_3@0x09014020 { compatible = "smsc,com20020"; reg = <0x14020 0x8>; interrupt-parent = <>; interrupts = <2 0x4>; resets = <_reset 2 0>; }; com20020_4@0x09014030 { compatible = "smsc,com20020"; reg = <0x14030 0x8>; interrupt-parent = <>; interrupts = <3 0x4>; resets = <_reset 3 0>; }; com20020_5@0x09014040 { compatible = "smsc,com20020"; reg = <0x14040 0x8>; interrupt-parent = <>; interrupts = <4 0x4>; resets = <_reset 4 0>; }; com20020_6@0x09014050 { compatible = "smsc,com20020"; reg = <0x14050 0x8>; interrupt-parent = <>; interrupts = <5 0x4>; resets = <_reset 5 0>; }; kmae_reset: kmae_reset@0x09014060 { compatible = "eae,kmae-reset"; reg = <0x14060 0x8>; reset-controller; #reset-cells = <1>; }; kmae_irq: kmae_irq@0x09014060 { compatible = "eae,kmae-irq"; reg = <0x1406c 0x2>; interrupt-controller; #interrupt-cells = <2>; interrupt-parent = <>; interrupts = <31 0x4>; gpmc = <>; }; }; You can imagine this kind of scenarios in various situations where the device structure is loaded into an FPGA. The simplest way to memory map that packed layout pagewise is by using syscon in that case. Regards, Michael -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | signature.asc Description: PGP signature
Re: [PATCH v2] regmap: irq: allow different device for irq chip and regmap
On Fri, Jun 23, 2017 at 01:00:43PM +0100, Mark Brown wrote: > On Thu, Jun 22, 2017 at 01:03:20PM +0200, Michael Grzeschik wrote: > > > If the irq chip device is using the regmap of its parent device or > > a syscon regmap that doesn't have an associated device at all, > > allow the driver to provide its own device. That makes it possible > > to reference the irq controller from other devices running on the > > same regmap. > > I would strongly expect that the regmap for a device would be associated > with the physical device, if it's not that seems likely to create > further problems. How is this happening? > > syscon is one potential thing here but it seems odd for the sort of > hardware that syscon handles to be a good fit for regmap-irq. We have the special case that we use the syscon as the basic driver underneath some subdevices that vary in function. We have six arcnet controllers sitting side by side in an 8 byte offset. And after them we have the next small memory windows for an reset controller and one interrupt controller which the other devices reference. For that scenario the interrupt driver sitting under the "devicefree" syscon node, we have to add our own device node with dev_regmap_add_irq_chip. kmae_conf: syscon@0x0900 { compatible = "syscon", "simple-bus"; bits = <32>; reg-io-width = <1>; stride = <1>; reg = <0x0900 0x2>; com20020_1@0x09014000 { compatible = "smsc,com20020"; reg = <0x14000 0x8>; interrupt-parent = <>; interrupts = <0 0x4>; resets = <_reset 0 0>; }; com20020_2@0x09014010 { compatible = "smsc,com20020"; reg = <0x14010 0x8>; interrupt-parent = <>; interrupts = <1 0x4>; resets = <_reset 1 0>; }; com20020_3@0x09014020 { compatible = "smsc,com20020"; reg = <0x14020 0x8>; interrupt-parent = <>; interrupts = <2 0x4>; resets = <_reset 2 0>; }; com20020_4@0x09014030 { compatible = "smsc,com20020"; reg = <0x14030 0x8>; interrupt-parent = <>; interrupts = <3 0x4>; resets = <_reset 3 0>; }; com20020_5@0x09014040 { compatible = "smsc,com20020"; reg = <0x14040 0x8>; interrupt-parent = <>; interrupts = <4 0x4>; resets = <_reset 4 0>; }; com20020_6@0x09014050 { compatible = "smsc,com20020"; reg = <0x14050 0x8>; interrupt-parent = <>; interrupts = <5 0x4>; resets = <_reset 5 0>; }; kmae_reset: kmae_reset@0x09014060 { compatible = "eae,kmae-reset"; reg = <0x14060 0x8>; reset-controller; #reset-cells = <1>; }; kmae_irq: kmae_irq@0x09014060 { compatible = "eae,kmae-irq"; reg = <0x1406c 0x2>; interrupt-controller; #interrupt-cells = <2>; interrupt-parent = <>; interrupts = <31 0x4>; gpmc = <>; }; }; You can imagine this kind of scenarios in various situations where the device structure is loaded into an FPGA. The simplest way to memory map that packed layout pagewise is by using syscon in that case. Regards, Michael -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | signature.asc Description: PGP signature
Re: [PATCH] arcnet: fix spelling mistake "Ackknowledge" -> "Acknowledge"
On Sun, Jun 25, 2017 at 10:15:06PM +0100, Colin King wrote: > From: Colin Ian King> > Trivial fix to spelling mistake in arc_printk message > > Signed-off-by: Colin Ian King > --- > drivers/net/arcnet/capmode.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/net/arcnet/capmode.c b/drivers/net/arcnet/capmode.c > index a80f4eb9262d..b780be6f41ff 100644 > --- a/drivers/net/arcnet/capmode.c > +++ b/drivers/net/arcnet/capmode.c > @@ -212,7 +212,7 @@ static int ack_tx(struct net_device *dev, int acked) > ackpkt->soft.cap.proto = 0; /* using protocol 0 for acknowledge */ > ackpkt->soft.cap.mes.ack = acked; > > - arc_printk(D_PROTO, dev, "Ackknowledge for cap packet %x.\n", > + arc_printk(D_PROTO, dev, "Acknowledge for cap packet %x.\n", > *((int *)>soft.cap.cookie[0])); > > ackskb->protocol = cpu_to_be16(ETH_P_ARCNET); I will take it into my next pull request. -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- |
Re: [PATCH] arcnet: fix spelling mistake "Ackknowledge" -> "Acknowledge"
On Sun, Jun 25, 2017 at 10:15:06PM +0100, Colin King wrote: > From: Colin Ian King > > Trivial fix to spelling mistake in arc_printk message > > Signed-off-by: Colin Ian King > --- > drivers/net/arcnet/capmode.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/net/arcnet/capmode.c b/drivers/net/arcnet/capmode.c > index a80f4eb9262d..b780be6f41ff 100644 > --- a/drivers/net/arcnet/capmode.c > +++ b/drivers/net/arcnet/capmode.c > @@ -212,7 +212,7 @@ static int ack_tx(struct net_device *dev, int acked) > ackpkt->soft.cap.proto = 0; /* using protocol 0 for acknowledge */ > ackpkt->soft.cap.mes.ack = acked; > > - arc_printk(D_PROTO, dev, "Ackknowledge for cap packet %x.\n", > + arc_printk(D_PROTO, dev, "Acknowledge for cap packet %x.\n", > *((int *)>soft.cap.cookie[0])); > > ackskb->protocol = cpu_to_be16(ETH_P_ARCNET); I will take it into my next pull request. -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- |
[PATCH v2] regmap: irq: add chip option mask_writeonly
Some irq controllers have writeonly/multipurpose register layouts. In those cases we read invalid data back. Here we add the option mask_writeonly as masking option. Signed-off-by: Michael Grzeschik <m.grzesc...@pengutronix.de> --- v1 -> v2: - rebased on regmap/for-next - removed unneeded extra empty lines from previous patch drivers/base/regmap/regmap-irq.c | 40 +--- include/linux/regmap.h | 2 ++ 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c index c4a1eadb093f3..429ca8ed7e518 100644 --- a/drivers/base/regmap/regmap-irq.c +++ b/drivers/base/regmap/regmap-irq.c @@ -60,6 +60,16 @@ static void regmap_irq_lock(struct irq_data *data) mutex_lock(>lock); } +static int regmap_irq_update_bits(struct regmap_irq_chip_data *d, + unsigned int reg, unsigned int mask, + unsigned int val) +{ + if (d->chip->mask_writeonly) + return regmap_write_bits(d->map, reg, mask, val); + else + return regmap_update_bits(d->map, reg, mask, val); +} + static void regmap_irq_sync_unlock(struct irq_data *data) { struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); @@ -84,11 +94,11 @@ static void regmap_irq_sync_unlock(struct irq_data *data) reg = d->chip->mask_base + (i * map->reg_stride * d->irq_reg_stride); if (d->chip->mask_invert) { - ret = regmap_update_bits(d->map, reg, + ret = regmap_irq_update_bits(d, reg, d->mask_buf_def[i], ~d->mask_buf[i]); } else if (d->chip->unmask_base) { /* set mask with mask_base register */ - ret = regmap_update_bits(d->map, reg, + ret = regmap_irq_update_bits(d, reg, d->mask_buf_def[i], ~d->mask_buf[i]); if (ret < 0) dev_err(d->map->dev, @@ -97,12 +107,12 @@ static void regmap_irq_sync_unlock(struct irq_data *data) unmask_offset = d->chip->unmask_base - d->chip->mask_base; /* clear mask with unmask_base register */ - ret = regmap_update_bits(d->map, + ret = regmap_irq_update_bits(d, reg + unmask_offset, d->mask_buf_def[i], d->mask_buf[i]); } else { - ret = regmap_update_bits(d->map, reg, + ret = regmap_irq_update_bits(d, reg, d->mask_buf_def[i], d->mask_buf[i]); } if (ret != 0) @@ -113,11 +123,11 @@ static void regmap_irq_sync_unlock(struct irq_data *data) (i * map->reg_stride * d->irq_reg_stride); if (d->wake_buf) { if (d->chip->wake_invert) - ret = regmap_update_bits(d->map, reg, + ret = regmap_irq_update_bits(d, reg, d->mask_buf_def[i], ~d->wake_buf[i]); else - ret = regmap_update_bits(d->map, reg, + ret = regmap_irq_update_bits(d, reg, d->mask_buf_def[i], d->wake_buf[i]); if (ret != 0) @@ -153,10 +163,10 @@ static void regmap_irq_sync_unlock(struct irq_data *data) reg = d->chip->type_base + (i * map->reg_stride * d->type_reg_stride); if (d->chip->type_invert) - ret = regmap_update_bits(d->map, reg, + ret = regmap_irq_update_bits(d, reg, d->type_buf_def[i], ~d->type_buf[i]); else - ret = regmap_update_bits(d->map, reg, + ret = regmap_irq_update_bits(d, reg, d->type_buf_def[i], d->type_buf[i]); if (ret != 0) dev_err(d->map->dev, "Failed to sync type in %x\n", @@ -519,17 +529,17 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, reg = chip->mask_base +
[PATCH v2] regmap: irq: add chip option mask_writeonly
Some irq controllers have writeonly/multipurpose register layouts. In those cases we read invalid data back. Here we add the option mask_writeonly as masking option. Signed-off-by: Michael Grzeschik --- v1 -> v2: - rebased on regmap/for-next - removed unneeded extra empty lines from previous patch drivers/base/regmap/regmap-irq.c | 40 +--- include/linux/regmap.h | 2 ++ 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c index c4a1eadb093f3..429ca8ed7e518 100644 --- a/drivers/base/regmap/regmap-irq.c +++ b/drivers/base/regmap/regmap-irq.c @@ -60,6 +60,16 @@ static void regmap_irq_lock(struct irq_data *data) mutex_lock(>lock); } +static int regmap_irq_update_bits(struct regmap_irq_chip_data *d, + unsigned int reg, unsigned int mask, + unsigned int val) +{ + if (d->chip->mask_writeonly) + return regmap_write_bits(d->map, reg, mask, val); + else + return regmap_update_bits(d->map, reg, mask, val); +} + static void regmap_irq_sync_unlock(struct irq_data *data) { struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); @@ -84,11 +94,11 @@ static void regmap_irq_sync_unlock(struct irq_data *data) reg = d->chip->mask_base + (i * map->reg_stride * d->irq_reg_stride); if (d->chip->mask_invert) { - ret = regmap_update_bits(d->map, reg, + ret = regmap_irq_update_bits(d, reg, d->mask_buf_def[i], ~d->mask_buf[i]); } else if (d->chip->unmask_base) { /* set mask with mask_base register */ - ret = regmap_update_bits(d->map, reg, + ret = regmap_irq_update_bits(d, reg, d->mask_buf_def[i], ~d->mask_buf[i]); if (ret < 0) dev_err(d->map->dev, @@ -97,12 +107,12 @@ static void regmap_irq_sync_unlock(struct irq_data *data) unmask_offset = d->chip->unmask_base - d->chip->mask_base; /* clear mask with unmask_base register */ - ret = regmap_update_bits(d->map, + ret = regmap_irq_update_bits(d, reg + unmask_offset, d->mask_buf_def[i], d->mask_buf[i]); } else { - ret = regmap_update_bits(d->map, reg, + ret = regmap_irq_update_bits(d, reg, d->mask_buf_def[i], d->mask_buf[i]); } if (ret != 0) @@ -113,11 +123,11 @@ static void regmap_irq_sync_unlock(struct irq_data *data) (i * map->reg_stride * d->irq_reg_stride); if (d->wake_buf) { if (d->chip->wake_invert) - ret = regmap_update_bits(d->map, reg, + ret = regmap_irq_update_bits(d, reg, d->mask_buf_def[i], ~d->wake_buf[i]); else - ret = regmap_update_bits(d->map, reg, + ret = regmap_irq_update_bits(d, reg, d->mask_buf_def[i], d->wake_buf[i]); if (ret != 0) @@ -153,10 +163,10 @@ static void regmap_irq_sync_unlock(struct irq_data *data) reg = d->chip->type_base + (i * map->reg_stride * d->type_reg_stride); if (d->chip->type_invert) - ret = regmap_update_bits(d->map, reg, + ret = regmap_irq_update_bits(d, reg, d->type_buf_def[i], ~d->type_buf[i]); else - ret = regmap_update_bits(d->map, reg, + ret = regmap_irq_update_bits(d, reg, d->type_buf_def[i], d->type_buf[i]); if (ret != 0) dev_err(d->map->dev, "Failed to sync type in %x\n", @@ -519,17 +529,17 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, reg = chip->mask_base + (i * map->
[PATCH v2] regmap: irq: allow different device for irq chip and regmap
From: Philipp Zabel <p.za...@pengutronix.de> If the irq chip device is using the regmap of its parent device or a syscon regmap that doesn't have an associated device at all, allow the driver to provide its own device. That makes it possible to reference the irq controller from other devices running on the same regmap. Signed-off-by: Philipp Zabel <p.za...@pengutronix.de> Signed-off-by: Michael Grzeschik <m.grzesc...@pengutronix.de> --- v1 -> v2: Added my own missing Signed-off-by. drivers/base/regmap/regmap-irq.c | 93 +--- include/linux/regmap.h | 4 ++ 2 files changed, 62 insertions(+), 35 deletions(-) diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c index cd54189f2b1d4..a2525705c1ad0 100644 --- a/drivers/base/regmap/regmap-irq.c +++ b/drivers/base/regmap/regmap-irq.c @@ -25,6 +25,7 @@ struct regmap_irq_chip_data { struct mutex lock; struct irq_chip irq_chip; + struct device *dev; struct regmap *map; const struct regmap_irq_chip *chip; @@ -63,16 +64,16 @@ static void regmap_irq_lock(struct irq_data *data) static void regmap_irq_sync_unlock(struct irq_data *data) { struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); + struct device *dev = d->dev; struct regmap *map = d->map; int i, ret; u32 reg; u32 unmask_offset; if (d->chip->runtime_pm) { - ret = pm_runtime_get_sync(map->dev); + ret = pm_runtime_get_sync(dev); if (ret < 0) - dev_err(map->dev, "IRQ sync failed to resume: %d\n", - ret); + dev_err(dev, "IRQ sync failed to resume: %d\n", ret); } /* @@ -106,8 +107,7 @@ static void regmap_irq_sync_unlock(struct irq_data *data) d->mask_buf_def[i], d->mask_buf[i]); } if (ret != 0) - dev_err(d->map->dev, "Failed to sync masks in %x\n", - reg); + dev_err(dev, "Failed to sync masks in %x\n", reg); reg = d->chip->wake_base + (i * map->reg_stride * d->irq_reg_stride); @@ -121,8 +121,7 @@ static void regmap_irq_sync_unlock(struct irq_data *data) d->mask_buf_def[i], d->wake_buf[i]); if (ret != 0) - dev_err(d->map->dev, - "Failed to sync wakes in %x: %d\n", + dev_err(dev, "Failed to sync wakes in %x: %d\n", reg, ret); } @@ -142,7 +141,7 @@ static void regmap_irq_sync_unlock(struct irq_data *data) else ret = regmap_write(map, reg, d->mask_buf[i]); if (ret != 0) - dev_err(d->map->dev, "Failed to ack 0x%x: %d\n", + dev_err(dev, "Failed to ack 0x%x: %d\n", reg, ret); } } @@ -164,7 +163,7 @@ static void regmap_irq_sync_unlock(struct irq_data *data) } if (d->chip->runtime_pm) - pm_runtime_put(map->dev); + pm_runtime_put(dev); /* If we've changed our wakeup count propagate it to the parent */ if (d->wake_count < 0) @@ -263,6 +262,7 @@ static irqreturn_t regmap_irq_thread(int irq, void *d) { struct regmap_irq_chip_data *data = d; const struct regmap_irq_chip *chip = data->chip; + struct device *dev = data->dev; struct regmap *map = data->map; int ret, i; bool handled = false; @@ -272,11 +272,10 @@ static irqreturn_t regmap_irq_thread(int irq, void *d) chip->handle_pre_irq(chip->irq_drv_data); if (chip->runtime_pm) { - ret = pm_runtime_get_sync(map->dev); + ret = pm_runtime_get_sync(dev); if (ret < 0) { - dev_err(map->dev, "IRQ thread failed to resume: %d\n", - ret); - pm_runtime_put(map->dev); + dev_err(dev, "IRQ thread failed to resume: %d\n", ret); + pm_runtime_put(dev); goto exit; } } @@ -297,8 +296,7 @@ static irqreturn_t regmap_irq_thread(int irq, void *d) data->status_reg_buf,
[PATCH v2] regmap: irq: allow different device for irq chip and regmap
From: Philipp Zabel If the irq chip device is using the regmap of its parent device or a syscon regmap that doesn't have an associated device at all, allow the driver to provide its own device. That makes it possible to reference the irq controller from other devices running on the same regmap. Signed-off-by: Philipp Zabel Signed-off-by: Michael Grzeschik --- v1 -> v2: Added my own missing Signed-off-by. drivers/base/regmap/regmap-irq.c | 93 +--- include/linux/regmap.h | 4 ++ 2 files changed, 62 insertions(+), 35 deletions(-) diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c index cd54189f2b1d4..a2525705c1ad0 100644 --- a/drivers/base/regmap/regmap-irq.c +++ b/drivers/base/regmap/regmap-irq.c @@ -25,6 +25,7 @@ struct regmap_irq_chip_data { struct mutex lock; struct irq_chip irq_chip; + struct device *dev; struct regmap *map; const struct regmap_irq_chip *chip; @@ -63,16 +64,16 @@ static void regmap_irq_lock(struct irq_data *data) static void regmap_irq_sync_unlock(struct irq_data *data) { struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); + struct device *dev = d->dev; struct regmap *map = d->map; int i, ret; u32 reg; u32 unmask_offset; if (d->chip->runtime_pm) { - ret = pm_runtime_get_sync(map->dev); + ret = pm_runtime_get_sync(dev); if (ret < 0) - dev_err(map->dev, "IRQ sync failed to resume: %d\n", - ret); + dev_err(dev, "IRQ sync failed to resume: %d\n", ret); } /* @@ -106,8 +107,7 @@ static void regmap_irq_sync_unlock(struct irq_data *data) d->mask_buf_def[i], d->mask_buf[i]); } if (ret != 0) - dev_err(d->map->dev, "Failed to sync masks in %x\n", - reg); + dev_err(dev, "Failed to sync masks in %x\n", reg); reg = d->chip->wake_base + (i * map->reg_stride * d->irq_reg_stride); @@ -121,8 +121,7 @@ static void regmap_irq_sync_unlock(struct irq_data *data) d->mask_buf_def[i], d->wake_buf[i]); if (ret != 0) - dev_err(d->map->dev, - "Failed to sync wakes in %x: %d\n", + dev_err(dev, "Failed to sync wakes in %x: %d\n", reg, ret); } @@ -142,7 +141,7 @@ static void regmap_irq_sync_unlock(struct irq_data *data) else ret = regmap_write(map, reg, d->mask_buf[i]); if (ret != 0) - dev_err(d->map->dev, "Failed to ack 0x%x: %d\n", + dev_err(dev, "Failed to ack 0x%x: %d\n", reg, ret); } } @@ -164,7 +163,7 @@ static void regmap_irq_sync_unlock(struct irq_data *data) } if (d->chip->runtime_pm) - pm_runtime_put(map->dev); + pm_runtime_put(dev); /* If we've changed our wakeup count propagate it to the parent */ if (d->wake_count < 0) @@ -263,6 +262,7 @@ static irqreturn_t regmap_irq_thread(int irq, void *d) { struct regmap_irq_chip_data *data = d; const struct regmap_irq_chip *chip = data->chip; + struct device *dev = data->dev; struct regmap *map = data->map; int ret, i; bool handled = false; @@ -272,11 +272,10 @@ static irqreturn_t regmap_irq_thread(int irq, void *d) chip->handle_pre_irq(chip->irq_drv_data); if (chip->runtime_pm) { - ret = pm_runtime_get_sync(map->dev); + ret = pm_runtime_get_sync(dev); if (ret < 0) { - dev_err(map->dev, "IRQ thread failed to resume: %d\n", - ret); - pm_runtime_put(map->dev); + dev_err(dev, "IRQ thread failed to resume: %d\n", ret); + pm_runtime_put(dev); goto exit; } } @@ -297,8 +296,7 @@ static irqreturn_t regmap_irq_thread(int irq, void *d) data->status_reg_buf, chip->num_regs); if (ret != 0) { -
[PATCH] regmap: irq: add chip option mask_writeonly
Some irq controllers have writeonly/multipurpose register layouts. In those cases we read invalid data back. Here we add the option mask_writeonly as masking option. Signed-off-by: Michael Grzeschik <m.grzesc...@pengutronix.de> --- drivers/base/regmap/regmap-irq.c | 43 ++-- include/linux/regmap.h | 2 ++ 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c index a2525705c1ad0..a599a8ee38647 100644 --- a/drivers/base/regmap/regmap-irq.c +++ b/drivers/base/regmap/regmap-irq.c @@ -61,6 +61,16 @@ static void regmap_irq_lock(struct irq_data *data) mutex_lock(>lock); } +static int regmap_irq_update_bits(struct regmap_irq_chip_data *d, + unsigned int reg, unsigned int mask, + unsigned int val) +{ + if (d->chip->mask_writeonly) + return regmap_write_bits(d->map, reg, mask, val); + else + return regmap_update_bits(d->map, reg, mask, val); +} + static void regmap_irq_sync_unlock(struct irq_data *data) { struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); @@ -85,12 +95,13 @@ static void regmap_irq_sync_unlock(struct irq_data *data) reg = d->chip->mask_base + (i * map->reg_stride * d->irq_reg_stride); if (d->chip->mask_invert) { - ret = regmap_update_bits(d->map, reg, + ret = regmap_irq_update_bits(d, reg, d->mask_buf_def[i], ~d->mask_buf[i]); } else if (d->chip->unmask_base) { /* set mask with mask_base register */ - ret = regmap_update_bits(d->map, reg, + ret = regmap_irq_update_bits(d, reg, d->mask_buf_def[i], ~d->mask_buf[i]); + if (ret < 0) dev_err(d->map->dev, "Failed to sync unmasks in %x\n", @@ -98,13 +109,14 @@ static void regmap_irq_sync_unlock(struct irq_data *data) unmask_offset = d->chip->unmask_base - d->chip->mask_base; /* clear mask with unmask_base register */ - ret = regmap_update_bits(d->map, + ret = regmap_irq_update_bits(d, reg + unmask_offset, d->mask_buf_def[i], d->mask_buf[i]); } else { - ret = regmap_update_bits(d->map, reg, + ret = regmap_irq_update_bits(d, reg, d->mask_buf_def[i], d->mask_buf[i]); + } if (ret != 0) dev_err(dev, "Failed to sync masks in %x\n", reg); @@ -113,11 +125,11 @@ static void regmap_irq_sync_unlock(struct irq_data *data) (i * map->reg_stride * d->irq_reg_stride); if (d->wake_buf) { if (d->chip->wake_invert) - ret = regmap_update_bits(d->map, reg, + ret = regmap_irq_update_bits(d, reg, d->mask_buf_def[i], ~d->wake_buf[i]); else - ret = regmap_update_bits(d->map, reg, + ret = regmap_irq_update_bits(d, reg, d->mask_buf_def[i], d->wake_buf[i]); if (ret != 0) @@ -152,10 +164,10 @@ static void regmap_irq_sync_unlock(struct irq_data *data) reg = d->chip->type_base + (i * map->reg_stride * d->type_reg_stride); if (d->chip->type_invert) - ret = regmap_update_bits(d->map, reg, + ret = regmap_irq_update_bits(d, reg, d->type_buf_def[i], ~d->type_buf[i]); else - ret = regmap_update_bits(d->map, reg, + ret = regmap_irq_update_bits(d, reg, d->type_buf_def[i], d->type_buf[i]); if (ret != 0) dev_err(d->map->dev, "Failed to sync type in %x\n", @@ -519,17 +531,18 @@ int dev_regmap_add_irq_chip(struct device *dev, struct regmap *map,
[PATCH] regmap: irq: add chip option mask_writeonly
Some irq controllers have writeonly/multipurpose register layouts. In those cases we read invalid data back. Here we add the option mask_writeonly as masking option. Signed-off-by: Michael Grzeschik --- drivers/base/regmap/regmap-irq.c | 43 ++-- include/linux/regmap.h | 2 ++ 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c index a2525705c1ad0..a599a8ee38647 100644 --- a/drivers/base/regmap/regmap-irq.c +++ b/drivers/base/regmap/regmap-irq.c @@ -61,6 +61,16 @@ static void regmap_irq_lock(struct irq_data *data) mutex_lock(>lock); } +static int regmap_irq_update_bits(struct regmap_irq_chip_data *d, + unsigned int reg, unsigned int mask, + unsigned int val) +{ + if (d->chip->mask_writeonly) + return regmap_write_bits(d->map, reg, mask, val); + else + return regmap_update_bits(d->map, reg, mask, val); +} + static void regmap_irq_sync_unlock(struct irq_data *data) { struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); @@ -85,12 +95,13 @@ static void regmap_irq_sync_unlock(struct irq_data *data) reg = d->chip->mask_base + (i * map->reg_stride * d->irq_reg_stride); if (d->chip->mask_invert) { - ret = regmap_update_bits(d->map, reg, + ret = regmap_irq_update_bits(d, reg, d->mask_buf_def[i], ~d->mask_buf[i]); } else if (d->chip->unmask_base) { /* set mask with mask_base register */ - ret = regmap_update_bits(d->map, reg, + ret = regmap_irq_update_bits(d, reg, d->mask_buf_def[i], ~d->mask_buf[i]); + if (ret < 0) dev_err(d->map->dev, "Failed to sync unmasks in %x\n", @@ -98,13 +109,14 @@ static void regmap_irq_sync_unlock(struct irq_data *data) unmask_offset = d->chip->unmask_base - d->chip->mask_base; /* clear mask with unmask_base register */ - ret = regmap_update_bits(d->map, + ret = regmap_irq_update_bits(d, reg + unmask_offset, d->mask_buf_def[i], d->mask_buf[i]); } else { - ret = regmap_update_bits(d->map, reg, + ret = regmap_irq_update_bits(d, reg, d->mask_buf_def[i], d->mask_buf[i]); + } if (ret != 0) dev_err(dev, "Failed to sync masks in %x\n", reg); @@ -113,11 +125,11 @@ static void regmap_irq_sync_unlock(struct irq_data *data) (i * map->reg_stride * d->irq_reg_stride); if (d->wake_buf) { if (d->chip->wake_invert) - ret = regmap_update_bits(d->map, reg, + ret = regmap_irq_update_bits(d, reg, d->mask_buf_def[i], ~d->wake_buf[i]); else - ret = regmap_update_bits(d->map, reg, + ret = regmap_irq_update_bits(d, reg, d->mask_buf_def[i], d->wake_buf[i]); if (ret != 0) @@ -152,10 +164,10 @@ static void regmap_irq_sync_unlock(struct irq_data *data) reg = d->chip->type_base + (i * map->reg_stride * d->type_reg_stride); if (d->chip->type_invert) - ret = regmap_update_bits(d->map, reg, + ret = regmap_irq_update_bits(d, reg, d->type_buf_def[i], ~d->type_buf[i]); else - ret = regmap_update_bits(d->map, reg, + ret = regmap_irq_update_bits(d, reg, d->type_buf_def[i], d->type_buf[i]); if (ret != 0) dev_err(d->map->dev, "Failed to sync type in %x\n", @@ -519,17 +531,18 @@ int dev_regmap_add_irq_chip(struct device *dev, struct regmap *map, int irq,
[PATCH] regmap: irq: allow different device for irq chip and regmap
From: Philipp ZabelIf the irq chip device is using the regmap of its parent device or a syscon regmap that doesn't have an associated device at all, allow the driver to provide its own device. That makes it possible to reference the irq controller from other devices running on the same regmap. Signed-off-by: Philipp Zabel --- drivers/base/regmap/regmap-irq.c | 93 +--- include/linux/regmap.h | 4 ++ 2 files changed, 62 insertions(+), 35 deletions(-) diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c index cd54189f2b1d4..a2525705c1ad0 100644 --- a/drivers/base/regmap/regmap-irq.c +++ b/drivers/base/regmap/regmap-irq.c @@ -25,6 +25,7 @@ struct regmap_irq_chip_data { struct mutex lock; struct irq_chip irq_chip; + struct device *dev; struct regmap *map; const struct regmap_irq_chip *chip; @@ -63,16 +64,16 @@ static void regmap_irq_lock(struct irq_data *data) static void regmap_irq_sync_unlock(struct irq_data *data) { struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); + struct device *dev = d->dev; struct regmap *map = d->map; int i, ret; u32 reg; u32 unmask_offset; if (d->chip->runtime_pm) { - ret = pm_runtime_get_sync(map->dev); + ret = pm_runtime_get_sync(dev); if (ret < 0) - dev_err(map->dev, "IRQ sync failed to resume: %d\n", - ret); + dev_err(dev, "IRQ sync failed to resume: %d\n", ret); } /* @@ -106,8 +107,7 @@ static void regmap_irq_sync_unlock(struct irq_data *data) d->mask_buf_def[i], d->mask_buf[i]); } if (ret != 0) - dev_err(d->map->dev, "Failed to sync masks in %x\n", - reg); + dev_err(dev, "Failed to sync masks in %x\n", reg); reg = d->chip->wake_base + (i * map->reg_stride * d->irq_reg_stride); @@ -121,8 +121,7 @@ static void regmap_irq_sync_unlock(struct irq_data *data) d->mask_buf_def[i], d->wake_buf[i]); if (ret != 0) - dev_err(d->map->dev, - "Failed to sync wakes in %x: %d\n", + dev_err(dev, "Failed to sync wakes in %x: %d\n", reg, ret); } @@ -142,7 +141,7 @@ static void regmap_irq_sync_unlock(struct irq_data *data) else ret = regmap_write(map, reg, d->mask_buf[i]); if (ret != 0) - dev_err(d->map->dev, "Failed to ack 0x%x: %d\n", + dev_err(dev, "Failed to ack 0x%x: %d\n", reg, ret); } } @@ -164,7 +163,7 @@ static void regmap_irq_sync_unlock(struct irq_data *data) } if (d->chip->runtime_pm) - pm_runtime_put(map->dev); + pm_runtime_put(dev); /* If we've changed our wakeup count propagate it to the parent */ if (d->wake_count < 0) @@ -263,6 +262,7 @@ static irqreturn_t regmap_irq_thread(int irq, void *d) { struct regmap_irq_chip_data *data = d; const struct regmap_irq_chip *chip = data->chip; + struct device *dev = data->dev; struct regmap *map = data->map; int ret, i; bool handled = false; @@ -272,11 +272,10 @@ static irqreturn_t regmap_irq_thread(int irq, void *d) chip->handle_pre_irq(chip->irq_drv_data); if (chip->runtime_pm) { - ret = pm_runtime_get_sync(map->dev); + ret = pm_runtime_get_sync(dev); if (ret < 0) { - dev_err(map->dev, "IRQ thread failed to resume: %d\n", - ret); - pm_runtime_put(map->dev); + dev_err(dev, "IRQ thread failed to resume: %d\n", ret); + pm_runtime_put(dev); goto exit; } } @@ -297,8 +296,7 @@ static irqreturn_t regmap_irq_thread(int irq, void *d) data->status_reg_buf, chip->num_regs); if (ret != 0) { - dev_err(map->dev, "Failed to read IRQ status: %d\n", - ret); + dev_err(dev, "Failed to read IRQ status: %d\n", ret); goto exit; } @@ -327,11 +325,10 @@ static
[PATCH] regmap: irq: allow different device for irq chip and regmap
From: Philipp Zabel If the irq chip device is using the regmap of its parent device or a syscon regmap that doesn't have an associated device at all, allow the driver to provide its own device. That makes it possible to reference the irq controller from other devices running on the same regmap. Signed-off-by: Philipp Zabel --- drivers/base/regmap/regmap-irq.c | 93 +--- include/linux/regmap.h | 4 ++ 2 files changed, 62 insertions(+), 35 deletions(-) diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c index cd54189f2b1d4..a2525705c1ad0 100644 --- a/drivers/base/regmap/regmap-irq.c +++ b/drivers/base/regmap/regmap-irq.c @@ -25,6 +25,7 @@ struct regmap_irq_chip_data { struct mutex lock; struct irq_chip irq_chip; + struct device *dev; struct regmap *map; const struct regmap_irq_chip *chip; @@ -63,16 +64,16 @@ static void regmap_irq_lock(struct irq_data *data) static void regmap_irq_sync_unlock(struct irq_data *data) { struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); + struct device *dev = d->dev; struct regmap *map = d->map; int i, ret; u32 reg; u32 unmask_offset; if (d->chip->runtime_pm) { - ret = pm_runtime_get_sync(map->dev); + ret = pm_runtime_get_sync(dev); if (ret < 0) - dev_err(map->dev, "IRQ sync failed to resume: %d\n", - ret); + dev_err(dev, "IRQ sync failed to resume: %d\n", ret); } /* @@ -106,8 +107,7 @@ static void regmap_irq_sync_unlock(struct irq_data *data) d->mask_buf_def[i], d->mask_buf[i]); } if (ret != 0) - dev_err(d->map->dev, "Failed to sync masks in %x\n", - reg); + dev_err(dev, "Failed to sync masks in %x\n", reg); reg = d->chip->wake_base + (i * map->reg_stride * d->irq_reg_stride); @@ -121,8 +121,7 @@ static void regmap_irq_sync_unlock(struct irq_data *data) d->mask_buf_def[i], d->wake_buf[i]); if (ret != 0) - dev_err(d->map->dev, - "Failed to sync wakes in %x: %d\n", + dev_err(dev, "Failed to sync wakes in %x: %d\n", reg, ret); } @@ -142,7 +141,7 @@ static void regmap_irq_sync_unlock(struct irq_data *data) else ret = regmap_write(map, reg, d->mask_buf[i]); if (ret != 0) - dev_err(d->map->dev, "Failed to ack 0x%x: %d\n", + dev_err(dev, "Failed to ack 0x%x: %d\n", reg, ret); } } @@ -164,7 +163,7 @@ static void regmap_irq_sync_unlock(struct irq_data *data) } if (d->chip->runtime_pm) - pm_runtime_put(map->dev); + pm_runtime_put(dev); /* If we've changed our wakeup count propagate it to the parent */ if (d->wake_count < 0) @@ -263,6 +262,7 @@ static irqreturn_t regmap_irq_thread(int irq, void *d) { struct regmap_irq_chip_data *data = d; const struct regmap_irq_chip *chip = data->chip; + struct device *dev = data->dev; struct regmap *map = data->map; int ret, i; bool handled = false; @@ -272,11 +272,10 @@ static irqreturn_t regmap_irq_thread(int irq, void *d) chip->handle_pre_irq(chip->irq_drv_data); if (chip->runtime_pm) { - ret = pm_runtime_get_sync(map->dev); + ret = pm_runtime_get_sync(dev); if (ret < 0) { - dev_err(map->dev, "IRQ thread failed to resume: %d\n", - ret); - pm_runtime_put(map->dev); + dev_err(dev, "IRQ thread failed to resume: %d\n", ret); + pm_runtime_put(dev); goto exit; } } @@ -297,8 +296,7 @@ static irqreturn_t regmap_irq_thread(int irq, void *d) data->status_reg_buf, chip->num_regs); if (ret != 0) { - dev_err(map->dev, "Failed to read IRQ status: %d\n", - ret); + dev_err(dev, "Failed to read IRQ status: %d\n", ret); goto exit; } @@ -327,11 +325,10 @@ static irqreturn_t regmap_irq_thread(int irq, void *d)
Re: [PATCH 2/5] arcnet: com90xx: add __init attribute
On Mon, Apr 18, 2016 at 04:55:35PM +0200, Julia Lawall wrote: > Add __init attribute on a function that is only called from other __init > functions and that is not inlined, at least with gcc version 4.8.4 on an > x86 machine with allyesconfig. Currently, the function is put in the > .text.unlikely segment. Declaring it as __init will cause it to be put in > the .init.text and to disappear after initialization. > > The result of objdump -x on the function before the change is as follows: > > l F .text.unlikely 00bf check_mirror > > And after the change it is as follows: > > l F .init.text 00ba check_mirror > > Done with the help of Coccinelle. The semantic patch checks for local > static non-init functions that are called from an __init function and are > not called from any other function. > > Signed-off-by: Julia Lawall <julia.law...@lip6.fr> > Acked-by: Michael Grzeschik <m...@pengutronix.de> > --- > drivers/net/arcnet/com90xx.c |2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/net/arcnet/com90xx.c b/drivers/net/arcnet/com90xx.c > index 0d9b45f..81f90c4 100644 > --- a/drivers/net/arcnet/com90xx.c > +++ b/drivers/net/arcnet/com90xx.c > @@ -433,7 +433,7 @@ static void __init com90xx_probe(void) > kfree(iomem); > } > > -static int check_mirror(unsigned long addr, size_t size) > +static int __init check_mirror(unsigned long addr, size_t size) > { > void __iomem *p; > int res = -1; > > -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- |
Re: [PATCH 2/5] arcnet: com90xx: add __init attribute
On Mon, Apr 18, 2016 at 04:55:35PM +0200, Julia Lawall wrote: > Add __init attribute on a function that is only called from other __init > functions and that is not inlined, at least with gcc version 4.8.4 on an > x86 machine with allyesconfig. Currently, the function is put in the > .text.unlikely segment. Declaring it as __init will cause it to be put in > the .init.text and to disappear after initialization. > > The result of objdump -x on the function before the change is as follows: > > l F .text.unlikely 00bf check_mirror > > And after the change it is as follows: > > l F .init.text 00ba check_mirror > > Done with the help of Coccinelle. The semantic patch checks for local > static non-init functions that are called from an __init function and are > not called from any other function. > > Signed-off-by: Julia Lawall > Acked-by: Michael Grzeschik > --- > drivers/net/arcnet/com90xx.c |2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/net/arcnet/com90xx.c b/drivers/net/arcnet/com90xx.c > index 0d9b45f..81f90c4 100644 > --- a/drivers/net/arcnet/com90xx.c > +++ b/drivers/net/arcnet/com90xx.c > @@ -433,7 +433,7 @@ static void __init com90xx_probe(void) > kfree(iomem); > } > > -static int check_mirror(unsigned long addr, size_t size) > +static int __init check_mirror(unsigned long addr, size_t size) > { > void __iomem *p; > int res = -1; > > -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- |
[PATCH v3] can: c_can: add xceiver enable/disable support
This patch adds support to enable and disable the xceiver in case it's switchable by the regulator framework. Signed-off-by: Michael Grzeschik --- v1 -> v2: - always returning PTR_ERR in case devm_regulator_get fails - removed inline wrapper functions with checks for xceiver == NULL v2 -> v3: - adding documentation for the devicetree binding (already generic) Documentation/devicetree/bindings/net/can/c_can.txt | 2 ++ drivers/net/can/c_can/c_can.c | 12 drivers/net/can/c_can/c_can.h | 1 + 3 files changed, 15 insertions(+) diff --git a/Documentation/devicetree/bindings/net/can/c_can.txt b/Documentation/devicetree/bindings/net/can/c_can.txt index 5a1d8b0..a36fea2 100644 --- a/Documentation/devicetree/bindings/net/can/c_can.txt +++ b/Documentation/devicetree/bindings/net/can/c_can.txt @@ -18,6 +18,8 @@ Optional properties: RAMINIT register, register offset to the RAMINIT register and the CAN instance number (0 offset). +- xceiver-supply: Regulator that powers the CAN transceiver + Note: "ti,hwmods" field is used to fetch the base address and irq resources from TI, omap hwmod data base during device registration. Future plan is to migrate hwmod data base contents into device tree diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index f91b094..0723aeb 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -612,6 +613,10 @@ static int c_can_start(struct net_device *dev) else pinctrl_pm_select_default_state(priv->device); + err = regulator_enable(priv->reg_xceiver); + if (err) + return err; + return 0; } @@ -626,6 +631,9 @@ static void c_can_stop(struct net_device *dev) /* deactivate pins */ pinctrl_pm_select_sleep_state(dev->dev.parent); + + regulator_disable(priv->reg_xceiver); + priv->can.state = CAN_STATE_STOPPED; } @@ -1263,6 +1271,10 @@ int register_c_can_dev(struct net_device *dev) */ pinctrl_pm_select_sleep_state(dev->dev.parent); + priv->reg_xceiver = devm_regulator_get(priv->device, "xceiver"); + if (IS_ERR(priv->reg_xceiver)) + return PTR_ERR(priv->reg_xceiver); + c_can_pm_runtime_enable(priv); dev->flags |= IFF_ECHO; /* we support local echo */ diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h index 8acdc7f..59246e3 100644 --- a/drivers/net/can/c_can/c_can.h +++ b/drivers/net/can/c_can/c_can.h @@ -213,6 +213,7 @@ struct c_can_priv { u32 comm_rcv_high; u32 rxmasked; u32 dlc[C_CAN_MSG_OBJ_TX_NUM]; + struct regulator *reg_xceiver; }; struct net_device *alloc_c_can_dev(void); -- 2.7.0.rc3
[PATCH v3] can: c_can: add xceiver enable/disable support
This patch adds support to enable and disable the xceiver in case it's switchable by the regulator framework. Signed-off-by: Michael Grzeschik <m.grzesc...@pengutronix.de> --- v1 -> v2: - always returning PTR_ERR in case devm_regulator_get fails - removed inline wrapper functions with checks for xceiver == NULL v2 -> v3: - adding documentation for the devicetree binding (already generic) Documentation/devicetree/bindings/net/can/c_can.txt | 2 ++ drivers/net/can/c_can/c_can.c | 12 drivers/net/can/c_can/c_can.h | 1 + 3 files changed, 15 insertions(+) diff --git a/Documentation/devicetree/bindings/net/can/c_can.txt b/Documentation/devicetree/bindings/net/can/c_can.txt index 5a1d8b0..a36fea2 100644 --- a/Documentation/devicetree/bindings/net/can/c_can.txt +++ b/Documentation/devicetree/bindings/net/can/c_can.txt @@ -18,6 +18,8 @@ Optional properties: RAMINIT register, register offset to the RAMINIT register and the CAN instance number (0 offset). +- xceiver-supply: Regulator that powers the CAN transceiver + Note: "ti,hwmods" field is used to fetch the base address and irq resources from TI, omap hwmod data base during device registration. Future plan is to migrate hwmod data base contents into device tree diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index f91b094..0723aeb 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -612,6 +613,10 @@ static int c_can_start(struct net_device *dev) else pinctrl_pm_select_default_state(priv->device); + err = regulator_enable(priv->reg_xceiver); + if (err) + return err; + return 0; } @@ -626,6 +631,9 @@ static void c_can_stop(struct net_device *dev) /* deactivate pins */ pinctrl_pm_select_sleep_state(dev->dev.parent); + + regulator_disable(priv->reg_xceiver); + priv->can.state = CAN_STATE_STOPPED; } @@ -1263,6 +1271,10 @@ int register_c_can_dev(struct net_device *dev) */ pinctrl_pm_select_sleep_state(dev->dev.parent); + priv->reg_xceiver = devm_regulator_get(priv->device, "xceiver"); + if (IS_ERR(priv->reg_xceiver)) + return PTR_ERR(priv->reg_xceiver); + c_can_pm_runtime_enable(priv); dev->flags |= IFF_ECHO; /* we support local echo */ diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h index 8acdc7f..59246e3 100644 --- a/drivers/net/can/c_can/c_can.h +++ b/drivers/net/can/c_can/c_can.h @@ -213,6 +213,7 @@ struct c_can_priv { u32 comm_rcv_high; u32 rxmasked; u32 dlc[C_CAN_MSG_OBJ_TX_NUM]; + struct regulator *reg_xceiver; }; struct net_device *alloc_c_can_dev(void); -- 2.7.0.rc3
Re: [PATCH v2] can: c_can: add xceiver enable/disable support
Hi, On Wed, Jan 20, 2016 at 05:19:18PM +0100, Bjørn Mork wrote: > Michael Grzeschik writes: > > > @@ -1263,6 +1271,10 @@ int register_c_can_dev(struct net_device *dev) > > */ > > pinctrl_pm_select_sleep_state(dev->dev.parent); > > > > + priv->reg_xceiver = devm_regulator_get(priv->device, "xceiver"); > > + if (IS_ERR(priv->reg_xceiver)) > > + return PTR_ERR(priv->reg_xceiver); > > + > > c_can_pm_runtime_enable(priv); > > > > dev->flags |= IFF_ECHO; /* we support local echo */ > > Do you really want to leave priv->reg_xceiver pointing to an ERR_PTR in > case of error? No, therefore the priv->reg_xceiver will be returned in case of error. This codepath is called once on device registration. Michael -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- |
Re: [PATCH v2] can: c_can: add xceiver enable/disable support
Hi, On Wed, Jan 20, 2016 at 05:19:18PM +0100, Bjørn Mork wrote: > Michael Grzeschik <m.grzesc...@pengutronix.de> writes: > > > @@ -1263,6 +1271,10 @@ int register_c_can_dev(struct net_device *dev) > > */ > > pinctrl_pm_select_sleep_state(dev->dev.parent); > > > > + priv->reg_xceiver = devm_regulator_get(priv->device, "xceiver"); > > + if (IS_ERR(priv->reg_xceiver)) > > + return PTR_ERR(priv->reg_xceiver); > > + > > c_can_pm_runtime_enable(priv); > > > > dev->flags |= IFF_ECHO; /* we support local echo */ > > Do you really want to leave priv->reg_xceiver pointing to an ERR_PTR in > case of error? No, therefore the priv->reg_xceiver will be returned in case of error. This codepath is called once on device registration. Michael -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- |
[PATCH][RESEND] MAINTAINERS: add arcnet and take maintainership
Add entry for arcnet to MAINTAINERS file and add myself as the maintainer of the subsystem. Signed-off-by: Michael Grzeschik Cc: da...@davemloft.net Cc: j...@perches.com --- MAINTAINERS | 7 +++ 1 file changed, 7 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 7ba7ab7..0a015f7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -808,6 +808,13 @@ S: Maintained F: drivers/video/fbdev/arcfb.c F: drivers/video/fbdev/core/fb_defio.c +ARCNET NETWORK LAYER +M: Michael Grzeschik +L: net...@vger.kernel.org +S: Maintained +F: drivers/net/arcnet/ +F: include/uapi/linux/if_arcnet.h + ARM MFM AND FLOPPY DRIVERS M: Ian Molton S: Maintained -- 2.5.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH][RESEND] ARCNET: fix hard_header_len limit
For arcnet the bare minimum header only contains the 4 bytes to specify source, dest and offset (1, 1 and 2 bytes respectively). The corresponding struct is struct arc_hardware. The struct archdr contains additionally a union of possible soft headers. When doing $insertusecasehere packets might well include short (or even no?) soft headers. For this reason only use arc_hardware instead of archdr to determine the hard_header_len for an arcnet device. Signed-off-by: Michael Grzeschik --- drivers/net/arcnet/arcnet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c index 10f71c73..816d0e9 100644 --- a/drivers/net/arcnet/arcnet.c +++ b/drivers/net/arcnet/arcnet.c @@ -326,7 +326,7 @@ static void arcdev_setup(struct net_device *dev) dev->type = ARPHRD_ARCNET; dev->netdev_ops = _netdev_ops; dev->header_ops = _header_ops; - dev->hard_header_len = sizeof(struct archdr); + dev->hard_header_len = sizeof(struct arc_hardware); dev->mtu = choose_mtu(); dev->addr_len = ARCNET_ALEN; -- 2.5.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH][RESEND] ARCNET: fix hard_header_len limit
For arcnet the bare minimum header only contains the 4 bytes to specify source, dest and offset (1, 1 and 2 bytes respectively). The corresponding struct is struct arc_hardware. The struct archdr contains additionally a union of possible soft headers. When doing $insertusecasehere packets might well include short (or even no?) soft headers. For this reason only use arc_hardware instead of archdr to determine the hard_header_len for an arcnet device. Signed-off-by: Michael Grzeschik <m.grzesc...@pengutronix.de> --- drivers/net/arcnet/arcnet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c index 10f71c73..816d0e9 100644 --- a/drivers/net/arcnet/arcnet.c +++ b/drivers/net/arcnet/arcnet.c @@ -326,7 +326,7 @@ static void arcdev_setup(struct net_device *dev) dev->type = ARPHRD_ARCNET; dev->netdev_ops = _netdev_ops; dev->header_ops = _header_ops; - dev->hard_header_len = sizeof(struct archdr); + dev->hard_header_len = sizeof(struct arc_hardware); dev->mtu = choose_mtu(); dev->addr_len = ARCNET_ALEN; -- 2.5.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH][RESEND] MAINTAINERS: add arcnet and take maintainership
Add entry for arcnet to MAINTAINERS file and add myself as the maintainer of the subsystem. Signed-off-by: Michael Grzeschik <m.grzesc...@pengutronix.de> Cc: da...@davemloft.net Cc: j...@perches.com --- MAINTAINERS | 7 +++ 1 file changed, 7 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 7ba7ab7..0a015f7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -808,6 +808,13 @@ S: Maintained F: drivers/video/fbdev/arcfb.c F: drivers/video/fbdev/core/fb_defio.c +ARCNET NETWORK LAYER +M: Michael Grzeschik <m.grzesc...@pengutronix.de> +L: net...@vger.kernel.org +S: Maintained +F: drivers/net/arcnet/ +F: include/uapi/linux/if_arcnet.h + ARM MFM AND FLOPPY DRIVERS M: Ian Molton <sp...@f2s.com> S: Maintained -- 2.5.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] ARCNET: fix hard_header_len limit
On Wed, Aug 05, 2015 at 05:34:51PM +0200, Michael Grzeschik wrote: > On Thu, Jul 30, 2015 at 11:16:36AM -0700, David Miller wrote: > > From: Michael Grzeschik > > Date: Thu, 30 Jul 2015 15:34:36 +0200 > > > > > The commit <9c7077622dd9> ("packet: make packet_snd fail on len smaller > > > than l2 header") adds the check for minimum packet length of the used l2. > > > For arcnet the hardware header length is not the complete archdr which > > > includes hard + soft header. This patch changes the length to > > > sizeof(arc_hardware). > > > > > > Signed-off-by: Michael Grzeschik > > > > The hard header len is used for other purposes as well, are you sure > > those don't get broken by this change? > > Its meaning is to represent the amount of the hardware (link layer) > data of one packet. > > Which other purposes do you mean? > Can you point to some code? > > > Code assumes that if the data at the SKB mac pointer is taken, for > > dev->hard_header_len bytes, that is exactly the link layer header. > > And that this can be used to compare two MAC headers, copy the > > MAC header from one packet to another, etc. > > The link layer size of arcnet is 4 bytes long. 1 byte source, 1 byte > dest and two offset bytes. As described by struct arc_hardware in > if_arcnet.h . The above condition is fulfilled when the mac pointer > is 0. > > The following pending bytes of struct archdr have a variable meaning > depending of the used protocol and are represented by an union. > (network layer) > > In the case of raw packets, the payload comes immediately after the > hard_header. > Ping! I have the cleanup patches from Joe Perches and several ARCNET patches on top, waiting to be posted on the list. What is your Opinion to my Maintainer Request I send some weeks ago? Michael -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] ARCNET: fix hard_header_len limit
On Wed, Aug 05, 2015 at 05:34:51PM +0200, Michael Grzeschik wrote: > On Thu, Jul 30, 2015 at 11:16:36AM -0700, David Miller wrote: > > From: Michael Grzeschik <m.grzesc...@pengutronix.de> > > Date: Thu, 30 Jul 2015 15:34:36 +0200 > > > > > The commit <9c7077622dd9> ("packet: make packet_snd fail on len smaller > > > than l2 header") adds the check for minimum packet length of the used l2. > > > For arcnet the hardware header length is not the complete archdr which > > > includes hard + soft header. This patch changes the length to > > > sizeof(arc_hardware). > > > > > > Signed-off-by: Michael Grzeschik <m.grzesc...@pengutronix.de> > > > > The hard header len is used for other purposes as well, are you sure > > those don't get broken by this change? > > Its meaning is to represent the amount of the hardware (link layer) > data of one packet. > > Which other purposes do you mean? > Can you point to some code? > > > Code assumes that if the data at the SKB mac pointer is taken, for > > dev->hard_header_len bytes, that is exactly the link layer header. > > And that this can be used to compare two MAC headers, copy the > > MAC header from one packet to another, etc. > > The link layer size of arcnet is 4 bytes long. 1 byte source, 1 byte > dest and two offset bytes. As described by struct arc_hardware in > if_arcnet.h . The above condition is fulfilled when the mac pointer > is 0. > > The following pending bytes of struct archdr have a variable meaning > depending of the used protocol and are represented by an union. > (network layer) > > In the case of raw packets, the payload comes immediately after the > hard_header. > Ping! I have the cleanup patches from Joe Perches and several ARCNET patches on top, waiting to be posted on the list. What is your Opinion to my Maintainer Request I send some weeks ago? Michael -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] ARCNET: fix hard_header_len limit
On Thu, Jul 30, 2015 at 11:16:36AM -0700, David Miller wrote: > From: Michael Grzeschik > Date: Thu, 30 Jul 2015 15:34:36 +0200 > > > The commit <9c7077622dd9> ("packet: make packet_snd fail on len smaller > > than l2 header") adds the check for minimum packet length of the used l2. > > For arcnet the hardware header length is not the complete archdr which > > includes hard + soft header. This patch changes the length to > > sizeof(arc_hardware). > > > > Signed-off-by: Michael Grzeschik > > The hard header len is used for other purposes as well, are you sure > those don't get broken by this change? Its meaning is to represent the amount of the hardware (link layer) data of one packet. Which other purposes do you mean? Can you point to some code? > Code assumes that if the data at the SKB mac pointer is taken, for > dev->hard_header_len bytes, that is exactly the link layer header. > And that this can be used to compare two MAC headers, copy the > MAC header from one packet to another, etc. The link layer size of arcnet is 4 bytes long. 1 byte source, 1 byte dest and two offset bytes. As described by struct arc_hardware in if_arcnet.h . The above condition is fulfilled when the mac pointer is 0. The following pending bytes of struct archdr have a variable meaning depending of the used protocol and are represented by an union. (network layer) In the case of raw packets, the payload comes immediately after the hard_header. Thanks, Michael -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] ARCNET: fix hard_header_len limit
On Thu, Jul 30, 2015 at 11:16:36AM -0700, David Miller wrote: From: Michael Grzeschik m.grzesc...@pengutronix.de Date: Thu, 30 Jul 2015 15:34:36 +0200 The commit 9c7077622dd9 (packet: make packet_snd fail on len smaller than l2 header) adds the check for minimum packet length of the used l2. For arcnet the hardware header length is not the complete archdr which includes hard + soft header. This patch changes the length to sizeof(arc_hardware). Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de The hard header len is used for other purposes as well, are you sure those don't get broken by this change? Its meaning is to represent the amount of the hardware (link layer) data of one packet. Which other purposes do you mean? Can you point to some code? Code assumes that if the data at the SKB mac pointer is taken, for dev-hard_header_len bytes, that is exactly the link layer header. And that this can be used to compare two MAC headers, copy the MAC header from one packet to another, etc. The link layer size of arcnet is 4 bytes long. 1 byte source, 1 byte dest and two offset bytes. As described by struct arc_hardware in if_arcnet.h . The above condition is fulfilled when the mac pointer is 0. The following pending bytes of struct archdr have a variable meaning depending of the used protocol and are represented by an union. (network layer) In the case of raw packets, the payload comes immediately after the hard_header. Thanks, Michael -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] ARCNET: fix hard_header_len limit
The commit <9c7077622dd9> ("packet: make packet_snd fail on len smaller than l2 header") adds the check for minimum packet length of the used l2. For arcnet the hardware header length is not the complete archdr which includes hard + soft header. This patch changes the length to sizeof(arc_hardware). Signed-off-by: Michael Grzeschik --- drivers/net/arcnet/arcnet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c index 10f71c73..816d0e9 100644 --- a/drivers/net/arcnet/arcnet.c +++ b/drivers/net/arcnet/arcnet.c @@ -326,7 +326,7 @@ static void arcdev_setup(struct net_device *dev) dev->type = ARPHRD_ARCNET; dev->netdev_ops = _netdev_ops; dev->header_ops = _header_ops; - dev->hard_header_len = sizeof(struct archdr); + dev->hard_header_len = sizeof(struct arc_hardware); dev->mtu = choose_mtu(); dev->addr_len = ARCNET_ALEN; -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] MAINTAINERS: add arcnet and take maintainership
Add entry for arcnet to MAINTAINERS file and add myself as the maintainer of the subsystem. Signed-off-by: Michael Grzeschik Cc: da...@davemloft.net Cc: j...@perches.com --- As I have a test coverage of com20020 based arcnet systems I would like to take the responsibility of maintaining the subsystem. MAINTAINERS | 6 ++ 1 file changed, 6 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 9289ecb..08f1a41 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -790,6 +790,12 @@ S: Maintained F: drivers/video/fbdev/arcfb.c F: drivers/video/fbdev/core/fb_defio.c +ARCNET NETWORK LAYER +M: Michael Grzeschik +L: net...@vger.kernel.org +S: Maintained +F: drivers/net/arcnet/ + ARM MFM AND FLOPPY DRIVERS M: Ian Molton S: Maintained -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] MAINTAINERS: add arcnet and take maintainership
Add entry for arcnet to MAINTAINERS file and add myself as the maintainer of the subsystem. Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de Cc: da...@davemloft.net Cc: j...@perches.com --- As I have a test coverage of com20020 based arcnet systems I would like to take the responsibility of maintaining the subsystem. MAINTAINERS | 6 ++ 1 file changed, 6 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 9289ecb..08f1a41 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -790,6 +790,12 @@ S: Maintained F: drivers/video/fbdev/arcfb.c F: drivers/video/fbdev/core/fb_defio.c +ARCNET NETWORK LAYER +M: Michael Grzeschik m.grzesc...@pengutronix.de +L: net...@vger.kernel.org +S: Maintained +F: drivers/net/arcnet/ + ARM MFM AND FLOPPY DRIVERS M: Ian Molton sp...@f2s.com S: Maintained -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] ARCNET: fix hard_header_len limit
The commit 9c7077622dd9 (packet: make packet_snd fail on len smaller than l2 header) adds the check for minimum packet length of the used l2. For arcnet the hardware header length is not the complete archdr which includes hard + soft header. This patch changes the length to sizeof(arc_hardware). Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de --- drivers/net/arcnet/arcnet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c index 10f71c73..816d0e9 100644 --- a/drivers/net/arcnet/arcnet.c +++ b/drivers/net/arcnet/arcnet.c @@ -326,7 +326,7 @@ static void arcdev_setup(struct net_device *dev) dev-type = ARPHRD_ARCNET; dev-netdev_ops = arcnet_netdev_ops; dev-header_ops = arcnet_header_ops; - dev-hard_header_len = sizeof(struct archdr); + dev-hard_header_len = sizeof(struct arc_hardware); dev-mtu = choose_mtu(); dev-addr_len = ARCNET_ALEN; -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 00/21] ARCNET: Defibrillation
Hi, and sorry for the delay. On Wed, Apr 29, 2015 at 08:49:25PM -0700, Joe Perches wrote: > On Mon, 2015-04-27 at 16:57 +0200, Michael Grzeschik wrote: > > Hi! > > > > On Fri, Apr 24, 2015 at 11:58:53PM -0400, David Miller wrote: > > > From: Marc Kleine-Budde > > > Date: Fri, 24 Apr 2015 23:14:41 +0200 > > > > > > > On 04/24/2015 08:47 PM, Joe Perches wrote: > > > >> On Fri, 2015-04-24 at 19:20 +0200, Michael Grzeschik wrote: > > > >>> Hi! > > > >> > > > >> Hello. > > > >> > > > >>> This patch series tries to reanimate the ARCNET hardware layer to be > > > >>> somehow readable and maintainable again. It includes a lot of cleanup > > > >>> patches. It also adds some fixes which leads the layer to become > > > >>> usable > > > >>> again. And as a special treatment it adds more features like correct > > > >>> loading and unloading of the com20020 card. > > > >> > > > >> Wow. Good for you, but why? Does anyone still use these? > > > > > > > > Yes, there are parts of the industry where "old" machines are > > > > retrofitted with new hardware...and a lot of these machines still talk > > > > ARCNET :) > > > > > > But the real issue is, this layer is development wise in the same > > > category as the IDE layer. > > > > > > Any non-trivial change is nothing but pure risk, especially given the > > > low level of test coverage the code gets. > > > > Do you count coding style patches as non-trivial or trivial > > patches? > > > > > So I really only want to see the most critical obvious bug fixes > > > submitted for this layer and drivers. > > > > The cleanup changes I submitted should not change the actual behaviour. > > Replacing the register access macros with their equivalent outb/inb > > seems pretty obvious. What is your opinion on those? > > > > I see that the "ARCNET: whitespace, tab and codingstyle fixes" patch is > > pretty mixed up and not very reliable. But Joe has sent me a nice series > > for the cleanup. > > > > > And no I will not accept an argument stating that you have to > > > restructure and clean this code up in order to fix the bugs. That's > > > bogus. > > > > OK. > > > > I have the following patches in this series which fix bugs found during > > my development: > > > > com20020-pci: add dev_port for udev handling > > ARCNET: fix hard_header_len limit > > ARCNET: com20020: add enable and disable device on open/close > > > > I would send a new series containing only those patches with more > > detailed patch descriptions, if that's fine with you? > > I was away for a few days and while out I did another > restructuring of all the inb/outb/readb/writeb code > removing all the A macros. It removes all the > dependencies on ioaddr and names all the offsets with > new defines. > > I could post if you like. Sure, you should do that! I will rework my patches on top of them. > I think it's a lot cleaner and easier to read. OK! I would like to know what David things about the whole work. Thanks, Michael -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 00/21] ARCNET: Defibrillation
Hi, and sorry for the delay. On Wed, Apr 29, 2015 at 08:49:25PM -0700, Joe Perches wrote: On Mon, 2015-04-27 at 16:57 +0200, Michael Grzeschik wrote: Hi! On Fri, Apr 24, 2015 at 11:58:53PM -0400, David Miller wrote: From: Marc Kleine-Budde m...@pengutronix.de Date: Fri, 24 Apr 2015 23:14:41 +0200 On 04/24/2015 08:47 PM, Joe Perches wrote: On Fri, 2015-04-24 at 19:20 +0200, Michael Grzeschik wrote: Hi! Hello. This patch series tries to reanimate the ARCNET hardware layer to be somehow readable and maintainable again. It includes a lot of cleanup patches. It also adds some fixes which leads the layer to become usable again. And as a special treatment it adds more features like correct loading and unloading of the com20020 card. Wow. Good for you, but why? Does anyone still use these? Yes, there are parts of the industry where old machines are retrofitted with new hardware...and a lot of these machines still talk ARCNET :) But the real issue is, this layer is development wise in the same category as the IDE layer. Any non-trivial change is nothing but pure risk, especially given the low level of test coverage the code gets. Do you count coding style patches as non-trivial or trivial patches? So I really only want to see the most critical obvious bug fixes submitted for this layer and drivers. The cleanup changes I submitted should not change the actual behaviour. Replacing the register access macros with their equivalent outb/inb seems pretty obvious. What is your opinion on those? I see that the ARCNET: whitespace, tab and codingstyle fixes patch is pretty mixed up and not very reliable. But Joe has sent me a nice series for the cleanup. And no I will not accept an argument stating that you have to restructure and clean this code up in order to fix the bugs. That's bogus. OK. I have the following patches in this series which fix bugs found during my development: com20020-pci: add dev_port for udev handling ARCNET: fix hard_header_len limit ARCNET: com20020: add enable and disable device on open/close I would send a new series containing only those patches with more detailed patch descriptions, if that's fine with you? I was away for a few days and while out I did another restructuring of all the inb/outb/readb/writeb code removing all the AFOO macros. It removes all the dependencies on ioaddr and names all the offsets with new defines. I could post if you like. Sure, you should do that! I will rework my patches on top of them. I think it's a lot cleaner and easier to read. OK! I would like to know what David things about the whole work. Thanks, Michael -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 00/21] ARCNET: Defibrillation
Hi! On Fri, Apr 24, 2015 at 11:58:53PM -0400, David Miller wrote: > From: Marc Kleine-Budde > Date: Fri, 24 Apr 2015 23:14:41 +0200 > > > On 04/24/2015 08:47 PM, Joe Perches wrote: > >> On Fri, 2015-04-24 at 19:20 +0200, Michael Grzeschik wrote: > >>> Hi! > >> > >> Hello. > >> > >>> This patch series tries to reanimate the ARCNET hardware layer to be > >>> somehow readable and maintainable again. It includes a lot of cleanup > >>> patches. It also adds some fixes which leads the layer to become usable > >>> again. And as a special treatment it adds more features like correct > >>> loading and unloading of the com20020 card. > >> > >> Wow. Good for you, but why? Does anyone still use these? > > > > Yes, there are parts of the industry where "old" machines are > > retrofitted with new hardware...and a lot of these machines still talk > > ARCNET :) > > But the real issue is, this layer is development wise in the same > category as the IDE layer. > > Any non-trivial change is nothing but pure risk, especially given the > low level of test coverage the code gets. Do you count coding style patches as non-trivial or trivial patches? > So I really only want to see the most critical obvious bug fixes > submitted for this layer and drivers. The cleanup changes I submitted should not change the actual behaviour. Replacing the register access macros with their equivalent outb/inb seems pretty obvious. What is your opinion on those? I see that the "ARCNET: whitespace, tab and codingstyle fixes" patch is pretty mixed up and not very reliable. But Joe has sent me a nice series for the cleanup. > And no I will not accept an argument stating that you have to > restructure and clean this code up in order to fix the bugs. That's > bogus. OK. I have the following patches in this series which fix bugs found during my development: com20020-pci: add dev_port for udev handling ARCNET: fix hard_header_len limit ARCNET: com20020: add enable and disable device on open/close I would send a new series containing only those patches with more detailed patch descriptions, if that's fine with you? Regards, Michael -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 06/21] ARCNET: com20020: remove unneeded macros
On Fri, Apr 24, 2015 at 04:04:45PM -0700, Joe Perches wrote: > On Fri, 2015-04-24 at 19:20 +0200, Michael Grzeschik wrote: > > The macros SET_SUBADR, ARCRESET, ARCRESET0, ACOMMAND, ASTATUS, AINTMASK > > and ADIAGSTATUS are unnecessary indirections to the use of registers. > > This patch removes them and improves the readability of the code. > > This breaks compilation. > > Please compile test your patches before sending them. Sorry, but I can not reproduce this break. What was your base you applied this series on? Can you send me the failure you get? Thanks, Michael -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 00/21] ARCNET: Defibrillation
Hi! On Fri, Apr 24, 2015 at 11:58:53PM -0400, David Miller wrote: From: Marc Kleine-Budde m...@pengutronix.de Date: Fri, 24 Apr 2015 23:14:41 +0200 On 04/24/2015 08:47 PM, Joe Perches wrote: On Fri, 2015-04-24 at 19:20 +0200, Michael Grzeschik wrote: Hi! Hello. This patch series tries to reanimate the ARCNET hardware layer to be somehow readable and maintainable again. It includes a lot of cleanup patches. It also adds some fixes which leads the layer to become usable again. And as a special treatment it adds more features like correct loading and unloading of the com20020 card. Wow. Good for you, but why? Does anyone still use these? Yes, there are parts of the industry where old machines are retrofitted with new hardware...and a lot of these machines still talk ARCNET :) But the real issue is, this layer is development wise in the same category as the IDE layer. Any non-trivial change is nothing but pure risk, especially given the low level of test coverage the code gets. Do you count coding style patches as non-trivial or trivial patches? So I really only want to see the most critical obvious bug fixes submitted for this layer and drivers. The cleanup changes I submitted should not change the actual behaviour. Replacing the register access macros with their equivalent outb/inb seems pretty obvious. What is your opinion on those? I see that the ARCNET: whitespace, tab and codingstyle fixes patch is pretty mixed up and not very reliable. But Joe has sent me a nice series for the cleanup. And no I will not accept an argument stating that you have to restructure and clean this code up in order to fix the bugs. That's bogus. OK. I have the following patches in this series which fix bugs found during my development: com20020-pci: add dev_port for udev handling ARCNET: fix hard_header_len limit ARCNET: com20020: add enable and disable device on open/close I would send a new series containing only those patches with more detailed patch descriptions, if that's fine with you? Regards, Michael -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 06/21] ARCNET: com20020: remove unneeded macros
On Fri, Apr 24, 2015 at 04:04:45PM -0700, Joe Perches wrote: On Fri, 2015-04-24 at 19:20 +0200, Michael Grzeschik wrote: The macros SET_SUBADR, ARCRESET, ARCRESET0, ACOMMAND, ASTATUS, AINTMASK and ADIAGSTATUS are unnecessary indirections to the use of registers. This patch removes them and improves the readability of the code. This breaks compilation. Please compile test your patches before sending them. Sorry, but I can not reproduce this break. What was your base you applied this series on? Can you send me the failure you get? Thanks, Michael -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 19/21] ARCNET: com20020: add enable and disable device on open/close
This patch changes the driver to properly work with the linux netif interface. The controller gets enabled on open and disabled on close. Therefor it removes every bogus start of the xceiver. It only gets enabled on com20020_open and disabled on com20020_close. Signed-off-by: Michael Grzeschik --- drivers/net/arcnet/com20020.c | 41 ++--- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/drivers/net/arcnet/com20020.c b/drivers/net/arcnet/com20020.c index 1dbc748..713eb5d 100644 --- a/drivers/net/arcnet/com20020.c +++ b/drivers/net/arcnet/com20020.c @@ -118,7 +118,7 @@ int com20020_check(struct net_device *dev) outb(STARTIOcmd, ioaddr + _COMMAND); } - lp->config = TXENcfg | (lp->timeout << 3) | (lp->backplane << 2) | SUB_NODE; + lp->config = (lp->timeout << 3) | (lp->backplane << 2) | SUB_NODE; /* set node ID to 0x42 (but transmitter is disabled, so it's okay) */ outb(lp->config, ioaddr + _CONFIG); outb(0x42, ioaddr + _XREG); @@ -131,11 +131,6 @@ int com20020_check(struct net_device *dev) } BUGMSG(D_INIT_REASONS, "status after reset: %X\n", status); - /* Enable TX */ - lp->config |= TXENcfg; - outb(lp->config, ioaddr + _CONFIG); - outb(inb(ioaddr + 8), ioaddr + _XREG); - outb((CFLAGScmd | RESETclear | CONFIGclear), ioaddr + _COMMAND); status = inb(ioaddr + _STATUS); @@ -169,9 +164,33 @@ static int com20020_set_hwaddr(struct net_device *dev, void *addr) return 0; } +int com20020_netdev_open(struct net_device *dev) +{ + int ioaddr = dev->base_addr; + struct arcnet_local *lp = netdev_priv(dev); + + lp->config |= TXENcfg; + outb(lp->config, ioaddr + _CONFIG); + + return arcnet_open(dev); +} + +int com20020_netdev_close(struct net_device *dev) +{ + int ioaddr = dev->base_addr; + struct arcnet_local *lp = netdev_priv(dev); + + arcnet_close(dev); + + /* disable transmitter */ + lp->config &= ~TXENcfg; + outb(lp->config, ioaddr + _CONFIG); + return 0; +} + const struct net_device_ops com20020_netdev_ops = { - .ndo_open = arcnet_open, - .ndo_stop = arcnet_close, + .ndo_open = com20020_netdev_open, + .ndo_stop = com20020_netdev_close, .ndo_start_xmit = arcnet_send_packet, .ndo_tx_timeout = arcnet_timeout, .ndo_set_mac_address = com20020_set_hwaddr, @@ -216,8 +235,8 @@ int com20020_found(struct net_device *dev, int shared) outb(STARTIOcmd, ioaddr + _COMMAND); } - lp->config = TXENcfg | (lp->timeout << 3) | (lp->backplane << 2) | SUB_NODE; - /* Default 0x38 + register: Node ID */ + lp->config = (lp->timeout << 3) | (lp->backplane << 2) | SUB_NODE; + /* Default 0x18 + register: Node ID */ outb(lp->config, ioaddr + _CONFIG); outb(dev->dev_addr[0], ioaddr + _XREG); @@ -270,7 +289,7 @@ static int com20020_reset(struct net_device *dev, int really_reset) dev->name, inb(ioaddr + _STATUS)); BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__); - lp->config = TXENcfg | (lp->timeout << 3) | (lp->backplane << 2); + lp->config |= (lp->timeout << 3) | (lp->backplane << 2); /* power-up defaults */ outb(lp->config, ioaddr + _CONFIG); BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__); -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 01/21] com20020-pci: add dev_port for udev handling
This patch sets the dev_port according to the index of the card. This can be used by udev to name the ports in userspace. Signed-off-by: Michael Grzeschik --- drivers/net/arcnet/com20020-pci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c index 96edc13..9fa4eee 100644 --- a/drivers/net/arcnet/com20020-pci.c +++ b/drivers/net/arcnet/com20020-pci.c @@ -96,6 +96,7 @@ static int com20020pci_probe(struct pci_dev *pdev, const struct pci_device_id *i ret = -ENOMEM; goto out_port; } + dev->dev_port = i; dev->netdev_ops = _netdev_ops; -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 02/21] ARCNET: fix hard_header_len limit
The commit <9c7077622dd9> ("packet: make packet_snd fail on len smaller than l2 header") adds the check for minimum packet length of the used l2. For arcnet the hardware header length is not the complete archdr which includes hard + soft header. This patch changes the length to sizeof(arc_hardware). Signed-off-by: Michael Grzeschik --- drivers/net/arcnet/arcnet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c index 10f71c73..816d0e9 100644 --- a/drivers/net/arcnet/arcnet.c +++ b/drivers/net/arcnet/arcnet.c @@ -326,7 +326,7 @@ static void arcdev_setup(struct net_device *dev) dev->type = ARPHRD_ARCNET; dev->netdev_ops = _netdev_ops; dev->header_ops = _header_ops; - dev->hard_header_len = sizeof(struct archdr); + dev->hard_header_len = sizeof(struct arc_hardware); dev->mtu = choose_mtu(); dev->addr_len = ARCNET_ALEN; -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 04/21] ARCNET: whitespace, tab and codingstyle fixes
This patch removes trailing whitespaces in the whole the ARCNET layer. It also replaces the use of space with tabs and changes fixes the codingstyle on those lines. Signed-off-by: Michael Grzeschik --- drivers/net/arcnet/arc-rawmode.c | 4 +- drivers/net/arcnet/arc-rimi.c | 2 +- drivers/net/arcnet/arcnet.c | 116 +++ drivers/net/arcnet/com20020-isa.c | 2 +- drivers/net/arcnet/com20020.c | 13 +- drivers/net/arcnet/com20020_cs.c | 298 ++ drivers/net/arcnet/com90io.c | 2 +- drivers/net/arcnet/com90xx.c | 4 +- include/linux/arcdevice.h | 7 +- include/linux/com20020.h | 4 +- include/uapi/linux/if_arcnet.h| 48 +++--- 11 files changed, 239 insertions(+), 261 deletions(-) diff --git a/drivers/net/arcnet/arc-rawmode.c b/drivers/net/arcnet/arc-rawmode.c index 705e6ce..b603470 100644 --- a/drivers/net/arcnet/arc-rawmode.c +++ b/drivers/net/arcnet/arc-rawmode.c @@ -1,6 +1,6 @@ /* * Linux ARCnet driver - "raw mode" packet encapsulation (no soft headers) - * + * * Written 1994-1999 by Avery Pennarun. * Derived from skeleton.c by Donald Becker. * @@ -150,7 +150,7 @@ static int build_header(struct sk_buff *skb, struct net_device *dev, /* see linux/net/ethernet/eth.c to see where I got the following */ if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) { - /* + /* * FIXME: fill in the last byte of the dest ipaddr here to better * comply with RFC1051 in "noarp" mode. */ diff --git a/drivers/net/arcnet/arc-rimi.c b/drivers/net/arcnet/arc-rimi.c index b8b4c7b..4c95d3c 100644 --- a/drivers/net/arcnet/arc-rimi.c +++ b/drivers/net/arcnet/arc-rimi.c @@ -1,6 +1,6 @@ /* * Linux ARCnet driver - "RIM I" (entirely mem-mapped) cards - * + * * Written 1994-1999 by Avery Pennarun. * Written 1999-2000 by Martin Mares . * Derived from skeleton.c by Donald Becker. diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c index 816d0e9..f83034c 100644 --- a/drivers/net/arcnet/arcnet.c +++ b/drivers/net/arcnet/arcnet.c @@ -1,6 +1,6 @@ /* * Linux ARCnet driver - device-independent routines - * + * * Written 1997 by David Woodhouse. * Written 1994-1999 by Avery Pennarun. * Written 1999-2000 by Martin Mares . @@ -20,12 +20,12 @@ * modified by SRC, incorporated herein by reference. * * ** - * + * * The change log is now in a file called ChangeLog in this directory. * * Sources: * - Crynwr arcnet.com/arcether.com packet drivers. - * - arcnet.c v0.00 dated 1/1/94 and apparently by + * - arcnet.c v0.00 dated 1/1/94 and apparently by * Donald Becker - it didn't work :) * - skeleton.c v0.05 dated 11/16/93 by Donald Becker * (from Linux Kernel 1.1.45) @@ -168,7 +168,6 @@ void arcnet_dump_skb(struct net_device *dev, EXPORT_SYMBOL(arcnet_dump_skb); #endif - /* * Dump the contents of an ARCnet buffer */ @@ -184,11 +183,11 @@ static void arcnet_dump_packet(struct net_device *dev, int bufnum, /* hw.copy_from_card expects IRQ context so take the IRQ lock to keep it single threaded */ - if(take_arcnet_lock) + if (take_arcnet_lock) spin_lock_irqsave(>lock, flags); lp->hw.copy_from_card(dev, bufnum, 0, buf, 512); - if(take_arcnet_lock) + if (take_arcnet_lock) spin_unlock_irqrestore(>lock, flags); /* if the offset[0] byte is nonzero, this is a 256-byte packet */ @@ -229,11 +228,10 @@ void arcnet_unregister_proto(struct ArcProto *proto) } } - /* * Add a buffer to the queue. Only the interrupt handler is allowed to do * this, unless interrupts are disabled. - * + * * Note: we don't check for a full queue, since there aren't enough buffers * to more than fill it. */ @@ -248,13 +246,12 @@ static void release_arcbuf(struct net_device *dev, int bufnum) BUGLVL(D_DURING) { BUGMSG(D_DURING, "release_arcbuf: freed #%d; buffer queue is now: ", bufnum); - for (i = lp->next_buf; i != lp->first_free_buf; i = (i+1) % 5) + for (i = lp->next_buf; i != lp->first_free_buf; i = (i + 1) % 5) BUGMSG2(D_DURING, "#%d ", lp->buf_queue[i]); BUGMSG2(D_DURING, "\n"); } } - /* * Get a buffer from the queue. If this returns -1, there are no buffers * available. @@ -284,7 +281,7 @@ static int get_arcbuf(struct net_device *dev) BUGLVL(D_DURING) { BUGMSG(D_DURING, "get_arcbuf: got #%d; buffer queue is now: ", buf); - for (i = lp->next_buf; i != lp->first_free_buf; i = (i+1) % 5) + for (i = lp->next_buf; i != lp->first_free_buf; i = (i + 1
[PATCH 10/21] ARCNET: com20020: fix ioaddr prefixes
This patch removes the use of the variable ioaddr in the macros and uses it directly in the calling functions. This improves the readability of the code and changes the macros to be used as offsets. Signed-off-by: Michael Grzeschik --- drivers/net/arcnet/com20020-isa.c | 2 +- drivers/net/arcnet/com20020.c | 89 --- drivers/net/arcnet/com20020_cs.c | 6 +-- include/linux/com20020.h | 20 - 4 files changed, 59 insertions(+), 58 deletions(-) diff --git a/drivers/net/arcnet/com20020-isa.c b/drivers/net/arcnet/com20020-isa.c index c674511..3e5be24 100644 --- a/drivers/net/arcnet/com20020-isa.c +++ b/drivers/net/arcnet/com20020-isa.c @@ -68,7 +68,7 @@ static int __init com20020isa_probe(struct net_device *dev) ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1); return -ENXIO; } - if (inb(_STATUS) == 0xFF) { + if (inb(ioaddr + _STATUS) == 0xFF) { BUGMSG(D_NORMAL, "IO address %x empty\n", ioaddr); err = -ENODEV; goto out; diff --git a/drivers/net/arcnet/com20020.c b/drivers/net/arcnet/com20020.c index ed0cdd3..4b4bb96 100644 --- a/drivers/net/arcnet/com20020.c +++ b/drivers/net/arcnet/com20020.c @@ -63,11 +63,11 @@ static void com20020_copy_from_card(struct net_device *dev, int bufnum, int ioaddr = dev->base_addr, ofs = 512 * bufnum + offset; /* set up the address register */ - outb((ofs >> 8) | RDDATAflag | AUTOINCflag, _ADDR_HI); - outb(ofs & 0xff, _ADDR_LO); + outb((ofs >> 8) | RDDATAflag | AUTOINCflag, ioaddr + _ADDR_HI); + outb(ofs & 0xff, ioaddr + _ADDR_LO); /* copy the data */ - TIME("insb", count, insb(_MEMDATA, buf, count)); + TIME("insb", count, insb(ioaddr + _MEMDATA, buf, count)); } @@ -77,11 +77,11 @@ static void com20020_copy_to_card(struct net_device *dev, int bufnum, int ioaddr = dev->base_addr, ofs = 512 * bufnum + offset; /* set up the address register */ - outb((ofs >> 8) | AUTOINCflag, _ADDR_HI); - outb(ofs & 0xff, _ADDR_LO); + outb((ofs >> 8) | AUTOINCflag, ioaddr + _ADDR_HI); + outb(ofs & 0xff, ioaddr + _ADDR_LO); /* copy the data */ - TIME("outsb", count, outsb(_MEMDATA, buf, count)); + TIME("outsb", count, outsb(ioaddr + _MEMDATA, buf, count)); } @@ -92,9 +92,9 @@ int com20020_check(struct net_device *dev) struct arcnet_local *lp = netdev_priv(dev); /* reset the card */ - outb(0x18 | 0x80, _CONFIG); + outb(0x18 | 0x80, ioaddr + _CONFIG); udelay(5); - outb(0x18, _CONFIG); + outb(0x18, ioaddr + _CONFIG); mdelay(RESETtime); lp->setup = lp->clockm ? 0 : (lp->clockp << 1); @@ -105,25 +105,25 @@ int com20020_check(struct net_device *dev) lp->setup = lp->setup | P1MODE; lp->config = (lp->config & ~0x03) | SUB_SETUP1; - outb(lp->config, _CONFIG); - outb(lp->setup, _XREG); + outb(lp->config, ioaddr + _CONFIG); + outb(lp->setup, ioaddr + _XREG); if (lp->clockm != 0) { - outb(SUB_SETUP2, _SUBADR); - outb(lp->setup2, _XREG); + outb(SUB_SETUP2, ioaddr + _SUBADR); + outb(lp->setup2, ioaddr + _XREG); /* must now write the magic "restart operation" command */ mdelay(1); - outb(0x18, _COMMAND); + outb(0x18, ioaddr + _COMMAND); } lp->config = 0x21 | (lp->timeout << 3) | (lp->backplane << 2); /* set node ID to 0x42 (but transmitter is disabled, so it's okay) */ - outb(lp->config, _CONFIG); + outb(lp->config, ioaddr + _CONFIG); outb(0x42, ioaddr + BUS_ALIGN*7); - status = inb(_STATUS); + status = inb(ioaddr + _STATUS); if ((status & 0x99) != (NORXflag | TXFREEflag | RESETflag)) { BUGMSG(D_NORMAL, "status invalid (%Xh).\n", status); @@ -132,20 +132,21 @@ int com20020_check(struct net_device *dev) BUGMSG(D_INIT_REASONS, "status after reset: %X\n", status); /* Enable TX */ - outb(0x39, _CONFIG); + outb(0x39, ioaddr + _CONFIG); outb(inb(ioaddr + BUS_ALIGN*8), ioaddr + BUS_ALIGN*7); - outb((CFLAGScmd | RESETclear | CONFIGclear), _COMMAND); + outb((CFLAGScmd | RESETclear | CONFIGclear), ioaddr + _COMMAND); - status = inb(_STATUS); + status = inb(ioaddr + _STATUS); BUGMSG(D_INIT_REASONS, "status after reset acknowledged: %X\n", status); /* Read first location of memory */ - outb(0 | RDDATAflag | AUTOINCflag, _ADDR_HI); - outb(0, _ADDR_LO); +
[PATCH 15/21] ARCNET: capmode: remove extra function and use C99 in struct
This patch cleans the capmode protocol module. It removes the obsolete function arcnet_cap_init and uses the C99 struct definition. It also replaces printk with pr_info. Signed-off-by: Michael Grzeschik --- drivers/net/arcnet/capmode.c | 28 +++- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/drivers/net/arcnet/capmode.c b/drivers/net/arcnet/capmode.c index b6868a2..91ec9fa 100644 --- a/drivers/net/arcnet/capmode.c +++ b/drivers/net/arcnet/capmode.c @@ -229,22 +229,22 @@ free_outskb: return 0; } -static struct ArcProto capmode_proto = -{ - 'r', - XMTU, - 0, - rx, - build_header, - prepare_tx, - NULL, - ack_tx +static struct ArcProto capmode_proto = { + .suffix = 'r', + .mtu= XMTU, + .rx = rx, + .build_header = build_header, + .prepare_tx = prepare_tx, + .continue_tx= NULL, + .ack_tx = ack_tx }; -static void arcnet_cap_init(void) +static int __init capmode_module_init(void) { int count; + pr_info(VERSION); + for (count = 1; count <= 8; count++) if (arc_proto_map[count] == arc_proto_default) arc_proto_map[count] = _proto; @@ -255,12 +255,6 @@ static void arcnet_cap_init(void) arc_proto_default = _proto; arc_raw_proto = _proto; -} - -static int __init capmode_module_init(void) -{ - printk(VERSION); - arcnet_cap_init(); return 0; } -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 16/21] ARCNET: capmode: move dev_free_skb to its only user
The call for dev_free_skb is done only once. This patch moves its call to its only user and removes the obsolete condition variable. Signed-off-by: Michael Grzeschik --- drivers/net/arcnet/arcnet.c | 10 ++ 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c index 4990b0d..5eec14d 100644 --- a/drivers/net/arcnet/arcnet.c +++ b/drivers/net/arcnet/arcnet.c @@ -541,7 +541,7 @@ netdev_tx_t arcnet_send_packet(struct sk_buff *skb, struct ArcProto *proto; int txbuf; unsigned long flags; - int freeskb, retval; + int retval; BUGMSG(D_DURING, "transmit requested (status=%Xh, txbufs=%d/%d, len=%d, protocol %x)\n", @@ -578,15 +578,13 @@ netdev_tx_t arcnet_send_packet(struct sk_buff *skb, /* done right away and we don't want to acknowledge the package later - forget about it now */ dev->stats.tx_bytes += skb->len; - freeskb = 1; + dev_kfree_skb(skb); } else { /* do it the 'split' way */ lp->outgoing.proto = proto; lp->outgoing.skb = skb; lp->outgoing.pkt = pkt; - freeskb = 0; - if (proto->continue_tx && proto->continue_tx(dev, txbuf)) { BUGMSG(D_NORMAL, @@ -598,7 +596,6 @@ netdev_tx_t arcnet_send_packet(struct sk_buff *skb, lp->next_tx = txbuf; } else { retval = NETDEV_TX_BUSY; - freeskb = 0; } BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n", @@ -613,9 +610,6 @@ netdev_tx_t arcnet_send_packet(struct sk_buff *skb, __FILE__, __LINE__, __func__, lp->hw.status(dev)); spin_unlock_irqrestore(>lock, flags); - if (freeskb) { - dev_kfree_skb(skb); - } return retval; /* no need to try again */ } -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 21/21] ARCNET: com20020-pci: add rotary index support
The EAE PLX-PCI card has a special rotary encoder to configure the address of every card individually. We take this information for the initial setup of the cards dev_id. Signed-off-by: Michael Grzeschik --- drivers/net/arcnet/com20020-pci.c | 28 include/linux/com20020.h | 4 2 files changed, 32 insertions(+) diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c index de8c894..308adb9 100644 --- a/drivers/net/arcnet/com20020-pci.c +++ b/drivers/net/arcnet/com20020-pci.c @@ -67,6 +67,7 @@ static void com20020pci_remove(struct pci_dev *pdev); static int com20020pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct com20020_pci_card_info *ci; + struct com20020_pci_channel_map *mm; struct net_device *dev; struct arcnet_local *lp; struct com20020_priv *priv; @@ -83,9 +84,21 @@ static int com20020pci_probe(struct pci_dev *pdev, const struct pci_device_id *i ci = (struct com20020_pci_card_info *)id->driver_data; priv->ci = ci; + mm = >misc_map; INIT_LIST_HEAD(>list_dev); + if (mm->size) { + ioaddr = pci_resource_start(pdev, mm->bar) + mm->offset; + r = devm_request_region(>dev, ioaddr, mm->size, + "com20020-pci"); + if (!r) { + pr_err("IO region %xh-%xh already allocated.\n", + ioaddr, ioaddr + mm->size - 1); + return -EBUSY; + } + priv->misc = ioaddr; + } for (i = 0; i < ci->devcount; i++) { struct com20020_pci_channel_map *cm = >chan_map_tbl[i]; @@ -132,6 +145,9 @@ static int com20020pci_probe(struct pci_dev *pdev, const struct pci_device_id *i lp->timeout = timeout; lp->hw.owner = THIS_MODULE; + /* Get the dev_id from the PLX rotary coder */ + dev->dev_id = inb(priv->misc + ci->rotary) >> 4; + if (inb(_STATUS) == 0xFF) { pr_err("IO address %Xh is empty!\n", ioaddr); ret = -EIO; @@ -237,6 +253,12 @@ static struct com20020_pci_card_info card_info_eae_arc1 = { .size = 0x08, }, }, + .misc_map = { + .bar = 2, + .offset = 0x10, + .size = 0x04, + }, + .rotary = 0x0, .flags = ARC_CAN_10MBIT, }; @@ -254,6 +276,12 @@ static struct com20020_pci_card_info card_info_eae_ma1 = { .size = 0x08, } }, + .misc_map = { + .bar = 2, + .offset = 0x10, + .size = 0x04, + }, + .rotary = 0x0, .flags = ARC_CAN_10MBIT, }; diff --git a/include/linux/com20020.h b/include/linux/com20020.h index 939d69d..8028ef8 100644 --- a/include/linux/com20020.h +++ b/include/linux/com20020.h @@ -47,6 +47,9 @@ struct com20020_pci_card_info { int devcount; struct com20020_pci_channel_map chan_map_tbl[PLX_PCI_MAX_CARDS]; + struct com20020_pci_channel_map misc_map; + + int rotary; unsigned int flags; }; @@ -54,6 +57,7 @@ struct com20020_pci_card_info { struct com20020_priv { struct com20020_pci_card_info *ci; struct list_head list_dev; + int __iomem misc; }; struct com20020_dev { -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 08/21] ARCNET: com90io: remove unneeded macros
The simple macros ARCRESET, ACOMMAND, ASTATUS, AINTMASK are unnecessary indirections to the use of registers. This patch removes them and improves the readability of the code. Signed-off-by: Michael Grzeschik --- drivers/net/arcnet/com90io.c | 36 +--- 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/drivers/net/arcnet/com90io.c b/drivers/net/arcnet/com90io.c index b1279af..6bc6366 100644 --- a/drivers/net/arcnet/com90io.c +++ b/drivers/net/arcnet/com90io.c @@ -69,16 +69,6 @@ static void com90io_copy_from_card(struct net_device *dev, int bufnum, int offse #define _ADDR_LO (ioaddr+14) #define _CONFIG (ioaddr+2)/* Configuration register */ -#undef ASTATUS -#undef ACOMMAND -#undef AINTMASK - -#define ASTATUS() inb(_STATUS) -#define ACOMMAND(cmd) outb((cmd),_COMMAND) -#define AINTMASK(msk) outb((msk),_INTMASK) -#define SETCONF() outb((lp->config),_CONFIG) - - / * * * IO-mapped operation routines * @@ -164,14 +154,14 @@ static int __init com90io_probe(struct net_device *dev) ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1); return -ENXIO; } - if (ASTATUS() == 0xFF) { + if (inb(_STATUS) == 0xFF) { BUGMSG(D_INIT_REASONS, "IO address %x empty\n", ioaddr); goto err_out; } inb(_RESET); mdelay(RESETtime); - status = ASTATUS(); + status = inb(_STATUS); if ((status & 0x9D) != (NORXflag | RECONflag | TXFREEflag | RESETflag)) { BUGMSG(D_INIT_REASONS, "Status invalid (%Xh).\n", status); @@ -179,11 +169,11 @@ static int __init com90io_probe(struct net_device *dev) } BUGMSG(D_INIT_REASONS, "Status after reset: %X\n", status); - ACOMMAND(CFLAGScmd | RESETclear | CONFIGclear); + outb(CFLAGScmd | RESETclear | CONFIGclear, _COMMAND); BUGMSG(D_INIT_REASONS, "Status after reset acknowledged: %X\n", status); - status = ASTATUS(); + status = inb(_STATUS); if (status & RESETflag) { BUGMSG(D_INIT_REASONS, "Eternal reset (status=%Xh)\n", status); @@ -259,7 +249,7 @@ static int __init com90io_found(struct net_device *dev) lp->hw.copy_from_card = com90io_copy_from_card; lp->config = (0x16 | IOMAPflag) & ~ENABLE16flag; - SETCONF(); + outb(lp->config, _CONFIG); /* get and check the station ID from offset 1 in shmem */ @@ -293,7 +283,7 @@ static int com90io_reset(struct net_device *dev, int really_reset) struct arcnet_local *lp = netdev_priv(dev); short ioaddr = dev->base_addr; - BUGMSG(D_INIT, "Resetting %s (status=%02Xh)\n", dev->name, ASTATUS()); + BUGMSG(D_INIT, "Resetting %s (status=%02Xh)\n", dev->name, inb(_STATUS)); if (really_reset) { /* reset the card */ @@ -302,10 +292,10 @@ static int com90io_reset(struct net_device *dev, int really_reset) } /* Set the thing to IO-mapped, 8-bit mode */ lp->config = (0x1C | IOMAPflag) & ~ENABLE16flag; - SETCONF(); + outb(lp->config, _CONFIG); - ACOMMAND(CFLAGScmd | RESETclear); /* clear flags & end reset */ - ACOMMAND(CFLAGScmd | CONFIGclear); + outb(CFLAGScmd | RESETclear, _COMMAND); /* clear flags & end reset */ + outb(CFLAGScmd | CONFIGclear, _COMMAND); /* verify that the ARCnet signature byte is present */ if (get_buffer_byte(dev, 0) != TESTvalue) { @@ -313,7 +303,7 @@ static int com90io_reset(struct net_device *dev, int really_reset) return 1; } /* enable extended (512-byte) packets */ - ACOMMAND(CONFIGcmd | EXTconf); + outb(CONFIGcmd | EXTconf, _COMMAND); /* done! return success. */ return 0; @@ -324,7 +314,7 @@ static void com90io_command(struct net_device *dev, int cmd) { short ioaddr = dev->base_addr; - ACOMMAND(cmd); + outb(cmd, _COMMAND); } @@ -332,7 +322,7 @@ static int com90io_status(struct net_device *dev) { short ioaddr = dev->base_addr; - return ASTATUS(); + return inb(_STATUS); } @@ -340,7 +330,7 @@ static void com90io_setmask(struct net_device *dev, int mask) { short ioaddr = dev->base_addr; - AINTMASK(mask); + outb(mask, _INTMASK); } static void com90io_copy_to_card(struct net_device *dev, int bufnum, int offset, -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 03/21] ARCNET: capmode: fix transfer length
The commit <52edc17f94f7bd4d9> ("bugfixes and new hardware support for arcnet driver") adds fixes for the packet length calculations in arc-rawmode. As the capmode protocol is derived from the arc-rawmode code, the capmode also needs the fixes. rx(): - Fixed error in received packet lengths; 256 byte packets were being received as 257 bytes packets. prepare_tx(): - Fixed error in transmit length calcs; 257 byte packets were being transmitted as 260 byte packets. Signed-off-by: Michael Grzeschik --- drivers/net/arcnet/capmode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/arcnet/capmode.c b/drivers/net/arcnet/capmode.c index 42fce91..b6868a2 100644 --- a/drivers/net/arcnet/capmode.c +++ b/drivers/net/arcnet/capmode.c @@ -49,7 +49,7 @@ static void rx(struct net_device *dev, int bufnum, BUGMSG(D_DURING, "it's a raw(cap) packet (length=%d)\n", length); - if (length >= MinTU) + if (length > MTU) ofs = 512 - length; else ofs = 256 - length; @@ -156,7 +156,7 @@ static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length, length, XMTU); length = XMTU; } - if (length > MinTU) { + if (length >= MinTU) { hard->offset[0] = 0; hard->offset[1] = ofs = 512 - length; } else if (length > MTU) { -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 14/21] ARCNET: arc-rawmode: reorder module functions
This patch moves the module_init and module_exit patches to the end of the file. It also replaces the printk with pr_info. Signed-off-by: Michael Grzeschik --- drivers/net/arcnet/arc-rawmode.c | 87 ++-- 1 file changed, 38 insertions(+), 49 deletions(-) diff --git a/drivers/net/arcnet/arc-rawmode.c b/drivers/net/arcnet/arc-rawmode.c index b603470..68466b3 100644 --- a/drivers/net/arcnet/arc-rawmode.c +++ b/drivers/net/arcnet/arc-rawmode.c @@ -35,55 +35,6 @@ #define VERSION "arcnet: raw mode (`r') encapsulation support loaded.\n" - -static void rx(struct net_device *dev, int bufnum, - struct archdr *pkthdr, int length); -static int build_header(struct sk_buff *skb, struct net_device *dev, - unsigned short type, uint8_t daddr); -static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length, - int bufnum); - -static struct ArcProto rawmode_proto = -{ - .suffix = 'r', - .mtu= XMTU, - .rx = rx, - .build_header = build_header, - .prepare_tx = prepare_tx, - .continue_tx= NULL, - .ack_tx = NULL -}; - - -static int __init arcnet_raw_init(void) -{ - int count; - - printk(VERSION); - - for (count = 0; count < 256; count++) - if (arc_proto_map[count] == arc_proto_default) - arc_proto_map[count] = _proto; - - /* for raw mode, we only set the bcast proto if there's no better one */ - if (arc_bcast_proto == arc_proto_default) - arc_bcast_proto = _proto; - - arc_proto_default = _proto; - return 0; -} - -static void __exit arcnet_raw_exit(void) -{ - arcnet_unregister_proto(_proto); -} - -module_init(arcnet_raw_init); -module_exit(arcnet_raw_exit); - -MODULE_LICENSE("GPL"); - - /* packet receiver */ static void rx(struct net_device *dev, int bufnum, struct archdr *pkthdr, int length) @@ -201,3 +152,41 @@ static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length, return 1; /* done */ } + +static struct ArcProto rawmode_proto = { + .suffix = 'r', + .mtu= XMTU, + .rx = rx, + .build_header = build_header, + .prepare_tx = prepare_tx, + .continue_tx= NULL, + .ack_tx = NULL +}; + +static int __init arcnet_raw_init(void) +{ + int count; + + pr_info(VERSION); + + for (count = 0; count < 256; count++) + if (arc_proto_map[count] == arc_proto_default) + arc_proto_map[count] = _proto; + + /* for raw mode, we only set the bcast proto if there's no better one */ + if (arc_bcast_proto == arc_proto_default) + arc_bcast_proto = _proto; + + arc_proto_default = _proto; + return 0; +} + +static void __exit arcnet_raw_exit(void) +{ + arcnet_unregister_proto(_proto); +} + +module_init(arcnet_raw_init); +module_exit(arcnet_raw_exit); + +MODULE_LICENSE("GPL"); -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 00/21] ARCNET: Defibrillation
Hi! This patch series tries to reanimate the ARCNET hardware layer to be somehow readable and maintainable again. It includes a lot of cleanup patches. It also adds some fixes which leads the layer to become usable again. And as a special treatment it adds more features like correct loading and unloading of the com20020 card. Cheers, Michael Michael Grzeschik (21): com20020-pci: add dev_port for udev handling ARCNET: fix hard_header_len limit ARCNET: capmode: fix transfer length ARCNET: whitespace, tab and codingstyle fixes ARCNET: remove unneeded macros ARCNET: com20020: remove unneeded macros ARCNET: rimi: remove unneeded macros ARCNET: com90io: remove unneeded macros ARCNET: com90xx: remove unneeded macros ARCNET: com20020: fix ioaddr prefixes ARCNET: rimi: fix ioaddr prefixes ARCNET: com90io: fix ioaddr prefixes ARCNET: com90xx: fix ioaddr prefixes ARCNET: arc-rawmode: reorder module functions ARCNET: capmode: remove extra function and use C99 in struct ARCNET: capmode: move dev_free_skb to its only user ARCNET: com20020: replace magic numbers with readable macros ARCNET: com20020: remove obsolete BUS_ALIGN offset factor ARCNET: com20020: add enable and disable device on open/close ARCNET: com20020-pci: reformat structs to C99 format ARCNET: com20020-pci: add rotary index support drivers/net/arcnet/arc-rawmode.c | 91 +--- drivers/net/arcnet/arc-rimi.c | 42 ++ drivers/net/arcnet/arcnet.c | 192 +++- drivers/net/arcnet/capmode.c | 32 ++-- drivers/net/arcnet/com20020-isa.c | 4 +- drivers/net/arcnet/com20020-pci.c | 66 - drivers/net/arcnet/com20020.c | 152 +++ drivers/net/arcnet/com20020_cs.c | 302 ++ drivers/net/arcnet/com90io.c | 98 ++--- drivers/net/arcnet/com90xx.c | 65 include/linux/arcdevice.h | 15 +- include/linux/com20020.h | 69 +++-- include/uapi/linux/if_arcnet.h| 48 +++--- 13 files changed, 572 insertions(+), 604 deletions(-) -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 09/21] ARCNET: com90xx: remove unneeded macros
The simple macros ARCRESET, ACOMMAND, ASTATUS, AINTMASK are unnecessary indirections to the use of registers. This patch removes them and improves the readability of the code. Signed-off-by: Michael Grzeschik --- drivers/net/arcnet/com90xx.c | 35 +-- 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/drivers/net/arcnet/com90xx.c b/drivers/net/arcnet/com90xx.c index 03bd71c..2b99a04 100644 --- a/drivers/net/arcnet/com90xx.c +++ b/drivers/net/arcnet/com90xx.c @@ -89,15 +89,6 @@ static int numcards; #define _ADDR_HI (ioaddr+15) /* Control registers for said */ #define _ADDR_LO (ioaddr+14) -#undef ASTATUS -#undef ACOMMAND -#undef AINTMASK - -#define ASTATUS() inb(_STATUS) -#define ACOMMAND(cmd) outb((cmd),_COMMAND) -#define AINTMASK(msk) outb((msk),_INTMASK) - - static int com90xx_skip_probe __initdata = 0; /* Module parameters */ @@ -175,7 +166,7 @@ static void __init com90xx_probe(void) *port-- = ports[--numports]; continue; } - if (ASTATUS() == 0xFF) { + if (inb(_STATUS) == 0xFF) { BUGMSG2(D_INIT_REASONS, "(empty)\n"); BUGMSG2(D_INIT_REASONS, "S1: "); BUGLVL(D_INIT_REASONS) numprint = 0; @@ -317,7 +308,7 @@ static void __init com90xx_probe(void) BUGMSG2(D_INIT, "%Xh ", *port); ioaddr = *port; - status = ASTATUS(); + status = inb(_STATUS); if ((status & 0x9D) != (NORXflag | RECONflag | TXFREEflag | RESETflag)) { @@ -328,8 +319,8 @@ static void __init com90xx_probe(void) *port-- = ports[--numports]; continue; } - ACOMMAND(CFLAGScmd | RESETclear | CONFIGclear); - status = ASTATUS(); + outb(CFLAGScmd | RESETclear | CONFIGclear, _COMMAND); + status = inb(_STATUS); if (status & RESETflag) { BUGMSG2(D_INIT_REASONS, " (eternal reset, status=%Xh)\n", status); @@ -348,9 +339,9 @@ static void __init com90xx_probe(void) * we tell it to start receiving. */ airqmask = probe_irq_on(); - AINTMASK(NORXflag); + outb(NORXflag, _INTMASK); udelay(1); - AINTMASK(0); + outb(0, _INTMASK); airq = probe_irq_off(airqmask); if (airq <= 0) { @@ -557,7 +548,7 @@ static void com90xx_command(struct net_device *dev, int cmd) { short ioaddr = dev->base_addr; - ACOMMAND(cmd); + outb(cmd, _COMMAND); } @@ -565,7 +556,7 @@ static int com90xx_status(struct net_device *dev) { short ioaddr = dev->base_addr; - return ASTATUS(); + return inb(_STATUS); } @@ -573,7 +564,7 @@ static void com90xx_setmask(struct net_device *dev, int mask) { short ioaddr = dev->base_addr; - AINTMASK(mask); + outb(mask, _INTMASK); } @@ -590,15 +581,15 @@ static int com90xx_reset(struct net_device *dev, int really_reset) struct arcnet_local *lp = netdev_priv(dev); short ioaddr = dev->base_addr; - BUGMSG(D_INIT, "Resetting (status=%02Xh)\n", ASTATUS()); + BUGMSG(D_INIT, "Resetting (status=%02Xh)\n", inb(_STATUS)); if (really_reset) { /* reset the card */ inb(_RESET); mdelay(RESETtime); } - ACOMMAND(CFLAGScmd | RESETclear); /* clear flags & end reset */ - ACOMMAND(CFLAGScmd | CONFIGclear); + outb(CFLAGScmd | RESETclear, _COMMAND); /* clear flags & end reset */ + outb(CFLAGScmd | CONFIGclear, _COMMAND); /* don't do this until we verify that it doesn't hurt older cards! */ /* outb(inb(_CONFIG) | ENABLE16flag, _CONFIG); */ @@ -610,7 +601,7 @@ static int com90xx_reset(struct net_device *dev, int really_reset) return 1; } /* enable extended (512-byte) packets */ - ACOMMAND(CONFIGcmd | EXTconf); + outb(CONFIGcmd | EXTconf, _COMMAND); /* clean out all the memory to make debugging make more sense :) */ BUGLVL(D_DURING) -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 17/21] ARCNET: com20020: replace magic numbers with readable macros
This patch replaces all magic numbers in the driver with proper named macros. For the case of XTOcfg and STARTIOcmd it introduces the new macros. Signed-off-by: Michael Grzeschik --- drivers/net/arcnet/com20020.c | 21 +++-- include/linux/arcdevice.h | 1 + include/linux/com20020.h | 1 + 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/net/arcnet/com20020.c b/drivers/net/arcnet/com20020.c index 4b4bb96..27ad484 100644 --- a/drivers/net/arcnet/com20020.c +++ b/drivers/net/arcnet/com20020.c @@ -92,9 +92,9 @@ int com20020_check(struct net_device *dev) struct arcnet_local *lp = netdev_priv(dev); /* reset the card */ - outb(0x18 | 0x80, ioaddr + _CONFIG); + outb(XTOcfg(3) | RESETcfg, ioaddr + _CONFIG); udelay(5); - outb(0x18, ioaddr + _CONFIG); + outb(XTOcfg(3), ioaddr + _CONFIG); mdelay(RESETtime); lp->setup = lp->clockm ? 0 : (lp->clockp << 1); @@ -115,13 +115,13 @@ int com20020_check(struct net_device *dev) /* must now write the magic "restart operation" command */ mdelay(1); - outb(0x18, ioaddr + _COMMAND); + outb(STARTIOcmd, ioaddr + _COMMAND); } - lp->config = 0x21 | (lp->timeout << 3) | (lp->backplane << 2); + lp->config = TXENcfg | (lp->timeout << 3) | (lp->backplane << 2) | SUB_NODE; /* set node ID to 0x42 (but transmitter is disabled, so it's okay) */ outb(lp->config, ioaddr + _CONFIG); - outb(0x42, ioaddr + BUS_ALIGN*7); + outb(0x42, ioaddr + _XREG); status = inb(ioaddr + _STATUS); @@ -132,8 +132,9 @@ int com20020_check(struct net_device *dev) BUGMSG(D_INIT_REASONS, "status after reset: %X\n", status); /* Enable TX */ - outb(0x39, ioaddr + _CONFIG); - outb(inb(ioaddr + BUS_ALIGN*8), ioaddr + BUS_ALIGN*7); + lp->config |= TXENcfg; + outb(lp->config, ioaddr + _CONFIG); + outb(inb(ioaddr + BUS_ALIGN * 8), ioaddr + _XREG); outb((CFLAGScmd | RESETclear | CONFIGclear), ioaddr + _COMMAND); @@ -212,10 +213,10 @@ int com20020_found(struct net_device *dev, int shared) /* must now write the magic "restart operation" command */ mdelay(1); - outb(0x18, ioaddr + _COMMAND); + outb(STARTIOcmd, ioaddr + _COMMAND); } - lp->config = 0x20 | (lp->timeout << 3) | (lp->backplane << 2) | 1; + lp->config = TXENcfg | (lp->timeout << 3) | (lp->backplane << 2) | SUB_NODE; /* Default 0x38 + register: Node ID */ outb(lp->config, ioaddr + _CONFIG); outb(dev->dev_addr[0], ioaddr + _XREG); @@ -276,7 +277,7 @@ static int com20020_reset(struct net_device *dev, int really_reset) if (really_reset) { /* reset the card */ - outb(lp->config | 0x80, ioaddr + _CONFIG); + outb(lp->config | RESETcfg, ioaddr + _CONFIG); udelay(5); outb(lp->config, ioaddr + _CONFIG); mdelay(RESETtime * 2); /* COM20020 seems to be slower sometimes */ diff --git a/include/linux/arcdevice.h b/include/linux/arcdevice.h index c20f100..bc3b085 100644 --- a/include/linux/arcdevice.h +++ b/include/linux/arcdevice.h @@ -155,6 +155,7 @@ extern int arcnet_debug; #define CONFIGcmd 0x05 /* define configuration */ #define CFLAGScmd 0x06 /* clear flags */ #define TESTcmd 0x07 /* load test flags */ +#define STARTIOcmd 0x18 /* start internal operation */ /* flags for "clear flags" command */ #define RESETclear 0x08 /* power-on-reset */ diff --git a/include/linux/com20020.h b/include/linux/com20020.h index c2d8647..f194b74 100644 --- a/include/linux/com20020.h +++ b/include/linux/com20020.h @@ -92,6 +92,7 @@ struct com20020_dev { /* in the CONFIG register */ #define RESETcfg 0x80/* put card in reset state */ #define TXENcfg0x20/* enable TX */ +#define XTOcfg(x) ((x) << 3) /* extended timeout */ /* in SETUP register */ #define PROMISCset 0x10/* enable RCV_ALL */ -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 20/21] ARCNET: com20020-pci: reformat structs to C99 format
This patch changes the macro definitions to match the C99 formating. This improves the readability. Signed-off-by: Michael Grzeschik --- drivers/net/arcnet/com20020-pci.c | 35 +-- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c index 18c0b1f..de8c894 100644 --- a/drivers/net/arcnet/com20020-pci.c +++ b/drivers/net/arcnet/com20020-pci.c @@ -191,7 +191,11 @@ static struct com20020_pci_card_info card_info_10mbit = { .name = "ARC-PCI", .devcount = 1, .chan_map_tbl = { - { 2, 0x00, 0x08 }, + { + .bar = 2, + .offset = 0x00, + .size = 0x08, + }, }, .flags = ARC_CAN_10MBIT, }; @@ -200,7 +204,11 @@ static struct com20020_pci_card_info card_info_5mbit = { .name = "ARC-PCI", .devcount = 1, .chan_map_tbl = { - { 2, 0x00, 0x08 }, + { + .bar = 2, + .offset = 0x00, + .size = 0x08, + }, }, .flags = ARC_IS_5MBIT, }; @@ -210,7 +218,11 @@ static struct com20020_pci_card_info card_info_sohard = { .devcount = 1, /* SOHARD needs PCI base addr 4 */ .chan_map_tbl = { - {4, 0x00, 0x08}, + { + .bar = 4, + .offset = 0x00, + .size = 0x08 + }, }, .flags = ARC_CAN_10MBIT, }; @@ -219,7 +231,11 @@ static struct com20020_pci_card_info card_info_eae_arc1 = { .name = "EAE PLX-PCI ARC1", .devcount = 1, .chan_map_tbl = { - { 2, 0x00, 0x08 }, + { + .bar = 2, + .offset = 0x00, + .size = 0x08, + }, }, .flags = ARC_CAN_10MBIT, }; @@ -228,8 +244,15 @@ static struct com20020_pci_card_info card_info_eae_ma1 = { .name = "EAE PLX-PCI MA1", .devcount = 2, .chan_map_tbl = { - { 2, 0x00, 0x08 }, - { 2, 0x08, 0x08 } + { + .bar = 2, + .offset = 0x00, + .size = 0x08, + }, { + .bar = 2, + .offset = 0x08, + .size = 0x08, + } }, .flags = ARC_CAN_10MBIT, }; -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 13/21] ARCNET: com90xx: fix ioaddr prefixes
This patch removes the use of the variable ioaddr in the macros and uses it directly in the calling functions. This improves the readability of the code and changes the macros to be used as offsets. Signed-off-by: Michael Grzeschik --- drivers/net/arcnet/com90xx.c | 52 ++-- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/drivers/net/arcnet/com90xx.c b/drivers/net/arcnet/com90xx.c index 2b99a04..d8a9fe5 100644 --- a/drivers/net/arcnet/com90xx.c +++ b/drivers/net/arcnet/com90xx.c @@ -80,14 +80,14 @@ static int numcards; #define MIRROR_SIZE (BUFFER_SIZE*4) /* COM 9026 controller chip --> ARCnet register addresses */ -#define _INTMASK (ioaddr+0)/* writable */ -#define _STATUS (ioaddr+0)/* readable */ -#define _COMMAND (ioaddr+1)/* writable, returns random vals on read (?) */ -#define _CONFIG (ioaddr+2)/* Configuration register */ -#define _RESET (ioaddr+8)/* software reset (on read) */ -#define _MEMDATA (ioaddr+12) /* Data port for IO-mapped memory */ -#define _ADDR_HI (ioaddr+15) /* Control registers for said */ -#define _ADDR_LO (ioaddr+14) +#define _INTMASK 0 /* writable */ +#define _STATUS0 /* readable */ +#define _COMMAND 1 /* writable, returns random vals on read (?) */ +#define _CONFIG2 /* Configuration register */ +#define _RESET 8 /* software reset (on read) */ +#define _MEMDATA 12 /* Data port for IO-mapped memory */ +#define _ADDR_HI 15 /* Control registers for said */ +#define _ADDR_LO 14 static int com90xx_skip_probe __initdata = 0; @@ -166,7 +166,7 @@ static void __init com90xx_probe(void) *port-- = ports[--numports]; continue; } - if (inb(_STATUS) == 0xFF) { + if (inb(ioaddr + _STATUS) == 0xFF) { BUGMSG2(D_INIT_REASONS, "(empty)\n"); BUGMSG2(D_INIT_REASONS, "S1: "); BUGLVL(D_INIT_REASONS) numprint = 0; @@ -174,7 +174,7 @@ static void __init com90xx_probe(void) *port-- = ports[--numports]; continue; } - inb(_RESET);/* begin resetting card */ + inb(ioaddr + _RESET); /* begin resetting card */ BUGMSG2(D_INIT_REASONS, "\n"); BUGMSG2(D_INIT_REASONS, "S1: "); @@ -308,7 +308,7 @@ static void __init com90xx_probe(void) BUGMSG2(D_INIT, "%Xh ", *port); ioaddr = *port; - status = inb(_STATUS); + status = inb(ioaddr + _STATUS); if ((status & 0x9D) != (NORXflag | RECONflag | TXFREEflag | RESETflag)) { @@ -319,8 +319,8 @@ static void __init com90xx_probe(void) *port-- = ports[--numports]; continue; } - outb(CFLAGScmd | RESETclear | CONFIGclear, _COMMAND); - status = inb(_STATUS); + outb(CFLAGScmd | RESETclear | CONFIGclear, ioaddr + _COMMAND); + status = inb(ioaddr + _STATUS); if (status & RESETflag) { BUGMSG2(D_INIT_REASONS, " (eternal reset, status=%Xh)\n", status); @@ -339,9 +339,9 @@ static void __init com90xx_probe(void) * we tell it to start receiving. */ airqmask = probe_irq_on(); - outb(NORXflag, _INTMASK); + outb(NORXflag, ioaddr + _INTMASK); udelay(1); - outb(0, _INTMASK); + outb(0, ioaddr + _INTMASK); airq = probe_irq_off(airqmask); if (airq <= 0) { @@ -367,14 +367,14 @@ static void __init com90xx_probe(void) */ #ifdef FAST_PROBE if (numports > 1 || numshmems > 1) { - inb(_RESET); + inb(ioaddr + _RESET); mdelay(RESETtime); } else { /* just one shmem and port, assume they match */ writeb(TESTvalue, iomem[0]); } #else - inb(_RESET); + inb(ioaddr + _RESET); mdelay(RESETtime); #endif @@ -548,7 +548,7 @@ static void com90xx_command(struct net_device *dev, int cmd) { short ioaddr = dev->base_addr; - outb(cmd, _COMMAND); + outb(cmd, ioaddr + _COMMAND); } @@ -556,7 +556,7 @@ static int com90xx_status(struct net_device *dev) { short ioaddr = dev->base_addr; - return inb(_STATUS); + return inb(ioaddr + _STATUS); } @@ -564,7 +56
[PATCH 18/21] ARCNET: com20020: remove obsolete BUS_ALIGN offset factor
This patch removes the obsolete macro BUS_ALIGN as the kernel option CONFIG_SA1100_CT6001 is not longer available. Signed-off-by: Michael Grzeschik --- drivers/net/arcnet/com20020.c | 4 ++-- include/linux/com20020.h | 27 ++- 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/drivers/net/arcnet/com20020.c b/drivers/net/arcnet/com20020.c index 27ad484..1dbc748 100644 --- a/drivers/net/arcnet/com20020.c +++ b/drivers/net/arcnet/com20020.c @@ -134,7 +134,7 @@ int com20020_check(struct net_device *dev) /* Enable TX */ lp->config |= TXENcfg; outb(lp->config, ioaddr + _CONFIG); - outb(inb(ioaddr + BUS_ALIGN * 8), ioaddr + _XREG); + outb(inb(ioaddr + 8), ioaddr + _XREG); outb((CFLAGScmd | RESETclear | CONFIGclear), ioaddr + _COMMAND); @@ -200,7 +200,7 @@ int com20020_found(struct net_device *dev, int shared) lp->hw.close = com20020_close; if (!dev->dev_addr[0]) - dev->dev_addr[0] = inb(ioaddr + BUS_ALIGN*8); /* FIXME: do this some other way! */ + dev->dev_addr[0] = inb(ioaddr + 8); /* FIXME: do this some other way! */ lp->config = (lp->config & ~0x03) | SUB_SETUP1; outb(lp->config, ioaddr + _CONFIG); diff --git a/include/linux/com20020.h b/include/linux/com20020.h index f194b74..939d69d 100644 --- a/include/linux/com20020.h +++ b/include/linux/com20020.h @@ -34,13 +34,6 @@ extern const struct net_device_ops com20020_netdev_ops; /* The number of low I/O ports used by the card. */ #define ARCNET_TOTAL_SIZE 8 -/* various register addresses */ -#ifdef CONFIG_SA1100_CT6001 -#define BUS_ALIGN 2 /* 8 bit device on a 16 bit bus - needs padding */ -#else -#define BUS_ALIGN 1 -#endif - #define PLX_PCI_MAX_CARDS 2 struct com20020_pci_channel_map { @@ -71,16 +64,16 @@ struct com20020_dev { int index; }; -#define _INTMASK (BUS_ALIGN*0)/* writable */ -#define _STATUS (BUS_ALIGN*0)/* readable */ -#define _COMMAND (BUS_ALIGN*1)/* standard arcnet commands */ -#define _DIAGSTAT (BUS_ALIGN*1)/* diagnostic status register */ -#define _ADDR_HI (BUS_ALIGN*2)/* control registers for IO-mapped memory */ -#define _ADDR_LO (BUS_ALIGN*3) -#define _MEMDATA (BUS_ALIGN*4)/* data port for IO-mapped memory */ -#define _SUBADR (BUS_ALIGN*5)/* the extended port _XREG refers to */ -#define _CONFIG (BUS_ALIGN*6)/* configuration register */ -#define _XREG (BUS_ALIGN*7)/* extra registers (indexed by _CONFIG +#define _INTMASK 0/* writable */ +#define _STATUS 0/* readable */ +#define _COMMAND 1/* standard arcnet commands */ +#define _DIAGSTAT 1/* diagnostic status register */ +#define _ADDR_HI 2/* control registers for IO-mapped memory */ +#define _ADDR_LO 3 +#define _MEMDATA 4/* data port for IO-mapped memory */ +#define _SUBADR 5/* the extended port _XREG refers to */ +#define _CONFIG 6/* configuration register */ +#define _XREG 7/* extra registers (indexed by _CONFIG or _SUBADR) */ /* in the ADDR_HI register */ -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 07/21] ARCNET: rimi: remove unneeded macros
The simple macros ARCRESET, ACOMMAND, ASTATUS, AINTMASK are unnecessary indirections to the use of registers. This patch removes them and improves the readability of the code. Signed-off-by: Michael Grzeschik --- drivers/net/arcnet/arc-rimi.c | 24 +++- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/drivers/net/arcnet/arc-rimi.c b/drivers/net/arcnet/arc-rimi.c index 4c95d3c..c920b86 100644 --- a/drivers/net/arcnet/arc-rimi.c +++ b/drivers/net/arcnet/arc-rimi.c @@ -69,16 +69,6 @@ static void arcrimi_copy_from_card(struct net_device *dev, int bufnum, int offse #define _ADDR_LO (ioaddr+14) #define _CONFIG (ioaddr+2)/* Configuration register */ -#undef ASTATUS -#undef ACOMMAND -#undef AINTMASK - -#define ASTATUS() readb(_STATUS) -#define ACOMMAND(cmd) writeb((cmd),_COMMAND) -#define AINTMASK(msk) writeb((msk),_INTMASK) -#define SETCONF() writeb(lp->config,_CONFIG) - - /* * We cannot probe for a RIM I card; one reason is I don't know how to reset * them. In fact, we can't even get their node ID automatically. So, we @@ -263,17 +253,17 @@ static int arcrimi_reset(struct net_device *dev, int really_reset) struct arcnet_local *lp = netdev_priv(dev); void __iomem *ioaddr = lp->mem_start + 0x800; - BUGMSG(D_INIT, "Resetting %s (status=%02Xh)\n", dev->name, ASTATUS()); + BUGMSG(D_INIT, "Resetting %s (status=%02Xh)\n", dev->name, readb(_STATUS)); if (really_reset) { writeb(TESTvalue, ioaddr - 0x800); /* fake reset */ return 0; } - ACOMMAND(CFLAGScmd | RESETclear); /* clear flags & end reset */ - ACOMMAND(CFLAGScmd | CONFIGclear); + writeb(CFLAGScmd | RESETclear, _COMMAND); /* clear flags & end reset */ + writeb(CFLAGScmd | CONFIGclear, _COMMAND); /* enable extended (512-byte) packets */ - ACOMMAND(CONFIGcmd | EXTconf); + writeb(CONFIGcmd | EXTconf, _COMMAND); /* done! return success. */ return 0; @@ -284,7 +274,7 @@ static void arcrimi_setmask(struct net_device *dev, int mask) struct arcnet_local *lp = netdev_priv(dev); void __iomem *ioaddr = lp->mem_start + 0x800; - AINTMASK(mask); + writeb(mask, _INTMASK); } static int arcrimi_status(struct net_device *dev) @@ -292,7 +282,7 @@ static int arcrimi_status(struct net_device *dev) struct arcnet_local *lp = netdev_priv(dev); void __iomem *ioaddr = lp->mem_start + 0x800; - return ASTATUS(); + return readb(_STATUS); } static void arcrimi_command(struct net_device *dev, int cmd) @@ -300,7 +290,7 @@ static void arcrimi_command(struct net_device *dev, int cmd) struct arcnet_local *lp = netdev_priv(dev); void __iomem *ioaddr = lp->mem_start + 0x800; - ACOMMAND(cmd); + writeb(cmd, _COMMAND); } static void arcrimi_copy_to_card(struct net_device *dev, int bufnum, int offset, -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 12/21] ARCNET: com90io: fix ioaddr prefixes
This patch removes the use of the variable ioaddr in the macros and uses it directly in the calling functions. This improves the readability of the code and changes the macros to be used as offsets. Signed-off-by: Michael Grzeschik --- drivers/net/arcnet/com90io.c | 86 ++-- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/drivers/net/arcnet/com90io.c b/drivers/net/arcnet/com90io.c index 6bc6366..df7314d 100644 --- a/drivers/net/arcnet/com90io.c +++ b/drivers/net/arcnet/com90io.c @@ -60,14 +60,14 @@ static void com90io_copy_from_card(struct net_device *dev, int bufnum, int offse #define ARCNET_TOTAL_SIZE 16 /* COM 9026 controller chip --> ARCnet register addresses */ -#define _INTMASK (ioaddr+0)/* writable */ -#define _STATUS (ioaddr+0)/* readable */ -#define _COMMAND (ioaddr+1)/* writable, returns random vals on read (?) */ -#define _RESET (ioaddr+8) /* software reset (on read) */ -#define _MEMDATA (ioaddr+12) /* Data port for IO-mapped memory */ -#define _ADDR_HI (ioaddr+15) /* Control registers for said */ -#define _ADDR_LO (ioaddr+14) -#define _CONFIG (ioaddr+2)/* Configuration register */ +#define _INTMASK 0 /* writable */ +#define _STATUS0 /* readable */ +#define _COMMAND 1 /* writable, returns random vals on read (?) */ +#define _RESET 8 /* software reset (on read) */ +#define _MEMDATA 12 /* Data port for IO-mapped memory */ +#define _ADDR_HI 15 /* Control registers for said */ +#define _ADDR_LO 14 +#define _CONFIG2 /* Configuration register */ / * * @@ -82,10 +82,10 @@ static u_char get_buffer_byte(struct net_device *dev, unsigned offset) { int ioaddr = dev->base_addr; - outb(offset >> 8, _ADDR_HI); - outb(offset & 0xff, _ADDR_LO); + outb(offset >> 8, ioaddr + _ADDR_HI); + outb(offset & 0xff, ioaddr + _ADDR_LO); - return inb(_MEMDATA); + return inb(ioaddr + _MEMDATA); } #ifdef ONE_AT_A_TIME_TX @@ -93,10 +93,10 @@ static void put_buffer_byte(struct net_device *dev, unsigned offset, u_char datu { int ioaddr = dev->base_addr; - outb(offset >> 8, _ADDR_HI); - outb(offset & 0xff, _ADDR_LO); + outb(offset >> 8, ioaddr + _ADDR_HI); + outb(offset & 0xff, ioaddr + _ADDR_LO); - outb(datum, _MEMDATA); + outb(datum, ioaddr + _MEMDATA); } #endif @@ -106,14 +106,14 @@ static void get_whole_buffer(struct net_device *dev, unsigned offset, unsigned l { int ioaddr = dev->base_addr; - outb((offset >> 8) | AUTOINCflag, _ADDR_HI); - outb(offset & 0xff, _ADDR_LO); + outb((offset >> 8) | AUTOINCflag, ioaddr + _ADDR_HI); + outb(offset & 0xff, ioaddr + _ADDR_LO); while (length--) #ifdef ONE_AT_A_TIME_RX *(dest++) = get_buffer_byte(dev, offset++); #else - *(dest++) = inb(_MEMDATA); + *(dest++) = inb(ioaddr + _MEMDATA); #endif } @@ -121,14 +121,14 @@ static void put_whole_buffer(struct net_device *dev, unsigned offset, unsigned l { int ioaddr = dev->base_addr; - outb((offset >> 8) | AUTOINCflag, _ADDR_HI); - outb(offset & 0xff, _ADDR_LO); + outb((offset >> 8) | AUTOINCflag, ioaddr + _ADDR_HI); + outb(offset & 0xff, ioaddr + _ADDR_LO); while (length--) #ifdef ONE_AT_A_TIME_TX put_buffer_byte(dev, offset++, *(dest++)); #else - outb(*(dest++), _MEMDATA); + outb(*(dest++), ioaddr + _MEMDATA); #endif } @@ -154,14 +154,14 @@ static int __init com90io_probe(struct net_device *dev) ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1); return -ENXIO; } - if (inb(_STATUS) == 0xFF) { + if (inb(ioaddr + _STATUS) == 0xFF) { BUGMSG(D_INIT_REASONS, "IO address %x empty\n", ioaddr); goto err_out; } - inb(_RESET); + inb(ioaddr + _RESET); mdelay(RESETtime); - status = inb(_STATUS); + status = inb(ioaddr + _STATUS); if ((status & 0x9D) != (NORXflag | RECONflag | TXFREEflag | RESETflag)) { BUGMSG(D_INIT_REASONS, "Status invalid (%Xh).\n", status); @@ -169,24 +169,24 @@ static int __init com90io_probe(struct net_device *dev) } BUGMSG(D_INIT_REASONS, "Status after reset: %X\n", status); - outb(CFLAGScmd | RESETclear | CONFIGclear, _COMMAND); + outb(CFLAGScmd | RESETclear | CONFIGclear, ioaddr + _COMMAND); BUGMSG(D_INIT_REASONS, "Status after reset acknowledged: %X\n", s
[PATCH 11/21] ARCNET: rimi: fix ioaddr prefixes
This patch removes the use of the variable ioaddr in the macros and uses it directly in the calling functions. This improves the readability of the code and changes the macros to be used as offsets. Signed-off-by: Michael Grzeschik --- drivers/net/arcnet/arc-rimi.c | 30 +++--- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/net/arcnet/arc-rimi.c b/drivers/net/arcnet/arc-rimi.c index c920b86..6e28a51 100644 --- a/drivers/net/arcnet/arc-rimi.c +++ b/drivers/net/arcnet/arc-rimi.c @@ -60,14 +60,14 @@ static void arcrimi_copy_from_card(struct net_device *dev, int bufnum, int offse #define MIRROR_SIZE (BUFFER_SIZE*4) /* COM 9026 controller chip --> ARCnet register addresses */ -#define _INTMASK (ioaddr+0)/* writable */ -#define _STATUS (ioaddr+0)/* readable */ -#define _COMMAND (ioaddr+1)/* writable, returns random vals on read (?) */ -#define _RESET (ioaddr+8) /* software reset (on read) */ -#define _MEMDATA (ioaddr+12) /* Data port for IO-mapped memory */ -#define _ADDR_HI (ioaddr+15) /* Control registers for said */ -#define _ADDR_LO (ioaddr+14) -#define _CONFIG (ioaddr+2)/* Configuration register */ +#define _INTMASK 0 /* writable */ +#define _STATUS0 /* readable */ +#define _COMMAND 1 /* writable, returns random vals on read (?) */ +#define _RESET 8 /* software reset (on read) */ +#define _MEMDATA 12 /* Data port for IO-mapped memory */ +#define _ADDR_HI 15 /* Control registers for said */ +#define _ADDR_LO 14 +#define _CONFIG2 /* Configuration register */ /* * We cannot probe for a RIM I card; one reason is I don't know how to reset @@ -253,17 +253,17 @@ static int arcrimi_reset(struct net_device *dev, int really_reset) struct arcnet_local *lp = netdev_priv(dev); void __iomem *ioaddr = lp->mem_start + 0x800; - BUGMSG(D_INIT, "Resetting %s (status=%02Xh)\n", dev->name, readb(_STATUS)); + BUGMSG(D_INIT, "Resetting %s (status=%02Xh)\n", dev->name, readb(ioaddr + _STATUS)); if (really_reset) { writeb(TESTvalue, ioaddr - 0x800); /* fake reset */ return 0; } - writeb(CFLAGScmd | RESETclear, _COMMAND); /* clear flags & end reset */ - writeb(CFLAGScmd | CONFIGclear, _COMMAND); + writeb(CFLAGScmd | RESETclear, ioaddr + _COMMAND); /* clear flags & end reset */ + writeb(CFLAGScmd | CONFIGclear, ioaddr + _COMMAND); /* enable extended (512-byte) packets */ - writeb(CONFIGcmd | EXTconf, _COMMAND); + writeb(CONFIGcmd | EXTconf, ioaddr + _COMMAND); /* done! return success. */ return 0; @@ -274,7 +274,7 @@ static void arcrimi_setmask(struct net_device *dev, int mask) struct arcnet_local *lp = netdev_priv(dev); void __iomem *ioaddr = lp->mem_start + 0x800; - writeb(mask, _INTMASK); + writeb(mask, ioaddr + _INTMASK); } static int arcrimi_status(struct net_device *dev) @@ -282,7 +282,7 @@ static int arcrimi_status(struct net_device *dev) struct arcnet_local *lp = netdev_priv(dev); void __iomem *ioaddr = lp->mem_start + 0x800; - return readb(_STATUS); + return readb(ioaddr + _STATUS); } static void arcrimi_command(struct net_device *dev, int cmd) @@ -290,7 +290,7 @@ static void arcrimi_command(struct net_device *dev, int cmd) struct arcnet_local *lp = netdev_priv(dev); void __iomem *ioaddr = lp->mem_start + 0x800; - writeb(cmd, _COMMAND); + writeb(cmd, ioaddr + _COMMAND); } static void arcrimi_copy_to_card(struct net_device *dev, int bufnum, int offset, -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 05/21] ARCNET: remove unneeded macros
The simple macros ARCRESET, ACOMMAND, ASTATUS, AINTMASK are unnecessary indirections to the use of registers. This patch removes them and improves the readability of the code. Signed-off-by: Michael Grzeschik --- drivers/net/arcnet/arcnet.c | 68 +++-- include/linux/arcdevice.h | 7 - 2 files changed, 35 insertions(+), 40 deletions(-) diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c index f83034c..4990b0d 100644 --- a/drivers/net/arcnet/arcnet.c +++ b/drivers/net/arcnet/arcnet.c @@ -382,7 +382,7 @@ int arcnet_open(struct net_device *dev) * time, actually reset it. */ error = -ENODEV; - if (ARCRESET(0) && ARCRESET(1)) + if (lp->hw.reset(dev, 0) && lp->hw.reset(dev, 1)) goto out_module_put; newmtu = choose_mtu(); @@ -427,22 +427,22 @@ int arcnet_open(struct net_device *dev) "DOS networking programs!\n"); BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__); - if (ASTATUS() & RESETflag) { + if (lp->hw.status(dev) & RESETflag) { BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__); - ACOMMAND(CFLAGScmd | RESETclear); + lp->hw.command(dev, CFLAGScmd | RESETclear); } BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__); /* make sure we're ready to receive IRQ's. */ - AINTMASK(0); + lp->hw.intmask(dev, 0); udelay(1); /* give it time to set the mask before * we reset it again. (may not even be * necessary) */ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__); lp->intmask = NORXflag | RECONflag; - AINTMASK(lp->intmask); + lp->hw.intmask(dev, lp->intmask); BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__); netif_start_queue(dev); @@ -463,9 +463,9 @@ int arcnet_close(struct net_device *dev) netif_stop_queue(dev); /* flush TX and disable RX */ - AINTMASK(0); - ACOMMAND(NOTXcmd); /* stop transmit */ - ACOMMAND(NORXcmd); /* disable receive */ + lp->hw.intmask(dev, 0); + lp->hw.command(dev, NOTXcmd); /* stop transmit */ + lp->hw.command(dev, NORXcmd); /* disable receive */ mdelay(1); /* shut down the card */ @@ -545,7 +545,7 @@ netdev_tx_t arcnet_send_packet(struct sk_buff *skb, BUGMSG(D_DURING, "transmit requested (status=%Xh, txbufs=%d/%d, len=%d, protocol %x)\n", - ASTATUS(), lp->cur_tx, lp->next_tx, skb->len,skb->protocol); + lp->hw.status(dev), lp->cur_tx, lp->next_tx, skb->len, skb->protocol); pkt = (struct archdr *) skb->data; soft = >soft.rfc1201; @@ -566,7 +566,7 @@ netdev_tx_t arcnet_send_packet(struct sk_buff *skb, netif_stop_queue(dev); spin_lock_irqsave(>lock, flags); - AINTMASK(0); + lp->hw.intmask(dev, 0); if (lp->next_tx == -1) { txbuf = get_arcbuf(dev); } else { @@ -601,14 +601,16 @@ netdev_tx_t arcnet_send_packet(struct sk_buff *skb, freeskb = 0; } - BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n",__FILE__,__LINE__,__func__,ASTATUS()); + BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n", + __FILE__, __LINE__, __func__, lp->hw.status(dev)); /* make sure we didn't ignore a TX IRQ while we were in here */ - AINTMASK(0); + lp->hw.intmask(dev, 0); - BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__); + BUGMSG(D_DEBUG, "%s: %d: %s\n", __FILE__, __LINE__, __func__); lp->intmask |= TXFREEflag|EXCNAKflag; - AINTMASK(lp->intmask); - BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n",__FILE__,__LINE__,__func__,ASTATUS()); + lp->hw.intmask(dev, lp->intmask); + BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n", + __FILE__, __LINE__, __func__, lp->hw.status(dev)); spin_unlock_irqrestore(>lock, flags); if (freeskb) { @@ -627,7 +629,7 @@ static int go_tx(struct net_device *dev) struct arcnet_local *lp = netdev_priv(dev); BUGMSG(D_DURING, "go_tx: status=%Xh, intmask=%Xh, next_tx=%d, cur_tx=%d\n", - ASTATUS(), lp->intmask, lp->next_tx, lp->cur_tx); + lp->hw.status(dev), lp->intmask, lp->next_tx, lp->cur_tx); if (lp->cur_tx != -1 || lp->next_tx == -1) return 0; @@ -638,7 +640,7 @@ static int go_tx(struct net_device *dev) lp->next_tx = -1; /*
[PATCH 06/21] ARCNET: com20020: remove unneeded macros
The macros SET_SUBADR, ARCRESET, ARCRESET0, ACOMMAND, ASTATUS, AINTMASK and ADIAGSTATUS are unnecessary indirections to the use of registers. This patch removes them and improves the readability of the code. Signed-off-by: Michael Grzeschik --- drivers/net/arcnet/com20020-isa.c | 2 +- drivers/net/arcnet/com20020-pci.c | 2 +- drivers/net/arcnet/com20020.c | 56 ++- include/linux/com20020.h | 33 --- 4 files changed, 34 insertions(+), 59 deletions(-) diff --git a/drivers/net/arcnet/com20020-isa.c b/drivers/net/arcnet/com20020-isa.c index d8746ca..c674511 100644 --- a/drivers/net/arcnet/com20020-isa.c +++ b/drivers/net/arcnet/com20020-isa.c @@ -68,7 +68,7 @@ static int __init com20020isa_probe(struct net_device *dev) ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1); return -ENXIO; } - if (ASTATUS() == 0xFF) { + if (inb(_STATUS) == 0xFF) { BUGMSG(D_NORMAL, "IO address %x empty\n", ioaddr); err = -ENODEV; goto out; diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c index 9fa4eee..18c0b1f 100644 --- a/drivers/net/arcnet/com20020-pci.c +++ b/drivers/net/arcnet/com20020-pci.c @@ -132,7 +132,7 @@ static int com20020pci_probe(struct pci_dev *pdev, const struct pci_device_id *i lp->timeout = timeout; lp->hw.owner = THIS_MODULE; - if (ASTATUS() == 0xFF) { + if (inb(_STATUS) == 0xFF) { pr_err("IO address %Xh is empty!\n", ioaddr); ret = -EIO; goto out_port; diff --git a/drivers/net/arcnet/com20020.c b/drivers/net/arcnet/com20020.c index 0d84f6c..ed0cdd3 100644 --- a/drivers/net/arcnet/com20020.c +++ b/drivers/net/arcnet/com20020.c @@ -91,7 +91,10 @@ int com20020_check(struct net_device *dev) int ioaddr = dev->base_addr, status; struct arcnet_local *lp = netdev_priv(dev); - ARCRESET0; + /* reset the card */ + outb(0x18 | 0x80, _CONFIG); + udelay(5); + outb(0x18, _CONFIG); mdelay(RESETtime); lp->setup = lp->clockm ? 0 : (lp->clockp << 1); @@ -101,12 +104,13 @@ int com20020_check(struct net_device *dev) /* Enable P1Mode for backplane mode */ lp->setup = lp->setup | P1MODE; - SET_SUBADR(SUB_SETUP1); + lp->config = (lp->config & ~0x03) | SUB_SETUP1; + outb(lp->config, _CONFIG); outb(lp->setup, _XREG); if (lp->clockm != 0) { - SET_SUBADR(SUB_SETUP2); + outb(SUB_SETUP2, _SUBADR); outb(lp->setup2, _XREG); /* must now write the magic "restart operation" command */ @@ -116,10 +120,10 @@ int com20020_check(struct net_device *dev) lp->config = 0x21 | (lp->timeout << 3) | (lp->backplane << 2); /* set node ID to 0x42 (but transmitter is disabled, so it's okay) */ - SETCONF; + outb(lp->config, _CONFIG); outb(0x42, ioaddr + BUS_ALIGN*7); - status = ASTATUS(); + status = inb(_STATUS); if ((status & 0x99) != (NORXflag | TXFREEflag | RESETflag)) { BUGMSG(D_NORMAL, "status invalid (%Xh).\n", status); @@ -131,9 +135,9 @@ int com20020_check(struct net_device *dev) outb(0x39, _CONFIG); outb(inb(ioaddr + BUS_ALIGN*8), ioaddr + BUS_ALIGN*7); - ACOMMAND(CFLAGScmd | RESETclear | CONFIGclear); + outb((CFLAGScmd | RESETclear | CONFIGclear), _COMMAND); - status = ASTATUS(); + status = inb(_STATUS); BUGMSG(D_INIT_REASONS, "status after reset acknowledged: %X\n", status); @@ -156,7 +160,8 @@ static int com20020_set_hwaddr(struct net_device *dev, void *addr) struct sockaddr *hwaddr = addr; memcpy(dev->dev_addr, hwaddr->sa_data, 1); - SET_SUBADR(SUB_NODE); + lp->config = (lp->config & ~0x03) | SUB_NODE; + outb(lp->config, _CONFIG); outb(dev->dev_addr[0], _XREG); return 0; @@ -195,12 +200,13 @@ int com20020_found(struct net_device *dev, int shared) if (!dev->dev_addr[0]) dev->dev_addr[0] = inb(ioaddr + BUS_ALIGN*8); /* FIXME: do this some other way! */ - SET_SUBADR(SUB_SETUP1); + lp->config = (lp->config & ~0x03) | SUB_SETUP1; + outb(lp->config, _CONFIG); outb(lp->setup, _XREG); if (lp->card_flags & ARC_CAN_10MBIT) { - SET_SUBADR(SUB_SETUP2); + outb(SUB_SETUP2, _SUBADR); outb(lp->setup2, _XREG); /* must now write the magic "restart operation" command */ @@ -210,7 +216,7 @@ int com20020_found(struct net_devi