* [PATCH v6 net-next 17/17] net: qualcomm: add QCA7000 UART driver
From: Stefan Wahren @ 2017-05-23 13:12 UTC (permalink / raw)
To: Rob Herring, Mark Rutland, David S. Miller
Cc: Greg Kroah-Hartman, Jiri Slaby, Lino Sanfilippo, Jakub Kicinski,
devicetree-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
linux-serial-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Stefan Wahren
In-Reply-To: <1495545173-22150-1-git-send-email-stefan.wahren-eS4NqCHxEME@public.gmane.org>
This patch adds the Ethernet over UART driver for the
Qualcomm QCA7000 HomePlug GreenPHY.
Signed-off-by: Stefan Wahren <stefan.wahren-eS4NqCHxEME@public.gmane.org>
---
drivers/net/ethernet/qualcomm/Kconfig | 16 +
drivers/net/ethernet/qualcomm/Makefile | 2 +
drivers/net/ethernet/qualcomm/qca_7k_common.h | 6 +
drivers/net/ethernet/qualcomm/qca_uart.c | 423 ++++++++++++++++++++++++++
4 files changed, 447 insertions(+)
create mode 100644 drivers/net/ethernet/qualcomm/qca_uart.c
diff --git a/drivers/net/ethernet/qualcomm/Kconfig b/drivers/net/ethernet/qualcomm/Kconfig
index b4c369d..877675a 100644
--- a/drivers/net/ethernet/qualcomm/Kconfig
+++ b/drivers/net/ethernet/qualcomm/Kconfig
@@ -30,6 +30,22 @@ config QCA7000_SPI
To compile this driver as a module, choose M here. The module
will be called qcaspi.
+config QCA7000_UART
+ tristate "Qualcomm Atheros QCA7000 UART support"
+ select QCA7000
+ depends on SERIAL_DEV_BUS && OF
+ ---help---
+ This UART protocol driver supports the Qualcomm Atheros QCA7000.
+
+ Currently the driver assumes these device UART settings:
+ Data bits: 8
+ Parity: None
+ Stop bits: 1
+ Flow control: None
+
+ To compile this driver as a module, choose M here. The module
+ will be called qcauart.
+
config QCOM_EMAC
tristate "Qualcomm Technologies, Inc. EMAC Gigabit Ethernet support"
depends on HAS_DMA && HAS_IOMEM
diff --git a/drivers/net/ethernet/qualcomm/Makefile b/drivers/net/ethernet/qualcomm/Makefile
index 65556ca..92fa7c4 100644
--- a/drivers/net/ethernet/qualcomm/Makefile
+++ b/drivers/net/ethernet/qualcomm/Makefile
@@ -5,5 +5,7 @@
obj-$(CONFIG_QCA7000) += qca_7k_common.o
obj-$(CONFIG_QCA7000_SPI) += qcaspi.o
qcaspi-objs := qca_7k.o qca_debug.o qca_spi.o
+obj-$(CONFIG_QCA7000_UART) += qcauart.o
+qcauart-objs := qca_uart.o
obj-y += emac/
diff --git a/drivers/net/ethernet/qualcomm/qca_7k_common.h b/drivers/net/ethernet/qualcomm/qca_7k_common.h
index 07bdd6c..928554f 100644
--- a/drivers/net/ethernet/qualcomm/qca_7k_common.h
+++ b/drivers/net/ethernet/qualcomm/qca_7k_common.h
@@ -122,6 +122,12 @@ static inline void qcafrm_fsm_init_spi(struct qcafrm_handle *handle)
handle->state = handle->init;
}
+static inline void qcafrm_fsm_init_uart(struct qcafrm_handle *handle)
+{
+ handle->init = QCAFRM_WAIT_AA1;
+ handle->state = handle->init;
+}
+
/* Gather received bytes and try to extract a full Ethernet frame
* by following a simple state machine.
*
diff --git a/drivers/net/ethernet/qualcomm/qca_uart.c b/drivers/net/ethernet/qualcomm/qca_uart.c
new file mode 100644
index 0000000..43d91ba
--- /dev/null
+++ b/drivers/net/ethernet/qualcomm/qca_uart.c
@@ -0,0 +1,423 @@
+/*
+ * Copyright (c) 2011, 2012, Qualcomm Atheros Communications Inc.
+ * Copyright (c) 2017, I2SE GmbH
+ *
+ * Permission to use, copy, modify, and/or distribute this software
+ * for any purpose with or without fee is hereby granted, provided
+ * that the above copyright notice and this permission notice appear
+ * in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* This module implements the Qualcomm Atheros UART protocol for
+ * kernel-based UART device; it is essentially an Ethernet-to-UART
+ * serial converter;
+ */
+
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/etherdevice.h>
+#include <linux/if_arp.h>
+#include <linux/if_ether.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_net.h>
+#include <linux/sched.h>
+#include <linux/serdev.h>
+#include <linux/skbuff.h>
+#include <linux/types.h>
+
+#include "qca_7k_common.h"
+
+#define QCAUART_DRV_VERSION "0.1.0"
+#define QCAUART_DRV_NAME "qcauart"
+#define QCAUART_TX_TIMEOUT (1 * HZ)
+
+struct qcauart {
+ struct net_device *net_dev;
+ spinlock_t lock; /* transmit lock */
+ struct work_struct tx_work; /* Flushes transmit buffer */
+
+ struct serdev_device *serdev;
+ struct qcafrm_handle frm_handle;
+ struct sk_buff *rx_skb;
+
+ unsigned char *tx_head; /* pointer to next XMIT byte */
+ int tx_left; /* bytes left in XMIT queue */
+ unsigned char *tx_buffer;
+};
+
+static int
+qca_tty_receive(struct serdev_device *serdev, const unsigned char *data,
+ size_t count)
+{
+ struct qcauart *qca = serdev_device_get_drvdata(serdev);
+ struct net_device *netdev = qca->net_dev;
+ struct net_device_stats *n_stats = &netdev->stats;
+ size_t i;
+
+ if (!qca->rx_skb) {
+ qca->rx_skb = netdev_alloc_skb_ip_align(netdev,
+ netdev->mtu +
+ VLAN_ETH_HLEN);
+ if (!qca->rx_skb) {
+ n_stats->rx_errors++;
+ n_stats->rx_dropped++;
+ return 0;
+ }
+ }
+
+ for (i = 0; i < count; i++) {
+ s32 retcode;
+
+ retcode = qcafrm_fsm_decode(&qca->frm_handle,
+ qca->rx_skb->data,
+ skb_tailroom(qca->rx_skb),
+ data[i]);
+
+ switch (retcode) {
+ case QCAFRM_GATHER:
+ case QCAFRM_NOHEAD:
+ break;
+ case QCAFRM_NOTAIL:
+ netdev_dbg(netdev, "recv: no RX tail\n");
+ n_stats->rx_errors++;
+ n_stats->rx_dropped++;
+ break;
+ case QCAFRM_INVLEN:
+ netdev_dbg(netdev, "recv: invalid RX length\n");
+ n_stats->rx_errors++;
+ n_stats->rx_dropped++;
+ break;
+ default:
+ n_stats->rx_packets++;
+ n_stats->rx_bytes += retcode;
+ skb_put(qca->rx_skb, retcode);
+ qca->rx_skb->protocol = eth_type_trans(
+ qca->rx_skb, qca->rx_skb->dev);
+ qca->rx_skb->ip_summed = CHECKSUM_UNNECESSARY;
+ netif_rx_ni(qca->rx_skb);
+ qca->rx_skb = netdev_alloc_skb_ip_align(netdev,
+ netdev->mtu +
+ VLAN_ETH_HLEN);
+ if (!qca->rx_skb) {
+ netdev_dbg(netdev, "recv: out of RX resources\n");
+ n_stats->rx_errors++;
+ return i;
+ }
+ }
+ }
+
+ return i;
+}
+
+/* Write out any remaining transmit buffer. Scheduled when tty is writable */
+static void qcauart_transmit(struct work_struct *work)
+{
+ struct qcauart *qca = container_of(work, struct qcauart, tx_work);
+ struct net_device_stats *n_stats = &qca->net_dev->stats;
+ int written;
+
+ spin_lock_bh(&qca->lock);
+
+ /* First make sure we're connected. */
+ if (!netif_running(qca->net_dev)) {
+ spin_unlock_bh(&qca->lock);
+ return;
+ }
+
+ if (qca->tx_left <= 0) {
+ /* Now serial buffer is almost free & we can start
+ * transmission of another packet
+ */
+ n_stats->tx_packets++;
+ spin_unlock_bh(&qca->lock);
+ netif_wake_queue(qca->net_dev);
+ return;
+ }
+
+ written = serdev_device_write_buf(qca->serdev, qca->tx_head,
+ qca->tx_left);
+ if (written > 0) {
+ qca->tx_left -= written;
+ qca->tx_head += written;
+ }
+ spin_unlock_bh(&qca->lock);
+}
+
+/* Called by the driver when there's room for more data.
+ * Schedule the transmit.
+ */
+static void qca_tty_wakeup(struct serdev_device *serdev)
+{
+ struct qcauart *qca = serdev_device_get_drvdata(serdev);
+
+ schedule_work(&qca->tx_work);
+}
+
+static struct serdev_device_ops qca_serdev_ops = {
+ .receive_buf = qca_tty_receive,
+ .write_wakeup = qca_tty_wakeup,
+};
+
+static int qcauart_netdev_open(struct net_device *dev)
+{
+ struct qcauart *qca = netdev_priv(dev);
+
+ netif_start_queue(qca->net_dev);
+
+ return 0;
+}
+
+static int qcauart_netdev_close(struct net_device *dev)
+{
+ struct qcauart *qca = netdev_priv(dev);
+
+ netif_stop_queue(dev);
+ flush_work(&qca->tx_work);
+
+ spin_lock_bh(&qca->lock);
+ qca->tx_left = 0;
+ spin_unlock_bh(&qca->lock);
+
+ return 0;
+}
+
+static netdev_tx_t
+qcauart_netdev_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct net_device_stats *n_stats = &dev->stats;
+ struct qcauart *qca = netdev_priv(dev);
+ u8 pad_len = 0;
+ int written;
+ u8 *pos;
+
+ spin_lock(&qca->lock);
+
+ WARN_ON(qca->tx_left);
+
+ if (!netif_running(dev)) {
+ spin_unlock(&qca->lock);
+ netdev_warn(qca->net_dev, "xmit: iface is down\n");
+ goto out;
+ }
+
+ pos = qca->tx_buffer;
+
+ if (skb->len < QCAFRM_MIN_LEN)
+ pad_len = QCAFRM_MIN_LEN - skb->len;
+
+ pos += qcafrm_create_header(pos, skb->len + pad_len);
+
+ memcpy(pos, skb->data, skb->len);
+ pos += skb->len;
+
+ if (pad_len) {
+ memset(pos, 0, pad_len);
+ pos += pad_len;
+ }
+
+ pos += qcafrm_create_footer(pos);
+
+ netif_stop_queue(qca->net_dev);
+
+ written = serdev_device_write_buf(qca->serdev, qca->tx_buffer,
+ pos - qca->tx_buffer);
+ if (written > 0) {
+ qca->tx_left = (pos - qca->tx_buffer) - written;
+ qca->tx_head = qca->tx_buffer + written;
+ n_stats->tx_bytes += written;
+ }
+ spin_unlock(&qca->lock);
+
+ netif_trans_update(dev);
+out:
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+}
+
+static void qcauart_netdev_tx_timeout(struct net_device *dev)
+{
+ struct qcauart *qca = netdev_priv(dev);
+
+ netdev_info(qca->net_dev, "Transmit timeout at %ld, latency %ld\n",
+ jiffies, dev_trans_start(dev));
+ dev->stats.tx_errors++;
+ dev->stats.tx_dropped++;
+}
+
+static int qcauart_netdev_init(struct net_device *dev)
+{
+ struct qcauart *qca = netdev_priv(dev);
+ size_t len;
+
+ /* Finish setting up the device info. */
+ dev->mtu = QCAFRM_MAX_MTU;
+ dev->type = ARPHRD_ETHER;
+
+ len = QCAFRM_HEADER_LEN + QCAFRM_MAX_LEN + QCAFRM_FOOTER_LEN;
+ qca->tx_buffer = devm_kmalloc(&qca->serdev->dev, len, GFP_KERNEL);
+ if (!qca->tx_buffer)
+ return -ENOMEM;
+
+ qca->rx_skb = netdev_alloc_skb_ip_align(qca->net_dev,
+ qca->net_dev->mtu +
+ VLAN_ETH_HLEN);
+ if (!qca->rx_skb)
+ return -ENOBUFS;
+
+ return 0;
+}
+
+static void qcauart_netdev_uninit(struct net_device *dev)
+{
+ struct qcauart *qca = netdev_priv(dev);
+
+ if (qca->rx_skb)
+ dev_kfree_skb(qca->rx_skb);
+}
+
+static const struct net_device_ops qcauart_netdev_ops = {
+ .ndo_init = qcauart_netdev_init,
+ .ndo_uninit = qcauart_netdev_uninit,
+ .ndo_open = qcauart_netdev_open,
+ .ndo_stop = qcauart_netdev_close,
+ .ndo_start_xmit = qcauart_netdev_xmit,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_tx_timeout = qcauart_netdev_tx_timeout,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
+static void qcauart_netdev_setup(struct net_device *dev)
+{
+ dev->netdev_ops = &qcauart_netdev_ops;
+ dev->watchdog_timeo = QCAUART_TX_TIMEOUT;
+ dev->priv_flags &= ~IFF_TX_SKB_SHARING;
+ dev->tx_queue_len = 100;
+
+ /* MTU range: 46 - 1500 */
+ dev->min_mtu = QCAFRM_MIN_MTU;
+ dev->max_mtu = QCAFRM_MAX_MTU;
+}
+
+static const struct of_device_id qca_uart_of_match[] = {
+ {
+ .compatible = "qca,qca7000",
+ },
+ {}
+};
+MODULE_DEVICE_TABLE(of, qca_uart_of_match);
+
+static int qca_uart_probe(struct serdev_device *serdev)
+{
+ struct net_device *qcauart_dev = alloc_etherdev(sizeof(struct qcauart));
+ struct qcauart *qca;
+ const char *mac;
+ u32 speed = 115200;
+ int ret;
+
+ if (!qcauart_dev)
+ return -ENOMEM;
+
+ qcauart_netdev_setup(qcauart_dev);
+ SET_NETDEV_DEV(qcauart_dev, &serdev->dev);
+
+ qca = netdev_priv(qcauart_dev);
+ if (!qca) {
+ pr_err("qca_uart: Fail to retrieve private structure\n");
+ ret = -ENOMEM;
+ goto free;
+ }
+ qca->net_dev = qcauart_dev;
+ qca->serdev = serdev;
+ qcafrm_fsm_init_uart(&qca->frm_handle);
+
+ spin_lock_init(&qca->lock);
+ INIT_WORK(&qca->tx_work, qcauart_transmit);
+
+ of_property_read_u32(serdev->dev.of_node, "current-speed", &speed);
+
+ mac = of_get_mac_address(serdev->dev.of_node);
+
+ if (mac)
+ ether_addr_copy(qca->net_dev->dev_addr, mac);
+
+ if (!is_valid_ether_addr(qca->net_dev->dev_addr)) {
+ eth_hw_addr_random(qca->net_dev);
+ dev_info(&serdev->dev, "Using random MAC address: %pM\n",
+ qca->net_dev->dev_addr);
+ }
+
+ netif_carrier_on(qca->net_dev);
+ serdev_device_set_drvdata(serdev, qca);
+ serdev_device_set_client_ops(serdev, &qca_serdev_ops);
+
+ ret = serdev_device_open(serdev);
+ if (ret) {
+ dev_err(&serdev->dev, "Unable to open device %s\n",
+ qcauart_dev->name);
+ goto free;
+ }
+
+ speed = serdev_device_set_baudrate(serdev, speed);
+ dev_info(&serdev->dev, "Using baudrate: %u\n", speed);
+
+ serdev_device_set_flow_control(serdev, false);
+
+ ret = register_netdev(qcauart_dev);
+ if (ret) {
+ dev_err(&serdev->dev, "Unable to register net device %s\n",
+ qcauart_dev->name);
+ serdev_device_close(serdev);
+ goto free;
+ }
+
+ return 0;
+
+free:
+ free_netdev(qcauart_dev);
+ return ret;
+}
+
+static void qca_uart_remove(struct serdev_device *serdev)
+{
+ struct qcauart *qca = serdev_device_get_drvdata(serdev);
+
+ netif_carrier_off(qca->net_dev);
+ cancel_work_sync(&qca->tx_work);
+ unregister_netdev(qca->net_dev);
+
+ /* Flush any pending characters in the driver. */
+ serdev_device_close(serdev);
+
+ free_netdev(qca->net_dev);
+}
+
+static struct serdev_device_driver qca_uart_driver = {
+ .probe = qca_uart_probe,
+ .remove = qca_uart_remove,
+ .driver = {
+ .name = QCAUART_DRV_NAME,
+ .of_match_table = of_match_ptr(qca_uart_of_match),
+ },
+};
+
+module_serdev_device_driver(qca_uart_driver);
+
+MODULE_DESCRIPTION("Qualcomm Atheros QCA7000 UART Driver");
+MODULE_AUTHOR("Qualcomm Atheros Communications");
+MODULE_AUTHOR("Stefan Wahren <stefan.wahren-eS4NqCHxEME@public.gmane.org>");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_VERSION(QCAUART_DRV_VERSION);
--
2.1.4
--
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 V1] serial: imx: revert setup DCEDTE early and ensure DCD and RI irqs to be off
From: Uwe Kleine-König @ 2017-05-23 14:09 UTC (permalink / raw)
To: Steve Twiss
Cc: Greg Kroah-Hartman, Jiri Slaby, LINUX-KERNEL, LINUX-SERIAL,
Lucas Stach, Support Opensource, kernel
In-Reply-To: <20170523123145.E268B3FAD4@swsrvapps-01.diasemi.com>
On Tue, May 23, 2017 at 01:17:26PM +0100, Steve Twiss wrote:
> From: Steve Twiss <stwiss.opensource@diasemi.com>
>
> Revert the commit e61c38d85b7392e ("serial: imx: setup DCEDTE early and
> ensure DCD and RI irqs to be off")
>
> The patch submitted to setup DCEDTE early and ensure DCD and RI irqs to
> be off, causes a serial console display problem the i.MX6Q SABRESD board.
> The console becomes unreadable and unwritable.
>
> Tested-by: Steve Twiss <stwiss.opensource@diasemi.com>
> Signed-off-by: Steve Twiss <stwiss.opensource@diasemi.com>
You're not the first to report this issue but you still have the chance
to be the first to test a suggested patch for it.
See
http://marc.info/?l=linux-serial&m=149434029912947&w=2
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply
* RE: [PATCH V1] serial: imx: revert setup DCEDTE early and ensure DCD and RI irqs to be off
From: Steve Twiss @ 2017-05-23 14:28 UTC (permalink / raw)
To: Uwe Kleine-König
Cc: Greg Kroah-Hartman, Jiri Slaby, LINUX-KERNEL, LINUX-SERIAL,
Lucas Stach, Support Opensource, kernel@pengutronix.de
In-Reply-To: <20170523140941.l6cjvfdsvsg76cbx@pengutronix.de>
Hi Uwe,
Thanks for your quick response.
On 23 May 2017 15:10, Uwe Kleine-König wrote:
> Subject: Re: [PATCH V1] serial: imx: revert setup DCEDTE early and ensure DCD and RI irqs to be off
> On Tue, May 23, 2017 at 01:17:26PM +0100, Steve Twiss wrote:
> >
> > Revert the commit e61c38d85b7392e ("serial: imx: setup DCEDTE early and
> > ensure DCD and RI irqs to be off")
> >
> > The patch submitted to setup DCEDTE early and ensure DCD and RI irqs to
> > be off, causes a serial console display problem the i.MX6Q SABRESD board.
> > The console becomes unreadable and unwritable.
> >
> > Tested-by: Steve Twiss <stwiss.opensource@diasemi.com>
> > Signed-off-by: Steve Twiss <stwiss.opensource@diasemi.com>
>
> You're not the first to report this issue but you still have the chance
> to be the first to test a suggested patch for it.
I've just applied your patch against a clean linux-next/v4.12-rc2
I added your patch ...
> http://marc.info/?l=linux-serial&m=149434029912947&w=2
(this one?)
diff --git a/gp_sparse/linux-next/v4.12-rc2/drivers/tty/serial/imx.c b/gp_sparse/linux-next/v4.12-rc2/drivers/tty/serial/imx.c
index 33509b4..2182548 100644
--- a/gp_sparse/linux-next/v4.12-rc2/drivers/tty/serial/imx.c
+++ b/gp_sparse/linux-next/v4.12-rc2/drivers/tty/serial/imx.c
@@ -2193,9 +2193,14 @@ static int serial_imx_probe(struct platform_device *pdev)
*/
writel(IMX21_UCR3_RXDMUXSEL | UCR3_ADNIMP | UCR3_DSR,
sport->port.membase + UCR3);
-
} else {
+ unsigned long ucr3 = UCR3_DSR;
+
+ if (!is_imx1_uart(sport))
+ ucr3 |= IMX21_UCR3_RXDMUXSEL | UCR3_ADNIMP;
+
writel(0, sport->port.membase + UFCR);
+ writel(ucr3, sport->port.membase + UCR3);
}
clk_disable_unprepare(sport->clk_ipg);
I've added that to my working directory, but I am still seeing the corrupted
console output on the i.MX6 Q (quad) board.
Best regards
Steve
^ permalink raw reply related
* Re: [PATCH V1] serial: imx: revert setup DCEDTE early and ensure DCD and RI irqs to be off
From: Uwe Kleine-König @ 2017-05-23 14:37 UTC (permalink / raw)
To: Steve Twiss
Cc: Greg Kroah-Hartman, Jiri Slaby, LINUX-KERNEL, LINUX-SERIAL,
Lucas Stach, Support Opensource, kernel@pengutronix.de
In-Reply-To: <6ED8E3B22081A4459DAC7699F3695FB7018CD8D303@SW-EX-MBX02.diasemi.com>
Hallo Steve,
On Tue, May 23, 2017 at 02:28:11PM +0000, Steve Twiss wrote:
> On 23 May 2017 15:10, Uwe Kleine-König wrote:
> > Subject: Re: [PATCH V1] serial: imx: revert setup DCEDTE early and ensure DCD and RI irqs to be off
> > On Tue, May 23, 2017 at 01:17:26PM +0100, Steve Twiss wrote:
> > >
> > > Revert the commit e61c38d85b7392e ("serial: imx: setup DCEDTE early and
> > > ensure DCD and RI irqs to be off")
> > >
> > > The patch submitted to setup DCEDTE early and ensure DCD and RI irqs to
> > > be off, causes a serial console display problem the i.MX6Q SABRESD board.
> > > The console becomes unreadable and unwritable.
> > >
> > > Tested-by: Steve Twiss <stwiss.opensource@diasemi.com>
> > > Signed-off-by: Steve Twiss <stwiss.opensource@diasemi.com>
> >
> > You're not the first to report this issue but you still have the chance
> > to be the first to test a suggested patch for it.
>
> I've just applied your patch against a clean linux-next/v4.12-rc2
> I added your patch ...
>
> > http://marc.info/?l=linux-serial&m=149434029912947&w=2
>
> (this one?)
>
> diff --git a/gp_sparse/linux-next/v4.12-rc2/drivers/tty/serial/imx.c b/gp_sparse/linux-next/v4.12-rc2/drivers/tty/serial/imx.c
> index 33509b4..2182548 100644
> --- a/gp_sparse/linux-next/v4.12-rc2/drivers/tty/serial/imx.c
> +++ b/gp_sparse/linux-next/v4.12-rc2/drivers/tty/serial/imx.c
> @@ -2193,9 +2193,14 @@ static int serial_imx_probe(struct platform_device *pdev)
> */
> writel(IMX21_UCR3_RXDMUXSEL | UCR3_ADNIMP | UCR3_DSR,
> sport->port.membase + UCR3);
> -
> } else {
> + unsigned long ucr3 = UCR3_DSR;
> +
> + if (!is_imx1_uart(sport))
> + ucr3 |= IMX21_UCR3_RXDMUXSEL | UCR3_ADNIMP;
> +
> writel(0, sport->port.membase + UFCR);
> + writel(ucr3, sport->port.membase + UCR3);
> }
>
> clk_disable_unprepare(sport->clk_ipg);
>
Yeah, that's the patch I meant.
> I've added that to my working directory, but I am still seeing the corrupted
> console output on the i.MX6 Q (quad) board.
I don't have a failing board (I think). So here are a few questions
about yours:
- how does the dts snippet for your failing device look like?
- This is not the device the console runs on, right?
- Can you initialize the device in the bootloader and check if it is
working there?
- Does it make a difference in Linux if the bootloader used the device
before?
- Can you dump the register space of the uart with v4.12-rc2 and
v4.12-rc2 + revert of e61c38d85b7392e?
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply
* Re: [PATCH 1/2] Document: DT: Add bindings for Mediatek MT2712 SoC Platform
From: Rob Herring @ 2017-05-23 14:57 UTC (permalink / raw)
To: YT Shen
Cc: Matthias Brugger, Mark Rutland, devicetree-u79uwXL29TY76Z2rM5mHXA,
Jason Cooper, srv_heupstream-NuS5LvNUpcJWk0Htik3J/w, Marc Zyngier,
Catalin Marinas, Will Deacon, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
Mars Cheng, linux-serial-u79uwXL29TY76Z2rM5mHXA,
Greg Kroah-Hartman,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Thomas Gleixner,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <1495192186-22480-2-git-send-email-yt.shen-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
On Fri, May 19, 2017 at 07:09:45PM +0800, YT Shen wrote:
> This adds dt-binding documentation for Mediatek MT2712.
> Only include very basic items: cpu, gic and uart.
'dt-bindings: arm: ...' is the preferred subject prefix.
>
> Signed-off-by: YT Shen <yt.shen-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> ---
> Documentation/devicetree/bindings/arm/mediatek.txt | 4 ++++
> .../devicetree/bindings/interrupt-controller/mediatek,sysirq.txt | 1 +
> Documentation/devicetree/bindings/serial/mtk-uart.txt | 1 +
> 3 files changed, 6 insertions(+)
Otherwise,
Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
--
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 V1] serial: imx: revert setup DCEDTE early and ensure DCD and RI irqs to be off
From: Steve Twiss @ 2017-05-23 15:01 UTC (permalink / raw)
To: Uwe Kleine-König
Cc: Greg Kroah-Hartman, Jiri Slaby, LINUX-KERNEL, LINUX-SERIAL,
Lucas Stach, Support Opensource, kernel@pengutronix.de
In-Reply-To: <20170523143715.yeg3gpkmvlu4l5kt@pengutronix.de>
Hi Uwe,
On 23 May 2017 15:37, Uwe Kleine-König wrote:
> Subject: Re: [PATCH V1] serial: imx: revert setup DCEDTE early and ensure DCD and RI irqs to be off
> On Tue, May 23, 2017 at 02:28:11PM +0000, Steve Twiss wrote:
> > On 23 May 2017 15:10, Uwe Kleine-König wrote:
> > > On Tue, May 23, 2017 at 01:17:26PM +0100, Steve Twiss wrote:
> > > >
> > > > Revert the commit e61c38d85b7392e ("serial: imx: setup DCEDTE early and
> > > > ensure DCD and RI irqs to be off")
> > > > The patch submitted to setup DCEDTE early and ensure DCD and RI irqs to
> > > > be off, causes a serial console display problem the i.MX6Q SABRESD board.
> > > > The console becomes unreadable and unwritable.
> > > >
> > > > Tested-by: Steve Twiss <stwiss.opensource@diasemi.com>
> > > > Signed-off-by: Steve Twiss <stwiss.opensource@diasemi.com>
> > >
> > > You're not the first to report this issue but you still have the chance
> > > to be the first to test a suggested patch for it.
> >
> > I've just applied your patch against a clean linux-next/v4.12-rc2
> > I added your patch ...
> >
> > > http://marc.info/?l=linux-serial&m=149434029912947&w=2
> >
[...]
> > I've added that to my working directory, but I am still seeing the corrupted
> > console output on the i.MX6 Q (quad) board.
>
> I don't have a failing board (I think). So here are a few questions
> about yours:
>
> - how does the dts snippet for your failing device look like?
I am using the standard DTS from the v4.12-rc2 kernel, no changes.
I did an earlier test yesterday using the DTS from v4.11 to see if it was the new
imx7 changes that have recently gone into the kernel but I still see the same
effect.
> - This is not the device the console runs on, right?
I am connected through the USB to UART, U22 on the i.MX6Q board.
Terminal set to 115200 baud, no parity, 8bit data.
> - Can you initialize the device in the bootloader and check if it is working there?
I can get U-boot ok for all cases.
Once I TFTP the kernel across, I am okay until I get to "Starting kernel ...",
then, the UART is "working" in the sense that I get the some characters in the style
of the kernel starting up, but they are all garbled.
I expect the kernel has started ok, but I am unable to read/write through the UART
console because of corruptions.
Console log:
--- 8< ---
U-Boot 2009.08-00001-gf65536a (Jan 12 2015 - 15:47:19)
CPU: Freescale i.MX6 family TO1.2 at 792 MHz
Thermal sensor with ratio = 200
Temperature: 46 C, calibration data 0x5f15527d
mx6q pll1: 792MHz
mx6q pll2: 528MHz
mx6q pll3: 480MHz
mx6q pll8: 50MHz
ipg clock : 66000000Hz
ipg per clock : 66000000Hz
uart clock : 80000000Hz
cspi clock : 60000000Hz
ahb clock : 132000000Hz
axi clock : 264000000Hz
emi_slow clock: 132000000Hz
ddr clock : 528000000Hz
usdhc1 clock : 198000000Hz
usdhc2 clock : 198000000Hz
usdhc3 clock : 198000000Hz
usdhc4 clock : 198000000Hz
nfc clock : 24000000Hz
Board: i.MX6Q-SABRESD: unknown-board Board: 0x63012 [WDOG ]
Boot Device: SD
I2C: ready
DRAM: 1 GB
MMC: FSL_USDHC: 0,FSL_USDHC: 1,FSL_USDHC: 2,FSL_USDHC: 3
In: serial
Out: serial
Err: serial
Found PFUZE100! deviceid=10,revid=11
Net: got MAC address from IIM: 00:04:9f:02:e3:0a
FEC0 [PRIME]
Hit any key to stop autoboot: 0
PHY indentify @ 0x1 = 0x004dd074
FEC: Link is Up 796d
Using FEC0 device
TFTP from server 192.168.2.1; our IP address is 192.168.2.2
Filename 'uImage_dtb.imx6q.v4.12-rc2'.
Load address: 0x12000000
Loading: #################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
##########################################################
done
Bytes transferred = 5951108 (5ace84 hex)
## Booting kernel from Legacy Image at 12000000 ...
Image Name:
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 5951044 Bytes = 5.7 MB
Load Address: 10800000
Entry Point: 10800000
Verifying Checksum ... OK
Loading Kernel Image ... OK
OK
Starting kernel ...
à\x1cü\x1cü\x1cpþ\x1càüþü\x1cà\x1càà\x1càüþü\x1c\x1c\x1c\x1càüü\x1cþü\x1cà\x1cü\x1cà\x1cà\x1càüŽ\x1c\x1càü\x1càü\x1c\x1c\x1c\x1c\x1càà\x1cà\x1cà\x1c€à\x1càüþü\x1c\x1c\x1c\x1cààü\x1c\x1cüÿ
à\x1càüŽü\x1cþü\x1càüàð\x1c\x1cààðàà\x1c\x1cà\x1c\x1c\x1cþ\x1c\x1c\x1c~pà\x1cœà\x1c`þ\x1cü\x1càüŽà\x1cà\x1c\x1cà\x1cü\x1cà\x1c\x1cþ\x1cüþ\x1c\x1c\x1c\x1cà\x1cü\x1c\x1cà\x1cŽàà\x1c\x1cà\x1c\x1c\x1c
ààü\x1c\x1cüÿ\x1cà\x1càüŽü\x1cþü\x1càüàð\x1c\x1c€àà\x1c\x1cààààðàà\x1cðàüààüðààðààà\x1c\x1c\x1c\x1cþ\x1c\x1cüÿ\x1c\x1cüðü\x1c\x1cüŽ\x1cà\x1c\x1cüŽà\x1cà\x1c\x1cà\x1cüü
\x1c\x1c\x1c\x1cþ\x1c\x1c\x1cüÿ\x1cà\x1càü\x1cü\x1cpð\x1c\x1cüÀ\x1c\x1cüþü\x1c\x1cü\x1càà\x1càüpÿ\x1c\x1cüààðàà\x1cðàüàð\x1c\x1cà\x1cüàŽ\x1c\x1c~8à\x1cŽàà\x1cŽààü€ààðààüp
Ž\x1cà\x1c\x1cà\x1c\x1c\x1c\x1c\x1cüà\x1cà\x1c\x1cà\x1cààðàüðàà\x1cðà\x1cüàpþàüðàüðààþà\x1cðà\x1cüààà\x1cà\x1c\x1c\x1cààðàà\x1cðàüüàŽà\x1c€ü\x1c\x1c\x1c\x1c\x1c\x1càà\x1c
\x1c\x1cŽ\x1cüà~ÿ\x1cüàà\x1càà\x1cü\x1c\x1c\x1cüŽà\x1cà\x1cü\x1cþ\x1càü~Žüàðààðààà\x1c\x1cà\x1cþà\x1c€\x1cü\x1cààð\x1c\x1cü~ÿ\x1càüŽà\x1càüŽü\x1cþü\x1cà\x1cðààà\x1c
\x1c\x1cŽ\x1cüà~ÿ\x1cüàŽà\x1c\x1càü€\x1c\x1cþ\x1cüà\x1cðààü€\x1c\x1càüðààüüà€à\x1cüà\x1c€ü\x1c\x1c\x1c\x1c\x1c\x1càà\x1c\x1c\x1cŽ\x1c\x1c\x1càü\x1c\x1càà\x1c\x1cààã\x1cpŽ\x1cààü\x1cü
\x1cþü\x1c\x1càü\x1càüŽ\x1cà\x1càüþü\x1cà\x1càà\x1c\x1càþ\x1c\x1càü€\x1c\x1c\x1cü\x1c\x1cüð\x1c\x1càà\x1c\x1cààã\x1cpŽ\x1cà\x1c€\x1càü\x1càüŽ\x1cà\x1càüþü\x1cà\x1cà\x1cŽ\x1cü
--- 8< ---
> - Does it make a difference in Linux if the bootloader used the device before?
If you mean, if U-boot uses the UART console before loading the kernel, then no.
Is that what you mean?
It makes no difference until the kernel is loaded, then the serial output gets corrupted.
> - Can you dump the register space of the uart with v4.12-rc2 and
> v4.12-rc2 + revert of e61c38d85b7392e?
Difficult to do that I think. The console is unusable in both directions. I can't get any
response from the console (through typing) once the kernel has started.
Regards,
Steve
^ permalink raw reply
* Re: [PATCH 2/2] arm64: dts: Add Mediatek SoC MT2712 and evaluation board dts and Makefile
From: Rob Herring @ 2017-05-23 15:01 UTC (permalink / raw)
To: YT Shen
Cc: Matthias Brugger, Mark Rutland, Thomas Gleixner, Jason Cooper,
Marc Zyngier, Greg Kroah-Hartman, Catalin Marinas, Will Deacon,
Mars Cheng, devicetree, linux-kernel, linux-serial,
linux-arm-kernel, linux-mediatek, srv_heupstream
In-Reply-To: <1495192186-22480-3-git-send-email-yt.shen@mediatek.com>
On Fri, May 19, 2017 at 07:09:46PM +0800, YT Shen wrote:
> This adds basic chip support for Mediatek 2712
>
> Signed-off-by: YT Shen <yt.shen@mediatek.com>
> ---
> arch/arm64/boot/dts/mediatek/Makefile | 1 +
> arch/arm64/boot/dts/mediatek/mt2712-evb.dts | 44 +++++++
> arch/arm64/boot/dts/mediatek/mt2712e.dtsi | 172 ++++++++++++++++++++++++++++
> 3 files changed, 217 insertions(+)
> create mode 100644 arch/arm64/boot/dts/mediatek/mt2712-evb.dts
> create mode 100644 arch/arm64/boot/dts/mediatek/mt2712e.dtsi
>
> diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
> index 9fbfd32..fcc0604 100644
> --- a/arch/arm64/boot/dts/mediatek/Makefile
> +++ b/arch/arm64/boot/dts/mediatek/Makefile
> @@ -1,3 +1,4 @@
> +dtb-$(CONFIG_ARCH_MEDIATEK) += mt2712-evb.dtb
> dtb-$(CONFIG_ARCH_MEDIATEK) += mt6755-evb.dtb
> dtb-$(CONFIG_ARCH_MEDIATEK) += mt6795-evb.dtb
> dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-evb.dtb
> diff --git a/arch/arm64/boot/dts/mediatek/mt2712-evb.dts b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
> new file mode 100644
> index 0000000..40b0c91
> --- /dev/null
> +++ b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
> @@ -0,0 +1,44 @@
> +/*
> + * Copyright (c) 2017 MediaTek Inc.
> + * Author: YT Shen <yt.shen@mediatek.com>
> + *
> + * 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.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
You may want to dual license this. Not sure what the rest of Mediatek
dts files do though. Also, you can use SPDX tag here if you want.
> +
> +/dts-v1/;
> +#include "mt2712e.dtsi"
> +
> +/ {
> + model = "MediaTek MT2712 evaluation board";
> + compatible = "mediatek,mt2712-evb", "mediatek,mt2712";
> +
> + aliases {
> + serial0 = &uart0;
> + serial1 = &uart1;
> + serial2 = &uart2;
> + serial3 = &uart3;
> + serial4 = &uart4;
> + serial5 = &uart5;
> + };
> +
> + memory@40000000 {
> + device_type = "memory";
> + reg = <0 0x40000000 0 0x80000000>;
> + };
> +
> + chosen {
> + bootargs = "console=ttyS0,921600n1 initrd=0x45000000,90M";
Both of these have a way to be expressed in DT. For the initrd, the
bootloader should be setting the address and size anyway.
> + };
> +};
> +
> +&uart0 {
> + status = "okay";
> +};
> +
> diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
> new file mode 100644
> index 0000000..40747a9
> --- /dev/null
> +++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
> @@ -0,0 +1,172 @@
> +/*
> + * Copyright (c) 2017 MediaTek Inc.
> + * Author: YT Shen <yt.shen@mediatek.com>
> + *
> + * 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.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <dt-bindings/interrupt-controller/irq.h>
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +
> +/ {
> + compatible = "mediatek,mt2712";
> + interrupt-parent = <&sysirq>;
> + #address-cells = <2>;
> + #size-cells = <2>;
> +
> + cpus {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + cpu-map {
> + cluster0 {
> + core0 {
> + cpu = <&cpu0>;
> + };
> + core1 {
> + cpu = <&cpu1>;
> + };
> + };
> +
> + cluster1 {
> + core0 {
> + cpu = <&cpu2>;
> + };
> + };
> + };
> +
> + cpu0: cpu@0 {
> + device_type = "cpu";
> + compatible = "arm,cortex-a35";
> + reg = <0x000>;
> + };
> +
> + cpu1: cpu@1 {
> + device_type = "cpu";
> + compatible = "arm,cortex-a35";
> + reg = <0x001>;
> + enable-method = "psci";
> + };
> +
> + cpu2: cpu@200 {
> + device_type = "cpu";
> + compatible = "arm,cortex-a72";
> + reg = <0x200>;
> + enable-method = "psci";
> + };
> + };
> +
> + psci {
> + compatible = "arm,psci-0.2";
> + method = "smc";
> + };
> +
> + uart_clk: dummy26m {
> + compatible = "fixed-clock";
> + clock-frequency = <26000000>;
> + #clock-cells = <0>;
> + };
> +
> + timer {
> + compatible = "arm,armv8-timer";
> + interrupt-parent = <&gic>;
> + interrupts = <GIC_PPI 13
> + (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
> + <GIC_PPI 14
> + (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
> + <GIC_PPI 11
> + (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
> + <GIC_PPI 10
> + (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>;
> + };
> +
> + soc {
> + #address-cells = <2>;
> + #size-cells = <2>;
> + compatible = "simple-bus";
> + ranges;
> +
> + uart5: serial@1000f000 {
> + compatible = "mediatek,mt2712-uart",
> + "mediatek,mt6577-uart";
> + reg = <0 0x1000f000 0 0x400>;
> + interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_LOW>;
> + clocks = <&uart_clk>;
> + status = "disabled";
> + };
> +
> + sysirq: intpol-controller@10220a80 {
interrupt-controller@...
> + compatible = "mediatek,mt2712-sysirq",
> + "mediatek,mt6577-sysirq";
> + interrupt-controller;
> + #interrupt-cells = <3>;
> + interrupt-parent = <&gic>;
> + reg = <0 0x10220a80 0 0x40>;
> + };
> +
> + gic: interrupt-controller@10510000 {
> + compatible = "arm,gic-400";
> + #interrupt-cells = <3>;
> + interrupt-parent = <&gic>;
> + interrupt-controller;
> + reg = <0 0x10510000 0 0x1000>,
> + <0 0x10520000 0 0x1000>,
> + <0 0x10540000 0 0x2000>,
> + <0 0x10560000 0 0x2000>;
> + interrupts = <GIC_PPI 9
> + (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_HIGH)>;
> + };
> +
> + uart0: serial@11002000 {
> + compatible = "mediatek,mt2712-uart",
> + "mediatek,mt6577-uart";
> + reg = <0 0x11002000 0 0x400>;
> + interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_LOW>;
> + clocks = <&uart_clk>;
> + status = "disabled";
> + };
> +
> + uart1: serial@11003000 {
> + compatible = "mediatek,mt2712-uart",
> + "mediatek,mt6577-uart";
> + reg = <0 0x11003000 0 0x400>;
> + interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_LOW>;
> + clocks = <&uart_clk>;
> + status = "disabled";
> + };
> +
> + uart2: serial@11004000 {
> + compatible = "mediatek,mt2712-uart",
> + "mediatek,mt6577-uart";
> + reg = <0 0x11004000 0 0x400>;
> + interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_LOW>;
> + clocks = <&uart_clk>;
> + status = "disabled";
> + };
> +
> + uart3: serial@11005000 {
> + compatible = "mediatek,mt2712-uart",
> + "mediatek,mt6577-uart";
> + reg = <0 0x11005000 0 0x400>;
> + interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_LOW>;
> + clocks = <&uart_clk>;
> + status = "disabled";
> + };
> +
> + uart4: serial@11019000 {
> + compatible = "mediatek,mt2712-uart",
> + "mediatek,mt6577-uart";
> + reg = <0 0x11019000 0 0x400>;
> + interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_LOW>;
> + clocks = <&uart_clk>;
> + status = "disabled";
> + };
> + };
> +};
> +
> --
> 1.9.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: gpio-exar: Why filtering out Commtech devices?
From: Jan Kiszka @ 2017-05-23 15:05 UTC (permalink / raw)
To: Technical Support
Cc: Sudip Mukherjee, Linux Kernel Mailing List, linux-serial,
linux-gpio
In-Reply-To: <CAPpjZG_HPFqKzf+7rBxM27TJcZJ4+vfUYSPChifM-JTN7ekTOA@mail.gmail.com>
On 2017-05-23 16:33, Technical Support wrote:
> Both the PCI and the PCIe cards use the MPIO pins and the device driver
> actually sets the pins as outputs after registering the device with the
> PCI core. So the changes made to the default settings shouldn't break
> anything.
>
> Do the new default settings keep the UART_EXAR_MPIOINT_X_X values at
> 0x00 to disable their interrupts?
Look at
https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git/commit/?h=tty-next&id=7dea8165f1d6434dc7572004363f86339f0f4322
Interrupts remain off, but all pins are now inputs. Again, if the logic
on the PCIe cards need any of them to be driven low, my patch causes a
regression. In that case, we also need to make the MPIO setup card-specific.
Thanks,
Jan
>
> -Landon
>
> Commtech, Inc.
> Voice: 316-636-1131 <tel:%28316%29%20636-1131>
> http://www.fastcomproducts.com
>
>
>
>
> On Mon, May 22, 2017 at 1:18 PM, Jan Kiszka <jan.kiszka@siemens.com
> <mailto:jan.kiszka@siemens.com>> wrote:
>
> On 2017-05-22 18:24, Jan Kiszka wrote:
> > On 2017-05-22 17:17, Technical Support wrote:
> >> Hello,
> >>
> >> The Exar MPIO pins are used by our device driver to control features of
> >> the line driver and can't be used as GPIO pins. I agree, the condition
> >> can be moved to 8250_exar prior to a platform device being created for
> >> the gpio_exar driver.
> >>
> >
> > Thanks a lot for the feedback! I will send a refactoring patch.
>
> Hmm, are you possibly talking about PCI device with the IDs 0x2, 0x4,
> 0xa, 0xb (4222PCI335, 4224PCI335, 2324PCI335, 2328PCI335), because those
> actually set the GPIOs for apparent internal reasons. However,
> 0x20..0x22 (4222PCIE, 4224PCIE, 4228PCIE) already share setup_gpio() via
> pci_xr17v35x_setup(), and that looks different.
>
> I'm also asking again because we just changed the default MPIO settings
> for the latter to all inputs. If you depended on them to be all outputs
> and 0, we may have broken something.
>
> Thanks,
> Jan
>
> --
> Siemens AG, Corporate Technology, CT RDA ITP SES-DE
> Corporate Competence Center Embedded Linux
>
>
--
Siemens AG, Corporate Technology, CT RDA ITP SES-DE
Corporate Competence Center Embedded Linux
^ permalink raw reply
* Re: [PATCH V1] serial: imx: revert setup DCEDTE early and ensure DCD and RI irqs to be off
From: Uwe Kleine-König @ 2017-05-23 16:08 UTC (permalink / raw)
To: Steve Twiss
Cc: Greg Kroah-Hartman, Jiri Slaby, LINUX-KERNEL, LINUX-SERIAL,
Lucas Stach, Support Opensource, kernel@pengutronix.de
In-Reply-To: <6ED8E3B22081A4459DAC7699F3695FB7018CD8D328@SW-EX-MBX02.diasemi.com>
Hello Steve,
On Tue, May 23, 2017 at 03:01:26PM +0000, Steve Twiss wrote:
> On 23 May 2017 15:37, Uwe Kleine-König wrote:
> > Subject: Re: [PATCH V1] serial: imx: revert setup DCEDTE early and ensure DCD and RI irqs to be off
> > On Tue, May 23, 2017 at 02:28:11PM +0000, Steve Twiss wrote:
> > > On 23 May 2017 15:10, Uwe Kleine-König wrote:
> > > > On Tue, May 23, 2017 at 01:17:26PM +0100, Steve Twiss wrote:
> > > > >
> > > > > Revert the commit e61c38d85b7392e ("serial: imx: setup DCEDTE early and
> > > > > ensure DCD and RI irqs to be off")
> > > > > The patch submitted to setup DCEDTE early and ensure DCD and RI irqs to
> > > > > be off, causes a serial console display problem the i.MX6Q SABRESD board.
> > > > > The console becomes unreadable and unwritable.
> > > > >
> > > > > Tested-by: Steve Twiss <stwiss.opensource@diasemi.com>
> > > > > Signed-off-by: Steve Twiss <stwiss.opensource@diasemi.com>
> > > >
> > > > You're not the first to report this issue but you still have the chance
> > > > to be the first to test a suggested patch for it.
> > >
> > > I've just applied your patch against a clean linux-next/v4.12-rc2
> > > I added your patch ...
> > >
> > > > http://marc.info/?l=linux-serial&m=149434029912947&w=2
> > >
> [...]
> > > I've added that to my working directory, but I am still seeing the corrupted
> > > console output on the i.MX6 Q (quad) board.
> >
> > I don't have a failing board (I think). So here are a few questions
> > about yours:
> >
> > - how does the dts snippet for your failing device look like?
>
> I am using the standard DTS from the v4.12-rc2 kernel, no changes.
> I did an earlier test yesterday using the DTS from v4.11 to see if it was the new
> imx7 changes that have recently gone into the kernel but I still see the same
> effect.
>
> > - This is not the device the console runs on, right?
>
> I am connected through the USB to UART, U22 on the i.MX6Q board.
> Terminal set to 115200 baud, no parity, 8bit data.
>
> > - Can you initialize the device in the bootloader and check if it is working there?
>
> I can get U-boot ok for all cases.
> Once I TFTP the kernel across, I am okay until I get to "Starting kernel ...",
> then, the UART is "working" in the sense that I get the some characters in the style
> of the kernel starting up, but they are all garbled.
>
> I expect the kernel has started ok, but I am unable to read/write through the UART
> console because of corruptions.
>
> Console log:
> --- 8< ---
> U-Boot 2009.08-00001-gf65536a (Jan 12 2015 - 15:47:19)
>
> CPU: Freescale i.MX6 family TO1.2 at 792 MHz
> Thermal sensor with ratio = 200
> Temperature: 46 C, calibration data 0x5f15527d
huh, it's hot in your office :-)
> mx6q pll1: 792MHz
> mx6q pll2: 528MHz
> mx6q pll3: 480MHz
> mx6q pll8: 50MHz
> ipg clock : 66000000Hz
> ipg per clock : 66000000Hz
> uart clock : 80000000Hz
> cspi clock : 60000000Hz
> ahb clock : 132000000Hz
> axi clock : 264000000Hz
> emi_slow clock: 132000000Hz
> ddr clock : 528000000Hz
> usdhc1 clock : 198000000Hz
> usdhc2 clock : 198000000Hz
> usdhc3 clock : 198000000Hz
> usdhc4 clock : 198000000Hz
> nfc clock : 24000000Hz
> Board: i.MX6Q-SABRESD: unknown-board Board: 0x63012 [WDOG ]
> Boot Device: SD
> I2C: ready
> DRAM: 1 GB
> MMC: FSL_USDHC: 0,FSL_USDHC: 1,FSL_USDHC: 2,FSL_USDHC: 3
> In: serial
> Out: serial
> Err: serial
> Found PFUZE100! deviceid=10,revid=11
> Net: got MAC address from IIM: 00:04:9f:02:e3:0a
> FEC0 [PRIME]
> Hit any key to stop autoboot: 0
> PHY indentify @ 0x1 = 0x004dd074
> FEC: Link is Up 796d
> Using FEC0 device
> TFTP from server 192.168.2.1; our IP address is 192.168.2.2
> Filename 'uImage_dtb.imx6q.v4.12-rc2'.
> Load address: 0x12000000
> Loading: #################################################################
> #################################################################
> #################################################################
> #################################################################
> #################################################################
> #################################################################
> #################################################################
> #################################################################
> #################################################################
> #################################################################
> #################################################################
> #################################################################
> #################################################################
> #################################################################
> #################################################################
> #################################################################
> #################################################################
> ##########################################################
> done
> Bytes transferred = 5951108 (5ace84 hex)
> ## Booting kernel from Legacy Image at 12000000 ...
> Image Name:
> Image Type: ARM Linux Kernel Image (uncompressed)
> Data Size: 5951044 Bytes = 5.7 MB
> Load Address: 10800000
> Entry Point: 10800000
> Verifying Checksum ... OK
> Loading Kernel Image ... OK
> OK
>
> Starting kernel ...
>
> à\x1cü\x1cü\x1cpþ\x1càüþü\x1cà\x1càà\x1càüþü\x1c\x1c\x1c\x1càüü\x1cþü\x1cà\x1cü\x1cà\x1cà\x1càüŽ\x1c\x1càü\x1càü\x1c\x1c\x1c\x1c\x1càà\x1cà\x1cà\x1c€à\x1càüþü\x1c\x1c\x1c\x1cààü\x1c\x1cüÿ
> à\x1càüŽü\x1cþü\x1càüàð\x1c\x1cààðàà\x1c\x1cà\x1c\x1c\x1cþ\x1c\x1c\x1c~pà\x1cœà\x1c`þ\x1cü\x1càüŽà\x1cà\x1c\x1cà\x1cü\x1cà\x1c\x1cþ\x1cüþ\x1c\x1c\x1c\x1cà\x1cü\x1c\x1cà\x1cŽàà\x1c\x1cà\x1c\x1c\x1c
> ààü\x1c\x1cüÿ\x1cà\x1càüŽü\x1cþü\x1càüàð\x1c\x1c€àà\x1c\x1cààààðàà\x1cðàüààüðààðààà\x1c\x1c\x1c\x1cþ\x1c\x1cüÿ\x1c\x1cüðü\x1c\x1cüŽ\x1cà\x1c\x1cüŽà\x1cà\x1c\x1cà\x1cüü
> \x1c\x1c\x1c\x1cþ\x1c\x1c\x1cüÿ\x1cà\x1càü\x1cü\x1cpð\x1c\x1cüÀ\x1c\x1cüþü\x1c\x1cü\x1càà\x1càüpÿ\x1c\x1cüààðàà\x1cðàüàð\x1c\x1cà\x1cüàŽ\x1c\x1c~8à\x1cŽàà\x1cŽààü€ààðààüp
> Ž\x1cà\x1c\x1cà\x1c\x1c\x1c\x1c\x1cüà\x1cà\x1c\x1cà\x1cààðàüðàà\x1cðà\x1cüàpþàüðàüðààþà\x1cðà\x1cüààà\x1cà\x1c\x1c\x1cààðàà\x1cðàüüàŽà\x1c€ü\x1c\x1c\x1c\x1c\x1c\x1càà\x1c
> \x1c\x1cŽ\x1cüà~ÿ\x1cüàà\x1càà\x1cü\x1c\x1c\x1cüŽà\x1cà\x1cü\x1cþ\x1càü~Žüàðààðààà\x1c\x1cà\x1cþà\x1c€\x1cü\x1cààð\x1c\x1cü~ÿ\x1càüŽà\x1càüŽü\x1cþü\x1cà\x1cðààà\x1c
> \x1c\x1cŽ\x1cüà~ÿ\x1cüàŽà\x1c\x1càü€\x1c\x1cþ\x1cüà\x1cðààü€\x1c\x1càüðààüüà€à\x1cüà\x1c€ü\x1c\x1c\x1c\x1c\x1c\x1càà\x1c\x1c\x1cŽ\x1c\x1c\x1càü\x1c\x1càà\x1c\x1cààã\x1cpŽ\x1cààü\x1cü
> \x1cþü\x1c\x1càü\x1càüŽ\x1cà\x1càüþü\x1cà\x1càà\x1c\x1càþ\x1c\x1càü€\x1c\x1c\x1cü\x1c\x1cüð\x1c\x1càà\x1c\x1cààã\x1cpŽ\x1cà\x1c€\x1càü\x1càüŽ\x1cà\x1càüþü\x1cà\x1cà\x1cŽ\x1cü
did you check with an oscilloscope if the baud rate is as expected (hmm,
but I wouldn't expect my patch to change the baud rate).
> --- 8< ---
>
> > - Does it make a difference in Linux if the bootloader used the device before?
>
> If you mean, if U-boot uses the UART console before loading the kernel, then no.
> Is that what you mean?
I didn't expect that it destroys the console UART so I expected that you
can make use of a 2nd UART in U-Boot somehow to already initialize the
port and check if that makes it magically work in Linux.
Note to myself: So we're taking about the UART at 0x02020000, it is
operated in DCE mode.
> It makes no difference until the kernel is loaded, then the serial
> output gets corrupted.
>
> > - Can you dump the register space of the uart with v4.12-rc2 and
> > v4.12-rc2 + revert of e61c38d85b7392e?
>
> Difficult to do that I think. The console is unusable in both directions. I can't get any
> response from the console (through typing) once the kernel has started.
ssh or telnet come to mind.
Can you try to just remove the line
writel(0, sport->port.membase + UFCR);
that was introduced in the last hunk by commit e61c38d85b7?
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply
* Re: [PATCH V1] serial: imx: revert setup DCEDTE early and ensure DCD and RI irqs to be off
From: Fabio Estevam @ 2017-05-23 16:26 UTC (permalink / raw)
To: Steve Twiss
Cc: Greg Kroah-Hartman, Jiri Slaby, LINUX-KERNEL, LINUX-SERIAL,
Lucas Stach, Uwe Kleine-Konig, Support Opensource
In-Reply-To: <20170523123145.E268B3FAD4@swsrvapps-01.diasemi.com>
Hi Steve,
On Tue, May 23, 2017 at 9:17 AM, Steve Twiss
<stwiss.opensource@diasemi.com> wrote:
> From: Steve Twiss <stwiss.opensource@diasemi.com>
>
> Revert the commit e61c38d85b7392e ("serial: imx: setup DCEDTE early and
> ensure DCD and RI irqs to be off")
>
> The patch submitted to setup DCEDTE early and ensure DCD and RI irqs to
> be off, causes a serial console display problem the i.MX6Q SABRESD board.
> The console becomes unreadable and unwritable.
>
> Tested-by: Steve Twiss <stwiss.opensource@diasemi.com>
> Signed-off-by: Steve Twiss <stwiss.opensource@diasemi.com>
>
> ---
> This patch applies against linux-next and v4.12-rc2
>
> Hi,
>
> I have been seeing a problem with the serial output console on the i.MX6Q
> SABRESD, but not the i.MX6DL SABRESD. Everything was fine up to
> linux-mainline/v4.11 but changed after linux-next/next-20170501.
>
> Some bisection has pointed at the commit
> e61c38d85b7392e033ee03bca46f1d6006156175 which, once removed from my
> linux-next/v4.12-rc2 build allows the i.MX6Q board to display the console
> correctly again.
>
> This patch removes the original commit e61c38d85b7392e ("serial: imx:
> setup DCEDTE early and ensure DCD and RI irqs to be off") from linux-next
> v4.12-rc2 and fixes the serial problem seen in the i.MX6Q SABRESD board.
How can the error be reproduced?
Care to share more details of the error, please?
^ permalink raw reply
* Re: [PATCH v6 net-next 17/17] net: qualcomm: add QCA7000 UART driver
From: Lino Sanfilippo @ 2017-05-23 18:16 UTC (permalink / raw)
To: Stefan Wahren, Rob Herring, Mark Rutland, David S. Miller
Cc: Greg Kroah-Hartman, Jiri Slaby, Jakub Kicinski, devicetree,
netdev, linux-serial, linux-kernel
In-Reply-To: <1495545173-22150-18-git-send-email-stefan.wahren@i2se.com>
Hi,
On 23.05.2017 15:12, Stefan Wahren wrote:
> +}
> +
> +static void qca_uart_remove(struct serdev_device *serdev)
> +{
> + struct qcauart *qca = serdev_device_get_drvdata(serdev);
> +
> + netif_carrier_off(qca->net_dev);
> + cancel_work_sync(&qca->tx_work);
> + unregister_netdev(qca->net_dev);
Note that it is still possible that the tx work is queued right after cancel_work_sync()
returned and before the net device is unregistered (and thus the check for the net device
being up at the beginning of the tx work function is passed and the function is executed).
I suggest to avoid this possible race by first unregistering the netdevice and then
calling cancel_work_sync().
Regards,
Lino
^ permalink raw reply
* Re: [PATCH v6 net-next 17/17] net: qualcomm: add QCA7000 UART driver
From: Stefan Wahren @ 2017-05-23 19:38 UTC (permalink / raw)
To: Rob Herring, Mark Rutland, David S. Miller, Lino Sanfilippo
Cc: linux-serial, Jiri Slaby, Greg Kroah-Hartman, netdev,
linux-kernel, Jakub Kicinski, devicetree
In-Reply-To: <053235ad-a963-6a09-ccb0-b643115dee00@gmx.de>
> Lino Sanfilippo <LinoSanfilippo@gmx.de> hat am 23. Mai 2017 um 20:16 geschrieben:
>
>
> Hi,
>
> On 23.05.2017 15:12, Stefan Wahren wrote:
>
>
> > +}
> > +
> > +static void qca_uart_remove(struct serdev_device *serdev)
> > +{
> > + struct qcauart *qca = serdev_device_get_drvdata(serdev);
> > +
> > + netif_carrier_off(qca->net_dev);
> > + cancel_work_sync(&qca->tx_work);
> > + unregister_netdev(qca->net_dev);
>
> Note that it is still possible that the tx work is queued right after cancel_work_sync()
> returned and before the net device is unregistered (and thus the check for the net device
> being up at the beginning of the tx work function is passed and the function is executed).
Even if the carrier is off? Since i see this pattern in some drivers, can you please point me to a reference like a thread or something else?
> I suggest to avoid this possible race by first unregistering the netdevice and then
> calling cancel_work_sync().
What makes you sure that's safe to unregister the netdev while the tx work queue is possibly active?
> Regards,
> Lino
>
^ permalink raw reply
* Re: [PATCH 1/1] xilinx ps uart: Adding a kernel parameter for the number of xilinx ps uarts
From: Alan Cox @ 2017-05-23 20:07 UTC (permalink / raw)
To: Michal Simek
Cc: gregkh, linux-kernel, Rob Herring, Sam Povilus, linux-arm-kernel,
linux-serial, jslaby, soren.brinkmann
In-Reply-To: <1668f36e-f9be-7008-004a-e467a6813e0f@xilinx.com>
> yep hardcoded max 4 where in probe first free space is found and used
> (range 0-3) but still max3100s statically allocated.
> Shouldn't be this also dynamically allocated?
The code to do the dynamic allocation would be larger than the array of
pointers for the sane worst case.
> I am not quite sure how exactly you want to do this via DT.
Count the number of DT entries for this kind of port and allocate that
many ?
>
> Also what do you think is a safe maximum number? This is fpga - hundreds
> of pins which can do just uart.
>
> > There are lots of options better than breaking the "one kernel many
> > platforms" model.
>
> Another options is also module parameter and dynamically allocated array
> in cdns_uart_init.
For a given platform the number is constant and they need to be
described, so it seems to make no sense to put it anywhere other than the
DT for that platform.
Why should users have to pass magic config options not use DT as
intended ?
Alan
^ permalink raw reply
* Re: [PATCH v6 net-next 17/17] net: qualcomm: add QCA7000 UART driver
From: Lino Sanfilippo @ 2017-05-23 21:01 UTC (permalink / raw)
To: Stefan Wahren, Rob Herring, Mark Rutland, David S. Miller
Cc: linux-serial, Jiri Slaby, Greg Kroah-Hartman, netdev,
linux-kernel, Jakub Kicinski, devicetree
In-Reply-To: <1059621060.236992.1495568289051@email.1und1.de>
On 23.05.2017 21:38, Stefan Wahren wrote:
>
>> Lino Sanfilippo <LinoSanfilippo@gmx.de> hat am 23. Mai 2017 um 20:16 geschrieben:
>>
>>
>> Hi,
>>
>> On 23.05.2017 15:12, Stefan Wahren wrote:
>>
>>
>>> +}
>>> +
>>> +static void qca_uart_remove(struct serdev_device *serdev)
>>> +{
>>> + struct qcauart *qca = serdev_device_get_drvdata(serdev);
>>> +
>>> + netif_carrier_off(qca->net_dev);
>>> + cancel_work_sync(&qca->tx_work);
>>> + unregister_netdev(qca->net_dev);
>>
>> Note that it is still possible that the tx work is queued right after cancel_work_sync()
>> returned and before the net device is unregistered (and thus the check for the net device
>> being up at the beginning of the tx work function is passed and the function is executed).
>
> Even if the carrier is off? Since i see this pattern in some drivers, can you please point me to a reference like a thread or something else?
>
The check in the tx work function is against the "running" state not against the carrier. So why should
the carrier matter in this case?
>> I suggest to avoid this possible race by first unregistering the netdevice and then
>> calling cancel_work_sync().
>
> What makes you sure that's safe to unregister the netdev while the tx work queue is possibly active?
unregister_netdevice() calls netdev_close() if the interface is still up. netdev_close() calls flush_work()
so the unregistration is delayed until the tx work function is finished. Furthermore both close() and
tx work are synchronized by means of the qca->lock which also guarantees that unregister_netdevice() wont
be finished until the tx work is done.
But I may have missed something and if unregistering the device while the tx work could be running worries you,
we could first close and later unregister the device like in the following sequence:
dev_close();
/* the tx work wont be scheduled any more now, however we have to wait for a potentially
earlier scheduled work */
cancel_work_sync(&qca->tx_work);
/* we can be sure that the tx work will neither be running nor be started again, so
it is safe to unregister the netdev */
unregister_netdev(qca->net_dev);
serdev_device_close(serdev);
free_netdev(qca->net_dev);
What do you think?
Regards,
Lino
^ permalink raw reply
* Re: gpio-exar: Why filtering out Commtech devices?
From: Jan Kiszka @ 2017-05-23 21:16 UTC (permalink / raw)
To: Technical Support
Cc: Sudip Mukherjee, Linux Kernel Mailing List, linux-serial,
linux-gpio
In-Reply-To: <CAPpjZG953JHZWt8UzgEmYurSMh9o1v5HvxmO+4FD41M92GA-Ww@mail.gmail.com>
On 2017-05-23 22:05, Technical Support wrote:
> Our kernel module handles card specific MPIO setup, ensuring the pins
> are set correctly for our hardware regardless of what exar_8250
> initializes them as.
>
> https://github.com/commtech/serialfc-linux/blob/784e1321e00d4f72c93dae8da11cdc7f99c15dee/src/utils.c#L1463-L1491
OK, that code shows what we need to do in the official driver: handle
the commtech devices like before, i.e. keep the GPIOs as output for
them. I'll update my patch.
But now some good advice: you should rather work on the upstream code
and schedule your special driver for retirement. This will ensure that
your users have the best experience when they plug in any of your cards
and boot a standard Linux disto: it will just work.
Right now, your out-of-tree driver competes with the official one for
the same resources, apparently comes with own userspace interfaces to
configure special features instead of building on existing APIs (you
don't support TIOCSRS485 e.g., do you?), and seems to contain support
for a number of cards that are still missing in upstream. This is very
unhandy for your users.
For the same reason, we are currently upstreaming the code for our
Exar-based design (and that's why I came across all this): We want to
get rid of special board support to improve user experience and
long-term availability.
Jan
--
Siemens AG, Corporate Technology, CT RDA ITP SES-DE
Corporate Competence Center Embedded Linux
^ permalink raw reply
* Re: [PATCH 1/1] xilinx ps uart: Adding a kernel parameter for the number of xilinx ps uarts
From: Sam Povilus @ 2017-05-24 3:27 UTC (permalink / raw)
To: Alan Cox
Cc: Michal Simek, gregkh, jslaby, soren.brinkmann, linux-serial,
linux-arm-kernel, linux-kernel
In-Reply-To: <20170522192636.5b578d89@alans-desktop>
On Mon, May 22, 2017 at 07:26:36PM +0100, Alan Cox wrote:
> > We have in soc vendor tree similar patch but the reason is different.
> >
> > tty: serial: Added a CONFIG_SERIAL_XILINX_NR_UARTS option.
> >
> > This patch Adds CONFIG_SERIAL_XILINX_NR_UARTS option to allow
> > the user to provide the Max number of uart ports information.
> > If multiple cards (or) PL UARTS are present, the default limit
> > of 2 ports should be increased.
> >
> > I haven't checked all drivers but in our case we have added this as
> > quick fix for scenarios where you use serial aliases where alias is
> > pointed to serial2 or more.
> > In cdns_uart_init() cdns_uart_uart_driver is passed which contains .nr
> > which is required to be passed.
> >
> > What's the best driver to look at dynamic allocation?
>
> So there are quite a few that dynamically allocate the objects as they
> are enumerated (eg max3100), but have a maximum set that is just pointers
> (so for the max number of ports cheaper than the dynamic code)
>
> The other question is why is it a CONFIG_ option. I'm assuming these
> platforms are all ARM and in that case you could just pass the value in
> the device tree, or hard code a safe maximum number of pointers to a
> value which is the worst case and then install them as they are
> enumerated.
>
> There are lots of options better than breaking the "one kernel many
> platforms" model.
>
> Alan
I guess I'm confused how this isn't a better solution than what we have
now, or how it breaks the "one kernel many platforms model".
I agree that it is not the best solution, certainly this driver should be
re-written to use the device tree and dynamic allocation, but that is
not the patch being offered at this time.
This is a very minor module buried deep in the drivers tree. I guess I
don't understand how allowing users to choose how many UARTS they might
want to implement breaks the "one kernel" model. The users of this module
and those like it do not use a pre-compiled kernel and customize their
kernels extensively.
Is there some documentation online I could read that explains this "one
kernel many platforms" model? Specifically how it pertains to FPGAs? I
am but a humble embedded developer trying to make the kernel more useful
to myself (and hopefully others), and I think I might have a limited
worldview that restricts my ability to see the full picture and I would
like to learn.
^ permalink raw reply
* [PATCH] serial: 8250_of: Add reset support
From: Joel Stanley @ 2017-05-24 4:53 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rob Herring, Mark Rutland
Cc: linux-serial, devicetree, linux-kernel, Philipp Zabel
This adds the hooks for an optional reset controller in the 8250 device
tree node.
Signed-off-by: Joel Stanley <joel@jms.id.au>
---
Documentation/devicetree/bindings/serial/8250.txt | 1 +
drivers/tty/serial/8250/8250_of.c | 16 ++++++++++++++++
2 files changed, 17 insertions(+)
diff --git a/Documentation/devicetree/bindings/serial/8250.txt b/Documentation/devicetree/bindings/serial/8250.txt
index 10276a46ecef..63e32393f82b 100644
--- a/Documentation/devicetree/bindings/serial/8250.txt
+++ b/Documentation/devicetree/bindings/serial/8250.txt
@@ -45,6 +45,7 @@ Optional properties:
property.
- tx-threshold: Specify the TX FIFO low water indication for parts with
programmable TX FIFO thresholds.
+- resets : phandle + reset specifier pairs
Note:
* fsl,ns16550:
diff --git a/drivers/tty/serial/8250/8250_of.c b/drivers/tty/serial/8250/8250_of.c
index 1cbadafc6889..f34dd23376f4 100644
--- a/drivers/tty/serial/8250/8250_of.c
+++ b/drivers/tty/serial/8250/8250_of.c
@@ -19,11 +19,13 @@
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/clk.h>
+#include <linux/reset.h>
#include "8250.h"
struct of_serial_info {
struct clk *clk;
+ struct reset_control *rst;
int type;
int line;
};
@@ -132,6 +134,18 @@ static int of_platform_serial_setup(struct platform_device *ofdev,
}
}
+ info->rst = devm_reset_control_get_optional(&ofdev->dev, NULL);
+ if (IS_ERR(info->rst)) {
+ ret = PTR_ERR(info->rst);
+ if (ret == -EPROBE_DEFER)
+ goto out;
+ info->rst = NULL;
+ } else {
+ ret = reset_control_deassert(info->rst);
+ if (ret)
+ goto out;
+ }
+
port->type = type;
port->uartclk = clk;
port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP
@@ -231,6 +245,8 @@ static int of_platform_serial_remove(struct platform_device *ofdev)
if (info->clk)
clk_disable_unprepare(info->clk);
+ if (info->rst)
+ reset_control_assert(info->rst);
kfree(info);
return 0;
}
--
2.11.0
^ permalink raw reply related
* Re: [PATCH] serial: 8250_of: Add reset support
From: Philipp Zabel @ 2017-05-24 8:18 UTC (permalink / raw)
To: Joel Stanley
Cc: Greg Kroah-Hartman, Rob Herring, Mark Rutland,
linux-serial-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170524045319.29926-1-joel-U3u1mxZcP9KHXe+LvDLADg@public.gmane.org>
Hi Joel,
On Wed, 2017-05-24 at 14:53 +1000, Joel Stanley wrote:
> This adds the hooks for an optional reset controller in the 8250 device
> tree node.
>
> Signed-off-by: Joel Stanley <joel-U3u1mxZcP9KHXe+LvDLADg@public.gmane.org>
> ---
> Documentation/devicetree/bindings/serial/8250.txt | 1 +
> drivers/tty/serial/8250/8250_of.c | 16 ++++++++++++++++
> 2 files changed, 17 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/serial/8250.txt b/Documentation/devicetree/bindings/serial/8250.txt
> index 10276a46ecef..63e32393f82b 100644
> --- a/Documentation/devicetree/bindings/serial/8250.txt
> +++ b/Documentation/devicetree/bindings/serial/8250.txt
> @@ -45,6 +45,7 @@ Optional properties:
> property.
> - tx-threshold: Specify the TX FIFO low water indication for parts with
> programmable TX FIFO thresholds.
> +- resets : phandle + reset specifier pairs
>
> Note:
> * fsl,ns16550:
> diff --git a/drivers/tty/serial/8250/8250_of.c b/drivers/tty/serial/8250/8250_of.c
> index 1cbadafc6889..f34dd23376f4 100644
> --- a/drivers/tty/serial/8250/8250_of.c
> +++ b/drivers/tty/serial/8250/8250_of.c
> @@ -19,11 +19,13 @@
> #include <linux/of_irq.h>
> #include <linux/of_platform.h>
> #include <linux/clk.h>
> +#include <linux/reset.h>
>
> #include "8250.h"
>
> struct of_serial_info {
> struct clk *clk;
> + struct reset_control *rst;
> int type;
> int line;
> };
> @@ -132,6 +134,18 @@ static int of_platform_serial_setup(struct platform_device *ofdev,
> }
> }
>
> + info->rst = devm_reset_control_get_optional(&ofdev->dev, NULL);
Please use devm_reset_control_get_optional_shared instead.
This looks like shared (clock-like) reset use, where you just have to
make sure that the reset is deasserted while the module is in use, but
you don't care whether it is actually asserted all the time otherwise.
> + if (IS_ERR(info->rst)) {
> + ret = PTR_ERR(info->rst);
> + if (ret == -EPROBE_DEFER)
> + goto out;
> + info->rst = NULL;
devm_reset_control_get_optional returns NULL if no reset is specified in
the device tree specifically so we don't have to do this in all the
drivers. If an error is returned, just goto out unconditionally, ...
> + } else {
> + ret = reset_control_deassert(info->rst);
> + if (ret)
> + goto out;
> + }
... then reset_control_deassert can be called unconditionally, too.
> +
> port->type = type;
> port->uartclk = clk;
> port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP
> @@ -231,6 +245,8 @@ static int of_platform_serial_remove(struct platform_device *ofdev)
>
> if (info->clk)
> clk_disable_unprepare(info->clk);
> + if (info->rst)
Not necessary, reset_control_assert checks this, too.
> + reset_control_assert(info->rst);
> kfree(info);
> return 0;
> }
regards
Philipp
--
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 v6 net-next 17/17] net: qualcomm: add QCA7000 UART driver
From: Stefan Wahren @ 2017-05-24 9:06 UTC (permalink / raw)
To: Lino Sanfilippo, Rob Herring, Mark Rutland, David S. Miller
Cc: linux-serial, Jiri Slaby, Greg Kroah-Hartman, netdev,
linux-kernel, Jakub Kicinski, devicetree
In-Reply-To: <41c7302e-b25c-9f57-470a-dd95200a060f@gmx.de>
Am 23.05.2017 um 23:01 schrieb Lino Sanfilippo:
> On 23.05.2017 21:38, Stefan Wahren wrote:
>>> Lino Sanfilippo <LinoSanfilippo@gmx.de> hat am 23. Mai 2017 um 20:16 geschrieben:
>>>
>>> I suggest to avoid this possible race by first unregistering the netdevice and then
>>> calling cancel_work_sync().
>> What makes you sure that's safe to unregister the netdev while the tx work queue is possibly active?
> unregister_netdevice() calls netdev_close() if the interface is still up. netdev_close() calls flush_work()
> so the unregistration is delayed until the tx work function is finished. Furthermore both close() and
> tx work are synchronized by means of the qca->lock which also guarantees that unregister_netdevice() wont
> be finished until the tx work is done.
>
Thanks for the explanation. I suspect there could be the same race
between serdev_device_close() and the tx work queue.
So i would propose a variant of your original suggestion:
unregister_netdev(qca->net_dev);
/* Flush any pending characters in the driver. */
serdev_device_close(serdev);
cancel_work_sync(&qca->tx_work);
Since we have the same pattern in the error path of the probe function,
the same applies there.
Stefan
^ permalink raw reply
* [PATCH v7 net-next 17/17] net: qualcomm: add QCA7000 UART driver
From: Stefan Wahren @ 2017-05-24 9:29 UTC (permalink / raw)
To: Rob Herring, Mark Rutland, David S. Miller
Cc: Greg Kroah-Hartman, Jiri Slaby, Lino Sanfilippo, Jakub Kicinski,
devicetree-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
linux-serial-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Stefan Wahren
In-Reply-To: <50e5a442-777f-1516-4e94-16db7fa28f8b-eS4NqCHxEME@public.gmane.org>
This patch adds the Ethernet over UART driver for the
Qualcomm QCA7000 HomePlug GreenPHY.
Signed-off-by: Stefan Wahren <stefan.wahren-eS4NqCHxEME@public.gmane.org>
---
drivers/net/ethernet/qualcomm/Kconfig | 16 +
drivers/net/ethernet/qualcomm/Makefile | 2 +
drivers/net/ethernet/qualcomm/qca_7k_common.h | 6 +
drivers/net/ethernet/qualcomm/qca_uart.c | 423 ++++++++++++++++++++++++++
4 files changed, 447 insertions(+)
create mode 100644 drivers/net/ethernet/qualcomm/qca_uart.c
diff --git a/drivers/net/ethernet/qualcomm/Kconfig b/drivers/net/ethernet/qualcomm/Kconfig
index b4c369d..877675a 100644
--- a/drivers/net/ethernet/qualcomm/Kconfig
+++ b/drivers/net/ethernet/qualcomm/Kconfig
@@ -30,6 +30,22 @@ config QCA7000_SPI
To compile this driver as a module, choose M here. The module
will be called qcaspi.
+config QCA7000_UART
+ tristate "Qualcomm Atheros QCA7000 UART support"
+ select QCA7000
+ depends on SERIAL_DEV_BUS && OF
+ ---help---
+ This UART protocol driver supports the Qualcomm Atheros QCA7000.
+
+ Currently the driver assumes these device UART settings:
+ Data bits: 8
+ Parity: None
+ Stop bits: 1
+ Flow control: None
+
+ To compile this driver as a module, choose M here. The module
+ will be called qcauart.
+
config QCOM_EMAC
tristate "Qualcomm Technologies, Inc. EMAC Gigabit Ethernet support"
depends on HAS_DMA && HAS_IOMEM
diff --git a/drivers/net/ethernet/qualcomm/Makefile b/drivers/net/ethernet/qualcomm/Makefile
index 65556ca..92fa7c4 100644
--- a/drivers/net/ethernet/qualcomm/Makefile
+++ b/drivers/net/ethernet/qualcomm/Makefile
@@ -5,5 +5,7 @@
obj-$(CONFIG_QCA7000) += qca_7k_common.o
obj-$(CONFIG_QCA7000_SPI) += qcaspi.o
qcaspi-objs := qca_7k.o qca_debug.o qca_spi.o
+obj-$(CONFIG_QCA7000_UART) += qcauart.o
+qcauart-objs := qca_uart.o
obj-y += emac/
diff --git a/drivers/net/ethernet/qualcomm/qca_7k_common.h b/drivers/net/ethernet/qualcomm/qca_7k_common.h
index 07bdd6c..928554f 100644
--- a/drivers/net/ethernet/qualcomm/qca_7k_common.h
+++ b/drivers/net/ethernet/qualcomm/qca_7k_common.h
@@ -122,6 +122,12 @@ static inline void qcafrm_fsm_init_spi(struct qcafrm_handle *handle)
handle->state = handle->init;
}
+static inline void qcafrm_fsm_init_uart(struct qcafrm_handle *handle)
+{
+ handle->init = QCAFRM_WAIT_AA1;
+ handle->state = handle->init;
+}
+
/* Gather received bytes and try to extract a full Ethernet frame
* by following a simple state machine.
*
diff --git a/drivers/net/ethernet/qualcomm/qca_uart.c b/drivers/net/ethernet/qualcomm/qca_uart.c
new file mode 100644
index 0000000..db6068c
--- /dev/null
+++ b/drivers/net/ethernet/qualcomm/qca_uart.c
@@ -0,0 +1,423 @@
+/*
+ * Copyright (c) 2011, 2012, Qualcomm Atheros Communications Inc.
+ * Copyright (c) 2017, I2SE GmbH
+ *
+ * Permission to use, copy, modify, and/or distribute this software
+ * for any purpose with or without fee is hereby granted, provided
+ * that the above copyright notice and this permission notice appear
+ * in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* This module implements the Qualcomm Atheros UART protocol for
+ * kernel-based UART device; it is essentially an Ethernet-to-UART
+ * serial converter;
+ */
+
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/etherdevice.h>
+#include <linux/if_arp.h>
+#include <linux/if_ether.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_net.h>
+#include <linux/sched.h>
+#include <linux/serdev.h>
+#include <linux/skbuff.h>
+#include <linux/types.h>
+
+#include "qca_7k_common.h"
+
+#define QCAUART_DRV_VERSION "0.1.0"
+#define QCAUART_DRV_NAME "qcauart"
+#define QCAUART_TX_TIMEOUT (1 * HZ)
+
+struct qcauart {
+ struct net_device *net_dev;
+ spinlock_t lock; /* transmit lock */
+ struct work_struct tx_work; /* Flushes transmit buffer */
+
+ struct serdev_device *serdev;
+ struct qcafrm_handle frm_handle;
+ struct sk_buff *rx_skb;
+
+ unsigned char *tx_head; /* pointer to next XMIT byte */
+ int tx_left; /* bytes left in XMIT queue */
+ unsigned char *tx_buffer;
+};
+
+static int
+qca_tty_receive(struct serdev_device *serdev, const unsigned char *data,
+ size_t count)
+{
+ struct qcauart *qca = serdev_device_get_drvdata(serdev);
+ struct net_device *netdev = qca->net_dev;
+ struct net_device_stats *n_stats = &netdev->stats;
+ size_t i;
+
+ if (!qca->rx_skb) {
+ qca->rx_skb = netdev_alloc_skb_ip_align(netdev,
+ netdev->mtu +
+ VLAN_ETH_HLEN);
+ if (!qca->rx_skb) {
+ n_stats->rx_errors++;
+ n_stats->rx_dropped++;
+ return 0;
+ }
+ }
+
+ for (i = 0; i < count; i++) {
+ s32 retcode;
+
+ retcode = qcafrm_fsm_decode(&qca->frm_handle,
+ qca->rx_skb->data,
+ skb_tailroom(qca->rx_skb),
+ data[i]);
+
+ switch (retcode) {
+ case QCAFRM_GATHER:
+ case QCAFRM_NOHEAD:
+ break;
+ case QCAFRM_NOTAIL:
+ netdev_dbg(netdev, "recv: no RX tail\n");
+ n_stats->rx_errors++;
+ n_stats->rx_dropped++;
+ break;
+ case QCAFRM_INVLEN:
+ netdev_dbg(netdev, "recv: invalid RX length\n");
+ n_stats->rx_errors++;
+ n_stats->rx_dropped++;
+ break;
+ default:
+ n_stats->rx_packets++;
+ n_stats->rx_bytes += retcode;
+ skb_put(qca->rx_skb, retcode);
+ qca->rx_skb->protocol = eth_type_trans(
+ qca->rx_skb, qca->rx_skb->dev);
+ qca->rx_skb->ip_summed = CHECKSUM_UNNECESSARY;
+ netif_rx_ni(qca->rx_skb);
+ qca->rx_skb = netdev_alloc_skb_ip_align(netdev,
+ netdev->mtu +
+ VLAN_ETH_HLEN);
+ if (!qca->rx_skb) {
+ netdev_dbg(netdev, "recv: out of RX resources\n");
+ n_stats->rx_errors++;
+ return i;
+ }
+ }
+ }
+
+ return i;
+}
+
+/* Write out any remaining transmit buffer. Scheduled when tty is writable */
+static void qcauart_transmit(struct work_struct *work)
+{
+ struct qcauart *qca = container_of(work, struct qcauart, tx_work);
+ struct net_device_stats *n_stats = &qca->net_dev->stats;
+ int written;
+
+ spin_lock_bh(&qca->lock);
+
+ /* First make sure we're connected. */
+ if (!netif_running(qca->net_dev)) {
+ spin_unlock_bh(&qca->lock);
+ return;
+ }
+
+ if (qca->tx_left <= 0) {
+ /* Now serial buffer is almost free & we can start
+ * transmission of another packet
+ */
+ n_stats->tx_packets++;
+ spin_unlock_bh(&qca->lock);
+ netif_wake_queue(qca->net_dev);
+ return;
+ }
+
+ written = serdev_device_write_buf(qca->serdev, qca->tx_head,
+ qca->tx_left);
+ if (written > 0) {
+ qca->tx_left -= written;
+ qca->tx_head += written;
+ }
+ spin_unlock_bh(&qca->lock);
+}
+
+/* Called by the driver when there's room for more data.
+ * Schedule the transmit.
+ */
+static void qca_tty_wakeup(struct serdev_device *serdev)
+{
+ struct qcauart *qca = serdev_device_get_drvdata(serdev);
+
+ schedule_work(&qca->tx_work);
+}
+
+static struct serdev_device_ops qca_serdev_ops = {
+ .receive_buf = qca_tty_receive,
+ .write_wakeup = qca_tty_wakeup,
+};
+
+static int qcauart_netdev_open(struct net_device *dev)
+{
+ struct qcauart *qca = netdev_priv(dev);
+
+ netif_start_queue(qca->net_dev);
+
+ return 0;
+}
+
+static int qcauart_netdev_close(struct net_device *dev)
+{
+ struct qcauart *qca = netdev_priv(dev);
+
+ netif_stop_queue(dev);
+ flush_work(&qca->tx_work);
+
+ spin_lock_bh(&qca->lock);
+ qca->tx_left = 0;
+ spin_unlock_bh(&qca->lock);
+
+ return 0;
+}
+
+static netdev_tx_t
+qcauart_netdev_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct net_device_stats *n_stats = &dev->stats;
+ struct qcauart *qca = netdev_priv(dev);
+ u8 pad_len = 0;
+ int written;
+ u8 *pos;
+
+ spin_lock(&qca->lock);
+
+ WARN_ON(qca->tx_left);
+
+ if (!netif_running(dev)) {
+ spin_unlock(&qca->lock);
+ netdev_warn(qca->net_dev, "xmit: iface is down\n");
+ goto out;
+ }
+
+ pos = qca->tx_buffer;
+
+ if (skb->len < QCAFRM_MIN_LEN)
+ pad_len = QCAFRM_MIN_LEN - skb->len;
+
+ pos += qcafrm_create_header(pos, skb->len + pad_len);
+
+ memcpy(pos, skb->data, skb->len);
+ pos += skb->len;
+
+ if (pad_len) {
+ memset(pos, 0, pad_len);
+ pos += pad_len;
+ }
+
+ pos += qcafrm_create_footer(pos);
+
+ netif_stop_queue(qca->net_dev);
+
+ written = serdev_device_write_buf(qca->serdev, qca->tx_buffer,
+ pos - qca->tx_buffer);
+ if (written > 0) {
+ qca->tx_left = (pos - qca->tx_buffer) - written;
+ qca->tx_head = qca->tx_buffer + written;
+ n_stats->tx_bytes += written;
+ }
+ spin_unlock(&qca->lock);
+
+ netif_trans_update(dev);
+out:
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+}
+
+static void qcauart_netdev_tx_timeout(struct net_device *dev)
+{
+ struct qcauart *qca = netdev_priv(dev);
+
+ netdev_info(qca->net_dev, "Transmit timeout at %ld, latency %ld\n",
+ jiffies, dev_trans_start(dev));
+ dev->stats.tx_errors++;
+ dev->stats.tx_dropped++;
+}
+
+static int qcauart_netdev_init(struct net_device *dev)
+{
+ struct qcauart *qca = netdev_priv(dev);
+ size_t len;
+
+ /* Finish setting up the device info. */
+ dev->mtu = QCAFRM_MAX_MTU;
+ dev->type = ARPHRD_ETHER;
+
+ len = QCAFRM_HEADER_LEN + QCAFRM_MAX_LEN + QCAFRM_FOOTER_LEN;
+ qca->tx_buffer = devm_kmalloc(&qca->serdev->dev, len, GFP_KERNEL);
+ if (!qca->tx_buffer)
+ return -ENOMEM;
+
+ qca->rx_skb = netdev_alloc_skb_ip_align(qca->net_dev,
+ qca->net_dev->mtu +
+ VLAN_ETH_HLEN);
+ if (!qca->rx_skb)
+ return -ENOBUFS;
+
+ return 0;
+}
+
+static void qcauart_netdev_uninit(struct net_device *dev)
+{
+ struct qcauart *qca = netdev_priv(dev);
+
+ if (qca->rx_skb)
+ dev_kfree_skb(qca->rx_skb);
+}
+
+static const struct net_device_ops qcauart_netdev_ops = {
+ .ndo_init = qcauart_netdev_init,
+ .ndo_uninit = qcauart_netdev_uninit,
+ .ndo_open = qcauart_netdev_open,
+ .ndo_stop = qcauart_netdev_close,
+ .ndo_start_xmit = qcauart_netdev_xmit,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_tx_timeout = qcauart_netdev_tx_timeout,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
+static void qcauart_netdev_setup(struct net_device *dev)
+{
+ dev->netdev_ops = &qcauart_netdev_ops;
+ dev->watchdog_timeo = QCAUART_TX_TIMEOUT;
+ dev->priv_flags &= ~IFF_TX_SKB_SHARING;
+ dev->tx_queue_len = 100;
+
+ /* MTU range: 46 - 1500 */
+ dev->min_mtu = QCAFRM_MIN_MTU;
+ dev->max_mtu = QCAFRM_MAX_MTU;
+}
+
+static const struct of_device_id qca_uart_of_match[] = {
+ {
+ .compatible = "qca,qca7000",
+ },
+ {}
+};
+MODULE_DEVICE_TABLE(of, qca_uart_of_match);
+
+static int qca_uart_probe(struct serdev_device *serdev)
+{
+ struct net_device *qcauart_dev = alloc_etherdev(sizeof(struct qcauart));
+ struct qcauart *qca;
+ const char *mac;
+ u32 speed = 115200;
+ int ret;
+
+ if (!qcauart_dev)
+ return -ENOMEM;
+
+ qcauart_netdev_setup(qcauart_dev);
+ SET_NETDEV_DEV(qcauart_dev, &serdev->dev);
+
+ qca = netdev_priv(qcauart_dev);
+ if (!qca) {
+ pr_err("qca_uart: Fail to retrieve private structure\n");
+ ret = -ENOMEM;
+ goto free;
+ }
+ qca->net_dev = qcauart_dev;
+ qca->serdev = serdev;
+ qcafrm_fsm_init_uart(&qca->frm_handle);
+
+ spin_lock_init(&qca->lock);
+ INIT_WORK(&qca->tx_work, qcauart_transmit);
+
+ of_property_read_u32(serdev->dev.of_node, "current-speed", &speed);
+
+ mac = of_get_mac_address(serdev->dev.of_node);
+
+ if (mac)
+ ether_addr_copy(qca->net_dev->dev_addr, mac);
+
+ if (!is_valid_ether_addr(qca->net_dev->dev_addr)) {
+ eth_hw_addr_random(qca->net_dev);
+ dev_info(&serdev->dev, "Using random MAC address: %pM\n",
+ qca->net_dev->dev_addr);
+ }
+
+ netif_carrier_on(qca->net_dev);
+ serdev_device_set_drvdata(serdev, qca);
+ serdev_device_set_client_ops(serdev, &qca_serdev_ops);
+
+ ret = serdev_device_open(serdev);
+ if (ret) {
+ dev_err(&serdev->dev, "Unable to open device %s\n",
+ qcauart_dev->name);
+ goto free;
+ }
+
+ speed = serdev_device_set_baudrate(serdev, speed);
+ dev_info(&serdev->dev, "Using baudrate: %u\n", speed);
+
+ serdev_device_set_flow_control(serdev, false);
+
+ ret = register_netdev(qcauart_dev);
+ if (ret) {
+ dev_err(&serdev->dev, "Unable to register net device %s\n",
+ qcauart_dev->name);
+ serdev_device_close(serdev);
+ cancel_work_sync(&qca->tx_work);
+ goto free;
+ }
+
+ return 0;
+
+free:
+ free_netdev(qcauart_dev);
+ return ret;
+}
+
+static void qca_uart_remove(struct serdev_device *serdev)
+{
+ struct qcauart *qca = serdev_device_get_drvdata(serdev);
+
+ unregister_netdev(qca->net_dev);
+
+ /* Flush any pending characters in the driver. */
+ serdev_device_close(serdev);
+ cancel_work_sync(&qca->tx_work);
+
+ free_netdev(qca->net_dev);
+}
+
+static struct serdev_device_driver qca_uart_driver = {
+ .probe = qca_uart_probe,
+ .remove = qca_uart_remove,
+ .driver = {
+ .name = QCAUART_DRV_NAME,
+ .of_match_table = of_match_ptr(qca_uart_of_match),
+ },
+};
+
+module_serdev_device_driver(qca_uart_driver);
+
+MODULE_DESCRIPTION("Qualcomm Atheros QCA7000 UART Driver");
+MODULE_AUTHOR("Qualcomm Atheros Communications");
+MODULE_AUTHOR("Stefan Wahren <stefan.wahren-eS4NqCHxEME@public.gmane.org>");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_VERSION(QCAUART_DRV_VERSION);
--
2.1.4
--
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 RESEND v7 net-next 17/17] net: qualcomm: add QCA7000 UART driver
From: Stefan Wahren @ 2017-05-24 9:32 UTC (permalink / raw)
To: Rob Herring, Mark Rutland, David S. Miller
Cc: Greg Kroah-Hartman, Jiri Slaby, Lino Sanfilippo, Jakub Kicinski,
devicetree, netdev, linux-serial, linux-kernel, Stefan Wahren
In-Reply-To: <50e5a442-777f-1516-4e94-16db7fa28f8b@i2se.com>
This patch adds the Ethernet over UART driver for the
Qualcomm QCA7000 HomePlug GreenPHY.
Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
---
drivers/net/ethernet/qualcomm/Kconfig | 16 +
drivers/net/ethernet/qualcomm/Makefile | 2 +
drivers/net/ethernet/qualcomm/qca_7k_common.h | 6 +
drivers/net/ethernet/qualcomm/qca_uart.c | 423 ++++++++++++++++++++++++++
4 files changed, 447 insertions(+)
create mode 100644 drivers/net/ethernet/qualcomm/qca_uart.c
Changes in v7:
* fix race between tx workqueue and device deregistration (reported by Lino)
diff --git a/drivers/net/ethernet/qualcomm/Kconfig b/drivers/net/ethernet/qualcomm/Kconfig
index b4c369d..877675a 100644
--- a/drivers/net/ethernet/qualcomm/Kconfig
+++ b/drivers/net/ethernet/qualcomm/Kconfig
@@ -30,6 +30,22 @@ config QCA7000_SPI
To compile this driver as a module, choose M here. The module
will be called qcaspi.
+config QCA7000_UART
+ tristate "Qualcomm Atheros QCA7000 UART support"
+ select QCA7000
+ depends on SERIAL_DEV_BUS && OF
+ ---help---
+ This UART protocol driver supports the Qualcomm Atheros QCA7000.
+
+ Currently the driver assumes these device UART settings:
+ Data bits: 8
+ Parity: None
+ Stop bits: 1
+ Flow control: None
+
+ To compile this driver as a module, choose M here. The module
+ will be called qcauart.
+
config QCOM_EMAC
tristate "Qualcomm Technologies, Inc. EMAC Gigabit Ethernet support"
depends on HAS_DMA && HAS_IOMEM
diff --git a/drivers/net/ethernet/qualcomm/Makefile b/drivers/net/ethernet/qualcomm/Makefile
index 65556ca..92fa7c4 100644
--- a/drivers/net/ethernet/qualcomm/Makefile
+++ b/drivers/net/ethernet/qualcomm/Makefile
@@ -5,5 +5,7 @@
obj-$(CONFIG_QCA7000) += qca_7k_common.o
obj-$(CONFIG_QCA7000_SPI) += qcaspi.o
qcaspi-objs := qca_7k.o qca_debug.o qca_spi.o
+obj-$(CONFIG_QCA7000_UART) += qcauart.o
+qcauart-objs := qca_uart.o
obj-y += emac/
diff --git a/drivers/net/ethernet/qualcomm/qca_7k_common.h b/drivers/net/ethernet/qualcomm/qca_7k_common.h
index 07bdd6c..928554f 100644
--- a/drivers/net/ethernet/qualcomm/qca_7k_common.h
+++ b/drivers/net/ethernet/qualcomm/qca_7k_common.h
@@ -122,6 +122,12 @@ static inline void qcafrm_fsm_init_spi(struct qcafrm_handle *handle)
handle->state = handle->init;
}
+static inline void qcafrm_fsm_init_uart(struct qcafrm_handle *handle)
+{
+ handle->init = QCAFRM_WAIT_AA1;
+ handle->state = handle->init;
+}
+
/* Gather received bytes and try to extract a full Ethernet frame
* by following a simple state machine.
*
diff --git a/drivers/net/ethernet/qualcomm/qca_uart.c b/drivers/net/ethernet/qualcomm/qca_uart.c
new file mode 100644
index 0000000..db6068c
--- /dev/null
+++ b/drivers/net/ethernet/qualcomm/qca_uart.c
@@ -0,0 +1,423 @@
+/*
+ * Copyright (c) 2011, 2012, Qualcomm Atheros Communications Inc.
+ * Copyright (c) 2017, I2SE GmbH
+ *
+ * Permission to use, copy, modify, and/or distribute this software
+ * for any purpose with or without fee is hereby granted, provided
+ * that the above copyright notice and this permission notice appear
+ * in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* This module implements the Qualcomm Atheros UART protocol for
+ * kernel-based UART device; it is essentially an Ethernet-to-UART
+ * serial converter;
+ */
+
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/etherdevice.h>
+#include <linux/if_arp.h>
+#include <linux/if_ether.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_net.h>
+#include <linux/sched.h>
+#include <linux/serdev.h>
+#include <linux/skbuff.h>
+#include <linux/types.h>
+
+#include "qca_7k_common.h"
+
+#define QCAUART_DRV_VERSION "0.1.0"
+#define QCAUART_DRV_NAME "qcauart"
+#define QCAUART_TX_TIMEOUT (1 * HZ)
+
+struct qcauart {
+ struct net_device *net_dev;
+ spinlock_t lock; /* transmit lock */
+ struct work_struct tx_work; /* Flushes transmit buffer */
+
+ struct serdev_device *serdev;
+ struct qcafrm_handle frm_handle;
+ struct sk_buff *rx_skb;
+
+ unsigned char *tx_head; /* pointer to next XMIT byte */
+ int tx_left; /* bytes left in XMIT queue */
+ unsigned char *tx_buffer;
+};
+
+static int
+qca_tty_receive(struct serdev_device *serdev, const unsigned char *data,
+ size_t count)
+{
+ struct qcauart *qca = serdev_device_get_drvdata(serdev);
+ struct net_device *netdev = qca->net_dev;
+ struct net_device_stats *n_stats = &netdev->stats;
+ size_t i;
+
+ if (!qca->rx_skb) {
+ qca->rx_skb = netdev_alloc_skb_ip_align(netdev,
+ netdev->mtu +
+ VLAN_ETH_HLEN);
+ if (!qca->rx_skb) {
+ n_stats->rx_errors++;
+ n_stats->rx_dropped++;
+ return 0;
+ }
+ }
+
+ for (i = 0; i < count; i++) {
+ s32 retcode;
+
+ retcode = qcafrm_fsm_decode(&qca->frm_handle,
+ qca->rx_skb->data,
+ skb_tailroom(qca->rx_skb),
+ data[i]);
+
+ switch (retcode) {
+ case QCAFRM_GATHER:
+ case QCAFRM_NOHEAD:
+ break;
+ case QCAFRM_NOTAIL:
+ netdev_dbg(netdev, "recv: no RX tail\n");
+ n_stats->rx_errors++;
+ n_stats->rx_dropped++;
+ break;
+ case QCAFRM_INVLEN:
+ netdev_dbg(netdev, "recv: invalid RX length\n");
+ n_stats->rx_errors++;
+ n_stats->rx_dropped++;
+ break;
+ default:
+ n_stats->rx_packets++;
+ n_stats->rx_bytes += retcode;
+ skb_put(qca->rx_skb, retcode);
+ qca->rx_skb->protocol = eth_type_trans(
+ qca->rx_skb, qca->rx_skb->dev);
+ qca->rx_skb->ip_summed = CHECKSUM_UNNECESSARY;
+ netif_rx_ni(qca->rx_skb);
+ qca->rx_skb = netdev_alloc_skb_ip_align(netdev,
+ netdev->mtu +
+ VLAN_ETH_HLEN);
+ if (!qca->rx_skb) {
+ netdev_dbg(netdev, "recv: out of RX resources\n");
+ n_stats->rx_errors++;
+ return i;
+ }
+ }
+ }
+
+ return i;
+}
+
+/* Write out any remaining transmit buffer. Scheduled when tty is writable */
+static void qcauart_transmit(struct work_struct *work)
+{
+ struct qcauart *qca = container_of(work, struct qcauart, tx_work);
+ struct net_device_stats *n_stats = &qca->net_dev->stats;
+ int written;
+
+ spin_lock_bh(&qca->lock);
+
+ /* First make sure we're connected. */
+ if (!netif_running(qca->net_dev)) {
+ spin_unlock_bh(&qca->lock);
+ return;
+ }
+
+ if (qca->tx_left <= 0) {
+ /* Now serial buffer is almost free & we can start
+ * transmission of another packet
+ */
+ n_stats->tx_packets++;
+ spin_unlock_bh(&qca->lock);
+ netif_wake_queue(qca->net_dev);
+ return;
+ }
+
+ written = serdev_device_write_buf(qca->serdev, qca->tx_head,
+ qca->tx_left);
+ if (written > 0) {
+ qca->tx_left -= written;
+ qca->tx_head += written;
+ }
+ spin_unlock_bh(&qca->lock);
+}
+
+/* Called by the driver when there's room for more data.
+ * Schedule the transmit.
+ */
+static void qca_tty_wakeup(struct serdev_device *serdev)
+{
+ struct qcauart *qca = serdev_device_get_drvdata(serdev);
+
+ schedule_work(&qca->tx_work);
+}
+
+static struct serdev_device_ops qca_serdev_ops = {
+ .receive_buf = qca_tty_receive,
+ .write_wakeup = qca_tty_wakeup,
+};
+
+static int qcauart_netdev_open(struct net_device *dev)
+{
+ struct qcauart *qca = netdev_priv(dev);
+
+ netif_start_queue(qca->net_dev);
+
+ return 0;
+}
+
+static int qcauart_netdev_close(struct net_device *dev)
+{
+ struct qcauart *qca = netdev_priv(dev);
+
+ netif_stop_queue(dev);
+ flush_work(&qca->tx_work);
+
+ spin_lock_bh(&qca->lock);
+ qca->tx_left = 0;
+ spin_unlock_bh(&qca->lock);
+
+ return 0;
+}
+
+static netdev_tx_t
+qcauart_netdev_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct net_device_stats *n_stats = &dev->stats;
+ struct qcauart *qca = netdev_priv(dev);
+ u8 pad_len = 0;
+ int written;
+ u8 *pos;
+
+ spin_lock(&qca->lock);
+
+ WARN_ON(qca->tx_left);
+
+ if (!netif_running(dev)) {
+ spin_unlock(&qca->lock);
+ netdev_warn(qca->net_dev, "xmit: iface is down\n");
+ goto out;
+ }
+
+ pos = qca->tx_buffer;
+
+ if (skb->len < QCAFRM_MIN_LEN)
+ pad_len = QCAFRM_MIN_LEN - skb->len;
+
+ pos += qcafrm_create_header(pos, skb->len + pad_len);
+
+ memcpy(pos, skb->data, skb->len);
+ pos += skb->len;
+
+ if (pad_len) {
+ memset(pos, 0, pad_len);
+ pos += pad_len;
+ }
+
+ pos += qcafrm_create_footer(pos);
+
+ netif_stop_queue(qca->net_dev);
+
+ written = serdev_device_write_buf(qca->serdev, qca->tx_buffer,
+ pos - qca->tx_buffer);
+ if (written > 0) {
+ qca->tx_left = (pos - qca->tx_buffer) - written;
+ qca->tx_head = qca->tx_buffer + written;
+ n_stats->tx_bytes += written;
+ }
+ spin_unlock(&qca->lock);
+
+ netif_trans_update(dev);
+out:
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+}
+
+static void qcauart_netdev_tx_timeout(struct net_device *dev)
+{
+ struct qcauart *qca = netdev_priv(dev);
+
+ netdev_info(qca->net_dev, "Transmit timeout at %ld, latency %ld\n",
+ jiffies, dev_trans_start(dev));
+ dev->stats.tx_errors++;
+ dev->stats.tx_dropped++;
+}
+
+static int qcauart_netdev_init(struct net_device *dev)
+{
+ struct qcauart *qca = netdev_priv(dev);
+ size_t len;
+
+ /* Finish setting up the device info. */
+ dev->mtu = QCAFRM_MAX_MTU;
+ dev->type = ARPHRD_ETHER;
+
+ len = QCAFRM_HEADER_LEN + QCAFRM_MAX_LEN + QCAFRM_FOOTER_LEN;
+ qca->tx_buffer = devm_kmalloc(&qca->serdev->dev, len, GFP_KERNEL);
+ if (!qca->tx_buffer)
+ return -ENOMEM;
+
+ qca->rx_skb = netdev_alloc_skb_ip_align(qca->net_dev,
+ qca->net_dev->mtu +
+ VLAN_ETH_HLEN);
+ if (!qca->rx_skb)
+ return -ENOBUFS;
+
+ return 0;
+}
+
+static void qcauart_netdev_uninit(struct net_device *dev)
+{
+ struct qcauart *qca = netdev_priv(dev);
+
+ if (qca->rx_skb)
+ dev_kfree_skb(qca->rx_skb);
+}
+
+static const struct net_device_ops qcauart_netdev_ops = {
+ .ndo_init = qcauart_netdev_init,
+ .ndo_uninit = qcauart_netdev_uninit,
+ .ndo_open = qcauart_netdev_open,
+ .ndo_stop = qcauart_netdev_close,
+ .ndo_start_xmit = qcauart_netdev_xmit,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_tx_timeout = qcauart_netdev_tx_timeout,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
+static void qcauart_netdev_setup(struct net_device *dev)
+{
+ dev->netdev_ops = &qcauart_netdev_ops;
+ dev->watchdog_timeo = QCAUART_TX_TIMEOUT;
+ dev->priv_flags &= ~IFF_TX_SKB_SHARING;
+ dev->tx_queue_len = 100;
+
+ /* MTU range: 46 - 1500 */
+ dev->min_mtu = QCAFRM_MIN_MTU;
+ dev->max_mtu = QCAFRM_MAX_MTU;
+}
+
+static const struct of_device_id qca_uart_of_match[] = {
+ {
+ .compatible = "qca,qca7000",
+ },
+ {}
+};
+MODULE_DEVICE_TABLE(of, qca_uart_of_match);
+
+static int qca_uart_probe(struct serdev_device *serdev)
+{
+ struct net_device *qcauart_dev = alloc_etherdev(sizeof(struct qcauart));
+ struct qcauart *qca;
+ const char *mac;
+ u32 speed = 115200;
+ int ret;
+
+ if (!qcauart_dev)
+ return -ENOMEM;
+
+ qcauart_netdev_setup(qcauart_dev);
+ SET_NETDEV_DEV(qcauart_dev, &serdev->dev);
+
+ qca = netdev_priv(qcauart_dev);
+ if (!qca) {
+ pr_err("qca_uart: Fail to retrieve private structure\n");
+ ret = -ENOMEM;
+ goto free;
+ }
+ qca->net_dev = qcauart_dev;
+ qca->serdev = serdev;
+ qcafrm_fsm_init_uart(&qca->frm_handle);
+
+ spin_lock_init(&qca->lock);
+ INIT_WORK(&qca->tx_work, qcauart_transmit);
+
+ of_property_read_u32(serdev->dev.of_node, "current-speed", &speed);
+
+ mac = of_get_mac_address(serdev->dev.of_node);
+
+ if (mac)
+ ether_addr_copy(qca->net_dev->dev_addr, mac);
+
+ if (!is_valid_ether_addr(qca->net_dev->dev_addr)) {
+ eth_hw_addr_random(qca->net_dev);
+ dev_info(&serdev->dev, "Using random MAC address: %pM\n",
+ qca->net_dev->dev_addr);
+ }
+
+ netif_carrier_on(qca->net_dev);
+ serdev_device_set_drvdata(serdev, qca);
+ serdev_device_set_client_ops(serdev, &qca_serdev_ops);
+
+ ret = serdev_device_open(serdev);
+ if (ret) {
+ dev_err(&serdev->dev, "Unable to open device %s\n",
+ qcauart_dev->name);
+ goto free;
+ }
+
+ speed = serdev_device_set_baudrate(serdev, speed);
+ dev_info(&serdev->dev, "Using baudrate: %u\n", speed);
+
+ serdev_device_set_flow_control(serdev, false);
+
+ ret = register_netdev(qcauart_dev);
+ if (ret) {
+ dev_err(&serdev->dev, "Unable to register net device %s\n",
+ qcauart_dev->name);
+ serdev_device_close(serdev);
+ cancel_work_sync(&qca->tx_work);
+ goto free;
+ }
+
+ return 0;
+
+free:
+ free_netdev(qcauart_dev);
+ return ret;
+}
+
+static void qca_uart_remove(struct serdev_device *serdev)
+{
+ struct qcauart *qca = serdev_device_get_drvdata(serdev);
+
+ unregister_netdev(qca->net_dev);
+
+ /* Flush any pending characters in the driver. */
+ serdev_device_close(serdev);
+ cancel_work_sync(&qca->tx_work);
+
+ free_netdev(qca->net_dev);
+}
+
+static struct serdev_device_driver qca_uart_driver = {
+ .probe = qca_uart_probe,
+ .remove = qca_uart_remove,
+ .driver = {
+ .name = QCAUART_DRV_NAME,
+ .of_match_table = of_match_ptr(qca_uart_of_match),
+ },
+};
+
+module_serdev_device_driver(qca_uart_driver);
+
+MODULE_DESCRIPTION("Qualcomm Atheros QCA7000 UART Driver");
+MODULE_AUTHOR("Qualcomm Atheros Communications");
+MODULE_AUTHOR("Stefan Wahren <stefan.wahren@i2se.com>");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_VERSION(QCAUART_DRV_VERSION);
--
2.1.4
^ permalink raw reply related
* CPU_BIG_ENDIAN in generic code (was: Re: [PATCH v3 3/7] arch/sparc: Define config parameter CPU_BIG_ENDIAN)
From: Geert Uytterhoeven @ 2017-05-24 9:59 UTC (permalink / raw)
To: Babu Moger
Cc: David S. Miller, Peter Zijlstra, Ingo Molnar, Arnd Bergmann,
sparclinux, linux-kernel@vger.kernel.org, Linux-Arch,
devicetree@vger.kernel.org, linux-serial@vger.kernel.org
On Tue, May 23, 2017 at 11:45 PM, Babu Moger <babu.moger@oracle.com> wrote:
> Found this problem while enabling queued rwlock on SPARC.
> The parameter CONFIG_CPU_BIG_ENDIAN is used to clear the
> specific byte in qrwlock structure. Without this parameter,
> we clear the wrong byte. Here is the code.
>
> static inline u8 *__qrwlock_write_byte(struct qrwlock *lock)
> {
> return (u8 *)lock + 3 * IS_BUILTIN(CONFIG_CPU_BIG_ENDIAN);
> }
>
> Define CPU_BIG_ENDIAN for SPARC to fix it.
> --- a/arch/sparc/Kconfig
> +++ b/arch/sparc/Kconfig
> @@ -92,6 +92,10 @@ config ARCH_DEFCONFIG
> config ARCH_PROC_KCORE_TEXT
> def_bool y
>
> +config CPU_BIG_ENDIAN
> + bool
> + default y if SPARC
Nice catch!
Traditionally, CPU_BIG_ENDIAN and CPU_LITTLE_ENDIAN were defined only on
architectures that may support both. And it was checked in platform code
and drivers only.
Hence the symbol is lacking from most architectures. Heck, even
architectures that support both may default to one endiannes, and declare
only the symbol for the other endianness:
--- arch/alpha ---
--- arch/arc ---
arch/arc/Kconfig:config CPU_BIG_ENDIAN
--- arch/arm ---
arch/arm/mm/Kconfig:config CPU_BIG_ENDIAN
--- arch/arm64 ---
arch/arm64/Kconfig:config CPU_BIG_ENDIAN
--- arch/blackfin ---
--- arch/c6x ---
arch/c6x/Kconfig:config CPU_BIG_ENDIAN
--- arch/cris ---
--- arch/frv ---
--- arch/h8300 ---
--- arch/hexagon ---
--- arch/ia64 ---
--- arch/Kconfig ---
--- arch/m32r ---
arch/m32r/Kconfig:config CPU_LITTLE_ENDIAN
--- arch/m68k ---
--- arch/metag ---
--- arch/microblaze ---
--- arch/mips ---
arch/mips/Kconfig:config CPU_BIG_ENDIAN
arch/mips/Kconfig:config CPU_LITTLE_ENDIAN
--- arch/mn10300 ---
--- arch/nios2 ---
--- arch/openrisc ---
--- arch/parisc ---
--- arch/powerpc ---
arch/powerpc/platforms/Kconfig.cputype:config CPU_BIG_ENDIAN
arch/powerpc/platforms/Kconfig.cputype:config CPU_LITTLE_ENDIAN
--- arch/s390 ---
arch/s390/Kconfig:config CPU_BIG_ENDIAN
--- arch/score ---
--- arch/sh ---
arch/sh/Kconfig.cpu:config CPU_LITTLE_ENDIAN
arch/sh/Kconfig.cpu:config CPU_BIG_ENDIAN
--- arch/sparc ---
--- arch/tile ---
--- arch/um ---
--- arch/unicore32 ---
--- arch/x86 ---
--- arch/xtensa ---
However, there are already a few users in generic code, which are thus
broken on many platforms:
drivers/of/base.c
drivers/of/fdt.c
drivers/tty/serial/earlycon.c
drivers/tty/serial/serial_core.c
include/asm-generic/qrwlock.h is also generic, but depends on the
architecture to select ARCH_USE_QUEUED_RWLOCKS, which only very few do
(x86, and now sparc).
I guess the time is ripe for adding (both) symbols to all architectures?
Gr{oetje,eeting}s,
Geert
^ permalink raw reply
* Re: CPU_BIG_ENDIAN in generic code (was: Re: [PATCH v3 3/7] arch/sparc: Define config parameter CPU_BIG_ENDIAN)
From: Arnd Bergmann @ 2017-05-24 10:18 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Babu Moger, David S. Miller, Peter Zijlstra, Ingo Molnar,
sparclinux, linux-kernel@vger.kernel.org, Linux-Arch,
devicetree@vger.kernel.org, linux-serial@vger.kernel.org
In-Reply-To: <CAMuHMdVjh+1TR19mUUQYHSazHnBHa4uxn7KyHUO+jAh7WDxy5Q@mail.gmail.com>
On Wed, May 24, 2017 at 11:59 AM, Geert Uytterhoeven
<geert@linux-m68k.org> wrote:
> On Tue, May 23, 2017 at 11:45 PM, Babu Moger <babu.moger@oracle.com> wrote:
>> Found this problem while enabling queued rwlock on SPARC.
>> The parameter CONFIG_CPU_BIG_ENDIAN is used to clear the
>> specific byte in qrwlock structure. Without this parameter,
>> we clear the wrong byte. Here is the code.
>>
>> static inline u8 *__qrwlock_write_byte(struct qrwlock *lock)
>> {
>> return (u8 *)lock + 3 * IS_BUILTIN(CONFIG_CPU_BIG_ENDIAN);
>> }
>>
>> Define CPU_BIG_ENDIAN for SPARC to fix it.
>
>> --- a/arch/sparc/Kconfig
>> +++ b/arch/sparc/Kconfig
>> @@ -92,6 +92,10 @@ config ARCH_DEFCONFIG
>> config ARCH_PROC_KCORE_TEXT
>> def_bool y
>>
>> +config CPU_BIG_ENDIAN
>> + bool
>> + default y if SPARC
>
> Nice catch!
>
> Traditionally, CPU_BIG_ENDIAN and CPU_LITTLE_ENDIAN were defined only on
> architectures that may support both. And it was checked in platform code
> and drivers only.
> Hence the symbol is lacking from most architectures. Heck, even
> architectures that support both may default to one endiannes, and declare
> only the symbol for the other endianness:
>
> --- arch/alpha ---
> --- arch/arc ---
> arch/arc/Kconfig:config CPU_BIG_ENDIAN
> --- arch/arm ---
> arch/arm/mm/Kconfig:config CPU_BIG_ENDIAN
> --- arch/arm64 ---
> arch/arm64/Kconfig:config CPU_BIG_ENDIAN
> --- arch/blackfin ---
> --- arch/c6x ---
> arch/c6x/Kconfig:config CPU_BIG_ENDIAN
> --- arch/cris ---
> --- arch/frv ---
> --- arch/h8300 ---
> --- arch/hexagon ---
> --- arch/ia64 ---
> --- arch/Kconfig ---
> --- arch/m32r ---
> arch/m32r/Kconfig:config CPU_LITTLE_ENDIAN
> --- arch/m68k ---
> --- arch/metag ---
> --- arch/microblaze ---
> --- arch/mips ---
> arch/mips/Kconfig:config CPU_BIG_ENDIAN
> arch/mips/Kconfig:config CPU_LITTLE_ENDIAN
> --- arch/mn10300 ---
> --- arch/nios2 ---
> --- arch/openrisc ---
> --- arch/parisc ---
> --- arch/powerpc ---
> arch/powerpc/platforms/Kconfig.cputype:config CPU_BIG_ENDIAN
> arch/powerpc/platforms/Kconfig.cputype:config CPU_LITTLE_ENDIAN
> --- arch/s390 ---
> arch/s390/Kconfig:config CPU_BIG_ENDIAN
> --- arch/score ---
> --- arch/sh ---
> arch/sh/Kconfig.cpu:config CPU_LITTLE_ENDIAN
> arch/sh/Kconfig.cpu:config CPU_BIG_ENDIAN
> --- arch/sparc ---
> --- arch/tile ---
> --- arch/um ---
> --- arch/unicore32 ---
> --- arch/x86 ---
> --- arch/xtensa ---
>
> However, there are already a few users in generic code, which are thus
> broken on many platforms:
>
> drivers/of/base.c
> drivers/of/fdt.c
> drivers/tty/serial/earlycon.c
> drivers/tty/serial/serial_core.c
>
> include/asm-generic/qrwlock.h is also generic, but depends on the
> architecture to select ARCH_USE_QUEUED_RWLOCKS, which only very few do
> (x86, and now sparc).
>
> I guess the time is ripe for adding (both) symbols to all architectures?
Good idea. I think we can do most of this by adding a few lines to
arch/Kconfig:
config CPU_BIG_ENDIAN
bool
config CPU_LITTLE_ENDIAN
def_bool !CPU_BIG_ENDIAN
This way, we only need to add 'select CPU_BIG_ENDIAN' to the
architectures that are always big-endian, and we don't need to
change anything for the ones that have a single 'CPU_BIG_ENDIAN'
option.
The three architectures that have a 'choice' statement (mips, ppc and
sh) will have to convert, and m32r will have to replace the
option with the opposite one, which could break 'make oldconfig',
but nobody really cares about m32r any more.
Arnd
^ permalink raw reply
* RE: [PATCH V1] serial: imx: revert setup DCEDTE early and ensure DCD and RI irqs to be off
From: Steve Twiss @ 2017-05-24 10:28 UTC (permalink / raw)
To: Uwe Kleine-König
Cc: Greg Kroah-Hartman, Jiri Slaby, LINUX-KERNEL, LINUX-SERIAL,
Lucas Stach, Support Opensource, kernel@pengutronix.de
In-Reply-To: <20170523160845.wli3z4ukcy5uquzz@pengutronix.de>
Hi Uwe,
On 23 May 2017 17:09, Uwe Kleine-König wrote:
> On Tue, May 23, 2017 at 03:01:26PM +0000, Steve Twiss wrote:
> > On 23 May 2017 15:37, Uwe Kleine-König wrote:
> > > Subject: Re: [PATCH V1] serial: imx: revert setup DCEDTE early and ensure DCD and RI irqs to be off
> > > On Tue, May 23, 2017 at 02:28:11PM +0000, Steve Twiss wrote:
> > > > On 23 May 2017 15:10, Uwe Kleine-König wrote:
> > > > > On Tue, May 23, 2017 at 01:17:26PM +0100, Steve Twiss wrote:
> > > > > >
> > > > > > Revert the commit e61c38d85b7392e ("serial: imx: setup DCEDTE early and
> > > > > > ensure DCD and RI irqs to be off")
> > > > > > The patch submitted to setup DCEDTE early and ensure DCD and RI irqs to
> > > > > > be off, causes a serial console display problem the i.MX6Q SABRESD board.
> > > > > > The console becomes unreadable and unwritable.
> > > > > >
> > > > > > Tested-by: Steve Twiss <stwiss.opensource@diasemi.com>
> > > > > > Signed-off-by: Steve Twiss <stwiss.opensource@diasemi.com>
> > > > >
> > > > > You're not the first to report this issue but you still have the chance
> > > > > to be the first to test a suggested patch for it.
> > > >
> > > > I've just applied your patch against a clean linux-next/v4.12-rc2
> > > > I added your patch ...
> > > >
> > > > > http://marc.info/?l=linux-serial&m=149434029912947&w=2
> > > >
> > [...]
> > > > I've added that to my working directory, but I am still seeing the corrupted
> > > > console output on the i.MX6 Q (quad) board.
> > >
> > > I don't have a failing board (I think). So here are a few questions
> > > about yours:
> > >
> > > - how does the dts snippet for your failing device look like?
> >
> > I am using the standard DTS from the v4.12-rc2 kernel, no changes.
> > I did an earlier test yesterday using the DTS from v4.11 to see if it was the new
> > imx7 changes that have recently gone into the kernel but I still see the same
> > effect.
> >
> > > - This is not the device the console runs on, right?
> >
> > I am connected through the USB to UART, U22 on the i.MX6Q board.
> > Terminal set to 115200 baud, no parity, 8bit data.
> >
> > > - Can you initialize the device in the bootloader and check if it is working
> there?
> >
> > I can get U-boot ok for all cases.
> > Once I TFTP the kernel across, I am okay until I get to "Starting kernel ...",
> > then, the UART is "working" in the sense that I get the some characters in the style
> > of the kernel starting up, but they are all garbled.
> >
> > I expect the kernel has started ok, but I am unable to read/write through the UART
> > console because of corruptions.
> >
> > Console log:
> > --- 8< ---
[...]
> > Starting kernel ...
> >
> à\x1cü\x1cü\x1cpþ\x1càüþü\x1cà\x1càà\x1càüþü\x1c\x1c\x1c\x1càüü\x1cþü\x1cà\x1cü\x1cà\x1cà\x1càüŽ\x1c\x1càü\x1càü\x1c\x1c\x1c\x1c\x1càà\x1c
[...]
>
> did you check with an oscilloscope if the baud rate is as expected (hmm,
> but I wouldn't expect my patch to change the baud rate).
I did try several different baudrates on the terminal connection, but I didn't find any
that worked. I've only checked the obvious ones however. I have not tried to debug
this problem any further than diagnosing what kernel commit caused the difference.
We also swapped compilers to begin with, when the first investigation began.
I noticed kernelci.org had some i.MX sabre boards, but used a different compiler
and did not see any problem.
Swapping the compiler made no difference and led us to find it only happened
on the i.MX6Q not the i.MX6DL. The kernelci.org site does not test any i.MX6Q
boards.
> > > - Does it make a difference in Linux if the bootloader used the device before?
> >
> > If you mean, if U-boot uses the UART console before loading the kernel, then no.
> > Is that what you mean?
>
> I didn't expect that it destroys the console UART so I expected that you
> can make use of a 2nd UART in U-Boot somehow to already initialize the
> port and check if that makes it magically work in Linux.
>
> Note to myself: So we're taking about the UART at 0x02020000, it is
> operated in DCE mode.
> > It makes no difference until the kernel is loaded, then the serial
> > output gets corrupted.
> >
> > > - Can you dump the register space of the uart with v4.12-rc2 and
> > > v4.12-rc2 + revert of e61c38d85b7392e?
> >
> > Difficult to do that I think. The console is unusable in both directions. I can't get any
> > response from the console (through typing) once the kernel has started.
>
> ssh or telnet come to mind.
Yup. We thought of that also, but finding the time at this side is the problem.
I am looking at this Linux kernel i.MX6Q problem, but other customers are taking my
priority at the moment, so this does not have a very high level (probably because
we have found a "fix", at least to unblock our testing).
Dialog do want to assist the Linux community however. So I will try to help where I can.
> Can you try to just remove the line
> writel(0, sport->port.membase + UFCR);
> that was introduced in the last hunk by commit e61c38d85b7?
Yep. I can do this.
If I make this change, to the stock linux-next/v4.12-rc2 kernel, like this:
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 33509b4..68cfd3e 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -2194,9 +2194,7 @@ static int serial_imx_probe(struct platform_device *pdev)
writel(IMX21_UCR3_RXDMUXSEL | UCR3_ADNIMP | UCR3_DSR,
sport->port.membase + UCR3);
- } else {
- writel(0, sport->port.membase + UFCR);
- }
+ }
clk_disable_unprepare(sport->clk_ipg);
This console works okay.
Everything is ok on our i.MX6Q board after this change to v4.12-rc2.
-- 8< --
U-Boot 2009.08-00001-gf65536a (Jan 12 2015 - 15:47:19)
CPU: Freescale i.MX6 family TO1.2 at 792 MHz
Thermal sensor with ratio = 200
Temperature: 25 C, calibration data 0x5f15527d
mx6q pll1: 792MHz
mx6q pll2: 528MHz
mx6q pll3: 480MHz
mx6q pll8: 50MHz
ipg clock : 66000000Hz
ipg per clock : 66000000Hz
uart clock : 80000000Hz
cspi clock : 60000000Hz
ahb clock : 132000000Hz
axi clock : 264000000Hz
emi_slow clock: 132000000Hz
ddr clock : 528000000Hz
usdhc1 clock : 198000000Hz
usdhc2 clock : 198000000Hz
usdhc3 clock : 198000000Hz
usdhc4 clock : 198000000Hz
nfc clock : 24000000Hz
Board: i.MX6Q-SABRESD: unknown-board Board: 0x63012 [POR ]
Boot Device: SD
I2C: ready
DRAM: 1 GB
MMC: FSL_USDHC: 0,FSL_USDHC: 1,FSL_USDHC: 2,FSL_USDHC: 3
In: serial
Out: serial
Err: serial
Found PFUZE100! deviceid=10,revid=11
Net: got MAC address from IIM: 00:04:9f:02:e3:0a
FEC0 [PRIME]
Hit any key to stop autoboot: 0
PHY indentify @ 0x1 = 0x004dd074
FEC: Link is Up 796d
Using FEC0 device
TFTP from server 192.168.2.1; our IP address is 192.168.2.2
Filename 'uImage_dtb.imx6q.v4.12-rc2'.
Load address: 0x12000000
Loading: #################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
##########################################################
done
Bytes transferred = 5951076 (5ace64 hex)
## Booting kernel from Legacy Image at 12000000 ...
Image Name:
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 5951012 Bytes = 5.7 MB
Load Address: 10800000
Entry Point: 10800000
Verifying Checksum ... OK
Loading Kernel Image ... OK
OK
Starting kernel ...
Booting Linux on physical CPU 0x0
Linux version 4.12.0-rc2 (stwiss@test) (gcc version 4.8.3 20140320 (prerelease) (Sourcery CodeBench Lite 2014.05-29) ) #1 SMP Wed May 24 11:10:14 BST 2017
CPU: ARMv7 Processor [412fc09a] revision 10 (ARMv7), cr=10c5387d
CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
OF: fdt: Machine model: Freescale i.MX6 Quad SABRE Smart Device Board
...
-- 8< --
Regards,
Steve
^ permalink raw reply related
* RE: [PATCH V1] serial: imx: revert setup DCEDTE early and ensure DCD and RI irqs to be off
From: Steve Twiss @ 2017-05-24 10:32 UTC (permalink / raw)
To: Fabio Estevam
Cc: Greg Kroah-Hartman, Jiri Slaby, LINUX-KERNEL, LINUX-SERIAL,
Lucas Stach, Uwe Kleine-Konig, Support Opensource
In-Reply-To: <CAOMZO5CT5MS1WGm_rCJ61Ambh+rMapsQWD84RXtagtt3HhmZwg@mail.gmail.com>
Hi Fabio,
On 23 May 2017 17:26 Fabio Estevam wrote:
> Subject: Re: [PATCH V1] serial: imx: revert setup DCEDTE early and ensure DCD and RI irqs to be off
> On Tue, May 23, 2017 at 9:17 AM, Steve Twiss wrote:
> >
> > Revert the commit e61c38d85b7392e ("serial: imx: setup DCEDTE early and
> > ensure DCD and RI irqs to be off")
> >
> > The patch submitted to setup DCEDTE early and ensure DCD and RI irqs to
> > be off, causes a serial console display problem the i.MX6Q SABRESD board.
> > The console becomes unreadable and unwritable.
> >
> > Tested-by: Steve Twiss <stwiss.opensource@diasemi.com>
> > Signed-off-by: Steve Twiss <stwiss.opensource@diasemi.com>
> >
> > ---
> > This patch applies against linux-next and v4.12-rc2
> >
> > Hi,
> >
> > I have been seeing a problem with the serial output console on the i.MX6Q
> > SABRESD, but not the i.MX6DL SABRESD. Everything was fine up to
> > linux-mainline/v4.11 but changed after linux-next/next-20170501.
> >
> > Some bisection has pointed at the commit
> > e61c38d85b7392e033ee03bca46f1d6006156175 which, once removed from my
> > linux-next/v4.12-rc2 build allows the i.MX6Q board to display the console
> > correctly again.
> >
> > This patch removes the original commit e61c38d85b7392e ("serial: imx:
> > setup DCEDTE early and ensure DCD and RI irqs to be off") from linux-next
> > v4.12-rc2 and fixes the serial problem seen in the i.MX6Q SABRESD board.
>
> How can the error be reproduced?
>
> Care to share more details of the error, please?
The USB to UART connection gets corrupted.
If this patch is applied to the kernel, the i.MX6 Q (quad), and only this board as far as
we know, starts to fail. This does *not* change the i.MX6DL and other sabre boards
have been tested on kernelci.org and do not see a problem.
An NXP/Freescale SABRESD i.MX6 Q board is requred.
My system for testing is to TFTP the Linux kernel over an ethernet connection. The
U-boot executes okay and the UART is working at that point. When the kernel loads
the console trace becomes garbled, in the sense that I get the some characters being
output to the console, in the style of the kernel starting up, but they are not correct.
I expect the kernel has started ok, but I am unable to read/write through the UART
console because of corruptions.
Console log with the output I am seeing with linux-next/v4.12-rc2
--- 8< ---
U-Boot 2009.08-00001-gf65536a (Jan 12 2015 - 15:47:19)
CPU: Freescale i.MX6 family TO1.2 at 792 MHz
Thermal sensor with ratio = 200
Temperature: 46 C, calibration data 0x5f15527d
mx6q pll1: 792MHz
mx6q pll2: 528MHz
mx6q pll3: 480MHz
mx6q pll8: 50MHz
ipg clock : 66000000Hz
ipg per clock : 66000000Hz
uart clock : 80000000Hz
cspi clock : 60000000Hz
ahb clock : 132000000Hz
axi clock : 264000000Hz
emi_slow clock: 132000000Hz
ddr clock : 528000000Hz
usdhc1 clock : 198000000Hz
usdhc2 clock : 198000000Hz
usdhc3 clock : 198000000Hz
usdhc4 clock : 198000000Hz
nfc clock : 24000000Hz
Board: i.MX6Q-SABRESD: unknown-board Board: 0x63012 [WDOG ]
Boot Device: SD
I2C: ready
DRAM: 1 GB
MMC: FSL_USDHC: 0,FSL_USDHC: 1,FSL_USDHC: 2,FSL_USDHC: 3
In: serial
Out: serial
Err: serial
Found PFUZE100! deviceid=10,revid=11
Net: got MAC address from IIM: 00:04:9f:02:e3:0a
FEC0 [PRIME]
Hit any key to stop autoboot: 0
PHY indentify @ 0x1 = 0x004dd074
FEC: Link is Up 796d
Using FEC0 device
TFTP from server 192.168.2.1; our IP address is 192.168.2.2
Filename 'uImage_dtb.imx6q.v4.12-rc2'.
Load address: 0x12000000
Loading: #################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
##########################################################
done
Bytes transferred = 5951108 (5ace84 hex)
## Booting kernel from Legacy Image at 12000000 ...
Image Name:
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 5951044 Bytes = 5.7 MB
Load Address: 10800000
Entry Point: 10800000
Verifying Checksum ... OK
Loading Kernel Image ... OK
OK
Starting kernel ...
à ü ü pþ àüþü à àà àüþü àüü þü à ü à à àüŽ àü àü àà à à €à àüþü ààü üÿ
à àüŽü þü àüàð ààðàà à þ ~pà œà `þ ü àüŽà à à ü à þ üþ à ü à Žàà à
ààü üÿ à àüŽü þü àüàð €àà ààààðàà ðàüààüðààðààà þ üÿ üðü üŽ à üŽà à à üü
þ üÿ à àü ü pð üÀ üþü ü àà àüpÿ üààðàà ðàüàð à üàŽ ~8à Žàà Žààü€ààðààüp
Ž à à üà à à ààðàüðàà ðà üàpþàüðàüðààþà ðà üààà à ààðàà ðàüüàŽà €ü àà
Ž üà~ÿ üàà àà ü üŽà à ü þ àü~Žüàðààðààà à þà € ü ààð ü~ÿ àüŽà àüŽü þü à ðààà
Ž üà~ÿ üàŽà àü€ þ üà ðààü€ àüðààüüà€à üà €ü àà Ž àü àà ààã pŽ ààü ü
þü àü àüŽ à àüþü à àà àþ àü€ ü üð àà ààã pŽ à € àü àüŽ à àüþü à à Ž ü
--- 8< ---
Is this enough information for you?
It would be difficult to reproduce without the i.MX6Q (quad) board from Freescale/NXP
I think.
Regards,
Steve
^ 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