* [PATCH 4/9] Doc/DT: Add DT binding documentation for HDMI Connector
From: Tomi Valkeinen @ 2014-02-28 12:20 UTC (permalink / raw)
To: linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: Philipp Zabel, Laurent Pinchart, Russell King - ARM Linux,
Sascha Hauer, Sebastian Hesselbarth, Rob Clark, Inki Dae,
Andrzej Hajda, Tomasz Figa, Thierry Reding, Tomi Valkeinen
In-Reply-To: <1393590016-9361-1-git-send-email-tomi.valkeinen-l0cyMroinI0@public.gmane.org>
Add DT binding documentation for HDMI Connector.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen-l0cyMroinI0@public.gmane.org>
Reviewed-by: Archit Taneja <archit-l0cyMroinI0@public.gmane.org>
---
.../devicetree/bindings/video/hdmi-connector.txt | 23 ++++++++++++++++++++++
1 file changed, 23 insertions(+)
create mode 100644 Documentation/devicetree/bindings/video/hdmi-connector.txt
diff --git a/Documentation/devicetree/bindings/video/hdmi-connector.txt b/Documentation/devicetree/bindings/video/hdmi-connector.txt
new file mode 100644
index 000000000000..5d25f6a432bb
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/hdmi-connector.txt
@@ -0,0 +1,23 @@
+HDMI Connector
+==============
+
+Required properties:
+- compatible: "hdmi-connector"
+
+Optional properties:
+- label: a symbolic name for the connector
+
+Required nodes:
+- Video port for HDMI input
+
+Example
+-------
+
+hdmi0: connector@1 {
+ compatible = "hdmi-connector";
+ label = "hdmi";
+
+ hdmi_connector_in: endpoint {
+ remote-endpoint = <&tpd12s015_out>;
+ };
+};
--
1.8.3.2
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 5/9] Doc/DT: Add DT binding documentation for MIPI DPI Panel
From: Tomi Valkeinen @ 2014-02-28 12:20 UTC (permalink / raw)
To: linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: Philipp Zabel, Laurent Pinchart, Russell King - ARM Linux,
Sascha Hauer, Sebastian Hesselbarth, Rob Clark, Inki Dae,
Andrzej Hajda, Tomasz Figa, Thierry Reding, Tomi Valkeinen
In-Reply-To: <1393590016-9361-1-git-send-email-tomi.valkeinen-l0cyMroinI0@public.gmane.org>
Add DT binding documentation for MIPI DPI Panel.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen-l0cyMroinI0@public.gmane.org>
Reviewed-by: Archit Taneja <archit-l0cyMroinI0@public.gmane.org>
---
.../devicetree/bindings/video/panel-dpi.txt | 43 ++++++++++++++++++++++
1 file changed, 43 insertions(+)
create mode 100644 Documentation/devicetree/bindings/video/panel-dpi.txt
diff --git a/Documentation/devicetree/bindings/video/panel-dpi.txt b/Documentation/devicetree/bindings/video/panel-dpi.txt
new file mode 100644
index 000000000000..72636c6f1c67
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/panel-dpi.txt
@@ -0,0 +1,43 @@
+Generic MIPI DPI Panel
+======================
+
+Required properties:
+- compatible: "panel-dpi"
+
+Optional properties:
+- label: a symbolic name for the panel
+- gpios: panel enable gpio and backlight enable gpio
+
+Required nodes:
+- "panel-timing" containing video timings
+ (Documentation/devicetree/bindings/video/display-timing.txt)
+- Video port for DPI input
+
+Example
+-------
+
+lcd0: display@0 {
+ compatible = "samsung,lte430wq-f0c", "panel-dpi";
+ label = "lcd";
+
+ lcd_in: endpoint {
+ remote-endpoint = <&dpi_out>;
+ };
+
+ panel-timing {
+ clock-frequency = <9200000>;
+ hactive = <480>;
+ vactive = <272>;
+ hfront-porch = <8>;
+ hback-porch = <4>;
+ hsync-len = <41>;
+ vback-porch = <2>;
+ vfront-porch = <4>;
+ vsync-len = <10>;
+
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+};
--
1.8.3.2
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 6/9] Doc/DT: Add DT binding documentation for MIPI DSI CM Panel
From: Tomi Valkeinen @ 2014-02-28 12:20 UTC (permalink / raw)
To: linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: Philipp Zabel, Laurent Pinchart, Russell King - ARM Linux,
Sascha Hauer, Sebastian Hesselbarth, Rob Clark, Inki Dae,
Andrzej Hajda, Tomasz Figa, Thierry Reding, Tomi Valkeinen
In-Reply-To: <1393590016-9361-1-git-send-email-tomi.valkeinen-l0cyMroinI0@public.gmane.org>
Add DT binding documentation for MIPI DSI Command Mode Panel.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen-l0cyMroinI0@public.gmane.org>
Reviewed-by: Archit Taneja <archit-l0cyMroinI0@public.gmane.org>
---
.../devicetree/bindings/video/panel-dsi-cm.txt | 26 ++++++++++++++++++++++
1 file changed, 26 insertions(+)
create mode 100644 Documentation/devicetree/bindings/video/panel-dsi-cm.txt
diff --git a/Documentation/devicetree/bindings/video/panel-dsi-cm.txt b/Documentation/devicetree/bindings/video/panel-dsi-cm.txt
new file mode 100644
index 000000000000..73f422556d4f
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/panel-dsi-cm.txt
@@ -0,0 +1,26 @@
+Generic MIPI DSI Command Mode Panel
+===================================
+
+Required properties:
+- compatible: "panel-dsi-cm"
+
+Optional properties:
+- label: a symbolic name for the panel
+- gpios: panel reset gpio and TE gpio
+
+Required nodes:
+- Video port for DSI input
+
+Example
+-------
+
+lcd0: display {
+ compatible = "tpo,taal", "panel-dsi-cm";
+ label = "lcd0";
+
+ gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>; /* 102, reset */
+
+ lcd0_in: endpoint {
+ remote-endpoint = <&dsi1_out_ep>;
+ };
+};
--
1.8.3.2
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 7/9] Doc/DT: Add DT binding documentation for Sony acx565akm panel
From: Tomi Valkeinen @ 2014-02-28 12:20 UTC (permalink / raw)
To: linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: Philipp Zabel, Laurent Pinchart, Russell King - ARM Linux,
Sascha Hauer, Sebastian Hesselbarth, Rob Clark, Inki Dae,
Andrzej Hajda, Tomasz Figa, Thierry Reding, Tomi Valkeinen
In-Reply-To: <1393590016-9361-1-git-send-email-tomi.valkeinen-l0cyMroinI0@public.gmane.org>
Add DT binding documentation for Sony acx565akm panel
Signed-off-by: Tomi Valkeinen <tomi.valkeinen-l0cyMroinI0@public.gmane.org>
Reviewed-by: Sebastian Reichel <sre-8fiUuRrzOP0dnm+yROfE0A@public.gmane.org>
Reviewed-by: Archit Taneja <archit-l0cyMroinI0@public.gmane.org>
---
.../devicetree/bindings/video/sony,acx565akm.txt | 28 ++++++++++++++++++++++
1 file changed, 28 insertions(+)
create mode 100644 Documentation/devicetree/bindings/video/sony,acx565akm.txt
diff --git a/Documentation/devicetree/bindings/video/sony,acx565akm.txt b/Documentation/devicetree/bindings/video/sony,acx565akm.txt
new file mode 100644
index 000000000000..cd9cfdf7e3fe
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/sony,acx565akm.txt
@@ -0,0 +1,28 @@
+Sony ACX565AKM SDI Panel
+========================
+
+Required properties:
+- compatible: "sony,acx565akm"
+
+Optional properties:
+- label: a symbolic name for the panel
+- gpios: panel reset gpio
+
+Required nodes:
+- Video port for SDI input
+
+Example
+-------
+
+acx565akm@2 {
+ compatible = "sony,acx565akm";
+ spi-max-frequency = <6000000>;
+ reg = <2>;
+
+ label = "lcd";
+ gpios = <&gpio3 26 GPIO_ACTIVE_HIGH>; /* 90 */
+
+ lcd_in: endpoint {
+ remote-endpoint = <&sdi_out>;
+ };
+};
--
1.8.3.2
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 8/9] Doc/DT: Add DT binding documentation for TFP410 encoder
From: Tomi Valkeinen @ 2014-02-28 12:20 UTC (permalink / raw)
To: linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: Philipp Zabel, Laurent Pinchart, Russell King - ARM Linux,
Sascha Hauer, Sebastian Hesselbarth, Rob Clark, Inki Dae,
Andrzej Hajda, Tomasz Figa, Thierry Reding, Tomi Valkeinen
In-Reply-To: <1393590016-9361-1-git-send-email-tomi.valkeinen-l0cyMroinI0@public.gmane.org>
Add DT binding documentation for TFP410 encoder
Signed-off-by: Tomi Valkeinen <tomi.valkeinen-l0cyMroinI0@public.gmane.org>
Reviewed-by: Archit Taneja <archit-l0cyMroinI0@public.gmane.org>
---
.../devicetree/bindings/video/ti,tfp410.txt | 41 ++++++++++++++++++++++
1 file changed, 41 insertions(+)
create mode 100644 Documentation/devicetree/bindings/video/ti,tfp410.txt
diff --git a/Documentation/devicetree/bindings/video/ti,tfp410.txt b/Documentation/devicetree/bindings/video/ti,tfp410.txt
new file mode 100644
index 000000000000..6a5a04627584
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/ti,tfp410.txt
@@ -0,0 +1,41 @@
+TFP410 DPI to DVI encoder
+=========================
+
+Required properties:
+- compatible: "ti,tfp410"
+
+Optional properties:
+- gpios: power-down gpio
+
+Required nodes:
+- Video port 0 for DPI input
+- Video port 1 for DVI output
+
+Example
+-------
+
+tfp410: encoder@0 {
+ compatible = "ti,tfp410";
+ gpios = <&twl_gpio 2 GPIO_ACTIVE_LOW>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ tfp410_in: endpoint@0 {
+ remote-endpoint = <&dpi_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ tfp410_out: endpoint@0 {
+ remote-endpoint = <&dvi_connector_in>;
+ };
+ };
+ };
+};
--
1.8.3.2
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 9/9] Doc/DT: Add DT binding documentation for tpd12s015 encoder
From: Tomi Valkeinen @ 2014-02-28 12:20 UTC (permalink / raw)
To: linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: Philipp Zabel, Laurent Pinchart, Russell King - ARM Linux,
Sascha Hauer, Sebastian Hesselbarth, Rob Clark, Inki Dae,
Andrzej Hajda, Tomasz Figa, Thierry Reding, Tomi Valkeinen
In-Reply-To: <1393590016-9361-1-git-send-email-tomi.valkeinen-l0cyMroinI0@public.gmane.org>
Add DT binding documentation for tpd12s015 encoder
Signed-off-by: Tomi Valkeinen <tomi.valkeinen-l0cyMroinI0@public.gmane.org>
Reviewed-by: Archit Taneja <archit-l0cyMroinI0@public.gmane.org>
---
.../devicetree/bindings/video/ti,tpd12s015.txt | 44 ++++++++++++++++++++++
1 file changed, 44 insertions(+)
create mode 100644 Documentation/devicetree/bindings/video/ti,tpd12s015.txt
diff --git a/Documentation/devicetree/bindings/video/ti,tpd12s015.txt b/Documentation/devicetree/bindings/video/ti,tpd12s015.txt
new file mode 100644
index 000000000000..26e6d32e3f20
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/ti,tpd12s015.txt
@@ -0,0 +1,44 @@
+TPD12S015 HDMI level shifter and ESD protection chip
+====================================================
+
+Required properties:
+- compatible: "ti,tpd12s015"
+
+Optional properties:
+- gpios: CT CP HPD, LS OE and HPD gpios
+
+Required nodes:
+- Video port 0 for HDMI input
+- Video port 1 for HDMI output
+
+Example
+-------
+
+tpd12s015: encoder@1 {
+ compatible = "ti,tpd12s015";
+
+ gpios = <&gpio2 28 GPIO_ACTIVE_HIGH>, /* 60, CT CP HPD */
+ <&gpio2 9 GPIO_ACTIVE_HIGH>, /* 41, LS OE */
+ <&gpio2 31 GPIO_ACTIVE_HIGH>; /* 63, HPD */
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ tpd12s015_in: endpoint@0 {
+ remote-endpoint = <&hdmi_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ tpd12s015_out: endpoint@0 {
+ remote-endpoint = <&hdmi_connector_in>;
+ };
+ };
+ };
+};
--
1.8.3.2
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: [PATCH 0/9] Doc/DT: DT bindings for various display components
From: Tomasz Figa @ 2014-02-28 12:37 UTC (permalink / raw)
To: Tomi Valkeinen, linux-fbdev, dri-devel, devicetree,
linux-arm-kernel
Cc: Russell King - ARM Linux, Andrzej Hajda, Laurent Pinchart,
Sebastian Hesselbarth
In-Reply-To: <1393590016-9361-1-git-send-email-tomi.valkeinen@ti.com>
Hi Tomi,
On 28.02.2014 13:20, Tomi Valkeinen wrote:
> Hi,
>
> This series is a re-send of
> http://article.gmane.org/gmane.linux.drivers.devicetree/61739
>
> I'm cc'ing more people, and I want to clarify the contents of the series:
>
> While this has been developed for OMAP, only the first patch is about OMAP
> bindings. The rest are generic bindings for video components, which can be used
> on any platform.
>
> The bindings use the V4L2 style video port/endpoint system, described in
> Documentation/devicetree/bindings/media/video-interfaces.txt, to connect the
> components. The same port/endpoint bindings are used by Philipp Zabel in his
> imx-drm patch series.
>
> Shortly about the display components in the series, in the order of probable
> public interest:
>
> * Analog TV, DVI and HDMI Connectors represent a respective connector on the
> board. They don't do much, but they do mark the end of the video pipeline (from
> the board's pov), and they should also in the future offer ways to handle
> things like the +5V pin on DVI and HDMI connector and HPD pin.
>
> * MIPI DPI panel and MIPI DSI CM panels represent bindings for simple panels
> using the respective video bus.
I'm yet to take a deeper look at this series, but have you seen Andrzej
Hajda's patches adding support for DSI panels on Exynos [1] ?
[1] http://thread.gmane.org/gmane.linux.kernel.samsung-soc/27044
Best regards,
Tomasz
^ permalink raw reply
* RE: [PATCH v4] can: xilinx CAN controller support.
From: Appana Durga Kedareswara Rao @ 2014-02-28 12:44 UTC (permalink / raw)
To: Marc Kleine-Budde, wg@grandegger.com, Michal Simek,
grant.likely@linaro.org, robh+dt@kernel.org,
linux-can@vger.kernel.org
Cc: netdev@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, devicetree@vger.kernel.org
In-Reply-To: <53104995.4010305@pengutronix.de>
Hi Marc,
> -----Original Message-----
> From: Marc Kleine-Budde [mailto:mkl@pengutronix.de]
> Sent: Friday, February 28, 2014 2:02 PM
> To: Appana Durga Kedareswara Rao; wg@grandegger.com; Michal Simek;
> grant.likely@linaro.org; robh+dt@kernel.org; linux-can@vger.kernel.org
> Cc: netdev@vger.kernel.org; linux-arm-kernel@lists.infradead.org; linux-
> kernel@vger.kernel.org; devicetree@vger.kernel.org
> Subject: Re: [PATCH v4] can: xilinx CAN controller support.
>
> On 02/28/2014 06:50 AM, Appana Durga Kedareswara Rao wrote:
> > Hi Marc,
> >
> >
> >> -----Original Message-----
> >> From: Marc Kleine-Budde [mailto:mkl@pengutronix.de]
> >> Sent: Wednesday, February 26, 2014 9:13 PM
> >> To: Appana Durga Kedareswara Rao; wg@grandegger.com; Michal Simek;
> >> grant.likely@linaro.org; robh+dt@kernel.org;
> >> linux-can@vger.kernel.org
> >> Cc: netdev@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
> >> linux- kernel@vger.kernel.org; devicetree@vger.kernel.org
> >> Subject: Re: [PATCH v4] can: xilinx CAN controller support.
> >>
> >> On 02/26/2014 03:46 PM, Appana Durga Kedareswara Rao wrote:
> >>> Hi Marc,
> >>>
> >>>
> >>>> -----Original Message-----
> >>>> From: Marc Kleine-Budde [mailto:mkl@pengutronix.de]
> >>>> Sent: Wednesday, February 26, 2014 6:52 PM
> >>>> To: Appana Durga Kedareswara Rao; wg@grandegger.com; Michal
> Simek;
> >>>> grant.likely@linaro.org; robh+dt@kernel.org;
> >>>> linux-can@vger.kernel.org
> >>>> Cc: netdev@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
> >>>> linux- kernel@vger.kernel.org; devicetree@vger.kernel.org
> >>>> Subject: Re: [PATCH v4] can: xilinx CAN controller support.
> >>>>
> >>>> On 02/26/2014 02:07 PM, Appana Durga Kedareswara Rao wrote:
> >>>>>> This loop looks broken. Can you explain how it works.
> >>>>>>
> >>>>>> What it shoud do is:
> >>>>>> We have put (priv->tx_head - priv->tx_tail) CAN frames into the
> FIFO.
> >>>>>> This means at maximum there could be this amount of CAN frames
> >>>>>> which have been successfully transmitted. For every cycle in this
> >>>>>> while loop you
> >>>>>> should:
> >>>>>> a) check if a CAN frame has successfully been transmitted
> >>>>>> (as this CAN core uses a FIFO it should be "oldest")
> >>>>>> A read_reg() of some kind is missing in your loop.
> >>>>>> b) if needed, remove this event from the FIFO or
> >>>>>> mark the interrupt as done. Whatever you hardware needs.
> >>>>>> c) update your statistics
> >>>>>> d) Use can_get_echo_skb to push this frame into the networking
> >>>>>> stack
> >>>>>> e) As a CAN frame has been transmitted successfully, wake the
> >> tx_queue.
> >>>>>>
> >>>>>>> + while (priv->tx_head - priv->tx_tail > 0) {
> >>>>>>> + if (isr & XCAN_IXR_TXFLL_MASK) {
> >>>>>>> + priv->write_reg(priv, XCAN_ICR_OFFSET,
> >>>>>>> + XCAN_IXR_TXFLL_MASK);
> >>>>>>> + netif_stop_queue(ndev);
> >>>>>>
> >>>>>> Why do you stop the queue here? A CAN frame has successfully
> been
> >>>>>> transmitted, there should be room in the FIFO.
> >>>>>>
> >>>>>>> + break;
> >>>>>>> + }
> >>>>>>> + can_get_echo_skb(ndev, priv->tx_tail %
> >>>>>>> + priv->xcan_echo_skb_max_tx);
> >>>>>>> + priv->tx_tail++;
> >>>>>>> + }
> >>>>>>> +
> >>>>>
> >>>>> The below are the bit fields available for the Transmit FIFO.
> >>>>> 1) In the ISR(interrupt status register) Tx Ok interrupt and Tx
> >>>>> fifo full
> >>>> interrupt.
> >>>>> 2) in the SR(Status Register) Tx fifo full condition.
> >>>>>
> >>>>>
> >>>>> I am modifying the entire tx interrupt logic to like below.
> >>>>>
> >>>>> static void xcan_tx_interrupt(struct net_device *ndev, u32 isr) {
> >>>>> struct xcan_priv *priv = netdev_priv(ndev);
> >>>>> struct net_device_stats *stats = &ndev->stats;
> >>>>>
> >>>>> while (priv->tx_head - priv->tx_tail > 0) {
> >>>>> if (isr & XCAN_IXR_TXFLL_MASK) {
> >>>>> priv->write_reg(priv, XCAN_ICR_OFFSET,
> >>>>> XCAN_IXR_TXFLL_MASK);
> >>>>> break;
> >>>>> }
> >>>>> can_get_echo_skb(ndev, priv->tx_tail %
> >>>>> priv->xcan_echo_skb_max_tx);
> >>>>> priv->tx_tail++;
> >>>>> stats->tx_packets++;
> >>>>> netif_wake_queue(ndev);
> >>>>> can_led_event(ndev, CAN_LED_EVENT_TX);
> >>>>>
> >>>>> }
> >>>>
> >>>> You just need to wake the queue once.
> >>>
> >>> Ok
> >>>>
> >>>>> }
> >>>>>
> >>>>>
> >>>>> Are you Ok with the above logic?
> >>>>
> >>>> No, how can you tell how many frames have been transmitted?
> >>>
> >>> There is no register to read how many can frames are transmitted.
> >>> The only way to know Is by reading this parameter
> >>> (stats->tx_packets++;) through ip command
> >>
> >> stats->tx_packets is calculated in the above loop and the loop is
> >> broken. Let me illustrate the problem:
> >>
> >> - xmit is called 10 times in a row
> >> - this means you have 10 CAN frames in the TX FIFO
> >> - a single CAN frame gets transmitted
> >> - you get an interrupt
> >> - you enter the above routine and loop 10 times and echo the CAN frame
> >> back into the stack
> >>
> >> Now every application sees 10 transmitted packages, but there is only
> >> one transmitted. Every time you loop you have to check if the CAN
> >> frame has already been transmitted or not. Is that possible with the
> hardware?
> >
> > The only way to know whether the TX packet is transmitted
> successfully or not is by using the Tx Ok interrupt from the ISR.
> > This interrupt will come for every Tx Packet.
> > So I am thinking of there is no loop required in the TX interrupt routine. As
> it is called for each and every packet.
>
> What happens if the interrupt handler is delayed? For example in a RT
> enabled system the interrupt handler runs as a thread. There might be other
> threads with higher priority. The hardware will probably send all CAN
> frames in the FIFO, so you want to reduce the overhead and loop in the tx
> complete handler.
>
Yes I agree with your comment.
It will be good to have a loop in the Tx interrupt handler
I am modifying the Tx interrupt handler like below.
static void xcan_tx_interrupt(struct net_device *ndev, u32 isr)
{
struct xcan_priv *priv = netdev_priv(ndev);
struct net_device_stats *stats = &ndev->stats;
while (priv->tx_head - priv->tx_tail > 0) {
if (!(isr & XCAN_IXR_TXOK_MASK)) {
break;
}
can_get_echo_skb(ndev, priv->tx_tail %
priv->xcan_echo_skb_max_tx);
priv->tx_tail++;
stats->tx_packets++;
can_led_event(ndev, CAN_LED_EVENT_TX);
isr = priv->read_reg(priv, XCAN_ISR_OFFSET);
}
netif_wake_queue(ndev);
}
Are you Ok with this?
> >
> > static void xcan_tx_interrupt(struct net_device *ndev, u32 isr) {
> > struct xcan_priv *priv = netdev_priv(ndev);
> > struct net_device_stats *stats = &ndev->stats;
> >
> >
> > can_get_echo_skb(ndev, priv->tx_tail %
> > priv->xcan_echo_skb_max_tx);
> > priv->tx_tail++;
> > stats->tx_packets++;
> > can_led_event(ndev, CAN_LED_EVENT_TX);
> > netif_wake_queue(ndev);
> > }
> >
> > If you want me to put some locks for this Will put some spin_locks in the
> _xmit and in the tx interrupt routine (for the tx_head and tx_tail).
>
> There is no need for locking regarding tx_{head,tail}. As the tx complete
> handler only increments tx_tail and the xmit routine increments tx_head.
>
Ok
Regards,
Kedar.
> Marc
>
> --
> Pengutronix e.K. | Marc Kleine-Budde |
> Industrial Linux Solutions | Phone: +49-231-2826-924 |
> Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
> Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
^ permalink raw reply
* Re: [PATCH v2 1/4] pci: OF: Fix the conversion of IO ranges into IO resources.
From: Liviu Dudau @ 2014-02-28 12:50 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Jason Gunthorpe, linux-arm-kernel@lists.infradead.org, linux-pci,
Bjorn Helgaas, Catalin Marinas, Will Deacon, linaro-kernel,
devicetree@vger.kernel.org, LKML
In-Reply-To: <11097076.0C13zaKdYD@wuerfel>
On Thu, Feb 27, 2014 at 08:22:12PM +0000, Arnd Bergmann wrote:
> On Thursday 27 February 2014 13:07:29 Jason Gunthorpe wrote:
> > On Thu, Feb 27, 2014 at 08:48:08PM +0100, Arnd Bergmann wrote:
> > > > It also looks correct for architectures that use the CPU MMIO address
> > > > as the IO address directly (where IO_SPACE_LIMIT would be 4G)
> > >
> > > Are you aware of any that still do? I thought we had stopped doing
> > > that.
> >
> > I thought ia64 used to, but it has been a long time since I've touched
> > one...
>
> They have a different way of doing it now, no idea how it looked in
> the past:
>
> #define IO_SPACE_LIMIT 0xffffffffffffffffUL
>
> #define MAX_IO_SPACES_BITS 8
> #define MAX_IO_SPACES (1UL << MAX_IO_SPACES_BITS)
> #define IO_SPACE_BITS 24
> #define IO_SPACE_SIZE (1UL << IO_SPACE_BITS)
>
> #define IO_SPACE_NR(port) ((port) >> IO_SPACE_BITS)
> #define IO_SPACE_BASE(space) ((space) << IO_SPACE_BITS)
> #define IO_SPACE_PORT(port) ((port) & (IO_SPACE_SIZE - 1))
>
> #define IO_SPACE_SPARSE_ENCODING(p) ((((p) >> 2) << 12) | ((p) & 0xfff))
>
> So their port number is a logical token that contains the I/O space number
> and a 16MB offset.
>
> Apparently sparc64 uses physical memory addressing for I/O space, the
> same way they do for memory space, and they just set IO_SPACE_LIMIT to
> 0xffffffffffffffffUL.
>
> > > > Architectures that use the virtual IO window technique will always
> > > > require a custom pci_address_to_pio implementation.
> > >
> > > Hmm, at the moment we only call it from of_address_to_resource(),
> > > which in turn does not get called on PCI devices, and does not
> > > call pci_address_to_pio for 'simple' platform devices. The only
> > > case I can think of where it actually matters is when we have
> > > ISA devices in DT that use an I/O port address in the reg property,
> > > and that case hopefully won't happen on ARM32 or ARM64.
> >
> > Sure, I ment, after Liviu's patch it will become required since he is
> > cleverly using it to figure out what the io mapping the bridge driver
> > setup before calling the helper.
>
> Ok. I was arguing more that we should add this dependency.
I've thought about this last night and I think I was trying to be too clever
for my own good. As Jason points out, arm64 needs its own version of
pci_address_to_pio(). I have an idea on how to borrow the powerpc/microblaze
one and make it useful without the need for pci_controller *hose. It would
be generic enough for other platforms that use virtual I/O windows can use,
but I'll start with it being defined for arm64 for discussions in this list.
I'll post v3 shortly.
Best regards,
Liviu
>
> > > > I think the legacy reasons for having all those layers of translation
> > > > are probably not applicable to ARM64, and it is much simpler without
> > > > the extra translation step....
> > > >
> > > > Arnd, what do you think?
> > >
> > > Either I don't like it or I misunderstand you ;-)
> > >
> > > Most PCI drivers normally don't call ioport_map or pci_iomap, so
> > > we can't just do it there. If you are thinking of calling ioport_map
> >
> > Okay, that was one of the 'legacy reasons'. Certainly lots of drivers
> > do call pci_iomap, but if you think legacy drivers that don't are
> > important to ARM64 then it makes sense to use the virtual IO window.
>
> I think all uses of I/O space are legacy, but I don't think that
> drivers doing inb/outb are more obsolete than those doing pci_iomap.
> It's got more to do with the subsystem requirements, e.g. libata
> requires the use of pci_iomap.
>
> > > for every PCI device that has an I/O BAR and storing the virtual
> > > address in the pci_dev resource, I don't see what that gains us
> >
> > Mainly we get to drop the fancy dynamic allocation stuff for the fixed
> > virtual window, and it gives the option to have a 1:1 relationship
> > between CPU addresses and PCI BARs.
>
> I don't think the allocation is much of a problem, as long as we
> can localize it in one function that is shared by everyone.
> The problems I saw were all about explaining to people how it
> works, but they really shouldn't have to know.
>
>
> Arnd
>
>
--
====================
| I would like to |
| fix the world, |
| but they're not |
| giving me the |
\ source code! /
---------------
¯\_(ツ)_/¯
^ permalink raw reply
* Re: [PATCH v4] can: xilinx CAN controller support.
From: Marc Kleine-Budde @ 2014-02-28 12:56 UTC (permalink / raw)
To: Appana Durga Kedareswara Rao, wg@grandegger.com, Michal Simek,
grant.likely@linaro.org, robh+dt@kernel.org,
linux-can@vger.kernel.org
Cc: netdev@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, devicetree@vger.kernel.org
In-Reply-To: <48409965-e214-43b7-8b6a-08bf075707e1@CO9EHSMHS001.ehs.local>
[-- Attachment #1: Type: text/plain, Size: 7961 bytes --]
On 02/28/2014 01:44 PM, Appana Durga Kedareswara Rao wrote:
> Hi Marc,
>
>
>> -----Original Message-----
>> From: Marc Kleine-Budde [mailto:mkl@pengutronix.de]
>> Sent: Friday, February 28, 2014 2:02 PM
>> To: Appana Durga Kedareswara Rao; wg@grandegger.com; Michal Simek;
>> grant.likely@linaro.org; robh+dt@kernel.org; linux-can@vger.kernel.org
>> Cc: netdev@vger.kernel.org; linux-arm-kernel@lists.infradead.org; linux-
>> kernel@vger.kernel.org; devicetree@vger.kernel.org
>> Subject: Re: [PATCH v4] can: xilinx CAN controller support.
>>
>> On 02/28/2014 06:50 AM, Appana Durga Kedareswara Rao wrote:
>>> Hi Marc,
>>>
>>>
>>>> -----Original Message-----
>>>> From: Marc Kleine-Budde [mailto:mkl@pengutronix.de]
>>>> Sent: Wednesday, February 26, 2014 9:13 PM
>>>> To: Appana Durga Kedareswara Rao; wg@grandegger.com; Michal Simek;
>>>> grant.likely@linaro.org; robh+dt@kernel.org;
>>>> linux-can@vger.kernel.org
>>>> Cc: netdev@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
>>>> linux- kernel@vger.kernel.org; devicetree@vger.kernel.org
>>>> Subject: Re: [PATCH v4] can: xilinx CAN controller support.
>>>>
>>>> On 02/26/2014 03:46 PM, Appana Durga Kedareswara Rao wrote:
>>>>> Hi Marc,
>>>>>
>>>>>
>>>>>> -----Original Message-----
>>>>>> From: Marc Kleine-Budde [mailto:mkl@pengutronix.de]
>>>>>> Sent: Wednesday, February 26, 2014 6:52 PM
>>>>>> To: Appana Durga Kedareswara Rao; wg@grandegger.com; Michal
>> Simek;
>>>>>> grant.likely@linaro.org; robh+dt@kernel.org;
>>>>>> linux-can@vger.kernel.org
>>>>>> Cc: netdev@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
>>>>>> linux- kernel@vger.kernel.org; devicetree@vger.kernel.org
>>>>>> Subject: Re: [PATCH v4] can: xilinx CAN controller support.
>>>>>>
>>>>>> On 02/26/2014 02:07 PM, Appana Durga Kedareswara Rao wrote:
>>>>>>>> This loop looks broken. Can you explain how it works.
>>>>>>>>
>>>>>>>> What it shoud do is:
>>>>>>>> We have put (priv->tx_head - priv->tx_tail) CAN frames into the
>> FIFO.
>>>>>>>> This means at maximum there could be this amount of CAN frames
>>>>>>>> which have been successfully transmitted. For every cycle in this
>>>>>>>> while loop you
>>>>>>>> should:
>>>>>>>> a) check if a CAN frame has successfully been transmitted
>>>>>>>> (as this CAN core uses a FIFO it should be "oldest")
>>>>>>>> A read_reg() of some kind is missing in your loop.
>>>>>>>> b) if needed, remove this event from the FIFO or
>>>>>>>> mark the interrupt as done. Whatever you hardware needs.
>>>>>>>> c) update your statistics
>>>>>>>> d) Use can_get_echo_skb to push this frame into the networking
>>>>>>>> stack
>>>>>>>> e) As a CAN frame has been transmitted successfully, wake the
>>>> tx_queue.
>>>>>>>>
>>>>>>>>> + while (priv->tx_head - priv->tx_tail > 0) {
>>>>>>>>> + if (isr & XCAN_IXR_TXFLL_MASK) {
>>>>>>>>> + priv->write_reg(priv, XCAN_ICR_OFFSET,
>>>>>>>>> + XCAN_IXR_TXFLL_MASK);
>>>>>>>>> + netif_stop_queue(ndev);
>>>>>>>>
>>>>>>>> Why do you stop the queue here? A CAN frame has successfully
>> been
>>>>>>>> transmitted, there should be room in the FIFO.
>>>>>>>>
>>>>>>>>> + break;
>>>>>>>>> + }
>>>>>>>>> + can_get_echo_skb(ndev, priv->tx_tail %
>>>>>>>>> + priv->xcan_echo_skb_max_tx);
>>>>>>>>> + priv->tx_tail++;
>>>>>>>>> + }
>>>>>>>>> +
>>>>>>>
>>>>>>> The below are the bit fields available for the Transmit FIFO.
>>>>>>> 1) In the ISR(interrupt status register) Tx Ok interrupt and Tx
>>>>>>> fifo full
>>>>>> interrupt.
>>>>>>> 2) in the SR(Status Register) Tx fifo full condition.
>>>>>>>
>>>>>>>
>>>>>>> I am modifying the entire tx interrupt logic to like below.
>>>>>>>
>>>>>>> static void xcan_tx_interrupt(struct net_device *ndev, u32 isr) {
>>>>>>> struct xcan_priv *priv = netdev_priv(ndev);
>>>>>>> struct net_device_stats *stats = &ndev->stats;
>>>>>>>
>>>>>>> while (priv->tx_head - priv->tx_tail > 0) {
>>>>>>> if (isr & XCAN_IXR_TXFLL_MASK) {
>>>>>>> priv->write_reg(priv, XCAN_ICR_OFFSET,
>>>>>>> XCAN_IXR_TXFLL_MASK);
>>>>>>> break;
>>>>>>> }
>>>>>>> can_get_echo_skb(ndev, priv->tx_tail %
>>>>>>> priv->xcan_echo_skb_max_tx);
>>>>>>> priv->tx_tail++;
>>>>>>> stats->tx_packets++;
>>>>>>> netif_wake_queue(ndev);
>>>>>>> can_led_event(ndev, CAN_LED_EVENT_TX);
>>>>>>>
>>>>>>> }
>>>>>>
>>>>>> You just need to wake the queue once.
>>>>>
>>>>> Ok
>>>>>>
>>>>>>> }
>>>>>>>
>>>>>>>
>>>>>>> Are you Ok with the above logic?
>>>>>>
>>>>>> No, how can you tell how many frames have been transmitted?
>>>>>
>>>>> There is no register to read how many can frames are transmitted.
>>>>> The only way to know Is by reading this parameter
>>>>> (stats->tx_packets++;) through ip command
>>>>
>>>> stats->tx_packets is calculated in the above loop and the loop is
>>>> broken. Let me illustrate the problem:
>>>>
>>>> - xmit is called 10 times in a row
>>>> - this means you have 10 CAN frames in the TX FIFO
>>>> - a single CAN frame gets transmitted
>>>> - you get an interrupt
>>>> - you enter the above routine and loop 10 times and echo the CAN frame
>>>> back into the stack
>>>>
>>>> Now every application sees 10 transmitted packages, but there is only
>>>> one transmitted. Every time you loop you have to check if the CAN
>>>> frame has already been transmitted or not. Is that possible with the
>> hardware?
>>>
>>> The only way to know whether the TX packet is transmitted
>> successfully or not is by using the Tx Ok interrupt from the ISR.
>>> This interrupt will come for every Tx Packet.
>>> So I am thinking of there is no loop required in the TX interrupt routine. As
>> it is called for each and every packet.
>>
>> What happens if the interrupt handler is delayed? For example in a RT
>> enabled system the interrupt handler runs as a thread. There might be other
>> threads with higher priority. The hardware will probably send all CAN
>> frames in the FIFO, so you want to reduce the overhead and loop in the tx
>> complete handler.
>>
> Yes I agree with your comment.
> It will be good to have a loop in the Tx interrupt handler
> I am modifying the Tx interrupt handler like below.
>
> static void xcan_tx_interrupt(struct net_device *ndev, u32 isr)
> {
> struct xcan_priv *priv = netdev_priv(ndev);
> struct net_device_stats *stats = &ndev->stats;
>
> while (priv->tx_head - priv->tx_tail > 0) {
> if (!(isr & XCAN_IXR_TXOK_MASK)) {
> break;
> }
> can_get_echo_skb(ndev, priv->tx_tail %
> priv->xcan_echo_skb_max_tx);
> priv->tx_tail++;
> stats->tx_packets++;
> can_led_event(ndev, CAN_LED_EVENT_TX);
> isr = priv->read_reg(priv, XCAN_ISR_OFFSET);
> }
> netif_wake_queue(ndev);
> }
>
> Are you Ok with this?
Do you have to ACK the interrupt, so that TXOK_MASK is finally cleared?
The use case is here: m CAN frames are put into the FIFO, n out of m CAN
frames are transferred, where n < m. In this case you have to leave the
loop after n, but "priv->tx_head - priv->tx_tail == m".
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 242 bytes --]
^ permalink raw reply
* Re: [PATCH 0/9] Doc/DT: DT bindings for various display components
From: Sebastian Hesselbarth @ 2014-02-28 12:57 UTC (permalink / raw)
To: Tomi Valkeinen, linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: Philipp Zabel, Laurent Pinchart, Russell King - ARM Linux,
Sascha Hauer, Rob Clark, Inki Dae, Andrzej Hajda, Tomasz Figa,
Thierry Reding
In-Reply-To: <1393590016-9361-1-git-send-email-tomi.valkeinen-l0cyMroinI0@public.gmane.org>
On 02/28/14 13:20, Tomi Valkeinen wrote:
> This series is a re-send of
> http://article.gmane.org/gmane.linux.drivers.devicetree/61739
>
...
> Shortly about the display components in the series, in the order of probable
> public interest:
>
> * Analog TV, DVI and HDMI Connectors represent a respective connector on the
> board. They don't do much, but they do mark the end of the video pipeline (from
> the board's pov), and they should also in the future offer ways to handle
> things like the +5V pin on DVI and HDMI connector and HPD pin.
>
> * MIPI DPI panel and MIPI DSI CM panels represent bindings for simple panels
> using the respective video bus.
>
> * Sony acx565akm is an SPI controlled panel using flatlink video bus.
>
> * TFP410 is a DPI to DVI encoder.
>
> * TPD12S015 is a HDMI companion chip, used on OMAP boards.
Tomi,
Out of curiosity, will there be DT nodes for pull-up resistors soon,
too? ;)
Honestly, TPD12S015 is a level shifter, there is nothing in it that
would justify a DT node nor a driver.
Above you already note, that connector nodes should offer HPD in the
future, but I guess the binding should represent that now already.
I will be a DT stub anyway, the corresponding video sink driver will
have to look it up.
Looking through the bindings for DVI and HDMI, I guess HPD gpio is
better kept in those nodes. From the relevant (DT) properties DVI and
HDMI connectors are in no way different.
Sebastian
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* RE: [PATCH v4] can: xilinx CAN controller support.
From: Appana Durga Kedareswara Rao @ 2014-02-28 13:07 UTC (permalink / raw)
To: Marc Kleine-Budde, wg@grandegger.com, Michal Simek,
grant.likely@linaro.org, robh+dt@kernel.org,
linux-can@vger.kernel.org
Cc: netdev@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, devicetree@vger.kernel.org
In-Reply-To: <53108798.7090902@pengutronix.de>
Hi Marc,
> -----Original Message-----
> From: Marc Kleine-Budde [mailto:mkl@pengutronix.de]
> Sent: Friday, February 28, 2014 6:27 PM
> To: Appana Durga Kedareswara Rao; wg@grandegger.com; Michal Simek;
> grant.likely@linaro.org; robh+dt@kernel.org; linux-can@vger.kernel.org
> Cc: netdev@vger.kernel.org; linux-arm-kernel@lists.infradead.org; linux-
> kernel@vger.kernel.org; devicetree@vger.kernel.org
> Subject: Re: [PATCH v4] can: xilinx CAN controller support.
>
> On 02/28/2014 01:44 PM, Appana Durga Kedareswara Rao wrote:
> > Hi Marc,
> >
> >
> >> -----Original Message-----
> >> From: Marc Kleine-Budde [mailto:mkl@pengutronix.de]
> >> Sent: Friday, February 28, 2014 2:02 PM
> >> To: Appana Durga Kedareswara Rao; wg@grandegger.com; Michal Simek;
> >> grant.likely@linaro.org; robh+dt@kernel.org;
> >> linux-can@vger.kernel.org
> >> Cc: netdev@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
> >> linux- kernel@vger.kernel.org; devicetree@vger.kernel.org
> >> Subject: Re: [PATCH v4] can: xilinx CAN controller support.
> >>
> >> On 02/28/2014 06:50 AM, Appana Durga Kedareswara Rao wrote:
> >>> Hi Marc,
> >>>
> >>>
> >>>> -----Original Message-----
> >>>> From: Marc Kleine-Budde [mailto:mkl@pengutronix.de]
> >>>> Sent: Wednesday, February 26, 2014 9:13 PM
> >>>> To: Appana Durga Kedareswara Rao; wg@grandegger.com; Michal
> Simek;
> >>>> grant.likely@linaro.org; robh+dt@kernel.org;
> >>>> linux-can@vger.kernel.org
> >>>> Cc: netdev@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
> >>>> linux- kernel@vger.kernel.org; devicetree@vger.kernel.org
> >>>> Subject: Re: [PATCH v4] can: xilinx CAN controller support.
> >>>>
> >>>> On 02/26/2014 03:46 PM, Appana Durga Kedareswara Rao wrote:
> >>>>> Hi Marc,
> >>>>>
> >>>>>
> >>>>>> -----Original Message-----
> >>>>>> From: Marc Kleine-Budde [mailto:mkl@pengutronix.de]
> >>>>>> Sent: Wednesday, February 26, 2014 6:52 PM
> >>>>>> To: Appana Durga Kedareswara Rao; wg@grandegger.com; Michal
> >> Simek;
> >>>>>> grant.likely@linaro.org; robh+dt@kernel.org;
> >>>>>> linux-can@vger.kernel.org
> >>>>>> Cc: netdev@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
> >>>>>> linux- kernel@vger.kernel.org; devicetree@vger.kernel.org
> >>>>>> Subject: Re: [PATCH v4] can: xilinx CAN controller support.
> >>>>>>
> >>>>>> On 02/26/2014 02:07 PM, Appana Durga Kedareswara Rao wrote:
> >>>>>>>> This loop looks broken. Can you explain how it works.
> >>>>>>>>
> >>>>>>>> What it shoud do is:
> >>>>>>>> We have put (priv->tx_head - priv->tx_tail) CAN frames into the
> >> FIFO.
> >>>>>>>> This means at maximum there could be this amount of CAN frames
> >>>>>>>> which have been successfully transmitted. For every cycle in
> >>>>>>>> this while loop you
> >>>>>>>> should:
> >>>>>>>> a) check if a CAN frame has successfully been transmitted
> >>>>>>>> (as this CAN core uses a FIFO it should be "oldest")
> >>>>>>>> A read_reg() of some kind is missing in your loop.
> >>>>>>>> b) if needed, remove this event from the FIFO or
> >>>>>>>> mark the interrupt as done. Whatever you hardware needs.
> >>>>>>>> c) update your statistics
> >>>>>>>> d) Use can_get_echo_skb to push this frame into the networking
> >>>>>>>> stack
> >>>>>>>> e) As a CAN frame has been transmitted successfully, wake the
> >>>> tx_queue.
> >>>>>>>>
> >>>>>>>>> + while (priv->tx_head - priv->tx_tail > 0) {
> >>>>>>>>> + if (isr & XCAN_IXR_TXFLL_MASK) {
> >>>>>>>>> + priv->write_reg(priv, XCAN_ICR_OFFSET,
> >>>>>>>>> + XCAN_IXR_TXFLL_MASK);
> >>>>>>>>> + netif_stop_queue(ndev);
> >>>>>>>>
> >>>>>>>> Why do you stop the queue here? A CAN frame has successfully
> >> been
> >>>>>>>> transmitted, there should be room in the FIFO.
> >>>>>>>>
> >>>>>>>>> + break;
> >>>>>>>>> + }
> >>>>>>>>> + can_get_echo_skb(ndev, priv->tx_tail %
> >>>>>>>>> + priv->xcan_echo_skb_max_tx);
> >>>>>>>>> + priv->tx_tail++;
> >>>>>>>>> + }
> >>>>>>>>> +
> >>>>>>>
> >>>>>>> The below are the bit fields available for the Transmit FIFO.
> >>>>>>> 1) In the ISR(interrupt status register) Tx Ok interrupt and Tx
> >>>>>>> fifo full
> >>>>>> interrupt.
> >>>>>>> 2) in the SR(Status Register) Tx fifo full condition.
> >>>>>>>
> >>>>>>>
> >>>>>>> I am modifying the entire tx interrupt logic to like below.
> >>>>>>>
> >>>>>>> static void xcan_tx_interrupt(struct net_device *ndev, u32 isr) {
> >>>>>>> struct xcan_priv *priv = netdev_priv(ndev);
> >>>>>>> struct net_device_stats *stats = &ndev->stats;
> >>>>>>>
> >>>>>>> while (priv->tx_head - priv->tx_tail > 0) {
> >>>>>>> if (isr & XCAN_IXR_TXFLL_MASK) {
> >>>>>>> priv->write_reg(priv, XCAN_ICR_OFFSET,
> >>>>>>> XCAN_IXR_TXFLL_MASK);
> >>>>>>> break;
> >>>>>>> }
> >>>>>>> can_get_echo_skb(ndev, priv->tx_tail %
> >>>>>>> priv->xcan_echo_skb_max_tx);
> >>>>>>> priv->tx_tail++;
> >>>>>>> stats->tx_packets++;
> >>>>>>> netif_wake_queue(ndev);
> >>>>>>> can_led_event(ndev, CAN_LED_EVENT_TX);
> >>>>>>>
> >>>>>>> }
> >>>>>>
> >>>>>> You just need to wake the queue once.
> >>>>>
> >>>>> Ok
> >>>>>>
> >>>>>>> }
> >>>>>>>
> >>>>>>>
> >>>>>>> Are you Ok with the above logic?
> >>>>>>
> >>>>>> No, how can you tell how many frames have been transmitted?
> >>>>>
> >>>>> There is no register to read how many can frames are transmitted.
> >>>>> The only way to know Is by reading this parameter
> >>>>> (stats->tx_packets++;) through ip command
> >>>>
> >>>> stats->tx_packets is calculated in the above loop and the loop is
> >>>> broken. Let me illustrate the problem:
> >>>>
> >>>> - xmit is called 10 times in a row
> >>>> - this means you have 10 CAN frames in the TX FIFO
> >>>> - a single CAN frame gets transmitted
> >>>> - you get an interrupt
> >>>> - you enter the above routine and loop 10 times and echo the CAN
> frame
> >>>> back into the stack
> >>>>
> >>>> Now every application sees 10 transmitted packages, but there is
> >>>> only one transmitted. Every time you loop you have to check if the
> >>>> CAN frame has already been transmitted or not. Is that possible
> >>>> with the
> >> hardware?
> >>>
> >>> The only way to know whether the TX packet is transmitted
> >> successfully or not is by using the Tx Ok interrupt from the ISR.
> >>> This interrupt will come for every Tx Packet.
> >>> So I am thinking of there is no loop required in the TX interrupt
> >>> routine. As
> >> it is called for each and every packet.
> >>
> >> What happens if the interrupt handler is delayed? For example in a RT
> >> enabled system the interrupt handler runs as a thread. There might be
> >> other threads with higher priority. The hardware will probably send
> >> all CAN frames in the FIFO, so you want to reduce the overhead and
> >> loop in the tx complete handler.
> >>
> > Yes I agree with your comment.
> > It will be good to have a loop in the Tx interrupt handler I am
> > modifying the Tx interrupt handler like below.
> >
> > static void xcan_tx_interrupt(struct net_device *ndev, u32 isr) {
> > struct xcan_priv *priv = netdev_priv(ndev);
> > struct net_device_stats *stats = &ndev->stats;
> >
> > while (priv->tx_head - priv->tx_tail > 0) {
> > if (!(isr & XCAN_IXR_TXOK_MASK)) {
> > break;
> > }
> > can_get_echo_skb(ndev, priv->tx_tail %
> > priv->xcan_echo_skb_max_tx);
> > priv->tx_tail++;
> > stats->tx_packets++;
> > can_led_event(ndev, CAN_LED_EVENT_TX);
> > isr = priv->read_reg(priv, XCAN_ISR_OFFSET);
--> clear Tx OK interrupt.
> > }
> > netif_wake_queue(ndev);
> > }
> >
> > Are you Ok with this?
>
> Do you have to ACK the interrupt, so that TXOK_MASK is finally cleared?
> The use case is here: m CAN frames are put into the FIFO, n out of m CAN
> frames are transferred, where n < m. In this case you have to leave the loop
> after n, but "priv->tx_head - priv->tx_tail == m".
>
Yes I forget to add that I added a line here above in the loop clear TXOK interrupt.
I think it fixes your above question. Please Correct me if I miss understand your question.
Regards,
Kedar.
> Marc
>
> --
> Pengutronix e.K. | Marc Kleine-Budde |
> Industrial Linux Solutions | Phone: +49-231-2826-924 |
> Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
> Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
^ permalink raw reply
* [PATCH v3 0/5] [RFC] Support for creating generic host_bridge from device tree
From: Liviu Dudau @ 2014-02-28 13:08 UTC (permalink / raw)
To: linux-pci, Bjorn Helgaas, Catalin Marinas, Will Deacon,
linaro-kernel
Cc: Benjamin Herrenschmidt, LKML, devicetree@vger.kernel.org, LAKML
This is v3 of my attempt to add support for a generic pci_host_bridge controller created
from a description passed in the device tree.
Changes from v2:
- Use range->cpu_addr when calling pci_address_to_pio()
- Introduce pci_register_io_range() helper function in order to register
io ranges ahead of their conversion to PIO values. This is needed as no
information is being stored yet regarding the range mapping, making
pci_address_to_pio() fail. Default weak implementation does nothing,
to cover the default weak implementation of pci_address_to_pio() that
expects direct mapping of physical addresses into PIO values (x86 view).
Changes from v1:
- Add patch to fix conversion of IO ranges into IO resources.
- Added a domain_nr member to pci_host_bridge structure, and a new function
to create a root bus in a given domain number. In order to facilitate that
I propose changing the order of initialisation between pci_host_bridge and
it's related bus in pci_create_root_bus() as sort of a rever of 7b5436635800.
This is done in patch 1/4 and 2/4.
- Added a simple allocator of domain numbers in drivers/pci/host-bridge.c. The
code will first try to get a domain id from of_alias_get_id(..., "pci-domain")
and if that fails assign the next unallocated domain id.
- Changed the name of the function that creates the generic host bridge from
pci_host_bridge_of_init to of_create_pci_host_bridge and exported as GPL symbol.
v1 thread here: https://lkml.org/lkml/2014/2/3/380
The following is an edit of the original blurb:
Following the discussion started here [1], I now have a proposal for tackling
generic support for host bridges described via device tree. It is an initial
stab at it, to try to get feedback and suggestions, but it is functional enough
that I have PCI Express for arm64 working on an FPGA using the patch that I am
also publishing that adds support for PCI for that platform.
Looking at the existing architectures that fit the requirements (use of device
tree and PCI) yields the powerpc and microblaze as generic enough to make them
candidates for conversion. I have a tentative patch for microblaze that I can
only compile test it, unfortunately using qemu-microblaze leads to an early
crash in the kernel.
As Bjorn has mentioned in the previous discussion, the idea is to add to
struct pci_host_bridge enough data to be able to reduce the size or remove the
architecture specific pci_controller structure. arm64 support actually manages
to get rid of all the architecture static data and has no pci_controller structure
defined. For host bridge drivers that means a change of API unless architectures
decide to provide a compatibility layer (comments here please).
In order to initialise a host bridge with the new API, the following example
code is sufficient for a _probe() function:
static int myhostbridge_probe(struct platform_device *pdev)
{
int err;
struct device_node *dev;
struct pci_host_bridge *bridge;
struct myhostbridge_port *pp;
resource_size_t lastbus;
dev = pdev->dev.of_node;
if (!of_device_is_available(dev)) {
pr_warn("%s: disabled\n", dev->full_name);
return -ENODEV;
}
pp = kzalloc(sizeof(struct myhostbridge_port), GFP_KERNEL);
if (!pp)
return -ENOMEM;
bridge = of_create_pci_host_bridge(&pdev->dev, &myhostbridge_ops, pp);
if (!bridge) {
err = -EINVAL;
goto bridge_init_fail;
}
err = myhostbridge_setup(bridge->bus);
if (err)
goto bridge_init_fail;
/* We always enable PCI domains and we keep domain 0 backward
* compatible in /proc for video cards
*/
pci_add_flags(PCI_ENABLE_PROC_DOMAINS | PCI_COMPAT_DOMAIN_0);
pci_add_flags(PCI_REASSIGN_ALL_BUS | PCI_REASSIGN_ALL_RSRC);
lastbus = pci_scan_child_bus(bridge->bus);
pci_bus_update_busn_res_end(bridge->bus, lastbus);
pci_assign_unassigned_bus_resources(bridge->bus);
pci_bus_add_devices(bridge->bus);
return 0;
bridge_init_fail:
kfree(pp);
return err;
}
[1] http://thread.gmane.org/gmane.linux.kernel.pci/25946
Best regards,
Liviu
Liviu Dudau (5):
pci: Introduce pci_register_io_range() helper function.
pci: OF: Fix the conversion of IO ranges into IO resources.
pci: Create pci_host_bridge before its associated bus in pci_create_root_bus.
pci: Introduce a domain number for pci_host_bridge.
pci: Add support for creating a generic host_bridge from device tree
drivers/of/address.c | 39 +++++++++++++
drivers/pci/host-bridge.c | 134 +++++++++++++++++++++++++++++++++++++++++++++
drivers/pci/probe.c | 66 ++++++++++++++--------
include/linux/of_address.h | 14 +----
include/linux/pci.h | 17 ++++++
5 files changed, 236 insertions(+), 34 deletions(-)
--
1.9.0
^ permalink raw reply
* [PATCH v3 1/5] pci: Introduce pci_register_io_range() helper function.
From: Liviu Dudau @ 2014-02-28 13:08 UTC (permalink / raw)
To: linux-pci, Bjorn Helgaas, Catalin Marinas, Will Deacon,
linaro-kernel
Cc: Benjamin Herrenschmidt, LKML, devicetree@vger.kernel.org, LAKML
In-Reply-To: <1393592902-24750-1-git-send-email-Liviu.Dudau@arm.com>
Some architectures do not share x86 simple view of the I/O space and
instead use a range of addresses that map to external devices. For PCI,
these ranges can be expressed by OF bindings in a device tree file.
Introduce a pci_register_io_range() helper function that can be used
by the architecture code to keep track of the io ranges described by the
PCI bindings.
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
diff --git a/drivers/of/address.c b/drivers/of/address.c
index 1a54f1f..d1bb30f 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -619,6 +619,11 @@ const __be32 *of_get_address(struct device_node *dev, int index, u64 *size,
}
EXPORT_SYMBOL(of_get_address);
+int __weak pci_register_io_range(phys_addr_t addr, resource_size_t size)
+{
+ return 0;
+}
+
unsigned long __weak pci_address_to_pio(phys_addr_t address)
{
if (address > IO_SPACE_LIMIT)
diff --git a/include/linux/of_address.h b/include/linux/of_address.h
index 5f6ed6b..40c418d 100644
--- a/include/linux/of_address.h
+++ b/include/linux/of_address.h
@@ -56,6 +56,7 @@ extern void __iomem *of_iomap(struct device_node *device, int index);
extern const __be32 *of_get_address(struct device_node *dev, int index,
u64 *size, unsigned int *flags);
+extern int pci_register_io_range(phys_addr_t addr, resource_size_t size);
extern unsigned long pci_address_to_pio(phys_addr_t addr);
extern int of_pci_range_parser_init(struct of_pci_range_parser *parser,
--
1.9.0
^ permalink raw reply related
* [PATCH v3 2/5] pci: OF: Fix the conversion of IO ranges into IO resources.
From: Liviu Dudau @ 2014-02-28 13:08 UTC (permalink / raw)
To: linux-pci, Bjorn Helgaas, Catalin Marinas, Will Deacon,
linaro-kernel
Cc: Benjamin Herrenschmidt, LKML, LAKML, devicetree@vger.kernel.org
In-Reply-To: <1393592902-24750-1-git-send-email-Liviu.Dudau@arm.com>
The ranges property for a host bridge controller in DT describes
the mapping between the PCI bus address and the CPU physical address.
The resources framework however expects that the IO resources start
at a pseudo "port" address 0 (zero) and have a maximum size of IO_SPACE_LIMIT.
The conversion from pci ranges to resources failed to take that into account.
In the process move the function into drivers/of/address.c as it
now depends on pci_address_to_pio() code.
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
diff --git a/drivers/of/address.c b/drivers/of/address.c
index d1bb30f..d595d98 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -724,3 +724,37 @@ void __iomem *of_iomap(struct device_node *np, int index)
return ioremap(res.start, resource_size(&res));
}
EXPORT_SYMBOL(of_iomap);
+
+/**
+ * of_pci_range_to_resource - Create a resource from an of_pci_range
+ * @range: the PCI range that describes the resource
+ * @np: device node where the range belongs to
+ * @res: pointer to a valid resource that will be updated to
+ * reflect the values contained in the range.
+ * Note that if the range is an IO range, the resource will be converted
+ * using pci_address_to_pio() which can fail if it is called too early or
+ * if the range cannot be matched to any host bridge IO space (our case here).
+ * To guard against that we try to register the IO range first.
+ * If that fails we know that pci_address_to_pio() will do too.
+ */
+void of_pci_range_to_resource(struct of_pci_range *range,
+ struct device_node *np, struct resource *res)
+{
+ res->flags = range->flags;
+ if (res->flags & IORESOURCE_IO) {
+ unsigned long port = -1;
+ if (!pci_register_io_range(range->cpu_addr, range->size))
+ port = pci_address_to_pio(range->cpu_addr);
+ if (port == (unsigned long)-1) {
+ res->start = (resource_size_t)OF_BAD_ADDR;
+ res->end = (resource_size_t)OF_BAD_ADDR;
+ return;
+ }
+ res->start = port;
+ } else {
+ res->start = range->cpu_addr;
+ }
+ res->end = res->start + range->size - 1;
+ res->parent = res->child = res->sibling = NULL;
+ res->name = np->full_name;
+}
diff --git a/include/linux/of_address.h b/include/linux/of_address.h
index 40c418d..3fe500a 100644
--- a/include/linux/of_address.h
+++ b/include/linux/of_address.h
@@ -23,17 +23,8 @@ struct of_pci_range {
#define for_each_of_pci_range(parser, range) \
for (; of_pci_range_parser_one(parser, range);)
-static inline void of_pci_range_to_resource(struct of_pci_range *range,
- struct device_node *np,
- struct resource *res)
-{
- res->flags = range->flags;
- res->start = range->cpu_addr;
- res->end = range->cpu_addr + range->size - 1;
- res->parent = res->child = res->sibling = NULL;
- res->name = np->full_name;
-}
-
+extern void of_pci_range_to_resource(struct of_pci_range *range,
+ struct device_node *np, struct resource *res);
/* Translate a DMA address from device space to CPU space */
extern u64 of_translate_dma_address(struct device_node *dev,
const __be32 *in_addr);
--
1.9.0
^ permalink raw reply related
* [PATCH v3 3/5] pci: Create pci_host_bridge before its associated bus in pci_create_root_bus.
From: Liviu Dudau @ 2014-02-28 13:08 UTC (permalink / raw)
To: linux-pci, Bjorn Helgaas, Catalin Marinas, Will Deacon,
linaro-kernel
Cc: Benjamin Herrenschmidt, LKML, LAKML, devicetree@vger.kernel.org
In-Reply-To: <1393592902-24750-1-git-send-email-Liviu.Dudau@arm.com>
Before commit 7b5436635800 the pci_host_bridge was created before the root bus.
As that commit has added a needless dependency on the bus for pci_alloc_host_bridge()
the creation order has been changed for no good reason. Revert the order of
creation as we are going to depend on the pci_host_bridge structure to retrieve the
domain number of the root bus.
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 6e34498..78ccba0 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -505,7 +505,7 @@ static void pci_release_host_bridge_dev(struct device *dev)
kfree(bridge);
}
-static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
+static struct pci_host_bridge *pci_alloc_host_bridge(void)
{
struct pci_host_bridge *bridge;
@@ -514,7 +514,6 @@ static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
return NULL;
INIT_LIST_HEAD(&bridge->windows);
- bridge->bus = b;
return bridge;
}
@@ -1727,9 +1726,21 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
char bus_addr[64];
char *fmt;
+ bridge = pci_alloc_host_bridge();
+ if (!bridge)
+ return NULL;
+
+ bridge->dev.parent = parent;
+ bridge->dev.release = pci_release_host_bridge_dev;
+ error = pcibios_root_bridge_prepare(bridge);
+ if (error) {
+ kfree(bridge);
+ return NULL;
+ }
+
b = pci_alloc_bus();
if (!b)
- return NULL;
+ goto err_out;
b->sysdata = sysdata;
b->ops = ops;
@@ -1738,26 +1749,15 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
if (b2) {
/* If we already got to this bus through a different bridge, ignore it */
dev_dbg(&b2->dev, "bus already known\n");
- goto err_out;
+ goto err_bus_out;
}
- bridge = pci_alloc_host_bridge(b);
- if (!bridge)
- goto err_out;
-
- bridge->dev.parent = parent;
- bridge->dev.release = pci_release_host_bridge_dev;
+ bridge->bus = b;
dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus);
- error = pcibios_root_bridge_prepare(bridge);
- if (error) {
- kfree(bridge);
- goto err_out;
- }
-
error = device_register(&bridge->dev);
if (error) {
put_device(&bridge->dev);
- goto err_out;
+ goto err_bus_out;
}
b->bridge = get_device(&bridge->dev);
device_enable_async_suspend(b->bridge);
@@ -1814,8 +1814,10 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
class_dev_reg_err:
put_device(&bridge->dev);
device_unregister(&bridge->dev);
-err_out:
+err_bus_out:
kfree(b);
+err_out:
+ kfree(bridge);
return NULL;
}
--
1.9.0
^ permalink raw reply related
* [PATCH v3 4/5] pci: Introduce a domain number for pci_host_bridge.
From: Liviu Dudau @ 2014-02-28 13:08 UTC (permalink / raw)
To: linux-pci, Bjorn Helgaas, Catalin Marinas, Will Deacon,
linaro-kernel
Cc: Benjamin Herrenschmidt, LKML, devicetree@vger.kernel.org, LAKML
In-Reply-To: <1393592902-24750-1-git-send-email-Liviu.Dudau@arm.com>
Make it easier to discover the domain number of a bus by storing
the number in pci_host_bridge for the root bus. Several architectures
have their own way of storing this information, so it makes sense
to try to unify the code. While at this, add a new function that
creates a root bus in a given domain and make pci_create_root_bus()
a wrapper around this function.
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 78ccba0..1b2f45c 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1714,8 +1714,9 @@ void __weak pcibios_remove_bus(struct pci_bus *bus)
{
}
-struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
- struct pci_ops *ops, void *sysdata, struct list_head *resources)
+struct pci_bus *pci_create_root_bus_in_domain(struct device *parent,
+ int domain, int bus, struct pci_ops *ops, void *sysdata,
+ struct list_head *resources)
{
int error;
struct pci_host_bridge *bridge;
@@ -1732,6 +1733,7 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
bridge->dev.parent = parent;
bridge->dev.release = pci_release_host_bridge_dev;
+ bridge->domain_nr = domain;
error = pcibios_root_bridge_prepare(bridge);
if (error) {
kfree(bridge);
@@ -1745,7 +1747,7 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
b->sysdata = sysdata;
b->ops = ops;
b->number = b->busn_res.start = bus;
- b2 = pci_find_bus(pci_domain_nr(b), bus);
+ b2 = pci_find_bus(bridge->domain_nr, bus);
if (b2) {
/* If we already got to this bus through a different bridge, ignore it */
dev_dbg(&b2->dev, "bus already known\n");
@@ -1753,7 +1755,7 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
}
bridge->bus = b;
- dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus);
+ dev_set_name(&bridge->dev, "pci%04x:%02x", bridge->domain_nr, bus);
error = device_register(&bridge->dev);
if (error) {
put_device(&bridge->dev);
@@ -1768,7 +1770,7 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
b->dev.class = &pcibus_class;
b->dev.parent = b->bridge;
- dev_set_name(&b->dev, "%04x:%02x", pci_domain_nr(b), bus);
+ dev_set_name(&b->dev, "%04x:%02x", bridge->domain_nr, bus);
error = device_register(&b->dev);
if (error)
goto class_dev_reg_err;
@@ -1821,6 +1823,22 @@ err_out:
return NULL;
}
+struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
+ struct pci_ops *ops, void *sysdata, struct list_head *resources)
+{
+ int domain_nr;
+ struct pci_bus *b = pci_alloc_bus();
+ if (!b)
+ return NULL;
+
+ b->sysdata = sysdata;
+ domain_nr = pci_domain_nr(b);
+ kfree(b);
+
+ return pci_create_root_bus_in_domain(parent, domain_nr, bus,
+ ops, sysdata, resources);
+}
+
int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int bus_max)
{
struct resource *res = &b->busn_res;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 33aa2ca..1eed009 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -394,6 +394,7 @@ struct pci_host_bridge_window {
struct pci_host_bridge {
struct device dev;
struct pci_bus *bus; /* root bus */
+ int domain_nr;
struct list_head windows; /* pci_host_bridge_windows */
void (*release_fn)(struct pci_host_bridge *);
void *release_data;
@@ -747,6 +748,9 @@ struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata);
struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
struct pci_ops *ops, void *sysdata,
struct list_head *resources);
+struct pci_bus *pci_create_root_bus_in_domain(struct device *parent,
+ int domain, int bus, struct pci_ops *ops,
+ void *sysdata, struct list_head *resources);
int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int busmax);
int pci_bus_update_busn_res_end(struct pci_bus *b, int busmax);
void pci_bus_release_busn_res(struct pci_bus *b);
--
1.9.0
^ permalink raw reply related
* [PATCH v3 5/5] pci: Add support for creating a generic host_bridge from device tree
From: Liviu Dudau @ 2014-02-28 13:08 UTC (permalink / raw)
To: linux-pci, Bjorn Helgaas, Catalin Marinas, Will Deacon,
linaro-kernel
Cc: Benjamin Herrenschmidt, LKML, devicetree@vger.kernel.org, LAKML
In-Reply-To: <1393592902-24750-1-git-send-email-Liviu.Dudau@arm.com>
Several platforms use a rather generic version of parsing
the device tree to find the host bridge ranges. Move the common code
into the generic PCI code and use it to create a pci_host_bridge
structure that can be used by arch code.
Based on early attempts by Andrew Murray to unify the code.
Used powerpc and microblaze PCI code as starting point.
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
diff --git a/drivers/pci/host-bridge.c b/drivers/pci/host-bridge.c
index 06ace62..feb8436 100644
--- a/drivers/pci/host-bridge.c
+++ b/drivers/pci/host-bridge.c
@@ -6,9 +6,13 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_pci.h>
#include "pci.h"
+static int domain_nr;
+
static struct pci_bus *find_pci_root_bus(struct pci_bus *bus)
{
while (bus->parent)
@@ -91,3 +95,133 @@ void pcibios_bus_to_resource(struct pci_bus *bus, struct resource *res,
res->end = region->end + offset;
}
EXPORT_SYMBOL(pcibios_bus_to_resource);
+
+/**
+ * pci_host_bridge_of_get_ranges - Parse PCI host bridge resources from DT
+ * @dev: device node of the host bridge having the range property
+ * @resources: list where the range of resources will be added after DT parsing
+ * @io_base: pointer to a variable that will contain the physical address for
+ * the start of the I/O range.
+ *
+ * If this function returns an error then the @resources list will be freed.
+ *
+ * This function will parse the "ranges" property of a PCI host bridge device
+ * node and setup the resource mapping based on its content. It is expected
+ * that the property conforms with the Power ePAPR document.
+ *
+ * Each architecture is then offered the chance of applying their own
+ * filtering of pci_host_bridge_windows based on their own restrictions by
+ * calling pcibios_fixup_bridge_ranges(). The filtered list of windows
+ * can then be used when creating a pci_host_bridge structure.
+ */
+static int pci_host_bridge_of_get_ranges(struct device_node *dev,
+ struct list_head *resources, resource_size_t *io_base)
+{
+ struct resource *res;
+ struct of_pci_range range;
+ struct of_pci_range_parser parser;
+ int err;
+
+ pr_info("PCI host bridge %s ranges:\n", dev->full_name);
+
+ /* Check for ranges property */
+ err = of_pci_range_parser_init(&parser, dev);
+ if (err)
+ return err;
+
+ pr_debug("Parsing ranges property...\n");
+ for_each_of_pci_range(&parser, &range) {
+ /* Read next ranges element */
+ pr_debug("pci_space: 0x%08x pci_addr:0x%016llx ",
+ range.pci_space, range.pci_addr);
+ pr_debug("cpu_addr:0x%016llx size:0x%016llx\n",
+ range.cpu_addr, range.size);
+
+ /*
+ * If we failed translation or got a zero-sized region
+ * then skip this range
+ */
+ if (range.cpu_addr == OF_BAD_ADDR || range.size == 0)
+ continue;
+
+ res = kzalloc(sizeof(struct resource), GFP_KERNEL);
+ if (!res) {
+ err = -ENOMEM;
+ goto bridge_ranges_nomem;
+ }
+
+ of_pci_range_to_resource(&range, dev, res);
+
+ if (resource_type(res) == IORESOURCE_IO)
+ *io_base = range.cpu_addr;
+
+ pci_add_resource_offset(resources, res,
+ res->start - range.pci_addr);
+ }
+
+ /* Apply architecture specific fixups for the ranges */
+ pcibios_fixup_bridge_ranges(resources);
+
+ return 0;
+
+bridge_ranges_nomem:
+ pci_free_resource_list(resources);
+ return err;
+}
+
+/**
+ * of_create_pci_host_bridge - Create a PCI host bridge structure using
+ * information passed in the DT.
+ * @parent: device owning this host bridge
+ * @ops: pci_ops associated with the host controller
+ * @host_data: opaque data structure used by the host controller.
+ *
+ * returns a pointer to the newly created pci_host_bridge structure, or
+ * NULL if the call failed.
+ *
+ * This function will try to obtain the host bridge domain number by
+ * using of_alias_get_id() call with "pci-domain" as a stem. If that
+ * fails, a local allocator will be used that will put each host bridge
+ * in a new domain.
+ */
+struct pci_host_bridge *
+of_create_pci_host_bridge(struct device *parent, struct pci_ops *ops, void *host_data)
+{
+ int err, domain, busno;
+ struct resource bus_range;
+ struct pci_bus *root_bus;
+ struct pci_host_bridge *bridge;
+ resource_size_t io_base;
+ LIST_HEAD(res);
+
+ domain = of_alias_get_id(parent->of_node, "pci-domain");
+ if (domain == -ENODEV)
+ domain = domain_nr++;
+
+ err = of_pci_parse_bus_range(parent->of_node, &bus_range);
+ if (err) {
+ dev_info(parent, "No bus range for %s, using default [0-255]\n",
+ parent->of_node->full_name);
+ bus_range.start = 0;
+ bus_range.end = 255;
+ bus_range.flags = IORESOURCE_BUS;
+ }
+ busno = bus_range.start;
+ pci_add_resource(&res, &bus_range);
+
+ /* now parse the rest of host bridge bus ranges */
+ if (pci_host_bridge_of_get_ranges(parent->of_node, &res, &io_base))
+ return NULL;
+
+ /* then create the root bus */
+ root_bus = pci_create_root_bus_in_domain(parent, domain, busno,
+ ops, host_data, &res);
+ if (!root_bus)
+ return NULL;
+
+ bridge = to_pci_host_bridge(root_bus->bridge);
+ bridge->io_base = io_base;
+
+ return bridge;
+}
+EXPORT_SYMBOL_GPL(of_create_pci_host_bridge);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 1eed009..0c5e269 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -395,6 +395,7 @@ struct pci_host_bridge {
struct device dev;
struct pci_bus *bus; /* root bus */
int domain_nr;
+ resource_size_t io_base; /* physical address for the start of I/O area */
struct list_head windows; /* pci_host_bridge_windows */
void (*release_fn)(struct pci_host_bridge *);
void *release_data;
@@ -1786,11 +1787,23 @@ static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
return bus ? bus->dev.of_node : NULL;
}
+struct pci_host_bridge *
+of_create_pci_host_bridge(struct device *parent, struct pci_ops *ops,
+ void *host_data);
+
+void pcibios_fixup_bridge_ranges(struct list_head *resources);
#else /* CONFIG_OF */
static inline void pci_set_of_node(struct pci_dev *dev) { }
static inline void pci_release_of_node(struct pci_dev *dev) { }
static inline void pci_set_bus_of_node(struct pci_bus *bus) { }
static inline void pci_release_bus_of_node(struct pci_bus *bus) { }
+
+static inline struct pci_host_bridge *
+pci_host_bridge_of_init(struct device *parent, struct pci_ops *ops,
+ void *host_data)
+{
+ return NULL;
+}
#endif /* CONFIG_OF */
#ifdef CONFIG_EEH
--
1.9.0
^ permalink raw reply related
* [PATCH v3 0/3] [RFC] Add support for PCI in AArch64
From: Liviu Dudau @ 2014-02-28 13:08 UTC (permalink / raw)
To: linux-pci, Bjorn Helgaas, Catalin Marinas, Will Deacon,
linaro-kernel
Cc: Benjamin Herrenschmidt, LKML, devicetree@vger.kernel.org, LAKML
Hi,
This patch adds support for PCI to AArch64. It is based on my v3 patch
that adds support for creating generic host bridge structure from
device tree. With that in place, I was able to boot a platform that
has PCIe host bridge support and use a PCIe network card.
Changes from v2:
- Implement an arch specific version of pci_register_io_range() and
pci_address_to_pio().
- Return 1 from pci_proc_domain().
Changes from v1:
- Added Catalin's patch for moving the PCI_IO_BASE location and extend
its size to 16MB
- Integrated Arnd's version of pci_ioremap_io that uses a bitmap for
keeping track of assigned IO space and returns an io_offset. At the
moment the code is added in arch/arm64 but it can be moved in drivers/pci.
- Added a fix for the generic ioport_map() function when !CONFIG_GENERIC_IOMAP
as suggested by Arnd.
The API used is different from the one used by ARM architecture. There is
no pci_common_init_dev() function and no hw_pci structure, as that is no
longer needed. Once the last signature is added to the legal agreement, I
will post the host bridge driver code that I am using. Meanwhile, here
is an example of what the probe function looks like, posted as an example:
static int myhostbridge_probe(struct platform_device *pdev)
{
int err;
struct device_node *dev;
struct pci_host_bridge *bridge;
struct myhostbridge_port *pp;
resource_size_t lastbus;
dev = pdev->dev.of_node;
if (!of_device_is_available(dev)) {
pr_warn("%s: disabled\n", dev->full_name);
return -ENODEV;
}
pp = kzalloc(sizeof(struct myhostbridge_port), GFP_KERNEL);
if (!pp)
return -ENOMEM;
bridge = of_create_pci_host_bridge(&pdev->dev, &myhostbridge_ops, pp);
if (!bridge) {
err = -EINVAL;
goto bridge_init_fail;
}
err = myhostbridge_setup(bridge->bus);
if (err)
goto bridge_init_fail;
/* We always enable PCI domains and we keep domain 0 backward
* compatible in /proc for video cards
*/
pci_add_flags(PCI_ENABLE_PROC_DOMAINS | PCI_COMPAT_DOMAIN_0);
pci_add_flags(PCI_REASSIGN_ALL_BUS | PCI_REASSIGN_ALL_RSRC);
lastbus = pci_scan_child_bus(bridge->bus);
pci_bus_update_busn_res_end(bridge->bus, lastbus);
pci_assign_unassigned_bus_resources(bridge->bus);
pci_bus_add_devices(bridge->bus);
return 0;
bridge_init_fail:
kfree(pp);
return err;
}
Best regards,
Liviu
Catalin Marinas (1):
arm64: Extend the PCI I/O space to 16MB
Liviu Dudau (2):
Fix ioport_map() for !CONFIG_GENERIC_IOMAP cases.
arm64: Add architecture support for PCI
Documentation/arm64/memory.txt | 16 ++--
arch/arm64/Kconfig | 19 ++++-
arch/arm64/include/asm/Kbuild | 1 +
arch/arm64/include/asm/io.h | 5 +-
arch/arm64/include/asm/pci.h | 47 +++++++++++
arch/arm64/kernel/Makefile | 1 +
arch/arm64/kernel/pci.c | 178 +++++++++++++++++++++++++++++++++++++++++
include/asm-generic/io.h | 2 +-
8 files changed, 259 insertions(+), 10 deletions(-)
create mode 100644 arch/arm64/include/asm/pci.h
create mode 100644 arch/arm64/kernel/pci.c
--
1.9.0
^ permalink raw reply
* [PATCH v3 1/3] Fix ioport_map() for !CONFIG_GENERIC_IOMAP cases.
From: Liviu Dudau @ 2014-02-28 13:08 UTC (permalink / raw)
To: linux-pci, Bjorn Helgaas, Catalin Marinas, Will Deacon,
linaro-kernel
Cc: Benjamin Herrenschmidt, LKML, devicetree@vger.kernel.org, LAKML
In-Reply-To: <1393592913-24796-1-git-send-email-Liviu.Dudau@arm.com>
The inline version of ioport_map() that gets used when !CONFIG_GENERIC_IOMAP
is wrong. It returns a mapped (i.e. virtual) address that can start from
zero and completely ignores the PCI_IOBASE and IO_SPACE_LIMIT that most
architectures that use !CONFIG_GENERIC_MAP define.
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h
index d5afe96..df72051 100644
--- a/include/asm-generic/io.h
+++ b/include/asm-generic/io.h
@@ -331,7 +331,7 @@ static inline void iounmap(void __iomem *addr)
#ifndef CONFIG_GENERIC_IOMAP
static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
{
- return (void __iomem *) port;
+ return (void __iomem *)(PCI_IOBASE + (port & IO_SPACE_LIMIT));
}
static inline void ioport_unmap(void __iomem *p)
--
1.9.0
^ permalink raw reply related
* [PATCH v3 2/3] arm64: Extend the PCI I/O space to 16MB
From: Liviu Dudau @ 2014-02-28 13:08 UTC (permalink / raw)
To: linux-pci, Bjorn Helgaas, Catalin Marinas, Will Deacon,
linaro-kernel
Cc: Benjamin Herrenschmidt, LKML, devicetree@vger.kernel.org, LAKML
In-Reply-To: <1393592913-24796-1-git-send-email-Liviu.Dudau@arm.com>
From: Catalin Marinas <catalin.marinas@arm.com>
The patch moves the PCI I/O space (currently at 64K) before the
earlyprintk mapping and extends it to 16MB.
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
diff --git a/Documentation/arm64/memory.txt b/Documentation/arm64/memory.txt
index 5e054bf..85e24c4 100644
--- a/Documentation/arm64/memory.txt
+++ b/Documentation/arm64/memory.txt
@@ -35,11 +35,13 @@ ffffffbc00000000 ffffffbdffffffff 8GB vmemmap
ffffffbe00000000 ffffffbffbbfffff ~8GB [guard, future vmmemap]
-ffffffbffbc00000 ffffffbffbdfffff 2MB earlyprintk device
+ffffffbffa000000 ffffffbffaffffff 16MB PCI I/O space
+
+ffffffbffb000000 ffffffbffbbfffff 12MB [guard]
-ffffffbffbe00000 ffffffbffbe0ffff 64KB PCI I/O space
+ffffffbffbc00000 ffffffbffbdfffff 2MB earlyprintk device
-ffffffbffbe10000 ffffffbcffffffff ~2MB [guard]
+ffffffbffbe00000 ffffffbffbffffff 2MB [guard]
ffffffbffc000000 ffffffbfffffffff 64MB modules
@@ -60,11 +62,13 @@ fffffdfc00000000 fffffdfdffffffff 8GB vmemmap
fffffdfe00000000 fffffdfffbbfffff ~8GB [guard, future vmmemap]
-fffffdfffbc00000 fffffdfffbdfffff 2MB earlyprintk device
+fffffdfffa000000 fffffdfffaffffff 16MB PCI I/O space
+
+fffffdfffb000000 fffffdfffbbfffff 12MB [guard]
-fffffdfffbe00000 fffffdfffbe0ffff 64KB PCI I/O space
+fffffdfffbc00000 fffffdfffbdfffff 2MB earlyprintk device
-fffffdfffbe10000 fffffdfffbffffff ~2MB [guard]
+fffffdfffbe00000 fffffdfffbffffff 2MB [guard]
fffffdfffc000000 fffffdffffffffff 64MB modules
diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 4cc813e..7846a6b 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -121,7 +121,7 @@ static inline u64 __raw_readq(const volatile void __iomem *addr)
* I/O port access primitives.
*/
#define IO_SPACE_LIMIT 0xffff
-#define PCI_IOBASE ((void __iomem *)(MODULES_VADDR - SZ_2M))
+#define PCI_IOBASE ((void __iomem *)(MODULES_VADDR - SZ_32M))
static inline u8 inb(unsigned long addr)
{
--
1.9.0
^ permalink raw reply related
* [PATCH v3 3/3] arm64: Add architecture support for PCI
From: Liviu Dudau @ 2014-02-28 13:08 UTC (permalink / raw)
To: linux-pci, Bjorn Helgaas, Catalin Marinas, Will Deacon,
linaro-kernel
Cc: Benjamin Herrenschmidt, LKML, devicetree@vger.kernel.org, LAKML
In-Reply-To: <1393592913-24796-1-git-send-email-Liviu.Dudau@arm.com>
Use the generic host bridge functions to provide support for
PCI Express on arm64. There is no support for ISA memory.
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
create mode 100644 arch/arm64/include/asm/pci.h
create mode 100644 arch/arm64/kernel/pci.c
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 27bbcfc..d1c8568 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -62,7 +62,7 @@ config MMU
def_bool y
config NO_IOPORT
- def_bool y
+ def_bool y if !PCI
config STACKTRACE_SUPPORT
def_bool y
@@ -134,6 +134,23 @@ menu "Bus support"
config ARM_AMBA
bool
+config PCI
+ bool "PCI support"
+ help
+ This feature enables support for PCIe bus system. If you say Y
+ here, the kernel will include drivers and infrastructure code
+ to support PCIe bus devices.
+
+config PCI_DOMAINS
+ def_bool PCI
+
+config PCI_SYSCALL
+ def_bool PCI
+
+source "drivers/pci/Kconfig"
+source "drivers/pci/pcie/Kconfig"
+source "drivers/pci/hotplug/Kconfig"
+
endmenu
menu "Kernel Features"
diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild
index 71c53ec..46924bc 100644
--- a/arch/arm64/include/asm/Kbuild
+++ b/arch/arm64/include/asm/Kbuild
@@ -26,6 +26,7 @@ generic-y += mman.h
generic-y += msgbuf.h
generic-y += mutex.h
generic-y += pci.h
+generic-y += pci-bridge.h
generic-y += poll.h
generic-y += posix_types.h
generic-y += resource.h
diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 7846a6b..67463a5 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -120,7 +120,8 @@ static inline u64 __raw_readq(const volatile void __iomem *addr)
/*
* I/O port access primitives.
*/
-#define IO_SPACE_LIMIT 0xffff
+#define arch_has_dev_port() (1)
+#define IO_SPACE_LIMIT 0x1ffffff
#define PCI_IOBASE ((void __iomem *)(MODULES_VADDR - SZ_32M))
static inline u8 inb(unsigned long addr)
diff --git a/arch/arm64/include/asm/pci.h b/arch/arm64/include/asm/pci.h
new file mode 100644
index 0000000..6ed4092
--- /dev/null
+++ b/arch/arm64/include/asm/pci.h
@@ -0,0 +1,47 @@
+#ifndef __ASM_PCI_H
+#define __ASM_PCI_H
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/io.h>
+#include <asm-generic/pci-bridge.h>
+#include <asm-generic/pci-dma-compat.h>
+
+#define PCIBIOS_MIN_IO 0x1000
+#define PCIBIOS_MIN_MEM 0
+
+/*
+ * Set to 1 if the kernel should re-assign all PCI bus numbers
+ */
+#define pcibios_assign_all_busses() \
+ (pci_has_flag(PCI_REASSIGN_ALL_BUS))
+
+/*
+ * PCI address space differs from physical memory address space
+ */
+#define PCI_DMA_BUS_IS_PHYS (0)
+
+extern int isa_dma_bridge_buggy;
+
+static inline int pci_domain_nr(struct pci_bus *bus)
+{
+ struct pci_host_bridge *bridge = to_pci_host_bridge(bus->bridge);
+
+ if (bridge)
+ return bridge->domain_nr;
+
+ return 0;
+}
+
+static inline int pci_proc_domain(struct pci_bus *bus)
+{
+ return 1;
+}
+
+extern unsigned long pci_ioremap_io(const struct resource *res, phys_addr_t phys_addr);
+
+#endif /* __KERNEL__ */
+#endif /* __ASM_PCI_H */
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 2d4554b..64fc479 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -20,6 +20,7 @@ arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)+= hw_breakpoint.o
arm64-obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND) += sleep.o suspend.o
arm64-obj-$(CONFIG_JUMP_LABEL) += jump_label.o
+arm64-obj-$(CONFIG_PCI) += pci.o
obj-y += $(arm64-obj-y) vdso/
obj-m += $(arm64-obj-m)
diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
new file mode 100644
index 0000000..f00471d
--- /dev/null
+++ b/arch/arm64/kernel/pci.c
@@ -0,0 +1,178 @@
+/*
+ * Code borrowed from powerpc/kernel/pci-common.c
+ *
+ * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
+ * Copyright (C) 2014 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/of_pci.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+
+#include <asm/pci-bridge.h>
+
+struct ioresource {
+ struct list_head list;
+ phys_addr_t start;
+ resource_size_t size;
+};
+
+static LIST_HEAD(io_list);
+
+int pci_register_io_range(phys_addr_t address, resource_size_t size)
+{
+ struct ioresource *res;
+ resource_size_t allocated_size = 0;
+
+ /* find if the range has not been already allocated */
+ list_for_each_entry(res, &io_list, list) {
+ if (address >= res->start &&
+ address + size <= res->start + size)
+ return 0;
+ allocated_size += res->size;
+ }
+
+ /* range not already registered, check for space */
+ if (allocated_size + size > IO_SPACE_LIMIT)
+ return -E2BIG;
+
+ /* add the range in the list */
+ res = kzalloc(sizeof(*res), GFP_KERNEL);
+ if (!res)
+ return -ENOMEM;
+ res->start = address;
+ res->size = size;
+
+ list_add_tail(&res->list, &io_list);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(pci_register_io_range);
+
+unsigned long pci_address_to_pio(phys_addr_t address)
+{
+ struct ioresource *res;
+
+ list_for_each_entry(res, &io_list, list) {
+ if (address >= res->start &&
+ address < res->start + res->size) {
+ return res->start - address;
+ }
+ }
+
+ return (unsigned long)-1;
+}
+EXPORT_SYMBOL_GPL(pci_address_to_pio);
+
+/*
+ * Called after each bus is probed, but before its children are examined
+ */
+void pcibios_fixup_bus(struct pci_bus *bus)
+{
+ struct pci_dev *dev;
+ struct resource *res;
+ int i;
+
+ if (!pci_is_root_bus(bus)) {
+ pci_read_bridge_bases(bus);
+
+ pci_bus_for_each_resource(bus, res, i) {
+ if (!res || !res->flags || res->parent)
+ continue;
+
+ /*
+ * If we are going to reassign everything, we can
+ * shrink the P2P resource to have zero size to
+ * save space
+ */
+ if (pci_has_flag(PCI_REASSIGN_ALL_RSRC)) {
+ res->flags |= IORESOURCE_UNSET;
+ res->start = 0;
+ res->end = -1;
+ continue;
+ }
+ }
+ }
+
+ list_for_each_entry(dev, &bus->devices, bus_list) {
+ /* Ignore fully discovered devices */
+ if (dev->is_added)
+ continue;
+
+ set_dev_node(&dev->dev, pcibus_to_node(dev->bus));
+
+ /* Read default IRQs and fixup if necessary */
+ dev->irq = of_irq_parse_and_map_pci(dev, 0, 0);
+ }
+}
+EXPORT_SYMBOL(pcibios_fixup_bus);
+
+/*
+ * We don't have to worry about legacy ISA devices, so nothing to do here
+ */
+resource_size_t pcibios_align_resource(void *data, const struct resource *res,
+ resource_size_t size, resource_size_t align)
+{
+ return ALIGN(res->start, align);
+}
+EXPORT_SYMBOL(pcibios_align_resource);
+
+int pcibios_enable_device(struct pci_dev *dev, int mask)
+{
+ return pci_enable_resources(dev, mask);
+}
+
+void pcibios_fixup_bridge_ranges(struct list_head *resources)
+{
+}
+
+#define IO_SPACE_PAGES ((IO_SPACE_LIMIT + 1) / PAGE_SIZE)
+static DECLARE_BITMAP(pci_iospace, IO_SPACE_PAGES);
+
+unsigned long pci_ioremap_io(const struct resource *res, phys_addr_t phys_addr)
+{
+ unsigned long start, len, virt_start;
+ int err;
+
+ if (res->end > IO_SPACE_LIMIT)
+ return -EINVAL;
+
+ /*
+ * try finding free space for the whole size first,
+ * fall back to 64K if not available
+ */
+ len = resource_size(res);
+ start = bitmap_find_next_zero_area(pci_iospace, IO_SPACE_PAGES,
+ res->start / PAGE_SIZE, len / PAGE_SIZE, 0);
+ if (start == IO_SPACE_PAGES && len > SZ_64K) {
+ len = SZ_64K;
+ start = 0;
+ start = bitmap_find_next_zero_area(pci_iospace, IO_SPACE_PAGES,
+ start, len / PAGE_SIZE, 0);
+ }
+
+ /* no 64K area found */
+ if (start == IO_SPACE_PAGES)
+ return -ENOMEM;
+
+ /* ioremap physical aperture to virtual aperture */
+ virt_start = start * PAGE_SIZE + (unsigned long)PCI_IOBASE;
+ err = ioremap_page_range(virt_start, virt_start + len,
+ phys_addr, __pgprot(PROT_DEVICE_nGnRE));
+ if (err)
+ return err;
+
+ bitmap_set(pci_iospace, start, len / PAGE_SIZE);
+
+ /* return io_offset */
+ return start * PAGE_SIZE - res->start;
+}
--
1.9.0
^ permalink raw reply related
* Re: [PATCH 0/9] Doc/DT: DT bindings for various display components
From: Tomi Valkeinen @ 2014-02-28 13:14 UTC (permalink / raw)
To: Sebastian Hesselbarth, linux-fbdev, dri-devel, devicetree,
linux-arm-kernel
Cc: Russell King - ARM Linux, Sascha Hauer, Tomasz Figa, Inki Dae,
Andrzej Hajda, Rob Clark, Thierry Reding, Laurent Pinchart,
Philipp Zabel
In-Reply-To: <531087C0.1090501@gmail.com>
[-- Attachment #1.1: Type: text/plain, Size: 2116 bytes --]
On 28/02/14 14:57, Sebastian Hesselbarth wrote:
> Out of curiosity, will there be DT nodes for pull-up resistors soon,
> too? ;)
If they don't work automatically, yes, we need DT nodes and drivers for
them.
> Honestly, TPD12S015 is a level shifter, there is nothing in it that
> would justify a DT node nor a driver.
TPD requires a power. Who turns that on? It also has two GPIOs, LS_OE
and CT_CP_HPD, which need to be controlled based on what the user wants
and the state of the HPD line. Who controls those?
> Above you already note, that connector nodes should offer HPD in the
> future, but I guess the binding should represent that now already.
I think it can be added when somebody uses it. I don't see why that
would cause trouble later to those that don't use it.
> I will be a DT stub anyway, the corresponding video sink driver will
> have to look it up.
I'm not sure what you mean with that. Yes, it's not the most complex DT
nodes out there.
> Looking through the bindings for DVI and HDMI, I guess HPD gpio is
> better kept in those nodes. From the relevant (DT) properties DVI and
> HDMI connectors are in no way different.
Well, I think the HPD gpio should be where it's most logical to have it.
I mean, you could have a setup where you have the SoC HDMI encoder and
and the HDMI connector, and the HPD pin goes directly to the HDMI
encoder, which has HW support for it. In that case, the HDMI encoder
node should contain the HPD, and the HDMI encoder should handle it.
Or, your HDMI encoder could not have any kind of support for HPD. In
that case you could have the HDMI connector driver handle the hotplug
event. You could of course make the HDMI encoder driver handle the HPD
gpio, but I usually try to have the driver handle the hardware device in
question.
In OMAP's case, we have the TPD chip between the HDMI encoder and the
connector, and the logical place to handle HPD GPIO in that case is the
TPD driver, as that's where the HPD is connected to and the TPD needs to
be configured according to the state of the HPD.
Tomi
[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 901 bytes --]
[-- Attachment #2: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v4] can: xilinx CAN controller support.
From: Marc Kleine-Budde @ 2014-02-28 13:15 UTC (permalink / raw)
To: Appana Durga Kedareswara Rao, wg@grandegger.com, Michal Simek,
grant.likely@linaro.org, robh+dt@kernel.org,
linux-can@vger.kernel.org
Cc: netdev@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, devicetree@vger.kernel.org
In-Reply-To: <4902b8d8-139a-4fd0-9e6e-a30ce7e6683b@CH1EHSMHS019.ehs.local>
[-- Attachment #1: Type: text/plain, Size: 1989 bytes --]
On 02/28/2014 02:07 PM, Appana Durga Kedareswara Rao wrote:
>>>> What happens if the interrupt handler is delayed? For example in a RT
>>>> enabled system the interrupt handler runs as a thread. There might be
>>>> other threads with higher priority. The hardware will probably send
>>>> all CAN frames in the FIFO, so you want to reduce the overhead and
>>>> loop in the tx complete handler.
>>>>
>>> Yes I agree with your comment.
>>> It will be good to have a loop in the Tx interrupt handler I am
>>> modifying the Tx interrupt handler like below.
>>>
>>> static void xcan_tx_interrupt(struct net_device *ndev, u32 isr) {
>>> struct xcan_priv *priv = netdev_priv(ndev);
>>> struct net_device_stats *stats = &ndev->stats;
>>>
>>> while (priv->tx_head - priv->tx_tail > 0) {
>>> if (!(isr & XCAN_IXR_TXOK_MASK)) {
>>> break;
>>> }
>>> can_get_echo_skb(ndev, priv->tx_tail %
>>> priv->xcan_echo_skb_max_tx);
>>> priv->tx_tail++;
>>> stats->tx_packets++;
>>> can_led_event(ndev, CAN_LED_EVENT_TX);
Probably first clear the interrupt, because you've just handled it, then
check if it's still present. The question is, do you have to clear the
IRQ for each transmitted frame, or does one clean of the interrupt clear
the bit for more then one transmitted frame?
>>> isr = priv->read_reg(priv, XCAN_ISR_OFFSET);
> --> clear Tx OK interrupt.
>
>>> }
>>> netif_wake_queue(ndev);
>>> }
>>>
>>> Are you Ok with this?
Were getting there :)
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 242 bytes --]
^ permalink raw reply
* RE: [PATCH v4] can: xilinx CAN controller support.
From: Appana Durga Kedareswara Rao @ 2014-02-28 13:27 UTC (permalink / raw)
To: Marc Kleine-Budde, wg-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org,
Michal Simek,
grant.likely-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
linux-can-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <53108BEF.1020308-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
Hi Marc,
> -----Original Message-----
> From: Marc Kleine-Budde [mailto:mkl@pengutronix.de]
> Sent: Friday, February 28, 2014 6:45 PM
> To: Appana Durga Kedareswara Rao; wg@grandegger.com; Michal Simek;
> grant.likely@linaro.org; robh+dt@kernel.org; linux-can@vger.kernel.org
> Cc: netdev@vger.kernel.org; linux-arm-kernel@lists.infradead.org; linux-
> kernel@vger.kernel.org; devicetree@vger.kernel.org
> Subject: Re: [PATCH v4] can: xilinx CAN controller support.
>
> On 02/28/2014 02:07 PM, Appana Durga Kedareswara Rao wrote:
> >>>> What happens if the interrupt handler is delayed? For example in a
> >>>> RT enabled system the interrupt handler runs as a thread. There
> >>>> might be other threads with higher priority. The hardware will
> >>>> probably send all CAN frames in the FIFO, so you want to reduce the
> >>>> overhead and loop in the tx complete handler.
> >>>>
> >>> Yes I agree with your comment.
> >>> It will be good to have a loop in the Tx interrupt handler I am
> >>> modifying the Tx interrupt handler like below.
> >>>
> >>> static void xcan_tx_interrupt(struct net_device *ndev, u32 isr) {
> >>> struct xcan_priv *priv = netdev_priv(ndev);
> >>> struct net_device_stats *stats = &ndev->stats;
> >>>
> >>> while (priv->tx_head - priv->tx_tail > 0) {
> >>> if (!(isr & XCAN_IXR_TXOK_MASK)) {
> >>> break;
> >>> }
> >>> can_get_echo_skb(ndev, priv->tx_tail %
> >>> priv->xcan_echo_skb_max_tx);
> >>> priv->tx_tail++;
> >>> stats->tx_packets++;
> >>> can_led_event(ndev, CAN_LED_EVENT_TX);
>
> Probably first clear the interrupt, because you've just handled it, then check
> if it's still present. The question is, do you have to clear the IRQ for each
> transmitted frame, or does one clean of the interrupt clear the bit for more
> then one transmitted frame?
>
We already were clearing it in the interrupt routine (xcan_interrupt). That's why clearing it at the end of the loop.
We have to clear the IRQ (TXOK) for each transmitted frame.
Regards,
Kedar.
> >>> isr = priv->read_reg(priv, XCAN_ISR_OFFSET);
> > --> clear Tx OK interrupt.
>
> >
> >>> }
> >>> netif_wake_queue(ndev);
> >>> }
> >>>
> >>> Are you Ok with this?
>
> Were getting there :)
>
> Marc
> --
> Pengutronix e.K. | Marc Kleine-Budde |
> Industrial Linux Solutions | Phone: +49-231-2826-924 |
> Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
> Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox